From e26690934f6c880b2834e94f9ca3741c020169e6 Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Wed, 21 Sep 2005 17:55:13 +0000 Subject: [PATCH] *** empty log message *** --- ANN/Copyright.txt | 47 - ANN/License.txt | 450 - ANN/Makefile | 114 - ANN/include/ANN/ANN.h | 829 - ANN/include/ANN/ANNperf.h | 226 - ANN/include/ANN/ANNx.h | 170 - ANN/src/ANN.cpp | 198 - ANN/src/bd_fix_rad_search.cpp | 61 - ANN/src/bd_pr_search.cpp | 62 - ANN/src/bd_search.cpp | 61 - ANN/src/bd_tree.cpp | 417 - ANN/src/bd_tree.h | 100 - ANN/src/brute.cpp | 109 - ANN/src/kd_dump.cpp | 444 - ANN/src/kd_fix_rad_search.cpp | 183 - ANN/src/kd_fix_rad_search.h | 44 - ANN/src/kd_pr_search.cpp | 219 - ANN/src/kd_pr_search.h | 49 - ANN/src/kd_search.cpp | 210 - ANN/src/kd_search.h | 48 - ANN/src/kd_split.cpp | 428 - ANN/src/kd_split.h | 85 - ANN/src/kd_tree.cpp | 405 - ANN/src/kd_tree.h | 197 - ANN/src/kd_util.cpp | 439 - ANN/src/kd_util.h | 124 - ANN/src/perf.cpp | 134 - ANN/src/pr_queue.h | 125 - ANN/src/pr_queue_k.h | 118 - MathEval/Makefile | 79 - MathEval/README | 23 - MathEval/common.h | 37 - MathEval/matheval.cpp | 248 - MathEval/matheval.h | 89 - MathEval/node.cpp | 653 - MathEval/node.h | 111 - MathEval/parser.tab.cpp | 1044 - MathEval/parser.tab.hpp | 11 - MathEval/parser.y | 126 - MathEval/scanner.l | 130 - MathEval/scanner.yy.cpp | 1716 -- MathEval/symbol_table.cpp | 212 - MathEval/symbol_table.h | 79 - MathEval/xmath.cpp | 101 - MathEval/xmath.h | 35 - Mesh/BDS.cpp | 3 + Metis/Doc/manual.ps | 16447 ------------- Metis/Makefile | 103 - Metis/Makefile.in | 22 - Metis/Makefile~ | 114 - Metis/balance.c | 278 - Metis/bucketsort.c | 43 - Metis/ccgraph.c | 599 - Metis/coarsen.c | 83 - Metis/compress.c | 256 - Metis/debug.c | 239 - Metis/defs.h | 161 - Metis/estmem.c | 157 - Metis/fm.c | 194 - Metis/fortran.c | 141 - Metis/frename.c | 312 - Metis/graph.c | 616 - Metis/initpart.c | 422 - Metis/kmetis.c | 129 - Metis/kvmetis.c | 130 - Metis/kwayfm.c | 672 - Metis/kwayrefine.c | 392 - Metis/kwayvolfm.c | 1778 -- Metis/kwayvolrefine.c | 460 - Metis/macros.h | 143 - Metis/match.c | 267 - Metis/mbalance.c | 260 - Metis/mbalance2.c | 328 - Metis/mcoarsen.c | 91 - Metis/memory.c | 208 - Metis/mesh.c | 398 - Metis/meshpart.c | 204 - Metis/metis.h | 37 - Metis/mfm.c | 344 - Metis/mfm2.c | 349 - Metis/mincover.c | 259 - Metis/minitpart.c | 355 - Metis/minitpart2.c | 368 - Metis/mkmetis.c | 123 - Metis/mkwayfmh.c | 677 - Metis/mkwayrefine.c | 297 - Metis/mmatch.c | 506 - Metis/mmd.c | 593 - Metis/mpmetis.c | 402 - Metis/mrefine.c | 219 - Metis/mrefine2.c | 55 - Metis/mutil.c | 101 - Metis/myqsort.c | 547 - Metis/ometis.c | 764 - Metis/parmetis.c | 371 - Metis/pmetis.c | 341 - Metis/pqueue.c | 579 - Metis/proto.h | 505 - Metis/refine.c | 204 - Metis/rename.h | 418 - Metis/separator.c | 284 - Metis/sfm.c | 1069 - Metis/srefine.c | 169 - Metis/stat.c | 287 - Metis/struct.h | 251 - Metis/subdomains.c | 1295 -- Metis/timing.c | 74 - Metis/util.c | 519 - NR/Makefile | 77 - NR/brent.cpp | 77 - NR/dpythag.cpp | 14 - NR/dsvdcmp.cpp | 183 - NR/fdjac.cpp | 29 - NR/fmin.cpp | 20 - NR/lnsrch.cpp | 65 - NR/lubksb.cpp | 23 - NR/ludcmp.cpp | 60 - NR/mnbrak.cpp | 67 - NR/newt.cpp | 92 - NR/nrutil.cpp | 620 - NR/nrutil.h | 109 - Netgen/COPYING.LIB | 504 - Netgen/Makefile | 4412 ---- Netgen/README | 72 - Netgen/VERSION | 1 - Netgen/libsrc/Makefile | 38 - Netgen/libsrc/csg/Makefile | 26 - Netgen/libsrc/csg/algprim.cpp | 1389 -- Netgen/libsrc/csg/algprim.hpp | 338 - Netgen/libsrc/csg/brick.cpp | 409 - Netgen/libsrc/csg/brick.hpp | 98 - Netgen/libsrc/csg/bspline2d.cpp | 242 - Netgen/libsrc/csg/csg.hpp | 48 - Netgen/libsrc/csg/csgeom.cpp | 1020 - Netgen/libsrc/csg/csgeom.hpp | 257 - Netgen/libsrc/csg/csgparser.cpp | 1156 - Netgen/libsrc/csg/csgparser_dalibor.cpp | 1111 - Netgen/libsrc/csg/csgscanner.cpp | 205 - Netgen/libsrc/csg/curve2d.cpp | 78 - Netgen/libsrc/csg/curve2d.hpp | 59 - Netgen/libsrc/csg/edgeflw.cpp | 1524 -- Netgen/libsrc/csg/edgeflw.hpp | 99 - Netgen/libsrc/csg/edgeflw2.cpp | 1404 -- Netgen/libsrc/csg/edgeflw_new.cpp | 1553 -- Netgen/libsrc/csg/edgeflw_old.cpp | 1405 -- Netgen/libsrc/csg/explicitcurve2d.cpp | 160 - Netgen/libsrc/csg/explicitcurve2d.hpp | 109 - Netgen/libsrc/csg/extrusion.cpp | 175 - Netgen/libsrc/csg/extrusion.hpp | 89 - Netgen/libsrc/csg/gencyl.cpp | 209 - Netgen/libsrc/csg/gencyl.hpp | 64 - Netgen/libsrc/csg/genmesh.cpp | 684 - Netgen/libsrc/csg/geometry.cpp | 1792 -- Netgen/libsrc/csg/geometry.h | 48 - Netgen/libsrc/csg/geometry.ll | 94 - Netgen/libsrc/csg/geometry.yy | 585 - Netgen/libsrc/csg/geoml.hpp | 16 - Netgen/libsrc/csg/identify.cpp | 1508 -- Netgen/libsrc/csg/identify.hpp | 180 - Netgen/libsrc/csg/lex.yy.cpp | 1834 -- Netgen/libsrc/csg/manifold.cpp | 14 - Netgen/libsrc/csg/manifold.hpp | 22 - Netgen/libsrc/csg/meshsurf.cpp | 178 - Netgen/libsrc/csg/meshsurf.hpp | 85 - Netgen/libsrc/csg/polyhedra.cpp | 358 - Netgen/libsrc/csg/polyhedra.hpp | 78 - Netgen/libsrc/csg/revolution.cpp | 151 - Netgen/libsrc/csg/revolution.hpp | 65 - Netgen/libsrc/csg/singularref.cpp | 117 - Netgen/libsrc/csg/singularref.hpp | 68 - Netgen/libsrc/csg/solid.cpp | 1217 - Netgen/libsrc/csg/solid.hpp | 195 - Netgen/libsrc/csg/specpoin.cpp | 1231 - Netgen/libsrc/csg/specpoin.hpp | 150 - Netgen/libsrc/csg/specpoin_new.cpp | 1367 -- Netgen/libsrc/csg/specpoin_old.cpp | 1370 -- Netgen/libsrc/csg/spline3d.cpp | 355 - Netgen/libsrc/csg/spline3d.hpp | 92 - Netgen/libsrc/csg/surface.cpp | 392 - Netgen/libsrc/csg/surface.hpp | 301 - Netgen/libsrc/csg/triapprox.cpp | 59 - Netgen/libsrc/csg/triapprox.hpp | 57 - Netgen/libsrc/general/Makefile | 12 - Netgen/libsrc/general/array.cpp | 75 - Netgen/libsrc/general/array.hpp | 478 - Netgen/libsrc/general/autoptr.hpp | 31 - Netgen/libsrc/general/bitarray.cpp | 132 - Netgen/libsrc/general/bitarray.hpp | 207 - Netgen/libsrc/general/dynamicmem.cpp | 117 - Netgen/libsrc/general/dynamicmem.hpp | 94 - Netgen/libsrc/general/flags.cpp | 330 - Netgen/libsrc/general/flags.hpp | 83 - Netgen/libsrc/general/hashtabl.cpp | 294 - Netgen/libsrc/general/hashtabl.hpp | 1000 - Netgen/libsrc/general/moveablemem.cpp | 249 - Netgen/libsrc/general/moveablemem.hpp | 97 - Netgen/libsrc/general/myadt.hpp | 43 - Netgen/libsrc/general/mystring.cpp | 386 - Netgen/libsrc/general/mystring.hpp | 209 - Netgen/libsrc/general/ngexception.cpp | 33 - Netgen/libsrc/general/ngexception.hpp | 30 - Netgen/libsrc/general/optmem.cpp | 63 - Netgen/libsrc/general/optmem.hpp | 52 - Netgen/libsrc/general/parthreads.cpp | 40 - Netgen/libsrc/general/parthreads.hpp | 126 - Netgen/libsrc/general/seti.cpp | 70 - Netgen/libsrc/general/seti.hpp | 45 - Netgen/libsrc/general/sort.cpp | 75 - Netgen/libsrc/general/sort.hpp | 19 - Netgen/libsrc/general/spbita2d.cpp | 172 - Netgen/libsrc/general/spbita2d.hpp | 56 - Netgen/libsrc/general/stack.hpp | 112 - Netgen/libsrc/general/stack.icc | 67 - Netgen/libsrc/general/symbolta.cpp | 52 - Netgen/libsrc/general/symbolta.hpp | 158 - Netgen/libsrc/general/table.cpp | 167 - Netgen/libsrc/general/table.hpp | 212 - Netgen/libsrc/general/template.hpp | 448 - Netgen/libsrc/geom2d/Makefile | 12 - Netgen/libsrc/geom2d/genmesh2d.cpp | 145 - Netgen/libsrc/geom2d/geom2dmesh.cpp | 55 - Netgen/libsrc/geom2d/geom2dmesh.hpp | 38 - Netgen/libsrc/geom2d/geometry2d.hpp | 20 - Netgen/libsrc/geom2d/spline2d.cpp | 395 - Netgen/libsrc/geom2d/spline2d.hpp | 204 - Netgen/libsrc/geom2d/splinegeometry2.cpp | 346 - Netgen/libsrc/geom2d/splinegeometry2.hpp | 83 - Netgen/libsrc/gprim/Makefile | 14 - Netgen/libsrc/gprim/adtree.cpp | 2245 -- Netgen/libsrc/gprim/adtree.hpp | 477 - Netgen/libsrc/gprim/geom2d.cpp | 485 - Netgen/libsrc/gprim/geom2d.hpp | 870 - Netgen/libsrc/gprim/geom3d.cpp | 650 - Netgen/libsrc/gprim/geom3d.hpp | 732 - Netgen/libsrc/gprim/geomfuncs.cpp | 111 - Netgen/libsrc/gprim/geomfuncs.hpp | 136 - Netgen/libsrc/gprim/geomobjects.hpp | 346 - Netgen/libsrc/gprim/geomobjects2.hpp | 366 - Netgen/libsrc/gprim/geomops.hpp | 391 - Netgen/libsrc/gprim/geomops2.hpp | 428 - Netgen/libsrc/gprim/geomtest3d.cpp | 1223 - Netgen/libsrc/gprim/geomtest3d.hpp | 80 - Netgen/libsrc/gprim/gprim.hpp | 26 - Netgen/libsrc/gprim/testgeom.cpp | 20 - Netgen/libsrc/gprim/transform3d.cpp | 173 - Netgen/libsrc/gprim/transform3d.hpp | 174 - Netgen/libsrc/include/FlexLexer.h | 184 - Netgen/libsrc/include/csg.hpp | 1 - Netgen/libsrc/include/geometry2d.hpp | 1 - Netgen/libsrc/include/gprim.hpp | 1 - Netgen/libsrc/include/incvis.hpp | 33 - Netgen/libsrc/include/linalg.hpp | 1 - Netgen/libsrc/include/meshing.hpp | 1 - Netgen/libsrc/include/myadt.hpp | 1 - Netgen/libsrc/include/mydefs.hpp | 29 - Netgen/libsrc/include/mystdlib.h | 69 - Netgen/libsrc/include/occgeom.hpp | 1 - Netgen/libsrc/include/opti.hpp | 1 - Netgen/libsrc/include/stepgeom.hpp | 10 - Netgen/libsrc/include/stepreader.hpp | 1 - Netgen/libsrc/include/stlgeom.hpp | 1 - Netgen/libsrc/include/visual.hpp | 1 - Netgen/libsrc/interface/Makefile | 7 - Netgen/libsrc/interface/importsolution.cpp | 121 - Netgen/libsrc/interface/nginterface.cpp | 1476 -- Netgen/libsrc/interface/nginterface.h | 245 - Netgen/libsrc/interface/nglib.cpp | 573 - Netgen/libsrc/interface/nglib.h | 208 - Netgen/libsrc/interface/printdest.cpp | 11 - Netgen/libsrc/interface/readuser.cpp | 394 - Netgen/libsrc/interface/writeabaqus.cpp | 237 - Netgen/libsrc/interface/writediffpack.cpp | 296 - Netgen/libsrc/interface/writeelmer.cpp | 127 - Netgen/libsrc/interface/writefeap.cpp | 220 - Netgen/libsrc/interface/writefluent.cpp | 193 - Netgen/libsrc/interface/writegmsh.cpp | 200 - Netgen/libsrc/interface/writepermas.cpp | 208 - Netgen/libsrc/interface/writepermas2.cpp | 173 - Netgen/libsrc/interface/writetecplot.cpp | 127 - Netgen/libsrc/interface/writetochnog.cpp | 108 - Netgen/libsrc/interface/writeuser.cpp | 899 - Netgen/libsrc/interface/writeuser.hpp | 114 - Netgen/libsrc/interface/wuchemnitz.cpp | 309 - Netgen/libsrc/linalg/Makefile | 13 - Netgen/libsrc/linalg/basemat.cpp | 472 - Netgen/libsrc/linalg/basemat.hpp | 109 - Netgen/libsrc/linalg/densemat.cpp | 1443 -- Netgen/libsrc/linalg/densemat.hpp | 260 - Netgen/libsrc/linalg/linalg.hpp | 35 - Netgen/libsrc/linalg/polynomial.cpp | 216 - Netgen/libsrc/linalg/polynomial.hpp | 45 - Netgen/libsrc/linalg/sparsmat.cpp | 1707 -- Netgen/libsrc/linalg/sparsmat.hpp | 265 - Netgen/libsrc/linalg/vector.cpp | 787 - Netgen/libsrc/linalg/vector.hpp | 485 - Netgen/libsrc/makefile.inc | 48 - Netgen/libsrc/makefile.mach.FREEBSD | 26 - Netgen/libsrc/makefile.mach.INTEL | 34 - Netgen/libsrc/makefile.mach.LINUX | 31 - Netgen/libsrc/makefile.mach.LINUXGCC33 | 33 - Netgen/libsrc/makefile.mach.SGI | 19 - Netgen/libsrc/makefile.mach.SGIGCC | 53 - Netgen/libsrc/makefile.mach.SUN | 16 - Netgen/libsrc/meshing/Makefile | 16 - Netgen/libsrc/meshing/adfront2.cpp | 526 - Netgen/libsrc/meshing/adfront2.hpp | 337 - Netgen/libsrc/meshing/adfront3.cpp | 883 - Netgen/libsrc/meshing/adfront3.hpp | 276 - Netgen/libsrc/meshing/bisect.cpp | 2371 -- Netgen/libsrc/meshing/bisect.hpp | 77 - Netgen/libsrc/meshing/boundarylayer.cpp | 91 - Netgen/libsrc/meshing/boundarylayer.hpp | 9 - Netgen/libsrc/meshing/clusters.cpp | 260 - Netgen/libsrc/meshing/clusters.hpp | 42 - Netgen/libsrc/meshing/curvedelems.cpp | 2037 -- Netgen/libsrc/meshing/curvedelems.hpp | 837 - Netgen/libsrc/meshing/curvedelems2.cpp | 752 - Netgen/libsrc/meshing/delaunay.cpp | 1683 -- Netgen/libsrc/meshing/findip.cpp | 115 - Netgen/libsrc/meshing/findip.hpp | 108 - Netgen/libsrc/meshing/geomsearch.cpp | 263 - Netgen/libsrc/meshing/geomsearch.hpp | 116 - Netgen/libsrc/meshing/global.cpp | 53 - Netgen/libsrc/meshing/global.hpp | 54 - Netgen/libsrc/meshing/hpref_prism.hpp | 300 - Netgen/libsrc/meshing/hpref_quad.hpp | 2129 -- Netgen/libsrc/meshing/hpref_tet.hpp | 2842 --- Netgen/libsrc/meshing/hpref_trig.hpp | 750 - Netgen/libsrc/meshing/hprefinement.cpp | 2605 --- Netgen/libsrc/meshing/hprefinement.hpp | 227 - Netgen/libsrc/meshing/improve2.cpp | 798 - Netgen/libsrc/meshing/improve2.hpp | 91 - Netgen/libsrc/meshing/improve2gen.cpp | 441 - Netgen/libsrc/meshing/improve3.cpp | 1947 -- Netgen/libsrc/meshing/improve3.hpp | 50 - Netgen/libsrc/meshing/localh.cpp | 682 - Netgen/libsrc/meshing/localh.hpp | 145 - Netgen/libsrc/meshing/meshclass.cpp | 4744 ---- Netgen/libsrc/meshing/meshclass.hpp | 620 - Netgen/libsrc/meshing/meshfunc.cpp | 688 - Netgen/libsrc/meshing/meshfunc.hpp | 41 - Netgen/libsrc/meshing/meshfunc2d.cpp | 61 - Netgen/libsrc/meshing/meshing.hpp | 60 - Netgen/libsrc/meshing/meshing2.cpp | 1864 -- Netgen/libsrc/meshing/meshing2.hpp | 149 - Netgen/libsrc/meshing/meshing3.cpp | 1260 - Netgen/libsrc/meshing/meshing3.hpp | 128 - Netgen/libsrc/meshing/meshtool.cpp | 978 - Netgen/libsrc/meshing/meshtool.hpp | 83 - Netgen/libsrc/meshing/meshtype.cpp | 2233 -- Netgen/libsrc/meshing/meshtype.hpp | 1025 - Netgen/libsrc/meshing/msghandler.cpp | 193 - Netgen/libsrc/meshing/msghandler.hpp | 52 - Netgen/libsrc/meshing/netrule2.cpp | 226 - Netgen/libsrc/meshing/netrule3.cpp | 1138 - Netgen/libsrc/meshing/parser2.cpp | 559 - Netgen/libsrc/meshing/parser3.cpp | 987 - Netgen/libsrc/meshing/prism2rls.cpp | 457 - Netgen/libsrc/meshing/prism2rls_2.cpp | 446 - Netgen/libsrc/meshing/pyramid2rls.cpp | 309 - Netgen/libsrc/meshing/pyramidrls.cpp | 263 - Netgen/libsrc/meshing/quadrls.cpp | 765 - Netgen/libsrc/meshing/refine.cpp | 721 - Netgen/libsrc/meshing/ruler2.cpp | 646 - Netgen/libsrc/meshing/ruler2.hpp | 166 - Netgen/libsrc/meshing/ruler3.cpp | 1176 - Netgen/libsrc/meshing/ruler3.hpp | 210 - Netgen/libsrc/meshing/secondorder.cpp | 496 - Netgen/libsrc/meshing/smoothing2.cpp | 922 - Netgen/libsrc/meshing/smoothing3.cpp | 1546 -- Netgen/libsrc/meshing/specials.cpp | 193 - Netgen/libsrc/meshing/specials.hpp | 16 - Netgen/libsrc/meshing/tetrarls.cpp | 1466 -- Netgen/libsrc/meshing/topology.cpp | 1595 -- Netgen/libsrc/meshing/topology.hpp | 113 - Netgen/libsrc/meshing/triarls.cpp | 468 - Netgen/libsrc/meshing/zrefine.cpp | 735 - Netgen/libsrc/occ/Makefile | 11 - Netgen/libsrc/occ/occgenmesh.cpp | 1245 - Netgen/libsrc/occ/occgeom.cpp | 1102 - Netgen/libsrc/occ/occgeom.hpp | 279 - Netgen/libsrc/occ/occmeshsurf.cpp | 592 - Netgen/libsrc/occ/occmeshsurf.hpp | 201 - Netgen/libsrc/opti/Makefile | 10 - Netgen/libsrc/opti/bfgs.cpp | 367 - Netgen/libsrc/opti/linopt.cpp | 73 - Netgen/libsrc/opti/linsearch.cpp | 346 - Netgen/libsrc/opti/opti.hpp | 142 - Netgen/libsrc/stlgeom/Makefile | 11 - Netgen/libsrc/stlgeom/meshstlsurface.cpp | 1130 - Netgen/libsrc/stlgeom/meshstlsurface.hpp | 121 - Netgen/libsrc/stlgeom/stlgeom.cpp | 3476 --- Netgen/libsrc/stlgeom/stlgeom.hpp | 450 - Netgen/libsrc/stlgeom/stlgeomchart.cpp | 801 - Netgen/libsrc/stlgeom/stlgeommesh.cpp | 1592 -- Netgen/libsrc/stlgeom/stlline.cpp | 780 - Netgen/libsrc/stlgeom/stlline.hpp | 188 - Netgen/libsrc/stlgeom/stltool.cpp | 1288 -- Netgen/libsrc/stlgeom/stltool.hpp | 271 - Netgen/libsrc/stlgeom/stltopology.cpp | 1067 - Netgen/libsrc/stlgeom/stltopology.hpp | 362 - Netgen/libsrc/visualization/Makefile | 13 - Netgen/libsrc/visualization/meshdoc.cpp | 615 - Netgen/libsrc/visualization/meshdoc.hpp | 37 - Netgen/libsrc/visualization/mvdraw.cpp | 1335 -- Netgen/libsrc/visualization/mvdraw.hpp | 370 - Netgen/libsrc/visualization/soldata.hpp | 45 - Netgen/libsrc/visualization/stlmeshing.cpp | 1074 - Netgen/libsrc/visualization/vispar.hpp | 89 - Netgen/libsrc/visualization/visual.hpp | 26 - Netgen/libsrc/visualization/vscsg.cpp | 199 - Netgen/libsrc/visualization/vsmesh.cpp | 3114 --- Netgen/libsrc/visualization/vsocc.cpp | 743 - Netgen/libsrc/visualization/vssolution.cpp | 3005 --- Netgen/libsrc/visualization/vssolution.hpp | 220 - Netgen/nglib_addon.cpp | 105 - Netgen/nglib_addon.h | 8 - Plugin/Makefile | 6 +- Tetgen/LICENSE | 65 - Tetgen/Makefile | 53 - Tetgen/predicates.cxx | 4176 ---- Tetgen/tetgen.cxx | 22807 ------------------- Tetgen/tetgen.h | 1764 -- Triangle/Makefile | 55 - Triangle/README | 74 - Triangle/triangle.c | 16008 ------------- Triangle/triangle.h | 282 - 427 files changed, 6 insertions(+), 237811 deletions(-) delete mode 100644 ANN/Copyright.txt delete mode 100644 ANN/License.txt delete mode 100644 ANN/Makefile delete mode 100644 ANN/include/ANN/ANN.h delete mode 100644 ANN/include/ANN/ANNperf.h delete mode 100644 ANN/include/ANN/ANNx.h delete mode 100644 ANN/src/ANN.cpp delete mode 100644 ANN/src/bd_fix_rad_search.cpp delete mode 100644 ANN/src/bd_pr_search.cpp delete mode 100644 ANN/src/bd_search.cpp delete mode 100644 ANN/src/bd_tree.cpp delete mode 100644 ANN/src/bd_tree.h delete mode 100644 ANN/src/brute.cpp delete mode 100644 ANN/src/kd_dump.cpp delete mode 100644 ANN/src/kd_fix_rad_search.cpp delete mode 100644 ANN/src/kd_fix_rad_search.h delete mode 100644 ANN/src/kd_pr_search.cpp delete mode 100644 ANN/src/kd_pr_search.h delete mode 100644 ANN/src/kd_search.cpp delete mode 100644 ANN/src/kd_search.h delete mode 100644 ANN/src/kd_split.cpp delete mode 100644 ANN/src/kd_split.h delete mode 100644 ANN/src/kd_tree.cpp delete mode 100644 ANN/src/kd_tree.h delete mode 100644 ANN/src/kd_util.cpp delete mode 100644 ANN/src/kd_util.h delete mode 100644 ANN/src/perf.cpp delete mode 100644 ANN/src/pr_queue.h delete mode 100644 ANN/src/pr_queue_k.h delete mode 100644 MathEval/Makefile delete mode 100644 MathEval/README delete mode 100644 MathEval/common.h delete mode 100644 MathEval/matheval.cpp delete mode 100644 MathEval/matheval.h delete mode 100644 MathEval/node.cpp delete mode 100644 MathEval/node.h delete mode 100644 MathEval/parser.tab.cpp delete mode 100644 MathEval/parser.tab.hpp delete mode 100644 MathEval/parser.y delete mode 100644 MathEval/scanner.l delete mode 100644 MathEval/scanner.yy.cpp delete mode 100644 MathEval/symbol_table.cpp delete mode 100644 MathEval/symbol_table.h delete mode 100644 MathEval/xmath.cpp delete mode 100644 MathEval/xmath.h delete mode 100644 Metis/Doc/manual.ps delete mode 100644 Metis/Makefile delete mode 100644 Metis/Makefile.in delete mode 100644 Metis/Makefile~ delete mode 100644 Metis/balance.c delete mode 100644 Metis/bucketsort.c delete mode 100644 Metis/ccgraph.c delete mode 100644 Metis/coarsen.c delete mode 100644 Metis/compress.c delete mode 100644 Metis/debug.c delete mode 100644 Metis/defs.h delete mode 100644 Metis/estmem.c delete mode 100644 Metis/fm.c delete mode 100644 Metis/fortran.c delete mode 100644 Metis/frename.c delete mode 100644 Metis/graph.c delete mode 100644 Metis/initpart.c delete mode 100644 Metis/kmetis.c delete mode 100644 Metis/kvmetis.c delete mode 100644 Metis/kwayfm.c delete mode 100644 Metis/kwayrefine.c delete mode 100644 Metis/kwayvolfm.c delete mode 100644 Metis/kwayvolrefine.c delete mode 100644 Metis/macros.h delete mode 100644 Metis/match.c delete mode 100644 Metis/mbalance.c delete mode 100644 Metis/mbalance2.c delete mode 100644 Metis/mcoarsen.c delete mode 100644 Metis/memory.c delete mode 100644 Metis/mesh.c delete mode 100644 Metis/meshpart.c delete mode 100644 Metis/metis.h delete mode 100644 Metis/mfm.c delete mode 100644 Metis/mfm2.c delete mode 100644 Metis/mincover.c delete mode 100644 Metis/minitpart.c delete mode 100644 Metis/minitpart2.c delete mode 100644 Metis/mkmetis.c delete mode 100644 Metis/mkwayfmh.c delete mode 100644 Metis/mkwayrefine.c delete mode 100644 Metis/mmatch.c delete mode 100644 Metis/mmd.c delete mode 100644 Metis/mpmetis.c delete mode 100644 Metis/mrefine.c delete mode 100644 Metis/mrefine2.c delete mode 100644 Metis/mutil.c delete mode 100644 Metis/myqsort.c delete mode 100644 Metis/ometis.c delete mode 100644 Metis/parmetis.c delete mode 100644 Metis/pmetis.c delete mode 100644 Metis/pqueue.c delete mode 100644 Metis/proto.h delete mode 100644 Metis/refine.c delete mode 100644 Metis/rename.h delete mode 100644 Metis/separator.c delete mode 100644 Metis/sfm.c delete mode 100644 Metis/srefine.c delete mode 100644 Metis/stat.c delete mode 100644 Metis/struct.h delete mode 100644 Metis/subdomains.c delete mode 100644 Metis/timing.c delete mode 100644 Metis/util.c delete mode 100644 NR/Makefile delete mode 100644 NR/brent.cpp delete mode 100644 NR/dpythag.cpp delete mode 100644 NR/dsvdcmp.cpp delete mode 100644 NR/fdjac.cpp delete mode 100644 NR/fmin.cpp delete mode 100644 NR/lnsrch.cpp delete mode 100644 NR/lubksb.cpp delete mode 100644 NR/ludcmp.cpp delete mode 100644 NR/mnbrak.cpp delete mode 100644 NR/newt.cpp delete mode 100644 NR/nrutil.cpp delete mode 100644 NR/nrutil.h delete mode 100644 Netgen/COPYING.LIB delete mode 100644 Netgen/Makefile delete mode 100644 Netgen/README delete mode 100644 Netgen/VERSION delete mode 100644 Netgen/libsrc/Makefile delete mode 100644 Netgen/libsrc/csg/Makefile delete mode 100644 Netgen/libsrc/csg/algprim.cpp delete mode 100644 Netgen/libsrc/csg/algprim.hpp delete mode 100644 Netgen/libsrc/csg/brick.cpp delete mode 100644 Netgen/libsrc/csg/brick.hpp delete mode 100644 Netgen/libsrc/csg/bspline2d.cpp delete mode 100644 Netgen/libsrc/csg/csg.hpp delete mode 100644 Netgen/libsrc/csg/csgeom.cpp delete mode 100644 Netgen/libsrc/csg/csgeom.hpp delete mode 100644 Netgen/libsrc/csg/csgparser.cpp delete mode 100644 Netgen/libsrc/csg/csgparser_dalibor.cpp delete mode 100644 Netgen/libsrc/csg/csgscanner.cpp delete mode 100644 Netgen/libsrc/csg/curve2d.cpp delete mode 100644 Netgen/libsrc/csg/curve2d.hpp delete mode 100644 Netgen/libsrc/csg/edgeflw.cpp delete mode 100644 Netgen/libsrc/csg/edgeflw.hpp delete mode 100644 Netgen/libsrc/csg/edgeflw2.cpp delete mode 100644 Netgen/libsrc/csg/edgeflw_new.cpp delete mode 100644 Netgen/libsrc/csg/edgeflw_old.cpp delete mode 100644 Netgen/libsrc/csg/explicitcurve2d.cpp delete mode 100644 Netgen/libsrc/csg/explicitcurve2d.hpp delete mode 100644 Netgen/libsrc/csg/extrusion.cpp delete mode 100644 Netgen/libsrc/csg/extrusion.hpp delete mode 100644 Netgen/libsrc/csg/gencyl.cpp delete mode 100644 Netgen/libsrc/csg/gencyl.hpp delete mode 100644 Netgen/libsrc/csg/genmesh.cpp delete mode 100644 Netgen/libsrc/csg/geometry.cpp delete mode 100644 Netgen/libsrc/csg/geometry.h delete mode 100644 Netgen/libsrc/csg/geometry.ll delete mode 100644 Netgen/libsrc/csg/geometry.yy delete mode 100644 Netgen/libsrc/csg/geoml.hpp delete mode 100644 Netgen/libsrc/csg/identify.cpp delete mode 100644 Netgen/libsrc/csg/identify.hpp delete mode 100644 Netgen/libsrc/csg/lex.yy.cpp delete mode 100644 Netgen/libsrc/csg/manifold.cpp delete mode 100644 Netgen/libsrc/csg/manifold.hpp delete mode 100644 Netgen/libsrc/csg/meshsurf.cpp delete mode 100644 Netgen/libsrc/csg/meshsurf.hpp delete mode 100644 Netgen/libsrc/csg/polyhedra.cpp delete mode 100644 Netgen/libsrc/csg/polyhedra.hpp delete mode 100644 Netgen/libsrc/csg/revolution.cpp delete mode 100644 Netgen/libsrc/csg/revolution.hpp delete mode 100644 Netgen/libsrc/csg/singularref.cpp delete mode 100644 Netgen/libsrc/csg/singularref.hpp delete mode 100644 Netgen/libsrc/csg/solid.cpp delete mode 100644 Netgen/libsrc/csg/solid.hpp delete mode 100644 Netgen/libsrc/csg/specpoin.cpp delete mode 100644 Netgen/libsrc/csg/specpoin.hpp delete mode 100644 Netgen/libsrc/csg/specpoin_new.cpp delete mode 100644 Netgen/libsrc/csg/specpoin_old.cpp delete mode 100644 Netgen/libsrc/csg/spline3d.cpp delete mode 100644 Netgen/libsrc/csg/spline3d.hpp delete mode 100644 Netgen/libsrc/csg/surface.cpp delete mode 100644 Netgen/libsrc/csg/surface.hpp delete mode 100644 Netgen/libsrc/csg/triapprox.cpp delete mode 100644 Netgen/libsrc/csg/triapprox.hpp delete mode 100644 Netgen/libsrc/general/Makefile delete mode 100644 Netgen/libsrc/general/array.cpp delete mode 100644 Netgen/libsrc/general/array.hpp delete mode 100644 Netgen/libsrc/general/autoptr.hpp delete mode 100644 Netgen/libsrc/general/bitarray.cpp delete mode 100644 Netgen/libsrc/general/bitarray.hpp delete mode 100644 Netgen/libsrc/general/dynamicmem.cpp delete mode 100644 Netgen/libsrc/general/dynamicmem.hpp delete mode 100644 Netgen/libsrc/general/flags.cpp delete mode 100644 Netgen/libsrc/general/flags.hpp delete mode 100644 Netgen/libsrc/general/hashtabl.cpp delete mode 100644 Netgen/libsrc/general/hashtabl.hpp delete mode 100644 Netgen/libsrc/general/moveablemem.cpp delete mode 100644 Netgen/libsrc/general/moveablemem.hpp delete mode 100644 Netgen/libsrc/general/myadt.hpp delete mode 100644 Netgen/libsrc/general/mystring.cpp delete mode 100644 Netgen/libsrc/general/mystring.hpp delete mode 100644 Netgen/libsrc/general/ngexception.cpp delete mode 100644 Netgen/libsrc/general/ngexception.hpp delete mode 100644 Netgen/libsrc/general/optmem.cpp delete mode 100644 Netgen/libsrc/general/optmem.hpp delete mode 100644 Netgen/libsrc/general/parthreads.cpp delete mode 100644 Netgen/libsrc/general/parthreads.hpp delete mode 100644 Netgen/libsrc/general/seti.cpp delete mode 100644 Netgen/libsrc/general/seti.hpp delete mode 100644 Netgen/libsrc/general/sort.cpp delete mode 100644 Netgen/libsrc/general/sort.hpp delete mode 100644 Netgen/libsrc/general/spbita2d.cpp delete mode 100644 Netgen/libsrc/general/spbita2d.hpp delete mode 100644 Netgen/libsrc/general/stack.hpp delete mode 100644 Netgen/libsrc/general/stack.icc delete mode 100644 Netgen/libsrc/general/symbolta.cpp delete mode 100644 Netgen/libsrc/general/symbolta.hpp delete mode 100644 Netgen/libsrc/general/table.cpp delete mode 100644 Netgen/libsrc/general/table.hpp delete mode 100644 Netgen/libsrc/general/template.hpp delete mode 100644 Netgen/libsrc/geom2d/Makefile delete mode 100644 Netgen/libsrc/geom2d/genmesh2d.cpp delete mode 100644 Netgen/libsrc/geom2d/geom2dmesh.cpp delete mode 100644 Netgen/libsrc/geom2d/geom2dmesh.hpp delete mode 100644 Netgen/libsrc/geom2d/geometry2d.hpp delete mode 100644 Netgen/libsrc/geom2d/spline2d.cpp delete mode 100644 Netgen/libsrc/geom2d/spline2d.hpp delete mode 100644 Netgen/libsrc/geom2d/splinegeometry2.cpp delete mode 100644 Netgen/libsrc/geom2d/splinegeometry2.hpp delete mode 100644 Netgen/libsrc/gprim/Makefile delete mode 100644 Netgen/libsrc/gprim/adtree.cpp delete mode 100644 Netgen/libsrc/gprim/adtree.hpp delete mode 100644 Netgen/libsrc/gprim/geom2d.cpp delete mode 100644 Netgen/libsrc/gprim/geom2d.hpp delete mode 100644 Netgen/libsrc/gprim/geom3d.cpp delete mode 100644 Netgen/libsrc/gprim/geom3d.hpp delete mode 100644 Netgen/libsrc/gprim/geomfuncs.cpp delete mode 100644 Netgen/libsrc/gprim/geomfuncs.hpp delete mode 100644 Netgen/libsrc/gprim/geomobjects.hpp delete mode 100644 Netgen/libsrc/gprim/geomobjects2.hpp delete mode 100644 Netgen/libsrc/gprim/geomops.hpp delete mode 100644 Netgen/libsrc/gprim/geomops2.hpp delete mode 100644 Netgen/libsrc/gprim/geomtest3d.cpp delete mode 100644 Netgen/libsrc/gprim/geomtest3d.hpp delete mode 100644 Netgen/libsrc/gprim/gprim.hpp delete mode 100644 Netgen/libsrc/gprim/testgeom.cpp delete mode 100644 Netgen/libsrc/gprim/transform3d.cpp delete mode 100644 Netgen/libsrc/gprim/transform3d.hpp delete mode 100644 Netgen/libsrc/include/FlexLexer.h delete mode 100644 Netgen/libsrc/include/csg.hpp delete mode 100644 Netgen/libsrc/include/geometry2d.hpp delete mode 100644 Netgen/libsrc/include/gprim.hpp delete mode 100644 Netgen/libsrc/include/incvis.hpp delete mode 100644 Netgen/libsrc/include/linalg.hpp delete mode 100644 Netgen/libsrc/include/meshing.hpp delete mode 100644 Netgen/libsrc/include/myadt.hpp delete mode 100644 Netgen/libsrc/include/mydefs.hpp delete mode 100644 Netgen/libsrc/include/mystdlib.h delete mode 100644 Netgen/libsrc/include/occgeom.hpp delete mode 100644 Netgen/libsrc/include/opti.hpp delete mode 100644 Netgen/libsrc/include/stepgeom.hpp delete mode 100644 Netgen/libsrc/include/stepreader.hpp delete mode 100644 Netgen/libsrc/include/stlgeom.hpp delete mode 100644 Netgen/libsrc/include/visual.hpp delete mode 100644 Netgen/libsrc/interface/Makefile delete mode 100644 Netgen/libsrc/interface/importsolution.cpp delete mode 100644 Netgen/libsrc/interface/nginterface.cpp delete mode 100644 Netgen/libsrc/interface/nginterface.h delete mode 100644 Netgen/libsrc/interface/nglib.cpp delete mode 100644 Netgen/libsrc/interface/nglib.h delete mode 100644 Netgen/libsrc/interface/printdest.cpp delete mode 100644 Netgen/libsrc/interface/readuser.cpp delete mode 100644 Netgen/libsrc/interface/writeabaqus.cpp delete mode 100644 Netgen/libsrc/interface/writediffpack.cpp delete mode 100644 Netgen/libsrc/interface/writeelmer.cpp delete mode 100644 Netgen/libsrc/interface/writefeap.cpp delete mode 100644 Netgen/libsrc/interface/writefluent.cpp delete mode 100644 Netgen/libsrc/interface/writegmsh.cpp delete mode 100644 Netgen/libsrc/interface/writepermas.cpp delete mode 100644 Netgen/libsrc/interface/writepermas2.cpp delete mode 100644 Netgen/libsrc/interface/writetecplot.cpp delete mode 100644 Netgen/libsrc/interface/writetochnog.cpp delete mode 100644 Netgen/libsrc/interface/writeuser.cpp delete mode 100644 Netgen/libsrc/interface/writeuser.hpp delete mode 100644 Netgen/libsrc/interface/wuchemnitz.cpp delete mode 100644 Netgen/libsrc/linalg/Makefile delete mode 100644 Netgen/libsrc/linalg/basemat.cpp delete mode 100644 Netgen/libsrc/linalg/basemat.hpp delete mode 100644 Netgen/libsrc/linalg/densemat.cpp delete mode 100644 Netgen/libsrc/linalg/densemat.hpp delete mode 100644 Netgen/libsrc/linalg/linalg.hpp delete mode 100644 Netgen/libsrc/linalg/polynomial.cpp delete mode 100644 Netgen/libsrc/linalg/polynomial.hpp delete mode 100644 Netgen/libsrc/linalg/sparsmat.cpp delete mode 100644 Netgen/libsrc/linalg/sparsmat.hpp delete mode 100644 Netgen/libsrc/linalg/vector.cpp delete mode 100644 Netgen/libsrc/linalg/vector.hpp delete mode 100644 Netgen/libsrc/makefile.inc delete mode 100644 Netgen/libsrc/makefile.mach.FREEBSD delete mode 100644 Netgen/libsrc/makefile.mach.INTEL delete mode 100644 Netgen/libsrc/makefile.mach.LINUX delete mode 100644 Netgen/libsrc/makefile.mach.LINUXGCC33 delete mode 100644 Netgen/libsrc/makefile.mach.SGI delete mode 100644 Netgen/libsrc/makefile.mach.SGIGCC delete mode 100644 Netgen/libsrc/makefile.mach.SUN delete mode 100644 Netgen/libsrc/meshing/Makefile delete mode 100644 Netgen/libsrc/meshing/adfront2.cpp delete mode 100644 Netgen/libsrc/meshing/adfront2.hpp delete mode 100644 Netgen/libsrc/meshing/adfront3.cpp delete mode 100644 Netgen/libsrc/meshing/adfront3.hpp delete mode 100644 Netgen/libsrc/meshing/bisect.cpp delete mode 100644 Netgen/libsrc/meshing/bisect.hpp delete mode 100644 Netgen/libsrc/meshing/boundarylayer.cpp delete mode 100644 Netgen/libsrc/meshing/boundarylayer.hpp delete mode 100644 Netgen/libsrc/meshing/clusters.cpp delete mode 100644 Netgen/libsrc/meshing/clusters.hpp delete mode 100644 Netgen/libsrc/meshing/curvedelems.cpp delete mode 100644 Netgen/libsrc/meshing/curvedelems.hpp delete mode 100644 Netgen/libsrc/meshing/curvedelems2.cpp delete mode 100644 Netgen/libsrc/meshing/delaunay.cpp delete mode 100644 Netgen/libsrc/meshing/findip.cpp delete mode 100644 Netgen/libsrc/meshing/findip.hpp delete mode 100644 Netgen/libsrc/meshing/geomsearch.cpp delete mode 100644 Netgen/libsrc/meshing/geomsearch.hpp delete mode 100644 Netgen/libsrc/meshing/global.cpp delete mode 100644 Netgen/libsrc/meshing/global.hpp delete mode 100644 Netgen/libsrc/meshing/hpref_prism.hpp delete mode 100644 Netgen/libsrc/meshing/hpref_quad.hpp delete mode 100644 Netgen/libsrc/meshing/hpref_tet.hpp delete mode 100644 Netgen/libsrc/meshing/hpref_trig.hpp delete mode 100644 Netgen/libsrc/meshing/hprefinement.cpp delete mode 100644 Netgen/libsrc/meshing/hprefinement.hpp delete mode 100644 Netgen/libsrc/meshing/improve2.cpp delete mode 100644 Netgen/libsrc/meshing/improve2.hpp delete mode 100644 Netgen/libsrc/meshing/improve2gen.cpp delete mode 100644 Netgen/libsrc/meshing/improve3.cpp delete mode 100644 Netgen/libsrc/meshing/improve3.hpp delete mode 100644 Netgen/libsrc/meshing/localh.cpp delete mode 100644 Netgen/libsrc/meshing/localh.hpp delete mode 100644 Netgen/libsrc/meshing/meshclass.cpp delete mode 100644 Netgen/libsrc/meshing/meshclass.hpp delete mode 100644 Netgen/libsrc/meshing/meshfunc.cpp delete mode 100644 Netgen/libsrc/meshing/meshfunc.hpp delete mode 100644 Netgen/libsrc/meshing/meshfunc2d.cpp delete mode 100644 Netgen/libsrc/meshing/meshing.hpp delete mode 100644 Netgen/libsrc/meshing/meshing2.cpp delete mode 100644 Netgen/libsrc/meshing/meshing2.hpp delete mode 100644 Netgen/libsrc/meshing/meshing3.cpp delete mode 100644 Netgen/libsrc/meshing/meshing3.hpp delete mode 100644 Netgen/libsrc/meshing/meshtool.cpp delete mode 100644 Netgen/libsrc/meshing/meshtool.hpp delete mode 100644 Netgen/libsrc/meshing/meshtype.cpp delete mode 100644 Netgen/libsrc/meshing/meshtype.hpp delete mode 100644 Netgen/libsrc/meshing/msghandler.cpp delete mode 100644 Netgen/libsrc/meshing/msghandler.hpp delete mode 100644 Netgen/libsrc/meshing/netrule2.cpp delete mode 100644 Netgen/libsrc/meshing/netrule3.cpp delete mode 100644 Netgen/libsrc/meshing/parser2.cpp delete mode 100644 Netgen/libsrc/meshing/parser3.cpp delete mode 100644 Netgen/libsrc/meshing/prism2rls.cpp delete mode 100644 Netgen/libsrc/meshing/prism2rls_2.cpp delete mode 100644 Netgen/libsrc/meshing/pyramid2rls.cpp delete mode 100644 Netgen/libsrc/meshing/pyramidrls.cpp delete mode 100644 Netgen/libsrc/meshing/quadrls.cpp delete mode 100644 Netgen/libsrc/meshing/refine.cpp delete mode 100644 Netgen/libsrc/meshing/ruler2.cpp delete mode 100644 Netgen/libsrc/meshing/ruler2.hpp delete mode 100644 Netgen/libsrc/meshing/ruler3.cpp delete mode 100644 Netgen/libsrc/meshing/ruler3.hpp delete mode 100644 Netgen/libsrc/meshing/secondorder.cpp delete mode 100644 Netgen/libsrc/meshing/smoothing2.cpp delete mode 100644 Netgen/libsrc/meshing/smoothing3.cpp delete mode 100644 Netgen/libsrc/meshing/specials.cpp delete mode 100644 Netgen/libsrc/meshing/specials.hpp delete mode 100644 Netgen/libsrc/meshing/tetrarls.cpp delete mode 100644 Netgen/libsrc/meshing/topology.cpp delete mode 100644 Netgen/libsrc/meshing/topology.hpp delete mode 100644 Netgen/libsrc/meshing/triarls.cpp delete mode 100644 Netgen/libsrc/meshing/zrefine.cpp delete mode 100644 Netgen/libsrc/occ/Makefile delete mode 100644 Netgen/libsrc/occ/occgenmesh.cpp delete mode 100644 Netgen/libsrc/occ/occgeom.cpp delete mode 100644 Netgen/libsrc/occ/occgeom.hpp delete mode 100644 Netgen/libsrc/occ/occmeshsurf.cpp delete mode 100644 Netgen/libsrc/occ/occmeshsurf.hpp delete mode 100644 Netgen/libsrc/opti/Makefile delete mode 100644 Netgen/libsrc/opti/bfgs.cpp delete mode 100644 Netgen/libsrc/opti/linopt.cpp delete mode 100644 Netgen/libsrc/opti/linsearch.cpp delete mode 100644 Netgen/libsrc/opti/opti.hpp delete mode 100644 Netgen/libsrc/stlgeom/Makefile delete mode 100644 Netgen/libsrc/stlgeom/meshstlsurface.cpp delete mode 100644 Netgen/libsrc/stlgeom/meshstlsurface.hpp delete mode 100644 Netgen/libsrc/stlgeom/stlgeom.cpp delete mode 100644 Netgen/libsrc/stlgeom/stlgeom.hpp delete mode 100644 Netgen/libsrc/stlgeom/stlgeomchart.cpp delete mode 100644 Netgen/libsrc/stlgeom/stlgeommesh.cpp delete mode 100644 Netgen/libsrc/stlgeom/stlline.cpp delete mode 100644 Netgen/libsrc/stlgeom/stlline.hpp delete mode 100644 Netgen/libsrc/stlgeom/stltool.cpp delete mode 100644 Netgen/libsrc/stlgeom/stltool.hpp delete mode 100644 Netgen/libsrc/stlgeom/stltopology.cpp delete mode 100644 Netgen/libsrc/stlgeom/stltopology.hpp delete mode 100644 Netgen/libsrc/visualization/Makefile delete mode 100644 Netgen/libsrc/visualization/meshdoc.cpp delete mode 100644 Netgen/libsrc/visualization/meshdoc.hpp delete mode 100644 Netgen/libsrc/visualization/mvdraw.cpp delete mode 100644 Netgen/libsrc/visualization/mvdraw.hpp delete mode 100644 Netgen/libsrc/visualization/soldata.hpp delete mode 100644 Netgen/libsrc/visualization/stlmeshing.cpp delete mode 100644 Netgen/libsrc/visualization/vispar.hpp delete mode 100644 Netgen/libsrc/visualization/visual.hpp delete mode 100644 Netgen/libsrc/visualization/vscsg.cpp delete mode 100644 Netgen/libsrc/visualization/vsmesh.cpp delete mode 100644 Netgen/libsrc/visualization/vsocc.cpp delete mode 100644 Netgen/libsrc/visualization/vssolution.cpp delete mode 100644 Netgen/libsrc/visualization/vssolution.hpp delete mode 100644 Netgen/nglib_addon.cpp delete mode 100644 Netgen/nglib_addon.h delete mode 100644 Tetgen/LICENSE delete mode 100644 Tetgen/Makefile delete mode 100644 Tetgen/predicates.cxx delete mode 100644 Tetgen/tetgen.cxx delete mode 100644 Tetgen/tetgen.h delete mode 100644 Triangle/Makefile delete mode 100644 Triangle/README delete mode 100644 Triangle/triangle.c delete mode 100644 Triangle/triangle.h diff --git a/ANN/Copyright.txt b/ANN/Copyright.txt deleted file mode 100644 index 9b752403d4..0000000000 --- a/ANN/Copyright.txt +++ /dev/null @@ -1,47 +0,0 @@ -ANN: Approximate Nearest Neighbors -Version: 1.1 -Release Date: May 3, 2005 ----------------------------------------------------------------------------- -Copyright (c) 1997-2005 University of Maryland and Sunil Arya and David -Mount All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser Public License as published by the -Free Software Foundation; either version 2.1 of the License, or (at your -option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser Public License for more details. - -A copy of the terms and conditions of the license can be found in -License.txt or online at - - http://www.gnu.org/copyleft/lesser.html - -To obtain a copy, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Disclaimer ----------- -The University of Maryland and the authors make no representations about -the suitability or fitness of this software for any purpose. It is -provided "as is" without express or implied warranty. ---------------------------------------------------------------------- - -Authors -------- -David Mount -Dept of Computer Science -University of Maryland, -College Park, MD 20742 USA -mount@cs.umd.edu -http://www.cs.umd.edu/~mount/ - -Sunil Arya -Dept of Computer Science -Hong University of Science and Technology -Clearwater Bay, HONG KONG -arya@cs.ust.hk -http://www.cs.ust.hk/faculty/arya/ diff --git a/ANN/License.txt b/ANN/License.txt deleted file mode 100644 index 456ea97817..0000000000 --- a/ANN/License.txt +++ /dev/null @@ -1,450 +0,0 @@ ----------------------------------------------------------------------- -The ANN Library (all versions) is provided under the terms and -conditions of the GNU Lesser General Public Library, which is stated -below. It can also be found at: - - http://www.gnu.org/copyleft/lesser.html - ----------------------------------------------------------------------- - -GNU LESSER GENERAL PUBLIC LICENSE - -Version 2.1, February 1999 - -Copyright (C) 1991, 1999 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts -as the successor of the GNU Library Public License, version 2, hence the -version number 2.1.] - -Preamble - -The licenses for most software are designed to take away your freedom to -share and change it. By contrast, the GNU General Public Licenses are -intended to guarantee your freedom to share and change free software--to -make sure the software is free for all its users. - -This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the Free -Software Foundation and other authors who decide to use it. You can use -it too, but we suggest you first think carefully about whether this -license or the ordinary General Public License is the better strategy to -use in any particular case, based on the explanations below. - -When we speak of free software, we are referring to freedom of use, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish); that you receive source code or can get it if -you want it; that you can change the software and use pieces of it in -new free programs; and that you are informed that you can do these -things. - -To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for you -if you distribute copies of the library or if you modify it. - -For example, if you distribute copies of the library, whether gratis or -for a fee, you must give the recipients all the rights that we gave you. -You must make sure that they, too, receive or can get the source code. -If you link other code with the library, you must provide complete -object files to the recipients, so that they can relink them with the -library after making changes to the library and recompiling it. And you -must show them these terms so they know their rights. - -We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - -To protect each distributor, we want to make it very clear that there is -no warranty for the free library. Also, if the library is modified by -someone else and passed on, the recipients should know that what they -have is not the original version, so that the original author's -reputation will not be affected by problems that might be introduced by -others. - -Finally, software patents pose a constant threat to the existence of any -free program. We wish to make sure that a company cannot effectively -restrict the users of a free program by obtaining a restrictive license -from a patent holder. Therefore, we insist that any patent license -obtained for a version of the library must be consistent with the full -freedom of use specified in this license. - -Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License. This license, the GNU Lesser General Public -License, applies to certain designated libraries, and is quite different -from the ordinary General Public License. We use this license for -certain libraries in order to permit linking those libraries into -non-free programs. - -When a program is linked with a library, whether statically or using a -shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the entire -combination fits its criteria of freedom. The Lesser General Public -License permits more lax criteria for linking other code with the -library. - -We call this license the "Lesser" General Public License because it does -Less to protect the user's freedom than the ordinary General Public -License. It also provides other free software developers Less of an -advantage over competing non-free programs. These disadvantages are the -reason we use the ordinary General Public License for many libraries. -However, the Lesser license provides advantages in certain special -circumstances. - -For example, on rare occasions, there may be a special need to encourage -the widest possible use of a certain library, so that it becomes a -de-facto standard. To achieve this, non-free programs must be allowed to -use the library. A more frequent case is that a free library does the -same job as widely used non-free libraries. In this case, there is -little to gain by limiting the free library to free software only, so we -use the Lesser General Public License. - -In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of free -software. For example, permission to use the GNU C Library in non-free -programs enables many more people to use the whole GNU operating system, -as well as its variant, the GNU/Linux operating system. - -Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is linked -with the Library has the freedom and the wherewithal to run that program -using a modified version of the Library. - -The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or other -authorized party saying it may be distributed under the terms of this -Lesser General Public License (also called "this License"). Each -licensee is addressed as "you". - -A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - -The "Library", below, refers to any such software library or work which -has been distributed under these terms. A "work based on the Library" -means either the Library or any derivative work under copyright law: -that is to say, a work containing the Library or a portion of it, either -verbatim or with modifications and/or translated straightforwardly into -another language. (Hereinafter, translation is included without -limitation in the term "modification".) - -"Source code" for a work means the preferred form of the work for making -modifications to it. For a library, complete source code means all the -source code for all modules it contains, plus any associated interface -definition files, plus the scripts used to control compilation and -installation of the library. - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of running -a program using the Library is not restricted, and output from such a -program is covered only if its contents constitute a work based on the -Library (independent of the use of the Library in a tool for writing -it). Whether that is true depends on what the Library does and what the -program that uses the Library does. - -1. You may copy and distribute verbatim copies of the Library's complete -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the notices -that refer to this License and to the absence of any warranty; and -distribute a copy of this License along with the Library. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Library or any portion of -it, thus forming a work based on the Library, and copy and distribute -such modifications or work under the terms of Section 1 above, provided -that you also meet all of these conditions: - - a) The modified work must itself be a software library. - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has -a purpose that is entirely well-defined independent of the application. -Therefore, Subsection 2d requires that any application-supplied function -or table used by this function must be optional: if the application does -not supply it, the square root function must still compute square -roots.) - - These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, and -can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based on -the Library, the distribution of the whole must be on the terms of this -License, whose permissions for other licensees extend to the entire -whole, and thus to each and every part regardless of who wrote it. - - Thus, it is not the intent of this section to claim rights or -contest your rights to work written entirely by you; rather, the intent -is to exercise the right to control the distribution of derivative or -collective works based on the Library. - - In addition, mere aggregation of another work not based on the -Library with the Library (or with a work based on the Library) on a -volume of a storage or distribution medium does not bring the other work -under the scope of this License. - -3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so that -they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in these -notices. - -Once this change is made in a given copy, it is irreversible for that -copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - -This option is useful when you wish to copy part of the code of the -Library into a program that is not a library. - -4. You may copy and distribute the Library (or a portion or derivative -of it, under Section 2) in object code or executable form under the -terms of Sections 1 and 2 above provided that you accompany it with the -complete corresponding machine-readable source code, which must be -distributed under the terms of Sections 1 and 2 above on a medium -customarily used for software interchange. - -If distribution of object code is made by offering access to copy from a -designated place, then offering equivalent access to copy the source -code from the same place satisfies the requirement to distribute the -source code, even though third parties are not compelled to copy the -source along with the object code. - -5. A program that contains no derivative of any portion of the Library, -but is designed to work with the Library by being compiled or linked -with it, is called a "work that uses the Library". Such a work, in -isolation, is not a derivative work of the Library, and therefore falls -outside the scope of this License. - -However, linking a "work that uses the Library" with the Library creates -an executable that is a derivative of the Library (because it contains -portions of the Library), rather than a "work that uses the library". -The executable is therefore covered by this License. Section 6 states -terms for distribution of such executables. - -When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be linked -without the Library, or if the work is itself a library. The threshold -for this to be true is not precisely defined by law. - -If such an object file uses only numerical parameters, data structure -layouts and accessors, and small macros and small inline functions (ten -lines or less in length), then the use of the object file is -unrestricted, regardless of whether it is legally a derivative work. -(Executables containing this object code plus portions of the Library -will still fall under Section 6.) - -Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, whether -or not they are linked directly with the Library itself. - -6. As an exception to the Sections above, you may also combine or link a -"work that uses the Library" with the Library to produce a work -containing portions of the Library, and distribute that work under terms -of your choice, provided that the terms permit modification of the work -for the customer's own use and reverse engineering for debugging such -modifications. - -You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work during -execution displays copyright notices, you must include the copyright -notice for the Library among them, as well as a reference directing the -user to the copy of this License. Also, you must do one of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood that - the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - -For an executable, the required form of the "work that uses the Library" -must include any data and utility programs needed for reproducing the -executable from it. However, as a special exception, the materials to be -distributed need not include anything that is normally distributed (in -either source or binary form) with the major components (compiler, -kernel, and so on) of the operating system on which the executable runs, -unless that component itself accompanies the executable. - -It may happen that this requirement contradicts the license restrictions -of other proprietary libraries that do not normally accompany the -operating system. Such a contradiction means you cannot use both them -and the Library together in an executable that you distribute. - -7. You may place library facilities that are a work based on the Library -side-by-side in a single library together with other library facilities -not covered by this License, and distribute such a combined library, -provided that the separate distribution of the work based on the Library -and of the other library facilities is otherwise permitted, and provided -that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - -8. You may not copy, modify, sublicense, link with, or distribute the -Library except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, link with, or distribute the -Library is void, and will automatically terminate your rights under this -License. However, parties who have received copies, or rights, from you -under this License will not have their licenses terminated so long as -such parties remain in full compliance. - -9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and all -its terms and conditions for copying, distributing or modifying the -Library or works based on it. - -10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - -11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot distribute -so as to satisfy simultaneously your obligations under this License and -any other pertinent obligations, then as a consequence you may not -distribute the Library at all. For example, if a patent license would -not permit royalty-free redistribution of the Library by all those who -receive copies directly or indirectly through you, then the only way you -could satisfy both it and this License would be to refrain entirely from -distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is implemented -by public license practices. Many people have made generous -contributions to the wide range of software distributed through that -system in reliance on consistent application of that system; it is up to -the author/donor to decide if he or she is willing to distribute -software through any other system and a licensee cannot impose that -choice. - -This section is intended to make thoroughly clear what is believed to be -a consequence of the rest of this License. - -12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may -add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among countries -not thus excluded. In such case, this License incorporates the -limitation as if written in the body of this License. - -13. The Free Software Foundation may publish revised and/or new versions -of the Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a license -version number, you may choose any version ever published by the Free -Software Foundation. - -14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free Software -Foundation; we sometimes make exceptions for this. Our decision will be -guided by the two goals of preserving the free status of all derivatives -of our free software and of promoting the sharing and reuse of software -generally. - -NO WARRANTY - -15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE -ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH -YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL -NECESSARY SERVICING, REPAIR OR CORRECTION. - -16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY -(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED -INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF -THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR -OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. diff --git a/ANN/Makefile b/ANN/Makefile deleted file mode 100644 index ae62a0c44f..0000000000 --- a/ANN/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -# $Id: Makefile,v 1.2 2005-08-22 00:35:06 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshANN.a -INCLUDE = -I../Common -I./include/ -CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} -DNO_PARALLEL_THREADS -UWIN32 - -SRC = src/ANN.cpp\ - src/bd_fix_rad_search.cpp\ -src/bd_pr_search.cpp\ -src/bd_search.cpp\ -src/bd_tree.cpp\ -src/brute.cpp\ -src/kd_dump.cpp\ -src/kd_fix_rad_search.cpp\ -src/kd_pr_search.cpp\ -src/kd_search.cpp\ -src/kd_split.cpp\ -src/kd_tree.cpp\ -src/kd_util.cpp\ -src/perf.cpp - -OBJ = ${SRC:.cpp=.o} - -.SUFFIXES: .o .cpp - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.cpp.o: - ${CXX} ${CFLAGS} -c $< -o ${<:.cpp=.o} - -clean: - rm -f src/*.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -# 1 "/Users/geuzaine/.gmsh/ANN//" -ANN.o: src/ANN.cpp include/ANN/ANNx.h include/ANN/ANN.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_fix_rad_search.o: src/bd_fix_rad_search.cpp src/bd_tree.h \ - include/ANN/ANNx.h include/ANN/ANN.h src/kd_tree.h \ - src/kd_fix_rad_search.h src/kd_util.h src/pr_queue_k.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_pr_search.o: src/bd_pr_search.cpp src/bd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_tree.h src/kd_pr_search.h src/kd_util.h \ - src/pr_queue.h include/ANN/ANNperf.h src/pr_queue_k.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_search.o: src/bd_search.cpp src/bd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_tree.h src/kd_search.h src/kd_util.h \ - src/pr_queue_k.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_tree.o: src/bd_tree.cpp src/bd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_tree.h src/kd_util.h src/kd_split.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -brute.o: src/brute.cpp include/ANN/ANNx.h include/ANN/ANN.h \ - src/pr_queue_k.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_dump.o: src/kd_dump.cpp src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/bd_tree.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_fix_rad_search.o: src/kd_fix_rad_search.cpp src/kd_fix_rad_search.h \ - src/kd_tree.h include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h \ - src/pr_queue_k.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_pr_search.o: src/kd_pr_search.cpp src/kd_pr_search.h src/kd_tree.h \ - include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h src/pr_queue.h \ - include/ANN/ANNperf.h src/pr_queue_k.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_search.o: src/kd_search.cpp src/kd_search.h src/kd_tree.h \ - include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h src/pr_queue_k.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_split.o: src/kd_split.cpp src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_util.h src/kd_split.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_tree.o: src/kd_tree.cpp src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_split.h src/kd_util.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_util.o: src/kd_util.cpp src/kd_util.h src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -perf.o: src/perf.cpp include/ANN/ANN.h include/ANN/ANNperf.h diff --git a/ANN/include/ANN/ANN.h b/ANN/include/ANN/ANN.h deleted file mode 100644 index ca8146a35a..0000000000 --- a/ANN/include/ANN/ANN.h +++ /dev/null @@ -1,829 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANN.h -// Programmer: Sunil Arya and David Mount -// Last modified: 05/03/05 (Release 1.1) -// Description: Basic include file for approximate nearest -// neighbor searching. -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). -// -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Added copyright and revision information -// Added ANNcoordPrec for coordinate precision. -// Added methods theDim, nPoints, maxPoints, thePoints to ANNpointSet. -// Cleaned up C++ structure for modern compilers -// Revision 1.1 05/03/05 -// Added fixed-radius k-NN searching -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// ANN - approximate nearest neighbor searching -// ANN is a library for approximate nearest neighbor searching, -// based on the use of standard and priority search in kd-trees -// and balanced box-decomposition (bbd) trees. Here are some -// references to the main algorithmic techniques used here: -// -// kd-trees: -// Friedman, Bentley, and Finkel, ``An algorithm for finding -// best matches in logarithmic expected time,'' ACM -// Transactions on Mathematical Software, 3(3):209-226, 1977. -// -// Priority search in kd-trees: -// Arya and Mount, ``Algorithms for fast vector quantization,'' -// Proc. of DCC '93: Data Compression Conference, eds. J. A. -// Storer and M. Cohn, IEEE Press, 1993, 381-390. -// -// Approximate nearest neighbor search and bbd-trees: -// Arya, Mount, Netanyahu, Silverman, and Wu, ``An optimal -// algorithm for approximate nearest neighbor searching,'' -// 5th Ann. ACM-SIAM Symposium on Discrete Algorithms, -// 1994, 573-582. -//---------------------------------------------------------------------- - -#ifndef ANN_H -#define ANN_H - -#ifdef WIN33 - //---------------------------------------------------------------------- - // For Microsoft Visual C++, externally accessible symbols must be - // explicitly indicated with DLL_API, which is somewhat like "extern." - // - // The following ifdef block is the standard way of creating macros - // which make exporting from a DLL simpler. All files within this DLL - // are compiled with the DLL_EXPORTS preprocessor symbol defined on the - // command line. In contrast, projects that use (or import) the DLL - // objects do not define the DLL_EXPORTS symbol. This way any other - // project whose source files include this file see DLL_API functions as - // being imported from a DLL, wheras this DLL sees symbols defined with - // this macro as being exported. - //---------------------------------------------------------------------- - #ifdef DLL_EXPORTS - #define DLL_API __declspec(dllexport) - #else - #define DLL_API __declspec(dllimport) - #endif - //---------------------------------------------------------------------- - // DLL_API is ignored for all other systems - //---------------------------------------------------------------------- -#else - #define DLL_API -#endif - -//---------------------------------------------------------------------- -// basic includes -//---------------------------------------------------------------------- - -#include <cmath> // math includes -#include <iostream> // I/O streams - -//---------------------------------------------------------------------- -// Limits -// There are a number of places where we use the maximum double value as -// default initializers (and others may be used, depending on the -// data/distance representation). These can usually be found in limits.h -// (as LONG_MAX, INT_MAX) or in float.h (as DBL_MAX, FLT_MAX). -// -// Not all systems have these files. If you are using such a system, -// you should set the preprocessor symbol ANN_NO_LIMITS_H when -// compiling, and modify the statements below to generate the -// appropriate value. For practical purposes, this does not need to be -// the maximum double value. It is sufficient that it be at least as -// large than the maximum squared distance between between any two -// points. -//---------------------------------------------------------------------- -#ifdef ANN_NO_LIMITS_H // limits.h unavailable - #include <cvalues> // replacement for limits.h - const double ANN_DBL_MAX = MAXDOUBLE; // insert maximum double -#else - #include <climits> - #include <cfloat> - const double ANN_DBL_MAX = DBL_MAX; -#endif - -#define ANNversion "1.0" // ANN version and information -#define ANNversionCmt "" -#define ANNcopyright "David M. Mount and Sunil Arya" -#define ANNlatestRev "Mar 1, 2005" - -//---------------------------------------------------------------------- -// ANNbool -// This is a simple boolean type. Although ANSI C++ is supposed -// to support the type bool, some compilers do not have it. -//---------------------------------------------------------------------- - -enum ANNbool {ANNfalse = 0, ANNtrue = 1}; // ANN boolean type (non ANSI C++) - -//---------------------------------------------------------------------- -// ANNcoord, ANNdist -// ANNcoord and ANNdist are the types used for representing -// point coordinates and distances. They can be modified by the -// user, with some care. It is assumed that they are both numeric -// types, and that ANNdist is generally of an equal or higher type -// from ANNcoord. A variable of type ANNdist should be large -// enough to store the sum of squared components of a variable -// of type ANNcoord for the number of dimensions needed in the -// application. For example, the following combinations are -// legal: -// -// ANNcoord ANNdist -// --------- ------------------------------- -// short short, int, long, float, double -// int int, long, float, double -// long long, float, double -// float float, double -// double double -// -// It is the user's responsibility to make sure that overflow does -// not occur in distance calculation. -//---------------------------------------------------------------------- - -typedef double ANNcoord; // coordinate data type -typedef double ANNdist; // distance data type - -//---------------------------------------------------------------------- -// ANNidx -// ANNidx is a point index. When the data structure is built, the -// points are given as an array. Nearest neighbor results are -// returned as an integer index into this array. To make it -// clearer when this is happening, we define the integer type -// ANNidx. Indexing starts from 0. -// -// For fixed-radius near neighbor searching, it is possible that -// there are not k nearest neighbors within the search radius. To -// indicate this, the algorithm returns ANN_NULL_IDX as its result. -// It should be distinguishable from any valid array index. -//---------------------------------------------------------------------- - -typedef int ANNidx; // point index -const ANNidx ANN_NULL_IDX = -1; // a NULL point index - -//---------------------------------------------------------------------- -// Infinite distance: -// The code assumes that there is an "infinite distance" which it -// uses to initialize distances before performing nearest neighbor -// searches. It should be as larger or larger than any legitimate -// nearest neighbor distance. -// -// On most systems, these should be found in the standard include -// file <limits.h> or possibly <float.h>. If you do not have these -// file, some suggested values are listed below, assuming 64-bit -// long, 32-bit int and 16-bit short. -// -// ANNdist ANN_DIST_INF Values (see <limits.h> or <float.h>) -// ------- ------------ ------------------------------------ -// double DBL_MAX 1.79769313486231570e+308 -// float FLT_MAX 3.40282346638528860e+38 -// long LONG_MAX 0x7fffffffffffffff -// int INT_MAX 0x7fffffff -// short SHRT_MAX 0x7fff -//---------------------------------------------------------------------- - -const ANNdist ANN_DIST_INF = ANN_DBL_MAX; - -//---------------------------------------------------------------------- -// Significant digits for tree dumps: -// When floating point coordinates are used, the routine that dumps -// a tree needs to know roughly how many significant digits there -// are in a ANNcoord, so it can output points to full precision. -// This is defined to be ANNcoordPrec. On most systems these -// values can be found in the standard include files <limits.h> or -// <float.h>. For integer types, the value is essentially ignored. -// -// ANNcoord ANNcoordPrec Values (see <limits.h> or <float.h>) -// -------- ------------ ------------------------------------ -// double DBL_DIG 15 -// float FLT_DIG 6 -// long doesn't matter 19 -// int doesn't matter 10 -// short doesn't matter 5 -//---------------------------------------------------------------------- - -#ifdef DBL_DIG // number of sig. bits in ANNcoord - const int ANNcoordPrec = DBL_DIG; -#else - const int ANNcoordPrec = 15; // default precision -#endif - -//---------------------------------------------------------------------- -// Self match? -// In some applications, the nearest neighbor of a point is not -// allowed to be the point itself. This occurs, for example, when -// computing all nearest neighbors in a set. By setting the -// parameter ANN_ALLOW_SELF_MATCH to ANNfalse, the nearest neighbor -// is the closest point whose distance from the query point is -// strictly positive. -//---------------------------------------------------------------------- - -const ANNbool ANN_ALLOW_SELF_MATCH = ANNtrue; - -//---------------------------------------------------------------------- -// Norms and metrics: -// ANN supports any Minkowski norm for defining distance. In -// particular, for any p >= 1, the L_p Minkowski norm defines the -// length of a d-vector (v0, v1, ..., v(d-1)) to be -// -// (|v0|^p + |v1|^p + ... + |v(d-1)|^p)^(1/p), -// -// (where ^ denotes exponentiation, and |.| denotes absolute -// value). The distance between two points is defined to be the -// norm of the vector joining them. Some common distance metrics -// include -// -// Euclidean metric p = 2 -// Manhattan metric p = 1 -// Max metric p = infinity -// -// In the case of the max metric, the norm is computed by taking -// the maxima of the absolute values of the components. ANN is -// highly "coordinate-based" and does not support general distances -// functions (e.g. those obeying just the triangle inequality). It -// also does not support distance functions based on -// inner-products. -// -// For the purpose of computing nearest neighbors, it is not -// necessary to compute the final power (1/p). Thus the only -// component that is used by the program is |v(i)|^p. -// -// ANN parameterizes the distance computation through the following -// macros. (Macros are used rather than procedures for -// efficiency.) Recall that the distance between two points is -// given by the length of the vector joining them, and the length -// or norm of a vector v is given by formula: -// -// |v| = ROOT(POW(v0) # POW(v1) # ... # POW(v(d-1))) -// -// where ROOT, POW are unary functions and # is an associative and -// commutative binary operator mapping the following types: -// -// ** POW: ANNcoord --> ANNdist -// ** #: ANNdist x ANNdist --> ANNdist -// ** ROOT: ANNdist (>0) --> double -// -// For early termination in distance calculation (partial distance -// calculation) we assume that POW and # together are monotonically -// increasing on sequences of arguments, meaning that for all -// v0..vk and y: -// -// POW(v0) #...# POW(vk) <= (POW(v0) #...# POW(vk)) # POW(y). -// -// Incremental Distance Calculation: -// The program uses an optimized method of computing distances for -// kd-trees and bd-trees, called incremental distance calculation. -// It is used when distances are to be updated when only a single -// coordinate of a point has been changed. In order to use this, -// we assume that there is an incremental update function DIFF(x,y) -// for #, such that if: -// -// s = x0 # ... # xi # ... # xk -// -// then if s' is equal to s but with xi replaced by y, that is, -// -// s' = x0 # ... # y # ... # xk -// -// then the length of s' can be computed by: -// -// |s'| = |s| # DIFF(xi,y). -// -// Thus, if # is + then DIFF(xi,y) is (yi-x). For the L_infinity -// norm we make use of the fact that in the program this function -// is only invoked when y > xi, and hence DIFF(xi,y)=y. -// -// Finally, for approximate nearest neighbor queries we assume -// that POW and ROOT are related such that -// -// v*ROOT(x) = ROOT(POW(v)*x) -// -// Here are the values for the various Minkowski norms: -// -// L_p: p even: p odd: -// ------------------------- ------------------------ -// POW(v) = v^p POW(v) = |v|^p -// ROOT(x) = x^(1/p) ROOT(x) = x^(1/p) -// # = + # = + -// DIFF(x,y) = y - x DIFF(x,y) = y - x -// -// L_inf: -// POW(v) = |v| -// ROOT(x) = x -// # = max -// DIFF(x,y) = y -// -// By default the Euclidean norm is assumed. To change the norm, -// uncomment the appropriate set of macros below. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Use the following for the Euclidean norm -//---------------------------------------------------------------------- -#define ANN_POW(v) ((v)*(v)) -#define ANN_ROOT(x) sqrt(x) -#define ANN_SUM(x,y) ((x) + (y)) -#define ANN_DIFF(x,y) ((y) - (x)) - -//---------------------------------------------------------------------- -// Use the following for the L_1 (Manhattan) norm -//---------------------------------------------------------------------- -// #define ANN_POW(v) fabs(v) -// #define ANN_ROOT(x) (x) -// #define ANN_SUM(x,y) ((x) + (y)) -// #define ANN_DIFF(x,y) ((y) - (x)) - -//---------------------------------------------------------------------- -// Use the following for a general L_p norm -//---------------------------------------------------------------------- -// #define ANN_POW(v) pow(fabs(v),p) -// #define ANN_ROOT(x) pow(fabs(x),1/p) -// #define ANN_SUM(x,y) ((x) + (y)) -// #define ANN_DIFF(x,y) ((y) - (x)) - -//---------------------------------------------------------------------- -// Use the following for the L_infinity (Max) norm -//---------------------------------------------------------------------- -// #define ANN_POW(v) fabs(v) -// #define ANN_ROOT(x) (x) -// #define ANN_SUM(x,y) ((x) > (y) ? (x) : (y)) -// #define ANN_DIFF(x,y) (y) - -//---------------------------------------------------------------------- -// Array types -// The following array types are of basic interest. A point is -// just a dimensionless array of coordinates, a point array is a -// dimensionless array of points. A distance array is a -// dimensionless array of distances and an index array is a -// dimensionless array of point indices. The latter two are used -// when returning the results of k-nearest neighbor queries. -//---------------------------------------------------------------------- - -typedef ANNcoord* ANNpoint; // a point -typedef ANNpoint* ANNpointArray; // an array of points -typedef ANNdist* ANNdistArray; // an array of distances -typedef ANNidx* ANNidxArray; // an array of point indices - -//---------------------------------------------------------------------- -// Basic point and array utilities: -// The following procedures are useful supplements to ANN's nearest -// neighbor capabilities. -// -// annDist(): -// Computes the (squared) distance between a pair of points. -// Note that this routine is not used internally by ANN for -// computing distance calculations. For reasons of efficiency -// this is done using incremental distance calculation. Thus, -// this routine cannot be modified as a method of changing the -// metric. -// -// Because points (somewhat like strings in C) are stored as -// pointers. Consequently, creating and destroying copies of -// points may require storage allocation. These procedures do -// this. -// -// annAllocPt() and annDeallocPt(): -// Allocate a deallocate storage for a single point, and -// return a pointer to it. The argument to AllocPt() is -// used to initialize all components. -// -// annAllocPts() and annDeallocPts(): -// Allocate and deallocate an array of points as well a -// place to store their coordinates, and initializes the -// points to point to their respective coordinates. It -// allocates point storage in a contiguous block large -// enough to store all the points. It performs no -// initialization. -// -// annCopyPt(): -// Creates a copy of a given point, allocating space for -// the new point. It returns a pointer to the newly -// allocated copy. -//---------------------------------------------------------------------- - -DLL_API ANNdist annDist( - int dim, // dimension of space - ANNpoint p, // points - ANNpoint q); - -DLL_API ANNpoint annAllocPt( - int dim, // dimension - ANNcoord c = 0); // coordinate value (all equal) - -DLL_API ANNpointArray annAllocPts( - int n, // number of points - int dim); // dimension - -DLL_API void annDeallocPt( - ANNpoint &p); // deallocate 1 point - -DLL_API void annDeallocPts( - ANNpointArray &pa); // point array - -DLL_API ANNpoint annCopyPt( - int dim, // dimension - ANNpoint source); // point to copy - -//---------------------------------------------------------------------- -//Overall structure: ANN supports a number of different data structures -//for approximate and exact nearest neighbor searching. These are: -// -// ANNbruteForce A simple brute-force search structure. -// ANNkd_tree A kd-tree tree search structure. ANNbd_tree -// A bd-tree tree search structure (a kd-tree with shrink -// capabilities). -// -// At a minimum, each of these data structures support k-nearest -// neighbor queries. The nearest neighbor query, annkSearch, -// returns an integer identifier and the distance to the nearest -// neighbor(s) and annRangeSearch returns the nearest points that -// lie within a given query ball. -// -// Each structure is built by invoking the appropriate constructor -// and passing it (at a minimum) the array of points, the total -// number of points and the dimension of the space. Each structure -// is also assumed to support a destructor and member functions -// that return basic information about the point set. -// -// Note that the array of points is not copied by the data -// structure (for reasons of space efficiency), and it is assumed -// to be constant throughout the lifetime of the search structure. -// -// The search algorithm, annkSearch, is given the query point (q), -// and the desired number of nearest neighbors to report (k), and -// the error bound (eps) (whose default value is 0, implying exact -// nearest neighbors). It returns two arrays which are assumed to -// contain at least k elements: one (nn_idx) contains the indices -// (within the point array) of the nearest neighbors and the other -// (dd) contains the squared distances to these nearest neighbors. -// -// The search algorithm, annkFRSearch, is a fixed-radius kNN -// search. In addition to a query point, it is given a (squared) -// radius bound. (This is done for consistency, because the search -// returns distances as squared quantities.) It does two things. -// First, it computes the k nearest neighbors within the radius -// bound, and second, it returns the total number of points lying -// within the radius bound. It is permitted to set k = 0, in which -// case it effectively answers a range counting query. If the -// error bound epsilon is positive, then the search is approximate -// in the sense that it is free to ignore any point that lies -// outside a ball of radius r/(1+epsilon), where r is the given -// (unsquared) radius bound. -// -// The generic object from which all the search structures are -// dervied is given below. It is a virtual object, and is useless -// by itself. -//---------------------------------------------------------------------- - -class DLL_API ANNpointSet { -public: - virtual ~ANNpointSet() {} // virtual distructor - - virtual void annkSearch( // approx k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (modified) - ANNdistArray dd, // dist to near neighbors (modified) - double eps=0.0 // error bound - ) = 0; // pure virtual (defined elsewhere) - - virtual int annkFRSearch( // approx fixed-radius kNN search - ANNpoint q, // query point - ANNdist sqRad, // squared radius - int k = 0, // number of near neighbors to return - ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) - ANNdistArray dd = NULL, // dist to near neighbors (modified) - double eps=0.0 // error bound - ) = 0; // pure virtual (defined elsewhere) - - virtual int theDim() = 0; // return dimension of space - virtual int nPoints() = 0; // return number of points - // return pointer to points - virtual ANNpointArray thePoints() = 0; -}; - -//---------------------------------------------------------------------- -// Brute-force nearest neighbor search: -// The brute-force search structure is very simple but inefficient. -// It has been provided primarily for the sake of comparison with -// and validation of the more complex search structures. -// -// Query processing is the same as described above, but the value -// of epsilon is ignored, since all distance calculations are -// performed exactly. -// -// WARNING: This data structure is very slow, and should not be -// used unless the number of points is very small. -// -// Internal information: -// --------------------- -// This data structure bascially consists of the array of points -// (each a pointer to an array of coordinates). The search is -// performed by a simple linear scan of all the points. -//---------------------------------------------------------------------- - -class DLL_API ANNbruteForce: public ANNpointSet { - int dim; // dimension - int n_pts; // number of points - ANNpointArray pts; // point array -public: - ANNbruteForce( // constructor from point array - ANNpointArray pa, // point array - int n, // number of points - int dd); // dimension - - ~ANNbruteForce(); // destructor - - void annkSearch( // approx k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (modified) - ANNdistArray dd, // dist to near neighbors (modified) - double eps=0.0); // error bound - - int annkFRSearch( // approx fixed-radius kNN search - ANNpoint q, // query point - ANNdist sqRad, // squared radius - int k = 0, // number of near neighbors to return - ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) - ANNdistArray dd = NULL, // dist to near neighbors (modified) - double eps=0.0); // error bound - - int theDim() // return dimension of space - { return dim; } - - int nPoints() // return number of points - { return n_pts; } - - ANNpointArray thePoints() // return pointer to points - { return pts; } -}; - -//---------------------------------------------------------------------- -// kd- and bd-tree splitting and shrinking rules -// kd-trees supports a collection of different splitting rules. -// In addition to the standard kd-tree splitting rule proposed -// by Friedman, Bentley, and Finkel, we have introduced a -// number of other splitting rules, which seem to perform -// as well or better (for the distributions we have tested). -// -// The splitting methods given below allow the user to tailor -// the data structure to the particular data set. They are -// are described in greater details in the kd_split.cc source -// file. The method ANN_KD_SUGGEST is the method chosen (rather -// subjectively) by the implementors as the one giving the -// fastest performance, and is the default splitting method. -// -// As with splitting rules, there are a number of different -// shrinking rules. The shrinking rule ANN_BD_NONE does no -// shrinking (and hence produces a kd-tree tree). The rule -// ANN_BD_SUGGEST uses the implementors favorite rule. -//---------------------------------------------------------------------- - -enum ANNsplitRule { - ANN_KD_STD = 0, // the optimized kd-splitting rule - ANN_KD_MIDPT = 1, // midpoint split - ANN_KD_FAIR = 2, // fair split - ANN_KD_SL_MIDPT = 3, // sliding midpoint splitting method - ANN_KD_SL_FAIR = 4, // sliding fair split method - ANN_KD_SUGGEST = 5}; // the authors' suggestion for best -const int ANN_N_SPLIT_RULES = 6; // number of split rules - -enum ANNshrinkRule { - ANN_BD_NONE = 0, // no shrinking at all (just kd-tree) - ANN_BD_SIMPLE = 1, // simple splitting - ANN_BD_CENTROID = 2, // centroid splitting - ANN_BD_SUGGEST = 3}; // the authors' suggested choice -const int ANN_N_SHRINK_RULES = 4; // number of shrink rules - -//---------------------------------------------------------------------- -// kd-tree: -// The main search data structure supported by ANN is a kd-tree. -// The main constructor is given a set of points and a choice of -// splitting method to use in building the tree. -// -// Construction: -// ------------- -// The constructor is given the point array, number of points, -// dimension, bucket size (default = 1), and the splitting rule -// (default = ANN_KD_SUGGEST). The point array is not copied, and -// is assumed to be kept constant throughout the lifetime of the -// search structure. There is also a "load" constructor that -// builds a tree from a file description that was created by the -// Dump operation. -// -// Search: -// ------- -// There are two search methods: -// -// Standard search (annkSearch()): -// Searches nodes in tree-traversal order, always visiting -// the closer child first. -// Priority search (annkPriSearch()): -// Searches nodes in order of increasing distance of the -// associated cell from the query point. For many -// distributions the standard search seems to work just -// fine, but priority search is safer for worst-case -// performance. -// -// Printing: -// --------- -// There are two methods provided for printing the tree. Print() -// is used to produce a "human-readable" display of the tree, with -// indenation, which is handy for debugging. Dump() produces a -// format that is suitable reading by another program. There is a -// "load" constructor, which constructs a tree which is assumed to -// have been saved by the Dump() procedure. -// -// Performance and Structure Statistics: -// ------------------------------------- -// The procedure getStats() collects statistics information on the -// tree (its size, height, etc.) See ANNperf.h for information on -// the stats structure it returns. -// -// Internal information: -// --------------------- -// The data structure consists of three major chunks of storage. -// The first (implicit) storage are the points themselves (pts), -// which have been provided by the users as an argument to the -// constructor, or are allocated dynamically if the tree is built -// using the load constructor). These should not be changed during -// the lifetime of the search structure. It is the user's -// responsibility to delete these after the tree is destroyed. -// -// The second is the tree itself (which is dynamically allocated in -// the constructor) and is given as a pointer to its root node -// (root). These nodes are automatically deallocated when the tree -// is deleted. See the file src/kd_tree.h for further information -// on the structure of the tree nodes. -// -// Each leaf of the tree does not contain a pointer directly to a -// point, but rather contains a pointer to a "bucket", which is an -// array consisting of point indices. The third major chunk of -// storage is an array (pidx), which is a large array in which all -// these bucket subarrays reside. (The reason for storing them -// separately is the buckets are typically small, but of varying -// sizes. This was done to avoid fragmentation.) This array is -// also deallocated when the tree is deleted. -// -// In addition to this, the tree consists of a number of other -// pieces of information which are used in searching and for -// subsequent tree operations. These consist of the following: -// -// dim Dimension of space -// n_pts Number of points currently in the tree -// n_max Maximum number of points that are allowed -// in the tree -// bkt_size Maximum bucket size (no. of points per leaf) -// bnd_box_lo Bounding box low point -// bnd_box_hi Bounding box high point -// splitRule Splitting method used -// -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Some types and objects used by kd-tree functions -// See src/kd_tree.h and src/kd_tree.cpp for definitions -//---------------------------------------------------------------------- -class ANNkdStats; // stats on kd-tree -class ANNkd_node; // generic node in a kd-tree -typedef ANNkd_node* ANNkd_ptr; // pointer to a kd-tree node - -class DLL_API ANNkd_tree: public ANNpointSet { -protected: - int dim; // dimension of space - int n_pts; // number of points in tree - int bkt_size; // bucket size - ANNpointArray pts; // the points - ANNidxArray pidx; // point indices (to pts array) - ANNkd_ptr root; // root of kd-tree - ANNpoint bnd_box_lo; // bounding box low point - ANNpoint bnd_box_hi; // bounding box high point - - void SkeletonTree( // construct skeleton tree - int n, // number of points - int dd, // dimension - int bs, // bucket size - ANNpointArray pa = NULL, // point array (optional) - ANNidxArray pi = NULL); // point indices (optional) - -public: - ANNkd_tree( // build skeleton tree - int n = 0, // number of points - int dd = 0, // dimension - int bs = 1); // bucket size - - ANNkd_tree( // build from point array - ANNpointArray pa, // point array - int n, // number of points - int dd, // dimension - int bs = 1, // bucket size - ANNsplitRule split = ANN_KD_SUGGEST); // splitting method - - ANNkd_tree( // build from dump file - std::istream& in); // input stream for dump file - - ~ANNkd_tree(); // tree destructor - - void annkSearch( // approx k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (modified) - ANNdistArray dd, // dist to near neighbors (modified) - double eps=0.0); // error bound - - void annkPriSearch( // priority k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (modified) - ANNdistArray dd, // dist to near neighbors (modified) - double eps=0.0); // error bound - - int annkFRSearch( // approx fixed-radius kNN search - ANNpoint q, // the query point - ANNdist sqRad, // squared radius of query ball - int k, // number of neighbors to return - ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) - ANNdistArray dd = NULL, // dist to near neighbors (modified) - double eps=0.0); // error bound - - int theDim() // return dimension of space - { return dim; } - - int nPoints() // return number of points - { return n_pts; } - - ANNpointArray thePoints() // return pointer to points - { return pts; } - - virtual void Print( // print the tree (for debugging) - ANNbool with_pts, // print points as well? - std::ostream& out); // output stream - - virtual void Dump( // dump entire tree - ANNbool with_pts, // print points as well? - std::ostream& out); // output stream - - virtual void getStats( // compute tree statistics - ANNkdStats& st); // the statistics (modified) -}; - -//---------------------------------------------------------------------- -// Box decomposition tree (bd-tree) -// The bd-tree is inherited from a kd-tree. The main difference -// in the bd-tree and the kd-tree is a new type of internal node -// called a shrinking node (in the kd-tree there is only one type -// of internal node, a splitting node). The shrinking node -// makes it possible to generate balanced trees in which the -// cells have bounded aspect ratio, by allowing the decomposition -// to zoom in on regions of dense point concentration. Although -// this is a nice idea in theory, few point distributions are so -// densely clustered that this is really needed. -//---------------------------------------------------------------------- - -class DLL_API ANNbd_tree: public ANNkd_tree { -public: - ANNbd_tree( // build skeleton tree - int n, // number of points - int dd, // dimension - int bs = 1) // bucket size - : ANNkd_tree(n, dd, bs) {} // build base kd-tree - - ANNbd_tree( // build from point array - ANNpointArray pa, // point array - int n, // number of points - int dd, // dimension - int bs = 1, // bucket size - ANNsplitRule split = ANN_KD_SUGGEST, // splitting rule - ANNshrinkRule shrink = ANN_BD_SUGGEST); // shrinking rule - - ANNbd_tree( // build from dump file - std::istream& in); // input stream for dump file -}; - -//---------------------------------------------------------------------- -// Other functions -// annMaxPtsVisit Sets a limit on the maximum number of points -// to visit in the search. -// annClose Can be called when all use of ANN is finished. -// It clears up a minor memory leak. -//---------------------------------------------------------------------- - -DLL_API void annMaxPtsVisit( // max. pts to visit in search - int maxPts); // the limit - -DLL_API void annClose(); // called to end use of ANN - -#endif diff --git a/ANN/include/ANN/ANNperf.h b/ANN/include/ANN/ANNperf.h deleted file mode 100644 index b18c81658d..0000000000 --- a/ANN/include/ANN/ANNperf.h +++ /dev/null @@ -1,226 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANNperf.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Include file for ANN performance stats -// -// Some of the code for statistics gathering has been adapted -// from the SmplStat.h package in the g++ library. -//---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). -// -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Added ANN_ prefix to avoid name conflicts. -//---------------------------------------------------------------------- - -#ifndef ANNperf_H -#define ANNperf_H - -//---------------------------------------------------------------------- -// basic includes -//---------------------------------------------------------------------- - -#include <ANN/ANN.h> // basic ANN includes - -//---------------------------------------------------------------------- -// kd-tree stats object -// This object is used for collecting information about a kd-tree -// or bd-tree. -//---------------------------------------------------------------------- - -class ANNkdStats { // stats on kd-tree -public: - int dim; // dimension of space - int n_pts; // no. of points - int bkt_size; // bucket size - int n_lf; // no. of leaves (including trivial) - int n_tl; // no. of trivial leaves (no points) - int n_spl; // no. of splitting nodes - int n_shr; // no. of shrinking nodes (for bd-trees) - int depth; // depth of tree - float sum_ar; // sum of leaf aspect ratios - float avg_ar; // average leaf aspect ratio - // - // reset stats - void reset(int d=0, int n=0, int bs=0) - { - dim = d; n_pts = n; bkt_size = bs; - n_lf = n_tl = n_spl = n_shr = depth = 0; - sum_ar = avg_ar = 0.0; - } - - ANNkdStats() // basic constructor - { reset(); } - - void merge(const ANNkdStats &st); // merge stats from child -}; - -//---------------------------------------------------------------------- -// ANNsampStat -// A sample stat collects numeric (double) samples and returns some -// simple statistics. Its main functions are: -// -// reset() Reset to no samples. -// += x Include sample x. -// samples() Return number of samples. -// mean() Return mean of samples. -// stdDev() Return standard deviation -// min() Return minimum of samples. -// max() Return maximum of samples. -//---------------------------------------------------------------------- -class DLL_API ANNsampStat { - int n; // number of samples - double sum; // sum - double sum2; // sum of squares - double minVal, maxVal; // min and max -public : - void reset() // reset everything - { - n = 0; - sum = sum2 = 0; - minVal = ANN_DBL_MAX; - maxVal = -ANN_DBL_MAX; - } - - ANNsampStat() { reset(); } // constructor - - void operator+=(double x) // add sample - { - n++; sum += x; sum2 += x*x; - if (x < minVal) minVal = x; - if (x > maxVal) maxVal = x; - } - - int samples() { return n; } // number of samples - - double mean() { return sum/n; } // mean - - // standard deviation - double stdDev() { return sqrt((sum2 - (sum*sum)/n)/(n-1));} - - double min() { return minVal; } // minimum - double max() { return maxVal; } // maximum -}; - -//---------------------------------------------------------------------- -// Operation count updates -//---------------------------------------------------------------------- - -#ifdef ANN_PERF - #define ANN_FLOP(n) {ann_Nfloat_ops += (n);} - #define ANN_LEAF(n) {ann_Nvisit_lfs += (n);} - #define ANN_SPL(n) {ann_Nvisit_spl += (n);} - #define ANN_SHR(n) {ann_Nvisit_shr += (n);} - #define ANN_PTS(n) {ann_Nvisit_pts += (n);} - #define ANN_COORD(n) {ann_Ncoord_hts += (n);} -#else - #define ANN_FLOP(n) - #define ANN_LEAF(n) - #define ANN_SPL(n) - #define ANN_SHR(n) - #define ANN_PTS(n) - #define ANN_COORD(n) -#endif - -//---------------------------------------------------------------------- -// Performance statistics -// The following data and routines are used for computing performance -// statistics for nearest neighbor searching. Because these routines -// can slow the code down, they can be activated and deactiviated by -// defining the ANN_PERF variable, by compiling with the option: -// -DANN_PERF -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Global counters for performance measurement -// -// visit_lfs The number of leaf nodes visited in the -// tree. -// -// visit_spl The number of splitting nodes visited in the -// tree. -// -// visit_shr The number of shrinking nodes visited in the -// tree. -// -// visit_pts The number of points visited in all the -// leaf nodes visited. Equivalently, this -// is the number of points for which distance -// calculations are performed. -// -// coord_hts The number of times a coordinate of a -// data point is accessed. This is generally -// less than visit_pts*d if partial distance -// calculation is used. This count is low -// in the sense that if a coordinate is hit -// many times in the same routine we may -// count it only once. -// -// float_ops The number of floating point operations. -// This includes all operations in the heap -// as well as distance calculations to boxes. -// -// average_err The average error of each query (the -// error of the reported point to the true -// nearest neighbor). For k nearest neighbors -// the error is computed k times. -// -// rank_err The rank error of each query (the difference -// in the rank of the reported point and its -// true rank). -// -// data_pts The number of data points. This is not -// a counter, but used in stats computation. -//---------------------------------------------------------------------- - -extern int ann_Ndata_pts; // number of data points -extern int ann_Nvisit_lfs; // number of leaf nodes visited -extern int ann_Nvisit_spl; // number of splitting nodes visited -extern int ann_Nvisit_shr; // number of shrinking nodes visited -extern int ann_Nvisit_pts; // visited points for one query -extern int ann_Ncoord_hts; // coordinate hits for one query -extern int ann_Nfloat_ops; // floating ops for one query -extern ANNsampStat ann_visit_lfs; // stats on leaf nodes visits -extern ANNsampStat ann_visit_spl; // stats on splitting nodes visits -extern ANNsampStat ann_visit_shr; // stats on shrinking nodes visits -extern ANNsampStat ann_visit_nds; // stats on total nodes visits -extern ANNsampStat ann_visit_pts; // stats on points visited -extern ANNsampStat ann_coord_hts; // stats on coordinate hits -extern ANNsampStat ann_float_ops; // stats on floating ops -//---------------------------------------------------------------------- -// The following need to be part of the public interface, because -// they are accessed outside the DLL in ann_test.cpp. -//---------------------------------------------------------------------- -DLL_API extern ANNsampStat ann_average_err; // average error -DLL_API extern ANNsampStat ann_rank_err; // rank error - -//---------------------------------------------------------------------- -// Declaration of externally accessible routines for statistics -//---------------------------------------------------------------------- - -DLL_API void annResetStats(int data_size); // reset stats for a set of queries - -DLL_API void annResetCounts(); // reset counts for one queries - -DLL_API void annUpdateStats(); // update stats with current counts - -DLL_API void annPrintStats(ANNbool validate); // print statistics for a run - -#endif diff --git a/ANN/include/ANN/ANNx.h b/ANN/include/ANN/ANNx.h deleted file mode 100644 index 38b07b76fa..0000000000 --- a/ANN/include/ANN/ANNx.h +++ /dev/null @@ -1,170 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANNx.h -// Programmer: Sunil Arya and David Mount -// Last modified: 03/04/98 (Release 0.1) -// Description: Internal include file for ANN -// -// These declarations are of use in manipulating some of -// the internal data objects appearing in ANN, but are not -// needed for applications just using the nearest neighbor -// search. -// -// Typical users of ANN should not need to access this file. -//---------------------------------------------------------------------- -// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David -// Mount. All Rights Reserved. -// -// This software and related documentation is part of the -// Approximate Nearest Neighbor Library (ANN). -// -// Permission to use, copy, and distribute this software and its -// documentation is hereby granted free of charge, provided that -// (1) it is not a component of a commercial product, and -// (2) this notice appears in all copies of the software and -// related documentation. -// -// The University of Maryland (U.M.) and the authors make no representations -// about the suitability or fitness of this software for any purpose. It is -// provided "as is" without express or implied warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Changed LO, HI, IN, OUT to ANN_LO, ANN_HI, etc. -//---------------------------------------------------------------------- - -#ifndef ANNx_H -#define ANNx_H - -#include <iomanip> // I/O manipulators -#include <ANN/ANN.h> // ANN includes - -//---------------------------------------------------------------------- -// Global constants and types -//---------------------------------------------------------------------- -enum {ANN_LO=0, ANN_HI=1}; // splitting indices -enum {ANN_IN=0, ANN_OUT=1}; // shrinking indices - // what to do in case of error -enum ANNerr {ANNwarn = 0, ANNabort = 1}; - -//---------------------------------------------------------------------- -// Maximum number of points to visit -// We have an option for terminating the search early if the -// number of points visited exceeds some threshold. If the -// threshold is 0 (its default) this means there is no limit -// and the algorithm applies its normal termination condition. -//---------------------------------------------------------------------- - -extern int ANNmaxPtsVisited; // maximum number of pts visited -extern int ANNptsVisited; // number of pts visited in search - -//---------------------------------------------------------------------- -// Global function declarations -//---------------------------------------------------------------------- - -void annError( // ANN error routine - char *msg, // error message - ANNerr level); // level of error - -void annPrintPt( // print a point - ANNpoint pt, // the point - int dim, // the dimension - std::ostream &out); // output stream - -//---------------------------------------------------------------------- -// Orthogonal (axis aligned) rectangle -// Orthogonal rectangles are represented by two points, one -// for the lower left corner (min coordinates) and the other -// for the upper right corner (max coordinates). -// -// The constructor initializes from either a pair of coordinates, -// pair of points, or another rectangle. Note that all constructors -// allocate new point storage. The destructor deallocates this -// storage. -// -// BEWARE: Orthogonal rectangles should be passed ONLY BY REFERENCE. -// (C++'s default copy constructor will not allocate new point -// storage, then on return the destructor free's storage, and then -// you get into big trouble in the calling procedure.) -//---------------------------------------------------------------------- - -class ANNorthRect { -public: - ANNpoint lo; // rectangle lower bounds - ANNpoint hi; // rectangle upper bounds -// - ANNorthRect( // basic constructor - int dd, // dimension of space - ANNcoord l=0, // default is empty - ANNcoord h=0) - { lo = annAllocPt(dd, l); hi = annAllocPt(dd, h); } - - ANNorthRect( // (almost a) copy constructor - int dd, // dimension - const ANNorthRect &r) // rectangle to copy - { lo = annCopyPt(dd, r.lo); hi = annCopyPt(dd, r.hi); } - - ANNorthRect( // construct from points - int dd, // dimension - ANNpoint l, // low point - ANNpoint h) // hight point - { lo = annCopyPt(dd, l); hi = annCopyPt(dd, h); } - - ~ANNorthRect() // destructor - { annDeallocPt(lo); annDeallocPt(hi); } - - ANNbool inside(int dim, ANNpoint p);// is point p inside rectangle? -}; - -void annAssignRect( // assign one rect to another - int dim, // dimension (both must be same) - ANNorthRect &dest, // destination (modified) - const ANNorthRect &source); // source - -//---------------------------------------------------------------------- -// Orthogonal (axis aligned) halfspace -// An orthogonal halfspace is represented by an integer cutting -// dimension cd, coordinate cutting value, cv, and side, sd, which is -// either +1 or -1. Our convention is that point q lies in the (closed) -// halfspace if (q[cd] - cv)*sd >= 0. -//---------------------------------------------------------------------- - -class ANNorthHalfSpace { -public: - int cd; // cutting dimension - ANNcoord cv; // cutting value - int sd; // which side -// - ANNorthHalfSpace() // default constructor - { cd = 0; cv = 0; sd = 0; } - - ANNorthHalfSpace( // basic constructor - int cdd, // dimension of space - ANNcoord cvv, // cutting value - int sdd) // side - { cd = cdd; cv = cvv; sd = sdd; } - - ANNbool in(ANNpoint q) const // is q inside halfspace? - { return (ANNbool) ((q[cd] - cv)*sd >= 0); } - - ANNbool out(ANNpoint q) const // is q outside halfspace? - { return (ANNbool) ((q[cd] - cv)*sd < 0); } - - ANNdist dist(ANNpoint q) const // (squared) distance from q - { return (ANNdist) ANN_POW(q[cd] - cv); } - - void setLowerBound(int d, ANNpoint p)// set to lower bound at p[i] - { cd = d; cv = p[d]; sd = +1; } - - void setUpperBound(int d, ANNpoint p)// set to upper bound at p[i] - { cd = d; cv = p[d]; sd = -1; } - - void project(ANNpoint &q) // project q (modified) onto halfspace - { if (out(q)) q[cd] = cv; } -}; - - // array of halfspaces -typedef ANNorthHalfSpace *ANNorthHSArray; - -#endif diff --git a/ANN/src/ANN.cpp b/ANN/src/ANN.cpp deleted file mode 100644 index 82f90f54af..0000000000 --- a/ANN/src/ANN.cpp +++ /dev/null @@ -1,198 +0,0 @@ -//---------------------------------------------------------------------- -// File: ANN.cpp -// Programmer: Sunil Arya and David Mount -// Description: Methods for ANN.h and ANNx.h -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Added performance counting to annDist() -//---------------------------------------------------------------------- - -#include <ANN/ANNx.h> // all ANN includes -#include <ANN/ANNperf.h> // ANN performance - -using namespace std; // make std:: accessible - -//---------------------------------------------------------------------- -// Point methods -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Distance utility. -// (Note: In the nearest neighbor search, most distances are -// computed using partial distance calculations, not this -// procedure.) -//---------------------------------------------------------------------- - -ANNdist annDist( // interpoint squared distance - int dim, - ANNpoint p, - ANNpoint q) -{ - register int d; - register ANNcoord diff; - register ANNcoord dist; - - dist = 0; - for (d = 0; d < dim; d++) { - diff = p[d] - q[d]; - dist = ANN_SUM(dist, ANN_POW(diff)); - } - ANN_FLOP(3*dim) // performance counts - ANN_PTS(1) - ANN_COORD(dim) - return dist; -} - -//---------------------------------------------------------------------- -// annPrintPoint() prints a point to a given output stream. -//---------------------------------------------------------------------- - -void annPrintPt( // print a point - ANNpoint pt, // the point - int dim, // the dimension - std::ostream &out) // output stream -{ - for (int j = 0; j < dim; j++) { - out << pt[j]; - if (j < dim-1) out << " "; - } -} - -//---------------------------------------------------------------------- -// Point allocation/deallocation: -// -// Because points (somewhat like strings in C) are stored -// as pointers. Consequently, creating and destroying -// copies of points may require storage allocation. These -// procedures do this. -// -// annAllocPt() and annDeallocPt() allocate a deallocate -// storage for a single point, and return a pointer to it. -// -// annAllocPts() allocates an array of points as well a place -// to store their coordinates, and initializes the points to -// point to their respective coordinates. It allocates point -// storage in a contiguous block large enough to store all the -// points. It performs no initialization. -// -// annDeallocPts() should only be used on point arrays allocated -// by annAllocPts since it assumes that points are allocated in -// a block. -// -// annCopyPt() copies a point taking care to allocate storage -// for the new point. -// -// annAssignRect() assigns the coordinates of one rectangle to -// another. The two rectangles must have the same dimension -// (and it is not possible to test this here). -//---------------------------------------------------------------------- - -ANNpoint annAllocPt(int dim, ANNcoord c) // allocate 1 point -{ - ANNpoint p = new ANNcoord[dim]; - for (int i = 0; i < dim; i++) p[i] = c; - return p; -} - -ANNpointArray annAllocPts(int n, int dim) // allocate n pts in dim -{ - ANNpointArray pa = new ANNpoint[n]; // allocate points - ANNpoint p = new ANNcoord[n*dim]; // allocate space for coords - for (int i = 0; i < n; i++) { - pa[i] = &(p[i*dim]); - } - return pa; -} - -void annDeallocPt(ANNpoint &p) // deallocate 1 point -{ - delete [] p; - p = NULL; -} - -void annDeallocPts(ANNpointArray &pa) // deallocate points -{ - delete [] pa[0]; // dealloc coordinate storage - delete [] pa; // dealloc points - pa = NULL; -} - -ANNpoint annCopyPt(int dim, ANNpoint source) // copy point -{ - ANNpoint p = new ANNcoord[dim]; - for (int i = 0; i < dim; i++) p[i] = source[i]; - return p; -} - - // assign one rect to another -void annAssignRect(int dim, ANNorthRect &dest, const ANNorthRect &source) -{ - for (int i = 0; i < dim; i++) { - dest.lo[i] = source.lo[i]; - dest.hi[i] = source.hi[i]; - } -} - - // is point inside rectangle? -ANNbool ANNorthRect::inside(int dim, ANNpoint p) -{ - for (int i = 0; i < dim; i++) { - if (p[i] < lo[i] || p[i] > hi[i]) return ANNfalse; - } - return ANNtrue; -} - -//---------------------------------------------------------------------- -// Error handler -//---------------------------------------------------------------------- - -void annError(char *msg, ANNerr level) -{ - if (level == ANNabort) { - cerr << "ANN: ERROR------->" << msg << "<-------------ERROR\n"; - exit(1); - } - else { - cerr << "ANN: WARNING----->" << msg << "<-------------WARNING\n"; - } -} - -//---------------------------------------------------------------------- -// Limit on number of points visited -// We have an option for terminating the search early if the -// number of points visited exceeds some threshold. If the -// threshold is 0 (its default) this means there is no limit -// and the algorithm applies its normal termination condition. -// This is for applications where there are real time constraints -// on the running time of the algorithm. -//---------------------------------------------------------------------- - -int ANNmaxPtsVisited = 0; // maximum number of pts visited -int ANNptsVisited; // number of pts visited in search - -//---------------------------------------------------------------------- -// Global function declarations -//---------------------------------------------------------------------- - -void annMaxPtsVisit( // set limit on max. pts to visit in search - int maxPts) // the limit -{ - ANNmaxPtsVisited = maxPts; -} diff --git a/ANN/src/bd_fix_rad_search.cpp b/ANN/src/bd_fix_rad_search.cpp deleted file mode 100644 index dea3f6bdf1..0000000000 --- a/ANN/src/bd_fix_rad_search.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//---------------------------------------------------------------------- -// File: bd_fix_rad_search.cpp -// Programmer: David Mount -// Description: Standard bd-tree search -// Last modified: 05/03/05 (Version 1.1) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 1.1 05/03/05 -// Initial release -//---------------------------------------------------------------------- - -#include "bd_tree.h" // bd-tree declarations -#include "kd_fix_rad_search.h" // kd-tree FR search declarations - -//---------------------------------------------------------------------- -// Approximate searching for bd-trees. -// See the file kd_FR_search.cpp for general information on the -// approximate nearest neighbor search algorithm. Here we -// include the extensions for shrinking nodes. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// bd_shrink::ann_FR_search - search a shrinking node -//---------------------------------------------------------------------- - -void ANNbd_shrink::ann_FR_search(ANNdist box_dist) -{ - // check dist calc term cond. - if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; - - ANNdist inner_dist = 0; // distance to inner box - for (int i = 0; i < n_bnds; i++) { // is query point in the box? - if (bnds[i].out(ANNkdFRQ)) { // outside this bounding side? - // add to inner distance - inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdFRQ)); - } - } - if (inner_dist <= box_dist) { // if inner box is closer - child[ANN_IN]->ann_FR_search(inner_dist);// search inner child first - child[ANN_OUT]->ann_FR_search(box_dist);// ...then outer child - } - else { // if outer box is closer - child[ANN_OUT]->ann_FR_search(box_dist);// search outer child first - child[ANN_IN]->ann_FR_search(inner_dist);// ...then outer child - } - ANN_FLOP(3*n_bnds) // increment floating ops - ANN_SHR(1) // one more shrinking node -} diff --git a/ANN/src/bd_pr_search.cpp b/ANN/src/bd_pr_search.cpp deleted file mode 100644 index d16d632945..0000000000 --- a/ANN/src/bd_pr_search.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//---------------------------------------------------------------------- -// File: bd_pr_search.cpp -// Programmer: David Mount -// Description: Priority search for bd-trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -//History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#include "bd_tree.h" // bd-tree declarations -#include "kd_pr_search.h" // kd priority search declarations - -//---------------------------------------------------------------------- -// Approximate priority searching for bd-trees. -// See the file kd_pr_search.cc for general information on the -// approximate nearest neighbor priority search algorithm. Here -// we include the extensions for shrinking nodes. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// bd_shrink::ann_search - search a shrinking node -//---------------------------------------------------------------------- - -void ANNbd_shrink::ann_pri_search(ANNdist box_dist) -{ - ANNdist inner_dist = 0; // distance to inner box - for (int i = 0; i < n_bnds; i++) { // is query point in the box? - if (bnds[i].out(ANNprQ)) { // outside this bounding side? - // add to inner distance - inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNprQ)); - } - } - if (inner_dist <= box_dist) { // if inner box is closer - if (child[ANN_OUT] != KD_TRIVIAL) // enqueue outer if not trivial - ANNprBoxPQ->insert(box_dist,child[ANN_OUT]); - // continue with inner child - child[ANN_IN]->ann_pri_search(inner_dist); - } - else { // if outer box is closer - if (child[ANN_IN] != KD_TRIVIAL) // enqueue inner if not trivial - ANNprBoxPQ->insert(inner_dist,child[ANN_IN]); - // continue with outer child - child[ANN_OUT]->ann_pri_search(box_dist); - } - ANN_FLOP(3*n_bnds) // increment floating ops - ANN_SHR(1) // one more shrinking node -} diff --git a/ANN/src/bd_search.cpp b/ANN/src/bd_search.cpp deleted file mode 100644 index f057018a28..0000000000 --- a/ANN/src/bd_search.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//---------------------------------------------------------------------- -// File: bd_search.cpp -// Programmer: David Mount -// Description: Standard bd-tree search -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#include "bd_tree.h" // bd-tree declarations -#include "kd_search.h" // kd-tree search declarations - -//---------------------------------------------------------------------- -// Approximate searching for bd-trees. -// See the file kd_search.cpp for general information on the -// approximate nearest neighbor search algorithm. Here we -// include the extensions for shrinking nodes. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// bd_shrink::ann_search - search a shrinking node -//---------------------------------------------------------------------- - -void ANNbd_shrink::ann_search(ANNdist box_dist) -{ - // check dist calc term cond. - if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; - - ANNdist inner_dist = 0; // distance to inner box - for (int i = 0; i < n_bnds; i++) { // is query point in the box? - if (bnds[i].out(ANNkdQ)) { // outside this bounding side? - // add to inner distance - inner_dist = (ANNdist) ANN_SUM(inner_dist, bnds[i].dist(ANNkdQ)); - } - } - if (inner_dist <= box_dist) { // if inner box is closer - child[ANN_IN]->ann_search(inner_dist); // search inner child first - child[ANN_OUT]->ann_search(box_dist); // ...then outer child - } - else { // if outer box is closer - child[ANN_OUT]->ann_search(box_dist); // search outer child first - child[ANN_IN]->ann_search(inner_dist); // ...then outer child - } - ANN_FLOP(3*n_bnds) // increment floating ops - ANN_SHR(1) // one more shrinking node -} diff --git a/ANN/src/bd_tree.cpp b/ANN/src/bd_tree.cpp deleted file mode 100644 index 0977dea96f..0000000000 --- a/ANN/src/bd_tree.cpp +++ /dev/null @@ -1,417 +0,0 @@ -//---------------------------------------------------------------------- -// File: bd_tree.cpp -// Programmer: David Mount -// Description: Basic methods for bd-trees. -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision l.0 04/01/05 -// Fixed centroid shrink threshold condition to depend on the -// dimension. -// Moved dump routine to kd_dump.cpp. -//---------------------------------------------------------------------- - -#include "bd_tree.h" // bd-tree declarations -#include "kd_util.h" // kd-tree utilities -#include "kd_split.h" // kd-tree splitting rules - -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// Printing a bd-tree -// These routines print a bd-tree. See the analogous procedure -// in kd_tree.cpp for more information. -//---------------------------------------------------------------------- - -void ANNbd_shrink::print( // print shrinking node - int level, // depth of node in tree - ostream &out) // output stream -{ - child[ANN_OUT]->print(level+1, out); // print out-child - - out << " "; - for (int i = 0; i < level; i++) // print indentation - out << ".."; - out << "Shrink"; - for (int j = 0; j < n_bnds; j++) { // print sides, 2 per line - if (j % 2 == 0) { - out << "\n"; // newline and indentation - for (int i = 0; i < level+2; i++) out << " "; - } - out << " ([" << bnds[j].cd << "]" - << (bnds[j].sd > 0 ? ">=" : "< ") - << bnds[j].cv << ")"; - } - out << "\n"; - - child[ANN_IN]->print(level+1, out); // print in-child -} - -//---------------------------------------------------------------------- -// kd_tree statistics utility (for performance evaluation) -// This routine computes various statistics information for -// shrinking nodes. See file kd_tree.cpp for more information. -//---------------------------------------------------------------------- - -void ANNbd_shrink::getStats( // get subtree statistics - int dim, // dimension of space - ANNkdStats &st, // stats (modified) - ANNorthRect &bnd_box) // bounding box -{ - ANNkdStats ch_stats; // stats for children - ANNorthRect inner_box(dim); // inner box of shrink - - annBnds2Box(bnd_box, // enclosing box - dim, // dimension - n_bnds, // number of bounds - bnds, // bounds array - inner_box); // inner box (modified) - // get stats for inner child - ch_stats.reset(); // reset - child[ANN_IN]->getStats(dim, ch_stats, inner_box); - st.merge(ch_stats); // merge them - // get stats for outer child - ch_stats.reset(); // reset - child[ANN_OUT]->getStats(dim, ch_stats, bnd_box); - st.merge(ch_stats); // merge them - - st.depth++; // increment depth - st.n_shr++; // increment number of shrinks -} - -//---------------------------------------------------------------------- -// bd-tree constructor -// This is the main constructor for bd-trees given a set of points. -// It first builds a skeleton kd-tree as a basis, then computes the -// bounding box of the data points, and then invokes rbd_tree() to -// actually build the tree, passing it the appropriate splitting -// and shrinking information. -//---------------------------------------------------------------------- - -ANNkd_ptr rbd_tree( // recursive construction of bd-tree - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - int bsp, // bucket space - ANNorthRect &bnd_box, // bounding box for current node - ANNkd_splitter splitter, // splitting routine - ANNshrinkRule shrink); // shrinking rule - -ANNbd_tree::ANNbd_tree( // construct from point array - ANNpointArray pa, // point array (with at least n pts) - int n, // number of points - int dd, // dimension - int bs, // bucket size - ANNsplitRule split, // splitting rule - ANNshrinkRule shrink) // shrinking rule - : ANNkd_tree(n, dd, bs) // build skeleton base tree -{ - pts = pa; // where the points are - if (n == 0) return; // no points--no sweat - - ANNorthRect bnd_box(dd); // bounding box for points - // construct bounding rectangle - annEnclRect(pa, pidx, n, dd, bnd_box); - // copy to tree structure - bnd_box_lo = annCopyPt(dd, bnd_box.lo); - bnd_box_hi = annCopyPt(dd, bnd_box.hi); - - switch (split) { // build by rule - case ANN_KD_STD: // standard kd-splitting rule - root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split, shrink); - break; - case ANN_KD_MIDPT: // midpoint split - root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split, shrink); - break; - case ANN_KD_SUGGEST: // best (in our opinion) - case ANN_KD_SL_MIDPT: // sliding midpoint split - root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split, shrink); - break; - case ANN_KD_FAIR: // fair split - root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split, shrink); - break; - case ANN_KD_SL_FAIR: // sliding fair split - root = rbd_tree(pa, pidx, n, dd, bs, - bnd_box, sl_fair_split, shrink); - break; - default: - annError("Illegal splitting method", ANNabort); - } -} - -//---------------------------------------------------------------------- -// Shrinking rules -//---------------------------------------------------------------------- - -enum ANNdecomp {SPLIT, SHRINK}; // decomposition methods - -//---------------------------------------------------------------------- -// trySimpleShrink - Attempt a simple shrink -// -// We compute the tight bounding box of the points, and compute -// the 2*dim ``gaps'' between the sides of the tight box and the -// bounding box. If any of the gaps is large enough relative to -// the longest side of the tight bounding box, then we shrink -// all sides whose gaps are large enough. (The reason for -// comparing against the tight bounding box, is that after -// shrinking the longest box size will decrease, and if we use -// the standard bounding box, we may decide to shrink twice in -// a row. Since the tight box is fixed, we cannot shrink twice -// consecutively.) -//---------------------------------------------------------------------- -const float BD_GAP_THRESH = 0.5; // gap threshold (must be < 1) -const int BD_CT_THRESH = 2; // min number of shrink sides - -ANNdecomp trySimpleShrink( // try a simple shrink - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - const ANNorthRect &bnd_box, // current bounding box - ANNorthRect &inner_box) // inner box if shrinking (returned) -{ - int i; - // compute tight bounding box - annEnclRect(pa, pidx, n, dim, inner_box); - - ANNcoord max_length = 0; // find longest box side - for (i = 0; i < dim; i++) { - ANNcoord length = inner_box.hi[i] - inner_box.lo[i]; - if (length > max_length) { - max_length = length; - } - } - - int shrink_ct = 0; // number of sides we shrunk - for (i = 0; i < dim; i++) { // select which sides to shrink - // gap between boxes - ANNcoord gap_hi = bnd_box.hi[i] - inner_box.hi[i]; - // big enough gap to shrink? - if (gap_hi < max_length*BD_GAP_THRESH) - inner_box.hi[i] = bnd_box.hi[i]; // no - expand - else shrink_ct++; // yes - shrink this side - - // repeat for high side - ANNcoord gap_lo = inner_box.lo[i] - bnd_box.lo[i]; - if (gap_lo < max_length*BD_GAP_THRESH) - inner_box.lo[i] = bnd_box.lo[i]; // no - expand - else shrink_ct++; // yes - shrink this side - } - - if (shrink_ct >= BD_CT_THRESH) // did we shrink enough sides? - return SHRINK; - else return SPLIT; -} - -//---------------------------------------------------------------------- -// tryCentroidShrink - Attempt a centroid shrink -// -// We repeatedly apply the splitting rule, always to the larger subset -// of points, until the number of points decreases by the constant -// fraction BD_FRACTION. If this takes more than dim*BD_MAX_SPLIT_FAC -// splits for this to happen, then we shrink to the final inner box -// Otherwise we split. -//---------------------------------------------------------------------- - -const float BD_MAX_SPLIT_FAC = 0.5; // maximum number of splits allowed -const float BD_FRACTION = 0.5; // ...to reduce points by this fraction - // ...This must be < 1. - -ANNdecomp tryCentroidShrink( // try a centroid shrink - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - const ANNorthRect &bnd_box, // current bounding box - ANNkd_splitter splitter, // splitting procedure - ANNorthRect &inner_box) // inner box if shrinking (returned) -{ - int n_sub = n; // number of points in subset - int n_goal = (int) (n*BD_FRACTION); // number of point in goal - int n_splits = 0; // number of splits needed - // initialize inner box to bounding box - annAssignRect(dim, inner_box, bnd_box); - - while (n_sub > n_goal) { // keep splitting until goal reached - int cd; // cut dim from splitter (ignored) - ANNcoord cv; // cut value from splitter (ignored) - int n_lo; // number of points on low side - // invoke splitting procedure - (*splitter)(pa, pidx, inner_box, n_sub, dim, cd, cv, n_lo); - n_splits++; // increment split count - - if (n_lo >= n_sub/2) { // most points on low side - inner_box.hi[cd] = cv; // collapse high side - n_sub = n_lo; // recurse on lower points - } - else { // most points on high side - inner_box.lo[cd] = cv; // collapse low side - pidx += n_lo; // recurse on higher points - n_sub -= n_lo; - } - } - if (n_splits > dim*BD_MAX_SPLIT_FAC)// took too many splits - return SHRINK; // shrink to final subset - else - return SPLIT; -} - -//---------------------------------------------------------------------- -// selectDecomp - select which decomposition to use -//---------------------------------------------------------------------- - -ANNdecomp selectDecomp( // select decomposition method - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - const ANNorthRect &bnd_box, // current bounding box - ANNkd_splitter splitter, // splitting procedure - ANNshrinkRule shrink, // shrinking rule - ANNorthRect &inner_box) // inner box if shrinking (returned) -{ - ANNdecomp decomp = SPLIT; // decomposition - - switch (shrink) { // check shrinking rule - case ANN_BD_NONE: // no shrinking allowed - decomp = SPLIT; - break; - case ANN_BD_SUGGEST: // author's suggestion - case ANN_BD_SIMPLE: // simple shrink - decomp = trySimpleShrink( - pa, pidx, // points and indices - n, dim, // number of points and dimension - bnd_box, // current bounding box - inner_box); // inner box if shrinking (returned) - break; - case ANN_BD_CENTROID: // centroid shrink - decomp = tryCentroidShrink( - pa, pidx, // points and indices - n, dim, // number of points and dimension - bnd_box, // current bounding box - splitter, // splitting procedure - inner_box); // inner box if shrinking (returned) - break; - default: - annError("Illegal shrinking rule", ANNabort); - } - return decomp; -} - -//---------------------------------------------------------------------- -// rbd_tree - recursive procedure to build a bd-tree -// -// This is analogous to rkd_tree, but for bd-trees. See the -// procedure rkd_tree() in kd_split.cpp for more information. -// -// If the number of points falls below the bucket size, then a -// leaf node is created for the points. Otherwise we invoke the -// procedure selectDecomp() which determines whether we are to -// split or shrink. If splitting is chosen, then we essentially -// do exactly as rkd_tree() would, and invoke the specified -// splitting procedure to the points. Otherwise, the selection -// procedure returns a bounding box, from which we extract the -// appropriate shrinking bounds, and create a shrinking node. -// Finally the points are subdivided, and the procedure is -// invoked recursively on the two subsets to form the children. -//---------------------------------------------------------------------- - -ANNkd_ptr rbd_tree( // recursive construction of bd-tree - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - int bsp, // bucket space - ANNorthRect &bnd_box, // bounding box for current node - ANNkd_splitter splitter, // splitting routine - ANNshrinkRule shrink) // shrinking rule -{ - ANNdecomp decomp; // decomposition method - - ANNorthRect inner_box(dim); // inner box (if shrinking) - - if (n <= bsp) { // n small, make a leaf node - if (n == 0) // empty leaf node - return KD_TRIVIAL; // return (canonical) empty leaf - else // construct the node and return - return new ANNkd_leaf(n, pidx); - } - - decomp = selectDecomp( // select decomposition method - pa, pidx, // points and indices - n, dim, // number of points and dimension - bnd_box, // current bounding box - splitter, shrink, // splitting/shrinking methods - inner_box); // inner box if shrinking (returned) - - if (decomp == SPLIT) { // split selected - int cd; // cutting dimension - ANNcoord cv; // cutting value - int n_lo; // number on low side of cut - // invoke splitting procedure - (*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo); - - ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension - ANNcoord hv = bnd_box.hi[cd]; - - bnd_box.hi[cd] = cv; // modify bounds for left subtree - ANNkd_ptr lo = rbd_tree( // build left subtree - pa, pidx, n_lo, // ...from pidx[0..n_lo-1] - dim, bsp, bnd_box, splitter, shrink); - bnd_box.hi[cd] = hv; // restore bounds - - bnd_box.lo[cd] = cv; // modify bounds for right subtree - ANNkd_ptr hi = rbd_tree( // build right subtree - pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1] - dim, bsp, bnd_box, splitter, shrink); - bnd_box.lo[cd] = lv; // restore bounds - // create the splitting node - return new ANNkd_split(cd, cv, lv, hv, lo, hi); - } - else { // shrink selected - int n_in; // number of points in box - int n_bnds; // number of bounding sides - - annBoxSplit( // split points around inner box - pa, // points to split - pidx, // point indices - n, // number of points - dim, // dimension - inner_box, // inner box - n_in); // number of points inside (returned) - - ANNkd_ptr in = rbd_tree( // build inner subtree pidx[0..n_in-1] - pa, pidx, n_in, dim, bsp, inner_box, splitter, shrink); - ANNkd_ptr out = rbd_tree( // build outer subtree pidx[n_in..n] - pa, pidx+n_in, n - n_in, dim, bsp, bnd_box, splitter, shrink); - - ANNorthHSArray bnds = NULL; // bounds (alloc in Box2Bnds and - // ...freed in bd_shrink destroyer) - - annBox2Bnds( // convert inner box to bounds - inner_box, // inner box - bnd_box, // enclosing box - dim, // dimension - n_bnds, // number of bounds (returned) - bnds); // bounds array (modified) - - // return shrinking node - return new ANNbd_shrink(n_bnds, bnds, in, out); - } -} diff --git a/ANN/src/bd_tree.h b/ANN/src/bd_tree.h deleted file mode 100644 index 408889a07d..0000000000 --- a/ANN/src/bd_tree.h +++ /dev/null @@ -1,100 +0,0 @@ -//---------------------------------------------------------------------- -// File: bd_tree.h -// Programmer: David Mount -// Description: Declarations for standard bd-tree routines -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Changed IN, OUT to ANN_IN, ANN_OUT -//---------------------------------------------------------------------- - -#ifndef ANN_bd_tree_H -#define ANN_bd_tree_H - -#include <ANN/ANNx.h> // all ANN includes -#include "kd_tree.h" // kd-tree includes - -//---------------------------------------------------------------------- -// bd-tree shrinking node. -// The main addition in the bd-tree is the shrinking node, which -// is declared here. -// -// Shrinking nodes are defined by list of orthogonal halfspaces. -// These halfspaces define a (possibly unbounded) orthogonal -// rectangle. There are two children, in and out. Points that -// lie within this rectangle are stored in the in-child, and the -// other points are stored in the out-child. -// -// We use a list of orthogonal halfspaces rather than an -// orthogonal rectangle object because typically the number of -// sides of the shrinking box will be much smaller than the -// worst case bound of 2*dim. -// -// BEWARE: Note that constructor just copies the pointer to the -// bounding array, but the destructor deallocates it. This is -// rather poor practice, but happens to be convenient. The list -// is allocated in the bd-tree building procedure rbd_tree() just -// prior to construction, and is used for no other purposes. -// -// WARNING: In the near neighbor searching code it is assumed that -// the list of bounding halfspaces is irredundant, meaning that there -// are no two distinct halfspaces in the list with the same outward -// pointing normals. -//---------------------------------------------------------------------- - -class ANNbd_shrink : public ANNkd_node // splitting node of a kd-tree -{ - int n_bnds; // number of bounding halfspaces - ANNorthHSArray bnds; // list of bounding halfspaces - ANNkd_ptr child[2]; // in and out children -public: - ANNbd_shrink( // constructor - int nb, // number of bounding halfspaces - ANNorthHSArray bds, // list of bounding halfspaces - ANNkd_ptr ic=NULL, ANNkd_ptr oc=NULL) // children - { - n_bnds = nb; // cutting dimension - bnds = bds; // assign bounds - child[ANN_IN] = ic; // set children - child[ANN_OUT] = oc; - } - - ~ANNbd_shrink() // destructor - { - if (child[ANN_IN]!= NULL && child[ANN_IN]!= KD_TRIVIAL) - delete child[ANN_IN]; - if (child[ANN_OUT]!= NULL&& child[ANN_OUT]!= KD_TRIVIAL) - delete child[ANN_OUT]; - if (bnds != NULL) - delete [] bnds; // delete bounds - } - - virtual void getStats( // get tree statistics - int dim, // dimension of space - ANNkdStats &st, // statistics - ANNorthRect &bnd_box); // bounding box - virtual void print(int level, ostream &out);// print node - virtual void dump(ostream &out); // dump node - - virtual void ann_search(ANNdist); // standard search - virtual void ann_pri_search(ANNdist); // priority search - virtual void ann_FR_search(ANNdist); // fixed-radius search -}; - -#endif diff --git a/ANN/src/brute.cpp b/ANN/src/brute.cpp deleted file mode 100644 index d7cba2c7f6..0000000000 --- a/ANN/src/brute.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//---------------------------------------------------------------------- -// File: brute.cpp -// Programmer: Sunil Arya and David Mount -// Description: Brute-force nearest neighbors -// Last modified: 05/03/05 (Version 1.1) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.1 05/03/05 -// Added fixed-radius kNN search -//---------------------------------------------------------------------- - -#include <ANN/ANNx.h> // all ANN includes -#include "pr_queue_k.h" // k element priority queue - -//---------------------------------------------------------------------- -// Brute-force search simply stores a pointer to the list of -// data points and searches linearly for the nearest neighbor. -// The k nearest neighbors are stored in a k-element priority -// queue (which is implemented in a pretty dumb way as well). -// -// If ANN_ALLOW_SELF_MATCH is ANNfalse then data points at distance -// zero are not considered. -// -// Note that the error bound eps is passed in, but it is ignored. -// These routines compute exact nearest neighbors (which is needed -// for validation purposes in ann_test.cpp). -//---------------------------------------------------------------------- - -ANNbruteForce::ANNbruteForce( // constructor from point array - ANNpointArray pa, // point array - int n, // number of points - int dd) // dimension -{ - dim = dd; n_pts = n; pts = pa; -} - -ANNbruteForce::~ANNbruteForce() { } // destructor (empty) - -void ANNbruteForce::annkSearch( // approx k near neighbor search - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor indices (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps) // error bound (ignored) -{ - ANNmin_k mk(k); // construct a k-limited priority queue - int i; - - if (k > n_pts) { // too many near neighbors? - annError("Requesting more near neighbors than data points", ANNabort); - } - // run every point through queue - for (i = 0; i < n_pts; i++) { - // compute distance to point - ANNdist sqDist = annDist(dim, pts[i], q); - if (ANN_ALLOW_SELF_MATCH || sqDist != 0) - mk.insert(sqDist, i); - } - for (i = 0; i < k; i++) { // extract the k closest points - dd[i] = mk.ith_smallest_key(i); - nn_idx[i] = mk.ith_smallest_info(i); - } -} - -int ANNbruteForce::annkFRSearch( // approx fixed-radius kNN search - ANNpoint q, // query point - ANNdist sqRad, // squared radius - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor array (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps) // error bound -{ - ANNmin_k mk(k); // construct a k-limited priority queue - int i; - int pts_in_range = 0; // number of points in query range - // run every point through queue - for (i = 0; i < n_pts; i++) { - // compute distance to point - ANNdist sqDist = annDist(dim, pts[i], q); - if (sqDist <= sqRad && // within radius bound - (ANN_ALLOW_SELF_MATCH || sqDist != 0)) { // ...and no self match - mk.insert(sqDist, i); - pts_in_range++; - } - } - for (i = 0; i < k; i++) { // extract the k closest points - if (dd != NULL) - dd[i] = mk.ith_smallest_key(i); - if (nn_idx != NULL) - nn_idx[i] = mk.ith_smallest_info(i); - } - - return pts_in_range; -} diff --git a/ANN/src/kd_dump.cpp b/ANN/src/kd_dump.cpp deleted file mode 100644 index e7015efe85..0000000000 --- a/ANN/src/kd_dump.cpp +++ /dev/null @@ -1,444 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_dump.cc -// Programmer: David Mount -// Description: Dump and Load for kd- and bd-trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Moved dump out of kd_tree.cc into this file. -// Added kd-tree load constructor. -//---------------------------------------------------------------------- -// This file contains routines for dumping kd-trees and bd-trees and -// reloading them. (It is an abuse of policy to include both kd- and -// bd-tree routines in the same file, sorry. There should be no problem -// in deleting the bd- versions of the routines if they are not -// desired.) -//---------------------------------------------------------------------- - -#include "kd_tree.h" // kd-tree declarations -#include "bd_tree.h" // bd-tree declarations - -using namespace std; // make std:: available - -//---------------------------------------------------------------------- -// Constants -//---------------------------------------------------------------------- - -const int STRING_LEN = 500; // maximum string length -const double EPSILON = 1E-5; // small number for float comparison - -enum ANNtreeType {KD_TREE, BD_TREE}; // tree types (used in loading) - -//---------------------------------------------------------------------- -// Procedure declarations -//---------------------------------------------------------------------- - -static ANNkd_ptr annReadDump( // read dump file - istream &in, // input stream - ANNtreeType tree_type, // type of tree expected - ANNpointArray &the_pts, // new points (if applic) - ANNidxArray &the_pidx, // point indices (returned) - int &the_dim, // dimension (returned) - int &the_n_pts, // number of points (returned) - int &the_bkt_size, // bucket size (returned) - ANNpoint &the_bnd_box_lo, // low bounding point - ANNpoint &the_bnd_box_hi); // high bounding point - -static ANNkd_ptr annReadTree( // read tree-part of dump file - istream &in, // input stream - ANNtreeType tree_type, // type of tree expected - ANNidxArray the_pidx, // point indices (modified) - int &next_idx); // next index (modified) - -//---------------------------------------------------------------------- -// ANN kd- and bd-tree Dump Format -// The dump file begins with a header containing the version of -// ANN, an optional section containing the points, followed by -// a description of the tree. The tree is printed in preorder. -// -// Format: -// #ANN <version number> <comments> [END_OF_LINE] -// points <dim> <n_pts> (point coordinates: this is optional) -// 0 <xxx> <xxx> ... <xxx> (point indices and coordinates) -// 1 <xxx> <xxx> ... <xxx> -// ... -// tree <dim> <n_pts> <bkt_size> -// <xxx> <xxx> ... <xxx> (lower end of bounding box) -// <xxx> <xxx> ... <xxx> (upper end of bounding box) -// If the tree is null, then a single line "null" is -// output. Otherwise the nodes of the tree are printed -// one per line in preorder. Leaves and splitting nodes -// have the following formats: -// Leaf node: -// leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]> -// Splitting nodes: -// split <cut_dim> <cut_val> <lo_bound> <hi_bound> -// -// For bd-trees: -// -// Shrinking nodes: -// shrink <n_bnds> -// <cut_dim> <cut_val> <side> -// <cut_dim> <cut_val> <side> -// ... (repeated n_bnds times) -//---------------------------------------------------------------------- - -void ANNkd_tree::Dump( // dump entire tree - ANNbool with_pts, // print points as well? - ostream &out) // output stream -{ - out << "#ANN " << ANNversion << "\n"; - out.precision(ANNcoordPrec); // use full precision in dumping - if (with_pts) { // print point coordinates - out << "points " << dim << " " << n_pts << "\n"; - for (int i = 0; i < n_pts; i++) { - out << i << " "; - annPrintPt(pts[i], dim, out); - out << "\n"; - } - } - out << "tree " // print tree elements - << dim << " " - << n_pts << " " - << bkt_size << "\n"; - - annPrintPt(bnd_box_lo, dim, out); // print lower bound - out << "\n"; - annPrintPt(bnd_box_hi, dim, out); // print upper bound - out << "\n"; - - if (root == NULL) // empty tree? - out << "null\n"; - else { - root->dump(out); // invoke printing at root - } - out.precision(0); // restore default precision -} - -void ANNkd_split::dump( // dump a splitting node - ostream &out) // output stream -{ - out << "split " << cut_dim << " " << cut_val << " "; - out << cd_bnds[ANN_LO] << " " << cd_bnds[ANN_HI] << "\n"; - - child[ANN_LO]->dump(out); // print low child - child[ANN_HI]->dump(out); // print high child -} - -void ANNkd_leaf::dump( // dump a leaf node - ostream &out) // output stream -{ - if (this == KD_TRIVIAL) { // canonical trivial leaf node - out << "leaf 0\n"; // leaf no points - } - else{ - out << "leaf " << n_pts; - for (int j = 0; j < n_pts; j++) { - out << " " << bkt[j]; - } - out << "\n"; - } -} - -void ANNbd_shrink::dump( // dump a shrinking node - ostream &out) // output stream -{ - out << "shrink " << n_bnds << "\n"; - for (int j = 0; j < n_bnds; j++) { - out << bnds[j].cd << " " << bnds[j].cv << " " << bnds[j].sd << "\n"; - } - child[ANN_IN]->dump(out); // print in-child - child[ANN_OUT]->dump(out); // print out-child -} - -//---------------------------------------------------------------------- -// Load kd-tree from dump file -// This rebuilds a kd-tree which was dumped to a file. The dump -// file contains all the basic tree information according to a -// preorder traversal. We assume that the dump file also contains -// point data. (This is to guarantee the consistency of the tree.) -// If not, then an error is generated. -// -// Indirectly, this procedure allocates space for points, point -// indices, all nodes in the tree, and the bounding box for the -// tree. When the tree is destroyed, all but the points are -// deallocated. -// -// This routine calls annReadDump to do all the work. -//---------------------------------------------------------------------- - -ANNkd_tree::ANNkd_tree( // build from dump file - istream &in) // input stream for dump file -{ - int the_dim; // local dimension - int the_n_pts; // local number of points - int the_bkt_size; // local number of points - ANNpoint the_bnd_box_lo; // low bounding point - ANNpoint the_bnd_box_hi; // high bounding point - ANNpointArray the_pts; // point storage - ANNidxArray the_pidx; // point index storage - ANNkd_ptr the_root; // root of the tree - - the_root = annReadDump( // read the dump file - in, // input stream - KD_TREE, // expecting a kd-tree - the_pts, // point array (returned) - the_pidx, // point indices (returned) - the_dim, the_n_pts, the_bkt_size, // basic tree info (returned) - the_bnd_box_lo, the_bnd_box_hi); // bounding box info (returned) - - // create a skeletal tree - SkeletonTree(the_n_pts, the_dim, the_bkt_size, the_pts, the_pidx); - - bnd_box_lo = the_bnd_box_lo; - bnd_box_hi = the_bnd_box_hi; - - root = the_root; // set the root -} - -ANNbd_tree::ANNbd_tree( // build bd-tree from dump file - istream &in) : ANNkd_tree() // input stream for dump file -{ - int the_dim; // local dimension - int the_n_pts; // local number of points - int the_bkt_size; // local number of points - ANNpoint the_bnd_box_lo; // low bounding point - ANNpoint the_bnd_box_hi; // high bounding point - ANNpointArray the_pts; // point storage - ANNidxArray the_pidx; // point index storage - ANNkd_ptr the_root; // root of the tree - - the_root = annReadDump( // read the dump file - in, // input stream - BD_TREE, // expecting a bd-tree - the_pts, // point array (returned) - the_pidx, // point indices (returned) - the_dim, the_n_pts, the_bkt_size, // basic tree info (returned) - the_bnd_box_lo, the_bnd_box_hi); // bounding box info (returned) - - // create a skeletal tree - SkeletonTree(the_n_pts, the_dim, the_bkt_size, the_pts, the_pidx); - bnd_box_lo = the_bnd_box_lo; - bnd_box_hi = the_bnd_box_hi; - - root = the_root; // set the root -} - -//---------------------------------------------------------------------- -// annReadDump - read a dump file -// -// This procedure reads a dump file, constructs a kd-tree -// and returns all the essential information needed to actually -// construct the tree. Because this procedure is used for -// constructing both kd-trees and bd-trees, the second argument -// is used to indicate which type of tree we are expecting. -//---------------------------------------------------------------------- - -static ANNkd_ptr annReadDump( - istream &in, // input stream - ANNtreeType tree_type, // type of tree expected - ANNpointArray &the_pts, // new points (returned) - ANNidxArray &the_pidx, // point indices (returned) - int &the_dim, // dimension (returned) - int &the_n_pts, // number of points (returned) - int &the_bkt_size, // bucket size (returned) - ANNpoint &the_bnd_box_lo, // low bounding point (ret'd) - ANNpoint &the_bnd_box_hi) // high bounding point (ret'd) -{ - int j; - char str[STRING_LEN]; // storage for string - char version[STRING_LEN]; // ANN version number - ANNkd_ptr the_root = NULL; - - //------------------------------------------------------------------ - // Input file header - //------------------------------------------------------------------ - in >> str; // input header - if (strcmp(str, "#ANN") != 0) { // incorrect header - annError("Incorrect header for dump file", ANNabort); - } - in.getline(version, STRING_LEN); // get version (ignore) - - //------------------------------------------------------------------ - // Input the points - // An array the_pts is allocated and points are read from - // the dump file. - //------------------------------------------------------------------ - in >> str; // get major heading - if (strcmp(str, "points") == 0) { // points section - in >> the_dim; // input dimension - in >> the_n_pts; // number of points - // allocate point storage - the_pts = annAllocPts(the_n_pts, the_dim); - for (int i = 0; i < the_n_pts; i++) { // input point coordinates - ANNidx idx; // point index - in >> idx; // input point index - if (idx < 0 || idx >= the_n_pts) { - annError("Point index is out of range", ANNabort); - } - for (j = 0; j < the_dim; j++) { - in >> the_pts[idx][j]; // read point coordinates - } - } - in >> str; // get next major heading - } - else { // no points were input - annError("Points must be supplied in the dump file", ANNabort); - } - - //------------------------------------------------------------------ - // Input the tree - // After the basic header information, we invoke annReadTree - // to do all the heavy work. We create our own array of - // point indices (so we can pass them to annReadTree()) - // but we do not deallocate them. They will be deallocated - // when the tree is destroyed. - //------------------------------------------------------------------ - if (strcmp(str, "tree") == 0) { // tree section - in >> the_dim; // read dimension - in >> the_n_pts; // number of points - in >> the_bkt_size; // bucket size - the_bnd_box_lo = annAllocPt(the_dim); // allocate bounding box pts - the_bnd_box_hi = annAllocPt(the_dim); - - for (j = 0; j < the_dim; j++) { // read bounding box low - in >> the_bnd_box_lo[j]; - } - for (j = 0; j < the_dim; j++) { // read bounding box low - in >> the_bnd_box_hi[j]; - } - the_pidx = new ANNidx[the_n_pts]; // allocate point index array - int next_idx = 0; // number of indices filled - // read the tree and indices - the_root = annReadTree(in, tree_type, the_pidx, next_idx); - if (next_idx != the_n_pts) { // didn't see all the points? - annError("Didn't see as many points as expected", ANNwarn); - } - } - else { - annError("Illegal dump format. Expecting section heading", ANNabort); - } - return the_root; -} - -//---------------------------------------------------------------------- -// annReadTree - input tree and return pointer -// -// annReadTree reads in a node of the tree, makes any recursive -// calls as needed to input the children of this node (if internal). -// It returns a pointer to the node that was created. An array -// of point indices is given along with a pointer to the next -// available location in the array. As leaves are read, their -// point indices are stored here, and the point buckets point -// to the first entry in the array. -// -// Recall that these are the formats. The tree is given in -// preorder. -// -// Leaf node: -// leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]> -// Splitting nodes: -// split <cut_dim> <cut_val> <lo_bound> <hi_bound> -// -// For bd-trees: -// -// Shrinking nodes: -// shrink <n_bnds> -// <cut_dim> <cut_val> <side> -// <cut_dim> <cut_val> <side> -// ... (repeated n_bnds times) -//---------------------------------------------------------------------- - -static ANNkd_ptr annReadTree( - istream &in, // input stream - ANNtreeType tree_type, // type of tree expected - ANNidxArray the_pidx, // point indices (modified) - int &next_idx) // next index (modified) -{ - char tag[STRING_LEN]; // tag (leaf, split, shrink) - int n_pts; // number of points in leaf - int cd; // cut dimension - ANNcoord cv; // cut value - ANNcoord lb; // low bound - ANNcoord hb; // high bound - int n_bnds; // number of bounding sides - int sd; // which side - - in >> tag; // input node tag - - if (strcmp(tag, "null") == 0) { // null tree - return NULL; - } - //------------------------------------------------------------------ - // Read a leaf - //------------------------------------------------------------------ - if (strcmp(tag, "leaf") == 0) { // leaf node - - in >> n_pts; // input number of points - int old_idx = next_idx; // save next_idx - if (n_pts == 0) { // trivial leaf - return KD_TRIVIAL; - } - else { - for (int i = 0; i < n_pts; i++) { // input point indices - in >> the_pidx[next_idx++]; // store in array of indices - } - } - return new ANNkd_leaf(n_pts, &the_pidx[old_idx]); - } - //------------------------------------------------------------------ - // Read a splitting node - //------------------------------------------------------------------ - else if (strcmp(tag, "split") == 0) { // splitting node - - in >> cd >> cv >> lb >> hb; - - // read low and high subtrees - ANNkd_ptr lc = annReadTree(in, tree_type, the_pidx, next_idx); - ANNkd_ptr hc = annReadTree(in, tree_type, the_pidx, next_idx); - // create new node and return - return new ANNkd_split(cd, cv, lb, hb, lc, hc); - } - //------------------------------------------------------------------ - // Read a shrinking node (bd-tree only) - //------------------------------------------------------------------ - else if (strcmp(tag, "shrink") == 0) { // shrinking node - if (tree_type != BD_TREE) { - annError("Shrinking node not allowed in kd-tree", ANNabort); - } - - in >> n_bnds; // number of bounding sides - // allocate bounds array - ANNorthHSArray bds = new ANNorthHalfSpace[n_bnds]; - for (int i = 0; i < n_bnds; i++) { - in >> cd >> cv >> sd; // input bounding halfspace - // copy to array - bds[i] = ANNorthHalfSpace(cd, cv, sd); - } - // read inner and outer subtrees - ANNkd_ptr ic = annReadTree(in, tree_type, the_pidx, next_idx); - ANNkd_ptr oc = annReadTree(in, tree_type, the_pidx, next_idx); - // create new node and return - return new ANNbd_shrink(n_bnds, bds, ic, oc); - } - else { - annError("Illegal node type in dump file", ANNabort); - exit(0); // to keep the compiler happy - } -} diff --git a/ANN/src/kd_fix_rad_search.cpp b/ANN/src/kd_fix_rad_search.cpp deleted file mode 100644 index 87eb757d7b..0000000000 --- a/ANN/src/kd_fix_rad_search.cpp +++ /dev/null @@ -1,183 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_fix_rad_search.cpp -// Programmer: Sunil Arya and David Mount -// Description: Standard kd-tree fixed-radius kNN search -// Last modified: 05/03/05 (Version 1.1) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 1.1 05/03/05 -// Initial release -//---------------------------------------------------------------------- - -#include "kd_fix_rad_search.h" // kd fixed-radius search decls - -//---------------------------------------------------------------------- -// Approximate fixed-radius k nearest neighbor search -// The squared radius is provided, and this procedure finds the -// k nearest neighbors within the radius, and returns the total -// number of points lying within the radius. -// -// The method used for searching the kd-tree is a variation of the -// nearest neighbor search used in kd_search.cpp, except that the -// radius of the search ball is known. We refer the reader to that -// file for the explanation of the recursive search procedure. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// To keep argument lists short, a number of global variables -// are maintained which are common to all the recursive calls. -// These are given below. -//---------------------------------------------------------------------- - -int ANNkdFRDim; // dimension of space -ANNpoint ANNkdFRQ; // query point -ANNdist ANNkdFRSqRad; // squared radius search bound -double ANNkdFRMaxErr; // max tolerable squared error -ANNpointArray ANNkdFRPts; // the points -ANNmin_k* ANNkdFRPointMK; // set of k closest points -int ANNkdFRPtsVisited; // total points visited -int ANNkdFRPtsInRange; // number of points in the range - -//---------------------------------------------------------------------- -// annkFRSearch - fixed radius search for k nearest neighbors -//---------------------------------------------------------------------- - -int ANNkd_tree::annkFRSearch( - ANNpoint q, // the query point - ANNdist sqRad, // squared radius search bound - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor indices (returned) - ANNdistArray dd, // the approximate nearest neighbor - double eps) // the error bound -{ - ANNkdFRDim = dim; // copy arguments to static equivs - ANNkdFRQ = q; - ANNkdFRSqRad = sqRad; - ANNkdFRPts = pts; - ANNkdFRPtsVisited = 0; // initialize count of points visited - ANNkdFRPtsInRange = 0; // ...and points in the range - - ANNkdFRMaxErr = ANN_POW(1.0 + eps); - ANN_FLOP(2) // increment floating op count - - ANNkdFRPointMK = new ANNmin_k(k); // create set for closest k points - // search starting at the root - root->ann_FR_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim)); - - for (int i = 0; i < k; i++) { // extract the k-th closest points - if (dd != NULL) - dd[i] = ANNkdFRPointMK->ith_smallest_key(i); - if (nn_idx != NULL) - nn_idx[i] = ANNkdFRPointMK->ith_smallest_info(i); - } - - delete ANNkdFRPointMK; // deallocate closest point set - return ANNkdFRPtsInRange; // return final point count -} - -//---------------------------------------------------------------------- -// kd_split::ann_FR_search - search a splitting node -// Note: This routine is similar in structure to the standard kNN -// search. It visits the subtree that is closer to the query point -// first. For fixed-radius search, there is no benefit in visiting -// one subtree before the other, but we maintain the same basic -// code structure for the sake of uniformity. -//---------------------------------------------------------------------- - -void ANNkd_split::ann_FR_search(ANNdist box_dist) -{ - // check dist calc term condition - if (ANNmaxPtsVisited != 0 && ANNkdFRPtsVisited > ANNmaxPtsVisited) return; - - // distance to cutting plane - ANNcoord cut_diff = ANNkdFRQ[cut_dim] - cut_val; - - if (cut_diff < 0) { // left of cutting plane - child[ANN_LO]->ann_FR_search(box_dist);// visit closer child first - - ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdFRQ[cut_dim]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - box_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - // visit further child if in range - if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad) - child[ANN_HI]->ann_FR_search(box_dist); - - } - else { // right of cutting plane - child[ANN_HI]->ann_FR_search(box_dist);// visit closer child first - - ANNcoord box_diff = ANNkdFRQ[cut_dim] - cd_bnds[ANN_HI]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - box_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - // visit further child if close enough - if (box_dist * ANNkdFRMaxErr <= ANNkdFRSqRad) - child[ANN_LO]->ann_FR_search(box_dist); - - } - ANN_FLOP(13) // increment floating ops - ANN_SPL(1) // one more splitting node visited -} - -//---------------------------------------------------------------------- -// kd_leaf::ann_FR_search - search points in a leaf node -// Note: The unreadability of this code is the result of -// some fine tuning to replace indexing by pointer operations. -//---------------------------------------------------------------------- - -void ANNkd_leaf::ann_FR_search(ANNdist box_dist) -{ - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNcoord t; - register int d; - - for (int i = 0; i < n_pts; i++) { // check points in bucket - - pp = ANNkdFRPts[bkt[i]]; // first coord of next data point - qq = ANNkdFRQ; // first coord of query point - dist = 0; - - for(d = 0; d < ANNkdFRDim; d++) { - ANN_COORD(1) // one more coordinate hit - ANN_FLOP(5) // increment floating ops - - t = *(qq++) - *(pp++); // compute length and adv coordinate - // exceeds dist to k-th smallest? - if( (dist = ANN_SUM(dist, ANN_POW(t))) > ANNkdFRSqRad) { - break; - } - } - - if (d >= ANNkdFRDim && // among the k best? - (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem - // add it to the list - ANNkdFRPointMK->insert(dist, bkt[i]); - ANNkdFRPtsInRange++; // increment point count - } - } - ANN_LEAF(1) // one more leaf node visited - ANN_PTS(n_pts) // increment points visited - ANNkdFRPtsVisited += n_pts; // increment number of points visited -} diff --git a/ANN/src/kd_fix_rad_search.h b/ANN/src/kd_fix_rad_search.h deleted file mode 100644 index 7bae230db2..0000000000 --- a/ANN/src/kd_fix_rad_search.h +++ /dev/null @@ -1,44 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_fix_rad_search.h -// Programmer: Sunil Arya and David Mount -// Description: Standard kd-tree fixed-radius kNN search -// Last modified: ??/??/?? (Version 1.1) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 1.1 ??/??/?? -// Initial release -//---------------------------------------------------------------------- - -#ifndef ANN_kd_fix_rad_search_H -#define ANN_kd_fix_rad_search_H - -#include "kd_tree.h" // kd-tree declarations -#include "kd_util.h" // kd-tree utilities -#include "pr_queue_k.h" // k-element priority queue - -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// Global variables -// These are active for the life of each call to -// annRangeSearch(). They are set to save the number of -// variables that need to be passed among the various search -// procedures. -//---------------------------------------------------------------------- - -extern ANNpoint ANNkdFRQ; // query point (static copy) - -#endif diff --git a/ANN/src/kd_pr_search.cpp b/ANN/src/kd_pr_search.cpp deleted file mode 100644 index edb0479f29..0000000000 --- a/ANN/src/kd_pr_search.cpp +++ /dev/null @@ -1,219 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_pr_search.cpp -// Programmer: Sunil Arya and David Mount -// Description: Priority search for kd-trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#include "kd_pr_search.h" // kd priority search declarations - -//---------------------------------------------------------------------- -// Approximate nearest neighbor searching by priority search. -// The kd-tree is searched for an approximate nearest neighbor. -// The point is returned through one of the arguments, and the -// distance returned is the SQUARED distance to this point. -// -// The method used for searching the kd-tree is called priority -// search. (It is described in Arya and Mount, ``Algorithms for -// fast vector quantization,'' Proc. of DCC '93: Data Compression -// Conference}, eds. J. A. Storer and M. Cohn, IEEE Press, 1993, -// 381--390.) -// -// The cell of the kd-tree containing the query point is located, -// and cells are visited in increasing order of distance from the -// query point. This is done by placing each subtree which has -// NOT been visited in a priority queue, according to the closest -// distance of the corresponding enclosing rectangle from the -// query point. The search stops when the distance to the nearest -// remaining rectangle exceeds the distance to the nearest point -// seen by a factor of more than 1/(1+eps). (Implying that any -// point found subsequently in the search cannot be closer by more -// than this factor.) -// -// The main entry point is annkPriSearch() which sets things up and -// then call the recursive routine ann_pri_search(). This is a -// recursive routine which performs the processing for one node in -// the kd-tree. There are two versions of this virtual procedure, -// one for splitting nodes and one for leaves. When a splitting node -// is visited, we determine which child to continue the search on -// (the closer one), and insert the other child into the priority -// queue. When a leaf is visited, we compute the distances to the -// points in the buckets, and update information on the closest -// points. -// -// Some trickery is used to incrementally update the distance from -// a kd-tree rectangle to the query point. This comes about from -// the fact that which each successive split, only one component -// (along the dimension that is split) of the squared distance to -// the child rectangle is different from the squared distance to -// the parent rectangle. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// To keep argument lists short, a number of global variables -// are maintained which are common to all the recursive calls. -// These are given below. -//---------------------------------------------------------------------- - -double ANNprEps; // the error bound -int ANNprDim; // dimension of space -ANNpoint ANNprQ; // query point -double ANNprMaxErr; // max tolerable squared error -ANNpointArray ANNprPts; // the points -ANNpr_queue *ANNprBoxPQ; // priority queue for boxes -ANNmin_k *ANNprPointMK; // set of k closest points - -//---------------------------------------------------------------------- -// annkPriSearch - priority search for k nearest neighbors -//---------------------------------------------------------------------- - -void ANNkd_tree::annkPriSearch( - ANNpoint q, // query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor indices (returned) - ANNdistArray dd, // dist to near neighbors (returned) - double eps) // error bound (ignored) -{ - // max tolerable squared error - ANNprMaxErr = ANN_POW(1.0 + eps); - ANN_FLOP(2) // increment floating ops - - ANNprDim = dim; // copy arguments to static equivs - ANNprQ = q; - ANNprPts = pts; - ANNptsVisited = 0; // initialize count of points visited - - ANNprPointMK = new ANNmin_k(k); // create set for closest k points - - // distance to root box - ANNdist box_dist = annBoxDistance(q, - bnd_box_lo, bnd_box_hi, dim); - - ANNprBoxPQ = new ANNpr_queue(n_pts);// create priority queue for boxes - ANNprBoxPQ->insert(box_dist, root); // insert root in priority queue - - while (ANNprBoxPQ->non_empty() && - (!(ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited))) { - ANNkd_ptr np; // next box from prior queue - - // extract closest box from queue - ANNprBoxPQ->extr_min(box_dist, (void *&) np); - - ANN_FLOP(2) // increment floating ops - if (box_dist*ANNprMaxErr >= ANNprPointMK->max_key()) - break; - - np->ann_pri_search(box_dist); // search this subtree. - } - - for (int i = 0; i < k; i++) { // extract the k-th closest points - dd[i] = ANNprPointMK->ith_smallest_key(i); - nn_idx[i] = ANNprPointMK->ith_smallest_info(i); - } - - delete ANNprPointMK; // deallocate closest point set - delete ANNprBoxPQ; // deallocate priority queue -} - -//---------------------------------------------------------------------- -// kd_split::ann_pri_search - search a splitting node -//---------------------------------------------------------------------- - -void ANNkd_split::ann_pri_search(ANNdist box_dist) -{ - ANNdist new_dist; // distance to child visited later - // distance to cutting plane - ANNcoord cut_diff = ANNprQ[cut_dim] - cut_val; - - if (cut_diff < 0) { // left of cutting plane - ANNcoord box_diff = cd_bnds[ANN_LO] - ANNprQ[cut_dim]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - new_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - if (child[ANN_HI] != KD_TRIVIAL)// enqueue if not trivial - ANNprBoxPQ->insert(new_dist, child[ANN_HI]); - // continue with closer child - child[ANN_LO]->ann_pri_search(box_dist); - } - else { // right of cutting plane - ANNcoord box_diff = ANNprQ[cut_dim] - cd_bnds[ANN_HI]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - new_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - if (child[ANN_LO] != KD_TRIVIAL)// enqueue if not trivial - ANNprBoxPQ->insert(new_dist, child[ANN_LO]); - // continue with closer child - child[ANN_HI]->ann_pri_search(box_dist); - } - ANN_SPL(1) // one more splitting node visited - ANN_FLOP(8) // increment floating ops -} - -//---------------------------------------------------------------------- -// kd_leaf::ann_pri_search - search points in a leaf node -// -// This is virtually identical to the ann_search for standard search. -//---------------------------------------------------------------------- - -void ANNkd_leaf::ann_pri_search(ANNdist box_dist) -{ - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNdist min_dist; // distance to k-th closest point - register ANNcoord t; - register int d; - - min_dist = ANNprPointMK->max_key(); // k-th smallest distance so far - - for (int i = 0; i < n_pts; i++) { // check points in bucket - - pp = ANNprPts[bkt[i]]; // first coord of next data point - qq = ANNprQ; // first coord of query point - dist = 0; - - for(d = 0; d < ANNprDim; d++) { - ANN_COORD(1) // one more coordinate hit - ANN_FLOP(4) // increment floating ops - - t = *(qq++) - *(pp++); // compute length and adv coordinate - // exceeds dist to k-th smallest? - if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) { - break; - } - } - - if (d >= ANNprDim && // among the k best? - (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem - // add it to the list - ANNprPointMK->insert(dist, bkt[i]); - min_dist = ANNprPointMK->max_key(); - } - } - ANN_LEAF(1) // one more leaf node visited - ANN_PTS(n_pts) // increment points visited - ANNptsVisited += n_pts; // increment number of points visited -} diff --git a/ANN/src/kd_pr_search.h b/ANN/src/kd_pr_search.h deleted file mode 100644 index 39e048418d..0000000000 --- a/ANN/src/kd_pr_search.h +++ /dev/null @@ -1,49 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_pr_search.h -// Programmer: Sunil Arya and David Mount -// Description: Priority kd-tree search -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#ifndef ANN_kd_pr_search_H -#define ANN_kd_pr_search_H - -#include "kd_tree.h" // kd-tree declarations -#include "kd_util.h" // kd-tree utilities -#include "pr_queue.h" // priority queue declarations -#include "pr_queue_k.h" // k-element priority queue - -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// Global variables -// Active for the life of each call to Appx_Near_Neigh() or -// Appx_k_Near_Neigh(). -//---------------------------------------------------------------------- - -extern double ANNprEps; // the error bound -extern int ANNprDim; // dimension of space -extern ANNpoint ANNprQ; // query point -extern double ANNprMaxErr; // max tolerable squared error -extern ANNpointArray ANNprPts; // the points -extern ANNpr_queue *ANNprBoxPQ; // priority queue for boxes -extern ANNmin_k *ANNprPointMK; // set of k closest points - -#endif diff --git a/ANN/src/kd_search.cpp b/ANN/src/kd_search.cpp deleted file mode 100644 index 5004ef798c..0000000000 --- a/ANN/src/kd_search.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_search.cpp -// Programmer: Sunil Arya and David Mount -// Description: Standard kd-tree search -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Changed names LO, HI to ANN_LO, ANN_HI -//---------------------------------------------------------------------- - -#include "kd_search.h" // kd-search declarations - -//---------------------------------------------------------------------- -// Approximate nearest neighbor searching by kd-tree search -// The kd-tree is searched for an approximate nearest neighbor. -// The point is returned through one of the arguments, and the -// distance returned is the squared distance to this point. -// -// The method used for searching the kd-tree is an approximate -// adaptation of the search algorithm described by Friedman, -// Bentley, and Finkel, ``An algorithm for finding best matches -// in logarithmic expected time,'' ACM Transactions on Mathematical -// Software, 3(3):209-226, 1977). -// -// The algorithm operates recursively. When first encountering a -// node of the kd-tree we first visit the child which is closest to -// the query point. On return, we decide whether we want to visit -// the other child. If the box containing the other child exceeds -// 1/(1+eps) times the current best distance, then we skip it (since -// any point found in this child cannot be closer to the query point -// by more than this factor.) Otherwise, we visit it recursively. -// The distance between a box and the query point is computed exactly -// (not approximated as is often done in kd-tree), using incremental -// distance updates, as described by Arya and Mount in ``Algorithms -// for fast vector quantization,'' Proc. of DCC '93: Data Compression -// Conference, eds. J. A. Storer and M. Cohn, IEEE Press, 1993, -// 381-390. -// -// The main entry points is annkSearch() which sets things up and -// then call the recursive routine ann_search(). This is a recursive -// routine which performs the processing for one node in the kd-tree. -// There are two versions of this virtual procedure, one for splitting -// nodes and one for leaves. When a splitting node is visited, we -// determine which child to visit first (the closer one), and visit -// the other child on return. When a leaf is visited, we compute -// the distances to the points in the buckets, and update information -// on the closest points. -// -// Some trickery is used to incrementally update the distance from -// a kd-tree rectangle to the query point. This comes about from -// the fact that which each successive split, only one component -// (along the dimension that is split) of the squared distance to -// the child rectangle is different from the squared distance to -// the parent rectangle. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// To keep argument lists short, a number of global variables -// are maintained which are common to all the recursive calls. -// These are given below. -//---------------------------------------------------------------------- - -int ANNkdDim; // dimension of space -ANNpoint ANNkdQ; // query point -double ANNkdMaxErr; // max tolerable squared error -ANNpointArray ANNkdPts; // the points -ANNmin_k *ANNkdPointMK; // set of k closest points - -//---------------------------------------------------------------------- -// annkSearch - search for the k nearest neighbors -//---------------------------------------------------------------------- - -void ANNkd_tree::annkSearch( - ANNpoint q, // the query point - int k, // number of near neighbors to return - ANNidxArray nn_idx, // nearest neighbor indices (returned) - ANNdistArray dd, // the approximate nearest neighbor - double eps) // the error bound -{ - - ANNkdDim = dim; // copy arguments to static equivs - ANNkdQ = q; - ANNkdPts = pts; - ANNptsVisited = 0; // initialize count of points visited - - if (k > n_pts) { // too many near neighbors? - annError("Requesting more near neighbors than data points", ANNabort); - } - - ANNkdMaxErr = ANN_POW(1.0 + eps); - ANN_FLOP(2) // increment floating op count - - ANNkdPointMK = new ANNmin_k(k); // create set for closest k points - // search starting at the root - root->ann_search(annBoxDistance(q, bnd_box_lo, bnd_box_hi, dim)); - - for (int i = 0; i < k; i++) { // extract the k-th closest points - dd[i] = ANNkdPointMK->ith_smallest_key(i); - nn_idx[i] = ANNkdPointMK->ith_smallest_info(i); - } - delete ANNkdPointMK; // deallocate closest point set -} - -//---------------------------------------------------------------------- -// kd_split::ann_search - search a splitting node -//---------------------------------------------------------------------- - -void ANNkd_split::ann_search(ANNdist box_dist) -{ - // check dist calc term condition - if (ANNmaxPtsVisited != 0 && ANNptsVisited > ANNmaxPtsVisited) return; - - // distance to cutting plane - ANNcoord cut_diff = ANNkdQ[cut_dim] - cut_val; - - if (cut_diff < 0) { // left of cutting plane - child[ANN_LO]->ann_search(box_dist);// visit closer child first - - ANNcoord box_diff = cd_bnds[ANN_LO] - ANNkdQ[cut_dim]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - box_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - // visit further child if close enough - if (box_dist * ANNkdMaxErr < ANNkdPointMK->max_key()) - child[ANN_HI]->ann_search(box_dist); - - } - else { // right of cutting plane - child[ANN_HI]->ann_search(box_dist);// visit closer child first - - ANNcoord box_diff = ANNkdQ[cut_dim] - cd_bnds[ANN_HI]; - if (box_diff < 0) // within bounds - ignore - box_diff = 0; - // distance to further box - box_dist = (ANNdist) ANN_SUM(box_dist, - ANN_DIFF(ANN_POW(box_diff), ANN_POW(cut_diff))); - - // visit further child if close enough - if (box_dist * ANNkdMaxErr < ANNkdPointMK->max_key()) - child[ANN_LO]->ann_search(box_dist); - - } - ANN_FLOP(10) // increment floating ops - ANN_SPL(1) // one more splitting node visited -} - -//---------------------------------------------------------------------- -// kd_leaf::ann_search - search points in a leaf node -// Note: The unreadability of this code is the result of -// some fine tuning to replace indexing by pointer operations. -//---------------------------------------------------------------------- - -void ANNkd_leaf::ann_search(ANNdist box_dist) -{ - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNdist min_dist; // distance to k-th closest point - register ANNcoord t; - register int d; - - min_dist = ANNkdPointMK->max_key(); // k-th smallest distance so far - - for (int i = 0; i < n_pts; i++) { // check points in bucket - - pp = ANNkdPts[bkt[i]]; // first coord of next data point - qq = ANNkdQ; // first coord of query point - dist = 0; - - for(d = 0; d < ANNkdDim; d++) { - ANN_COORD(1) // one more coordinate hit - ANN_FLOP(4) // increment floating ops - - t = *(qq++) - *(pp++); // compute length and adv coordinate - // exceeds dist to k-th smallest? - if( (dist = ANN_SUM(dist, ANN_POW(t))) > min_dist) { - break; - } - } - - if (d >= ANNkdDim && // among the k best? - (ANN_ALLOW_SELF_MATCH || dist!=0)) { // and no self-match problem - // add it to the list - ANNkdPointMK->insert(dist, bkt[i]); - min_dist = ANNkdPointMK->max_key(); - } - } - ANN_LEAF(1) // one more leaf node visited - ANN_PTS(n_pts) // increment points visited - ANNptsVisited += n_pts; // increment number of points visited -} diff --git a/ANN/src/kd_search.h b/ANN/src/kd_search.h deleted file mode 100644 index 1adcdd4008..0000000000 --- a/ANN/src/kd_search.h +++ /dev/null @@ -1,48 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_search.h -// Programmer: Sunil Arya and David Mount -// Description: Standard kd-tree search -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#ifndef ANN_kd_search_H -#define ANN_kd_search_H - -#include "kd_tree.h" // kd-tree declarations -#include "kd_util.h" // kd-tree utilities -#include "pr_queue_k.h" // k-element priority queue - -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// More global variables -// These are active for the life of each call to annkSearch(). They -// are set to save the number of variables that need to be passed -// among the various search procedures. -//---------------------------------------------------------------------- - -extern int ANNkdDim; // dimension of space (static copy) -extern ANNpoint ANNkdQ; // query point (static copy) -extern double ANNkdMaxErr; // max tolerable squared error -extern ANNpointArray ANNkdPts; // the points (static copy) -extern ANNmin_k *ANNkdPointMK; // set of k closest points -extern int ANNptsVisited; // number of points visited - -#endif diff --git a/ANN/src/kd_split.cpp b/ANN/src/kd_split.cpp deleted file mode 100644 index 8d5b3d8735..0000000000 --- a/ANN/src/kd_split.cpp +++ /dev/null @@ -1,428 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_split.cpp -// Programmer: Sunil Arya and David Mount -// Description: Methods for splitting kd-trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -//---------------------------------------------------------------------- - -#include "kd_tree.h" // kd-tree definitions -#include "kd_util.h" // kd-tree utilities -#include "kd_split.h" // splitting functions - -//---------------------------------------------------------------------- -// Constants -//---------------------------------------------------------------------- - -const double ERR = 0.001; // a small value -const double FS_ASPECT_RATIO = 3.0; // maximum allowed aspect ratio - // in fair split. Must be >= 2. - -//---------------------------------------------------------------------- -// kd_split - Bentley's standard splitting routine for kd-trees -// Find the dimension of the greatest spread, and split -// just before the median point along this dimension. -//---------------------------------------------------------------------- - -void kd_split( - ANNpointArray pa, // point array (permuted on return) - ANNidxArray pidx, // point indices - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) -{ - // find dimension of maximum spread - cut_dim = annMaxSpread(pa, pidx, n, dim); - n_lo = n/2; // median rank - // split about median - annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); -} - -//---------------------------------------------------------------------- -// midpt_split - midpoint splitting rule for box-decomposition trees -// -// This is the simplest splitting rule that guarantees boxes -// of bounded aspect ratio. It simply cuts the box with the -// longest side through its midpoint. If there are ties, it -// selects the dimension with the maximum point spread. -// -// WARNING: This routine (while simple) doesn't seem to work -// well in practice in high dimensions, because it tends to -// generate a large number of trivial and/or unbalanced splits. -// Either kd_split(), sl_midpt_split(), or fair_split() are -// recommended, instead. -//---------------------------------------------------------------------- - -void midpt_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) -{ - int d; - - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; - } - } - ANNcoord max_spread = -1; // find long side with most spread - for (d = 0; d < dim; d++) { - // is it among longest? - if (double(bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) { - // compute its spread - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // is it max so far? - max_spread = spr; - cut_dim = d; - } - } - } - // split along cut_dim at midpoint - cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim]) / 2; - // permute points accordingly - int br1, br2; - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - //------------------------------------------------------------------ - // On return: pa[0..br1-1] < cut_val - // pa[br1..br2-1] == cut_val - // pa[br2..n-1] > cut_val - // - // We can set n_lo to any value in the range [br1..br2]. - // We choose split so that points are most evenly divided. - //------------------------------------------------------------------ - if (br1 > n/2) n_lo = br1; - else if (br2 < n/2) n_lo = br2; - else n_lo = n/2; -} - -//---------------------------------------------------------------------- -// sl_midpt_split - sliding midpoint splitting rule -// -// This is a modification of midpt_split, which has the nonsensical -// name "sliding midpoint". The idea is that we try to use the -// midpoint rule, by bisecting the longest side. If there are -// ties, the dimension with the maximum spread is selected. If, -// however, the midpoint split produces a trivial split (no points -// on one side of the splitting plane) then we slide the splitting -// (maintaining its orientation) until it produces a nontrivial -// split. For example, if the splitting plane is along the x-axis, -// and all the data points have x-coordinate less than the x-bisector, -// then the split is taken along the maximum x-coordinate of the -// data points. -// -// Intuitively, this rule cannot generate trivial splits, and -// hence avoids midpt_split's tendency to produce trees with -// a very large number of nodes. -// -//---------------------------------------------------------------------- - -void sl_midpt_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) -{ - int d; - - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; - } - } - ANNcoord max_spread = -1; // find long side with most spread - for (d = 0; d < dim; d++) { - // is it among longest? - if ((bnds.hi[d] - bnds.lo[d]) >= (1-ERR)*max_length) { - // compute its spread - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // is it max so far? - max_spread = spr; - cut_dim = d; - } - } - } - // ideal split at midpoint - ANNcoord ideal_cut_val = (bnds.lo[cut_dim] + bnds.hi[cut_dim])/2; - - ANNcoord min, max; - annMinMax(pa, pidx, n, cut_dim, min, max); // find min/max coordinates - - if (ideal_cut_val < min) // slide to min or max as needed - cut_val = min; - else if (ideal_cut_val > max) - cut_val = max; - else - cut_val = ideal_cut_val; - - // permute points accordingly - int br1, br2; - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - //------------------------------------------------------------------ - // On return: pa[0..br1-1] < cut_val - // pa[br1..br2-1] == cut_val - // pa[br2..n-1] > cut_val - // - // We can set n_lo to any value in the range [br1..br2] to satisfy - // the exit conditions of the procedure. - // - // if ideal_cut_val < min (implying br2 >= 1), - // then we select n_lo = 1 (so there is one point on left) and - // if ideal_cut_val > max (implying br1 <= n-1), - // then we select n_lo = n-1 (so there is one point on right). - // Otherwise, we select n_lo as close to n/2 as possible within - // [br1..br2]. - //------------------------------------------------------------------ - if (ideal_cut_val < min) n_lo = 1; - else if (ideal_cut_val > max) n_lo = n-1; - else if (br1 > n/2) n_lo = br1; - else if (br2 < n/2) n_lo = br2; - else n_lo = n/2; -} - -//---------------------------------------------------------------------- -// fair_split - fair-split splitting rule -// -// This is a compromise between the kd-tree splitting rule (which -// always splits data points at their median) and the midpoint -// splitting rule (which always splits a box through its center. -// The goal of this procedure is to achieve both nicely balanced -// splits, and boxes of bounded aspect ratio. -// -// A constant FS_ASPECT_RATIO is defined. Given a box, those sides -// which can be split so that the ratio of the longest to shortest -// side does not exceed ASPECT_RATIO are identified. Among these -// sides, we select the one in which the points have the largest -// spread. We then split the points in a manner which most evenly -// distributes the points on either side of the splitting plane, -// subject to maintaining the bound on the ratio of long to short -// sides. To determine that the aspect ratio will be preserved, -// we determine the longest side (other than this side), and -// determine how narrowly we can cut this side, without causing the -// aspect ratio bound to be exceeded (small_piece). -// -// This procedure is more robust than either kd_split or midpt_split, -// but is more complicated as well. When point distribution is -// extremely skewed, this degenerates to midpt_split (actually -// 1/3 point split), and when the points are most evenly distributed, -// this degenerates to kd-split. -//---------------------------------------------------------------------- - -void fair_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) -{ - int d; - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - cut_dim = 0; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; - cut_dim = d; - } - } - - ANNcoord max_spread = 0; // find legal cut with max spread - cut_dim = 0; - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - // is this side midpoint splitable - // without violating aspect ratio? - if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) { - // compute spread along this dim - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // best spread so far - max_spread = spr; - cut_dim = d; // this is dimension to cut - } - } - } - - max_length = 0; // find longest side other than cut_dim - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (d != cut_dim && length > max_length) - max_length = length; - } - // consider most extreme splits - ANNcoord small_piece = max_length / FS_ASPECT_RATIO; - ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut - ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut - - int br1, br2; - // is median below lo_cut ? - if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) { - cut_val = lo_cut; // cut at lo_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br1; - } - // is median above hi_cut? - else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) { - cut_val = hi_cut; // cut at hi_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br2; - } - else { // median cut preserves asp ratio - n_lo = n/2; // split about median - annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); - } -} - -//---------------------------------------------------------------------- -// sl_fair_split - sliding fair split splitting rule -// -// Sliding fair split is a splitting rule that combines the -// strengths of both fair split with sliding midpoint split. -// Fair split tends to produce balanced splits when the points -// are roughly uniformly distributed, but it can produce many -// trivial splits when points are highly clustered. Sliding -// midpoint never produces trivial splits, and shrinks boxes -// nicely if points are highly clustered, but it may produce -// rather unbalanced splits when points are unclustered but not -// quite uniform. -// -// Sliding fair split is based on the theory that there are two -// types of splits that are "good": balanced splits that produce -// fat boxes, and unbalanced splits provided the cell with fewer -// points is fat. -// -// This splitting rule operates by first computing the longest -// side of the current bounding box. Then it asks which sides -// could be split (at the midpoint) and still satisfy the aspect -// ratio bound with respect to this side. Among these, it selects -// the side with the largest spread (as fair split would). It -// then considers the most extreme cuts that would be allowed by -// the aspect ratio bound. This is done by dividing the longest -// side of the box by the aspect ratio bound. If the median cut -// lies between these extreme cuts, then we use the median cut. -// If not, then consider the extreme cut that is closer to the -// median. If all the points lie to one side of this cut, then -// we slide the cut until it hits the first point. This may -// violate the aspect ratio bound, but will never generate empty -// cells. However the sibling of every such skinny cell is fat, -// and hence packing arguments still apply. -// -//---------------------------------------------------------------------- - -void sl_fair_split( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo) // num of points on low side (returned) -{ - int d; - ANNcoord min, max; // min/max coordinates - int br1, br2; // split break points - - ANNcoord max_length = bnds.hi[0] - bnds.lo[0]; - cut_dim = 0; - for (d = 1; d < dim; d++) { // find length of longest box side - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (length > max_length) { - max_length = length; - cut_dim = d; - } - } - - ANNcoord max_spread = 0; // find legal cut with max spread - cut_dim = 0; - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - // is this side midpoint splitable - // without violating aspect ratio? - if (((double) max_length)*2.0/((double) length) <= FS_ASPECT_RATIO) { - // compute spread along this dim - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spread) { // best spread so far - max_spread = spr; - cut_dim = d; // this is dimension to cut - } - } - } - - max_length = 0; // find longest side other than cut_dim - for (d = 0; d < dim; d++) { - ANNcoord length = bnds.hi[d] - bnds.lo[d]; - if (d != cut_dim && length > max_length) - max_length = length; - } - // consider most extreme splits - ANNcoord small_piece = max_length / FS_ASPECT_RATIO; - ANNcoord lo_cut = bnds.lo[cut_dim] + small_piece;// lowest legal cut - ANNcoord hi_cut = bnds.hi[cut_dim] - small_piece;// highest legal cut - // find min and max along cut_dim - annMinMax(pa, pidx, n, cut_dim, min, max); - // is median below lo_cut? - if (annSplitBalance(pa, pidx, n, cut_dim, lo_cut) >= 0) { - if (max > lo_cut) { // are any points above lo_cut? - cut_val = lo_cut; // cut at lo_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br1; // balance if there are ties - } - else { // all points below lo_cut - cut_val = max; // cut at max value - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = n-1; - } - } - // is median above hi_cut? - else if (annSplitBalance(pa, pidx, n, cut_dim, hi_cut) <= 0) { - if (min < hi_cut) { // are any points below hi_cut? - cut_val = hi_cut; // cut at hi_cut - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = br2; // balance if there are ties - } - else { // all points above hi_cut - cut_val = min; // cut at min value - annPlaneSplit(pa, pidx, n, cut_dim, cut_val, br1, br2); - n_lo = 1; - } - } - else { // median cut is good enough - n_lo = n/2; // split about median - annMedianSplit(pa, pidx, n, cut_dim, cut_val, n_lo); - } -} diff --git a/ANN/src/kd_split.h b/ANN/src/kd_split.h deleted file mode 100644 index ef80461ead..0000000000 --- a/ANN/src/kd_split.h +++ /dev/null @@ -1,85 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_split.h -// Programmer: Sunil Arya and David Mount -// Description: Methods for splitting kd-trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#ifndef ANN_KD_SPLIT_H -#define ANN_KD_SPLIT_H - -#include "kd_tree.h" // kd-tree definitions - -//---------------------------------------------------------------------- -// External entry points -// These are all splitting procedures for kd-trees. -//---------------------------------------------------------------------- - -void kd_split( // standard (optimized) kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -void midpt_split( // midpoint kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -void sl_midpt_split( // sliding midpoint kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -void fair_split( // fair-split kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -void sl_fair_split( // sliding fair-split kd-splitter - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -#endif diff --git a/ANN/src/kd_tree.cpp b/ANN/src/kd_tree.cpp deleted file mode 100644 index 2828fd2cfd..0000000000 --- a/ANN/src/kd_tree.cpp +++ /dev/null @@ -1,405 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_tree.cpp -// Programmer: Sunil Arya and David Mount -// Description: Basic methods for kd-trees. -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Increased aspect ratio bound (ANN_AR_TOOBIG) from 100 to 1000. -// Fixed leaf counts to count trivial leaves. -// Added optional pa, pi arguments to Skeleton kd_tree constructor -// for use in load constructor. -// Added annClose() to eliminate KD_TRIVIAL memory leak. -//---------------------------------------------------------------------- - -#include "kd_tree.h" // kd-tree declarations -#include "kd_split.h" // kd-tree splitting rules -#include "kd_util.h" // kd-tree utilities -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// Global data -// -// For some splitting rules, especially with small bucket sizes, -// it is possible to generate a large number of empty leaf nodes. -// To save storage we allocate a single trivial leaf node which -// contains no points. For messy coding reasons it is convenient -// to have it reference a trivial point index. -// -// KD_TRIVIAL is allocated when the first kd-tree is created. It -// must *never* deallocated (since it may be shared by more than -// one tree). -//---------------------------------------------------------------------- -static int IDX_TRIVIAL[] = {0}; // trivial point index -ANNkd_leaf *KD_TRIVIAL = NULL; // trivial leaf node - -//---------------------------------------------------------------------- -// Printing the kd-tree -// These routines print a kd-tree in reverse inorder (high then -// root then low). (This is so that if you look at the output -// from the right side it appear from left to right in standard -// inorder.) When outputting leaves we output only the point -// indices rather than the point coordinates. There is an option -// to print the point coordinates separately. -// -// The tree printing routine calls the printing routines on the -// individual nodes of the tree, passing in the level or depth -// in the tree. The level in the tree is used to print indentation -// for readability. -//---------------------------------------------------------------------- - -void ANNkd_split::print( // print splitting node - int level, // depth of node in tree - ostream &out) // output stream -{ - child[ANN_HI]->print(level+1, out); // print high child - out << " "; - for (int i = 0; i < level; i++) // print indentation - out << ".."; - out << "Split cd=" << cut_dim << " cv=" << cut_val; - out << " lbnd=" << cd_bnds[ANN_LO]; - out << " hbnd=" << cd_bnds[ANN_HI]; - out << "\n"; - child[ANN_LO]->print(level+1, out); // print low child -} - -void ANNkd_leaf::print( // print leaf node - int level, // depth of node in tree - ostream &out) // output stream -{ - - out << " "; - for (int i = 0; i < level; i++) // print indentation - out << ".."; - - if (this == KD_TRIVIAL) { // canonical trivial leaf node - out << "Leaf (trivial)\n"; - } - else{ - out << "Leaf n=" << n_pts << " <"; - for (int j = 0; j < n_pts; j++) { - out << bkt[j]; - if (j < n_pts-1) out << ","; - } - out << ">\n"; - } -} - -void ANNkd_tree::Print( // print entire tree - ANNbool with_pts, // print points as well? - ostream &out) // output stream -{ - out << "ANN Version " << ANNversion << "\n"; - if (with_pts) { // print point coordinates - out << " Points:\n"; - for (int i = 0; i < n_pts; i++) { - out << "\t" << i << ": "; - annPrintPt(pts[i], dim, out); - out << "\n"; - } - } - if (root == NULL) // empty tree? - out << " Null tree.\n"; - else { - root->print(0, out); // invoke printing at root - } -} - -//---------------------------------------------------------------------- -// kd_tree statistics (for performance evaluation) -// This routine compute various statistics information for -// a kd-tree. It is used by the implementors for performance -// evaluation of the data structure. -//---------------------------------------------------------------------- - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - -void ANNkdStats::merge(const ANNkdStats &st) // merge stats from child -{ - n_lf += st.n_lf; n_tl += st.n_tl; - n_spl += st.n_spl; n_shr += st.n_shr; - depth = MAX(depth, st.depth); - sum_ar += st.sum_ar; -} - -//---------------------------------------------------------------------- -// Update statistics for nodes -//---------------------------------------------------------------------- - -const double ANN_AR_TOOBIG = 1000; // too big an aspect ratio - -void ANNkd_leaf::getStats( // get subtree statistics - int dim, // dimension of space - ANNkdStats &st, // stats (modified) - ANNorthRect &bnd_box) // bounding box -{ - st.reset(); - st.n_lf = 1; // count this leaf - if (this == KD_TRIVIAL) st.n_tl = 1; // count trivial leaf - double ar = annAspectRatio(dim, bnd_box); // aspect ratio of leaf - // incr sum (ignore outliers) - st.sum_ar += float(ar < ANN_AR_TOOBIG ? ar : ANN_AR_TOOBIG); -} - -void ANNkd_split::getStats( // get subtree statistics - int dim, // dimension of space - ANNkdStats &st, // stats (modified) - ANNorthRect &bnd_box) // bounding box -{ - ANNkdStats ch_stats; // stats for children - // get stats for low child - ANNcoord hv = bnd_box.hi[cut_dim]; // save box bounds - bnd_box.hi[cut_dim] = cut_val; // upper bound for low child - ch_stats.reset(); // reset - child[ANN_LO]->getStats(dim, ch_stats, bnd_box); - st.merge(ch_stats); // merge them - bnd_box.hi[cut_dim] = hv; // restore bound - // get stats for high child - ANNcoord lv = bnd_box.lo[cut_dim]; // save box bounds - bnd_box.lo[cut_dim] = cut_val; // lower bound for high child - ch_stats.reset(); // reset - child[ANN_HI]->getStats(dim, ch_stats, bnd_box); - st.merge(ch_stats); // merge them - bnd_box.lo[cut_dim] = lv; // restore bound - - st.depth++; // increment depth - st.n_spl++; // increment number of splits -} - -//---------------------------------------------------------------------- -// getStats -// Collects a number of statistics related to kd_tree or -// bd_tree. -//---------------------------------------------------------------------- - -void ANNkd_tree::getStats( // get tree statistics - ANNkdStats &st) // stats (modified) -{ - st.reset(dim, n_pts, bkt_size); // reset stats - // create bounding box - ANNorthRect bnd_box(dim, bnd_box_lo, bnd_box_hi); - if (root != NULL) { // if nonempty tree - root->getStats(dim, st, bnd_box); // get statistics - st.avg_ar = st.sum_ar / st.n_lf; // average leaf asp ratio - } -} - -//---------------------------------------------------------------------- -// kd_tree destructor -// The destructor just frees the various elements that were -// allocated in the construction process. -//---------------------------------------------------------------------- - -ANNkd_tree::~ANNkd_tree() // tree destructor -{ - if (root != NULL) delete root; - if (pidx != NULL) delete [] pidx; - if (bnd_box_lo != NULL) annDeallocPt(bnd_box_lo); - if (bnd_box_hi != NULL) annDeallocPt(bnd_box_hi); -} - -//---------------------------------------------------------------------- -// This is called with all use of ANN is finished. It eliminates the -// minor memory leak caused by the allocation of KD_TRIVIAL. -//---------------------------------------------------------------------- -void annClose() // close use of ANN -{ - if (KD_TRIVIAL != NULL) { - delete KD_TRIVIAL; - KD_TRIVIAL = NULL; - } -} - -//---------------------------------------------------------------------- -// kd_tree constructors -// There is a skeleton kd-tree constructor which sets up a -// trivial empty tree. The last optional argument allows -// the routine to be passed a point index array which is -// assumed to be of the proper size (n). Otherwise, one is -// allocated and initialized to the identity. Warning: In -// either case the destructor will deallocate this array. -// -// As a kludge, we need to allocate KD_TRIVIAL if one has not -// already been allocated. (This is because I'm too dumb to -// figure out how to cause a pointer to be allocated at load -// time.) -//---------------------------------------------------------------------- - -void ANNkd_tree::SkeletonTree( // construct skeleton tree - int n, // number of points - int dd, // dimension - int bs, // bucket size - ANNpointArray pa, // point array - ANNidxArray pi) // point indices -{ - dim = dd; // initialize basic elements - n_pts = n; - bkt_size = bs; - pts = pa; // initialize points array - - root = NULL; // no associated tree yet - - if (pi == NULL) { // point indices provided? - pidx = new ANNidx[n]; // no, allocate space for point indices - for (int i = 0; i < n; i++) { - pidx[i] = i; // initially identity - } - } - else { - pidx = pi; // yes, use them - } - - bnd_box_lo = bnd_box_hi = NULL; // bounding box is nonexistent - if (KD_TRIVIAL == NULL) // no trivial leaf node yet? - KD_TRIVIAL = new ANNkd_leaf(0, IDX_TRIVIAL); // allocate it -} - -ANNkd_tree::ANNkd_tree( // basic constructor - int n, // number of points - int dd, // dimension - int bs) // bucket size -{ SkeletonTree(n, dd, bs); } // construct skeleton tree - -//---------------------------------------------------------------------- -// rkd_tree - recursive procedure to build a kd-tree -// -// Builds a kd-tree for points in pa as indexed through the -// array pidx[0..n-1] (typically a subarray of the array used in -// the top-level call). This routine permutes the array pidx, -// but does not alter pa[]. -// -// The construction is based on a standard algorithm for constructing -// the kd-tree (see Friedman, Bentley, and Finkel, ``An algorithm for -// finding best matches in logarithmic expected time,'' ACM Transactions -// on Mathematical Software, 3(3):209-226, 1977). The procedure -// operates by a simple divide-and-conquer strategy, which determines -// an appropriate orthogonal cutting plane (see below), and splits -// the points. When the number of points falls below the bucket size, -// we simply store the points in a leaf node's bucket. -// -// One of the arguments is a pointer to a splitting routine, -// whose prototype is: -// -// void split( -// ANNpointArray pa, // complete point array -// ANNidxArray pidx, // point array (permuted on return) -// ANNorthRect &bnds, // bounds of current cell -// int n, // number of points -// int dim, // dimension of space -// int &cut_dim, // cutting dimension -// ANNcoord &cut_val, // cutting value -// int &n_lo) // no. of points on low side of cut -// -// This procedure selects a cutting dimension and cutting value, -// partitions pa about these values, and returns the number of -// points on the low side of the cut. -//---------------------------------------------------------------------- - -ANNkd_ptr rkd_tree( // recursive construction of kd-tree - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - int bsp, // bucket space - ANNorthRect &bnd_box, // bounding box for current node - ANNkd_splitter splitter) // splitting routine -{ - if (n <= bsp) { // n small, make a leaf node - if (n == 0) // empty leaf node - return KD_TRIVIAL; // return (canonical) empty leaf - else // construct the node and return - return new ANNkd_leaf(n, pidx); - } - else { // n large, make a splitting node - int cd; // cutting dimension - ANNcoord cv; // cutting value - int n_lo; // number on low side of cut - ANNkd_node *lo, *hi; // low and high children - - // invoke splitting procedure - (*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo); - - ANNcoord lv = bnd_box.lo[cd]; // save bounds for cutting dimension - ANNcoord hv = bnd_box.hi[cd]; - - bnd_box.hi[cd] = cv; // modify bounds for left subtree - lo = rkd_tree( // build left subtree - pa, pidx, n_lo, // ...from pidx[0..n_lo-1] - dim, bsp, bnd_box, splitter); - bnd_box.hi[cd] = hv; // restore bounds - - bnd_box.lo[cd] = cv; // modify bounds for right subtree - hi = rkd_tree( // build right subtree - pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1] - dim, bsp, bnd_box, splitter); - bnd_box.lo[cd] = lv; // restore bounds - - // create the splitting node - ANNkd_split *ptr = new ANNkd_split(cd, cv, lv, hv, lo, hi); - - return ptr; // return pointer to this node - } -} - -//---------------------------------------------------------------------- -// kd-tree constructor -// This is the main constructor for kd-trees given a set of points. -// It first builds a skeleton tree, then computes the bounding box -// of the data points, and then invokes rkd_tree() to actually -// build the tree, passing it the appropriate splitting routine. -//---------------------------------------------------------------------- - -ANNkd_tree::ANNkd_tree( // construct from point array - ANNpointArray pa, // point array (with at least n pts) - int n, // number of points - int dd, // dimension - int bs, // bucket size - ANNsplitRule split) // splitting method -{ - SkeletonTree(n, dd, bs); // set up the basic stuff - pts = pa; // where the points are - if (n == 0) return; // no points--no sweat - - ANNorthRect bnd_box(dd); // bounding box for points - annEnclRect(pa, pidx, n, dd, bnd_box);// construct bounding rectangle - // copy to tree structure - bnd_box_lo = annCopyPt(dd, bnd_box.lo); - bnd_box_hi = annCopyPt(dd, bnd_box.hi); - - switch (split) { // build by rule - case ANN_KD_STD: // standard kd-splitting rule - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split); - break; - case ANN_KD_MIDPT: // midpoint split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split); - break; - case ANN_KD_FAIR: // fair split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split); - break; - case ANN_KD_SUGGEST: // best (in our opinion) - case ANN_KD_SL_MIDPT: // sliding midpoint split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split); - break; - case ANN_KD_SL_FAIR: // sliding fair split - root = rkd_tree(pa, pidx, n, dd, bs, bnd_box, sl_fair_split); - break; - default: - annError("Illegal splitting method", ANNabort); - } -} diff --git a/ANN/src/kd_tree.h b/ANN/src/kd_tree.h deleted file mode 100644 index 81284b6fff..0000000000 --- a/ANN/src/kd_tree.h +++ /dev/null @@ -1,197 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_tree.h -// Programmer: Sunil Arya and David Mount -// Description: Declarations for standard kd-tree routines -// Last modified: 05/03/05 (Version 1.1) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.1 05/03/05 -// Added fixed radius kNN search -//---------------------------------------------------------------------- - -#ifndef ANN_kd_tree_H -#define ANN_kd_tree_H - -#include <ANN/ANNx.h> // all ANN includes - -using namespace std; // make std:: available - -//---------------------------------------------------------------------- -// Generic kd-tree node -// -// Nodes in kd-trees are of two types, splitting nodes which contain -// splitting information (a splitting hyperplane orthogonal to one -// of the coordinate axes) and leaf nodes which contain point -// information (an array of points stored in a bucket). This is -// handled by making a generic class kd_node, which is essentially an -// empty shell, and then deriving the leaf and splitting nodes from -// this. -//---------------------------------------------------------------------- - -class ANNkd_node{ // generic kd-tree node (empty shell) -public: - virtual ~ANNkd_node() {} // virtual distroyer - - virtual void ann_search(ANNdist) = 0; // tree search - virtual void ann_pri_search(ANNdist) = 0; // priority search - virtual void ann_FR_search(ANNdist) = 0; // fixed-radius search - - virtual void getStats( // get tree statistics - int dim, // dimension of space - ANNkdStats &st, // statistics - ANNorthRect &bnd_box) = 0; // bounding box - // print node - virtual void print(int level, ostream &out) = 0; - virtual void dump(ostream &out) = 0; // dump node - - friend class ANNkd_tree; // allow kd-tree to access us -}; - -//---------------------------------------------------------------------- -// kd-splitting function: -// kd_splitter is a pointer to a splitting routine for preprocessing. -// Different splitting procedures result in different strategies -// for building the tree. -//---------------------------------------------------------------------- - -typedef void (*ANNkd_splitter)( // splitting routine for kd-trees - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices (permuted on return) - const ANNorthRect &bnds, // bounding rectangle for cell - int n, // number of points - int dim, // dimension of space - int &cut_dim, // cutting dimension (returned) - ANNcoord &cut_val, // cutting value (returned) - int &n_lo); // num of points on low side (returned) - -//---------------------------------------------------------------------- -// Leaf kd-tree node -// Leaf nodes of the kd-tree store the set of points associated -// with this bucket, stored as an array of point indices. These -// are indices in the array points, which resides with the -// root of the kd-tree. We also store the number of points -// that reside in this bucket. -//---------------------------------------------------------------------- - -class ANNkd_leaf: public ANNkd_node // leaf node for kd-tree -{ - int n_pts; // no. points in bucket - ANNidxArray bkt; // bucket of points -public: - ANNkd_leaf( // constructor - int n, // number of points - ANNidxArray b) // bucket - { - n_pts = n; // number of points in bucket - bkt = b; // the bucket - } - - ~ANNkd_leaf() { } // destructor (none) - - virtual void getStats( // get tree statistics - int dim, // dimension of space - ANNkdStats &st, // statistics - ANNorthRect &bnd_box); // bounding box - virtual void print(int level, ostream &out);// print node - virtual void dump(ostream &out); // dump node - - virtual void ann_search(ANNdist); // standard search - virtual void ann_pri_search(ANNdist); // priority search - virtual void ann_FR_search(ANNdist); // fixed-radius search -}; - -//---------------------------------------------------------------------- -// KD_TRIVIAL is a special pointer to an empty leaf node. Since -// some splitting rules generate many (more than 50%) trivial -// leaves, we use this one shared node to save space. -// -// The pointer is initialized to NULL, but whenever a kd-tree is -// created, we allocate this node, if it has not already been -// allocated. This node is *never* deallocated, so it produces -// a small memory leak. -//---------------------------------------------------------------------- - -extern ANNkd_leaf *KD_TRIVIAL; // trivial (empty) leaf node - -//---------------------------------------------------------------------- -// kd-tree splitting node. -// Splitting nodes contain a cutting dimension and a cutting value. -// These indicate the axis-parellel plane which subdivide the -// box for this node. The extent of the bounding box along the -// cutting dimension is maintained (this is used to speed up point -// to box distance calculations) [we do not store the entire bounding -// box since this may be wasteful of space in high dimensions]. -// We also store pointers to the 2 children. -//---------------------------------------------------------------------- - -class ANNkd_split : public ANNkd_node // splitting node of a kd-tree -{ - int cut_dim; // dim orthogonal to cutting plane - ANNcoord cut_val; // location of cutting plane - ANNcoord cd_bnds[2]; // lower and upper bounds of - // rectangle along cut_dim - ANNkd_ptr child[2]; // left and right children -public: - ANNkd_split( // constructor - int cd, // cutting dimension - ANNcoord cv, // cutting value - ANNcoord lv, ANNcoord hv, // low and high values - ANNkd_ptr lc=NULL, ANNkd_ptr hc=NULL) // children - { - cut_dim = cd; // cutting dimension - cut_val = cv; // cutting value - cd_bnds[ANN_LO] = lv; // lower bound for rectangle - cd_bnds[ANN_HI] = hv; // upper bound for rectangle - child[ANN_LO] = lc; // left child - child[ANN_HI] = hc; // right child - } - - ~ANNkd_split() // destructor - { - if (child[ANN_LO]!= NULL && child[ANN_LO]!= KD_TRIVIAL) - delete child[ANN_LO]; - if (child[ANN_HI]!= NULL && child[ANN_HI]!= KD_TRIVIAL) - delete child[ANN_HI]; - } - - virtual void getStats( // get tree statistics - int dim, // dimension of space - ANNkdStats &st, // statistics - ANNorthRect &bnd_box); // bounding box - virtual void print(int level, ostream &out);// print node - virtual void dump(ostream &out); // dump node - - virtual void ann_search(ANNdist); // standard search - virtual void ann_pri_search(ANNdist); // priority search - virtual void ann_FR_search(ANNdist); // fixed-radius search -}; - -//---------------------------------------------------------------------- -// External entry points -//---------------------------------------------------------------------- - -ANNkd_ptr rkd_tree( // recursive construction of kd-tree - ANNpointArray pa, // point array (unaltered) - ANNidxArray pidx, // point indices to store in subtree - int n, // number of points - int dim, // dimension of space - int bsp, // bucket space - ANNorthRect &bnd_box, // bounding box for current node - ANNkd_splitter splitter); // splitting routine - -#endif diff --git a/ANN/src/kd_util.cpp b/ANN/src/kd_util.cpp deleted file mode 100644 index 06d65b835d..0000000000 --- a/ANN/src/kd_util.cpp +++ /dev/null @@ -1,439 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_util.cpp -// Programmer: Sunil Arya and David Mount -// Description: Common utilities for kd-trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#include "kd_util.h" // kd-utility declarations - -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// The following routines are utility functions for manipulating -// points sets, used in determining splitting planes for kd-tree -// construction. -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// NOTE: Virtually all point indexing is done through an index (i.e. -// permutation) array pidx. Consequently, a reference to the d-th -// coordinate of the i-th point is pa[pidx[i]][d]. The macro PA(i,d) -// is a shorthand for this. -//---------------------------------------------------------------------- - // standard 2-d indirect indexing -#define PA(i,d) (pa[pidx[(i)]][(d)]) - // accessing a single point -#define PP(i) (pa[pidx[(i)]]) - -//---------------------------------------------------------------------- -// annAspectRatio -// Compute the aspect ratio (ratio of longest to shortest side) -// of a rectangle. -//---------------------------------------------------------------------- - -double annAspectRatio( - int dim, // dimension - const ANNorthRect &bnd_box) // bounding cube -{ - ANNcoord length = bnd_box.hi[0] - bnd_box.lo[0]; - ANNcoord min_length = length; // min side length - ANNcoord max_length = length; // max side length - for (int d = 0; d < dim; d++) { - length = bnd_box.hi[d] - bnd_box.lo[d]; - if (length < min_length) min_length = length; - if (length > max_length) max_length = length; - } - return max_length/min_length; -} - -//---------------------------------------------------------------------- -// annEnclRect, annEnclCube -// These utilities compute the smallest rectangle and cube enclosing -// a set of points, respectively. -//---------------------------------------------------------------------- - -void annEnclRect( - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds) // bounding cube (returned) -{ - for (int d = 0; d < dim; d++) { // find smallest enclosing rectangle - ANNcoord lo_bnd = PA(0,d); // lower bound on dimension d - ANNcoord hi_bnd = PA(0,d); // upper bound on dimension d - for (int i = 0; i < n; i++) { - if (PA(i,d) < lo_bnd) lo_bnd = PA(i,d); - else if (PA(i,d) > hi_bnd) hi_bnd = PA(i,d); - } - bnds.lo[d] = lo_bnd; - bnds.hi[d] = hi_bnd; - } -} - -void annEnclCube( // compute smallest enclosing cube - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds) // bounding cube (returned) -{ - int d; - // compute smallest enclosing rect - annEnclRect(pa, pidx, n, dim, bnds); - - ANNcoord max_len = 0; // max length of any side - for (d = 0; d < dim; d++) { // determine max side length - ANNcoord len = bnds.hi[d] - bnds.lo[d]; - if (len > max_len) { // update max_len if longest - max_len = len; - } - } - for (d = 0; d < dim; d++) { // grow sides to match max - ANNcoord len = bnds.hi[d] - bnds.lo[d]; - ANNcoord half_diff = (max_len - len) / 2; - bnds.lo[d] -= half_diff; - bnds.hi[d] += half_diff; - } -} - -//---------------------------------------------------------------------- -// annBoxDistance - utility routine which computes distance from point to -// box (Note: most distances to boxes are computed using incremental -// distance updates, not this function.) -//---------------------------------------------------------------------- - -ANNdist annBoxDistance( // compute distance from point to box - const ANNpoint q, // the point - const ANNpoint lo, // low point of box - const ANNpoint hi, // high point of box - int dim) // dimension of space -{ - register ANNdist dist = 0.0; // sum of squared distances - register ANNdist t; - - for (register int d = 0; d < dim; d++) { - if (q[d] < lo[d]) { // q is left of box - t = ANNdist(lo[d]) - ANNdist(q[d]); - dist = ANN_SUM(dist, ANN_POW(t)); - } - else if (q[d] > hi[d]) { // q is right of box - t = ANNdist(q[d]) - ANNdist(hi[d]); - dist = ANN_SUM(dist, ANN_POW(t)); - } - } - ANN_FLOP(4*dim) // increment floating op count - - return dist; -} - -//---------------------------------------------------------------------- -// annSpread - find spread along given dimension -// annMinMax - find min and max coordinates along given dimension -// annMaxSpread - find dimension of max spread -//---------------------------------------------------------------------- - -ANNcoord annSpread( // compute point spread along dimension - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d) // dimension to check -{ - ANNcoord min = PA(0,d); // compute max and min coords - ANNcoord max = PA(0,d); - for (int i = 1; i < n; i++) { - ANNcoord c = PA(i,d); - if (c < min) min = c; - else if (c > max) max = c; - } - return (max - min); // total spread is difference -} - -void annMinMax( // compute min and max coordinates along dim - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension to check - ANNcoord &min, // minimum value (returned) - ANNcoord &max) // maximum value (returned) -{ - min = PA(0,d); // compute max and min coords - max = PA(0,d); - for (int i = 1; i < n; i++) { - ANNcoord c = PA(i,d); - if (c < min) min = c; - else if (c > max) max = c; - } -} - -int annMaxSpread( // compute dimension of max spread - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim) // dimension of space -{ - int max_dim = 0; // dimension of max spread - ANNcoord max_spr = 0; // amount of max spread - - if (n == 0) return max_dim; // no points, who cares? - - for (int d = 0; d < dim; d++) { // compute spread along each dim - ANNcoord spr = annSpread(pa, pidx, n, d); - if (spr > max_spr) { // bigger than current max - max_spr = spr; - max_dim = d; - } - } - return max_dim; -} - -//---------------------------------------------------------------------- -// annMedianSplit - split point array about its median -// Splits a subarray of points pa[0..n] about an element of given -// rank (median: n_lo = n/2) with respect to dimension d. It places -// the element of rank n_lo-1 correctly (because our splitting rule -// takes the mean of these two). On exit, the array is permuted so -// that: -// -// pa[0..n_lo-2][d] <= pa[n_lo-1][d] <= pa[n_lo][d] <= pa[n_lo+1..n-1][d]. -// -// The mean of pa[n_lo-1][d] and pa[n_lo][d] is returned as the -// splitting value. -// -// All indexing is done indirectly through the index array pidx. -// -// This function uses the well known selection algorithm due to -// C.A.R. Hoare. -//---------------------------------------------------------------------- - - // swap two points in pa array -#define PASWAP(a,b) { int tmp = pidx[a]; pidx[a] = pidx[b]; pidx[b] = tmp; } - -void annMedianSplit( - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord &cv, // cutting value - int n_lo) // split into n_lo and n-n_lo -{ - int l = 0; // left end of current subarray - int r = n-1; // right end of current subarray - while (l < r) { - register int i = (r+l)/2; // select middle as pivot - register int k; - - if (PA(i,d) > PA(r,d)) // make sure last > pivot - PASWAP(i,r) - PASWAP(l,i); // move pivot to first position - - ANNcoord c = PA(l,d); // pivot value - i = l; - k = r; - for(;;) { // pivot about c - while (PA(++i,d) < c) ; - while (PA(--k,d) > c) ; - if (i < k) PASWAP(i,k) else break; - } - PASWAP(l,k); // pivot winds up in location k - - if (k > n_lo) r = k-1; // recurse on proper subarray - else if (k < n_lo) l = k+1; - else break; // got the median exactly - } - if (n_lo > 0) { // search for next smaller item - ANNcoord c = PA(0,d); // candidate for max - int k = 0; // candidate's index - for (int i = 1; i < n_lo; i++) { - if (PA(i,d) > c) { - c = PA(i,d); - k = i; - } - } - PASWAP(n_lo-1, k); // max among pa[0..n_lo-1] to pa[n_lo-1] - } - // cut value is midpoint value - cv = (PA(n_lo-1,d) + PA(n_lo,d))/2.0; -} - -//---------------------------------------------------------------------- -// annPlaneSplit - split point array about a cutting plane -// Split the points in an array about a given plane along a -// given cutting dimension. On exit, br1 and br2 are set so -// that: -// -// pa[ 0 ..br1-1] < cv -// pa[br1..br2-1] == cv -// pa[br2.. n -1] > cv -// -// All indexing is done indirectly through the index array pidx. -// -//---------------------------------------------------------------------- - -void annPlaneSplit( // split points by a plane - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv, // cutting value - int &br1, // first break (values < cv) - int &br2) // second break (values == cv) -{ - int l = 0; - int r = n-1; - for(;;) { // partition pa[0..n-1] about cv - while (l < n && PA(l,d) < cv) l++; - while (r >= 0 && PA(r,d) >= cv) r--; - if (l > r) break; - PASWAP(l,r); - l++; r--; - } - br1 = l; // now: pa[0..br1-1] < cv <= pa[br1..n-1] - r = n-1; - for(;;) { // partition pa[br1..n-1] about cv - while (l < n && PA(l,d) <= cv) l++; - while (r >= br1 && PA(r,d) > cv) r--; - if (l > r) break; - PASWAP(l,r); - l++; r--; - } - br2 = l; // now: pa[br1..br2-1] == cv < pa[br2..n-1] -} - - -//---------------------------------------------------------------------- -// annBoxSplit - split point array about a orthogonal rectangle -// Split the points in an array about a given orthogonal -// rectangle. On exit, n_in is set to the number of points -// that are inside (or on the boundary of) the rectangle. -// -// All indexing is done indirectly through the index array pidx. -// -//---------------------------------------------------------------------- - -void annBoxSplit( // split points by a box - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension of space - ANNorthRect &box, // the box - int &n_in) // number of points inside (returned) -{ - int l = 0; - int r = n-1; - for(;;) { // partition pa[0..n-1] about box - while (l < n && box.inside(dim, PP(l))) l++; - while (r >= 0 && !box.inside(dim, PP(r))) r--; - if (l > r) break; - PASWAP(l,r); - l++; r--; - } - n_in = l; // now: pa[0..n_in-1] inside and rest outside -} - -//---------------------------------------------------------------------- -// annSplitBalance - compute balance factor for a given plane split -// Balance factor is defined as the number of points lying -// below the splitting value minus n/2 (median). Thus, a -// median split has balance 0, left of this is negative and -// right of this is positive. (The points are unchanged.) -//---------------------------------------------------------------------- - -int annSplitBalance( // determine balance factor of a split - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv) // cutting value -{ - int n_lo = 0; - for(int i = 0; i < n; i++) { // count number less than cv - if (PA(i,d) < cv) n_lo++; - } - return n_lo - n/2; -} - -//---------------------------------------------------------------------- -// annBox2Bnds - convert bounding box to list of bounds -// Given two boxes, an inner box enclosed within a bounding -// box, this routine determines all the sides for which the -// inner box is strictly contained with the bounding box, -// and adds an appropriate entry to a list of bounds. Then -// we allocate storage for the final list of bounds, and return -// the resulting list and its size. -//---------------------------------------------------------------------- - -void annBox2Bnds( // convert inner box to bounds - const ANNorthRect &inner_box, // inner box - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int &n_bnds, // number of bounds (returned) - ANNorthHSArray &bnds) // bounds array (returned) -{ - int i; - n_bnds = 0; // count number of bounds - for (i = 0; i < dim; i++) { - if (inner_box.lo[i] > bnd_box.lo[i]) // low bound is inside - n_bnds++; - if (inner_box.hi[i] < bnd_box.hi[i]) // high bound is inside - n_bnds++; - } - - bnds = new ANNorthHalfSpace[n_bnds]; // allocate appropriate size - - int j = 0; - for (i = 0; i < dim; i++) { // fill the array - if (inner_box.lo[i] > bnd_box.lo[i]) { - bnds[j].cd = i; - bnds[j].cv = inner_box.lo[i]; - bnds[j].sd = +1; - j++; - } - if (inner_box.hi[i] < bnd_box.hi[i]) { - bnds[j].cd = i; - bnds[j].cv = inner_box.hi[i]; - bnds[j].sd = -1; - j++; - } - } -} - -//---------------------------------------------------------------------- -// annBnds2Box - convert list of bounds to bounding box -// Given an enclosing box and a list of bounds, this routine -// computes the corresponding inner box. It is assumed that -// the box points have been allocated already. -//---------------------------------------------------------------------- - -void annBnds2Box( - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int n_bnds, // number of bounds - ANNorthHSArray bnds, // bounds array - ANNorthRect &inner_box) // inner box (returned) -{ - annAssignRect(dim, inner_box, bnd_box); // copy bounding box to inner - - for (int i = 0; i < n_bnds; i++) { - bnds[i].project(inner_box.lo); // project each endpoint - bnds[i].project(inner_box.hi); - } -} diff --git a/ANN/src/kd_util.h b/ANN/src/kd_util.h deleted file mode 100644 index 6b4343048c..0000000000 --- a/ANN/src/kd_util.h +++ /dev/null @@ -1,124 +0,0 @@ -//---------------------------------------------------------------------- -// File: kd_util.h -// Programmer: Sunil Arya and David Mount -// Description: Common utilities for kd- trees -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#ifndef ANN_kd_util_H -#define ANN_kd_util_H - -#include "kd_tree.h" // kd-tree declarations - -//---------------------------------------------------------------------- -// externally accessible functions -//---------------------------------------------------------------------- - -double annAspectRatio( // compute aspect ratio of box - int dim, // dimension - const ANNorthRect &bnd_box); // bounding cube - -void annEnclRect( // compute smallest enclosing rectangle - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds); // bounding cube (returned) - -void annEnclCube( // compute smallest enclosing cube - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension - ANNorthRect &bnds); // bounding cube (returned) - -ANNdist annBoxDistance( // compute distance from point to box - const ANNpoint q, // the point - const ANNpoint lo, // low point of box - const ANNpoint hi, // high point of box - int dim); // dimension of space - -ANNcoord annSpread( // compute point spread along dimension - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d); // dimension to check - -void annMinMax( // compute min and max coordinates along dim - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension to check - ANNcoord& min, // minimum value (returned) - ANNcoord& max); // maximum value (returned) - -int annMaxSpread( // compute dimension of max spread - ANNpointArray pa, // point array - ANNidxArray pidx, // point indices - int n, // number of points - int dim); // dimension of space - -void annMedianSplit( // split points along median value - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord &cv, // cutting value - int n_lo); // split into n_lo and n-n_lo - -void annPlaneSplit( // split points by a plane - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv, // cutting value - int &br1, // first break (values < cv) - int &br2); // second break (values == cv) - -void annBoxSplit( // split points by a box - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int dim, // dimension of space - ANNorthRect &box, // the box - int &n_in); // number of points inside (returned) - -int annSplitBalance( // determine balance factor of a split - ANNpointArray pa, // points to split - ANNidxArray pidx, // point indices - int n, // number of points - int d, // dimension along which to split - ANNcoord cv); // cutting value - -void annBox2Bnds( // convert inner box to bounds - const ANNorthRect &inner_box, // inner box - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int &n_bnds, // number of bounds (returned) - ANNorthHSArray &bnds); // bounds array (returned) - -void annBnds2Box( // convert bounds to inner box - const ANNorthRect &bnd_box, // enclosing box - int dim, // dimension of space - int n_bnds, // number of bounds - ANNorthHSArray bnds, // bounds array - ANNorthRect &inner_box); // inner box (returned) - -#endif diff --git a/ANN/src/perf.cpp b/ANN/src/perf.cpp deleted file mode 100644 index 91bb0444ae..0000000000 --- a/ANN/src/perf.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//---------------------------------------------------------------------- -// File: perf.cpp -// Programmer: Sunil Arya and David Mount -// Description: Methods for performance stats -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -// Revision 1.0 04/01/05 -// Changed names to avoid namespace conflicts. -// Added flush after printing performance stats to fix bug -// in Microsoft Windows version. -//---------------------------------------------------------------------- - -#include <ANN/ANN.h> // basic ANN includes -#include <ANN/ANNperf.h> // performance includes - -using namespace std; // make std:: available - -//---------------------------------------------------------------------- -// Performance statistics -// The following data and routines are used for computing -// performance statistics for nearest neighbor searching. -// Because these routines can slow the code down, they can be -// activated and deactiviated by defining the PERF variable, -// by compiling with the option: -DPERF -//---------------------------------------------------------------------- - -//---------------------------------------------------------------------- -// Global counters for performance measurement -//---------------------------------------------------------------------- - -int ann_Ndata_pts = 0; // number of data points -int ann_Nvisit_lfs = 0; // number of leaf nodes visited -int ann_Nvisit_spl = 0; // number of splitting nodes visited -int ann_Nvisit_shr = 0; // number of shrinking nodes visited -int ann_Nvisit_pts = 0; // visited points for one query -int ann_Ncoord_hts = 0; // coordinate hits for one query -int ann_Nfloat_ops = 0; // floating ops for one query -ANNsampStat ann_visit_lfs; // stats on leaf nodes visits -ANNsampStat ann_visit_spl; // stats on splitting nodes visits -ANNsampStat ann_visit_shr; // stats on shrinking nodes visits -ANNsampStat ann_visit_nds; // stats on total nodes visits -ANNsampStat ann_visit_pts; // stats on points visited -ANNsampStat ann_coord_hts; // stats on coordinate hits -ANNsampStat ann_float_ops; // stats on floating ops -// -ANNsampStat ann_average_err; // average error -ANNsampStat ann_rank_err; // rank error - -//---------------------------------------------------------------------- -// Routines for statistics. -//---------------------------------------------------------------------- - -DLL_API void annResetStats(int data_size) // reset stats for a set of queries -{ - ann_Ndata_pts = data_size; - ann_visit_lfs.reset(); - ann_visit_spl.reset(); - ann_visit_shr.reset(); - ann_visit_nds.reset(); - ann_visit_pts.reset(); - ann_coord_hts.reset(); - ann_float_ops.reset(); - ann_average_err.reset(); - ann_rank_err.reset(); -} - -DLL_API void annResetCounts() // reset counts for one query -{ - ann_Nvisit_lfs = 0; - ann_Nvisit_spl = 0; - ann_Nvisit_shr = 0; - ann_Nvisit_pts = 0; - ann_Ncoord_hts = 0; - ann_Nfloat_ops = 0; -} - -DLL_API void annUpdateStats() // update stats with current counts -{ - ann_visit_lfs += ann_Nvisit_lfs; - ann_visit_nds += ann_Nvisit_spl + ann_Nvisit_lfs; - ann_visit_spl += ann_Nvisit_spl; - ann_visit_shr += ann_Nvisit_shr; - ann_visit_pts += ann_Nvisit_pts; - ann_coord_hts += ann_Ncoord_hts; - ann_float_ops += ann_Nfloat_ops; -} - - // print a single statistic -void print_one_stat(char *title, ANNsampStat s, double div) -{ - cout << title << "= [ "; - cout.width(9); cout << s.mean()/div << " : "; - cout.width(9); cout << s.stdDev()/div << " ]<"; - cout.width(9); cout << s.min()/div << " , "; - cout.width(9); cout << s.max()/div << " >\n"; -} - -DLL_API void annPrintStats( // print statistics for a run - ANNbool validate) // true if average errors desired -{ - cout.precision(4); // set floating precision - cout << " (Performance stats: " - << " [ mean : stddev ]< min , max >\n"; - print_one_stat(" leaf_nodes ", ann_visit_lfs, 1); - print_one_stat(" splitting_nodes ", ann_visit_spl, 1); - print_one_stat(" shrinking_nodes ", ann_visit_shr, 1); - print_one_stat(" total_nodes ", ann_visit_nds, 1); - print_one_stat(" points_visited ", ann_visit_pts, 1); - print_one_stat(" coord_hits/pt ", ann_coord_hts, ann_Ndata_pts); - print_one_stat(" floating_ops_(K) ", ann_float_ops, 1000); - if (validate) { - print_one_stat(" average_error ", ann_average_err, 1); - print_one_stat(" rank_error ", ann_rank_err, 1); - } - cout.precision(0); // restore the default - cout << " )\n"; - cout.flush(); -} diff --git a/ANN/src/pr_queue.h b/ANN/src/pr_queue.h deleted file mode 100644 index 3f4b75c878..0000000000 --- a/ANN/src/pr_queue.h +++ /dev/null @@ -1,125 +0,0 @@ -//---------------------------------------------------------------------- -// File: pr_queue.h -// Programmer: Sunil Arya and David Mount -// Description: Include file for priority queue and related -// structures. -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#ifndef PR_QUEUE_H -#define PR_QUEUE_H - -#include <ANN/ANNx.h> // all ANN includes -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// Basic types. -//---------------------------------------------------------------------- -typedef void *PQinfo; // info field is generic pointer -typedef ANNdist PQkey; // key field is distance - -//---------------------------------------------------------------------- -// Priority queue -// A priority queue is a list of items, along with associated -// priorities. The basic operations are insert and extract_minimum. -// -// The priority queue is maintained using a standard binary heap. -// (Implementation note: Indexing is performed from [1..max] rather -// than the C standard of [0..max-1]. This simplifies parent/child -// computations.) User information consists of a void pointer, -// and the user is responsible for casting this quantity into whatever -// useful form is desired. -// -// Because the priority queue is so central to the efficiency of -// query processing, all the code is inline. -//---------------------------------------------------------------------- - -class ANNpr_queue { - - struct pq_node { // node in priority queue - PQkey key; // key value - PQinfo info; // info field - }; - int n; // number of items in queue - int max_size; // maximum queue size - pq_node *pq; // the priority queue (array of nodes) - -public: - ANNpr_queue(int max) // constructor (given max size) - { - n = 0; // initially empty - max_size = max; // maximum number of items - pq = new pq_node[max+1]; // queue is array [1..max] of nodes - } - - ~ANNpr_queue() // destructor - { delete [] pq; } - - ANNbool empty() // is queue empty? - { if (n==0) return ANNtrue; else return ANNfalse; } - - ANNbool non_empty() // is queue nonempty? - { if (n==0) return ANNfalse; else return ANNtrue; } - - void reset() // make existing queue empty - { n = 0; } - - inline void insert( // insert item (inlined for speed) - PQkey kv, // key value - PQinfo inf) // item info - { - if (++n > max_size) annError("Priority queue overflow.", ANNabort); - register int r = n; - while (r > 1) { // sift up new item - register int p = r/2; - ANN_FLOP(1) // increment floating ops - if (pq[p].key <= kv) // in proper order - break; - pq[r] = pq[p]; // else swap with parent - r = p; - } - pq[r].key = kv; // insert new item at final location - pq[r].info = inf; - } - - inline void extr_min( // extract minimum (inlined for speed) - PQkey &kv, // key (returned) - PQinfo &inf) // item info (returned) - { - kv = pq[1].key; // key of min item - inf = pq[1].info; // information of min item - register PQkey kn = pq[n--].key;// last item in queue - register int p = 1; // p points to item out of position - register int r = p<<1; // left child of p - while (r <= n) { // while r is still within the heap - ANN_FLOP(2) // increment floating ops - // set r to smaller child of p - if (r < n && pq[r].key > pq[r+1].key) r++; - if (kn <= pq[r].key) // in proper order - break; - pq[p] = pq[r]; // else swap with child - p = r; // advance pointers - r = p<<1; - } - pq[p] = pq[n+1]; // insert last item in proper place - } -}; - -#endif diff --git a/ANN/src/pr_queue_k.h b/ANN/src/pr_queue_k.h deleted file mode 100644 index c2f01c34a5..0000000000 --- a/ANN/src/pr_queue_k.h +++ /dev/null @@ -1,118 +0,0 @@ -//---------------------------------------------------------------------- -// File: pr_queue_k.h -// Programmer: Sunil Arya and David Mount -// Description: Include file for priority queue with k items. -// Last modified: 01/04/05 (Version 1.0) -//---------------------------------------------------------------------- -// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and -// David Mount. All Rights Reserved. -// -// This software and related documentation is part of the Approximate -// Nearest Neighbor Library (ANN). This software is provided under -// the provisions of the Lesser GNU Public License (LGPL). See the -// file ../ReadMe.txt for further information. -// -// The University of Maryland (U.M.) and the authors make no -// representations about the suitability or fitness of this software for -// any purpose. It is provided "as is" without express or implied -// warranty. -//---------------------------------------------------------------------- -// History: -// Revision 0.1 03/04/98 -// Initial release -//---------------------------------------------------------------------- - -#ifndef PR_QUEUE_K_H -#define PR_QUEUE_K_H - -#include <ANN/ANNx.h> // all ANN includes -#include <ANN/ANNperf.h> // performance evaluation - -//---------------------------------------------------------------------- -// Basic types -//---------------------------------------------------------------------- -typedef ANNdist PQKkey; // key field is distance -typedef int PQKinfo; // info field is int - -//---------------------------------------------------------------------- -// Constants -// The NULL key value is used to initialize the priority queue, and -// so it should be larger than any valid distance, so that it will -// be replaced as legal distance values are inserted. The NULL -// info value must be a nonvalid array index, we use ANN_NULL_IDX, -// which is guaranteed to be negative. -//---------------------------------------------------------------------- - -const PQKkey PQ_NULL_KEY = ANN_DIST_INF; // nonexistent key value -const PQKinfo PQ_NULL_INFO = ANN_NULL_IDX; // nonexistent info value - -//---------------------------------------------------------------------- -// ANNmin_k -// An ANNmin_k structure is one which maintains the smallest -// k values (of type PQKkey) and associated information (of type -// PQKinfo). The special info and key values PQ_NULL_INFO and -// PQ_NULL_KEY means that thise entry is empty. -// -// It is currently implemented using an array with k items. -// Items are stored in increasing sorted order, and insertions -// are made through standard insertion sort. (This is quite -// inefficient, but current applications call for small values -// of k and relatively few insertions.) -// -// Note that the list contains k+1 entries, but the last entry -// is used as a simple placeholder and is otherwise ignored. -//---------------------------------------------------------------------- - -class ANNmin_k { - struct mk_node { // node in min_k structure - PQKkey key; // key value - PQKinfo info; // info field (user defined) - }; - - int k; // max number of keys to store - int n; // number of keys currently active - mk_node *mk; // the list itself - -public: - ANNmin_k(int max) // constructor (given max size) - { - n = 0; // initially no items - k = max; // maximum number of items - mk = new mk_node[max+1]; // sorted array of keys - } - - ~ANNmin_k() // destructor - { delete [] mk; } - - PQKkey ANNmin_key() // return minimum key - { return (n > 0 ? mk[0].key : PQ_NULL_KEY); } - - PQKkey max_key() // return maximum key - { return (n == k ? mk[k-1].key : PQ_NULL_KEY); } - - PQKkey ith_smallest_key(int i) // ith smallest key (i in [0..n-1]) - { return (i < n ? mk[i].key : PQ_NULL_KEY); } - - PQKinfo ith_smallest_info(int i) // info for ith smallest (i in [0..n-1]) - { return (i < n ? mk[i].info : PQ_NULL_INFO); } - - inline void insert( // insert item (inlined for speed) - PQKkey kv, // key value - PQKinfo inf) // item info - { - register int i; - // slide larger values up - for (i = n; i > 0; i--) { - if (mk[i-1].key > kv) - mk[i] = mk[i-1]; - else - break; - } - mk[i].key = kv; // store element here - mk[i].info = inf; - if (n < k) n++; // increment number of items - ANN_FLOP(k-i+1) // increment floating ops - } -}; - -#endif diff --git a/MathEval/Makefile b/MathEval/Makefile deleted file mode 100644 index 8d64db27e7..0000000000 --- a/MathEval/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# $Id: Makefile,v 1.8 2005-07-15 10:31:06 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshMathEval.a -INCLUDE = -I../Common -I../DataStr - -CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} - -SRC = matheval.cpp\ - node.cpp\ - scanner.yy.cpp\ - parser.tab.cpp\ - symbol_table.cpp\ - xmath.cpp - -OBJ = ${SRC:.cpp=.o} - -.SUFFIXES: .o .cpp - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.cpp.o: - ${CXX} ${CFLAGS} -c $< - -parser: - bison --output parser.tab.cpp -pme -d parser.y - if [ -r parser.tab.cpp.h ]; then mv parser.tab.cpp.h parser.tab.hpp ; fi - flex -oscanner.yy.cpp -Pme scanner.l - -clean: - rm -f *.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CC} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -# 1 "/Users/geuzaine/.gmsh/MathEval//" -matheval.o: matheval.cpp common.h ../DataStr/Malloc.h matheval.h node.h \ - symbol_table.h -# 1 "/Users/geuzaine/.gmsh/MathEval//" -node.o: node.cpp common.h ../DataStr/Malloc.h node.h symbol_table.h -# 1 "/Users/geuzaine/.gmsh/MathEval//" -scanner.yy.o: scanner.yy.cpp common.h ../DataStr/Malloc.h node.h \ - symbol_table.h parser.tab.hpp -# 1 "/Users/geuzaine/.gmsh/MathEval//" -parser.tab.o: parser.tab.cpp common.h ../DataStr/Malloc.h node.h \ - symbol_table.h -# 1 "/Users/geuzaine/.gmsh/MathEval//" -symbol_table.o: symbol_table.cpp common.h ../DataStr/Malloc.h \ - symbol_table.h xmath.h -# 1 "/Users/geuzaine/.gmsh/MathEval//" -xmath.o: xmath.cpp xmath.h diff --git a/MathEval/README b/MathEval/README deleted file mode 100644 index 721ce8f768..0000000000 --- a/MathEval/README +++ /dev/null @@ -1,23 +0,0 @@ - -This directory contains a modified version of GNU libmatheval. - -Copyright (C) 1999, 2002, 2003 Aleksandar B. Samardzic - -Copying and distribution of this file, with or without modification, are -permitted in any medium without royalty provided the copyright notice -and this notice are preserved. - -WHAT IS IT? - -GNU libmatheval is a library which contains several procedures that make -it possible to create an in-memory tree from the string representation -of a mathematical function over single or multiple variables. This tree -can be used later to evaluate a function for specified variable values, -to create a corresponding tree for the function derivative over a -specified variable, or to write a textual tree representation to a -specified string. - -BUGS - -Please report bugs and eventually send patches to -<bug-libmatheval@gnu.org> mailing list. diff --git a/MathEval/common.h b/MathEval/common.h deleted file mode 100644 index 781b6df4ad..0000000000 --- a/MathEval/common.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef COMMON_H -#define COMMON_H - -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "Malloc.h" - -/* Macro definitions to simplify corresponding function calls. */ -#define XMALLOC(type, num) ((type *) Malloc ((num) * sizeof(type))) -#define XREALLOC(type, p, num) ((type *) Realloc ((p), (num) * sizeof(type))) -#define XCALLOC(type, num) ((type *) Calloc ((num), sizeof(type))) -#define XFREE(stale) Free (stale); - -#endif diff --git a/MathEval/matheval.cpp b/MathEval/matheval.cpp deleted file mode 100644 index efc5e1b1cb..0000000000 --- a/MathEval/matheval.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include "common.h" -#include "matheval.h" -#include "node.h" -#include "symbol_table.h" - -/* Minimal length of evaluator symbol table. */ -#define MIN_TABLE_LENGTH 211 - -/* - * Function used to parse string representing function (this function is - * generated by parser generator). - */ -extern int meparse(); - -/* - * Following variables are needed for parsing (parser is able to communicate - * with program from which it is used through global variables only). - */ -char *matheval_input_string; /* String representing function. */ -Node *matheval_root; /* Root of tree representation of - * function. */ -SymbolTable *matheval_symbol_table; /* Evaluator symbol table. */ -int matheval_ok; /* Flag determining if parsing went OK. */ - -/* Data structure representing evaluator. */ -typedef struct { - Node *root; /* Root of tree representation of - * function. */ - SymbolTable *symbol_table; /* Evalutor symbol table. */ -} Evaluator; - -void * -evaluator_create(char *string) -{ - Evaluator *evaluator; /* Evaluator representing function given - * by string. */ - char *stringn; /* Copy of string terminated by newline - * character. */ - - /* - * Copy string representing function and terminate it with newline - * (this is necessary because parser expect newline character to - * terminate its input). - */ - stringn = XMALLOC(char, strlen(string) + 2); - - strcpy(stringn, string); - strcat(stringn, "\n"); - - /* - * Initialize global variables used by parser. - */ - matheval_input_string = stringn; - matheval_root = NULL; - matheval_symbol_table = symbol_table_create(MIN_TABLE_LENGTH); - matheval_ok = 1; - - /* - * Do parsing. - */ - meparse(); - - /* - * Free copy of string representing function. - */ - XFREE(stringn); - - /* - * Return null pointer as error indicator if parsing error occured. - */ - if (!matheval_ok || !matheval_root){ - node_destroy(matheval_root); - symbol_table_destroy(matheval_symbol_table); - return NULL; - } - - /* - * Simplify tree represention of function. - */ - matheval_root = node_simplify(matheval_root); - - /* - * Allocate memory for and initialize evaluator data structure. - */ - evaluator = XMALLOC(Evaluator, 1); - evaluator->root = matheval_root; - evaluator->symbol_table = matheval_symbol_table; - - return evaluator; -} - -void -evaluator_destroy(void *evaluator) -{ - /* - * Destroy tree represention of function, symbol table, as well as - * data structure representing evaluator. - */ - node_destroy(((Evaluator *) evaluator)->root); - symbol_table_destroy(((Evaluator *) evaluator)->symbol_table); - XFREE(evaluator); -} - -double -evaluator_evaluate(void *evaluator, int count, char **names, double *values) -{ - Record *record; /* Symbol table record corresponding to - * give variable name. */ - int i; /* Loop counter. */ - - /* - * Assign values to symbol table records corresponding to variable - * names. - */ - for (i = 0; i < count; i++) { - record = symbol_table_lookup(((Evaluator *) evaluator)->symbol_table, names[i]); - if (record && record->type == 'v') - record->data.value = values[i]; - } - - /* - * Evaluate function value using tree represention of function. - */ - return node_evaluate(((Evaluator *) evaluator)->root); -} - -int -evaluator_calculate_length(void *evaluator) -{ - /* - * Calculate length of evaluator textual representation. - */ - return node_calculate_length(((Evaluator *) evaluator)->root); -} - -void -evaluator_write(void *evaluator, char *string) -{ - /* - * Write evaluator textual representation to given string. - */ - node_write(((Evaluator *) evaluator)->root, string); -} - -void * -evaluator_derivative(void *evaluator, char *name) -{ - Evaluator *derivative; /* Derivative function evaluator. */ - - /* - * Allocate memory for and initalize data structure for evaluator - * representing derivative of function given by evaluator. - */ - derivative = XMALLOC(Evaluator, 1); - derivative->root = node_simplify(node_derivative(((Evaluator *) evaluator)->root, name, - ((Evaluator *) evaluator)->symbol_table)); - derivative->symbol_table = symbol_table_assign(((Evaluator *) evaluator)->symbol_table); - - return derivative; -} - -double -evaluator_evaluate_x(void *evaluator, double x) -{ - char *names[] = {"x"}; /* Array of variable names. */ - double values[] = {x}; /* Array of variable values. */ - - /* - * Evaluate function for given values of variable "x". - */ - return evaluator_evaluate(evaluator, sizeof(names) / sizeof(names[0]), names, values); -} - -double -evaluator_evaluate_x_y(void *evaluator, double x, double y) -{ - char *names[] = {"x", "y"}; /* Array of variable - * names. */ - double values[] = {x, y}; /* Array of variable values. */ - - /* - * Evaluate function for given values of variable "x" and "y". - */ - return evaluator_evaluate(evaluator, sizeof(names) / sizeof(names[0]), names, values); -} - -double -evaluator_evaluate_x_y_z(void *evaluator, double x, double y, double z) -{ - char *names[] = {"x", "y", "z"}; /* Array of variable - * names. */ - double values[] = {x, y, z}; /* Array of variable - * values. */ - - /* - * Evaluate function for given values of variable "x", "y" and "z". - */ - return evaluator_evaluate(evaluator, sizeof(names) / sizeof(names[0]), names, values); -} - -void * -evaluator_derivative_x(void *evaluator) -{ - /* - * Differentiate function using derivation variable "x". - */ - return evaluator_derivative(evaluator, "x"); -} - -void * -evaluator_derivative_y(void *evaluator) -{ - /* - * Differentiate function using derivation variable "y". - */ - return evaluator_derivative(evaluator, "y"); -} - -void * -evaluator_derivative_z(void *evaluator) -{ - /* - * Differentiate function using derivation variable "z". - */ - return evaluator_derivative(evaluator, "z"); -} diff --git a/MathEval/matheval.h b/MathEval/matheval.h deleted file mode 100644 index b155f4003c..0000000000 --- a/MathEval/matheval.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#ifndef EVALUATOR_H -#define EVALUATOR_H - -/* - * Create evaluator from string representing function. Function - * returns pointer that should be passed as first argument to all - * other library functions. If an error occurs, function will return - * null pointer. - */ -void *evaluator_create(char *string); - -/* - * Destroy evaluator specified. - */ -void evaluator_destroy(void *evaluator); - -/* - * Evaluate function represented by evaluator given. Variable names - * and respective values are represented by function third and fourth - * argument. Number of variables i.e. length of these two arrays is - * given by second argument. Function returns evaluated function - * value. In case that function contains variables with names not - * given through third function argument, value of this variable is - * undeterminated. - */ -double evaluator_evaluate(void *evaluator, int count, char **names, double *values); - -/* - * Calculate length of textual representation of evaluator. This - * procedure is inteded to be used along with evaluator_write() - * procedure that follows. - */ -int evaluator_calculate_length(void *evaluator); - -/* - * Write textual representation of evaluator (i.e. corresponding - * function) to given string. No string overflow is checked by this - * procedure; string of appropriate length (calculated beforehand - * using above evaluator_calculate_length() procedure) is expected to - * be allocated beforehand. - */ -void evaluator_write(void *evaluator, char *length); - -/* - * Create evaluator for first derivative of function represented by - * evaluator given as first argument using derivative variable given - * as second argument. - */ -void *evaluator_derivative(void *evaluator, char *name); - -/* - * Helper functions to simplify evaluation when variable names are - * "x", "x" and "y" or "x" and "y" and "z" respectively. - */ -double evaluator_evaluate_x(void *evaluator, double x); -double evaluator_evaluate_x_y(void *evaluator, double x, double y); -double evaluator_evaluate_x_y_z(void *evaluator, double x, double y, double z); - -/* - * Helper functions to simplify differentiation when variable names - * are "x" or "y" or "z" respectively. - */ -void *evaluator_derivative_x(void *evaluator); -void *evaluator_derivative_y(void *evaluator); -void *evaluator_derivative_z(void *evaluator); - -#endif diff --git a/MathEval/node.cpp b/MathEval/node.cpp deleted file mode 100644 index 420dfb6717..0000000000 --- a/MathEval/node.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <assert.h> -#include <stdarg.h> -#include "common.h" -#include "node.h" - -Node * -node_create(char type,...) -{ - Node *node; /* New node. */ - va_list ap; /* Variable argument list. */ - - /* - * Allocate memory for node and initialize its type. - */ - node = XMALLOC(Node, 1); - node->type = type; - - /* - * According to node type, initialize rest of the node from variable - * argument list. - */ - va_start(ap, type); - switch (node->type) { - case 'c': - /* - * Initialize constant value. - */ - node->data.constant = va_arg(ap, double); - break; - - case 'v': - /* - * Remember pointer to symbol table record describing - * variable. - */ - node->data.variable = va_arg(ap, Record *); - break; - - case 'f': - /* - * Remember pointer to symbol table record describing - * function and initialize function argument. - */ - node->data.function.record = va_arg(ap, Record *); - node->data.function.child = va_arg(ap, Node *); - break; - - case 'u': - /* - * Initialize operator type and operand. - */ - node->data.un_op.operatorr = (char) va_arg(ap, int); - node->data.un_op.child = va_arg(ap, Node *); - break; - - case 'b': - /* - * Initialize operator type and operands. - */ - node->data.un_op.operatorr = (char) va_arg(ap, int); - node->data.bin_op.left = va_arg(ap, Node *); - node->data.bin_op.right = va_arg(ap, Node *); - break; - - default: - assert(0); - } - va_end(ap); - - return node; -} - -void -node_destroy(Node * node) -{ - /* - * Skip if node already null (this may occur during simplification). - */ - if (!node) - return; - - /* - * If necessary, destroy subtree rooted at node. - */ - switch (node->type) { - case 'c': - case 'v': - break; - - case 'f': - node_destroy(node->data.function.child); - break; - - case 'u': - node_destroy(node->data.un_op.child); - break; - - case 'b': - node_destroy(node->data.bin_op.left); - node_destroy(node->data.bin_op.right); - break; - } - - /* - * Deallocate memory used by node. - */ - XFREE(node); -} - -Node * -node_copy(Node * node) -{ - /* - * According to node type, create (deep) copy of subtree rooted at - * node. - */ - switch (node->type) { - case 'c': - return node_create('c', node->data.constant); - - case 'v': - return node_create('v', node->data.variable); - - case 'f': - return node_create('f', node->data.function.record, node_copy(node->data.function.child)); - - case 'u': - return node_create('u', node->data.un_op.operatorr, node_copy(node->data.un_op.child)); - - case 'b': - return node_create('b', node->data.bin_op.operatorr, node_copy(node->data.bin_op.left), node_copy(node->data.bin_op.right)); - } - - return NULL; -} - -Node * -node_simplify(Node * node) -{ - /* - * According to node type, apply further simplifications. - */ - switch (node->type) { - case 'c': - case 'v': - return node; - - case 'f': - /* - * Simplify function argument and if constant evaluate function - * and replace function node with constant node (unless the - * function is Rand(x)). - */ - node->data.function.child = node_simplify(node->data.function.child); - if (node->data.function.child->type == 'c' && - strcmp(node->data.function.record->name, "Rand")) { - double value = node_evaluate(node); - - node_destroy(node); - return node_create('c', value); - } - else - return node; - - case 'u': - /* - * Simplify unary operator operand and if constant apply - * operator and replace operator node with constant node. - */ - node->data.un_op.child = node_simplify(node->data.un_op.child); - if (node->data.un_op.operatorr == '-' && node->data.un_op.child->type == 'c') { - double value = node_evaluate(node); - - node_destroy(node); - return node_create('c', value); - } - else - return node; - - case 'b': - /* - * Simplify binary operator operands. - */ - node->data.bin_op.left = node_simplify(node->data.bin_op.left); - node->data.bin_op.right = node_simplify(node->data.bin_op.right); - - /* - * If operands constant apply operator and replace operator - * node with constant node. - */ - if (node->data.bin_op.left->type == 'c' && node->data.bin_op.right->type == 'c') { - double value = node_evaluate(node); - - node_destroy(node); - return node_create('c', value); - } - /* - * Eliminate 0 as neutral addition operand. - */ - else if (node->data.bin_op.operatorr == '+') - if (node->data.bin_op.left->type == 'c' && node->data.bin_op.left->data.constant == 0) { - Node *right; - right = node->data.bin_op.right; - node->data.bin_op.right = NULL; - node_destroy(node); - return right; - } - else if (node->data.bin_op.right->type == 'c' && node->data.bin_op.right->data.constant == 0) { - Node *left; - left = node->data.bin_op.left; - node->data.bin_op.left = NULL; - node_destroy(node); - return left; - } - else - return node; - /* - * Eliminate 0 as neutral subtraction right operand. - */ - else if (node->data.bin_op.operatorr == '-') - if (node->data.bin_op.right->type == 'c' && node->data.bin_op.right->data.constant == 0) { - Node *left; - left = node->data.bin_op.left; - node->data.bin_op.left = NULL; - node_destroy(node); - return left; - } - else - return node; - /* - * Eliminate 1 as neutral multiplication operand. - */ - else if (node->data.bin_op.operatorr == '*') - if (node->data.bin_op.left->type == 'c' && node->data.bin_op.left->data.constant == 1) { - Node *right; - right = node->data.bin_op.right; - node->data.bin_op.right = NULL; - node_destroy(node); - return right; - } - else if (node->data.bin_op.right->type == 'c' && node->data.bin_op.right->data.constant == 1) { - Node *left; - left = node->data.bin_op.left; - node->data.bin_op.left = NULL; - node_destroy(node); - return left; - } - else - return node; - /* - * Eliminate 1 as neutral division right operand. - */ - else if (node->data.bin_op.operatorr == '/') - if (node->data.bin_op.right->type == 'c' && node->data.bin_op.right->data.constant == 1) { - Node *left; - left = node->data.bin_op.left; - node->data.bin_op.left = NULL; - node_destroy(node); - return left; - } - else - return node; - /* - * Eliminate 0 and 1 as both left and right exponentiation - * operands. - */ - else if (node->data.bin_op.operatorr == '^') - if (node->data.bin_op.left->type == 'c' && node->data.bin_op.left->data.constant == 0) { - node_destroy(node); - return node_create('c', 0.0); - } - else if (node->data.bin_op.left->type == 'c' && node->data.bin_op.left->data.constant == 1) { - node_destroy(node); - return node_create('c', 1.0); - } - else if (node->data.bin_op.right->type == 'c' && node->data.bin_op.right->data.constant == 0) { - node_destroy(node); - return node_create('c', 1.0); - } - else if (node->data.bin_op.right->type == 'c' && node->data.bin_op.right->data.constant == 1) { - Node *left; - left = node->data.bin_op.left; - node->data.bin_op.left = NULL; - node_destroy(node); - return left; - } - else - return node; - else - return node; - } - - return NULL; -} - -double -node_evaluate(Node * node) -{ - /* - * According to node type, evaluate subtree rooted at node. - */ - switch (node->type) { - case 'c': - return node->data.constant; - - case 'v': - /* - * Variable values are used from symbol table. - */ - return node->data.variable->data.value; - - case 'f': - /* - * Functions are evaluated through symbol table. - */ - return (*node->data.function.record->data.function) (node_evaluate(node->data.function.child)); - - case 'u': - /* - * Unary operator node is evaluated according to operator - * type. - */ - switch (node->data.un_op.operatorr) { - case '-': - return -node_evaluate(node->data.un_op.child); - } - - case 'b': - /* - * Binary operator node is evaluated according to operator - * type. - */ - switch (node->data.un_op.operatorr) { - case '+': - return node_evaluate(node->data.bin_op.left) + node_evaluate(node->data.bin_op.right); - - case '-': - return node_evaluate(node->data.bin_op.left) - node_evaluate(node->data.bin_op.right); - - case '*': - return node_evaluate(node->data.bin_op.left) * node_evaluate(node->data.bin_op.right); - - case '/': - return node_evaluate(node->data.bin_op.left) / node_evaluate(node->data.bin_op.right); - - case '^': - return pow(node_evaluate(node->data.bin_op.left), node_evaluate(node->data.bin_op.right)); - } - } - - return 0; -} - -Node * -node_derivative(Node * node, char *name, SymbolTable * symbol_table) -{ - /* - * According to node type, derivative tree for subtree rooted at node - * is created. - */ - switch (node->type) { - case 'c': - /* - * Derivative of constant equals 0. - */ - return node_create('c', 0.0); - - case 'v': - /* - * Derivative of variable equals 1 if variable is derivative - * variable, 0 otherwise. - */ - return node_create('c', (!strcmp(name, node->data.variable->name)) ? 1.0 : 0.0); - - case 'f': - /* - * Apply rule of exponential function derivative. - */ - if (!strcmp(node->data.function.record->name, "Exp")) - return node_create('b', '*', node_derivative(node->data.function.child, name, symbol_table), node_copy(node)); - /* - * Apply rule of logarithmic function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Log")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_copy(node->data.function.child)); - /* - * Apply rule of square root function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Sqrt")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '*', node_create('c', 2.0), node_copy(node))); - /* - * Apply rule of sine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Sin")) - return node_create('b', '*', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Cos"), node_copy(node->data.function.child))); - /* - * Apply rule of cosine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Cos")) - return node_create('u', '-', node_create('b', '*', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Sin"), node_copy(node->data.function.child)))); - /* - * Apply rule of tangent function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Tan")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '^', node_create('f', symbol_table_lookup(symbol_table, "Cos"), node_copy(node->data.function.child)), node_create('c', 2.0))); - /* - * Apply rule of cotangent function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Ctan")) - return node_create('u', '-', node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '^', node_create('f', symbol_table_lookup(symbol_table, "Sin"), node_copy(node->data.function.child)), node_create('c', 2.0)))); - /* - * Apply rule of inverse sine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Asin")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Sqrt"), node_create('b', '-', node_create('c', 1.0), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0))))); - /* - * Apply rule of inverse cosine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Acos")) - return node_create('u', '-', node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Sqrt"), node_create('b', '-', node_create('c', 1.0), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0)))))); - /* - * Apply rule of inverse tangent function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Atan")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '+', node_create('c', 1.0), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0)))); - /* - * Apply rule of inverse cotanget function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Actan")) - return node_create('u', '-', node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '+', node_create('c', 1.0), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0))))); - /* - * Apply rule of hyperbolic sine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Sinh")) - return node_create('b', '*', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Cosh"), node_copy(node->data.function.child))); - /* - * Apply rule of hyperbolic cosine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Cosh")) - return node_create('b', '*', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Sinh"), node_copy(node->data.function.child))); - /* - * Apply rule of hyperbolic tangent function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Tanh")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '^', node_create('f', symbol_table_lookup(symbol_table, "Cosh"), node_copy(node->data.function.child)), node_create('c', 2.0))); - /* - * Apply rule of hyperbolic cotangent function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Ctanh")) - return node_create('u', '-', node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '^', node_create('f', symbol_table_lookup(symbol_table, "sinh"), node_copy(node->data.function.child)), node_create('c', 2.0)))); - /* - * Apply rule of inverse hyperbolic sine function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Asinh")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Sqrt"), node_create('b', '-', node_create('c', 1.0), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0))))); - /* - * Apply rule of inverse hyperbolic cosine function - * derivative. - */ - else if (!strcmp(node->data.function.record->name, "Acosh")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('f', symbol_table_lookup(symbol_table, "Sqrt"), node_create('b', '-', node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0)), node_create('c', 1.0)))); - /* - * Apply rule of inverse hyperbolic tangent function - * derivative. - */ - else if (!strcmp(node->data.function.record->name, "Atanh")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '-', node_create('c', 1.0), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0)))); - /* - * Apply rule of inverse hyperbolic cotangent function - * derivative. - */ - else if (!strcmp(node->data.function.record->name, "Actanh")) - return node_create('b', '/', node_derivative(node->data.function.child, name, symbol_table), node_create('b', '-', node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0)), node_create('c', 1.0))); - /* - * Apply rule of absolute value function derivative. - */ - else if (!strcmp(node->data.function.record->name, "Fabs")) - return node_create('b', '/', node_create('b', '*', node_derivative(node->data.function.child, name, symbol_table), node_copy(node->data.function.child)), node_create('f', symbol_table_lookup(symbol_table, "Sqrt"), node_create('b', '^', node_copy(node->data.function.child), node_create('c', 2.0)))); - - case 'u': - switch (node->data.un_op.operatorr) { - case '-': - /* - * Apply (-f)'=-f' derivative rule. - */ - return node_create('u', '-', node_derivative(node->data.un_op.child, name, symbol_table)); - } - - case 'b': - switch (node->data.bin_op.operatorr) { - case '+': - /* - * Apply (f+g)'=f'+g' derivative rule. - */ - return node_create('b', '+', node_derivative(node->data.bin_op.left, name, symbol_table), node_derivative(node->data.bin_op.right, name, symbol_table)); - - case '-': - /* - * Apply (f-g)'=f'-g' derivative rule. - */ - return node_create('b', '-', node_derivative(node->data.bin_op.left, name, symbol_table), node_derivative(node->data.bin_op.right, name, symbol_table)); - - case '*': - /* - * Apply (f*g)'=f'*g+f*g' derivative rule. - */ - return node_create('b', '+', node_create('b', '*', node_derivative(node->data.bin_op.left, name, symbol_table), node_copy(node->data.bin_op.right)), node_create('b', '*', node_copy(node->data.bin_op.left), node_derivative(node->data.bin_op.right, name, symbol_table))); - - case '/': - /* - * Apply (f/g)'=(f'*g-f*g')/g^2 derivative rule. - */ - return node_create('b', '/', node_create('b', '-', node_create('b', '*', node_derivative(node->data.bin_op.left, name, symbol_table), node_copy(node->data.bin_op.right)), node_create('b', '*', node_copy(node->data.bin_op.left), node_derivative(node->data.bin_op.right, name, symbol_table))), node_create('b', '^', node_copy(node->data.bin_op.right), node_create('c', 2.0))); - - case '^': - /* - * If right operand of exponentiation constant apply - * (f^n)'=n*f^(n-1)*f' derivative rule. - */ - if (node->data.bin_op.right->type == 'c') - return node_create('b', '*', node_create('b', '*', node_create('c', node->data.bin_op.right->data.constant), node_derivative(node->data.bin_op.left, name, symbol_table)), node_create('b', '^', node_copy(node->data.bin_op.left), node_create('c', node->data.bin_op.right->data.constant - 1.0))); - /* - * Otherwise, apply logaritmhic derivative rule: - * (log(f^g))'=(f^g)'/f^g => - * (f^g)'=f^g*(log(f^g))'=f^g*(g*log(f))' - */ - else { - Node *log_node, *derivative; - log_node = node_create('b', '*', node_copy(node->data.bin_op.right), node_create('f', symbol_table_lookup(symbol_table, "Log"), node_copy(node->data.bin_op.left))); - derivative = node_create('b', '*', node_copy(node), node_derivative(log_node, name, symbol_table)); - node_destroy(log_node); - return derivative; - } - } - } - - return NULL; -} - -int -node_calculate_length(Node * node) -{ - char string[1024]; /* String representing constant node - * value. */ - int length; /* Length of above string. */ - - /* - * According to node type, calculate length of string representing - * subtree rooted at node. - */ - switch (node->type) { - case 'c': - length = 0; - if (node->data.constant < 0) - length += 1; - sprintf(string, "%g", node->data.constant); - length += strlen(string); - if (node->data.constant < 0) - length += 1; - return length; - - case 'v': - return strlen(node->data.variable->name); - - case 'f': - return strlen(node->data.function.record->name) + 1 + node_calculate_length(node->data.function.child) + 1; - break; - - case 'u': - return 1 + 1 + node_calculate_length(node->data.un_op.child) + 1; - - case 'b': - return 1 + node_calculate_length(node->data.bin_op.left) + 1 + node_calculate_length(node->data.bin_op.right) + 1; - } - - return 0; -} - -void -node_write(Node * node, char *string) -{ - /* - * According to node type, write subtree rooted at node to node - * string variable. Always use parenthesis to resolve operator - * precedence. - */ - switch (node->type) { - case 'c': - if (node->data.constant < 0) { - sprintf(string, "%c", '('); - string += strlen(string); - } - sprintf(string, "%g", node->data.constant); - string += strlen(string); - if (node->data.constant < 0) - sprintf(string, "%c", ')'); - break; - - case 'v': - sprintf(string, "%s", node->data.variable->name); - break; - - case 'f': - sprintf(string, "%s%c", node->data.function.record->name, '('); - string += strlen(string); - node_write(node->data.function.child, string); - string += strlen(string); - sprintf(string, "%c", ')'); - break; - - case 'u': - sprintf(string, "%c", '('); - string += strlen(string); - sprintf(string, "%c", node->data.un_op.operatorr); - string += strlen(string); - node_write(node->data.un_op.child, string); - string += strlen(string); - sprintf(string, "%c", ')'); - break; - - case 'b': - sprintf(string, "%c", '('); - string += strlen(string); - node_write(node->data.bin_op.left, string); - string += strlen(string); - sprintf(string, "%c", node->data.bin_op.operatorr); - string += strlen(string); - node_write(node->data.bin_op.right, string); - string += strlen(string); - sprintf(string, "%c", ')'); - break; - } -} diff --git a/MathEval/node.h b/MathEval/node.h deleted file mode 100644 index c2744aae19..0000000000 --- a/MathEval/node.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#ifndef NODE_H -#define NODE_H 1 - -#include "symbol_table.h" - -/* Data structure representing function tree node. */ -typedef struct _Node { - char type; /* Node type ('c' for constant, 'v' for - * variable, 'f' for function, 'u' for unary - * operator, 'b' for binary operator). */ - union { - double constant; /* Constant value. */ - Record *variable; /* Symbol table record for - * variable. */ - struct { - Record *record; /* Symbol table record for - * function. */ - struct _Node *child; /* Function argument node. */ - } function; /* Structure representing - * function. */ - struct { - char operatorr;/* Operator type ('-' - * for unary minus). */ - struct _Node *child; /* Operand node. */ - } un_op; /* Structure representing unary - * operator. */ - struct { - char operatorr;/* Operator type ('+' - * for adition, '-' for - * subtraction, '*' for - * multiplication, '/' - * for division and '^' - * for exponentiation). */ - struct _Node *left, *right; /* Operands nodes. */ - } bin_op; /* Structure representing binary - * operator. */ - } data; -} Node; - -/* - * Create node of given type and initialize it from optional arguments. - * Function returns pointer to node object that should be passed as first - * argument to all other node functions. - */ -Node *node_create(char type,...); - -/* Destroy subtree rooted at specified node. */ -void node_destroy(Node * node); - -/* - * Make a copy of subtree rooted at given node. Deep copy operation is - * employed. - */ -Node *node_copy(Node * node); - -/* - * Simplify subtree rooted at given node. Function returns root of - * simplified subtree (that may or may not be original node). - */ -Node *node_simplify(Node * node); - -/* - * Evaluate subtree rooted at given node. For variables, values from symbol - * table are used. - */ -double node_evaluate(Node * node); - -/* - * Create derivative tree for subtree rooted at given node. Second argument - * is derivation variable, third argument is symbol table (needed for - * functions derivatives). Function returns root of corresponding derivation - * tree. - */ -Node *node_derivative(Node * node, char *name, SymbolTable * symbol_table); - -/* - * Calculate length of the string representing subtree rooted at specified - * node. - */ -int node_calculate_length(Node * node); - -/* - * Write subtree rooted at specified node to given string variable. No - * checking of string overflow is done by this procedure; it is expected that - * string of appropriate length is passed as argument. - */ -void node_write(Node * node, char *string); - -#endif diff --git a/MathEval/parser.tab.cpp b/MathEval/parser.tab.cpp deleted file mode 100644 index 87a34199c0..0000000000 --- a/MathEval/parser.tab.cpp +++ /dev/null @@ -1,1044 +0,0 @@ - -/* A Bison parser, made from parser.y - by GNU Bison version 1.28 */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define yyparse meparse -#define yylex melex -#define yyerror meerror -#define yylval melval -#define yychar mechar -#define yydebug medebug -#define yynerrs menerrs -#define NUMBER 257 -#define VARIABLE 258 -#define FUNCTION 259 -#define NEG 260 - -#line 1 "parser.y" - -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include "common.h" -#include "node.h" - -/* Variables used to communicate with code using parser. */ -extern Node* matheval_root; /* Root of tree representation of function. */ -extern int matheval_ok; /* Flag representing success of parsing. */ - -/* Report parsing error. */ -int yyerror (char *s); - -/* Function used to tokenize string representing function (this function - is generated by scanner generator). */ -int yylex (void); - -/* Function used to flush the internal flex buffer when we exit - prematurely (i.e., in case of a parse error) so that the next time - we call the scanner, all is nicely reset. Without this, the - behaviour of the next call after an error is unpredictable. */ -void force_buffer_flush(void); - - -#line 48 "parser.y" -typedef union { - Node *node; - Record *record; -} YYSTYPE; -#include <stdio.h> - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 26 -#define YYFLAG -32768 -#define YYNTBASE 15 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 260 ? yytranslate[x] : 17) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, - 14, 8, 7, 2, 6, 2, 9, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 10 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 3, 5, 7, 11, 15, 19, 23, 26, 30, - 35 -}; - -static const short yyrhs[] = { 16, - 12, 0, 3, 0, 4, 0, 16, 7, 16, 0, - 16, 6, 16, 0, 16, 8, 16, 0, 16, 9, - 16, 0, 6, 16, 0, 16, 11, 16, 0, 5, - 13, 16, 14, 0, 13, 16, 14, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 71, 78, 81, 84, 88, 92, 96, 100, 104, 108, - 112 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","NUMBER", -"VARIABLE","FUNCTION","'-'","'+'","'*'","'/'","NEG","'^'","'\\n'","'('","')'", -"input","expression", NULL -}; -#endif - -static const short yyr1[] = { 0, - 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16 -}; - -static const short yyr2[] = { 0, - 2, 1, 1, 3, 3, 3, 3, 2, 3, 4, - 3 -}; - -static const short yydefact[] = { 0, - 2, 3, 0, 0, 0, 0, 0, 8, 0, 0, - 0, 0, 0, 0, 1, 0, 11, 5, 4, 6, - 7, 9, 10, 0, 0, 0 -}; - -static const short yydefgoto[] = { 24, - 6 -}; - -static const short yypact[] = { 8, --32768,-32768, -11, 8, 8, 27, 8, -7, 9, 8, - 8, 8, 8, 8,-32768, 18,-32768, 32, 32, -7, - -7,-32768,-32768, 5, 19,-32768 -}; - -static const short yypgoto[] = {-32768, - -4 -}; - - -#define YYLAST 43 - - -static const short yytable[] = { 8, - 9, 7, 16, 14, 25, 18, 19, 20, 21, 22, - 1, 2, 3, 4, 10, 11, 12, 13, 26, 14, - 5, 0, 17, 10, 11, 12, 13, 0, 14, 0, - 0, 23, 10, 11, 12, 13, 0, 14, 15, 12, - 13, 0, 14 -}; - -static const short yycheck[] = { 4, - 5, 13, 7, 11, 0, 10, 11, 12, 13, 14, - 3, 4, 5, 6, 6, 7, 8, 9, 0, 11, - 13, -1, 14, 6, 7, 8, 9, -1, 11, -1, - -1, 14, 6, 7, 8, 9, -1, 11, 12, 8, - 9, -1, 11 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison.simple" -/* This file comes from bison-1.28. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include <alloca.h> -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include <malloc.h> -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include <malloc.h> */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 217 "/usr/share/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 71 "parser.y" -{ - matheval_root = yyvsp[-1].node; - return 1; -; - break;} -case 2: -#line 78 "parser.y" -{ - yyval.node = yyvsp[0].node; -; - break;} -case 3: -#line 81 "parser.y" -{ - yyval.node = yyvsp[0].node; -; - break;} -case 4: -#line 84 "parser.y" -{ - /* Create addition binary operator node. */ - yyval.node = node_create ('b', '+', yyvsp[-2].node, yyvsp[0].node); -; - break;} -case 5: -#line 88 "parser.y" -{ - /* Create subtraction binary operator node. */ - yyval.node = node_create ('b', '-', yyvsp[-2].node, yyvsp[0].node); -; - break;} -case 6: -#line 92 "parser.y" -{ - /* Create multiplication binary operator node. */ - yyval.node = node_create ('b', '*', yyvsp[-2].node, yyvsp[0].node); -; - break;} -case 7: -#line 96 "parser.y" -{ - /* Create division binary operator node. */ - yyval.node = node_create ('b', '/', yyvsp[-2].node, yyvsp[0].node); -; - break;} -case 8: -#line 100 "parser.y" -{ - /* Create minus unary operator node. */ - yyval.node = node_create ('u', '-', yyvsp[0].node); -; - break;} -case 9: -#line 104 "parser.y" -{ - /* Create exponentiation unary operator node. */ - yyval.node = node_create ('b', '^', yyvsp[-2].node, yyvsp[0].node); -; - break;} -case 10: -#line 108 "parser.y" -{ - /* Create function node. */ - yyval.node = node_create ('f', yyvsp[-3].record, yyvsp[-1].node); -; - break;} -case 11: -#line 112 "parser.y" -{ - yyval.node = yyvsp[-1].node; -; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 543 "/usr/share/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} -#line 117 "parser.y" - - -int yyerror(char* s) -{ - /* Indicate parsing error through appropriate flag and stop - parsing. */ - matheval_ok = 0; - force_buffer_flush(); - return 0; -} diff --git a/MathEval/parser.tab.hpp b/MathEval/parser.tab.hpp deleted file mode 100644 index 561b245ad9..0000000000 --- a/MathEval/parser.tab.hpp +++ /dev/null @@ -1,11 +0,0 @@ -typedef union { - Node *node; - Record *record; -} YYSTYPE; -#define NUMBER 257 -#define VARIABLE 258 -#define FUNCTION 259 -#define NEG 260 - - -extern YYSTYPE melval; diff --git a/MathEval/parser.y b/MathEval/parser.y deleted file mode 100644 index 9b5817bf81..0000000000 --- a/MathEval/parser.y +++ /dev/null @@ -1,126 +0,0 @@ -%{ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include "common.h" -#include "node.h" - -/* Variables used to communicate with code using parser. */ -extern Node* matheval_root; /* Root of tree representation of function. */ -extern int matheval_ok; /* Flag representing success of parsing. */ - -/* Report parsing error. */ -int yyerror (char *s); - -/* Function used to tokenize string representing function (this function - is generated by scanner generator). */ -int yylex (void); - -/* Function used to flush the internal flex buffer when we exit - prematurely (i.e., in case of a parse error) so that the next time - we call the scanner, all is nicely reset. Without this, the - behaviour of the next call after an error is unpredictable. */ -void force_buffer_flush(void); - -%} - -/* Parser semantic values type. */ -%union { - Node *node; - Record *record; -} - -/* Grammar terminal symbols. */ -%token <node> NUMBER VARIABLE -%token <record> FUNCTION - -/* Grammar non-terminal symbols. */ -%type <node> expression - -%left '-' '+' -%left '*' '/' -%left NEG -%left '^' - -/* Grammar start non-terminal. */ -%start input - -%% - -input -: expression '\n' { - matheval_root = $1; - return 1; -} -; - -expression -: NUMBER { - $$ = $1; -} -| VARIABLE { - $$ = $1; -} -| expression '+' expression { - /* Create addition binary operator node. */ - $$ = node_create ('b', '+', $1, $3); -} -| expression '-' expression { - /* Create subtraction binary operator node. */ - $$ = node_create ('b', '-', $1, $3); -} -| expression '*' expression { - /* Create multiplication binary operator node. */ - $$ = node_create ('b', '*', $1, $3); -} -| expression '/' expression { - /* Create division binary operator node. */ - $$ = node_create ('b', '/', $1, $3); -} -| '-' expression %prec NEG { - /* Create minus unary operator node. */ - $$ = node_create ('u', '-', $2); -} -| expression '^' expression { - /* Create exponentiation unary operator node. */ - $$ = node_create ('b', '^', $1, $3); -} -| FUNCTION '(' expression ')' { - /* Create function node. */ - $$ = node_create ('f', $1, $3); -} -| '(' expression ')' { - $$ = $2; -} -; - -%% - -int yyerror(char* s) -{ - /* Indicate parsing error through appropriate flag and stop - parsing. */ - matheval_ok = 0; - force_buffer_flush(); - return 0; -} diff --git a/MathEval/scanner.l b/MathEval/scanner.l deleted file mode 100644 index 0b92fa78c8..0000000000 --- a/MathEval/scanner.l +++ /dev/null @@ -1,130 +0,0 @@ -%{ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include "common.h" -#include "node.h" -#include "parser.tab.hpp" -#include "symbol_table.h" - -#define YY_ALWAYS_INTERACTIVE 1 - -/* Redefine macro to redirect scanner input from string instead of - standard input. */ -#define YY_INPUT( buffer, result, max_size ) \ -{ result = input_from_string (buffer, max_size); } - -/* Variables used to communicate with code using scanner. */ -extern SymbolTable *matheval_symbol_table; /* Evaluator symbol table. */ -extern char *matheval_input_string; /* String representing function. */ - -/* Read next max_size character from string into buffer. */ -static int input_from_string (char *buffer, int max_size); -%} - -/* Token definitions. */ -whitespace [\ \t]+ -digit [0-9] -number ({digit}+|{digit}+"."{digit}*|{digit}*"."{digit}+)([Ee][-+]?{digit}+)? -function "Exp"|"Log"|"Sqrt"|"Sin"|"Cos"|"Tan"|"Ctan"|"Asin"|"Acos"|"Atan"|"Actan"|"Sinh"|"Cosh"|"Tanh"|"Ctanh"|"Asinh"|"Acosh"|"Atanh"|"Actanh"|"Fabs"|"Rand" -identifier [a-zA-Z\_][a-zA-Z0-9\_]* - -%% - -{whitespace} - -{number} { - /* Create node representing constant with appropriate value. */ - melval.node = node_create ('c', atof (metext)); - return NUMBER; -} - -{function} { - /* Find symbol table record corresponding to function name. */ - melval.record = symbol_table_lookup (matheval_symbol_table, metext); - return FUNCTION; -} - -{identifier} { - Record *record; /* Symbol table record. */ - /* Inserty variable into symbol table. */ - record = symbol_table_insert (matheval_symbol_table, metext, 'v'); - melval.node = node_create ('v', record); - return VARIABLE; -} - -"+" { - return '+'; -} - -"-" { - return '-'; -} - -"*" { - return '*'; -} - -"/" { - return '/'; -} - -"^" { - return '^'; -} - -"(" { - return '('; -} - -")" { - return ')'; -} - -"\n" { - return '\n'; -} - -%% - -#undef mewrap - -int mewrap() { return 1; } - -static int input_from_string (char *buffer, int max_size) -{ - int count; /* Count of characters to copy from input string to buffer. */ - - /* Calculate count of characters to copy. */ - count = strlen (matheval_input_string); - if (count > max_size) - count = max_size; - - /* Perform copy operation and update input string. */ - memcpy(buffer, matheval_input_string, count); - matheval_input_string += count; - - return count; -} - -void force_buffer_flush() { YY_FLUSH_BUFFER; } diff --git a/MathEval/scanner.yy.cpp b/MathEval/scanner.yy.cpp deleted file mode 100644 index e4bb1ff00b..0000000000 --- a/MathEval/scanner.yy.cpp +++ /dev/null @@ -1,1716 +0,0 @@ -#define yy_create_buffer me_create_buffer -#define yy_delete_buffer me_delete_buffer -#define yy_scan_buffer me_scan_buffer -#define yy_scan_string me_scan_string -#define yy_scan_bytes me_scan_bytes -#define yy_flex_debug me_flex_debug -#define yy_init_buffer me_init_buffer -#define yy_flush_buffer me_flush_buffer -#define yy_load_buffer_state me_load_buffer_state -#define yy_switch_to_buffer me_switch_to_buffer -#define yyin mein -#define yyleng meleng -#define yylex melex -#define yyout meout -#define yyrestart merestart -#define yytext metext -#define yywrap mewrap - -#line 20 "scanner.yy.cpp" -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header: /cvsroot/gmsh/MathEval/scanner.yy.cpp,v 1.1 2005-06-20 16:35:30 geuzaine Exp $ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include <stdio.h> - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include <stdlib.h> -#include <unistd.h> - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 13 -#define YY_END_OF_BUFFER 14 -static yyconst short int yy_accept[65] = - { 0, - 0, 0, 14, 13, 1, 12, 10, 11, 7, 5, - 6, 13, 8, 2, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 9, 1, 2, 2, 2, 0, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 2, 0, 2, 4, 4, 4, 4, 3, - 4, 3, 4, 4, 3, 4, 3, 3, 4, 3, - 3, 3, 3, 0 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 4, - 5, 6, 7, 1, 8, 9, 10, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 1, 1, 1, - 1, 1, 1, 1, 12, 13, 14, 13, 15, 16, - 13, 13, 13, 13, 13, 17, 13, 13, 13, 13, - 13, 18, 19, 20, 13, 13, 13, 13, 13, 13, - 1, 1, 1, 21, 13, 1, 22, 23, 24, 25, - - 26, 13, 27, 28, 29, 13, 13, 13, 13, 30, - 31, 32, 33, 34, 35, 36, 13, 13, 13, 37, - 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[38] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2 - } ; - -static yyconst short int yy_base[66] = - { 0, - 0, 0, 106, 107, 103, 107, 107, 107, 107, 107, - 107, 93, 107, 29, 15, 0, 10, 66, 80, 70, - 78, 14, 77, 107, 96, 34, 37, 47, 46, 0, - 28, 68, 74, 60, 72, 61, 69, 64, 60, 59, - 54, 57, 50, 75, 74, 49, 61, 52, 51, 52, - 49, 0, 43, 52, 47, 38, 44, 43, 40, 41, - 40, 39, 38, 107, 40 - } ; - -static yyconst short int yy_def[66] = - { 0, - 64, 1, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 64, 64, 64, 64, 64, 64, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 64, 64, 64, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 0, 64 - } ; - -static yyconst short int yy_nxt[145] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 27, 31, 28, - 34, 30, 40, 29, 26, 35, 41, 43, 29, 32, - 33, 29, 44, 44, 29, 27, 45, 28, 46, 29, - 43, 29, 29, 47, 29, 52, 52, 52, 52, 63, - 52, 52, 29, 52, 52, 29, 52, 52, 62, 52, - 61, 60, 59, 58, 45, 45, 57, 56, 55, 54, - 52, 53, 52, 51, 50, 49, 48, 25, 42, 39, - - 38, 37, 36, 26, 25, 64, 3, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64 - } ; - -static yyconst short int yy_chk[145] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 14, 15, 14, - 17, 65, 22, 14, 26, 17, 22, 27, 26, 15, - 15, 27, 29, 29, 14, 28, 29, 28, 31, 26, - 43, 28, 27, 31, 43, 63, 62, 61, 60, 59, - 58, 57, 28, 56, 55, 43, 54, 53, 51, 50, - 49, 48, 47, 46, 45, 44, 42, 41, 40, 39, - 38, 37, 36, 35, 34, 33, 32, 25, 23, 21, - - 20, 19, 18, 12, 5, 3, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "scanner.l" -#define INITIAL 0 -#line 2 "scanner.l" -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include "common.h" -#include "node.h" -#include "parser.tab.hpp" -#include "symbol_table.h" - -#define YY_ALWAYS_INTERACTIVE 1 - -/* Redefine macro to redirect scanner input from string instead of - standard input. */ -#define YY_INPUT( buffer, result, max_size ) \ -{ result = input_from_string (buffer, max_size); } - -/* Variables used to communicate with code using scanner. */ -extern SymbolTable *matheval_symbol_table; /* Evaluator symbol table. */ -extern char *matheval_input_string; /* String representing function. */ - -/* Read next max_size character from string into buffer. */ -static int input_from_string (char *buffer, int max_size); -/* Token definitions. */ -#line 476 "scanner.yy.cpp" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 52 "scanner.l" - - -#line 630 "scanner.yy.cpp" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 65 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 107 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 54 "scanner.l" - - YY_BREAK -case 2: -YY_RULE_SETUP -#line 56 "scanner.l" -{ - /* Create node representing constant with appropriate value. */ - melval.node = node_create ('c', atof (metext)); - return NUMBER; -} - YY_BREAK -case 3: -YY_RULE_SETUP -#line 62 "scanner.l" -{ - /* Find symbol table record corresponding to function name. */ - melval.record = symbol_table_lookup (matheval_symbol_table, metext); - return FUNCTION; -} - YY_BREAK -case 4: -YY_RULE_SETUP -#line 68 "scanner.l" -{ - Record *record; /* Symbol table record. */ - /* Inserty variable into symbol table. */ - record = symbol_table_insert (matheval_symbol_table, metext, 'v'); - melval.node = node_create ('v', record); - return VARIABLE; -} - YY_BREAK -case 5: -YY_RULE_SETUP -#line 76 "scanner.l" -{ - return '+'; -} - YY_BREAK -case 6: -YY_RULE_SETUP -#line 80 "scanner.l" -{ - return '-'; -} - YY_BREAK -case 7: -YY_RULE_SETUP -#line 84 "scanner.l" -{ - return '*'; -} - YY_BREAK -case 8: -YY_RULE_SETUP -#line 88 "scanner.l" -{ - return '/'; -} - YY_BREAK -case 9: -YY_RULE_SETUP -#line 92 "scanner.l" -{ - return '^'; -} - YY_BREAK -case 10: -YY_RULE_SETUP -#line 96 "scanner.l" -{ - return '('; -} - YY_BREAK -case 11: -YY_RULE_SETUP -#line 100 "scanner.l" -{ - return ')'; -} - YY_BREAK -case 12: -YY_RULE_SETUP -#line 104 "scanner.l" -{ - return '\n'; -} - YY_BREAK -case 13: -YY_RULE_SETUP -#line 108 "scanner.l" -ECHO; - YY_BREAK -#line 808 "scanner.yy.cpp" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 65 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 65 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 64); - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 108 "scanner.l" - - -#undef mewrap - -int mewrap() { return 1; } - -static int input_from_string (char *buffer, int max_size) -{ - int count; /* Count of characters to copy from input string to buffer. */ - - /* Calculate count of characters to copy. */ - count = strlen (matheval_input_string); - if (count > max_size) - count = max_size; - - /* Perform copy operation and update input string. */ - memcpy(buffer, matheval_input_string, count); - matheval_input_string += count; - - return count; -} - -void force_buffer_flush() { YY_FLUSH_BUFFER; } diff --git a/MathEval/symbol_table.cpp b/MathEval/symbol_table.cpp deleted file mode 100644 index 34e01043a4..0000000000 --- a/MathEval/symbol_table.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include <assert.h> -#include <stdarg.h> - -#include "common.h" -#include "symbol_table.h" -#include "xmath.h" - -/* - * Type definition for function accepting single argument of double type and - * returning double value. - */ -typedef double (*function_type) (double); - -/* Calculate hash value for given name and hash table length. */ -static int hash(char *name, int length); - -SymbolTable * -symbol_table_create(int length) -{ - SymbolTable *symbol_table; /* Pointer to symbol table. */ - static char *names[] = {"Exp", "Log", "Sqrt", "Sin", "Cos", "Tan", "Ctan", - "Asin", "Acos", "Atan", "Actan", "Sinh", "Cosh", "Tanh", - "Ctanh", "Asinh", "Acosh", "Atanh", "Actanh", "Fabs", "Rand" }; - static double (*functions[]) (double) = { exp, log, sqrt, sin, cos, tan, x_ctan, - asin, acos, atan, x_actan, sinh, cosh, tanh, - x_ctanh, x_asinh, x_acosh, x_atanh, x_actanh, - fabs, x_rand}; - unsigned int i; - - /* - * Allocate memory for symbol table data structure as well as for - * corresponding hash table. - */ - symbol_table = XMALLOC(SymbolTable, 1); - symbol_table->length = length; - symbol_table->records = XCALLOC(Record, symbol_table->length); - - /* - * Insert predefined functions into symbol table. - */ - for (i = 0; i < sizeof(names) / sizeof(names[0]); i++) - symbol_table_insert(symbol_table, names[i], 'f', functions[i]); - - /* - * Initialize symbol table reference count. - */ - symbol_table->reference_count = 1; - - return symbol_table; -} - -void -symbol_table_destroy(SymbolTable * symbol_table) -{ - Record *curr, *next; /* Pointers to current and next record - * while traversing hash table bucket. */ - int i; - - if(!symbol_table) - return; - - /* - * Decrement refernce count and return if symbol table still used - * elsewhere. - */ - if (--symbol_table->reference_count > 0) - return; - - /* - * Delete hash table as well as data structure representing symbol - * table. - */ - for (i = 0; i < symbol_table->length; i++) - for (curr = symbol_table->records[i].next; curr;) { - next = curr->next; - XFREE(curr->name); - XFREE(curr); - curr = next; - } - XFREE(symbol_table->records); - XFREE(symbol_table); -} - -Record * -symbol_table_insert(SymbolTable * symbol_table, char *name, char type,...) -{ - Record *record; /* Pointer to symbol table record - * corresponding to name given. */ - va_list ap; /* Function variable argument list. */ - int i; - - /* - * Check if symbol already in table and, if affirmative and record - * type same as type given, return corresponding record immediately. - */ - if ((record = symbol_table_lookup(symbol_table, name))) { - assert(record->type == type); - return record; - } - /* - * Allocate memory for and initialize new record. - */ - record = XMALLOC(Record, 1); - record->name = XMALLOC(char, strlen(name) + 1); - strcpy(record->name, name); - record->type = type; - - /* - * Parse function variable argument list to complete record - * initialization. - */ - va_start(ap, type); - switch (record->type) { - case 'v': - record->data.value = 0; - break; - - case 'f': - record->data.function = va_arg(ap, function_type); - break; - } - va_end(ap); - - /* - * Calculate hash value and put record in corresponding hash table - * bucket. - */ - i = hash(name, symbol_table->length); - record->next = symbol_table->records[i].next; - symbol_table->records[i].next = record; - - return record; -} - -Record * -symbol_table_lookup(SymbolTable * symbol_table, char *name) -{ - int i; /* Hash value. */ - Record *curr; /* Pointer to current symbol table record. */ - - /* - * Calcuate hash value for name given. - */ - i = hash(name, symbol_table->length); - - /* - * Lookup for name in hash table bucket corresponding to above hash - * value. - */ - for (curr = symbol_table->records[i].next; curr; curr = curr->next) - if (!strcmp(curr->name, name)) - return curr; - - return NULL; -} - -SymbolTable * -symbol_table_assign(SymbolTable * symbol_table) -{ - /* - * Increase symbol table reference count and return pointer to data - * structure representing table. - */ - symbol_table->reference_count++; - return symbol_table; -} - -/* - * Function below reused from A.V. Aho, R. Sethi, J.D. Ullman, "Compilers - - * Principle, Techniques, and Tools", Addison-Wesley, 1986, pp 435-437, and - * in turn from P.J. Weineberger's C compiler. - */ -static int -hash(char *s, int n) -{ - char *p; - unsigned h, g; - - h = 0; - - for (p = s; *p; p++) { - h = (h << 4) + *p; - if ((g = h & 0xf0000000)) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - - return h % n; -} diff --git a/MathEval/symbol_table.h b/MathEval/symbol_table.h deleted file mode 100644 index 0862c956ef..0000000000 --- a/MathEval/symbol_table.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#ifndef SYMBOL_TABLE_H -#define SYMBOL_TABLE_H - -/* Data structure representing symbol table record. */ -typedef struct _Record { - struct _Record *next; /* Pointer to next record. */ - char *name; /* Symbol name. */ - char type; /* Symbol type ('v' for variable, 'f' for function). */ - union { - double value; /* Variable value. */ - double (*function) (double); /* Pointer to function to calculate - * its value. */ - } data; -} Record; - -/* - * Data structure representing symbol table (hash table is used for this - * purpose). - */ -typedef struct { - int length; /* Hash table length. */ - Record *records; /* Hash table buckets. */ - int reference_count; /* Reference count for symbol table (evaluator - * for derivative uses same symbol table as - * evaluator for corresponding function). */ -} SymbolTable; - -/* Create symbol table using specified length of hash table. */ -SymbolTable *symbol_table_create(int length); - -/* Destroy symbol table. */ -void symbol_table_destroy(SymbolTable * symbol_table); - -/* - * Insert symbol into given symbol table. Further arguments are symbol name - * and its type, as well as additional arguments according to symbol type. - * Return value is pointer to symobl table record created to represent - * symbol. If symbol already in symbol table, pointer to its record is - * returned immediately. - */ -Record *symbol_table_insert(SymbolTable * symbol_table, char *name, char type,...); - -/* - * Lookup symbol by name from given symbol table. Pointer to symbol record - * is returned if symbol found, null pointer otherwise. - */ -Record *symbol_table_lookup(SymbolTable * symbol_table, char *name); - -/* - * Return symbol table pointer to be assigned to variable. This function - * should be used instead of simple pointer assignement for proper reference - * counting. Users willing to manage reference counts by themselves are free - * to ignore this functions. - */ -SymbolTable *symbol_table_assign(SymbolTable * symbol_table); - -#endif diff --git a/MathEval/xmath.cpp b/MathEval/xmath.cpp deleted file mode 100644 index da1479b032..0000000000 --- a/MathEval/xmath.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#include "xmath.h" -#include <math.h> -#include <stdlib.h> - -double -x_ctan(double x) -{ - /* - * Calculate cotangent value. - */ - return 1 / tan(x); -} - -double -x_actan(double x) -{ - /* - * Calculate inverse cotangent value. - */ - return atan(1 / x); -} - -double -x_ctanh(double x) -{ - /* - * Calculate hyperbolic cotangent value. - */ - return 1 / tanh(x); -} - -double -x_asinh(double x) -{ - /* - * Calculate inverse hyperbolic sine value using relation between - * hyperbolic and exponential functions. - */ - return log(x + sqrt(x * x + 1)); -} - -double -x_acosh(double x) -{ - /* - * Calculate inverse hyperbolic cosine value using relation between - * hyperbolic and exponential functions. - */ - return log(x + sqrt(x * x - 1)); -} - -double -x_atanh(double x) -{ - /* - * Calculate inverse hyperbolic tangent value using relation between - * hyperbolic and exponential functions. - */ - return 0.5 * log((1 + x) / (1 - x)); -} - -double -x_actanh(double x) -{ - /* - * Calculate inverse hyperbolic cotangent value. - */ - return atanh(1 / x); -} - -double -x_rand(double x) -{ - /* - * Calculate random value in [0, x]. - */ - - return x*(double)rand()/(double)RAND_MAX; -} diff --git a/MathEval/xmath.h b/MathEval/xmath.h deleted file mode 100644 index f086ad916a..0000000000 --- a/MathEval/xmath.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. - * - * This file is part of GNU libmatheval - * - * GNU libmatheval is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any later - * version. - * - * GNU libmatheval is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along with - * program; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This file was modified for inclusion in Gmsh */ - -#ifndef XMATH_H -#define XMATH_H - -double x_ctan(double x); -double x_actan(double x); -double x_ctanh(double x); -double x_asinh(double x); -double x_acosh(double x); -double x_atanh(double x); -double x_actanh(double x); -double x_rand(double x); - -#endif diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp index 0bca7582bd..66cc44fd1f 100644 --- a/Mesh/BDS.cpp +++ b/Mesh/BDS.cpp @@ -3,6 +3,9 @@ #include "Numeric.h" #include "GmshMatrix.h" #include "BDS.h" +#include "Context.h" + +extern Context_T CTX; /* (X-Xc)^2 = R^2 diff --git a/Metis/Doc/manual.ps b/Metis/Doc/manual.ps deleted file mode 100644 index d77abe5658..0000000000 --- a/Metis/Doc/manual.ps +++ /dev/null @@ -1,16447 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software -%%Title: manual.dvi -%%Pages: 44 -%%PageOrder: Ascend -%%BoundingBox: 0 0 612 792 -%%DocumentFonts: Helvetica-Bold MTSYN AvantGarde-Demi Helvetica -%%+ Times-Roman Times-Italic Times-Bold Helvetica-Narrow-Bold -%%+ Helvetica-Narrow ZapfDingbats RMTMI Courier Times-BoldItalic -%%+ Helvetica-Narrow-Oblique Courier-Oblique MTEX -%%DocumentPaperSizes: Letter -%%EndComments -%DVIPSCommandLine: dvips -o manual.ps manual -%DVIPSParameters: dpi=600, comments removed -%DVIPSSource: TeX output 1998.09.20:1257 -%%BeginProcSet: tex.pro -<< /Duplex true >> setpagedevice % GK -/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N -/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 -mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} -ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale -isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div -hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul -TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} -forall round exch round exch]setmatrix}N /@landscape{/isls true N}B -/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B -/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ -/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N -string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N -end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ -/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] -N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup -length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ -128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub -get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data -dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N -/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup -/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx -0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff -setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff -.1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} -if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup -length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ -cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin -0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul -add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict -/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook -known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X -/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for -65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 -0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V -{}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 -getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} -ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false -RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 -false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform -round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg -rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail -{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} -B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ -4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ -p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p -a}B /bos{/SS save N}B /eos{SS restore}B end -%%EndProcSet -%%BeginProcSet: psfrag.pro -userdict begin -/PSfragLib 90 dict def -/PSfragDict 6 dict def -/PSfrag { PSfragLib begin load exec end } bind def -end -PSfragLib begin -/RO /readonly load def -/CP /currentpoint load def -/CM /currentmatrix load def -/B { bind RO def } bind def -/X { exch def } B -/MD { { X } forall } B -/OE { end exec PSfragLib begin } B -/tstr 8 string def -/islev2 { languagelevel } stopped { false } { 2 ge } ifelse def -[ /tM /srcM /dstM /dM /idM /srcFM /dstFM ] { matrix def } forall -dM defaultmatrix RO idM invertmatrix RO pop -srcFM identmatrix pop -/Hide { gsave { CP } stopped not newpath clip { moveto } if } B -/Unhide { { CP } stopped not grestore { moveto } if } B -/setrepl islev2 {{ /glob currentglobal def true setglobal array astore - globaldict exch /PSfrags exch put glob setglobal }} - {{ array astore /PSfrags X }} ifelse B -/getrepl islev2 {{ globaldict /PSfrags get aload length }} - {{ PSfrags aload length }} ifelse B -/convert { - /src X src length string - /c 0 def src length { - dup c src c get dup 32 lt { pop 32 } if put /c c 1 add def - } repeat -} B -/Begin { - /saver save def - srcFM exch 3 exch put - 0 ne /debugMode X 0 setrepl - dup /S exch dict def { S 3 1 roll exch convert exch put } repeat - srcM CM dup invertmatrix pop - mark { currentdict { end } stopped { pop exit } if } loop - PSfragDict counttomark { begin } repeat pop -} B -/End { - mark { currentdict end dup PSfragDict eq { pop exit } if } loop - counttomark { begin } repeat pop - getrepl saver restore - 7 idiv dup /S exch dict def { - 6 array astore /mtrx X tstr cvs /K X - S K [ S K known { S K get aload pop } if mtrx ] put - } repeat -} B -/Place { - tstr cvs /K X - S K known { - bind /proc X tM CM pop - CP /cY X /cX X - 0 0 transform idtransform neg /aY X neg /aX X - S K get dup length /maxiter X - /iter 1 def { - iter maxiter ne { /saver save def } if - tM setmatrix aX aY translate - [ exch aload pop idtransform ] concat - cX neg cY neg translate cX cY moveto - /proc load OE - iter maxiter ne { saver restore /iter iter 1 add def } if - } forall - /noXY { CP /cY X /cX X } stopped def - tM setmatrix noXY { newpath } { cX cY moveto } ifelse - } { - Hide OE Unhide - } ifelse -} B -/normalize { - 2 index dup mul 2 index dup mul add sqrt div - dup 4 -1 roll exch mul 3 1 roll mul -} B -/replace { - aload pop MD - CP /bY X /lX X gsave initmatrix - str stringwidth abs exch abs add dup 0 eq - { pop } { 360 exch div dup scale } ifelse - lX neg bY neg translate newpath lX bY moveto - str { /ch X ( ) dup 0 ch put false charpath ch Kproc } forall - flattenpath pathbbox [ /uY /uX /lY /lX ] MD - CP grestore moveto - currentfont /FontMatrix get dstFM copy dup - 0 get 0 lt { uX lX /uX X /lX X } if - 3 get 0 lt { uY lY /uY X /lY X } if - /cX uX lX add 0.5 mul def - /cY uY lY add 0.5 mul def - debugMode { gsave 0 setgray 1 setlinewidth - lX lY moveto lX uY lineto uX uY lineto uX lY lineto closepath - lX bY moveto uX bY lineto lX cY moveto uX cY lineto - cX lY moveto cX uY lineto stroke - grestore } if - dstFM dup invertmatrix dstM CM srcM - 2 { dstM concatmatrix } repeat pop - getrepl /temp X - S str convert get { - aload pop [ /rot /scl /loc /K ] MD - /aX cX def /aY cY def - loc { - dup 66 eq { /aY bY def } { % B - dup 98 eq { /aY lY def } { % b - dup 108 eq { /aX lX def } { % l - dup 114 eq { /aX uX def } { % r - dup 116 eq { /aY uY def } % t - if } ifelse } ifelse } ifelse } ifelse pop - } forall - K srcFM rot tM rotate dstM - 2 { tM concatmatrix } repeat aload pop pop pop - 2 { scl normalize 4 2 roll } repeat - aX aY transform - /temp temp 7 add def - } forall - temp setrepl -} B -/Rif { - S 3 index convert known { pop replace } { exch pop OE } ifelse -} B -/XA { bind [ /Kproc /str } B /XC { ] 2 array astore def } B -/xs { pop } XA XC -/xks { /kern load OE } XA /kern XC -/xas { pop ax ay rmoveto } XA /ay /ax XC -/xws { c eq { cx cy rmoveto } if } XA /c /cy /cx XC -/xaws { ax ay rmoveto c eq { cx cy rmoveto } if } - XA /ay /ax /c /cy /cx XC -/raws { xaws { awidthshow } Rif } B -/rws { xws { widthshow } Rif } B -/rks { xks { kshow } Rif } B -/ras { xas { ashow } Rif } B -/rs { xs { show } Rif } B -/rrs { getrepl dup 2 add -1 roll restore setrepl } B -PSfragDict begin -islev2 not { /restore { /rrs PSfrag } B } if -/show { /rs PSfrag } B -/kshow { /rks PSfrag } B -/ashow { /ras PSfrag } B -/widthshow { /rws PSfrag } B -/awidthshow { /raws PSfrag } B -end PSfragDict RO pop -end - -%%EndProcSet -%%BeginFont: Helvetica-Bold -% @@psencodingfile@{ -% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", -% version = "0.6", -% date = "22 June 1996", -% filename = "8r.enc", -% email = "kb@@mail.tug.org", -% address = "135 Center Hill Rd. // Plymouth, MA 02360", -% codetable = "ISO/ASCII", -% checksum = "119 662 4424", -% docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." -% @} -% -% Idea is to have all the characters normally included in Type 1 fonts -% available for typesetting. This is effectively the characters in Adobe -% Standard Encoding + ISO Latin 1 + extra characters from Lucida. -% -% Character code assignments were made as follows: -% -% (1) the Windows ANSI characters are almost all in their Windows ANSI -% positions, because some Windows users cannot easily reencode the -% fonts, and it makes no difference on other systems. The only Windows -% ANSI characters not available are those that make no sense for -% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen -% (173). quotesingle and grave are moved just because it's such an -% irritation not having them in TeX positions. -% -% (2) Remaining characters are assigned arbitrarily to the lower part -% of the range, avoiding 0, 10 and 13 in case we meet dumb software. -% -% (3) Y&Y Lucida Bright includes some extra text characters; in the -% hopes that other PostScript fonts, perhaps created for public -% consumption, will include them, they are included starting at 0x12. -% -% (4) Remaining positions left undefined are for use in (hopefully) -% upward-compatible revisions, if someday more characters are generally -% available. -% -% (5) hyphen appears twice for compatibility with both ASCII and Windows. -% -/TeXBase1Encoding [ -% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) - /.notdef /dotaccent /fi /fl - /fraction /hungarumlaut /Lslash /lslash - /ogonek /ring /.notdef - /breve /minus /.notdef -% These are the only two remaining unencoded characters, so may as -% well include them. - /Zcaron /zcaron -% 0x10 - /caron /dotlessi -% (unusual TeX characters available in, e.g., Lucida Bright) - /dotlessj /ff /ffi /ffl - /.notdef /.notdef /.notdef /.notdef - /.notdef /.notdef /.notdef /.notdef - % very contentious; it's so painful not having quoteleft and quoteright - % at 96 and 145 that we move the things normally found there down to here. - /grave /quotesingle -% 0x20 (ASCII begins) - /space /exclam /quotedbl /numbersign - /dollar /percent /ampersand /quoteright - /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash -% 0x30 - /zero /one /two /three /four /five /six /seven - /eight /nine /colon /semicolon /less /equal /greater /question -% 0x40 - /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O -% 0x50 - /P /Q /R /S /T /U /V /W - /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore -% 0x60 - /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o -% 0x70 - /p /q /r /s /t /u /v /w - /x /y /z /braceleft /bar /braceright /asciitilde - /.notdef % rubout; ASCII ends -% 0x80 - /.notdef /.notdef /quotesinglbase /florin - /quotedblbase /ellipsis /dagger /daggerdbl - /circumflex /perthousand /Scaron /guilsinglleft - /OE /.notdef /.notdef /.notdef -% 0x90 - /.notdef /.notdef /.notdef /quotedblleft - /quotedblright /bullet /endash /emdash - /tilde /trademark /scaron /guilsinglright - /oe /.notdef /.notdef /Ydieresis -% 0xA0 - /.notdef % nobreakspace - /exclamdown /cent /sterling - /currency /yen /brokenbar /section - /dieresis /copyright /ordfeminine /guillemotleft - /logicalnot - /hyphen % Y&Y (also at 45); Windows' softhyphen - /registered - /macron -% 0xD0 - /degree /plusminus /twosuperior /threesuperior - /acute /mu /paragraph /periodcentered - /cedilla /onesuperior /ordmasculine /guillemotright - /onequarter /onehalf /threequarters /questiondown -% 0xC0 - /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla - /Egrave /Eacute /Ecircumflex /Edieresis - /Igrave /Iacute /Icircumflex /Idieresis -% 0xD0 - /Eth /Ntilde /Ograve /Oacute - /Ocircumflex /Otilde /Odieresis /multiply - /Oslash /Ugrave /Uacute /Ucircumflex - /Udieresis /Yacute /Thorn /germandbls -% 0xE0 - /agrave /aacute /acircumflex /atilde - /adieresis /aring /ae /ccedilla - /egrave /eacute /ecircumflex /edieresis - /igrave /iacute /icircumflex /idieresis -% 0xF0 - /eth /ntilde /ograve /oacute - /ocircumflex /otilde /odieresis /divide - /oslash /ugrave /uacute /ucircumflex - /udieresis /yacute /thorn /ydieresis -] def -%%EndFont -%%BeginFont: MTSYN - -% MathTime fonts were designed by Michael Spivak. -% Copyright (c) 1996 Publish or Perish, Inc. -% Hinting Copyright (c) 1996 Y&Y, Inc. -% MathTime is a registered trademark of Publish or Perish, Inc. - -11 dict begin -/FontInfo 9 dict dup begin -/version (1.000) readonly def -/Notice (Copyright (c) 1992-1996 Publish or Perish and Y&Y, Inc.) readonly def -/FullName (MTSYN) readonly def -/FamilyName (MathTime) readonly def -/Weight (Medium) readonly def -/ItalicAngle 0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /MTSYN def -/PaintType 0 def -/FontType 1 def -/FontMatrix [0.001 0 0 0.001 0 0] readonly def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 161 /minus put -dup 162 /periodcentered put -dup 163 /multiply put -dup 164 /asteriskmath put -dup 165 /divide put -dup 166 /diamondmath put -dup 167 /plusminus put -dup 168 /minusplus put -dup 169 /circleplus put -dup 170 /circleminus put -dup 173 /circlemultiply put -dup 174 /circledivide put -dup 175 /circledot put -dup 176 /circlecopyrt put -dup 177 /openbullet put -dup 178 /bullet put -dup 179 /equivasymptotic put -dup 180 /equivalence put -dup 181 /reflexsubset put -dup 182 /reflexsuperset put -dup 183 /lessequal put -dup 184 /greaterequal put -dup 185 /precedesequal put -dup 186 /followsequal put -dup 187 /similar put -dup 188 /approxequal put -dup 189 /propersubset put -dup 190 /propersuperset put -dup 191 /lessmuch put -dup 192 /greatermuch put -dup 193 /precedes put -dup 194 /follows put -dup 195 /arrowleft put -dup 196 /spade put -dup 128 /arrowleft put -dup 0 /minus put -dup 1 /periodcentered put -dup 2 /multiply put -dup 3 /asteriskmath put -dup 4 /divide put -dup 5 /diamondmath put -dup 6 /plusminus put -dup 7 /minusplus put -dup 8 /circleplus put -dup 9 /circleminus put -dup 10 /circlemultiply put -dup 11 /circledivide put -dup 12 /circledot put -dup 13 /circlecopyrt put -dup 14 /openbullet put -dup 15 /bullet put -dup 16 /equivasymptotic put -dup 17 /equivalence put -dup 18 /reflexsubset put -dup 19 /reflexsuperset put -dup 20 /lessequal put -dup 21 /greaterequal put -dup 22 /precedesequal put -dup 23 /followsequal put -dup 24 /similar put -dup 25 /approxequal put -dup 26 /propersubset put -dup 27 /propersuperset put -dup 28 /lessmuch put -dup 29 /greatermuch put -dup 30 /precedes put -dup 31 /follows put -dup 32 /arrowleft put -dup 33 /arrowright put -dup 34 /arrowup put -dup 35 /arrowdown put -dup 36 /arrowboth put -dup 37 /arrownortheast put -dup 38 /arrowsoutheast put -dup 39 /similarequal put -dup 40 /arrowdblleft put -dup 41 /arrowdblright put -dup 42 /arrowdblup put -dup 43 /arrowdbldown put -dup 44 /arrowdblboth put -dup 45 /arrownorthwest put -dup 46 /arrowsouthwest put -dup 47 /proportional put -dup 48 /prime put -dup 49 /infinity put -dup 50 /element put -dup 51 /owner put -dup 52 /triangle put -dup 53 /triangleinv put -dup 54 /negationslash put -dup 55 /mapsto put -dup 56 /universal put -dup 57 /existential put -dup 58 /logicalnot put -dup 59 /emptyset put -dup 60 /Rfractur put -dup 61 /Ifractur put -dup 62 /latticetop put -dup 63 /perpendicular put -dup 64 /aleph put -dup 65 /tie put -dup 66 /openbullet1 put -dup 67 /plus put -dup 68 /equal put -dup 69 /vector put -dup 70 /triangleright put -dup 71 /triangleleft put -dup 72 /equal1 put -dup 73 /semicolon put -dup 74 /grave put -dup 75 /acute put -dup 76 /caron put -dup 77 /breve put -dup 78 /macron put -dup 79 /circumflex put -dup 80 /dotaccent put -dup 81 /tilde put -dup 82 /dieresis put -dup 83 /overbar put -dup 84 /bracketleft put -dup 85 /bracketright put -dup 86 /colon put -dup 87 /exclam put -dup 88 /setminus put -dup 89 /cupproduct put -dup 90 /capproduct put -dup 91 /union put -dup 92 /intersection put -dup 93 /unionmulti put -dup 94 /logicaland put -dup 95 /logicalor put -dup 96 /turnstileleft put -dup 97 /turnstileright put -dup 98 /floorleft put -dup 99 /floorright put -dup 100 /ceilingleft put -dup 101 /ceilingright put -dup 102 /braceleft put -dup 103 /braceright put -dup 104 /angbracketleft put -dup 105 /angbracketright put -dup 106 /bar put -dup 107 /bardbl put -dup 108 /arrowbothv put -dup 109 /arrowdblbothv put -dup 110 /backslash put -dup 111 /wreathproduct put -dup 112 /radical put -dup 113 /coproduct put -dup 114 /nabla put -dup 115 /integral put -dup 116 /unionsq put -dup 117 /intersectionsq put -dup 118 /subsetsqequal put -dup 119 /supersetsqequal put -dup 120 /club1 put -dup 121 /club2 put -dup 122 /spade1 put -dup 123 /spade2 put -dup 124 /club put -dup 125 /diamond put -dup 126 /heart put -dup 127 /spade put -dup 132 /radical1 put -dup 160 /space put -readonly def -/FontBBox{0 -954 1043 900}readonly def -/UniqueID 5087393 def -currentdict end -currentfile eexec -80347982AB3942D930E069A70D0D48311E252234D51741E18DB3A68E8AD1024229E5817A10E796 -A78D2C7F7C1F50961B9A57AA604C9F821DBF5A9295197BC66631678D7D2C7E1F8F2151CE0C29EF -CE46270570F4301C5DAD1B38884732E53DAD05DFC36B020E726CA575F71F04ABF2B49E1F1D6D2A -08A477658CA9A48F1C8CCE14382F0A42201DE56E2821EE2B0E91A818B1B753D810EC2428DAE515 -3B66AF66A6CBCBA4DB2BF926E909644DB41326E327493B2750168D128A100FE56C76B17C16F9CE -939588D19C6E9CDA7CB062196E66E38E537670953934FFC63663C7146A12277D8F7C13B563981D -696E0ABE4478EABEBA753024EBDF3EE17F2613DF08C9228159906A48DDEED6212332EF96023E5C -73EA55AAC6A2B938138EC26B4732C11E8FED889257E9D4F2002935585D9AA2265929948E37BAB7 -ADF12F1A22B3C68D09A6B6C4E14B1470ECF0874D92D964CFBB8E2A0E4CBD1A114CC05BBDEE4699 -A576AB8C0BD8499B166E9E60B21F45561279F6474BB497E3D55DD09A26264FFA6E8D9F228E894C -456756D321BB5D5932C5BBCD39EB95F5B7D4DC2DA25D6773EA6BF8B758972BEF890ED520777E90 -B017BB4F0F1A7076DA33C972773E8ECFDF76B347FE529109A1EA0D91B80161C32E4DFB08EF07F2 -3680182631BAF1BEA4A5B9E505311402D9263290E3CF4409B44EDFE28038A0F2101424A9AA4CE8 -3A902FAAA4EE6DA88833898CD9EFB74A321458332CC9A62C93501CD1EB799C6DA44F94C61ADA58 -024D0CED31CD07BA36A70D986AAAD1D3B9C04D6ACBA7ECAE982A8712BA24B26BC4BF9B042C6FCC -9BF7D3404804E72D2B93FD4F56771495070AA0FD181C35CC11CF251BE8DEA12600643F2B79D09A -A1BCF2636F70EDF1F7E0E434DF83B888598ECE0100492A48645305B4BB8BF16CC994ABDAF88EE7 -CA62FA459E421580531F5BDFD3BD83467260F184AFA17ABFF39208581863ACD6632867C05EC9C1 -1A910E396F09359713C5B37AE855D3A2FF8657FB89CAD579EB1BAA0979EB227202E44306B7C89D -6B32C41795F994B293A6BAF7DF640C3F68CBA7674E695121892C8DF86D2C12158D6628BA8643AF -6C51D4241FE528EEAC4653FE8A99CC319F7B1351325AA04461810D536E61F220D309E0BF6A55EB -EB2D1605B65B5550F6DF814FC3E80ADD43E595DFD4C947C4126521D740199C6F98826DE413EDA3 -0F7D91CAF64987B9519B8329E91644DB1EABD71A9BFF215C4691D38024D081D4F769B5CD39ECA1 -67E006B69D797D17D6B9623B7A86AFE5C6E7528FD6D2338146CFA3F34D31A526CA389AC1AF9D72 -83931EA406E45980A3A56107885A74F2FFC195F0A44AA3747B7A4F2B35E7ABE1C949ABEC591E58 -50B654494A5081D0752358A7D90814CE9531D9857C3B127EDD77C3ED727BD0BE7A8143701624AD -DF7C7D84D37CDC05E3E97357D51E3CA329EC76C1924D84091FD864C03D6681136DBC5A81B93FC5 -81BCB2AE6BC9EAAF56BD9A4B7EBFC9A87B6828856BF2A0FD3D744755C02404518AA492077EDF15 -27A71C3A07A751EA11D80E1CA421EAC1F10E29DC40327C0E0F1F6E171E2CBCA87CEE30BA697735 -1361E221A57879D8E1AA7A59F69714389D2C861DF37439BC8713D1771269DA938C8712BB8D868F -D89084A7A8D843AA906C85D1F7EAFEC4DCCE5A8AB542C082B6DCD262C4CA3DA711CA55F28FFEA8 -48E8CCF3BB482CE7ED0D0F1476DBC00704E58207E89AFF346B09DA6000AEA0E6DF562AEC72B822 -6F1C0A9FD7D2378B0CDB7B9A6D51CD54E90051D47F382449D5D23CF6D176913E82474C08F6E4E3 -4577374CE08643CC099DB37FAF73F9D768C3AD7FB7E632FB2EBC0DDDFE6233B00AB0B3E17E0C81 -6093F5D0BCD6A575E587A677670BF7D7250689C7BCDEC50559B82AC0B3B0633638EC5D98AD125D -A00409EEF477825168094F02D3898DCF2C2EC2BBBD4E1BA25E5A4B8E15A6DEDE6005EB2B36EC46 -5B2FEF9532ADF7D35CA2EAEB5F8780AE3D7C09AF01A444FC709E3B2954D504F53D52050F17CAFC -9F57E64535C8FE2213E72DF4A9E8A38F4D4AABAC1FFD1145F5AE667C8A01CFD78DC45DDACB09F2 -7BBD5D23201AC648891138787900E880D512875E6CA58CC884933B164B53B4D288FF85B9B94B03 -EDD9D577670F4842870603BD0F6DA5C01613B9A8D43CD874D4FC67DA17BD49320FED903E5B5787 -9FC5795689C812D74BAE79B680544E8C6482BA00FD3581A366F61345B6936493B2BC8450AFB363 -3FD514D71ED865B791F73CE883AA7A86368EBDC60FE713081D2C0AB4057260AF002E5D298EE067 -1F04C33B7BA068B476BAE2DA48C383663A4921C02FFABFD5915125BAF1CBA2E26014CB589D6710 -A4E722B2C642786DD2B783A4347FC66E0158F699BDB8BD2D037FDBBC89580597C87EDC84C9412F -6BB07FF97A9EAE3DA693BB8E576D3849D244FF89F24A9A5809120A76037A6085BBCC89D096EF93 -DDF6B33D3969A28A0E33777774499D00595B4C4FB6BEB5DB1CB20AC0628CE23BD0211708801129 -42830CC65438739442C1101F09EA0FBF2686B6317CF0269278B451B03090E9604503A6B9D3798C -5F1C925BFBFCEB527C1262B8CD9C0F18A4A254171BB0BF44FA6BF978DE049096B8B39670EF6AE5 -790F6435F0C5509E1FF24334085429E3B64B48F3F91077F8CA3C21B0877ABE2EA0779736ABB492 -D050CD016D127FA3EDD0FC7413E7E4439A122C37E009B8EC4F958921F0D8501F6AFBA85A2FD614 -F9FF40AE81D821AAF6208C1CAD31ACE6EF57F7BB10F21D81BE5C2EC55730425770C35DE27F6630 -641AF6D39FE9B2610C965C867C001ABEF1AD4D4C7D262D602719E5DBBC327E609FF1F4982006B7 -C45681AE3EBAFE8AA4EF1DCCA0F37D3FF2CD55B1609B5A654B6A2890A53A9CE022BF9965720959 -0D14EB79D6E380ED246B1A632D8FA7795D22184917B063B58E9E2D87DE7655EFDC207DBAA36A2B -FF92BA88C5919FF06D085FB9FD0AB19F01F4C3181D9D82B88344C63A75401862F92282E49241CA -CC5C0AC86C72A5D75BE7D819940F21C8F6477BA35C5EB5DE7E244CB12C25ADE420823E8933FCB2 -407AAB99AD7A7B56DE0A21A3D7FBBD04C90C58A3504A9B5ECEAD94043A16EE8E766E550F6D0947 -30699B58FF84366C47BC2D2A99AEE14499E86A236A2344DAD2263C09C6F982AA252A4180880D9F -D7E90C16FFAA55A36EBED8A1E23E4792B3C7EB8EA63F60A08075F0E4BFB0379CE0DC4B7FB5C113 -CBD837F25C0B6F2CD5FE795E300F1245C99C842EE44DE3B8A352841DFA72B9CD6BECDBB51E7A95 -6470E5F081105AB88CC28DFFB66A85D0C75D86F3D7F34C6AA8B0DFFC8B9FC516602116FDD4858E -7DE3AC948F05877B83B7ED7FFDB0B69DE973127B626973AF1CAB5DB213AAFD9C6CA273D5485DC3 -90225252E0DA375406D26011CAC71A7B0C6B3372D2F1C9DABAA5A31C7F8D040B2E099FD7429824 -36C64D34E053C3DAE86B94E16EDCA81ECA39395F8BB552CB2DB50C7F2A9ABD3710C87017248D6A -1EB7416CE5EDAE99EC4270FEFF0DF173A7C18C13A75BE389A4A5412F69C4EE52E411CFE3716425 -DEAF057C40E0F9B2008E69BED121CC9EC4471A210D71823E8EBA1FAF6D88C1F8B2DB2375FF469B -E556CC6208EDF9AF791AC411E80D74BC6F395AD859BE71805E908A0047A12F958A4022FD1EBD48 -37087F283BA1F1B623A584A390663DA5548E43C314D2486E3831F8494C789AB4C636B78482E830 -662A15FC0CA3030C25A481740DB53C4200EF8206F0E097740F3D031544530FA10558CDABEADA04 -6EB00F7C807C73AAD1E3C60D9057A03CD8DC22946E637BB60A776A65164D24BF91A0C9FBC19DBF -BF3B8A0FFA91F438F3422595161200360D3321892D0192AC05BC7A74E52506A620A810AC0C7A5A -C13FE0BBB2A4B2090D1778595191FE755C48148BAEA2AB58DD6CA75F6E4028C9C836E6216C9090 -3ED51C1C33F7B5C8FFFE3E2DE23B0B25AB93FD935C408C678BDA7D623B1861B230BC8F5D21B8EB -AF6A2DC806FDFB21D662993F4DE3A85284BDE964FE7899B541BB17F4C4808BCFABC3A746A2F330 -77AEC41DB37637F4B5105EF1D58C64AC52CC86BF963F875919B3FD33F12A7147B3437B6894CF91 -6D6D3972830B4F849DC2E06CA9444D0EAC059C3B20705B77810C916554C94C7BB36070783A3757 -4CC482215D03C436D2AB7A1B705BC5C2939172839973E4D89D5F57D71A5D1297EBCA20A2947B15 -90907D172FCC7BB1488B1C663A06B91C139DA00AB40B16D933172C3EA66601AA0CA05828B35FF2 -5326184555BE5D36956F04A1BCE10F90D2DF77263E1AA8D79859BEE17780C64187224E1739FA8A -4AC464D07EF68101480E0925E7EE98FD8C0CF5AAF30F771383366BAEBC03D5636C1A1A81D92921 -05B67FDC74576EF3C2D4089BC68657B15733898A0B26B54D9BE19CB9990CB054E9BBB5BCD4BE87 -ADD1629A0D436884CB3E5CAF84C55093278393568251B4450EA719A857379E027FD259028CA68D -313F997616D51FA918B91DBCE6213FC3ECACD4585BAD71068F27243CDF7708F46EAE16A7F67913 -D201387A98776EA8B0C5E459E52B13754C191E27B3BBF8CED1D54A72DFC6D7EB1578AE9826441C -B476E54856E2F9BAC9F10E0B5FACEFBD3250F232F611666F5212CBA21862BA9060523BB0B44002 -F2FB29B038332C893EE3313C62AAEB1FF0DADC860AD1F179489C06C9BB96D843CEABF5196E7C1A -57DFF4502BA71B2B711653BE32A7003D6EE97209B2FB6C4F22B8DB8094166A28B993B6246B792E -D65DD84000F0D4A547B134E46BD4E495B2763C48E93BB7008EA14C2FC7C3461460711572C70699 -03BF49F11F3CE4556FCE122A015D54BD188BF6FDE4889DDF7A92CA1FD50E6604D11DE3B3380ECE -1987E9A446BF220E0C93230AB2A7C6084DD955C3ECC1CDCE0187A0E564CBCF68F6133C0F261320 -8179CABDE9FC93685DBF8B845C25B7249F11EE48DD48504759C765D17D387E0CF0B20C70B57377 -AD90EEB2793FC47ECFF08645BC4F47A702EA24FD69001CE5283266B371DD80882C9886F231E2F9 -838D9E765093B77E19247365F559B075CE1AFF75671E60152047D44BD0B69B168B39582210A09D -224F5226715581F43A9A6BA2D46968227D071CBF3EE13801CDD7F823F3141BBDB8EBEA60B48B26 -7898D5E27D431BBF528A5EF830E26E880734F6E1375ADDF92739347E128551D7E126ACC2A82FB7 -C57336E5653BF97A69027C90DC7179E65F76A7C43598F000A723A7EBB299E5B2EC549859FFED96 -28198C2C02A4FF2A58C0EAC12497B16A06F67CEE100BCF8AB48BA229F930C3D80752D05EE821A0 -C226AB62858FDBC6CF53E9B225456FD4F8ADC62B582CE583054547E14D0EC426E1B00B5A8E3421 -41C52E36C05FF715953F1BEF7AD3A36C92205198A2EE73144D89ECDE4E5B760BF5E64D09858B8A -DEA9C12FF4BE89B345F2032B7D40F1F94832BBF21E7B6FDF42A7602688D0545E1AEF166B8F78DA -BA20110D765981BCD22C6560B769B52A4B5B7A14A329BBF34E5395F218EDCA121500E3D698A705 -B524A3A448C2EED6E5F17FABDC7ACC3182959C7D969A5E37E9C39C1ECFE85DC9154C84301DCFC5 -8337ED83103EB593D165CF7F5339D748662AFDD55060BF1E33A0D73DCCEFAB95EBC614E23E5B0B -F9B900E92FE25E6AD98692A39B164EA46B88368F9AB8DE07953B3A9F0D889EB2B9BD06CD6FB265 -15699BFDE76CADE3A9ADF56CCD694408A776682CABD4CFB8D3CA37FE900B46F4D153CC3C58C36A -D79C692B71B36FF152CF92FD8898D193D3053A16067EC47FB0A5EF1BB806C5BBD5D75B613667A8 -5D1E73D8B72BA47ECD1702B524B9DDACE9ECFF9B10FB9C83E12D7C9D7220EB8C74759FB0C45F68 -92E5C6B3A502F06F45608DDEDAE2D178344D938CB36B6EE82D7321106D2C948201B3D7A95DFCC7 -BD3A1086A584718E3E62962E613E380CD99EFDA0DC033EB33E316BC8E9363B67EE5E04119EA06B -EFAC94C4C44448812B1A7F7FCDD0824783FFCD97707304D8275AD1746A6990C3C2D5607C72F775 -4F150A3B5F6175F453EAE89CF9E3A53BADF80115B7858E113DEBD4ADC2918F3BB2454C35C3F107 -7C2D97E067C98B0205613B145F340A37FD60F7176D265BF6451256269CAA16A48D998D80581F48 -CBED667D690E855E235B4266E8F3461933D9645CC35214AF73C4FC5A42B978A54BAFC561FAEF93 -BE0316B2E4B9927C100CEA3016DC42B8EDC939AC6AD5DA1B6FC86F21D92A5B9841B21412607402 -7559CC1C3DA05536033F2A0AE7F10F8A064AA145DD79DECBE6FCEEAB4C91DB9DFAC173AD124DFF -0BBA9097A84E8D351780382F7713E15F73C5CFD3C5BB48726C45D383FC2BE2732C8FFED42C8766 -6E0AAC7BF6AECC01E98A701526D642B90ADEFF9C48D5B70728EB378E93267E1ADFB7444BFEAF47 -25FB5CE72D8EE7DDCD03D3165CC32429D87565E7DCEC9E21FB34C1099E4AFA0D1993D4EA3B2AD6 -8D2796A5FD2CB2000DF2D8C730C7426854554D5D2D42041BE13AC3731860774B540D88806493CC -E8188C2F8BEB189A484D9F639E3D350A6776B56C2E51A56BC96E2773BDDA339098928E095207B8 -B485BD0652F107B8E5ECAEB68B7136F12AE4630EC2D9BD452283C4F5499BDC4A20073E37CF77F8 -68A417708EA7DEA3E7915AF3D4B3F1EBDABB60E37C3CA374D96B31BA0031D53DE839CCE388FE55 -3C073C1BE5CAE06DCE8012B1A91942068BF1EC74EC261F28EC5DEE7953DFE6C4C346F5E44EC312 -7610389D265A7530E18EBA2D3BEB6D0FC64F32DD4D288DE6FCED7086A0FBFC506F736279F97F05 -2E4CEADA7AA92A5F23EE5120FD2DFC954E5C8DA037E52D63C723C55DBF0CCFDDEB20741D16F5DF -0C2A5A0D1275BF9D3F37B6086429FEF89F59A970D44581BA0B66213F51C4CE33F104AE08A32017 -06E285C69151968DA35B2A78082E587028B405806CDF366C5D4C6E04A6F39D49C0BC23A36A4BF7 -681A3BC69E93FC3063F81F277400D2B45B931BEC7D087F31BD3B47B3F17AE6A6E4B49EC5A44234 -E55193D981033EEE43B79ABAD0752ED28F01BF12051B4511A43C2E8ED484D9D363FDE0129A311F -A62E3D2BCA70577AF1179DEE5137D50C011F74EEEC1230651E071BA0CC9DD9D7D4FDFD21F190A4 -25E8988DD779AF006009435AABA80EA233B9A68823DAB1580742CD026EE9EE874723BE5AD6BABC -FD9DAE0CC9A3E4567E1BAB53A5774550768EB4344062525D0836827569EF9A9BD2CE53CF85D7B9 -14C8AB0BF01A9743B86EDD1764BE91F100CDC9270C813D8B3895A55B46528B0B90CA2820034395 -8C566F25ECAB193C2C126E594A38EC6548BD47CECBF94550CC9DDA5DA4AACBA2AFD4CA53970935 -7FF3E4BA59BBCBAFAE3086F4D45C02B8592ABF94200CB8BB560645794014B384A5AB8C34478222 -BB942AFF1C95477C997B0FDEE302F01F7A52E461D10B0241737574BE4545889FB58642A3672A63 -CA19E8357396D54E18B6054BC91278159C22B391134A997007B04E98B8B036D8CBFCC457959A98 -858B734485736A5D1C932BCE464BDC7CFFA86FF1A7DABF37959D23C9E436FF6DF665E147EFFB5F -7CC0794B01F3B87CB74020A272A798697D12B88BE43BB192BF8AB33B474AF17AA13C3CA3190C10 -F6AB16C589D121738CD71EC64A610E73A2111220C2804D3C602CBD9047DDBEAEC51296203F4DDD -130D6748C819305196501904A00E0A52DC656A463DA07805852235ADD5BCD6953F07C700000DF1 -FFB52C5EBE6373747117DF5587D35BE15B4854054B0CB08AB96D07FA4355E038ED868841A3B4A1 -FA58FCA715CBD29D4D34FF42DAFB7F65A3990B974AF26D1BE701AE5E696EABDC7A997C4288C4C8 -CF6C10028C49E763DA39F26AA17F7BE65AA155D49B7594D702AEEDDA87891CD3D32D198F0CB233 -5369EBCB171287550EBC0394DBBAE9A637A789D052C7C51BC9FF6ED08791005BC6C0D730A49016 -AEDDD6563730AB510EC2BFBB8890D289DFF714DD074848DB372B453844EAB8396536AA5B93B6C2 -9516218F50622EA5B44B15066AC27026C40224FAE3C0A0A7B26E7271251E2CE70EFDA448B83665 -29B147BE0C81E4FA0A67D40D440CD80A0D5649D4EA919FDB09D20E4FD7AF7A8BE4168045097931 -7EDD65B6F16012995935C27F7318CAFE60494B2DE7B81D6B3813CD0075B5C93A3E4C907F277347 -32B553689DD7E1BD92033FECD1425DEE94E68DDB2983555FABBEFC10B3EE02D5836DB9632FA5E0 -6E3D18335BD999F4F2AF2222997392B905A262E87D379F3828E4225082DBD1F805FACFF2B6EB2D -A85C06DC8BC7A1B6D7FB7E33F30E57E75133246946D05A16A6D5F2BB73F46B1AAC466005BC64A7 -0C4ED52EE20E31DC101B1053FAB7D4D8CD2159CB260421B3261D18AAF221A0E17DF1B84035F573 -83D3FBBB1509D7744BEDDC79A21FC6E4E2CCF6EE21F7C1AA792823C4813A812A903402D36EC76A -B3840BB45D31277811B0CAFE17A7909B39B8B139A6AF831D928F751539625CF88E56353E2559B1 -E8BF899677561617726941B20A123D6EE3C6EA8F5FDFCE7EDB24C47FDF560127E219C7B70E359A -2F8BF5ED5696C589BC3DC55B8067609C69022CEAACA887F4D42F5ACDCB1B7A20730739D9F64A35 -9D76372939492FD3054DCD0543D608401A557058DA16E13041135E9E7A6A0DACCF3E4050E01E4A -F27531777C2EFA12F82281B7CED3A3B49FDBD0FD218CFB3407858EA0CB5401769E5583CAA61ABE -0351F66424144EC51F4C969C160FF37477F887139BFDFEE290FE77F0BE527103A6A30DE6C3494D -269386B8525B30CBEDF4D6C2BA04B5C843F76B07A11935954F48C55B9BA63F2B1DC3231B5FF9F8 -75D2DD2A071B63DFA057CF9988A8646035F625F63E892C449CE2A90A2324FC7474B53ADF072F5F -6B389DE6D4243B13DEA6D5DEEBC9EA428FD35B13B3648B8084AD3034C40E683FA6AB99B322DC91 -A946911A63B70B0B0A604ECE8F5E74DDE98261781218DF73B6666ED2C2E5F4E317BB6CEB2555CD -82A6A1DCCA0564AE1C7111BBEFA789880448DF720129F80F856439F261172671801EE0A690C2AD -B81434FF0A56F008A6B35CE08C8832EC2393DC62578CBA2EA45C07E61FDB658B31E80EF9EEF1F7 -1C776ABD17A17EDCF9E852386C0698A55F384F4342547CB07C038CC38426457C67C1E8FEE0D424 -33B7FB9E68DD533550F1E321E0221BB47658C784E1F2D81E40205F919590B71658F02DAA29CE3E -DD19A2AE8191CAB3430F61D4899DC44E7B8883A3E6384B63180F500891BF54C75A7E0B679C6CFE -9C71DCB785404DE3279F228B9389953BE4330497B00D90E0D164433FD693B3AFDD4639A669CDBF -F930558CD2A9C54031FF23EAC02FA2FC878FD29894FC2A3C181BE30D7C80FD5026B0E933B1875A -EC4A1C3B09F0AB78B686FDBC60C7CE7998EC2A610DD543C70D1E7000F3C4BA6EF15C0A0CD618FD -08A0646D582003E1BB8C4C28CDB11FFB0B764023F023C1BB8486BDBC341D865E04839820CEE2B8 -F0FE22513A8AD2DFACDE078504648010888BAB29011996575E1869D1F8CA4784B8488511080E98 -3EDA926D56FF4ECA3BC6A6B16B0D0C720A62F363CE48E83AB5FD243121F08AD6B47E326BDBD5D5 -FFC684307F3C40BADACDCC8049118E49EFAF4F9570823A9EDBF3FE8121C94CCEEB2600347CBCDB -C08FBCA3A972B4411F7A5EA4E8F1D890779AC095FAF29103242B8C090F645AD8CBABB555D50B29 -69019113712C6F058408F1080BC71302C2B9B79647FCB1CF9DBD9ABA4C5D6AD2FFB010E8C734BE -14E618AD1B735B099F0FB59B084C11CCD5579071E8655430474F7306CA9F49C46DC0BB548E5A8F -0D608E85881BD83A1EB98B4E92FE12B39E9C7ED86C46627B6CD527C4D3D92894835F47A80F1F4D -B0C73387E31A429002C4045AE770576E543B63B2A1EE2DD7F4EF11A1223E9514C9D75141101170 -F2774E52201AD076FF942ED6C97FB6D1D15E7D7C8391C3D25A0A08422202F93B33F38E58F8AC97 -5A41B2549E95C5268D79208143E420DDD94B97EF2ADF9E7C77A2F38BA50E03B6BF43972FC9B19C -22D071CD79F26BC6A2AE9442E57A3E0DC49F30B1A3F9A30D8985900DEB6CA9090B90656EE40CD4 -4F483415C71D4BF140E3D9A1617CE38320955680F74E120F40503C712E4438EED9354969E3217C -2F297BD277D1B0C120A8DA45E2BCD0DDBCE00EE2A5553AB493918AD82EAA20AA736DC5B93BD0E8 -094BEAFE5E3181D39028C1A2E30CD6B2816150A81BC3DC69C9A3B732600C45FCC2F0B485FC9B69 -23338458A054C570AB6F8E3B284E07F223B843BF38122A2E816A458D6A062E2E0E1B76060082D2 -DF3B4A5FF911C089698FBDA697CF2A3FA47C17A734FDBB33EE87A5AA068D21745CC4661C19AA1A -E05A8C6030739EB01685E839793CD5BD566353436380622A0D597517B684C04965DC1F13B5C611 -6C549DBDB42AFA964789A223EDEFD10C57EE4B1BB1B06B6942B64EE66E1D67E82D4CEADFE47ACC -35080AFE3657BBE687E353F4C94A3788A260436FA1C114B9003DF5DA81A3A471624D73472D61E9 -A616FDAB3ABABC225C845FD8F12103B8F67474D7414833074E47222BC00E86ABEB6D8630DF3A9D -84E981EFD99C9FAB64494894F6BF88045FFCE054C50945B75D2A00BBFF2F68EEEA5FA19D5F863E -128CF160182CA8B38EB1560F07F4DDB97E0E759077E70BC4C2B309020840C288951B56803394D1 -D57B46DF96DDC9777224BCE81E9797549F18CCC16CA7C25202C4569EECCA6E48EC9C0D911C7D9D -A2FD831635D913E54A181E56F8808E9A8D27BCA1C4DF10CC927794F64018A4B14E003B885F0C18 -DE9DB23401ED18890021623ACF1AB9C9DE1FDD33D4F6903E4CA4C668534F99F05CDE08647B3FA1 -A8DE467C565D9BA0F6E1D09595B886353C8C67E5095BE53F1A841E258BF2B8FBCDBA798CE77B7D -20D39940E6F6C8DD9A004778BFDB57BCB735DB413236F0A7B864CB6CC3BBFB1B33A23EDC484920 -E5582F8248933D9EEEFC1E5E5386567B576D0362FD750EA3FC631B31E61EE1C5D3D6A0AF9F4E8A -436212D359F7BBC9C69DCF4169EE4A5DB65A990AE63E4773607DE4A7DBB85CDDDEE4FA65018C23 -0900CB9F868885CF80AE58907134616D78B7179130F76557557BEA8F19B62EF87F9F8AA93A5F0B -DD78C6CEB352ED458806DCE1DF7DF2E2CC34B724C61364D707EFC4EAD4A8E3DB732E8FD1B5DFCF -8C3C46D531D266113B63B7D01FA053EC28347FD23A35CF986F5C73378C8ABD12D1A02B98EA98B4 -0F4ADD4F4226D773BE1ADC9841082A9C9E7A5F99534FD6846127054B2437D220A04BF83D16EEFA -7BDB4799DFDBD2DADB1276FFC40C6C24F2253245F21E230C822E323CAC694FC0B7903574CE5175 -94F6C22557E231C26768C5DA5572F3D473712C85225BFBDA924766D9544ADFC177ACF94798AB07 -985FBBB8A9F230702F3302B1511665B81E33EC69A61F6EE5AF160A034784C83D0BC0039E04AF3D -C8EBDE4DC0EEED8F1FA37D462EE55E63A3526E8278AF663BF5BA1902CA695E8AA7C4EE020FCA14 -BA93AB5A0DEFF681E7602135A13DE7567192764DD5D26B1B5862238FF3ACF20711FE0C24DA756A -E629E477DDABF428FE4E10AF898CBB8606BAF96D29627E68A78A483D47DB135DE7FC53ECD46A12 -9D64D17C3FB16BC53CEF1F1581976BEE603964EC3CFB28EC4DCABD6DAFE9FC854C69341DBCD4AA -1CBEB29789AAAE56A5C411437ACE39B035C26F77ABAAB2524B7EA71BB664815BBA7F1BD857BC69 -281071E74CDDB91C28E59C3007EB2280BEE16E14110AE00324B0A72C65547E3A0509B769608FF7 -4073E2BE295BB71ADAFF01E81EC86561C7095A2E5840F54C3030A83045593C43216B8B53269CF3 -BFA5A16BC7F258B34F46B5B505BCA9B5349F181D9DAB84372994660A77742AEC03AB32A3A95253 -7782C7F489219B19393A0C1A5D9EEAEE305A1BED8376E534163B3303AE930E816F818AC3C5314A -5E23460D8E6B08DEEF8FCCEB7F89E83A8805708CF5A6B2961455693109059C09182B7E08AA1C32 -61863F6F546CBAB64E249BA5ECD7AC030973CA1C69E3A37FD5474594181F53528300070F404F5D -4C2B9D43AD4445A7CA703F67B46B2735F7EC1D01B3A2D023B11AED0891AC2BDE28F32ED40DA342 -0B6F94EE07E269F4A8D07E29F13DCA62E59E14F3C84FB1836073DD34E29BAE513F9888BBBAE7FD -0F0EE251534E4D7FA6F27C64992A134E8ED6910B29FCE7AA2DA8A58113422E4798DEEEAA323035 -170A1D20F6A4BD68C5F495F42648210BB8F056F5DE8420240651AEB4B03A43D18589E2F8CA7380 -3864002F2709D60BC735C6CD5692DAA22D8BAD66144ECA52DB3F0910680EF1376CDD3886A37579 -A1AC30E349F9EC89AC8F5D7BB880D459BDD538FD516E9780B09A907E1C047F2D5EA6D385CA7B11 -32BB7FF7E81539D4D7EBD5C59C32DC82B44BC5DD698048789CD16C51B072F73E5A6E68546BDC32 -306E7D197E6D4288D715C1902E58B6E93CA321D45F7E82E379D569D040BC64352060E138CA4494 -61CF8E51BEA1CC4A9ADB6B5C26A72E6EE8C089E5198615A621323FC9620FA12770C36A22AF2277 -823090F7D058D3434A894FFCCCE04022686AB11670DBB6E68FB6E2336D6C18569675D219E7B6F9 -FCD6866FF8AD749B6CDC7EBFB573757AF230A1E9BA4F2F53E8F0F20660E105F5733B3553DC17B0 -580317BF4B87376B53D6C668F169723EEDDDD1776DE62B7E0E0E966C5F2F43DAE61339596C436C -64A2369EDED778D98A65B3222148921E381BB46FC0BA1DC3DDCAC224D0B9F0816C00BE91C50376 -9D969FE0BA42B89452E84B4F794B7D9688B66030C7734F63FCBDAE262E6B4FFC1AC235BA67E0E5 -1331118FC59B325B630E6E22CB55321928B7D153759A11A47DF9D679CB9D10714C5FBDADDFA765 -60CBE22A4D25943AA856B0B0E190FF911980914072C697C556A91B894D3B1A096E0AE9A74D2610 -5CDD88630F89A00EE9BD92BDE8B806A2D1D4AF265C796D1EE519D25CF196BFAE5CD837A0BD2F76 -A76B4EE2241B2CF9D89810807AC10B3BBE67179F216FC44920E28F1FEBD64C2750E1FDAABDF1AC -1DEC065CD4AC4239B3DD6A93CAEBC22BB7097FBB4122ED104DF6A7D1F4C76A1C8132FF188B2438 -67B38708F8CF59563E72D5F82B302F2B0FA4EF4D877138C14E250D36032E9D53B48F6906D73DF3 -A682439B8AFC64FBFA324C56D825315C8F3FEC5FB3D8F73F6292D617D29F427FE5DFC85C3F2DB0 -882BEBBBB704102B3A53918441A507F6F468E4EA1B8C46A4E2DFFC654107FAF494C035C0A03359 -1B83E8BF142162C7530A1BE5618206B97EC7E92B1B80EAB0061746AB3717ED65EC0ED719F2A1C7 -3F105D88687FC5B00617CC7CD288CE7A938C9F9C4522B7B43ECCF67EC5F342B62085938BA3C1D6 -0255A9DFFAF237D6CF752A52B252BB6C5AE4D6EC39F7DA8427D6BC715D7ADA63743E813AFCFFE0 -A07F8229FE2074A82E315EB7DA0448BBFD41D06C4CBDAB1DC014A259CCE764AE969B1C6322A1BF -CB703816FABA522713B50878897A91870943B20869D52A01DD76695BFC30C39595409EB8F2FD69 -97D7A3820E2DA1BB4F7555EAB7422CC31783E2A20F54D9B8759CE29F0461DD43885545FAB24357 -C1013C1FF6D778A01853AD30356382830F7653BAF57E2F6C3AD79CDDB2BD9376EB94616F975D83 -D85214593FF76FEB63297FA6F9A2566A1CE29811D81A03FF5C5493686DE4C5AFAB19283ED36241 -BBD6BAF5573CB6EBBF8DF5EDCAD5F69E8B65580AD4D6A4FF6C02D73BD52D21B73A6E69D4857E99 -BBD2AE2714A953DEA568878E338166311B45CD51A8FE1E0B6E6CF1A03193F82A8E428D9C3D2BB5 -1D26E0AF099F2464E235DCA9899BB75FD54C37AC15098E1AC9F33E49FB89E0F106FE9BE1F152E4 -E33DC4050C3517B5EF7BA154F0B267A7C35115F6EB6BFA3D061831BE470F5478A664DFC4E0AEE1 -1300B30526F50AB8274F3D56BABFB9623B0C7D7030C67EA7088E4B1C767F8A00A01EDAE880EB13 -D2E57C909556D6AF8E067AD42A1250E61D50ECCC72F67B50BEE2302AD6E670E0C940C6D3FCFD8F -426FC6B8EC86DD4461545742E2C1952AE52EBEB78FE286B72B75A3D7C0F0FB97876A85421BC38C -CAB03A436E42A09835569D741679103A52ECBE764C4E1B6FFC50738E98C154CA75C51925C5744E -A5299C85331D7BA5DFBB67E8AA8DB9C4EA559C4F6404D760EC9FCFC572B691E747FB7D6BC47D9A -43DF3F8B6873E929058A30D37087CCD0A7A7C2593E219B19B2095EE0542FC49E7B7EBC8FA6208B -96E891014B4BE49BA7510784271E2E8B4D2E4F6520BCC4EE5C7633B79150CAB9807A1B01B50E81 -BFC2B7B190A3A848B3DFC15E8B47AFBBAD5C7497A564D927B680B0976C5DA2693C87F18356931D -8CF9AC134A4A496FE850E6A5091956B89776BE6D893981E0279F5D01E605CCA08F6B4C32A6D01F -1FD9E2B243EC60D5781F4B2D6FCA13CFFDAC188F4F39A155B0F64E1BAD587E8C1953723C6C59D4 -7321289D9A086DC57FC08F7F2DA512C57A3B9CE4461D711F25E495C5E50740A364798E6B5B732D -6F17EAEA63ED222DEAF39D2E813601F3B2F416465776CE7154242C5CEB14F6CCBF23EEE181EB1F -92DC7C580610902C6CDA5FD15E096317549184CCD14F1AE54CD5688D5FC329114DD48AF6DB7524 -414DEE65B3528674768F9DA68CA2552A770E111D3327943CEC52A7B23DC55A98CBF2C0D3A6E2EC -F15A1F093E391AC11CAA0922696275B87137473FF0EA59A1ADAD12C529D76568DF36713DC914D5 -7DD5E298A6034F6D918DB3BEDAF88E74907F4B03C41B5ECB0773FEF89237C9C611F0DB6F3BF1A3 -1EB60AF8343680184FBBC3136257D2777802039F57F2BCA2B1515742C64026848B669F8D0DF5A6 -871858230EA9A9DBA628CD40269F33D9B8AF5DBA58D4BCA52F8A7A2A38E817B7039D6C4B40DA09 -B4F2DAF8CC12E14D96BFF75D61B4166121E56DC3D0B2D89E31BABC8E1308A86D0F6E3F28B4E873 -28CC47BBFA115500E22416BC153A68AC0299BD50C833E3C1AEE97EEF711449DCB33B20763E2E65 -1D429B9D3EBC3429E942429A00641715E268F9E226C0FCDA7A2193C42FDBC3F6A6E668F27DA5AF -D2539C04D7CE3DC030880DB21B7958F625ABC5E6DC94FAF9B8469790DBFDE65C89955F83CA117F -8E43D8AB9E5D8664F08A7CBBDAF4C86D786F4F0FF19D9947D08317BB5E184346EA5A164D9A558C -EE77581AA92DAC056584ED36663EB708D1114D73A00A001D440C8C338E7CC7710DFFAC6E93696C -FD245663F457C5BC29B9029BF91566E8B147016F0B3104BD8863F104A6F0E431CD33BEC307FDA8 -17BC5571D98C3DD1AC57A899787F2903D410941CFC818BB56C19DDEDC91295ACAC20931525182C -091AF85AC3E161FEA22F8E65B44E746F8FD40754226439FD9A660E2D02E1AEC9D9BC214F5F16A4 -D5BA4E1364D8E8C80A8E57096B510B5A8FBA5FE6715046BFC52EAC796F23B4CF996F8CA9ECD236 -1AF5D627A4076F02BBF615556801BC06D014A020C7A4D7BF87CDAB9EECFB90B4C8F6438E28EF59 -9C08E1646D023449FE2563F481B23C5765CE24ECBFC6EDFD5E69294E7910313DA056CD9C75DCD4 -722371BCF97AC6DD6D2DF99B35BC98C05932BAD200E1F5CE5F1A39BF2F14AE9BCE79157ACBDF8A -E4193C18FBA2271AAE398BB618DACE59C98424D17B4A9F152912B5AC21345C1E0C94631CAF2B51 -1DCAB35876A204F0BDE78BDB5F82148131DAD9C0BA3D98EA870BDFD86DFB920006DBA5B4037B83 -1255A44112C3C04BA51E3EE35B72E271640F37E6D1929615D75B8574BA58A2CF22264E1EBE3AE4 -74C0CC9EF06F251D9A702469CC838F7DA8EE2FFC1EB92368E839D658DA04AD3FD83325A439043E -6489945004F7383B5B77F9D799F3CB07D8E4446A00A8C1DE81D01F48AE998A898785609A498CE2 -FB0526FA2485F06F4F17E54141455D0C6E1D8D337BCE938A70FA1F9EA9B2C1FBF1166E26A0512D -E4C347254DF67369F91B82A1743F1F26794DC06C7DABA10079FAD6FD2B559DACC704EAFC12C204 -CB0A6BF8C97971D1094F307953947B309DA4823059A83AFA23ECDA8FCA4870E5949DE858F036E5 -0D3F193A705537E7A131256E72FC4F4949C49FB40C470480464629F987D6E4058A70D28ED1FAF4 -82C3E8E402BA5D2E9A8ED50177C356160F2D38A5D18775E2F204D9767953F3FA4C0A0F05EAFA33 -AA5788CEC8E64948D6DEFEC409901F7C2611110827B401F3A7A309DE2311FE4A27BC9ADEFD3B29 -7E86C696C57C2C70066438FA37876F8C0275458F82E6FC15D6B55DE4CBB8646452A26FC3D8248B -CADE704766582D20946FB5EAC8739837DCFF5A1E84EEA8D9C21D137CB93DB74925250A0336839D -32C115A5FEF9ED71D4E5A505230F6AC17AD3773A5E5A094BB3900FA0BF3055897966A0BD052AD2 -1E5CB6F327300D77CCD2A0283B5868023E86E50E064E850E45DFB3278799854C055CF83FE98AEF -8A5ED9059EA6C1EA5B4916F4673782335EAC2836507A3A2AB61917E24140454924863F30E5C7ED -786B5379227D4BF411FF8FFDD037FC30522BC8CBB887E860D871F59628E1FFA0BFD7FF2DC25700 -8E5DF7FDE2F02DCA442646EE35238075CAFB8ED068E50EB4D6B82EA5F7EB3DEC3C9132A8ED6F15 -59F530A04A4550E83A87A09CE39F699CE8B42D17EBC0EBAA6B916CD36C766160357404B227FC43 -1E1AA8E34B68864C18BE49995C92581AAA084D6FC95599770D84E567C3A45745D84A9DDCC9ED17 -9582B3F4BD021A28E9913D8BC40FF6178C7D0233BB2D876F91B3DB7F9B74A6EEDB70D2C363E8BA -D3D69B1C028752D95086EDC8CFCDB2DAD247ECDF88A28F245BCE710B796C554914CE83E4D967AF -C305D6BC70A004ADCAF4D354BDA1427DD0CCFFDCA32D9E5E8EAA67A37E145252D468ECED627F20 -38BB4533B00475AE81BAD8A49B9C8031E3AFE5AAE493E4864D5B9AFEF5331E4AA436BD6B6FAFE4 -3073C9DEDA76821B787C8C4CDD42F14DC97383648AFAC72F50E40671ABEC730DC100D4E442B762 -42726C8E569AACF6E43ECF9E5376F0BF839E7EE78689EA1DFFF44E97F93D0A98D19520DAE6F4D8 -8A6159B19FD2897878C26B816FA99DF3C99A5DD18A702A0E285B0256326636259700ADB9D79608 -F0341F6753120DCD82D4D80DB3F3AFC0A84BECE5C6AD87F7E0BF915ABE08E7F39D92A58894AE7C -3753A68CAEB56529E899D29EFCA137553DE0CEC1E27FE7D09198237B25B33EE059424E032BFAB5 -E8AE55336A9A22BD84B267B8141EEA7A0660C75C32CC9040C91694DE84E975BC52797CC4983A44 -044E9EC79183C985AA9994A8547A9AD5FD9BA515A79671B7E912974B4BFB58F3C1F4218987DEF2 -5753839C5A335C4EF125596A19DE6D28C10D648FFABE683D55957737AAF73E85593F5173E70A8F -9136943175FC0A1CBA166FAD4857AB9405F3CB1C96A824EE045D579436967ED9295FDD3C7D931D -9A77539F886F768FAB2D8EF6A987BC0452AE7DFC2BFB25620EC056246B7DDCD11E68BB3A2D055D -F0714AAEC08E88067B6C4DB719E49F1C310BC367B67AAC68CB72588D9A11E22DDD65215EEDB812 -78813D9C09A97E219CB5E968A8882C79EC2BF4A0B55761384D585A7E48981FE624117FA09AC46D -5B6E538609292D9C63874A192C1CD25FD5EB5BF30E1602213CCC5708AA7A28775AB1D669EED45B -8AD5BB8AE72CF4C827F34228BE33A0CD40DD3C1FA757DE434485E36D09800F1C2D28323B4E7E73 -C8F5F79346D87C617C5BFBF6E908322FAA26ED50BC66CBF71E0C026705E162A370822AEF8AA022 -860164E7FD1E7FB81C5E14DB0A81659DA7BCFA650B72112994922D416E98D30E3169F696E843B7 -B34C554DBCF8029FF5910539A66F55B7666B861BD7E2BE7A9B00D44CE2EAF55A98AAD03319380A -8F8378EBAD79823A27057276F9FE454C119C03E20241674F5896B67AD005130498711BCC8CADD0 -265157093D22A1F7CBDBF2A3381AE5A4BC07F316872418AB2F6588BA21DB31D7B0CC304CC2E23D -0F810DBC488F91954F5F28A82D3D53782F399113460B0DFDEF872FA825C94262A70B1FE72933BF -40FD4BECB14BC70B3F43911BC04948231139FC4D86B2F0854F782AE4B9CE7AC33EF50275AFB769 -C73435800D212094117D0DA5B694819DDA8600BBB6A098091C888E32CE9F8B3BC4E67757719B13 -420F989143F2E0B85B2DA6A695AA91DCB5B69186A59CC232F2F434F2D3FC1657DE90D3698230FB -D39C19B3B62F18ED9258D1D7CC8CBD1CBF58592BDBCCDD164C8A483AB70127F4C9E660BBC673C6 -3EED28CE5822C2BF20A785C0D2AEABA3F4061A585F5F48270A36F11B6C5077310BD00FA21475A4 -E2E60D99C8A1DD5D74B74CA470D964157C7D4D4992566D36558E58B7E07D091D7F9AA07CABF586 -F248D120917AADEFCFA4F689636185D53AE061401AEF4A3A19F8E0D9CB30B54979525D47AC3ACD -E79FE768CBB1AE7B0A2BF509D102CF924D0D859F89CD39BB99E2883C30A4E148D1918F1EDEA095 -149B37774ADCB4B3FD6C0345EA23F0213DB4F29A8F167324C2A1E8CD9BEE21AE8CA621BAF73145 -1AA582E9FD1EB460899A8C38B08ED183929A81ED396448BDF527F409644D17B4A005B9862F5F7F -B95F2155BB93063FDB7E545886477B5B710CD2BAE103A9CE1DEAD4F15F63F41C892CA84C62680D -D511324931D4E51831C25CB2C119DEF8E5D75A9A585B0E4C89FBF74B21A1A8E2206E6EBECB7304 -CB1DAFB7D0C4000DCE1A244A29525B3872B14F29CA1C9BC17CCE10B135E0C3F530F77AC7AA7C0B -059D07AD74EA9A7C55E9FA75B381CA902F13846C90A2F7C48383D1BEFC94BBD0103B991B79C1F4 -DB3EA8B83CAAE65FFF6B077ED2471AA551BAC92FFBD6100210C1CEB57225697BFDCC5C414B8EC7 -59A4C3AFE8034A9EEDA112D991D078CE7522CF3990462CA35F03CC7509BA2E30F7B5BE75F0352D -6F96D914A53F9AF8975DCBF3688201102A3162F68E4EA8E249B94D0781011FD9E0CEFF944455DB -2F6517FF96E2958EA69B86D96F267251044AE073089373B7822513E0FB589769391BCF2DB62ACA -DF995F020A2BAB02E0C972BC4A7F6B5F7410CAA369022F2D1B5F861C5C5276FCF4EFC65449DCBE -10E069725ADFA61DB972476EC495B544A174ADB5177C080C5EAE6B44E6E044DF660C748A935F0E -7AD665C390C73CB698B1FD187F9085F58AA14BFEBDA9BB1730B2BA5907CE8C790438D4EB02280B -B2B611BEEF36F75B636177E6096C0E1E31F8240B38318DEA7626688B8A0CA5817D8F281AA804EF -2B41A8CD7605F02D032498D51FE3368A00336084D38B29372931C2CCF738731F9EC569E3B2D54B -24411425B6D39C891393D00FAD30A4939848B4B1D5BB9FF68B345D5901CFC4DF9DEFE9B522C000 -086469D59A6BF467840C9EB5C491FE50ADFC769535E452878A8CF06968FA0E8B9DD30F35BBE61B -4C548344379489E5DC966E09588FE4F269DF0409713211C7299327BB0294D45FBA35EC304B7B07 -F5A67D46A786C8247807067086142816F3ACF77F03D5EE6FF5F8A2B8369C0F1CC922B59FA31564 -3271CFD550D6927E21CCE4E8FB93F7A920339D721CB2EF9F4848AE3D96F85BCEA64B4AE93F5254 -D9D4B18991CD8C5BD76871B9EBC855663EF043A8230B344539D2EC6906F58372B1DDAC014C189F -E9E3F73E25790CF11DB0ACB93A64D3ED9A57E11826825926629F23F332CDEF103DB74634DDBB3E -444BF96DBE0898E440587D86F5EE18C01CA829E5D1E30D1A06F1E42CCDE92ED96A1B5AD7362F36 -F0A3E12A98CC4A9E450AB2909475814D5CD4E06C6EC137D49B31716BD1CF579B668C189A49E9A0 -CD2DD4224388F1457FD508DF001BF9F1F7DBF9251589282F55EFEC08995A305605AFDB7A611212 -B8602A817B2B5A632888886921BC94BBF3BFB1C25A518741C8477C3E445485BE65BB0C90CEC0F4 -148734EBCE7E096314163C57F1F72E083253BCF06B45580086BBD0F3A3C6626708CA8E11D9C4E5 -28B6FF99B7C5FB64060C4B7C2AE76AE9C98E5A5071688AC1010FB0A81669E63745A26E027D6A21 -505594325EDECABEAB4CE8C6DCB221AC9789676F23B2B05EDDDD215539604BF3F82880F505D282 -F824C853442E8E39FB9C71BC55E793118BA5BC398F476930AAA980CCF7DC12D24B41D2E7589381 -8405E76FA5AE74586DD032C5C8540223BD218D5622DC8A6B0587D133D0FE9F31A636C07913C27F -20BE650D79B35F1616A6846B573B0D4B6BD560B50028C02390BB52ED835984B8F6630BB7C1967F -DFD2DC734068516352AF4B0F207E0143B24B22530EA7F058FA80487D7C1DAA8E6E049CE8F5E0BE -E2BD29DB095A48DD4242EF9B7388FC24EF655A2184965166E569C4D0F1DEDDD3B6B14D1E92D400 -8F8911D54E60822F4679AEA8F739E22BB7B03A5B04ECBD75A95DF15AD365068B7883264C139C4B -4BB9D7D65CB95D2D69008696443D3EA461E1543ACBDC42BF7CB9E3AE13D5EAA317F90414A3BB1B -94AF1A419845A8DD13E392F4359B4D145DE20BDC83B9559FE0A9FFAFFD71079A6F7FCE6F825085 -CC3577AE98BBDDDF39BB10C19541B2D65F230CC807B71D7EE35C35250775F8FC255FFF201D681E -CF7184D3551DAF6632374E2C0066B90B3F2FBA38DEBEC7E1AAFB9E75C25E1690EF1FB008BE0827 -38C42606443B9072A0C2EF27BCDCC51CC63B751D40EB50C8138680C07F213AE287E902E8E86DCD -FF44CDEA064F4F6DFE1E619165EF8CF42922A25A4716A110B92A83B4D2C439485893541FDAD9E5 -638BF0578FA0497F5E7D3C666B1183B830AC1925C267C1B4FFC87469A522BBC2E07D8270FEF5BD -A7C02846F5DF4216083CB0D110809A8BD08E3BD01F3E19C096D692E481ED952D8AF6870C1FBEAB -011BF3604A950871ABB2B3489EC07CB79102C15CFAAFAEB098D0B34040CC4D3FFC34CDAB240A40 -C26AA74C22C90B58B90AEDF1A4291C84B5E3AB0EF1D41EF30AF5E760518786C347B4AF86FBB861 -EF38C8ECAC757E2495F358E9B71C8BFC4A5F0604CADB5689F17993523FFFA64B39E9685AC9D503 -9224FCDB0EDEC24655E97530C827A587D375C9A40685CCFB532F9BC01F27B26553D8656DC07B53 -6AF6690434FF8F5BFEAE26460BEF05D4CC0358102FCE94223C048C96E004CC086D440D88799A47 -72C20DF93B83052131CD455A5498716EC46119EAD40F30FC1AE46019531490B4EB0919D54BDE0A -1D65304A9D9DDC4684E2E0AE546F9E54AA498403FD978D029CFA934D5D4C021C97C995A43179E9 -60255181BCA8860670A701939C0B2EFF33788ED38760D6DE2B19161AC68EACC2E9EE06E8147F16 -9E17F3849F9A8459439E4CE00D9FFBA40B01D0C92C5C5CC805BB825D9D03C4E8A299AAC9122E04 -0A234B4F973E00A1B2524E0278A04EA00D5F7AB15347B967DC5A8226E57577761ED08EC081DDD9 -E1BA28FE92A9520A9E86C14B7C40C9DD49EE603EBDA359F2C39F1E399949353FBA12E1EA1A0316 -E56D615C4F6C5A481D161EA6E225994FF7419E4408C7A0778CED1FB84090BF6F774E26E2264BD8 -E55CDFC33D0F970A992F683F0272ABE717F98F46AB271E68117E6339BC0AECB9E45F230FF57742 -D4CA51C9D0E3EF7CC82A7FD880C3EB4A24BADDA4EA12C1B7DD77E002EF91AEF22038DC0EFEAE71 -D7B86B32ABC84A6983C613EC3A5C40F180FD5E68F1CE8E6AAC0E880B35DB366408237ADE529FE2 -C497CA863B61955815B9E4438087605B952CC6B2AC37F2DA0FF60B8C208DCC873ABED2E02B65D1 -F107102BD0D8459A5AE4B23950A0796B610B3EA310B25709922C0537C88CB2F4770224A3A17F35 -F48BA498AAB10F423B9958EB9025D5F041F31A312B32A264B07067B8D27EB167056E9CA67462B3 -31AF4B55ECFE51D794493A508C09BC244B700380C01AFEC1F340149AE6544437EEE9C1222861AA -17B647D700CD75D95A51827226B1FA55D0BD6A780F31828580EB192E2E9072AD88E9A4D9C50752 -11583ED95AA662D563744CC8831F92D72A72EC2CB7FC7CFB76C89119810345026F15B4E5B9FE0B -09C83EA32147D38FB50D003E8897CE50A77AAB784700F3892A399EDC3CB5F5A95ABE85617C2983 -DBA02690B3789BCEAC789247547C3A39BE33AE871FF808D70B3D6D12BD51E1030A23C8356BBC76 -C901868694896882C90E40C1C1940BEAFF8BFEAEC1D426A1C44B6308EF4ADAF38D88766D6FE1DE -A163B9203E33E2807AB582AC0763BFB7E730CEE12F374108C84DF65966DCF77953C2793552E7EC -526C553B2B66348888BE30DF7DCAA1F4EB4BFC852C231358ABC89A3630D794D7B7B5581041050D -093998A61446FC8651C83C36986197AEA67C8F85EFCBA6A2E90249F15974598D11461012B2044B -0C730E6525C37D1196214394EC7A6D2A92F00F9DBCF62FDB8C1D41E70C1C655A4A25D30BD009A3 -FCAAE8DE1574E5359936E6680A3081D2C1648D1A5853D8EEB72E63DDE6885578D8DFBF7E90C5EE -A7D6F9F6CCED6C22C72177D58B8E05BCE2AB63D353D1C7DDB9AEC88E5E709CD645EC956CD1AF54 -34007DA54B7B0590AB5013E50758AA9D3AA1486DF2B7A368070DAE49C9C83C5FF98F33012DA73C -E02827F8209AE8182282EE67E936BF65B137D85F9458DF930E668FCC2CE7B1BC157223372A425A -E92B16556CEC07891AF58192EBF36340CA66D275D26AB19F5EB2A5031040D9A2472A0D1547FE42 -C302E23127C9BF7080B718192A4611888E1431B79C19BD95E8A0D1134E115D60F5CED1064D2B19 -59C21A9645673653752B0CFBEB9097F7747E6D45AF059338649875C5167BC91600250A8067F8AA -9652FA4CA4F08A42B95C6279A6A5BAF6320C3FF1AB33C6D7BEDB602AA4C81E4D53C2662D9A220A -CED6982B2F6F4D14C552248185D61D07E2A585CB87A93E38870F1C1F4D007A994126B4B6D37110 -5122A8C99FCDF07E4E05938EF82644DFEC40525F01BB06B958F787B3F94B4467EDC4F0515C9D69 -896A442EF69E9123012121EEE3B9CB2CA3F1AD1D07AA0E45 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark - -%%EndFont -%%BeginFont: RMTMI -%!PS-AdobeFont-1.1: RMTMI 1.1 -%%CreationDate: 1993 May 10 16:52:31 - -% Copyright (c) 1992, 1993 The TeXplorators Corporation -% Hinting Copyright (c) 1992, 1993 Y&Y, Inc. - -11 dict begin -/FontInfo 9 dict dup begin -/version (1.1) readonly def -/Notice (Copyright (C) 1992, 1993 The TeXplorators Corporation) readonly def -/FullName (RMTMI) readonly def -/FamilyName (MathTime) readonly def -/Weight (Medium) readonly def -/ItalicAngle -14.036 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /RMTMI def -/PaintType 0 def -/FontType 1 def -/FontMatrix [0.001 0 0 0.001 0 0] readonly def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 161 /Gamma put -dup 162 /Delta put -dup 163 /Theta put -dup 164 /Lambda put -dup 165 /Xi put -dup 166 /Pi put -dup 167 /Sigma put -dup 168 /Upsilon put -dup 169 /Phi put -dup 170 /Psi put -dup 173 /Omega put -dup 174 /alpha put -dup 175 /beta put -dup 176 /gamma put -dup 177 /delta put -dup 178 /epsilon1 put -dup 179 /zeta put -dup 180 /eta put -dup 181 /theta put -dup 182 /iota put -dup 183 /kappa put -dup 184 /lambda put -dup 185 /mu put -dup 186 /nu put -dup 187 /xi put -dup 188 /pi put -dup 189 /rho put -dup 190 /sigma put -dup 191 /tau put -dup 192 /upsilon put -dup 193 /phi put -dup 194 /chi put -dup 195 /psi put -dup 196 /Omega1 put -dup 0 /Gamma put -dup 1 /Delta put -dup 2 /Theta put -dup 3 /Lambda put -dup 4 /Xi put -dup 5 /Pi put -dup 6 /Sigma put -dup 7 /Upsilon put -dup 8 /Phi put -dup 9 /Psi put -dup 10 /Omega put -dup 11 /alpha put -dup 12 /beta put -dup 13 /gamma put -dup 14 /delta put -dup 15 /epsilon1 put -dup 16 /zeta put -dup 17 /eta put -dup 18 /theta put -dup 19 /iota put -dup 20 /kappa put -dup 21 /lambda put -dup 22 /mu put -dup 23 /nu put -dup 24 /xi put -dup 25 /pi put -dup 26 /rho put -dup 27 /sigma put -dup 28 /tau put -dup 29 /upsilon put -dup 30 /phi put -dup 31 /chi put -dup 32 /psi put -dup 33 /omega put -dup 34 /epsilon put -dup 35 /theta1 put -dup 36 /pi1 put -dup 37 /rho1 put -dup 38 /sigma1 put -dup 39 /phi1 put -dup 40 /arrowlefttophalf put -dup 41 /arrowleftbothalf put -dup 42 /arrowrighttophalf put -dup 43 /arrowrightbothalf put -dup 44 /arrowhookleft put -dup 45 /arrowhookright put -dup 46 /parenleft put -dup 47 /parenright put -dup 48 /Gamma1 put -dup 49 /Delta1 put -dup 50 /Theta1 put -dup 51 /Lambda1 put -dup 52 /Xi1 put -dup 53 /Pi1 put -dup 54 /Sigma1 put -dup 55 /Upsilon1 put -dup 56 /Phi1 put -dup 57 /Psi1 put -dup 58 /period put -dup 59 /comma put -dup 60 /less put -dup 61 /slash put -dup 62 /greater put -dup 63 /star put -dup 64 /partialdiff put -dup 91 /flat put -dup 92 /natural put -dup 93 /sharp put -dup 94 /slurbelow put -dup 95 /slurabove put -dup 96 /lscript put -dup 118 /v put -dup 119 /w put -dup 124 /dotlessj put -dup 125 /weierstrass put -dup 126 /kappa1 put -dup 127 /Omega1 put -dup 160 /space put -dup 128 /psi put -readonly def -/FontBBox{0 -213 987 680}readonly def -/UniqueID 5018946 def -currentdict end -currentfile eexec - -80347982AB3942D930E069A70D0D48311D70C1E2528F01045F8CAEC9829F31D648C8D0A29EA8 -51AF41C327A0D569ABAAFE5AFE94DAD818C312D3CEE72F1ACEA0B701B6A5608521A2866790BD -D5776D6CD0C7D971B9A48B96AA970DCBB8B76EDCB90DA356DC2529B665EB4BB80AC4F5B0F4C0 -ED76861E399638AD3DB1BE4759C78D4F2E81A2FF688D366B91D729D63AB5FC9556FE10A07B81 -904D879A7446DA82DC107FF41B0E3B7C2245D57B2EE9BAB31ECCFE9B79E3EC32CB1F10C622F4 -BCE18DF0E5C4B98EC714593D6F127C5CF6D719A79B83C627433D3AA39CB88EF85D274184C4B4 -C46CA5B496F20460ED75CCFB3D66073B710CC1AD2F2BEC4AC64065ED5E03930ED9EC97810F36 -845DD5048D90D724A88FD3C814CE17C417C84BA45C43F5569A4D73739F71544ED91C657705E1 -31F4D0C61752509FBE0212BDE9C02A833910DFF28F7C53F64B032C8E3CD2BA95C22177C3E053 -2F8699D106F119B80549C45726D793B9AEC38FF4C3120C259083FD13C644DEA026E1E7C75DEA -2EC2341983AFF4D712C27C024393022797DB1500C6543D620F20C9CE973EF7D917E7FB3E6CFE -E0999E06C9DFFF2D01BAC5B3BE0C47B2D5ABC02E1F0F383588F430FA64BFD5250E56DA323C91 -F033C8F0F4E0F9CBB36EB8D4D25B127FDA1BB032A7088CF6FB34B617290DE038198297F2AF32 -3602E5E96D475E4678E129D88AA15D5AD9CB58E244028CD8D9A8210FB1AECFC3F29299986C1D -F1CB3FFA0FC203626E8E2F6F3A6AB198963ACB2B528D6BC06687D59EFDDB9C88535C1C69DA5D -81812B911C5EF9985179796D2B2E4E92BEEC47A4075E306C8D26431D8E0732768DFF70EF2270 -D1FDDDDD4CCA0F209AD05C9AF2F26DA7CA0ACCCDAC0EA4F479B548C741193594D515F614BDA3 -F394C77BD7296981AC947CA0D6D6CCAFD9A05547B28F0CE449FFBDE2744249AF134A1D3629ED -FEC122C615E4A74067A7F8358519BFAC0F31D1A46D260A3DB271750D02CD6A12D019AB6C1C2F -9955CA205F12D8A03DE3203BB5EB869ED8B66B53D1C29EAA26B4D20F9460891B018031BF81EB -A788B77CCCCC5FF99ACB5B025A4DCBAFAFC1B34BB2ADBD17CDD741DA586AF1B784CF74CF8860 -3B20D68AFAB47D21C1A0C6BEE297777DB1A8231237A40EC89AA97CE1C848C9DA6804D3B98C11 -590B239616E0E6D668FC5B987075D77769EAF4877F1A359217B40731293574EAE905BD7A5C46 -719EC7F8A97FAC1C46DCD76B0344E8378FD61D02C9905B194613DF280648E2F86EF15A2DD8E6 -BEC1CAC0D90B8302B2846127B2D50D8FFB7D210C7826FDE88F2D165FA6AFD755DB04910140E0 -70126A663F3D57EA417ED6D2128BF21A7CC2911F8BF0F2668EADBE8E042A1CDCEA38C5C9A712 -26F6F4EDBC85DDF8C25D80933A42F5F303E5495C247E973DF20E2195B07B60657205DE149D86 -DBD56BB2594FEA81688F21573A8210F6FBF48C82425BF58215B3D91D3255012F7B2BC17357BF -B35CD40B0C1D5536CDE7BD0B29DEA7674B32BC83CB453BBF76807CF4A5AEECE57FAE3D291AE5 -0098B85E357E9606694FCFE15CC48406012BF12EFCEA89892D1811B5EF93ABAD0E929160090F -AD55766535E605ECB8381777DF5A2AC4A3E332A7E1B7AB9713A37619293BC7C8A69652EAEEA2 -9721F81FDEA87C0F323FA843325904149416D36CAD4BF4FF795DFE8F5F9073474A5CB2A662E8 -47B438BE9CF54058F1AE7F41CB8F298ADD3159AF95A1CFCE85FD603ED88F301B04D4E8BB4024 -D354FA4B27711651101B499AC32D80E83E0BC11535DDD465D0C061CC7E03513CAD0C2943CE6A -A5B6F9AB3133108A0F41C3AB724D46E10838205287C2EFE6AB5354A24CC5B7677BFC15E067A0 -FFBDE26300A5962A8E9609F4EA1E06811CE576D04DEB46C49CBE1412C01CDEF6DC45FE015123 -E1CAF9F40FE635F580687BB54E1D90C4F19A3B0F94E78D2820A4FA2D29E40D53C86025AB7B83 -43ACED39A4456E73347CC33843F7B1C7B6286BD315C88E891E5600E9140DB753BF076226CC23 -2786E952176F8767BA9F124FD73991B3D280B017AB0064C5EF5BF63267D054C69C9F08B50259 -6475D8B5083A23488867DAD890E37658D1407E6DD0E225280D43B36EE8FA7C6AF944A9A92BA4 -55F3452D2781965DF4A67FFD9EB6F2C7DAC8DA44B2655D8AF179C50DDA090970D9A15F7A742A -FA84435C72DF5C6627633B7ED52EBD8C4D5C835C93BE5FA7CB58F43A930D22513C88FA7DE196 -E7CF4AD21F59E85E4D5A1E45DC0807572D81C9A863EFFD54BE878B4223DD885187233D71B713 -A4A4D49606AAD372CAEF27DB943CE13592AE7B60B8355C4D4A4F65BF1A7292CC4566D8DE3148 -6FBF77E4C357D7F9D152AD67106F4E73C5D718583D7329CB086189B069F8AB1D372015A8A37C -753CE0701EE56F35BFCB78C3337DE4889AB74EEE983A3C6F6987790FF1B3FF67F4C95D32B524 -3A6557171F1C4A8E7D7113056E051964883404E5F748E060A4F2C83E0B909AD58E90E55C8201 -548BBF6BA31C7861B79995181E0723255A769DEE58BB098091A80505C59E671936CD2550B38F -F4AC0D4C8A2199EC15311FD5A7A659C8028742CF72A318AB3AD7171D8C8DB3115D49290B63B3 -C49330B9CD1F0DFBF5D41DEB9F5AD6FFA10DA0478239E0EB837D8A18FBB6C95FC36478B7BA9D -F0767283514A2317D0C868788D9A77FD6B341C71B9A3F56CD796727877DD4052CB9D00EA8E6F -B4D7344830366860D0FF5E42238C0E7C800DB4DC9ED75FC3104B60EDE11C7D51EFB2D54039A3 -56F6FC3362142F921068B5894FAF946F0391C009EC59392B7E3FD20FD42EDDAB0E92E0232701 -04D80365D513007A85B65A08ECAB836BB70D538221C6167E73E9B60B22FB122FF5F15E77B398 -43762CC2D11F166FAA06F7FB61DAF0A05A370FC47602E019A4656F585B913248070FF2C8EC8D -25AEE6FA7062471A562AAA8EB026260A67221E77F05D3EF6F79C2440F0ACD4AB03DA13405FD3 -39E3BC047412D0F503063F98B8FA0E6BD5E52EE9E2C2BBD3DDF5D07122869BA8F08F8F127DE4 -EA963E21B2DD27E050FDDCD751008BD32B731480FB0CB7E81D25B78F3A85B26EBDCD12062435 -47D82E7AE4AB9D573BB01EF4E6482CE8612EB67A1237B87D7515B51E1A218CBB724E745DA73C -72DCC1ED013E80D4D95C303642D0DB099158D108637EBA62A28A5E7AFF8DF1AFCF12E29455A7 -4EAA4C8FF91A9AC69E20FB107D6A4192743026FF10F2A48E3C83A06F3D8BD3127E3B9BC63324 -DB4C7840B91079D76A3163FCD35B13911A7703876B57331C6E67AD3A8177BE5D0F0519B5B7F5 -A9342FDE21FCED195C67BEF73C786C86F6E8E9E612A1467C3E1B1BBA763C882549017016918F -0AB2DCB6A3FAA0A25AEB632B2E5F5A01964D08E86FC8AC0E219AFF0802E8C561743CD4BC2558 -39707BDA8D0E318E257FABC2AAB156344DE064CF7D02F03956B02DEAD4607975EACAA0199AE6 -71FF07042879C5E604231E5700E13BFCF142361851CFAD31F6B90BF4C9677BCC985E2A6BA4BE -B0D492894F41D089EE969E7F59104AADCF79764BB5BEB1D4677A6D445C53AC9F9608183784C0 -33B991668671B222BF3DB336268DEAE34A12F8C4B27C5C38BAD94CCFF3C298D34F56CB3F53A5 -DF8A0FC9EE29B8A55B18843B9E53F5EECE43531B5B09DD483D831425648F27DBFD112C768176 -96C6A59AF58B35525FD6211D839FC4934D935CAFED49D86A0BB6885C0C2744BF6F59C3A84F09 -E1939B7ABA98844A9FD1B65E061EDD24ED129FC1E6E680549024594215FD43ABE89A3A2BBB91 -2D8831A6A571345897D49C6980EB77EBD00417EA3FE223F51155FEB010ED274F27DA8CF2FD8A -A2E2BA0BF8DE662B7A5A7051B4D4CC35F0AC975B9ED28609644F4BEDDB11017DBC8A29C86B4B -20328A9D76664F48C939BB0BD68170DFB6302F690570D02ECE0E08BAD62CA854F97D0E1B1351 -53EBE36C7FD037EE8F6004F535696DEC5D6F857038774E4A0F706CF419C4BE0FBC39F572DB79 -39D223065275454F26738DDABA3698E3CDAF49A2E932CA91BBF8270970F6CC22E313F40EF677 -71E3EBF14CBDCEADEC46D026D8746AE0AC3CD0EFCB874906DD3A861B04550131DE1E7852B76C -5FC8408A4038E239012491B1517A86CF14CB7E1A81B5C34F9C22ECE6C1C7DAE7363F0D200FB0 -3DD93D80DE49107E89D14B91CFF6CDC741C6BED3790FB03E484BE455A4218E9AAC7497C7B691 -4E0F108CC2995400F53E88D9650A0080E00E17AB94B4A0DD0F0BD227F85F8673986F8E2272B3 -C724F204565FE2A81A5B2C33FAD93821943A280BC4305108B0DCC7340C65957FC146CBA4B95A -E9A4415FC38B87493816AF1C4602DABEB64555B225B9FD1001156D6C94A1331258227CF8C043 -2C1EA27DC647EA7F2127A2FDB4AAB8203D85CDB25D2B057EAC6AF8D198D0CA763056C278C2F3 -A06513175ADBB14B33DBE438F9D7706C241CFF6626D750D2239C814E61BF1C6B278B3A2CF8E1 -5B2F93E2F2339A5F3FC17EC74FA00B2B4EA34379DA24058F4CED29453E59082E11DCA4C109DC -020C7574FDEBA6E6A5280DAAF1C8330AD5EB604AE9DB28920D86CB4018244C2BEC0B817651BD -65C7E5FB42BC4478FB72E15CA9EFCCC083CBD1122BBCD7D168FE296C86DEF11858F50ACB2C97 -5DFBC19EA4420429503B110B738C44E779D79BF2E0783A8EEB14C507ABBB7ADFC369959A2291 -904F03FC9E8A4D8AB895AF131D1879E33BBF68FC8FDFE22F0C801363CEE4C95286317E6A9055 -9456C766BFC5B4B08B765722E728EF7970E83AA83A67481098C7C2353BBDF25CED5C9AF6E3E7 -DBA81D4E95D52E2009EA9CC386322154CCD55B7AED8D1128028E8C31BBA7A73642A3FDAC7BC2 -2861A9B2A057F0E283B8AEB8F0CAA25439FF63BCA1B1EE1DA65D9D92D2EA2BF7AFE23F2B7D7B -A5B30104A2DAAC28651AEA8A603A2787FDC6AD72560B64F8A2BC8075ECC00030BDB8796E1CCF -EB6D6D95122F5C5A5080233F0533A92A93197432130625E00C75947326A72F9457F0883560FB -465F5DCEFDF279E5BDC645A0ADFA6E7C810526D4834D34317175BCF8F9E96D92BEEF971507FB -193E027F3AF309E5004CEEEC6434E1E5416B6BE2EE39658F31572514104E22FA6465A76EF978 -2CF7F94E9AE9AD133FE793B3CA411CB8DC4FDD0824567811B4A131046C7B2F70D28422428F57 -31D15AE5DCEE894EF5E8F882CEAB923470F67EDF67BEA6E72645E66D2406A9F3CBF7F4DC7E9D -71F22827A233C74D5781D528AB240E81B8F3C6162B7EB8D7A68FA6BA3EBC23EEF184B3FAC790 -1A38DCC662A18344F33C7349CE7BD8224A00EB7B039AB8F316D28020A6CAE42FA2DEE8798F34 -131A928B52511C1253683BDD9273862D02A693B50EF7FE7CCA8898278064620B3D460328FBB8 -75B4B2BAFADE2D784FD517F2678610E2C7E90C35DC082787537DC1DF0367F26992E03A3D3FA5 -5BD62B6B4D61E92E3CB9130D22C2A7C67A56050C43FADF7EF1962C61A70E98B6FBB5ADC5F014 -A5D42DD7B5C920A43C4E9E6ABD2F0F893E82E6BB4938D197F3FBAF120E79E105BB002BB9F981 -224763EA0FCD4018191497851C1323A85AF4E2022FDCD7173D3B590D7035FB65AEF28451B132 -24A79576D088823F6FE06152AE0F96E05A42532E425DBFCD9C4494C0E912B93AEB4829DC6E34 -ADDFDE3AAD7CF31E4CA44DE6D9D67CBA2516243F26DB4C9AFDB34A0A67F91CC689585E03A250 -5132B9A05285862574D7D3BAAEB1CF9A3571C147660F5E84FE69CD5C1FF8908D29415EA7707F -C04D0FB46425BEB9A1E3289FB938F11BA8808072F88E2EB5996CAAF6D1B90A5861E0962F3809 -706659BA963123221C2E7546417CF3D9BD4EA07FC6F3C212860CC0E9A5ABF469426655981A2C -0B54268DCC635B2883E2786FC5DBB46E09A5FE329FC32680250B744AA0D80E51C3524A8FBA6E -31C8B0899065ED33192C796383AB20FC7D9A9964EAEE7F9D7467B57787DD06C212028F08C538 -1EAEA92AE48A38BC67B9AA3C54009BFBCAA6027A13915EABEBBD3EECFA8F26132EF5F72C3491 -5A4857BE9B1457BDD1E04FD1E963BDDAE7BBA8C16AA459BBEE2ED112D7D7F63EDC21082BFD7B -702E3E7EC8241907E4176AA0CC537EA5C2DE58157F8221C7528E26B356188EAA7D7B35F7D721 -081C4406C96399A94798A6E47C443F8303B807BC8335061EFF884B59FCCF814B973600658E1A -092E5F0B9A16B964CDB55D1AF2D85B7534F85A46759668E472231EBD0B71B3595D5E13CA65E9 -2B97F882AD6375B0E8133C00CA86585A1DFE5482302B012D5EA2526F1A100BECEEAF4CE9D5A7 -C12FA5D9C951A2DC27B0D8CF87A1FE8767BC48594403F8E1A39D32D4AEA89D666471130A500B -2A0674D531FBB95F28C974FF9E76A2EE9D384373691772CECDE7CDA6C201CD6C4C29D5E15874 -F91193220133C0CDBE8B201B854D568FCF73B3964DF7D0EC3D43DA92D0578947D2B8276C1A0C -50DF18572A5B96A6EB90CB26EB6A11618D6BE38DCEAF72D19DE63942108BC32415B006258C9A -5AC732112E7EAE2CB6C8DDEF064CC23E2FF05916C6B79B17DF6FBBAC607E056EBAB1058D96F2 -A3472651FA35C4FC8299847C22480084885AE4E60763246A7763B05FB45CC2C8197C3C69E573 -E7150CC2AE980A165A159E7D4082D10DF64FC4269E7A71784161B3F21FAF7DAC3F1F74532591 -9C5029264AA34F7D2CE425D2C2B664D8AC10B220ACB4BECD94A935CCB220785DF617F156E310 -926D73B87B34F9FB33975EC74278D0B2FF7B8D9A0A93CE6FA9F7D722F894A9294F34CE8242B7 -20F6E438CACB7DBA554E29A319E3B54A7B6B6FE13FEB357D42FCB140F21BADD8BFB0690F086A -3E4931BF0EA1089BB7460744A36E33DAA66CCD029F30F0E7607D8554D9A9C7405EF8DB9A7EC1 -3C5517BE5094C2365F237CF5A28BBB49F29221A28EF95032C8EB4D4283C233E87D30C12254FB -084AB93D970C7245FE4673284367A9FBDC86EFC2EEE2998CFB9E9B60DDCA3EA54259701CA4BF -C7AB830268065C19A64F3661D4DE3968C8AE46D321426A1970F76568548DBA717059AA6B3D46 -49322B7F5231745FC65F73F383F711655383449AF2E0E99982CC796CBDCD8BF628783C3DA0F1 -509DC884EA0639C8FF8F7CDDE18820586D251166AF758D43D2DB9870449F1676B66CDC0C87B4 -F92EA1A6BBFCF0639AD7BDC990ECEA0A0F893D8E862488F28D35F1C83C2FC2DD164C8A1CE27C -8F0BB27F50776F2F30479C644618AA4A2E9F7F32BB7AD6A7454EAE1EFF844727A8189848EDAE -28BBADA3803148C563AC4769E8F7C3E109BA1BF2E8D1FD27F3ABB9A9A332C0A8D3980CCE846B -C64F6F598B1C048D2C29DF51E48AE2DD478B5132ED5C28DFC08F350834CD2CD7031F11EFCB37 -F8D8A26451A6578C10E4192CCE42230B0BD398AB2E38D45CD4F5FDB3EC6AA7A244EA0AE43BA0 -ED9B2E8712B41188FD037093BC9E16534C61211E36F21B2B69938197FBDBC459B02F950847C8 -941F7246177F2F6705BFA5A454BC8A3947C7FD9F70F41D2F3A15F6BA14340C4B1F1D97BAD850 -90AEAFEC1C1D79D2CFAA9915BD79FC3554F37CCAF7C89E496B6A8A0E641BE345B1F51D4EE651 -B9A85F56AE0515A25915B3F53EEA2DF8B78E79268595CCA76760D9509541F8641B9C455D23B8 -44206901DEE2F78DE37943FDE09A02B41A05BDE3AACECCB1CE6AE2E57C2F418785AE69556273 -F27D6089B5D1F5F3C41F9AA0280479885523B9614981FB6C0FA35AE488402DD9666F2F500992 -DE9DB83C1474D2A80F04FA78440674BA1F6A0561F2320716245CE4D4D34E3600FF4B880B02B2 -59B4F1672D714A8180C63DF5AA7A6811144CF3F21D1DA2F23D9ECB249FE4E76E87C759CAD386 -6701BF658919A9DD28ADCFA5E0CEA43E75BBC1C4CE94189FD435F8098BFB3D39E7736C45282E -B1575CA1FF186B9279BE2C61582FFC713A77DF22569C456722A3DF4B21DEEB398662144291A8 -74A104DDC60A521C723E89555DD66703CD79F4A7A07295097CEDE9F33B16C0BEB690B5BD379B -9225C099B048568A4589FD07570CF90FC6E8F0EFA16C566FE736D05A0E104AF10D2DF778057B -207F328EEFD63CDDF755F71CC5BC39B6778943178B172CF1F596EB17C89B9272E99B0069294D -D6C29278F3D2C097069A51F03E22B81596FE5A77931E436E0B06FAF45D2C383146C56746773B -63BA9AB3E49AB94F1600D4C0B15C82FDC17A2A869ABDE1FD79AFE9ECF07DD4241CB49DE6812E -DDCFD46F6E05C7FA95D1D1FF0CFED15FE25E4613C623E4B17D041179E943C2ADF392411B3B70 -1868942C6790089193058ECE47AC2B29BD55AE0A401677D1BE3F4214B0896065991F5D8595DB -9AE3EA4813F35B377C6E95A6156702BC1F675E7A88AFBCBA6E9D0ADE968374928418149B52C2 -05C306DA737D78FCCBFA2FEA01F09A2F19AC9AEA0D8878D5D2FD4F622A5DD64635E3B2E17779 -EF3BCD3C47466078222AFE4498194294CD1CB4D7DEA3F522867FF34F3A294B2FC69AB54CCE03 -54BB3AAE536E884A908B0EC384A0CA7DEA0BEB5423C08F7C5DC186E42410DEFC4DB8D51F02A6 -82C529439C3E3EA35552F0B459F0060361A9E695002BD293DA7D2C02E1B0DAEE6901CA644BF6 -141290A33B8682E03BD0DB0F5138F86868FB2A0549743AF7EE962F9DF241FE3A98A2377F158D -EE435C64E13DFF529D36DA039DDF7B5F3ACE1253F3EAC1549273704907EDF51576CA85D4A728 -F0C3E5381D06C5F7E052C08B75F64072DC77BD9C42CA097227A44C3F7A61002C5E89D1159784 -00F3A736E013019309C841A6896A885F307D1D7215F39D088B8E37BC61F08D7661B6EC99F956 -D65BAC784CBDB8B80F0C67AADED9E9E5E4D8C6E755764AFF57BF01EDDFEB8E6922B70EE999FD -A1F8B8309162E0885CCF0977400FF81F5B17DADF1953E39061EC7460FB06059E42BED7A2573F -1162152BBBC61375ED90F0779DB59B287C8EBB701A5799694D591B809E3EFCFD4BBD7254822F -4CC6C627D70F22414D1974EDF46B65BB1096288DF0D9EBB03E3821207E3C330F968678FD1BCD -697815CB606A7B596B030E15FA11BBE9B75BA02E0A70204E14C339C3F17EE4B6801402AF29CC -A09E6ED34F3AE9B46C78C54D92EC5B26619E721E55CBFAA4EC6085B4622F004D29914E0E7516 -10548F3AD23AB0570A8EC4F3F6A4CF0CBF89500C751EE8ED1E2222B447CFEB96A555256A3666 -659A11323F957AD376EC8FED66B381405EF270C7E888DFFBD36EA2EED15E8AE9F56EE6AA5736 -CD179C71F015625AD20F48A2CA9787FE4723CF9342909450D9920C0733A5FBEFBC408D3878CE -8355D805EFE4EBC0A6FFE6DDFBA64ADD9ED57411D98A9C94E5B76D465B8753FD409E748D7254 -2EE4B48CA6C2F0F21F0356CD41C64B0050B02DF20603FB71B8441D08C0B7BBDEA4B7D77D5390 -296E8410184B9529A698D028CFAD9FB9A476E9E22E93761CB2A00598430AF7FC18B2574C4551 -7465B6892AACF6E5E7B7D49C0FE801EB0D5E91A3ADA03C997B8D106D0FF348B1C028BD333B2C -AFE17304FAD94CD34F29F890E59FEC18A7474152596EE9971087C05C6E3AC02B66BF10E7A8E0 -37296B4F3B15F7312B81EE170FCF46ED6F6CF323CA8132CAD6C5694C52383BE49AFEDEE87D41 -E9770BAC679C9FFCF6337313AFCF77749BA31CDA260AADF7E8D901ADEDB5C5E9D107F2812F09 -2C552A4BBCF2C19AB9861751A69A05B5E846EE90CDBFBD17CCAD9CDE772470A1EC546C2A2B85 -0319C0EE72E0FA0C0ED628DB2402F755DCCBA80415CDDF0963AD7F61CB18C9EF41A53A1ED0D1 -B4596A6C2F0C790DEB3141C572A9ACCDF80A621A3F7D32051E94DD0E76053F9466AC6207B2C4 -A2182AB0CF0914F5431C73CABD9DCC87EE2AE54E888BF9ACE0D3CE786824069A70A69CC18B9A -14B458C4A7BB0DE1092C70ED33D294D16EDB8467DEA27B31BBD06049B511A6B6A81FDC9975EF -949C07A1B97993E0153C310BF7B9103350437183DB224EB19193FFA6518D97ACEAE1FD9B0557 -90B101A0A75DB04053CB4C4DB282A7342E1A57C2F97A9EC04EF07A4DE01300CBC51C2BE078CF -6097AC313E97F816CC9AA854A4E691D97B894EB9AE630B6BB676277E01BE16149E5E66B82850 -4584290F86C50CD4C3C115955DD6FEA544C8672D8FFC6DFC9AB940EDC3A37D58D1627FD3B100 -1D3FC2A67C0129FE64FD8ACD1395F555E8120E6AD855FED3F8DA57F850C6506B4BA17C9984AE -505F026F25B61C0CD9C6BDF3C83A11446E11BD3C60CF67C45144C7457D4C0A51667315C48004 -CEFA327E35B3593B568C722DF9A67DF323DFC13FD665CD56DEDAE2EED49567C128F2D1E7E485 -C1658B36441AA5CE8774FB11EDCC4994E15834C59397F84A4295EE44F8B8F71CDF5773AFED6D -74A42461C66C3CED2497F4527C28FC763067F082DC5E8A89242645A37A9A946247BB821E8527 -99B3D3AC1216A7B311DE1B7819D9A89D79878D877015D5ECC1410E380012FD570D8A20FC64D7 -FEE86025FBBBB5D6E9FD293226BB406570C32C2A6741474E0F001A5C0180DD32644B61ED4411 -5A018EADC5A832E1DFC7A5F8F255FF9871F4C959F23A1262F254855A44B49CC888395AFF5717 -AEE21A2DA5457D419A04780C2609DDFE2424D9B96C6B2B52FBDCBEB9CC99D1A9E224992F71B8 -51D694D99B306766E6C1BABFF7A11A3771321066FC5F73C334091972E0558392ECDF9C099B73 -8CF53BE2A04FAB67BE46C651C1FF3A6D19ACEE84DA8970E8C79CAD04A11A474B7FA560C11844 -82584A334B0217C22AA75C2FAB7C470CAE49C58265AD543A09C9FD1ED4ED40546F3138826637 -5DAC12975D10C8A4D65DE6A4166943ABCDF0E9A72CFECB9F2E5F8FE923108150201A812C9A8C -33FD567CF1B65978AAAC11D6CBD208F08758C1F5D9962282296A84B3052D924F25553D58D9F1 -14B88FDE7AA71593B0B7D01ACF64864D8A321ECEDD1A1AC4E0C381552E581B116452EF86173C -AE8F26C68B3B11EF710BCF432AAD4669CED707AAB0886E18694B0CCF1110D877D6CDD06A7B75 -0A4B7FDDC3EAFEA3F8C6A5E74A75D8DD8E4BD2F8033BC913468318D799C95D8F980F450C6C7B -CF178BF622989873D83270872C4C4004F00830B720EF4FD25A0A9C2D709B34EDBD8071036F3F -B8CCE42124C309009C01167FFDD0CD902772AE83A601904EAFA3684464DB245515D6AF6A1A2E -5AFD0B90F6D2C121B4B86CAF7D801C4FDE6A2CE664772F092120EEE81A93D9E3070F750E4809 -1AA0DFCD366592E12D17B627514C9F00F5F1858537DF0DDB2CA4E3BDEC9CFB76FB1F5A638E3C -7D399B369F7A003A55599EA3C1225246BB164A7EFA2DBBCDECDB3A662ED554B41B63E16A3501 -98F19B7B5BAB796915685B88108C713277B6733733E56EDFD8DB620781262ECED9875A756D77 -4230969057B06E2C33D3C7854F1ADBA2EB15B8A9DD3ABF30D7BD953DA804B83125D76BEA7C1E -0EBC885E07B4F03F1DCF33ADC5FA6592DB3B0E2B7100BCAB89F14D997D6E9169F581129DEDCB -6276E161AD6B80BA0ED346708EC2E73B018F923A6A2EE7282545C7B929A977007F0CE8BBE450 -940198D3404CDB88972BAD4296E62266672A0AC99D38C68DB786E3872A4E1B19C17C3E1901BC -B8D87785FB5EDA9DB640B1124D430A6C90F3EBBEFD70CA6C46792CB54037BDCC4C99430E4488 -EC64EBDDABA17B58098674ED45E0FBDFA2E7E8E99E9BF853FB2A4C12C5988552091832374459 -28FCE34910336AA490FDC251CFEBF2A95B38E649F050736208BD2DEAF23348B416C9765500D3 -678EA5649A2F8498A0B8E3888A168AD93CE3E3B1C4238A149A7FF1DCD8C2C0100034B94FD42C -1C33EE40BFB7C5B1EF47B021704E9A1839186432AD1A65AE0B2F2B899DE7484F5AA106804DD8 -1F0CE6F89A92720E4C38C7DB42817F0FAE2E7675B3B166A81B91F91E84A62B3969BE8A82A5BB -80A4CC87BDD4C3AD0E55EBDCE59BC9C84F049B68D9E4069B06A6FC4C7C89189EEEB70BA99CA9 -0D003FA72C8A17722015C2E47C36F649896C0F7C19C0DB88EBCD0352CFA77FE21F6A4B949DF0 -64847E1CD39C9D00E047AF4F5733955F71BCC7FB34D22D3C0CD5EF7011A97258B07569C68CE1 -536BD1C8E0864D8F5329BEBAEBFBE44599C3BA7680FE07FD3413C5A86893DAA16F77E167A8F6 -CDAE51C18E01F1A15C622BDE3C52DA37FC70102533031F914FC70540292EA1EE75C22BA10F6C -3C6501BA9F04F46B8F15FC457D931105CBB354828F7891C41DDF1ABD192FF5A912D8E5E9B0E4 -FC9D7B729BD63D0E7398A8E3EE729137D53C8E716563990F9D7A745574597777AC286ED35AB0 -F6571449E7D5FE6B251123D54D968F4136FFB04AFC97CCB5BC6C5AF8694982ECF269DADC8426 -9465AFA8247C099BF6D8B76F09003FC9450F12BAD9535686CA32CC36F0E5FA4E3C809BD4681E -D91214DC9A30796C3C854C051E2022DEFEB689D6BC100266D0D268FEA73A461B56228477AD34 -66DC50ED731F7146FDAB4EFDA869F3A28AB9D380AE308843CE4EFC29304DF9F9AEFF085335A4 -803BF0A8D69FB9FD0C2C3988CB136BCDFA47E99BEDAA6EB73EA3E996CFCD1F0B244AC604C280 -BBD6EBDD6270F3A64FCD0A18C90FAB3EA578CB79465BB6253FD7A45729429A936F58CAC73F47 -FE96920A21E1DB23BA1E200CC47890899817573A5C4D059194DDFEA14FDD8BEAA62ED7D7FCBD -CBAAA75E5A225A74EC2799AAA1E5E27127FF2D668B13DDD330817D292F650FD0747B3E403A1D -C15BA8BA9A86271A049C8CDC5C8CA2C231EE4287B8B6AD1D1A46BACB4DF6069A577E8FBE54A8 -0947425996DA313C2BD0FD12049BC24397AFD1C0E5BE145432DE54729D09B2B340F6AE470F86 -836B42EB0E46B0C1FBC033C0A9956681B243F7D6039F0F9EEE6D44130400228C48A7A5AA0A10 -22C7E141A6E9B618F6EF01DFC0E00D8219BB749352D2F6DFBE8B9018A5622216AD49C2894600 -654F6A34090AFA712C2A343A0FE43748A0F04044D5AB485FC474BEC3E2F9392AA8490ACD52D1 -255FD8E239D4415BB2C3DA4C38D68BCB36ED6E84B292EB09347D063FA852DDB16174EF574CBE -31BBEC0CBB5C121A949E0C191F86F29A81EA0C9252AD1C8E6E1C3FD7F8D114EBCD9501251758 -4C802CB3C98947C1F661D39DF1A1A4D327D293A088F03A683702C80E2303AC5E78E1CB295704 -AEC4326C0100495A79CB9007EB715A8CEF5A1CBA69F8C22AE7F60027C39C507B06E2A1D85B76 -087BCCAAF3AD091250D4976A0AABE280EED51F065D388BAEF2C4717673221B7D2C529771644F -05728DB0E647D3A9654ABE37E90B27B8B1F64CC7CC44AE5215491A54B16A4D4D2FCECEBF8812 -76633CD36ADD5A39CC58E395095B338A42B30E960A7AAE507AB018474EBD4D31DE34FD580912 -059DAA8D653D72BE8C00B29629F67FD820E7DDCD27A834B13482D9BD3CC73ECF907386E58DA6 -9E3405BBDA49CF5D289CAB230D1F12A885C76D9ED5E6F664537AC268F04096F405192F734DE5 -18E3EE750C0A4A59D570254DAEE61B1FF42CCC72DB585677351B0BF64F66940E1AD956768E84 -E38C85A89F647BA5B2C585E9F999E3D2CE5EE8D2C952E429DC7F055DEF3A814886CF49AD6BA1 -C891B7A3E3BFD464BD9F8E78B8F6E89E4FBC94CF284644788ABBC6C7412C2B4FA744C0EFB31D -93B8B1070766F2E7DA2912A075507622D04BEE1853BC9512BEA9F8F1921FC730ADAF63C8E34A -9877AA60DECAE43DCC128941F7F1372F164651073435A2F1F41BB598277F7BACAEF46382FD34 -C4E12E29DEDC340DDF9043926C00A5063993AC3918F4F3F459EEBE9D47EF868AF77F3B8D841E -0F65F8A3A31A65AB20DB5B6D48A96B2E50038C35484DB0B6724D29562F78312E184ECE38AE5B -631F0816C2C8261B06B6E654434FF4D42122F225FC0B199C6AB1943AF9E2B25151D64537DBC8 -CBEBAA55EE7A28DD0F194C512F28D3BD9042B095736E306446821E8F485B7401D9FC86C39A06 -1289B17F36EB173EC2772B469662E5F0F91301C15735F092D436DFB259F2D7EBA9D0A70CE7C6 -6D120A503D62CD6CA034FDD4D788ABD214BE1F48F78AD669AB5414E7BF99922D9A25404232EA -A88E7E154EA686F27146353ADE207AC6681EDEE54C78DFF47FB22C751236DF01774D20D692BC -218B8B2254F3FED353B9FD0D8670E19448F527CB8D1929A86052BB51EF3EC7CFB53863F2C5A9 -EF802DFBC4B1854251796B564EB7476B2FF6B6AB0CE99BD25E3844F4196653D0E11AE7404CEB -7E5994B78B1DB6E3AB153B47EE62DD5E4B384A511C71C79077BB0329E9A41E2D89913517A216 -DA292797B86951CC8FA43FFA64C7D7C48C1A00DE6710EC7D8D17439074ED3CD7CD3DA79B54E4 -247EDBE6087D8F71A1F5215DC2D35496CF3656B7A1D28BEB7F023781F1A68BB16356B1CAB4E0 -DA51B5C436F3D603D8198808461063EABC2F7D9764442595B850BE047EABD819B75D6ADF1A3F -9E4591777382742521ED08FD8A3D36594D288F2DE8363E893BAC702DAB04F0E5505FA54EB416 -3508ED09A61D284736D91683CB9688A3CD16637F71672B35A757A3C921BBC9E700EE41872B1B -8679ABAB584C72C7EC17C870CE0D8FA5B13DAB0E5B573E6E84E8F6613DB208615FE69E0EB951 -2032EDBDF33BA8FEA1EEFB0DB8FDB418A89B9C5221D25D9BAA0EE357E246C45F21FF73741F72 -A29A8F5EE9C139FEF8357641C900F79D648B201995D50D6694EAB86CF5B53141AC7F1FF45277 -67654BE31EE45773E48D791A162B2DE625B0A3AE12B3ABDB1B4BA72F49CCCE822E402E174C67 -B74874DD1923810FF1C641CEDCCBF00089F2C5D9D4BD6F2917ACEB0CACFAB51DE810A00715C7 -2414105CDEA8931BBCE2E2BDF218E91532E3CECD704E00ECAB6BD9327BB994C60A9D05532890 -F5C30F6099418289285FC9794D78F02D5032F91FFD96055E6AF3A1879DAF140EE73BC128FE6C -D084593D925F79732F23CF234A79028F916A1DFCE5F28D142FEBC8448780D14B7769A55BA217 -79DE070A6E9B4C17AD66AF7B7291A4F10AF69A82D541737E1C14801C6D724DADE22C399975B5 -3EC0604FA2F5260042BF9021B2AA68EAE6C7F505BBC213A8F87C249DC89A10EDA8702FA603CF -4C14F40FD09E9CD55D6DEC1DF20F3EAD890FE2EDD6972DDC06CBDCC09F6967D615E73F3F0452 -8BFD00C9C4926575F6037F858B28F48F2121A4955CE2A1C84EC8C3FBA59949DAC7117CBB037B -60C2B08FF325F74B8D6D9735BBAD7008B6AE79E8420523A899C6B796EFFC2828129F9674F6A9 -EE55B2CAB086439A731B9898EAC8D7C23B43FAFCD045E69E6C886617C9E999721531E5C78A91 -AD8B322C319A083673F429DCF09CAAA37CDCD31BA3B259AA4CBF5E9A6C70E5450226EF07D7C7 -C297D9541244E6ABDE1E2858EABB131C4E4E20EE1C2B143B9E24B7678DFF7C90481E0AF5451C -1B87DBB81CEE6AF6219CDB8CF93139B58C39314F530A4A8992D2C6EAC3115EE77F7363D81DAA -B0359C6118FB78BBF21589B3D7D75834733F8CF23D3E6BB17F6C31F56E5BEE74BCC7C4FF9AE3 -1CB9BCD5BA8BD82D2C3AA80D1E8BC391EEFEE1C00E04CC44134D0F29F1CBE237894AE72BAF49 -061B171F3DD077E5B4F64B3DCD3183797AE3938AB7E84695A9CF153419238ADEDBFDFF7D1676 -C4BA02EB00F19FC1E682B727201C1E20B75EB284BCE2756ED63974ADB2F4FE7FA3FBC117BF28 -14AEA5F78450A69B09BF39CE3D308863636AA4F4DA59115681866C5B225480BBA8FC219DC8BB -D8A89A891197D7B5773C9D2BFF4088143003EF10B8A3B29C7596D4C160BA4C1D87D3828CB1AD -A463B35211B11BAD337301B29463CCE7ED6F5C0CA763ACDD2CD4FCCEC6CF0387E0620C7662B4 -3DF04778F0DFEABE49F06B0B2E344D5C9BF59E898771DA82A1D8BFB33E67F0AB0FCA4B3E2771 -3BEB2ACFD2D4EFE88A6E93BDD52EF9BE9E5E93B4B88F3D8C961D3E9E8202D77B9FBFDCFF139A -00365DB1A7741E9E70FA62803DE7ACDBBE559B968E1290BFEA47816E15C8D2B419A66EACEF52 -A6C71173F5CE6B99C1343C9CDD6A11A729BBC54BF4B14574F7AF4B33DBE529521D9EFC471EDD -26DBA914DBAE2DE73EAA36CEC82EDE487F709A1A56B32EDD5AE039026D2B57B85A0189079BD1 -D6B1BE32CD05706832A55AECF57E946C4A0DCD4D976B7583A9FF609EA291AC03BB5AD0466ED5 -5C22B2ECF7A573E6120F2478F357E7B7B7476E2B8F00F82F4FE170F3D5D71041359DC21BA93F -338727386327638FDEDB37A4F10FDF9C4F548D971194CD4109482EBF2ED92CDD3D21B15646DD -46EA6E010B6B0CFE064D387E9EFBF6236FD618FFFC979D69B8BC50BEB143370E5061B2E65DB0 -4423CE2A8F0C9C880207E78C320241E311CE42C077AA89DD228BF28F0153836DA150332B050C -82ADB32FEE6DBFDAB3ED18680A0AB9BDFEDCFC2203C588AFFB481AFF930F26A1F7A0326BD1D6 -E786AFE43553280AB61D1B24FE33E7019C045A3EA01E4E8D125ABCD2F09B4F54771D1E94A206 -C5742DB08B79DC50BB5E44549A5C8BA98DA6AF2C2CE3A5E40FB0C94E4039EAC994F6E11AC94D -E42AC5A57217C1D37BF132765D6775D5D5A959ECDA55B081908D9AE8907CBEC2265FF56DD8C8 -E10732118883596567390E42471A8145098FE08253182C0969209B553ECB0098E4C9F3133A41 -10B15E13FC2AC00F9A247642AE2FF04D096378FE8C32F36BF5F0435D2B70AE96BD9DDC376C2B -DDFE12AD43F92FF4DD3C060AFE90F9ED2F3F579A54F72F8F8A1246254DC2F879D34AE11C0CB4 -37AFF31E320CC46B2F7B614D3ABE06FC42AE3A2FB03DB3E592F2CD0273AEA93EE12C60C7E371 -2FEDED8E9217E67EB18BD6688B83B75474475EE3A3963117F58E4A8F78129338D59EFC9E0898 -8F35BA35E04B4C15F2384CD74AC955776D883A34B8409F2FDE5335F259B60AB2DDC64629A10C -67A15FED67DD579C6A1442ACBC0D43F4BD371553E1A16AB01B030274C61D3013A6582EFC2BC7 -5E4E0454A7452A8E22A6159DF3A7EF74DF19DCD3F764B9C11CB9A6BAD0BF2B7C9BA5BB3F574E -3A9C0CB690E3D49E3ECEEBA3D04827BD87FC3546EF3C7E8155CE4991F501030EA2C89AE5F883 -B1AD24041308517D68066B9B4B40C91E74491A5E772BB452563AF50F190E6EB705180C674E25 -F897930928F29BC68C250170D5B54C1930A1D496B210CE54DBD1FCF8095FDA8B65C63EB0DC3B -C519602ED48139A09C3291B421AB403C95AA19E3F384108C54C83F3592F1D73D469054E239BA -011EC3024C02872C2F5F4D6E5B1CE3BCCB92F633D11235E3F8CEF92B9B5DAB50A4CB88A1C872 -7D1DB2B0776E162BCAC66AB3399721E2BD3B58993C386798E58A4FD0E370771EC6B0E0130221 -AF9842295C3AF9C2B6BAC8AF8FDB127D34C0F6BBBB24A9515C79A6695D78E14BCE78FC3E2143 -738BA7E0DF2904498E0214522EE3D8233D5166C6F35D14319FEA345213EC86E89EA473E35AAF -94BC5C2FFFE94377929661CB1171748DF2F56C889B62EC9FB1AFD06769CC7072CD356D3912FB -EAFAD4FD13A3D7E33010693C26527F33C27AC8B1DEDC441A75367D1378CD6F3D76B88A0F5B4C -1354C0456F99193A35EB6BA9B21270ADBD2769EBF66A9E6A023E873F3B9167B292FD95DB3796 -9C9B8A4E33E7E7FEF0D0F0E752E14F0B38B2C6320BD823135969798F4A127A8B7553A04526A0 -EBBCD4FD2D4B01C3438D167EBA0D4DCC11D271B3C48B796B616C9D4F5AACA25BA8CC2DD35038 -95CA8AE322FAE131F8A5E0CD911FE2E77A942D52F35DFA567E9044D9C1B73F8112ADEE7E1DE0 -8834D5DA281E9DFBB6B9C6B71252066584B0D38B40D8AD4369F7AB779A5B7191E56D30DF619B -00BB9B261E867185E078291D6206B114CE7C63B25D3DEFA60C9883E6BC8C98E3BD0E42EEC829 -C9313E55BB3D702FB1D7B66C8A226B62E8B1DC69C176409E52D85025AB01683C04370AA2CE06 -DBD286C3E1BD833C7FBC75FB26B9B8676B6A554C0AE8870E6921D50A2FAD1EB75C8418653843 -A02990F342CDAABC87E68717A872CB18EE805CF6D093C02E1893F588F8A6DC7894C39C45E1A8 -390F6B76E9D2292F06DA5A3AEF9F0E553F09715A7357A6B6D801518EAE2528D02DEB22982B04 -4D13503EFE857B1BC3D62449440421A04720AABC615A8815817D2D3D8EF337B8D8C0FB7D89B7 -D973CA876F595209E7D41464176C5B3796C41A1CBADD1BA3B5D928819788B395DF9E50C16D85 -8DB9E86E972AEE3B94FC822D91176A8F3B13ACC097BF8712F222C23369D2CE4855C5201C92E4 -60661DEACC951ED9D2C114E06967BB091C5451476403279760E3AC917187FC8189DFBE4BD204 -0774725E8B140CB4F8B4EC17BEA93A8AB22FDD4A0B21A1EBC43C7E5D481451EABC02CE3A48B1 -7F822FDECE44694EC09B0866D2ABA5B5BFF8BD17E261C58A48956C476FD979C40346C1D6145D -B7F5201BFD9733D1DB645E1565D9ABCC2F03CE5316BB44102C07E12880AC4E9565FB716815D8 -9FC47F553F85CEBA858C57EC7C7A6C1DF4CA3AC7BA4E7E71A0378E3DD7816F3043A78A380C10 -C5C5CDAC4EB0AA36B6ACC95989A5266C16C362F7F17CC3439D0E1943719E9EB52D582E271E88 -DC31F5790D6CA84AC3406B8CBED0E3705CA2616F43A7616D7056B500C7F9FCABF3A5E0CEB41F -8F9F3879DB6315269E52273C9358ED7D7E72EB21DE208788F43AD9F404B02869BB6B5C73D313 -40C29D4B5DE5229C168A7074B4DD97E5E2BCF468E97FC29AFB055049CD365B273D5DC7F0926B -7DF4882ACE772FD63A151AF5A0CB9E70EF5F416EE3D17B2D06315CEC1A6B0D96DE9D26839DC9 -E7BA7B392AA4E7197F20FA681FC5478B750A7C6E04214E257AB15B1C7C1DDE9E6D44D604C61C -5E47E2C7851E4C1C0CA2575FAD71710C35C85B87FC55080D5F08B6640BEFCDF88B427589E940 -442681FCC09E3FAE3A77E4113F29E7F54A8878CF49AA28FA2A1138A521A0658EB07DD2BF6419 -3C0E996EB89711026FC687897F3F7FAE6F540D9537B5088E5C0C16EB9819911CC8AEBE36B36D -B254E304ECE01D2F3B1277D11A8E2F5ADF183054E8516A0FC40CB03316C0F538EA6B1199C3D5 -6F9C6FA65D22B125B83571A326A915C6B3200DC798F50FECCDFBB826B8A6388CEE22BB526AD8 -834D3633DC50211E933C979D37B11F2ADCBBD6331FEF4F3B9992F7748086E52DDA3F3B47B027 -38DFA6124B9E14449128FD7747BB2E16C25CC8606993A593570742511977847C0126A1218742 -FFCA4AB7A08CED8BB1266E8018710DF2A7312A21608CF2C545340F62BF1A40063E03076713D9 -5130CF04D76FFB1BBAA7EA2EEEA5D9FC691686E4F6338A477E2AC59A108C8F4BC2DAA4456FC6 -0D91734637DAC47B65FD74B9B619B94774D1B58B0A14DD423202706C332133E49284268685C0 -ECDED7F63C0B9D1E16B77CB558892E59031590EB933C2A8B603A1F8B656358322EDC7308146D -082833D49AE7CBE009419F78623E73FEAFBD092A438F4861B8C07B78DD962CA0C34F82491F98 -14F1925344447712A921B1D26ABC6C89E8DD00F69775E6C0A8C580CFAF9743BD0149A31798C4 -50B97528723DDDDD1C10E79C2F79ECDF1A1479063C6D17B0568B767CCAB08AF0CFDF68BB46B1 -8F61780021A1008B6E7CF21B93347849102AA673B8107D0C34DD29C59878549E6A098E4EB5D8 -E1D532F0DF9B058CD32847171C7617F696BECE34A7B90DEB9AE28C866EB172F876F6A2A80728 -624E027CF5664203E27D34C2E8558BB67E43F241A457A37C21E8E9C55DE5DBADA35CB5D805EF -5ABB4F422E62BC4FF9EA332C616F2F881C6A6CAB91BD5066CF8E938F5AB5F6365B17D8D02FBD -957AEEEDAAF21EFD4F94973EF1C00A86CEFFE5E3C27CE6CCE082D0776850AEE702D2336A8A26 -74AFE34E4BBAB7C92B0D512C51734C629845119E636278874501510B0DC3F6E14E0E02326708 -9F66F37433E57E7CA920F574916EDAE9FF42738B14888487D87E744FA29543E1269978D9C6FB -71BD7D9D6D4646F6C2F702354B6442E1627AB0711B528F67CA90AB398169D8840DFF6CB09D30 -BF3CE8822FC14099C9CE2A1F8F5BB873F11B71BD5DD09CEE0E5F6E14B6FAC5DA098793A5356E -0C0CEBDC52F890CB295DD54E63040A801DD51A3ABEF3F2226F6D27A5C71612C156A0CECEDABF -D956F35A5EA4AD07225866EC415211A81957C32771D3DEF24104F0BBEA854AFD309EFB79B05D -C32A27D5E36A1402772FC5CFA29664BA3BDD1E0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark - - -%%EndFont -%%BeginFont: MTEX -%!PS-AdobeFont-1.1: MTEX 1.1 -%%CreationDate: 1993 Jun 26 10:30:36 - -% Copyright (c) 1992, 1993 The TeXplorators Corporation -% Hinting Copyright (c) 1992, 1993 Y&Y, Inc. - -11 dict begin -/FontInfo 9 dict dup begin -/version (1.1) readonly def -/Notice (Copyright (C) 1992, 1993 The TeXplorators Corporation) readonly def -/FullName (MTEX) readonly def -/FamilyName (MathTime) readonly def -/Weight (Medium) readonly def -/ItalicAngle 0 def -/isFixedPitch false def -/UnderlinePosition -100 def -/UnderlineThickness 50 def -end readonly def -/FontName /MTEX def -/PaintType 0 def -/FontType 1 def -/FontMatrix [0.001 0 0 0.001 0 0] readonly def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 161 /parenleftbig put -dup 162 /parenrightbig put -dup 163 /bracketleftbig put -dup 164 /bracketrightbig put -dup 165 /floorleftbig put -dup 166 /floorrightbig put -dup 167 /ceilingleftbig put -dup 168 /ceilingrightbig put -dup 169 /braceleftbig put -dup 170 /bracerightbig put -dup 173 /angbracketleftbig put -dup 174 /angbracketrightbig put -dup 175 /vextendsingle put -dup 176 /vextenddouble put -dup 177 /slashbig put -dup 178 /backslashbig put -dup 179 /parenleftBig put -dup 180 /parenrightBig put -dup 181 /parenleftbigg put -dup 182 /parenrightbigg put -dup 183 /bracketleftbigg put -dup 184 /bracketrightbigg put -dup 185 /floorleftbigg put -dup 186 /floorrightbigg put -dup 187 /ceilingleftbigg put -dup 188 /ceilingrightbigg put -dup 189 /braceleftbigg put -dup 190 /bracerightbigg put -dup 191 /angbracketleftbigg put -dup 192 /angbracketrightbigg put -dup 193 /slashbigg put -dup 194 /backslashbigg put -dup 195 /parenleftBigg put -dup 196 /arrowdblbt put -dup 128 /parenleftBigg put -dup 0 /parenleftbig put -dup 1 /parenrightbig put -dup 2 /bracketleftbig put -dup 3 /bracketrightbig put -dup 4 /floorleftbig put -dup 5 /floorrightbig put -dup 6 /ceilingleftbig put -dup 7 /ceilingrightbig put -dup 8 /braceleftbig put -dup 9 /bracerightbig put -dup 10 /angbracketleftbig put -dup 11 /angbracketrightbig put -dup 12 /vextendsingle put -dup 13 /vextenddouble put -dup 14 /slashbig put -dup 15 /backslashbig put -dup 16 /parenleftBig put -dup 17 /parenrightBig put -dup 18 /parenleftbigg put -dup 19 /parenrightbigg put -dup 20 /bracketleftbigg put -dup 21 /bracketrightbigg put -dup 22 /floorleftbigg put -dup 23 /floorrightbigg put -dup 24 /ceilingleftbigg put -dup 25 /ceilingrightbigg put -dup 26 /braceleftbigg put -dup 27 /bracerightbigg put -dup 28 /angbracketleftbigg put -dup 29 /angbracketrightbigg put -dup 30 /slashbigg put -dup 31 /backslashbigg put -dup 32 /parenleftBigg put -dup 33 /parenrightBigg put -dup 34 /bracketleftBigg put -dup 35 /bracketrightBigg put -dup 36 /floorleftBigg put -dup 37 /floorrightBigg put -dup 38 /ceilingleftBigg put -dup 39 /ceilingrightBigg put -dup 40 /braceleftBigg put -dup 41 /bracerightBigg put -dup 42 /angbracketleftBigg put -dup 43 /angbracketrightBigg put -dup 44 /slashBigg put -dup 45 /backslashBigg put -dup 46 /slashBig put -dup 47 /backslashBig put -dup 48 /parenlefttp put -dup 49 /parenrighttp put -dup 50 /bracketlefttp put -dup 51 /bracketrighttp put -dup 52 /bracketleftbt put -dup 53 /bracketrightbt put -dup 54 /bracketleftex put -dup 55 /bracketrightex put -dup 56 /bracelefttp put -dup 57 /bracerighttp put -dup 58 /braceleftbt put -dup 59 /bracerightbt put -dup 60 /braceleftmid put -dup 61 /bracerightmid put -dup 62 /braceex put -dup 63 /arrowvertex put -dup 64 /parenleftbt put -dup 65 /parenrightbt put -dup 66 /parenleftex put -dup 67 /parenrightex put -dup 68 /angbracketleftBig put -dup 69 /angbracketrightBig put -dup 70 /unionsqtext put -dup 71 /unionsqdisplay put -dup 72 /contintegraltext put -dup 73 /contintegraldisplay put -dup 74 /circledottext put -dup 75 /circledotdisplay put -dup 76 /circleplustext put -dup 77 /circleplusdisplay put -dup 78 /circlemultiplytext put -dup 79 /circlemultiplydisplay put -dup 80 /summationtext put -dup 81 /producttext put -dup 82 /integraltext put -dup 83 /uniontext put -dup 84 /intersectiontext put -dup 85 /unionmultitext put -dup 86 /logicalandtext put -dup 87 /logicalortext put -dup 88 /summationdisplay put -dup 89 /productdisplay put -dup 90 /integraldisplay put -dup 91 /uniondisplay put -dup 92 /intersectiondisplay put -dup 93 /unionmultidisplay put -dup 94 /logicalanddisplay put -dup 95 /logicalordisplay put -dup 96 /coproducttext put -dup 97 /coproductdisplay put -dup 98 /hatwide put -dup 99 /hatwider put -dup 100 /hatwidest put -dup 101 /tildewide put -dup 102 /tildewider put -dup 103 /tildewidest put -dup 104 /bracketleftBig put -dup 105 /bracketrightBig put -dup 106 /floorleftBig put -dup 107 /floorrightBig put -dup 108 /ceilingleftBig put -dup 109 /ceilingrightBig put -dup 110 /braceleftBig put -dup 111 /bracerightBig put -dup 112 /radicalbig put -dup 113 /radicalBig put -dup 114 /radicalbigg put -dup 115 /radicalBigg put -dup 116 /radicalbt put -dup 117 /radicalvertex put -dup 118 /radicaltp put -dup 119 /arrowvertexdbl put -dup 120 /arrowtp put -dup 121 /arrowbt put -dup 122 /bracehtipdownleft put -dup 123 /bracehtipdownright put -dup 124 /bracehtipupleft put -dup 125 /bracehtipupright put -dup 126 /arrowdbltp put -dup 127 /arrowdblbt put -dup 159 /radical put -dup 160 /space put -readonly def -/FontBBox{-23 -2958 1456 766}readonly def -/UniqueID 5018948 def -currentdict end -currentfile eexec - -80347982AB3942D930E069A70D0D48311D70C1E2528F01045F8CAEC9829F31D648C8D0A29EA8 -51AF41C327A0D569ABAAFE5AFE94DAD818C312D3CEE72F1ACEA0B701B6A5608521A2866790BD -D5776D6CD0C7D971B9A48B96AA970DCBB8B76EDCB90DA356DC2529B665EB4BB80AC4F5B0F4C0 -ED76861E399638AD3DB1BE4759C78D4F2E81A2FF688D366B91D729D63AB5FC9556FE10A07B81 -904D879A7446DA82DC107FF41B0E3B7C2245D57B2EE9BAB31ECCFE9B79E3EC32CB1F10C622F4 -BCE18DF0E5C4B98EC714593D6F127C5CF6D719A79B83C627433D3AA39CB88EF85D274184C4B4 -C46CA5B496F20460ED75CCFB3D66073B710CC1AD2F2BEC4AC64065ED5E03930ED9EC97810F36 -845DD5048D90D724A88FD3C814CE17C417C84BA45C43F5569A4D73739F71544ED91C657705E1 -31F4D0C61752509FBE0212BDE9C02A833910DFF28F7C53F64B032C8E3CD2BA95C22177C3E053 -2F8699D106F119B80549C45726D793B9AEC38FF4C3120C259083FD13C644DEA026E1E7C75DEA -2EC2341983AFF4D712C27C024393022797DB1500C6543D620F20C9CE973EF7D917E7FB3E6CFE -E0999E06C9DFFF2D01BAC5B3BE0C47B2D5ABC02E1F0F383588F430FA64BFD5250E56DA323C91 -F033C8F0F4E0F9CBB36EB8D4D25B127FDA1BB032A7088CF6FB34B617290DE038198297F2AF32 -3602E5E96D475E4678E129D88AA15D5AD9CB58E244028CD8D9A8210FB1AECFC3F29299986C1D -F1CB3FFA0FC203626E8E2F6F3A6AB198963ACB2B528D6BC06687D59EFDDB9C88535C1C69DA5D -81812B911C5EF9985179796D2B2E4E92BEEC47A4075E306C8D26431D8E0732768DFF70EF2270 -D1FDDDDD4CCA0F209AD05C9AF2F26DA7CA0ACCC0349D554800072FE70FE3F12F846085405A3E -13764F457E887846DB5ECA49493FB685ACAC9E0D4C5CA63C7B16408CB7EB5DECB4429557ACBE -97A89D9360F0D29566678E6C2E3569923451905D8951F729D6E4E166C0150CFADE571C25F928 -20FC6FB202F2D010BDB81E8BAA6232CD15F94AF4804B08CDDBC782C1295ED9D18025F1C453A6 -78F58A7E1B7BCFBA4400DDA52BD25CCAEF380AF4B5003DCC06F75960AC763EC42A6EF95EAF46 -F77B3AA68BBC3C182D192D602A713F8082AF7E531B1282E701D3A39904E4802C94B6DF379CC5 -FAF66B0FBC4E279EBE2154C755887098745EA0303640D9ECD80AD923DEDA40CCA8136F760A6E -4EAA342751FEF587651A7C6394ED4FE12A07E33FCDC615954AB2599F9A75CCF54E560B978ADD -203D169AD883C855F40EC67C410BF468E7AD9A8FE58C601BF464797F492CB9354C0A21DEB7E6 -E0B951770086D598FBD0138393A017903AC875192D5DA1D671E70F91C6CD9722D168EEBB3CFF -B58E56373712AE6823A0B39FE863CE84E8A867C5D1F5611AEFDF25D31C9896DCF5E320B0875D -D95C3A3F8BA7A6331558180E833AF7C1625D0A0EFD6266B95BA0A2DC769E694D43AB27088F81 -E8A7F25A9207EFD5AB98F0390B28D219AC289FA217FA1E67D801778DA34B6CA048034A044E83 -294061D64A98E7B5989EA55D9E4B046545C841452C7E8F23ED381387E1EA4E2912922C12ECF8 -C2822605C9934C37FDE6571C287AE7D66B15AFCACC0063F3EBD6FC91F5483928FFC85FDC712E -C46352ED74FD90778B8EA75A41AB0CF6A619FBB4187C77274565241CDACB46D3A96A66DE00BC -129825D7210A09757E2EAA6F6399E49A2FA7CAC9A2EB475EE8DECC5785DD1AD632A308872F86 -B8789E949DE16E8DC5B9BFF155EBCFBCE24CB82077EA65F147D6D2070BBC33C7B2AFB4A55369 -0CBFCE3FE274EFE7CCDD768B257FABC2EF28CCC3C361799EB6365F41927A1859EC2CE5A07EB9 -FDC066040ABBB17E98C5287CF3DDB94E5EB10375B52239AF35B012882A8F3D338801490D3F3F -FA3160C62D9E5E82EA6A456005BFA2279CC7E72397B09419D539EF1864ADC733AE203B2D8F72 -15B1A449228AF2666A8E5CE4C03C09E85AFE5B179C139027E0249D75A2EB070463CDCEEC2CBD -5D113829A137081D755ED274ED76D511C332222FCCFEC4E75FA82960F8D544A384D7A3760675 -E76312EABE9CBDA8B23716F835E358859A7A6468A890A0E5726F161F6D9FC73C83B27325E9E1 -8CC902D1CB601CDC9C66CD1ECE834FA07A0FA67AB883E1A415429E238093EBFEFD0911283CD9 -698B571A023B18E1BF83878518DF8F783E42202CF653BE501F77AB4074A5A2D10C569177DA76 -0FEE25D893676DE5025DF26685782D2EC98BD168DF71B5041F9F1E502513235B3A0198AA12A3 -91F664BCE4148D328685938AD62A83D215FA65AF0A2242FF495C97C08708BE977F3A0F635DA6 -85FA0224E9A3106AFD6606C580DF1EFDAB02F51B8D1409688A2FE0937DC74503D713BD217815 -8C6E89304F691C05DDC18B9501A0EC292B6900DB8DC47AF1D118336C459327E4E9134485AB76 -4D7E150A1204B61FA48D6C64F70704118DDFC63F7FB133FFDE65F278E2C61A5913DFBF4C6C77 -C019A13933B9C84DC671FA376BDBCF684EEBEF270C7C9BE054DD27DA19CB46C8AE6770A8C375 -3F44D645C626E640A1328B864A6038310AC575AA8D563040E7979F5B7128841F208C1DEAB059 -F4A125F72E3F508540C6D2338730B5AC7375E158CF49BAA7A095845ADB6BCCB32ADAF8163BE8 -4FA8B8652FEB9D9E4C3A8660233CD8BCEABBE97F90DABE0D18B04018C129C7A5F5FA0C7D4188 -68904E005BE329EC6A9B977FEF88806F0FFF2F285DFCAEBAA69E1780EE9BFD643EB41E380E16 -B87BDAB8C7622BBE4F26C356929692E3269715482FBA49A1C638A01BC95D764AB297DFE358C5 -0DC4384C443CE04BD2D5CC334870981F4F66F46388415CAE55F3CCCD74B189495505D75F945F -6F1BD6B7954FDC5A49BF2DDF4A32EA9437E1540BA8389C5197AF1D84091244AB411AC98AA6DE -D62AF3C2A8D7027A055A23F486A62CB8C9B727ABA8D05638E4CE62735A66AE83DE1191C9D32F -5BAEC262235F051F6EA5F9AC9618B3DAC8C805085CE8D6C03C94E63C96052C776BAC710C4BD1 -D34587B13356203A8B603F1095A582350E8EE92DC0F17037CC1C7A93ECBFF488AEECECE7AF19 -CA0ADF364C275BFD819067BD6557EC7B726E28111B3F3A137CFEF5F9EEAD77DA5C079A67A0F9 -EAF10656091E274CB52CB8196A3CC157720DA741E833758FF502507191B876D588AEF7E53B98 -1F87015B3A597A93E1B26AD08892956A4055AA05EA2273E84F288B004027DDEAA151BD24F504 -127206FED840BF1634F21A8C0E63BACBFABD1632E951D10912EAC843D2B956F12364C6B03C8E -0AE65C8FDDCBB882A5D6C99D79BEEA1BF8C76DB4AB6497B532FDE33C2CCFAF6CDD6B04B630F7 -3365E16F9212D3F75C1D655663FA2F9FAE6A872B8F4DFD4FBF357D7B22700A26BFC882A33AB2 -327E92A3070C72DC798687D2F01178971189BDB62A83936E0C0319073B037E96B6D125D401A5 -325725ECA5E701A51B3B6AED5FDCAE2B5B6284F671E855BEF502EED95E9CDFF7184F09754B72 -0292C91383363102EE9D37E6A8033631A0F4C11E197780D23486E647113B222E6547B115A899 -A46FE587AE36FE3C6AA75DD596227975FD55213EDA6DA9AFC0B39BE1D81C4932E4AE224954BE -F7E8FDB0FF8813F5F8D75E68F06B36F0796CE1E43F5B9D93627B630D2094269493161CADD19C -075CE39D381277496215F8B64AACB40BF623E2D68767DD05781909A1242156FEF405C0ADA5C3 -6F50ABC723F4BE18CBCCC097DB5FB48E30E18B657D54F4C1154ED50B342B4A00F1A4C0CB45AA -61F4483B0691DD6D52F310451F68C58DE913DE1FAB27849D9B9AAD9DB3C7C4D25B797306F2C1 -39CC43DCFEED1D0866ECA6F0321E6F49FE12965592F82DDB775EBA4E9C63A484BA1B36E636A8 -420B80D044C3CA74E7D02F3DD99833F979B2BEDB78D9E95B060B4D8EEE1B9CA4D3DA02FAAA9F -37680338851C6DC9E2DA0C1A17DF83190E9FD53DAEBF360E0777C7282DBCF02CBE01C7183E9B -BBB66649F3A4E1F30652D7A3D2D718CF9C44978E614025A9EA26A8F10F23EDDC9D7C563C2A9C -D406563C9202F35E760ABD0BDA1B3B7AAF882094C8524F1D0F5F7EC20FF38BAA21C8D47B1C50 -3EB79C31CD2A8133799EE820F71F04D1F71586D11C369AE5F131100B0D9538FE37786AEC273A -45223CF10AADE8D0E55F27916C4A6A3DC45F8FB0BFEC06F54DED4FA2F280191002E804E4558D -F64015EAD87DA779CAA0AD5F30EFF42738901A1E9F067ADBF578755C4CBD14455A7658E468DF -3C3D37CE976809259716459BB849E94FA803C1D7CC9BB6EE349E12A0E64676161434CA1AF6FB -72F6F3D28776F147AB78B522B76625C0567E945BCA6A04502B17F5F876E6828F59852F3294D3 -C7F4451A7A561E0CB4F19616E55C01257E2B673DCD05F939FFE995A8821D159324337BB2534C -1B9B07E1B9132C53AADC91AF43698D52ECAAC6B45AE7813AE95FE9B3C09A6676DB5E248C3CED -2D34D3162C6B7B121EE0B641473F8264836390FD68787D13EF6754AAD7478C4706D17E9E2FED -78491084131C407BFAF7281E8C64B65A11FE07EB111372FFA056FCBACA81D412080F53D2D837 -0252A767C4D67FB55D9133D7FCC1256C0258942FC094F1DCF076ACD3DB978C00968B021D802B -D11DBE9B4C0C0FD89468C05AC183606DA96A56A14C9851317DD75052A86E30B7EC13AD0E6474 -8354F40A5F38DD025F581EE1B813B5BCB4DF38240DFA342A39321DD3AA32D1D206CD5681E3F4 -B5C638C14BDBBA48381D18A4765C04525A43AED29F47BC2F41F09E98F9942462137BDD76EBE8 -AE60C03970CAB12B113B0F15D931F848AC1201DBA25F4E81B7F158E033CF2A4DA3856CF6A74A -EC130376A132AF3E763826B26BE54117AA646BED395228062EFCDFE78AF46ECF686871A570F2 -B20CC2AD65D09F868189128F7D41AAE20DFBE729870552C0F56F8C4005D9161CA4A5498AE2FB -F3E1FF9E02C050D3634D0B88A32EB75B3D225633B85085252F5939CEEB540D8B5F60A090B4BD -F2BFA14E1CB911BF23E7C3DA05BB28AA3BFE0676A3DAAF56CE804D425DDAE061281B248506F3 -88D9F7C4C95E2F0971316BC3E9BC783A30CE88A80BB247B6319721CFF31603EB1D1670F522C1 -46FED5F0B12ACA993397C06BD37FB7D439D003007853719A9FE2FB3B67D27D546FA8F762BA53 -18417F0D2CBA448345CC86A2338300D429A16B3453969EBC5D41BFCCE59F0EB5E443C6C706E2 -ACBDD250F74936E53F443019F97D86536913756995AFF9A5A91D93E093EB18EEB08F88C9F8B3 -354E6EF643E93937C2BE255C876272098538F181E68E686860DA6D6792D1FB2B2E1FE30F0662 -ECEEA87B37C436584B153C615CA7703738F708224C0D6B58BE2C3AE36C0E892A563F68AE1B11 -67C84B6527E34B98AFA281E4D03BB1BF6DD356D31DC794F92384A3BDA7EC3FE9FAA036575951 -0EA74B8937E0E38A04A58C623F0AA1787BC826DAA2364EE4CFA8B01B81EE5DD843DCB4048998 -E0CF8D18B10CA883233DE06779C332D29C87A7EA33F057ADD9F4C29A6970C56E170A80AF2A1F -56DDE778FC149469C5399F3E2C4EE34E3DDE95EB0CBD2A332B91679AAB4042DFF4CA9F2AB97D -06973892401B0F45A6E9FB9E7AD6C9B451DDE4072D7B68FA8C54A40276CA033E22783DF35753 -C60AB951A49CDD141DD12330D13CB7A205941D2A9B303BB5AF4A7E14A0FCE57192BFFFDB7414 -F4DC3262BE1E60DE8E4B5BBA84661DEC9B6C570E857F5905AC639E19DD553D57C2FF30F563C9 -1C4CFC74A8B08A961C3892633F988DD2C43BDB34A0F6C1ACA3700C1EAA12EA6FB3424F693A7A -CDCBA056556D7CD8E7AE6A966896A83E3AA73583A4196615ADA7082E964508EC5B20793A93C1 -ED113A816EB7CF05C2177F127958AAE01E23A3E11D81C4A0718CA2897E1DEB6B911F70A0DDDC -1EDAFCFCCB9030BF887F859B2B9D471EEE0BA651D858B196A19CF76F3F896649CD0ABE276D3A -C48EE62636C457F55E7C2621FB81EB168B861FD588FBC53EE99936E31AF2174A93F37C856421 -CF04098EE6E737030C47CEA6465A967D3B15038507DDE2D3AB2ECB82F5601D04CD74E38D8C17 -7CCB0E4209A5F83A5273FD99167B8ABB8DA1B3C661E8280D5A3552E1DFD6A53C6BA68118F6BB -86FC0205B1DCD030D4C20769A5BA10CDDAC3180CDAEAA8D689051D517B10E505EE47D2E75898 -B66A8B12046EF9DC2857B96B15DF161B7EC0E2A6B32E11DFDAFE47031338CDF0263E80B3EC9F -488A00C564784C0F5C5C62F6587C6FED0FBEABE0D5AEA15703000D0616E74FD52A80A6BEB318 -D7CBD787F16EB8BA66CB3AFF1D663DF6EFC7B2FD3497A9C5C7B4CA39001C65AC18D5E9F9E0C9 -899D972CE5E6AC875CBEFFEC6E5342A3F213DA1AD0EDB5204F2708327DAE47EFD3BACC26EDCB -44E553CF419A6CDD855A0661D409B06EBC76C9E5393797E33C5C9A1D3F40F85AADDF78C4D48B -DEDDBF3852AB90BB2212C9A479547E7137AB49E96AAA1EB6511A25F8A39FF0502AE15FB3B198 -79573F54EA6C822945F4BC9585C23C6A7712830A89ECC8E03001EB382358E186492971698748 -431E65800A19D6099650763E5399800A598D8794B042CBC59F5939716E2F33B5133DF9F60F7E -5AD538AAC1C67BC4C4888D4A966961BB879A4B1F6461F1868FFC4CC38C67471D7F5228E9511F -ADDADB25216E255CE86F25C74B682435DC57FEFC0DDF09012D401060356AA17EA9A72FD6E485 -4FB46EC0D4C5BE714979280F4C5472E746489B97D11B97D736F74604F4B61D907FD41DC25736 -CD9A3962245BB7B889613EB3209A064C8DA94260C0BD5D3489DFFAFD3CFC6B897E144DDF5075 -897CC74778692C369324580948CC0536033BDF403E7AD308C79A71FDC89ED669888E9DC7C9E8 -4D094AECFD4136CC3225CACF9EED5BB84BF0B5B865C015010F1D23AB7AA2A9B1AE50801FCA0F -BB9B37DFDF942F49884F2A1D988FC17A3665C00817272566907DAB9BC3FDD0C457542E91CCEF -013D2CB09464589552DCB8C0C9C1F9E43BE6238D12F2AD0B0FD5F91CA43BE45C92A6622B36A2 -162CC138AAA8371F75F3EE74290951C3F560662A5BF77E37145593AAB1AE4F5BDA574A176C34 -868F351C39997D7A725137EEA7A46096E0766EA71BA1E5DA00E33440EFA6BAF2346896EBDDEB -C3C87CCE018920B1D0BEBB660A81EB233EA9923199963FFBC0B30E6AF15704CCBA48CCED2167 -899B66CC3534EE33406F44D8E2C0ABED37E07217DA2F8C4516D98EF10BED1A355E8E8DBD593A -7724979770DD4E67B977829DB9F89F22AC31D7FF6637E02ED68E377600A438880A19FD377933 -0BEC227FBA1631D1EA18730F5FD88A9E7B66DE04327921A52F52EA62D33F338FDDCA44951983 -5FDB98FC4690EEA8EF5C90A9073352983540CDB356B91DEA0BE868F5EA905B2DB36FEAE31387 -4274442BD6A3C7709EAE9A3637504E1686453D4E7D41B8F6CE63AFE7F8C4F3F70F8BC03D4DA0 -B43A3A61106C6C757996FEE8450BE9D1D4E4B7A302E610F6E9E34762248A42A14F1AB4415387 -4DEE34FC1F0805008D6105BE49F30DE3228E6F56BFB1AA7638E691DDB1F9A5F8B2B70B6F4365 -9CF2133100306C9897131F0604930CB664B922790831C3F50E43D568B9916F47BD4A2F583184 -A86684C8E44C23648A1CAAF49602004907C06E466AB016390233180E7E9D2C1B4353288A7366 -F07A5D60B435068D3E0FB35351FF72A4A06C31E710E820B5874ABFB98CCF6B0FC2F1DC25F353 -00C01E54A07EDD2AFF15194DD710F77BDDA55F7ACE05210362D3D29CE1AA7C338538B2595B52 -3216B6F724F314A5968072C47C0A36198B7A0DA3BF2350281B8A635A83AD7B9F055383E8D675 -3537187EAC6B24F21CB4F840BCA22E1A7417D730C9CCD0A97DB533723253F92A2B00BB5DC945 -2485D1E0B0905DF2C6CAB95C9C4D501E9D45FE306FAB2CD8379669D56EDDB75D0F67E1C05C3B -47934CAFD125943FDB781C7393B2C426EB609C951A9D1E9222D16527C20C8DE9F6CFA0DEABA6 -9E31F28A7253EC6EC44CF054AF4DF1B7E3C655A91FB8FD88D79ED755B45C39C02A7D73A3F888 -F99AAE2586ED69F775384FB89B695358344BC3110BCEB38867A8CD54E8BA5687A552A30454A4 -4C8D089E67A19A15E65849DB7B39576FBB2CB4074AD8B4ED440CCF3EC2E932AEA4AF06D87997 -A1967737006392D6AF327387556A5CD54A991E5C23D862E9A6BD378E54BBD63FAAA3C18A133E -B47227C3F87A3F70324E24D7E975873815F6140969942F53D36917C7DC8012509973022CE814 -57FB43989D9F158810C3995C1D24A884853B9D6C250BBD49CDBA3080B3D59BB2F01812D59DD7 -C1823325DF1609A51E4CAD16E75669DC416590B526402DFDC0A966A284E950B96A489DF5EA1F -C52CC43738ABF53BEEFF55840C3894019C23AC6319F2DAE587BBD9119E64869E087C221E9EA8 -AE59CC5F7945E133F18575D39F00B920BCAE3105332DD77E876A4CE7A71E278F63DEEA7408AB -B4B110D52981C057B881CD06DD3091A8645231AF350126B7C7CADB6B89D2BCB1F3778F7F9C34 -623C2CB1537923D336DC75F2B3F06FD16DFA756B5C37F7EDCD0999583ABE6FB56FDEA2A64B7E -D3DFEC1D064166E57B821BDE93CEBEE3F41266927EFE03E646824BA6332B5D2A8B24A469D453 -508DAB6EF30E56FB17467416039E877CA59088FCF3D76682605698D61837448F272A9EEEE609 -E4E44B72B16031480A7ACCE56C042253B2761E8ACFFE13D09BAA39991AC83F7A7BFA671960E4 -BB054C66A544FE3D7CEC4732A77BDB619E0410E61B93BB45463FABAE0E8D44A5CD77E58AB55C -6E3A9F076AFE892FA9E43BC038380B5D1EB9EEEB5BB5CF0C96E91730BF186AC6D9D337C989F9 -4611C06666627266D0D304524CE7A87907D9C022E23000BAD7AB7743F2FCDA576D745B7D3346 -827966287BB484DA9873C7F491F02401A864ED4836E5920E3AC084B2D47098FBCE36EA223195 -6347B9CFF7942D60315119D3DD428B097AC82E009209A4CED3C5CD3B30F12457022D7E841959 -CAC6AEBC2DFD9287ECC7AC2D5B3A1DA280BD4E1CFAF1D17CE1FE5C3451949A8ECEE3368DF1BD -A3E5515C5C0F80B6273375BDEC432BDF1B78FE55F92B4B362DBD8C129C949DEB07715C8794D3 -5C3F49107430C4A604CA833093BCE1B95163A0D1345406FF054EB3B54FD5BCDCED531E01D252 -E6DB7162CFEF34AED6453BB7C61B7BD034B46703AE80309B4F5DDF1B15A40088BBA0FC55EB0A -174B97BB1D934C0BA8E5E6ADC41617CEBE9F18047663C635EC18B9FD1C0FAE76CC9038933BE8 -8C704A95D2F0D67F57FD061CA9757F46DF057D57D5826E2B49FE4454AD2671C7A4AE5F24F83D -F0A6A878F4F3A00720067DCD7B05E55564DE4D8AAC16A8C30DEF7155855D68DBC9453D5AEA88 -4D332E150A2AD5537E481D74DF2AE87FD227C08993741E9ABD9543D98767B4FF873969BD40CA -F3D153352A9B3430B46B88A4BEA305D955B277116090A3DFC81F56384E2666CC1F36E102C546 -4D09870A2EEB97FECED0B99C2862943C6DF1877E178141CF7361F74399268F4B77453E0731F4 -BB8DF0011E6328346253E12D881124534C9A64BA85D272A4FDAFB1DA8FF50C4F149D37C251D8 -3B5B4135C805D90F33E1AAD01914156A98A6AC178639D10387460A56D0C0B50E331131BA5522 -AF79ED5347EC80164A111D7C2286C88B851C43E893580DE162FFF77C0887DDEBFC82218434C2 -9B33A86140E4E1C9E46E8B49A83F656F0B46C917F603CD7CDF15CE8B0D49165E569B3BF18BCF -9BFCEC7DFD8B2010DB8D863C5C5AEDB36C0193392D565C24AD764497AB5331E7DF468ACF96D9 -8707CF755765D22C8876B2F15FF1C4AC403285BC2F21737675153288EDB766C6ED80588A503C -2291960EACAB24838E0F300C36D0E2050AB6C8D39022DA292FECDE19A62D5D539D3C66DBBAB1 -7AB4E9DDD0F3A4DE5A49D513786FEA2F0DACA2F3D52196FAEEF953F7C20386783323946EB1DB -BC774740333C5F3E6AB79D59D2C712D7AA90D8E96C5573925879D922E1807DE2039E381D1E6E -07D373D4C30F09253F4DEB3C8EE7ECDFF7A141F7450D0B63749256D96FFE8D8BE744786B4C28 -A762FD6A6403D8AEA0D4FDE81DF3986C7FCF3AEF0823176E1D7B234E4FD9C97CC3CDF7308E76 -BEFE9F11828AE7038C3C0D6E7ECAC8220FB9D05D99DA6B263A316A552E5070DBDB9582242492 -62706696970665B510F39182A7B79AF809B018353DE9E33FF4A745F777AB78E35BF901BF74E0 -45973BA70C96F2CE2F102AA4B5B5C997DF01FDF12A278247577D70275A2EB629D613898899EE -B39DFE950A7CB1B9F99F6EDFC378CE0B1490BDCA4F7E5614D369DA821C105D8D52C7FFB12F9A -B8DC180F59B137BB128BBC6C3764E3B8A44FE7152535D1DDFD152E2B9C2411EA530937F11EE6 -379D027AB5EBDE8BAC03BB9697836D2981749A4634A772063F04C81D54FA0CB61899788562C9 -AE5BBD0E3ACAF3E4607986851F7DC7F46C48B89BDB9A18E25A053BB3E84740760E91D2342225 -6109FB8F64F26F5E1E2EC47A09CF9392FD00FD61B422D597FF9C3FB325D4E8FD6FB892D24E28 -CC2FDEBB9E004D10A5AFB10D4467032075BF0B44DB26FB866E1730A60F87A3FE2E940E982A6E -4633B744D5E5CA36D6F6BD6714ED3478D64F8CD7F5A764E4EA4EB60639DA4E3B5DD0B6532381 -5820A6C70EF2D53A47B5085F9C74BE5E5E42E8BC5DADD35EBFD9E41C44A3B04651C5D62EA746 -B77182A81207D83D855F981CF2D1A23979D485A93658DBE1C69A003FE86AA64C6E7C382C83DE -F48927EB05BEC2C78466FBE79CBD59E73FC933485689D410A078C59A70B2B5496D1622AF30E7 -888EA2D3C0706045584AB89BB2A5ECA93A686D7BAD8F2DF0BBEC73F4B011EA252FA4987922E0 -A1E9CB93B9F3AC9273F78233BF8E3C9B9CA538D170E01785846EC6CBA18234C2027659D0252F -AC7E392C40CA3BAD479B154DDC418708731E1A70446D67F69E73957922114413A1C8921B91C5 -B542C2C646744128FB255A6CB3485F1CF409EF9776F200053BC89A499DACDCBA22613FE30654 -08DDA78A9741D102CD5EC74F7B6E80DE740E45D4A64DD13B70B2DCA6CA65442B12F922119471 -CD610408731735DAB12FF45494BD15D990EA4D6EE33AC20C00BB528C91CB7A5F049B187B9D7C -502DD7DA643FB5CED04AEB894ACB2CCF3D56D656E0551E5757104BDC29DAFB6C80A10B609494 -1EC1041FABDC2AAF1559E032AAA1B79575C4FA9D4A8917FEF7FA6C349A389E1F0D36D5FCCAF6 -A6CF66ADECE06D92592EE8867F2B142A8FC2FB772DA6C814FC6F6F66373329F2CCF69289085B -8AD7AA5B88C6F7A19CFA5E37BDC61561A82DDF0939844D8ED64BF11084F32C55E09852C6FA41 -A1D9115D0C68DABA31E4FB77D04E5A2B7EB79B521669C629BC9A7CCF129A2A67C92826A435AF -47F0243E14F1F976EA5B58DA6D79499332E85BF2DB5A7E95230979B6C567614E6370A9B341A0 -7D7813C42E8A1251D77AC6A59B6F5B6082F249879D2122B19E7E5AC42026B1EFA799BAAFE866 -B4A6DA7444C903FC0B45122857BD20B602883FE1E2705C0A27BAA636D0356A102093CED97308 -1BC38EE530B62CAE35C5847EAC973F02BBB7461895C526AC25674C972C4E61BDD86F4A852E15 -AB6D94403A030F32C8F3263113A2D1413E624A8143EA7A9613A2DED2C243266932359120A083 -673020E4134CE6483987A1C77E140E6FF5DCD2B3ECF571A52D3411CD5DB601EF4147C4F1DBD1 -EB16C4B838CB9A6640D8AD1A526C312E5CC7BD5AAA9442A6B38AC29FBA0994C91FE575840038 -13F9B8FEB92B20AF8B890BEC220BF995E3680AD69833D08B0357B6606FD60EAE95F497FFF1A8 -02BBE1D3BB3BF6905FBBC1F97A20F78A1B106DB9C158ECF1CCD16E55048CFB4C50E40EA9B9E6 -0768D440A4507F3E76123616FF79745C76F9135BC1104A9F98D6B8A9D299C0E8D3C0BA2FF429 -47CF866B5487F10194A1A8E672A330C0B9CC2202636A5360E10E53FAD86A2D3C88DFF64D4840 -681B6F96E9E797C459A07D0812550908F2AC36E684B1DBF3DEC6074B922E091277493485153C -93ABA41FD097D94F4BBB95581670A1EFF27A0D267B9DF689E2BF6FA657F87B390EF731538E34 -E776DCC1D14F8959A99AF11EB15FC59376BD1A136E6947B9076DCF62AAEFB50C8D6F9E10E090 -FCC17B6D90A0B05726F9BBF4FD92E08E5CF4CE66C426959A9F2E185B6B395B0DD4C80BB283E6 -16E6001DCA44A820C18F62521F1F1117263401E30F84C5974461E6E270B72E50E81CFE305D92 -4D26924E5B7675B52EDED59B87AB5606EE5ED95EDBCCE5DF07A0D41492A366C35DE50A4BF365 -5E6E0F24AA7DE91A16EEC22A9EC0F9667C831759C688928E217DFC6C7E33516D46A225E44A6F -AF58C72236D9FB9F2C13F05FA5F92AE1DD970420B7887E6DFA6C01D9C95DD674863AD81AF472 -3413C430CC912FD0FCEFF72EE9119C4A496C888C0562548F0792897DAC12479411BD39D5C969 -75B9140107D14C8BE1EAA5C482455352C2C5ED15172B9DAC379BDF76FC2E8F11AE24057F851B -0F41A7325994B1B20802F0CD520D439770029EB53E5E989E549F3C055CDA4E37F78E01E9D2E6 -A3D2DAA41232F7CFE9B7E74D87F4B75FB38F72D541D5EAC0D64567AFD28D6D3F07A4E649A853 -2288416A5A51242077DE5138F6BCC2EBF7524D43A6445BBAD2C4E934FD7BB827FD564209347A -C988F9DD9DA8C73A4CBCCACA945CA135FE83DBDFF85E2622728199FC975EB14B425AD1299F3E -69BA41D466CD8E6E9146C0ADB8E93ABE70D43A06CCB205313FEFF9B0F22F7CE37E0F132B8474 -5708C1BB0CE575D972524FA551F2E9F8A06C0B2312137578553D9D6C98838F06FA690278E7EB -A4A3344665C7E7F79C7096238D5CD9FBB12BAF120D1A287B831255A457532BE861B5A8D78972 -2AF86F49EE59915E456E27A3283EF8939AF44119DA2F508B0F0E6DF46B124DB8EC8454B048FB -6D29261E5819785EAEB7740EBAB7049A5641942407861D6B31E06AF206E51F62DBD88057FD58 -A1E41DDC6FAC15D6ABBF4A50ED13A464ADC608BAC45A230955B5E827CC57C2260387CAE9DB47 -D0E35812414D2CDD6C643ADF736AD15E1759BCC714C45CF38CA8E4C617EA8E6453EE4A908267 -8C3F90B8416AB1F4BCB0D0B3E50198F36346F778F7B572FECC635AC8429C17E2CCB4D8424C01 -69FCD29D4F8BD4364AAA30202D285DB593005D826B29F0AC6AB3A226B394E80580B2D7DE2DDA -C4C34D35668D3EC1B34199FFFD25D8DDAB1EC7CEC39BB76614E4BA8B30E75253B529C27823BE -8FDBD9C7103414836F2F955B40B174890B625F54C723E728D0AAB99CE7D73C2AC582ACCEDF5B -0671C07A97D0A9ED3AB5A4B163C83EA4C1C05F4D6DB2609D1E785D42229D59EC182C0C02719D -4420F72C6A9224B62FEA5C885EAA2D61DB6E56D29EA8C091803A2222B6683577A1867796F2C9 -F5175615F6D5FBF9E620AAFA4E60C20CF733EEE1D51F5696AF482AC4AD11278E56EDDFA7E0AD -533FF3ECD2D379C573FBF8E16E3CE11D8EF293967D76408C9C8A3B6A884A5DE9B1D4D40F8086 -48A7BDDE93624BDBED92CE790151E0081B9530DB07E8E982353CB80B50D8B63BCA09A6C42A33 -991C1A305F36857BDC4D18C5679D5716C1B82039C9C9E303B79378B012340DE204495D66A06A -4415980D023C07148785F6A2DCCAF9E86FF0C9835B47524F9A5ACFE9EBC53F7AA3299D595B3E -A3867D71AE686FF0FC9F194279746358C72B2B5AA73E6E92B41AB468964567CA14DC213338B6 -4079965E53EFB8E7EB5474E32D67916A66B896D5A88DBF605CFB36E2224E748FE4259844E6F8 -A20C1E0FB06F24772E06EC3C0E53075AF7072AFB2BA562A691B8D98418F38E4A7C7CD0CF7F45 -0C15BFFA0A267FAA6CFA0E82D49D1AB398442119493CC2A2E15689C7B01992CB73AD2EA3DC8E -4939739AFFF6C7F1D715DA77488F2B5E87E1FE3FF2477B5079705DF17BE7C6ECC949F0904C2E -89DB22A6890AE6B915896C47A74C3ADD1F8FA3FB08CD8C0FE48D380871B84E0E2E418CC81629 -3DA3F3425B19A66C05C24C7B5F2336EB7D3F57EB972EEE70A6CE9D8A8286025B1DA5130B9465 -AB5A097CF05F99F2F5265BF748D9573EA0CEEBC1F2FD5033141264DEDFD7746B65D207FF6CDF -E8124AFF6593C6443F8411DC9F5039D02324B14AD8EA9B1A361AAA6168BFA7C813C39CD0E6B3 -2EE696F8C67E5D15C273C12415C40C1B0F2736BFA6731FF10391DC0E23983905BF3235100413 -7986EDE64D0C3345417C1186AB1AE9E09A98C116DF8B0715FF2B1E99A2FE5FEE1B89F3468DEB -AF2DDDA899B9C1ABA9B2A762B5EA826727E30E158877E646D3CBACF83FD7691BD69E39C448FF -0339101CF7D47622F295A26A884B236B7E9E4BAE6A8DC38A9BEC2E986552DEA9355C1DF792F0 -3DDC318582918C8BAFBCD567638C99398AF9AC3940F3E3A37D5FB6B2129BB3620742B278A0AA -044C096B674CD2F6CB4526552FDCB51BD1E7832CF1F57D95D92CB43F409EFA47C0DAD18FA479 -F72F8657970287AF54C70B695ED1F157A3D171D7A16C30DF4F9530D8489A9A4720F5749659AF -864F1FCCF90B870A3EDBEAE4242893C425F5F0189DB04E3738209737979E12214482DE3E42C8 -9D9E2E8413AF5DE8E2BCF48862E35CDBC822B75CE3475799DB6E1C50071A91C9E0B8B2A23B4C -78F63DBE558CF5F8D026E1150A0A5A56EAC99C7B3BD7201B86ABA3A24845CC22630B2927CBEF -55CE3931698AA96AC1B7B17D9DA16983B3DC05C428184A0F86C818DDF1AC539BEA71ACAC2FC5 -4FA6B0B63E3B8FA4647B972815677003482A8851BF2DD7757698A85E892753ADCA249E607FD9 -7724FD34D5B978B683B7478A1F7C931DD1696B7049C8E4A949C28C540FADC908674E517CCF69 -FFECA21FA70C6034F2C1DFDAB530A6C0DC6F8F9963147F7F393BE5AEC11F95674712FAC4083E -4729A74D31B88516C169B62385D34423047A3A5AC7CF4EC1B3C0755498A06EBEEF941844066F -140F69FB48D6E0CF4FB678196E13A991BE17A8C9681A535EB0E379DB700C3703BC7C948B84FC -2E983B77AE2E926005FDA1DABC948CFB557EBBA947F0395FC7866685499C22E3812206F16DA4 -0776AFC8AC141FDA9A1E3C06FFABD1F1471E1D7149ECED3A9F318932EE192A85D04C26697381 -F4C9E5B3FA36BC2C071C08D4C2EE9D51BDAA5D91419CC54F6327353825BF4D983307A7371CDC -9F8736C6A79DE8FC34182262F5D8F58AFC30254DF5E9B6346BCFB6AE5739E9A5257596AB8D60 -FE0B539A5F8CCF794AB021762104EE69FB1305665D2AD8A04D1C872ED9F45803EAB198402647 -FE98E189FCAE485E55A5198745851D39330456DA286731440167C05ED527A3A3592736FD58EF -A01209F5D5BD52C873E31DBE8913ED626C61D8F759B31A49A0464CC8CCA713CD8C9796C28EF4 -4F6EDCFD2158C8753F04175175DFA7D174F2261B1D531D3DA4B683FCCD094BE75D58C533CDCE -AB481E9E72650164F34C32689B9E5B3E15FA75451CD0412CBCDCDEE1C55202F63018E2479E12 -66B31DFCD8EB29EAB003CDE8F9B00708871829E9E482F9F84DABF50E04A005758FB6F79A4B04 -BB349944962E38958F188FA33DA2D33032517B33A7BC638567C2C09BE64996495ED9DDCE44B4 -2C015F39FE9DFE6A486C1D3EE47FCC92241A54272966B90F9168136BD5E4B9902247BD370827 -4247EBB014FE046B87477898AD03893824065CC8D7D7E269158CE72321B28597BEC407EB9DA6 -E06F7A5079080273BB51BACFE3C2A233C6A5CC3F7009A981D593911C8074C8497A097D7F368C -FBEFC87293DACED1B267D8029C9341235FA531E9B9CD99A47BD939067EC1035778E9F90C4BBD -42C11F99FC4E2DEF0C65DD628717F794FE3AE20508D39A88F300D5FB033223A295507A212F85 -5344571D2A09E4644AEDA2414359CED6977507B64A4ACA4106584CDE9766482E61B8B21E2F9F -365670308D51E73E805137B7EC6E0CC773B0B71EF2B216A8FD98709723AE86757E29C5C47495 -57C682614C9E6B9BAC63388312C2CC5DFE9A63E7C8E1D30D02D5F787142385DDE69E3EF14C2C -F7A1C30389ED2C63B1D19C1530150BC1DCEA91AE06280B9D1C0CAF0AB2C48025D164B37A1983 -0DBE39932823E0B9978FF7D401636AC47300F86148290E0DF001B22B62483740CEAAD2A98F82 -54DBA38D848A15B3EE2C80604624E26B5A45127F58BDB3F1E021C8E0BCF4258F33AFBE778AAD -8390B6E7E82EA8114169E2775AE75EFCB67FC4F104AD327701A3F81807FCFE47C6060061AB35 -DCD77BF335D806B26C45648F5EE0B5AE053389310D80AE22F9EA2EEF1D068EAF4C776C0D3B2C -70C8D533F6B6C869B2CB9BE1104C638AB9057764353011728C2EF17E19DEB436B0D4FD544DE8 -0C0D5570FE9250FB028FE5C4F12A6353B65F87E28B2DDDCCA0936BD847E3498B0E05E53553E1 -49B0A2DE1E57E4D84FD6516259C91ACED13FB6EA70FFC03362E35146369FC6D2F943C4881A9E -68FAD45AAE9361B0EA34749817B3F98DAE65BBE2260F5A8B06F6CA003D16416717B7C740732F -E19663240670C04C558033793F21BDE8107F8655C7365D7C2EB1A6495F5FDE6D185A85A68C09 -4A96303FACEFE684CB75B2AACCEF45AD68C46B817BFDB41553FF360D07DDEBA08F5441E098E4 -E4A70704C4A6A3E07F6E0E28A582F19942FD7F53ECA391F40865EFA5AE9D6EA2359F8EC74C23 -D92585C206FD8AE87264A06DDDCF36720A8026525A84D0D68AC93171EE2E87571567F300D2DE -3CFB7DF541128107227D4949F4D2E6BC7FCFB1909DAFBCA11414C31F9A9C6DE380CE616B9143 -5C212C7F52F705BD46620EC2CE434BF73760D3F574894CEAE00E82DFDEF94B74E1A54117B4AA -B523186ED86DB61A8B842E3869BC2BBB3CB0B587E80963CF1C01D385F20F762CBCEECB1F5E12 -B551447AA9B8A8FCFE74E29C3AE2FD8F651553F80C1AD8D32EA25890D1B3D7BC9EE3571ED872 -BFC14AA5E14B1E24572CF6DEE0A37F30CC26AC91E405957E09EC263DDFEB7870CC24962505FD -B586FE0D2D9148E7DEC517034D87A3D59AB534362BE565A0B0E83C7036D25F912ECFF4C87BCA -1CCDED9037E2B51F1411455F1767974B52C9C040ED0F340DF403C70BB2AEDE49D0411037F27D -E9723419734B3B62613A6AD0D7FFB6B4AD60A927E7A0F6D0770734D886D9CFEFB3D38B701DF0 -88A05738AABDF63CBA03E97CC40943CABD85AE31F3AC3F741945067636CB58B705CF2B6EDE2D -26E721E0DB36F4355F2493E01347869F8452E7CF368B78A163711524FEB83A87F032BE27C9A8 -D0EEFBD78680F8196640D575A360D916E0C3C4BCF0BAF6209CCE3AB17ABBF315BA689BACDB46 -4C8E64F989B3491D8644C937DF9FBD9BDF4A46F377673575215D5951A67DDD00FFC27F4AF099 -B69A0E42B06A1D012D81C03E7A90893F4E7A9E979EA66C1BE4008443AE66D2237D61E1D51981 -D7E98E2BEB93425C27A9C5A2111B4806A9C55DD63E02B8E519E3B4DEFBAFA1D97C0CD09D5548 -89E67A37FE6E7843DB388AD4B211990DCA56CFAE1A1421E137E340DD93A13F82300F3BAC6C14 -801160D7A486E4D6D86612A34C3CDD889D310A4FF1DDFE9E086C93DCDDC7C9C855E57B2FF11E -EEB1602AB284A3C16C90471E355EEADFE60D7A4605471A2CF73F6E8C618BC3EDB50022194C23 -F6843929A63DDC83166B7804D5692BB462C2D9D536630BA9E7D09607F5F3D234C39EBF4514E4 -A66525D654D3F85CD8671B8FC7EAED36FAEAB0EBE66B435286C4F1BC9A7260A249FA6AA4534D -905333700E8575207D7CF4572CAF801E341438866624BF5DB014FA1D54E078241BE2796DFD0C -41A33A665C77302D6789152BEE35AB214762250491A8F6E2E5163DECAB37F324A6B24E4FC60B -4E8D09A98E8CA001AC6005742C697F2AEBE6DD2D6A315EB1C2130C62F0BA71A7E623979845CA -61CAFDE6CD3DC0E3862364E0326BB4505BA76C2E1ABA60F605C5CF16FFB22CD2D473B814B6C7 -1F274218E489C1DA40FDDD1275069D5A3FB8898B3D886B235ED23520CD36D888C484FC952F13 -E7A9A184B4892B88236319881EB0375F631D87C49C5881FB5F9BE508B2CF479496AF4B0A7816 -CA21921563296D2537DBA7A6A5E3C2EE64D14FCD53973AB4C8623CD3E0574BB76D50145AAAB9 -C01EE99218BDCA2250AD2773900B3FE46FB429F636F8A03AA3F85B15A65DB103C3DEA7A70ADC -8367C3F20425F614C09D7EDF1141E4200B22B0F0ABF246C4B1F3FB4534B0AA0193B35C6C9282 -3BD246C28A8FA1FB8CDD16C35E08577D7CB9D54EA4ED905ACBB4068933A0F0D8BE557A8CAC5B -9974E12FBC08ED8B3046ECB8F02F618E1AB086BCD379433EF63A578B05A4C0046C083808E858 -1B93B2F0ABF4A2A6416617C8C167BFEB25DD348729DF48BD207D8649234B5AD4DB4387B53015 -BC48ED1305D24AF73F02C649427FAF78003B5CE8952199763A7638133EF3D3B0AA5B84E44146 -73963276A76A6B8953A023D3643E4B860C4847978F5995FEB031C904466DAB7219BC833903E9 -90E24467D0797B8780238ED5B1AB05FAC6F2D8168CF727E0E688020D72D68ACA98B62FC686A8 -1AE8B9F9AFBA4DA0CFC118D04A81DE89ABB0FECC2EFAC05B98724E55FB884A83DE2A0543B235 -466CA665ADFB740D962D89F5D9E0A4BAD4FC8301371AEBBBB28AC5B6636C8892B997FDFEA2E1 -3FD233E46F988F95559290A7C61A93EDF933533D804BA77DE5CFF35B4BE7B4DA25E7A5ACFE76 -F9BE34CECB3F02C706CB40E260CCA8EE8F68E005F87608AF65A7296C0B4C2F90A3802B11FE3E -6663B5A046CA1EEDB52C50A2849B2996525A5176358B3C91286885B67469EED54AD644F4452C -9175871355ABAD45682F3DE3FA693B76B6F1B71DA5BEBDE7F7B4AD091FCAC8A7029F7EB3DA1E -88794777B6213A9C78F6218F025F81BCB0A79CACCBA5872485272508B8D9D17995E11E8B02B2 -95EFFEC42C0CD4A8299011A31D6354859E96343334B32D5F7E14A1AAE407077FE249C5182BA3 -39AE08750A3EA81206AC36E3BAD944E4795F2D5BE769245D83C76311BECEF343192A611C940D -679D1C2E5A9E7CDE3018A11800C6EE7902B628FB365ED37E115F4C96629CA4C7936EC37437C2 -B6F02A7F5AE65C1E88A6F382BBACE20015403ABB85B52FD484684A2C850C907AAB14B8AAA0B6 -0EDF2314B64ED3F1950A058D0D9D8D6AEB6CFDEA33EEAB955A70953B430EB9ED9E553D594297 -FB154F799A5B4A0FD82B067D8F234003B0023643CBC4FB636D3FF6B7F318F9C64DED734ADA11 -8AB8F138CD94C1564E43B92CBADCFA54FF3BFE5B647A5179CC92FABCB3638063DF444F17C18F -19DB63066D4B2FD7CF2B3DE63D1CF486DE54991B73D27E6DF0B63A54D45946CEB5C4BDCC9515 -E97A435349D7035155A42C280B075B59BC89845C6E294641D8BA2B49629C9DCEC496EFB8C323 -692347122D0BCEB8E793EE381647B5C922BF838A8568C2CBF709DD6EB70D38923AF564F04242 -EEFE46752AA083AD0F19B0A3492F5721A85A377A9C160A604446C2887E3123BF14D0CEDD2CFE -179C11DC231F9B3F06EC99C1C6D18671DD57204FF482E1E4D93639246EA912D6CD1005E10225 -F8C8DC2F2E540C93D9DB908AA8B1EA4140B152277A8AA3D3452ABD078741B546012FC73FEB4E -B882AB0C15D125B6B3DEC6E82A4EC1E11C837C28326E27D17879D9F3688DB1F38191426AA4C5 -0C42113E3A7005F92254B7A338E19C4A06CB706D903FC5359D408261F75F9E9C63D9307BB8DF -8C9F1FEB572D2BB11470CBE05E9C45B7C17D8A34DE703FF63355599448EA18BD15D7E8FDCF6B -EBBB2A89C27278A64A154E2C777E1502499D9A51C1E9236F70567DE5B748AF1949BED1C5409C -151F510424C00EBE7AF3A82D9FB8E898900C787ED304D05159B118B52C8826DA36049B70D6A1 -7BB445711402F8D6217A349B134CFF7C9852515EAAA496CCFDBC768970D464542F1076340507 -DC62041D7F32E25BA02EC9D78F737BD0ECFC7E2B725A050214DFEF8FD72EE67C0624A54B2C00 -B15768B0165F006764B85385426915CA8A3D8782DC05C9F516D85E5ECB5C594A4AC4E42365BB -4477AFC353E5F248142A3D5A22632DEB3DAC54A79CE890C7EF134703CE3B1C1949858B17F18B -BCB1FF377C562D6281C3C08A053B50CCD07CDB20C8D002CABEB082BBF179B9A081C16C3F7772 -6C44F8A3D5270BB63B34E8CFEFACD347F448ED5E690129D33812DC4BA7853B24735BD23149B9 -9D73654B4A22EAC87D19FDCAEDDD519EC97C6024B22BA98162DB5B0769327AE6B9D6F7ABE791 -3BBE25CB9156492D57F4F32E47661851DC82BDBEF74F3FDB433ABA59D6799F9B5FB956950656 -9FA852949ED182BD50D4DE2FF1BAD9EB9BB4D617A127ABB7070278A2AB2FB5E518C03B0E4E3E -15D7531C6B929C74AEE4B275D4AFB0000A309C7AEC9A10C9473FDF77A50F9AFB139ED61E0919 -944E72A0ADB6CC74B9609DFC9CD923C3C5C1BFB3546628E26FD5338005FE9389A493A27594B5 -8469454C2E2530C711F3F02951081DD33BF7A3DB773EA7E446912A18D75841C5B1239D752D48 -48FB8AD79B4B79504A41AB82BB6B43F425909C44853A8A3159BB75B7342F3CB7281AFC25FA76 -93B409FF5DCCD59DAA16E5FDEB1DC19CD1D303BD00D2154F0EC08E04B5FC441010349998C2C6 -EFA036734540532E588FA2A3FF65367997896DFC6A4AC97A31CF6434AEAD822890AA62621F8A -3E93785EA32CFC4EACF582AE356EBFD7134160519F91A50753898F505AE6BC39BF63F3599C07 -9AFCB6812D2D9B159BDC9017152F4A050B08014AC846F970F2DAD485EF15AAF397898584BBEF -2FCDD970786C41AF8B2D3728D3D4C5053EAA1FFBBB2C85752F4E8C0D6F6BF783ABB49796D75C -0F95A0DA58239580180B033816608D8B3C2D5D52A3D50A82D88C0EA92FDE25C314B1F7FB5D22 -0439E685975D29750A878EC4332BC74A67CBC345095DEF613CBD058AAD37EAAF7FF039673D4B -ECCA0E38398CF8B9CA775AF365AD16572FD1899342BB76C248886190C9B7540324CF7AB6E076 -8BA6CE39B012882AD64B08AAD4C1C40BF75FCB05F85C8CDE44C523D42B47B4C906BDF6CF27D0 -6689352A2004728F724FC37601BFE0C7FFEB527E7070F435D0453C0F996055F80B2AF2A36309 -46ECD88DD8E864DE048C09D0BD90C4F970A005FD1AB27DC2F374C4DB8D6E690CA525E313ECE3 -F8F8AB88E50000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark - - -%%EndFont -%%BeginProcSet: texps.pro -TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 -index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll -exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics -exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub -dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} -ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict -end definefont 3 -1 roll makefont /setfont load]cvx def}def -/ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def -/ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def -end -%%EndProcSet -%%BeginProcSet: special.pro -TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N -/vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen -false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B -/@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit -div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ -/CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ -10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B -/@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale -true def end /@MacSetUp{userdict /md known{userdict /md get type -/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup -length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} -N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath -clippath mark{transform{itransform moveto}}{transform{itransform lineto} -}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ -itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ -closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 -0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N -/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 -scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get -ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip -not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 -TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR -pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 --1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg -TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg -sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr -0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add -2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp -{pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 -div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} -N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict -maxlength dict begin /magscale true def normalscale currentpoint TR -/psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts -/psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx -psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy -scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR -/showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ -psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 -roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath -moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict -begin /SpecialSave save N gsave normalscale currentpoint TR -@SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial -{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto -closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx -sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR -}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse -CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury -lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath -}N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ -end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} -N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ -/SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX -SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X -/startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad -yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end -%%EndProcSet -TeXDict begin @defspecial - - TeXDict begin /box{newpath 2 copy moveto 3 copy pop exch lineto 4 -copy pop pop lineto 4 copy exch pop exch pop lineto closepath } bind -def /min{ 2 copy gt { exch } if pop } bind def/max{ 2 copy lt { exch -} if pop } bind def/roundedbox{/radius exch store 3 2 roll 2 copy min -radius sub /miny exch store max radius add /maxy exch store 2 copy -min radius sub /minx exch store max radius add /maxx exch store newpath -minx radius add miny moveto maxx miny maxx maxy radius arcto maxx maxy -minx maxy radius arcto minx maxy minx miny radius arcto minx miny maxx -miny radius arcto 16 {pop} repeat closepath }bind def /rectcartouche{box -gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def /cartouche{roundedbox -gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def end - -@fedspecial end TeXDict begin -40258431 52099146 1000 600 600 (manual.dvi) @start /Fa -157[25 98[{}1 50.000001 /Times-Italic rf /Fb 256[{}0 -50.000001 /RMTMI rf /Fc 167[117 88[{}1 83.333337 /MTEX -rf /Fd 144[50 50 10[50 99[{TeXBase1Encoding ReEncodeFont}3 -83.333337 /Courier-Oblique rf /Fe 205[40 1[17 48[{}2 -63.333383 /MTSYN rf /Ff 144[32 32 2[28 7[28 32 11[39 -86[{}6 63.333383 /Times-Italic rf /Fg 137[31 118[{}1 -63.333383 /RMTMI rf /Fh 139[19 34 23 1[38 2[57 1[34 2[38 -38 19 38 1[34 38 38 44[38 38 38 38 2[19 46[{ - TeXBase1Encoding ReEncodeFont }18 83.333337 /Helvetica-Narrow-Oblique -rf /Fi 4 40 df[<3FFF80000000000000000000000000000000000000007FFFFFE00000 -00000000000000000000000000000000FFFFFFFF80000000000000000000000000000000 -0000FFFFFFFFFC0000000000000000000000000000000000FFFFFFFFFFE0000000000000 -000000000000000000007FFFFFFFFFFE000000000000000000000000000000003FFFFFFF -FFFFE00000000000000000000000000000000000FFFFFFFFFC0000000000000000000000 -000000000000003FFFFFFF80000000000000000000000000000000000000FFFFFFF00000 -0000000000000000000000000000000007FFFFFE00000000000000000000000000000000 -0000003FFFFFC000000000000000000000000000000000000003FFFFF000000000000000 -0000000000000000000000003FFFFE0000000000000000000000000000000000000007FF -FF8000000000000000000000000000000000000000FFFFE0000000000000000000000000 -000000000000001FFFF80000000000000000000000000000000000000003FFFE00000000 -00000000000000000000000000000000FFFF800000000000000000000000000000000000 -00001FFFE00000000000000000000000000000000000000007FFF8000000000000000000 -0000000000000000000001FFFE00000000000000000000000000000000000000007FFF80 -000000000000000000000000000000000000001FFFE00000000000000000000000000000 -000000000007FFF00000000000000000000000000000000000000001FFFC000000000000 -00000000000000000000000000007FFE0000000000000000000000000000000000000000 -1FFF800000000000000000000000000000000000000007FFE00000000000000000000000 -000000000000000001FFF00000000000000000000000000000000000000000FFF8000000 -00000000000000000000000000000000003FFE0000000000000000000000000000000000 -0000001FFF000000000000000000000000000000000000000007FFC00000000000000000 -000000000000000000000001FFE00000000000000000000000000000000000000000FFF0 -00000000000000000000000000000000000000007FFC0000000000000000000000000000 -0000000000001FFE00000000000000000000000000000000000000000FFF000000000000 -000000000000000000000000000003FF8000000000000000000000000000000000000000 -01FFC00000000000000000000000000000000000000000FFF00000000000000000000000 -0000000000000000003FF800000000000000000000000000000000000000001FFC000000 -00000000000000000000000000000000000FFE0000000000000000000000000000000000 -00000007FF000000000000000000000000000000000000000003FF800000000000000000 -000000000000000000000000FFC000000000000000000000000000000000000000007FE0 -00000000000000000000000000000000000000003FF00000000000000000000000000000 -0000000000001FF800000000000000000000000000000000000000000FFC000000000000 -000000000000000000000000000007FE0000000000000000000000000000000000000000 -03FF000000000000000000000000000000000000000001FF800000000000000000000000 -000000000000000000FFC000000000000000000000000000000000000000007FE0000000 -00000000000000000000000000000000003FE00000000000000000000000000000000000 -0000001FF000000000000000000000000000000000000000000FF8000000000000000000 -000000000000000000000007FC000000000000000000000000000000000000000003FE00 -0000000000000000000000000000000000000003FF000000000000000000000000000000 -000000000001FF000000000000000000000000000000000000000000FF80000000000000 -00000000000000000000000000007FC00000000000000000000000000000000000000000 -3FE000000000000000000000000000000000000000001FE0000000000000000000000000 -00000000000000001FF000000000000000000000000000000000000000000FF800000000 -0000000000000000000000000000000007FC000000000000000000000000000000000000 -000003FC000000000000000000000000000000000000000003FE00000000000000000000 -0000000000000000000001FF000000000000000000000000000000000000000000FF0000 -000000000000000000000000000000000000007F80000000000000000000000000000000 -00000000007FC000000000000000000000000000000000000000003FC000000000000000 -000000000000000000000000001FE000000000000000000000000000000000000000001F -F000000000000000000000000000000000000000000FF000000000000000000000000000 -0000000000000007F8000000000000000000000000000000000000000007F80000000000 -00000000000000000000000000000003FC00000000000000000000000000000000000000 -0003FE000000000000000000000000000000000000000001FE0000000000000000000000 -00000000000000000000FF000000000000000000000000000000000000000000FF000000 -0000000000000000000000000000000000007F8000000000000000000000000000000000 -000000007F8000000000000000000000000000000000000000003FC00000000000000000 -0000000000000000000000003FC000000000000000000000000000000000000000001FE0 -00000000000000000000000000000000000000001FE00000000000000000000000000000 -0000000000000FF000000000000000000000000000000000000000000FF0000000000000 -000000000000000000000000000007F80000000000000000000000000000000000000000 -07F8000000000000000000000000000000000000000003FC000000000000000000000000 -000000000000000003FC000000000000000000000000000000000000000001FE00000000 -0000000000000000000000000000000001FE000000000000000000000000000000000000 -000000FF000000000000000000000000000000000000000000FF00000000000000000000 -00000000000000000000007F0000000000000000000000000000000000000000007F8000 -000000000000000000000000000000000000007F80000000000000000000000000000000 -00000000003FC000000000000000000000000000000000000000003FC000000000000000 -000000000000000000000000001FC000000000000000000000000000000000000000001F -E000000000000000000000000000000000000000001FE000000000000000000000000000 -000000000000000FE000000000000000000000000000000000000000000FF00000000000 -0000000000000000000000000000000FF000000000000000000000000000000000000000 -0007F0000000000000000000000000000000000000000007F80000000000000000000000 -00000000000000000007F8000000000000000000000000000000000000000003F8000000 -000000000000000000000000000000000003FC0000000000000000000000000000000000 -00000003FC000000000000000000000000000000000000000001FC000000000000000000 -000000000000000000000001FE000000000000000000000000000000000000000001FE00 -0000000000000000000000000000000000000000FE000000000000000000000000000000 -000000000000FE000000000000000000000000000000000000000000FF00000000000000 -0000000000000000000000000000FF000000000000000000000000000000000000000000 -7F0000000000000000000000000000000000000000007F00000000000000000000000000 -00000000000000007F8000000000000000000000000000000000000000007F8000000000 -000000000000000000000000000000003F80000000000000000000000000000000000000 -00003F8000000000000000000000000000000000000000003FC000000000000000000000 -000000000000000000003FC000000000000000000000000000000000000000001FC00000 -0000000000000000000000000000000000001FC000000000000000000000000000000000 -000000001FC000000000000000000000000000000000000000001FE00000000000000000 -0000000000000000000000001FE000000000000000000000000000000000000000000FE0 -00000000000000000000000000000000000000000FE00000000000000000000000000000 -0000000000000FE000000000000000000000000000000000000000000FE0000000000000 -00000000000000000000000000000FE00000000000000000000000000000000000000000 -0FF000000000000000000000000000000000000000000FF0000000000000000000000000 -000000000000000007F0000000000000000000000000000000000000000007F000000000 -0000000000000000000000000000000007F0000000000000000000000000000000000000 -000007F0000000000000000000000000000000000000000007F000000000000000000000 -0000000000000000000007F0000000000000000000000000000000000000000007F00000 -00000000000000000000000000000000000007F800000000000000000000000000000000 -0000000007F8000000000000000000000000000000000000000003F80000000000000000 -00000000000000000000000003F8000000000000000000000000000000000000000003F8 -000000000000000000000000000000000000000003F80000000000000000000000000000 -00000000000003F8000000000000000000000000000000000000000003F8000000000000 -000000000000000000000000000003F80000000000000000000000000000000000000000 -03F8000000000000000000000000000000000000000003F8000000000000000000000000 -000000000000000003F8000000000000000000000000000000000000000003F800000000 -0000000000000000000000000000000003F8000000000000000000000000000000000000 -000003F8000000000000000000000000000000000000000003F800000000000000000000 -0000000000000000000001F0000000000000000000000000000000000000000000F0> -173 173 294 134 332 36 D[<000000000000000000000000000000000000000000F000 -0000000000000000000000000000000000000001F0000000000000000000000000000000 -000000000003F8000000000000000000000000000000000000000003F800000000000000 -0000000000000000000000000003F8000000000000000000000000000000000000000003 -F8000000000000000000000000000000000000000003F800000000000000000000000000 -0000000000000003F8000000000000000000000000000000000000000003F80000000000 -00000000000000000000000000000003F800000000000000000000000000000000000000 -0003F8000000000000000000000000000000000000000003F80000000000000000000000 -00000000000000000003F8000000000000000000000000000000000000000003F8000000 -000000000000000000000000000000000003F80000000000000000000000000000000000 -00000003F8000000000000000000000000000000000000000007F8000000000000000000 -000000000000000000000007F8000000000000000000000000000000000000000007F000 -0000000000000000000000000000000000000007F0000000000000000000000000000000 -000000000007F0000000000000000000000000000000000000000007F000000000000000 -0000000000000000000000000007F0000000000000000000000000000000000000000007 -F0000000000000000000000000000000000000000007F000000000000000000000000000 -000000000000000FF000000000000000000000000000000000000000000FF00000000000 -0000000000000000000000000000000FE000000000000000000000000000000000000000 -000FE000000000000000000000000000000000000000000FE00000000000000000000000 -0000000000000000000FE000000000000000000000000000000000000000000FE0000000 -00000000000000000000000000000000001FE00000000000000000000000000000000000 -0000001FE000000000000000000000000000000000000000001FC0000000000000000000 -00000000000000000000001FC000000000000000000000000000000000000000001FC000 -000000000000000000000000000000000000003FC0000000000000000000000000000000 -00000000003FC000000000000000000000000000000000000000003F8000000000000000 -000000000000000000000000003F8000000000000000000000000000000000000000007F -8000000000000000000000000000000000000000007F8000000000000000000000000000 -000000000000007F0000000000000000000000000000000000000000007F000000000000 -000000000000000000000000000000FF0000000000000000000000000000000000000000 -00FF000000000000000000000000000000000000000000FE000000000000000000000000 -000000000000000000FE000000000000000000000000000000000000000001FE00000000 -0000000000000000000000000000000001FE000000000000000000000000000000000000 -000001FC000000000000000000000000000000000000000003FC00000000000000000000 -0000000000000000000003FC000000000000000000000000000000000000000003F80000 -00000000000000000000000000000000000007F800000000000000000000000000000000 -0000000007F8000000000000000000000000000000000000000007F00000000000000000 -0000000000000000000000000FF000000000000000000000000000000000000000000FF0 -00000000000000000000000000000000000000000FE00000000000000000000000000000 -0000000000001FE000000000000000000000000000000000000000001FE0000000000000 -00000000000000000000000000001FC00000000000000000000000000000000000000000 -3FC000000000000000000000000000000000000000003FC0000000000000000000000000 -00000000000000007F8000000000000000000000000000000000000000007F8000000000 -000000000000000000000000000000007F00000000000000000000000000000000000000 -0000FF000000000000000000000000000000000000000000FF0000000000000000000000 -00000000000000000001FE000000000000000000000000000000000000000001FE000000 -000000000000000000000000000000000003FC0000000000000000000000000000000000 -00000003FC000000000000000000000000000000000000000007F8000000000000000000 -000000000000000000000007F800000000000000000000000000000000000000000FF000 -000000000000000000000000000000000000000FF0000000000000000000000000000000 -00000000001FE000000000000000000000000000000000000000001FE000000000000000 -000000000000000000000000003FC000000000000000000000000000000000000000003F -C000000000000000000000000000000000000000007F8000000000000000000000000000 -000000000000007F800000000000000000000000000000000000000000FF000000000000 -000000000000000000000000000000FF0000000000000000000000000000000000000000 -01FE000000000000000000000000000000000000000003FE000000000000000000000000 -000000000000000003FC000000000000000000000000000000000000000007F800000000 -0000000000000000000000000000000007F8000000000000000000000000000000000000 -00000FF000000000000000000000000000000000000000001FF000000000000000000000 -000000000000000000001FE000000000000000000000000000000000000000003FC00000 -0000000000000000000000000000000000007FC000000000000000000000000000000000 -000000007F800000000000000000000000000000000000000000FF000000000000000000 -000000000000000000000001FF000000000000000000000000000000000000000003FE00 -0000000000000000000000000000000000000003FC000000000000000000000000000000 -000000000007FC00000000000000000000000000000000000000000FF800000000000000 -000000000000000000000000001FF000000000000000000000000000000000000000001F -E000000000000000000000000000000000000000003FE000000000000000000000000000 -000000000000007FC00000000000000000000000000000000000000000FF800000000000 -000000000000000000000000000001FF0000000000000000000000000000000000000000 -03FF000000000000000000000000000000000000000003FE000000000000000000000000 -000000000000000007FC00000000000000000000000000000000000000000FF800000000 -000000000000000000000000000000001FF0000000000000000000000000000000000000 -00003FE000000000000000000000000000000000000000007FE000000000000000000000 -00000000000000000000FFC00000000000000000000000000000000000000001FF800000 -000000000000000000000000000000000003FF0000000000000000000000000000000000 -00000007FE00000000000000000000000000000000000000000FFC000000000000000000 -00000000000000000000001FF800000000000000000000000000000000000000003FF000 -000000000000000000000000000000000000007FE0000000000000000000000000000000 -0000000000FFC00000000000000000000000000000000000000003FF8000000000000000 -00000000000000000000000007FF00000000000000000000000000000000000000000FFE -00000000000000000000000000000000000000001FFC0000000000000000000000000000 -0000000000003FF80000000000000000000000000000000000000000FFF0000000000000 -0000000000000000000000000001FFC00000000000000000000000000000000000000003 -FF80000000000000000000000000000000000000000FFF00000000000000000000000000 -000000000000001FFE00000000000000000000000000000000000000007FFC0000000000 -000000000000000000000000000000FFF000000000000000000000000000000000000000 -01FFE00000000000000000000000000000000000000007FFC00000000000000000000000 -00000000000000001FFF00000000000000000000000000000000000000003FFE00000000 -00000000000000000000000000000000FFF8000000000000000000000000000000000000 -0001FFF00000000000000000000000000000000000000007FFE000000000000000000000 -0000000000000000001FFF80000000000000000000000000000000000000007FFE000000 -0000000000000000000000000000000001FFFC0000000000000000000000000000000000 -000007FFF0000000000000000000000000000000000000001FFFE0000000000000000000 -000000000000000000007FFF8000000000000000000000000000000000000001FFFE0000 -000000000000000000000000000000000007FFF800000000000000000000000000000000 -0000001FFFE000000000000000000000000000000000000000FFFF800000000000000000 -0000000000000000000003FFFE000000000000000000000000000000000000001FFFF800 -000000000000000000000000000000000000FFFFE0000000000000000000000000000000 -00000007FFFF800000000000000000000000000000000000003FFFFE0000000000000000 -0000000000000000000003FFFFF00000000000000000000000000000000000003FFFFFC0 -000000000000000000000000000000000007FFFFFE000000000000000000000000000000 -000000FFFFFFF000000000000000000000000000000000003FFFFFFF8000000000000000 -000000000000000000FFFFFFFFFC0000000000000000000000000000003FFFFFFFFFFFE0 -0000000000000000000000000000007FFFFFFFFFFE000000000000000000000000000000 -00FFFFFFFFFFE000000000000000000000000000000000FFFFFFFFFC0000000000000000 -000000000000000000FFFFFFFF8000000000000000000000000000000000007FFFFFE000 -00000000000000000000000000000000003FFF8000000000000000000000000000000000 -000000>173 173 294 300 332 I[<3C0000000000000000000000000000000000000000 -007C000000000000000000000000000000000000000000FE000000000000000000000000 -000000000000000000FE000000000000000000000000000000000000000000FE00000000 -0000000000000000000000000000000000FE000000000000000000000000000000000000 -000000FE000000000000000000000000000000000000000000FE00000000000000000000 -0000000000000000000000FE000000000000000000000000000000000000000000FE0000 -00000000000000000000000000000000000000FE00000000000000000000000000000000 -0000000000FE000000000000000000000000000000000000000000FE0000000000000000 -00000000000000000000000000FE000000000000000000000000000000000000000000FE -000000000000000000000000000000000000000000FF0000000000000000000000000000 -00000000000000FF0000000000000000000000000000000000000000007F000000000000 -0000000000000000000000000000007F0000000000000000000000000000000000000000 -007F0000000000000000000000000000000000000000007F000000000000000000000000 -0000000000000000007F0000000000000000000000000000000000000000007F00000000 -00000000000000000000000000000000007F000000000000000000000000000000000000 -0000007F0000000000000000000000000000000000000000007F80000000000000000000 -00000000000000000000007F8000000000000000000000000000000000000000003F8000 -000000000000000000000000000000000000003F80000000000000000000000000000000 -00000000003F8000000000000000000000000000000000000000003F8000000000000000 -000000000000000000000000003FC000000000000000000000000000000000000000003F -C000000000000000000000000000000000000000001FC000000000000000000000000000 -000000000000001FC000000000000000000000000000000000000000001FC00000000000 -0000000000000000000000000000001FE000000000000000000000000000000000000000 -001FE000000000000000000000000000000000000000000FE00000000000000000000000 -0000000000000000000FE000000000000000000000000000000000000000000FE0000000 -00000000000000000000000000000000000FF00000000000000000000000000000000000 -0000000FF0000000000000000000000000000000000000000007F0000000000000000000 -000000000000000000000007F0000000000000000000000000000000000000000007F800 -0000000000000000000000000000000000000007F8000000000000000000000000000000 -000000000003F8000000000000000000000000000000000000000003FC00000000000000 -0000000000000000000000000003FC000000000000000000000000000000000000000001 -FC000000000000000000000000000000000000000001FC00000000000000000000000000 -0000000000000001FE000000000000000000000000000000000000000001FE0000000000 -00000000000000000000000000000000FE00000000000000000000000000000000000000 -0000FF000000000000000000000000000000000000000000FF0000000000000000000000 -000000000000000000007F0000000000000000000000000000000000000000007F800000 -0000000000000000000000000000000000007F8000000000000000000000000000000000 -000000003FC000000000000000000000000000000000000000003FC00000000000000000 -0000000000000000000000001FC000000000000000000000000000000000000000001FE0 -00000000000000000000000000000000000000001FE00000000000000000000000000000 -0000000000000FF000000000000000000000000000000000000000000FF0000000000000 -000000000000000000000000000007F00000000000000000000000000000000000000000 -07F8000000000000000000000000000000000000000007F8000000000000000000000000 -000000000000000003FC000000000000000000000000000000000000000003FC00000000 -0000000000000000000000000000000001FE000000000000000000000000000000000000 -000001FE000000000000000000000000000000000000000000FF00000000000000000000 -0000000000000000000000FF0000000000000000000000000000000000000000007F8000 -000000000000000000000000000000000000007F80000000000000000000000000000000 -00000000003FC000000000000000000000000000000000000000003FC000000000000000 -000000000000000000000000001FE000000000000000000000000000000000000000001F -E000000000000000000000000000000000000000000FF000000000000000000000000000 -000000000000000FF0000000000000000000000000000000000000000007F80000000000 -00000000000000000000000000000007F800000000000000000000000000000000000000 -0003FC000000000000000000000000000000000000000003FE0000000000000000000000 -00000000000000000001FE000000000000000000000000000000000000000000FF000000 -000000000000000000000000000000000000FF0000000000000000000000000000000000 -000000007F8000000000000000000000000000000000000000007FC00000000000000000 -0000000000000000000000003FC000000000000000000000000000000000000000001FE0 -00000000000000000000000000000000000000001FF00000000000000000000000000000 -0000000000000FF0000000000000000000000000000000000000000007F8000000000000 -000000000000000000000000000007FC0000000000000000000000000000000000000000 -03FE000000000000000000000000000000000000000001FE000000000000000000000000 -000000000000000001FF000000000000000000000000000000000000000000FF80000000 -00000000000000000000000000000000007FC00000000000000000000000000000000000 -0000003FC000000000000000000000000000000000000000003FE0000000000000000000 -00000000000000000000001FF000000000000000000000000000000000000000000FF800 -0000000000000000000000000000000000000007FC000000000000000000000000000000 -000000000007FE000000000000000000000000000000000000000003FE00000000000000 -0000000000000000000000000001FF000000000000000000000000000000000000000000 -FF8000000000000000000000000000000000000000007FC0000000000000000000000000 -00000000000000003FE000000000000000000000000000000000000000003FF000000000 -000000000000000000000000000000001FF8000000000000000000000000000000000000 -00000FFC000000000000000000000000000000000000000007FE00000000000000000000 -0000000000000000000003FF000000000000000000000000000000000000000001FF8000 -00000000000000000000000000000000000000FFC0000000000000000000000000000000 -00000000007FE000000000000000000000000000000000000000003FF000000000000000 -000000000000000000000000001FF800000000000000000000000000000000000000000F -FE000000000000000000000000000000000000000007FF00000000000000000000000000 -0000000000000003FF800000000000000000000000000000000000000001FFC000000000 -00000000000000000000000000000000FFE0000000000000000000000000000000000000 -00007FF800000000000000000000000000000000000000001FFC00000000000000000000 -000000000000000000000FFE000000000000000000000000000000000000000007FF0000 -00000000000000000000000000000000000003FFC0000000000000000000000000000000 -0000000001FFE000000000000000000000000000000000000000007FF800000000000000 -000000000000000000000000003FFC00000000000000000000000000000000000000001F -FF00000000000000000000000000000000000000000FFF80000000000000000000000000 -0000000000000003FFE00000000000000000000000000000000000000001FFF000000000 -000000000000000000000000000000007FFC000000000000000000000000000000000000 -00003FFE00000000000000000000000000000000000000000FFF80000000000000000000 -0000000000000000000007FFE00000000000000000000000000000000000000001FFF800 -00000000000000000000000000000000000000FFFE000000000000000000000000000000 -00000000003FFF80000000000000000000000000000000000000001FFFE0000000000000 -0000000000000000000000000007FFF80000000000000000000000000000000000000001 -FFFE00000000000000000000000000000000000000007FFF800000000000000000000000 -00000000000000001FFFE00000000000000000000000000000000000000007FFFC000000 -0000000000000000000000000000000001FFFF0000000000000000000000000000000000 -0000007FFFE0000000000000000000000000000000000000001FFFFC0000000000000000 -000000000000000000000007FFFF8000000000000000000000000000000000000001FFFF -F0000000000000000000000000000000000000003FFFFF00000000000000000000000000 -0000000000000FFFFFF000000000000000000000000000000000000001FFFFFF00000000 -0000000000000000000000000000003FFFFFF80000000000000000000000000000000000 -0007FFFFFFF0000000000000000000000000000000000000FFFFFFFFF800000000000000 -000000000000000000001FFFFFFFFFFFF000000000000000000000000000000001FFFFFF -FFFFF0000000000000000000000000000000001FFFFFFFFFF80000000000000000000000 -000000000001FFFFFFFFF800000000000000000000000000000000000FFFFFFFF8000000 -0000000000000000000000000000001FFFFFF00000000000000000000000000000000000 -00000FFFF0>173 173 128 300 332 I[<00000000000000000000000000000000000000 -0FFFF00000000000000000000000000000000000001FFFFFF00000000000000000000000 -0000000000000FFFFFFFF80000000000000000000000000000000001FFFFFFFFF8000000 -000000000000000000000000001FFFFFFFFFF800000000000000000000000000000001FF -FFFFFFFFF00000000000000000000000000000001FFFFFFFFFFFF0000000000000000000 -000000000000FFFFFFFFF80000000000000000000000000000000007FFFFFFF000000000 -000000000000000000000000003FFFFFF8000000000000000000000000000000000001FF -FFFF0000000000000000000000000000000000000FFFFFF0000000000000000000000000 -0000000000003FFFFF00000000000000000000000000000000000001FFFFF00000000000 -0000000000000000000000000007FFFF800000000000000000000000000000000000001F -FFFC000000000000000000000000000000000000007FFFE0000000000000000000000000 -00000000000001FFFF0000000000000000000000000000000000000007FFFC0000000000 -00000000000000000000000000001FFFE000000000000000000000000000000000000000 -7FFF8000000000000000000000000000000000000001FFFE000000000000000000000000 -0000000000000007FFF8000000000000000000000000000000000000001FFFE000000000 -0000000000000000000000000000003FFF80000000000000000000000000000000000000 -00FFFE0000000000000000000000000000000000000001FFF80000000000000000000000 -000000000000000007FFE0000000000000000000000000000000000000000FFF80000000 -000000000000000000000000000000003FFE000000000000000000000000000000000000 -00007FFC0000000000000000000000000000000000000001FFF000000000000000000000 -00000000000000000003FFE0000000000000000000000000000000000000000FFF800000 -00000000000000000000000000000000001FFF0000000000000000000000000000000000 -0000003FFC00000000000000000000000000000000000000007FF8000000000000000000 -0000000000000000000001FFE00000000000000000000000000000000000000003FFC000 -00000000000000000000000000000000000007FF00000000000000000000000000000000 -000000000FFE00000000000000000000000000000000000000001FFC0000000000000000 -0000000000000000000000007FF80000000000000000000000000000000000000000FFE0 -0000000000000000000000000000000000000001FFC00000000000000000000000000000 -000000000003FF800000000000000000000000000000000000000007FF00000000000000 -000000000000000000000000000FFE00000000000000000000000000000000000000001F -F800000000000000000000000000000000000000003FF000000000000000000000000000 -000000000000007FE00000000000000000000000000000000000000000FFC00000000000 -000000000000000000000000000001FF8000000000000000000000000000000000000000 -03FF000000000000000000000000000000000000000007FE000000000000000000000000 -00000000000000000FFC00000000000000000000000000000000000000001FF800000000 -000000000000000000000000000000003FF0000000000000000000000000000000000000 -00003FE000000000000000000000000000000000000000007FC000000000000000000000 -00000000000000000000FF800000000000000000000000000000000000000001FF000000 -000000000000000000000000000000000003FE0000000000000000000000000000000000 -00000007FE000000000000000000000000000000000000000007FC000000000000000000 -00000000000000000000000FF800000000000000000000000000000000000000001FF000 -000000000000000000000000000000000000003FE0000000000000000000000000000000 -00000000003FC000000000000000000000000000000000000000007FC000000000000000 -00000000000000000000000000FF800000000000000000000000000000000000000001FF -000000000000000000000000000000000000000001FE0000000000000000000000000000 -00000000000003FE000000000000000000000000000000000000000007FC000000000000 -000000000000000000000000000007F80000000000000000000000000000000000000000 -0FF000000000000000000000000000000000000000001FF0000000000000000000000000 -00000000000000001FE000000000000000000000000000000000000000003FC000000000 -000000000000000000000000000000007FC0000000000000000000000000000000000000 -00007F800000000000000000000000000000000000000000FF0000000000000000000000 -00000000000000000000FF000000000000000000000000000000000000000001FE000000 -000000000000000000000000000000000003FE0000000000000000000000000000000000 -00000003FC000000000000000000000000000000000000000007F8000000000000000000 -000000000000000000000007F800000000000000000000000000000000000000000FF000 -000000000000000000000000000000000000000FF0000000000000000000000000000000 -00000000001FE000000000000000000000000000000000000000001FE000000000000000 -000000000000000000000000003FC000000000000000000000000000000000000000003F -C000000000000000000000000000000000000000007F8000000000000000000000000000 -000000000000007F800000000000000000000000000000000000000000FF000000000000 -000000000000000000000000000000FF0000000000000000000000000000000000000000 -01FE000000000000000000000000000000000000000001FE000000000000000000000000 -000000000000000003FC000000000000000000000000000000000000000003FC00000000 -0000000000000000000000000000000007F8000000000000000000000000000000000000 -000007F8000000000000000000000000000000000000000007F000000000000000000000 -000000000000000000000FF000000000000000000000000000000000000000000FF00000 -0000000000000000000000000000000000001FE000000000000000000000000000000000 -000000001FE000000000000000000000000000000000000000001FC00000000000000000 -0000000000000000000000003FC000000000000000000000000000000000000000003FC0 -00000000000000000000000000000000000000007F800000000000000000000000000000 -0000000000007F8000000000000000000000000000000000000000007F00000000000000 -0000000000000000000000000000FF000000000000000000000000000000000000000000 -FF000000000000000000000000000000000000000000FE00000000000000000000000000 -0000000000000001FE000000000000000000000000000000000000000001FE0000000000 -00000000000000000000000000000001FC00000000000000000000000000000000000000 -0001FC000000000000000000000000000000000000000003FC0000000000000000000000 -00000000000000000003FC000000000000000000000000000000000000000003F8000000 -000000000000000000000000000000000007F80000000000000000000000000000000000 -00000007F8000000000000000000000000000000000000000007F0000000000000000000 -000000000000000000000007F000000000000000000000000000000000000000000FF000 -000000000000000000000000000000000000000FF0000000000000000000000000000000 -00000000000FE000000000000000000000000000000000000000000FE000000000000000 -000000000000000000000000000FE000000000000000000000000000000000000000001F -E000000000000000000000000000000000000000001FE000000000000000000000000000 -000000000000001FC000000000000000000000000000000000000000001FC00000000000 -0000000000000000000000000000001FC000000000000000000000000000000000000000 -003FC000000000000000000000000000000000000000003FC00000000000000000000000 -0000000000000000003F8000000000000000000000000000000000000000003F80000000 -00000000000000000000000000000000003F800000000000000000000000000000000000 -0000003F8000000000000000000000000000000000000000007F80000000000000000000 -00000000000000000000007F8000000000000000000000000000000000000000007F0000 -000000000000000000000000000000000000007F00000000000000000000000000000000 -00000000007F0000000000000000000000000000000000000000007F0000000000000000 -000000000000000000000000007F0000000000000000000000000000000000000000007F -0000000000000000000000000000000000000000007F0000000000000000000000000000 -000000000000007F000000000000000000000000000000000000000000FF000000000000 -000000000000000000000000000000FF0000000000000000000000000000000000000000 -00FE000000000000000000000000000000000000000000FE000000000000000000000000 -000000000000000000FE000000000000000000000000000000000000000000FE00000000 -0000000000000000000000000000000000FE000000000000000000000000000000000000 -000000FE000000000000000000000000000000000000000000FE00000000000000000000 -0000000000000000000000FE000000000000000000000000000000000000000000FE0000 -00000000000000000000000000000000000000FE00000000000000000000000000000000 -0000000000FE000000000000000000000000000000000000000000FE0000000000000000 -00000000000000000000000000FE0000000000000000000000000000000000000000007C -0000000000000000000000000000000000000000003C0000000000000000000000000000 -00000000000000>173 173 128 134 332 I E /Fj 133[40 40 -1[40 40 40 40 40 40 1[40 40 40 40 40 40 1[40 40 40 40 -40 40 40 40 40 10[40 40 40 40 40 1[40 40 40 40 1[40 1[40 -1[40 40 40 40 40 40 7[40 40 40 40 40 40 40 40 40 40 40 -40 40 40 40 40 40 40 40 2[40 1[40 35[{TeXBase1Encoding ReEncodeFont}61 -66.666667 /Courier rf /Fk 145[33 48 1[29 107[{}3 66.666667 -/Times-Italic rf /Fl 194[31 61[{}1 66.666667 /RMTMI rf -/Fm 205[28 28 49[{TeXBase1Encoding ReEncodeFont}2 56.666690 -/Times-Roman rf /Fn 205[32 32 49[{TeXBase1Encoding ReEncodeFont}2 -63.333383 /Times-Roman rf /Fo 139[23 32 32 1[42 1[46 -65 23 2[23 46 42 1[37 42 2[42 18[60 74 5[60 55 23[21 -46[{TeXBase1Encoding ReEncodeFont}18 83.333337 /Times-BoldItalic -rf /Fp 133[50 50 50 50 50 50 50 50 50 1[50 50 50 50 50 -50 50 50 50 50 1[50 50 50 50 50 3[50 1[50 6[50 50 4[50 -1[50 2[50 7[50 14[50 50 1[50 50 50 45[{TeXBase1Encoding ReEncodeFont}37 -83.333337 /Courier rf /Fq 182[22 3[53 69[{TeXBase1Encoding ReEncodeFont} -2 79.999924 /Helvetica-Bold rf /Fr 134[55 55 1[55 61 -33 55 39 1[61 61 61 89 28 1[28 28 61 61 1[55 61 55 61 -55 12[61 66 72 1[66 78 1[83 3[28 1[78 61 1[72 72 1[72 -8[55 55 55 55 55 55 55 55 2[28 33 5[28 39[{ -TeXBase1Encoding ReEncodeFont}44 100.000003 /Helvetica-Bold -rf /Fs 103[28 30[37 37 55 37 42 23 32 32 1[42 42 42 60 -23 1[23 23 42 42 23 37 42 37 42 42 3[32 1[32 4[51 1[46 -3[51 60 55 69 5[60 51 51 1[55 2[76 2[56 2[28 5[42 1[42 -42 42 23 21 28 1[56 7[42 31[42 3[{TeXBase1Encoding ReEncodeFont}49 -83.333337 /Times-Italic rf /Ft 135[37 2[42 6[42 60 1[37 -23 23 3[37 42 2[42 10[51 5[51 1[55 6[60 1[51 3[51 65[{}16 -83.333337 /Times-Italic rf /Fu 136[61 40 55[65 2[27 23 -10[31 31 46[{}7 83.333337 /RMTMI rf /Fv 182[15 3[36 69[{ - TeXBase1Encoding ReEncodeFont }2 66.666667 /Helvetica-Narrow -rf /Fw 212[78 43[{}1 83.333337 /ZapfDingbats rf /Fx 134[34 -34 49 34 38 19 34 23 38 38 38 38 57 15 2[15 38 38 19 -38 38 34 38 38 12[42 45 49 2[53 1[57 9[49 1[45 10[38 -38 2[38 38 38 1[19 23 3[23 23 37[34 2[{ TeXBase1Encoding ReEncodeFont } -40 83.333337 /Helvetica-Narrow rf /Fy 138[42 2[26 5[19 -2[19 1[42 1[38 2[42 38 12[42 13[42 12[38 38 38 38 38 -38 38 38 38 38 48[{ TeXBase1Encoding ReEncodeFont }20 -83.333337 /Helvetica-Narrow-Bold rf /Fz 134[42 1[60 42 -46 23 42 28 1[46 46 46 69 18 42 1[18 46 46 1[46 46 42 -46 46 7[55 1[78 55 1[51 55 60 1[55 1[60 69 1[55 1[23 -60 65 1[55 60 60 1[55 22[32 42[{TeXBase1Encoding ReEncodeFont}39 -83.333337 /Helvetica rf /FA 182[26 3[62 69[{ -TeXBase1Encoding ReEncodeFont}2 93.333301 /Helvetica-Bold -rf /FB 133[42 46 46 65 46 51 28 46 32 1[51 51 51 74 23 -46 1[23 51 51 28 46 51 46 51 46 9[78 55 1[51 55 60 1[55 -65 60 69 1[60 1[23 1[65 51 55 60 60 60 2[51 8[46 46 46 -1[46 46 2[23 28 45[{TeXBase1Encoding ReEncodeFont}49 -83.333337 /Helvetica-Bold rf /FC 133[37 42 42 60 42 46 -28 32 37 46 46 42 46 69 23 1[28 23 46 42 28 37 46 37 -46 42 9[83 60 1[55 46 60 1[51 1[60 1[55 2[32 5[60 1[60 -8[42 1[42 42 42 42 42 42 3[28 21 4[28 5[28 29[46 46 2[{ -TeXBase1Encoding ReEncodeFont}49 83.333337 /Times-Bold -rf /FD 134[65 1[90 1[71 39 65 45 71 1[71 71 103 32 2[32 -71 71 39 65 71 65 71 65 9[110 78 1[71 78 84 1[78 1[84 -97 71 2[32 5[84 1[84 10[65 65 65 65 65 65 3[39 5[32 39[{ -TeXBase1Encoding ReEncodeFont}40 116.666669 /Helvetica-Bold -rf /FE 103[22 30[37 1[52 1[41 22 37 26 1[41 1[41 59 1[37 -1[18 41 2[37 41 37 1[37 23[18 3[44 10[22 10[18 18 46[{ -TeXBase1Encoding ReEncodeFont}22 66.666667 /Helvetica-Bold -rf /FF 133[29 33 1[48 33 33 18 26 22 33 33 33 33 52 18 -33 1[18 33 33 22 29 33 29 33 29 9[63 1[48 41 37 44 1[37 -48 1[59 41 2[22 48 48 37 1[48 44 44 48 6[18 33 33 2[33 -33 33 33 33 33 18 17 22 17 6[55 33[37 37 2[{ -TeXBase1Encoding ReEncodeFont}57 66.666667 /Times-Roman -rf /FG 171[41 44 5[55 3[18 3[44 69[{TeXBase1Encoding ReEncodeFont}5 -66.666667 /Helvetica rf /FH 182[15 3[35 69[{ -TeXBase1Encoding ReEncodeFont}2 53.333281 /Helvetica -rf /FI 252[29 3[{}1 56.666690 /MTSYN rf /FJ 134[33 33 -50 33 37 21 29 29 1[37 37 37 54 21 33 1[21 37 37 21 33 -37 33 37 37 25 5[42 5[42 37 2[46 2[62 42 1[33 25 1[54 -1[46 54 50 1[46 6[25 11[19 6[25 36[37 2[{TeXBase1Encoding ReEncodeFont} -41 75.000000 /Times-Italic rf /FK 103[25 1[37 27[33 37 -37 54 37 37 21 29 25 37 37 37 37 58 21 37 21 21 37 37 -25 33 37 33 37 33 3[25 1[25 3[71 54 54 46 42 50 1[42 -1[54 66 46 54 29 25 54 54 1[46 54 50 50 54 6[21 37 37 -37 37 37 37 37 37 37 37 21 19 25 19 2[25 25 25 39[{ -TeXBase1Encoding ReEncodeFont}68 75.000000 /Times-Roman -rf /FL 104[83 28[37 42 42 60 42 42 23 32 28 42 42 42 -42 65 23 42 23 23 42 42 28 37 42 37 42 37 28 2[28 1[28 -2[60 78 60 60 51 46 55 1[46 60 60 74 51 60 1[28 60 60 -46 51 60 55 55 60 76 2[47 1[23 23 42 42 42 42 42 42 42 -42 42 42 23 21 28 21 1[42 28 28 28 65 69 33[46 46 2[{ -TeXBase1Encoding ReEncodeFont}78 83.333337 /Times-Roman -rf /FM 149[24 2[31 31 16[28 28 15[65 65 12[0 3[52 85 -22[65 22[43 3[{}12 83.333337 /MTSYN rf /FN 134[50 2[50 -50 28 39 33 1[50 50 50 78 28 2[28 50 1[33 44 1[44 50 -44 11[72 1[55 66 1[55 1[72 89 4[72 3[72 66 1[72 7[50 -50 2[50 50 1[50 50 50 28 2[25 44[{TeXBase1Encoding ReEncodeFont}37 -100.000003 /Times-Roman rf /FO 134[60 3[66 1[60 40 1[66 -66 66 100 3[27 1[66 1[66 66 2[66 10[80 10[80 3[93 71[{ -TeXBase1Encoding ReEncodeFont}16 119.999948 /Helvetica -rf /FP 140[53 38 2[77 72 4[29 3[77 14[84 33[67 3[67 1[33 -46[{TeXBase1Encoding ReEncodeFont}10 119.999948 /AvantGarde-Demi -rf /FQ 136[115 1[86 43 63 46 1[95 92 86 135 34 83 1[34 -86 95 40 92 95 92 1[95 11[92 1[75 83 1[80 121 1[129 5[121 -69 2[112 1[106 19[60 40 44[{TeXBase1Encoding ReEncodeFont}31 -143.999997 /AvantGarde-Demi rf /FR 252[66 3[{}1 126.665747 -/MTSYN rf /FS 171[126 138 5[172 77[{TeXBase1Encoding ReEncodeFont}3 -207.333362 /Helvetica-Bold rf /FT 182[46 3[110 69[{ -TeXBase1Encoding ReEncodeFont}2 165.866715 /Helvetica-Bold -rf end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 600dpi -TeXDict begin -%%PaperSize: Letter - -%%EndSetup -%%Page: 1 1 -1 0 bop 1700 560 a FS(M)-11 b FT(E)-42 b FS(T)g FT(I)p -FS(S)2202 499 y FR(\003)280 760 y FQ(A)40 b(Softw)l(ar)o(e)f(P)m(ac)n -(kage)g(f)m(or)i(P)m(ar)s(titioning)g(Unstr)s(uctur)o(ed)399 -961 y(Gra)s(phs)s(,)e(P)m(ar)s(titioning)i(Meshes)s(,)g(and)e -(Computing)484 1162 y(Fill-Reducing)i(Or)o(der)s(ings)f(of)g(Spar)s(se) -f(Ma)q(tr)s(ices)1640 1363 y FP(V)-12 b(er)r(sion)32 -b(4.0)1076 1749 y FO(George)j(Kar)t(ypis)e(and)h(Vipin)f(K)l(umar)167 -1929 y FN(Uni)n(v)o(ersity)23 b(of)i(Minnesota,)e(Department)h(of)h -(Computer)g(Science)g(/)g(Army)f(HPC)i(Research)g(Center)1459 -2057 y(Minneapolis,)d(MN)h(55455)1443 2214 y FM(f)p FL(karypis,)19 -b(kumar)p FM(g)p FL(@cs.umn.edu)1550 2406 y FN(September)25 -b(20,)g(1998)208 2756 y FK(Metis)16 b([MEE)g(tis]:)21 -b FJ(`Metis')16 b(is)g(the)h(Gr)m(eek)g(wor)m(d)g(for)g(wisdom.)22 -b(Metis)16 b(was)h(a)f(titaness)h(in)f(Gr)m(eek)i(mytholo)o(gy)l(.)23 -b(She)17 b(was)g(the)f(consort)208 2856 y(of)i(Zeus)h(and)h(the)f -(mother)g(of)g(Athena.)24 b(She)19 b(pr)m(esided)h(o)o(ver)g(all)f -(wisdom)g(and)h(knowledg)o(e)o(.)p 0 4929 1560 4 v 86 -4981 a FI(\003)122 5005 y FG(M)m FH(E)-13 b FG(T)g FH(I)q -FG(S)18 b FF(is)h(cop)o(yrighted)j(by)d(the)h(re)o(gents)g(of)f(the)h -(Uni)n(v)o(ersity)h(of)e(Minnesota.)28 b(This)19 b(w)o(ork)g(w)o(as)h -(supported)g(by)f(IST/BMDO)g(through)h(Army)f(Research)i(Of)n(\002ce)0 -5084 y(contract)d(D)m(A/D)m(AAH04-93-G-0080,)g(and)d(by)h(Army)f(High)g -(Performance)i(Computing)g(Research)h(Center)f(under)f(the)g(auspices)h -(of)e(the)h(Department)h(of)f(the)g(Army)l(,)0 5163 y(Army)i(Research)i -(Laboratory)g(cooperati)n(v)o(e)i(agreement)e(number)f(D)m -(AAH04-95-2-0003/contract)24 b(number)18 b(D)m(AAH04-95-C-0008,)j(the)e -(content)h(of)e(which)h(does)0 5242 y(not)g(necessarily)i(re\003ect)f -(the)f(position)h(or)e(the)h(polic)o(y)h(of)e(the)h(go)o(v)o(ernment,)h -(and)f(no)f(of)n(\002cial)i(endorsement)h(should)e(be)f(inferred.)26 -b(Access)19 b(to)g(computing)h(f)o(acilities)0 5321 y(were)14 -b(pro)o(vided)h(by)e(Minnesota)i(Supercomputer)h(Institute,)f(Cray)f -(Research)h(Inc,)f(and)g(by)f(the)h(Pittsb)o(ur)o(gh)g(Supercomputing)i -(Center)l(.)22 b(Related)15 b(papers)f(are)g(a)o(v)n(ailable)0 -5400 y(via)k(WWW)d(at)j(URL:)f FE(http://www)m(.cs.umn.edu/\230kar)q -(ypis)1929 5649 y FL(1)p eop -%%Page: 2 2 -2 1 bop 0 85 a FD(Contents)0 277 y FC(1)83 b(Intr)o(oduction)3281 -b(3)0 470 y(2)83 b(What)20 b(is)j FB(M)l FE(E)-17 b FB(T)g -FE(I)p FB(S)3237 b FC(4)0 663 y(3)83 b(What)20 b(is)h(New)f(in)h(This)h -(V)-8 b(ersion)2724 b(6)0 855 y(4)85 b FB(M)l FE(E)-17 -b FB(T)g FE(I)p FB(S)r FC(')m(s)22 b(Stand-Alone)d(Pr)o(ograms)2637 -b(8)125 965 y FL(4.1)85 b(Graph)20 b(P)o(artitioning)e(Programs)53 -b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g -(.)h(.)f(.)g(.)g(.)143 b(8)125 1074 y(4.2)85 b(Mesh)21 -b(P)o(artitioning)d(Programs)76 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)143 -b(9)125 1184 y(4.3)85 b(Sparse)21 b(Matrix)e(Reordering)g(Programs)58 -b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g -(.)102 b(11)125 1294 y(4.4)85 b(Auxiliary)19 b(Programs)43 -b(.)e(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h -(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) -g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(13)315 1403 -y(4.4.1)c(Mesh)20 b(T)-7 b(o)21 b(Graph)e(Con)m(v)o(ersion)75 -b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g -(.)102 b(13)315 1513 y(4.4.2)c(Graph)19 b(Check)o(er)56 -b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) -g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h -(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(14)125 1622 y(4.5)85 -b(Input)19 b(File)i(F)o(ormats)h(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g -(.)102 b(15)315 1732 y(4.5.1)c(Graph)19 b(File)79 b(.)41 -b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(15)315 1842 y(4.5.2)c(Mesh)20 -b(File)40 b(.)h(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h -(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(16)125 -1951 y(4.6)85 b(Output)20 b(File)h(F)o(ormats)28 b(.)41 -b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(17)315 2061 y(4.6.1)c(P)o -(artition)20 b(File)63 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 -b(17)315 2170 y(4.6.2)c(Ordering)19 b(File)48 b(.)42 -b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(17)0 2363 y FC(5)85 -b FB(M)l FE(E)-17 b FB(T)g FE(I)p FB(S)r FC(')m(s)22 -b(Library)e(Interface)2784 b(18)125 2473 y FL(5.1)85 -b(Graph)20 b(Data)g(Structure)52 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g -(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) -g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 -b(18)125 2582 y(5.2)85 b(Mesh)21 b(Data)f(Structure)75 -b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(19)125 2692 -y(5.3)85 b(P)o(artitioning)19 b(Objecti)n(v)o(es)62 b(.)41 -b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g -(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) -g(.)g(.)h(.)f(.)g(.)g(.)102 b(19)125 2801 y(5.4)85 b(Graph)20 -b(P)o(artitioning)e(Routines)77 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 -b(21)504 2911 y(METIS)p 759 2911 25 4 v 29 w(P)o(artGraphRecursi)n(v)o -(e)60 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)102 b(21)504 3020 y(METIS)p 759 3020 V 29 -w(P)o(artGraphKw)o(ay)68 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(22)504 -3130 y(METIS)p 759 3130 V 29 w(P)o(artGraphVKw)o(ay)70 -b(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)g(.)102 b(23)504 3240 y(METIS)p 759 3240 V 29 -w(mCP)o(artGraphRecursi)n(v)o(e)65 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(24)504 3349 y(METIS)p -759 3349 V 29 w(mCP)o(artGraphKw)o(ay)72 b(.)41 b(.)h(.)f(.)g(.)g(.)h -(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(26)504 -3459 y(METIS)p 759 3459 V 29 w(WP)o(artGraphRecursi)n(v)o(e)44 -b(.)e(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -102 b(28)504 3568 y(METIS)p 759 3568 V 29 w(WP)o(artGraphKw)o(ay)52 -b(.)41 b(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)g(.)102 b(30)504 3678 y(METIS)p 759 3678 V 29 -w(WP)o(artGraphVKw)o(ay)54 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(32)125 3788 y(5.5)85 -b(Mesh)21 b(P)o(artitioning)d(Routines)38 b(.)j(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 -b(34)504 3897 y(METIS)p 759 3897 V 29 w(P)o(artMeshNodal)23 -b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g -(.)h(.)f(.)g(.)g(.)102 b(34)504 4007 y(METIS)p 759 4007 -V 29 w(P)o(artMeshDual)65 b(.)42 b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(35)125 -4116 y(5.6)85 b(Sparse)21 b(Matrix)e(Reordering)g(Routines)h(.)41 -b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -102 b(36)504 4226 y(METIS)p 759 4226 V 29 w(EdgeND)67 -b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.) -g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h -(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(36)504 4336 y(METIS)p -759 4336 V 29 w(NodeND)58 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 -b(37)504 4445 y(METIS)p 759 4445 V 29 w(NodeWND)42 b(.)f(.)g(.)h(.)f(.) -g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h -(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -g(.)102 b(39)125 4555 y(5.7)85 b(Auxiliary)19 b(Routines)67 -b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(40)504 4664 -y(METIS)p 759 4664 V 29 w(MeshT)-7 b(oNodal)70 b(.)42 -b(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.) -f(.)g(.)g(.)102 b(40)504 4774 y(METIS)p 759 4774 V 29 -w(MeshT)-7 b(oDaul)50 b(.)41 b(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f -(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.) -h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(41)504 -4883 y(METIS)p 759 4883 V 29 w(EstimateMemory)29 b(.)41 -b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g -(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.) -g(.)g(.)102 b(42)125 4993 y(5.8)85 b(C)22 b(and)d(F)o(ortran)g(Support) -81 b(.)41 b(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)h(.)f -(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)h(.)f(.)g(.) -h(.)f(.)g(.)g(.)h(.)f(.)g(.)g(.)102 b(43)0 5186 y FC(6)83 -b(System)20 b(Requir)o(ements)g(and)h(Contact)e(Inf)n(ormation)2011 -b(44)1929 5649 y FL(2)p eop -%%Page: 3 3 -3 2 bop 0 85 a FD(1)116 b(Intr)n(oduction)0 261 y FL(Algorithms)17 -b(that)h(\002nd)g(a)h(good)d(partitioning)g(of)i(highly)f(unstructured) -f(graphs)h(are)h(critical)g(for)g(de)n(v)o(eloping)d(ef)n(\002cient)j -(solutions)f(for)0 370 y(a)25 b(wide)f(range)f(of)g(problems)g(in)h -(man)o(y)f(application)g(areas)h(on)g(both)f(serial)i(and)e(parallel)h -(computers.)35 b(F)o(or)24 b(e)o(xample,)f(lar)o(ge-scale)0 -480 y(numerical)f(simulations)h(on)g(parallel)h(computers,)e(such)i(as) -g(those)f(based)h(on)f(\002nite)h(element)f(methods,)g(require)f(the)i -(distrib)n(ution)0 590 y(of)e(the)h(\002nite)g(element)f(mesh)g(to)h -(the)g(processors.)31 b(This)22 b(distrib)n(ution)g(must)g(be)h(done)e -(so)i(that)g(the)g(number)d(of)j(elements)f(assigned)0 -699 y(to)28 b(each)g(processor)e(is)j(the)f(same,)h(and)f(the)g(number) -e(of)h(adjacent)g(elements)h(assigned)f(to)h(dif)n(ferent)e(processors) -h(is)i(minimized.)0 809 y(The)20 b(goal)g(of)h(the)f(\002rst)h -(condition)e(is)j(to)e(balance)g(the)g(computations)f(among)g(the)i -(processors.)k(The)20 b(goal)g(of)g(the)h(second)e(condition)0 -918 y(is)25 b(to)g(minimize)e(the)h(communication)e(resulting)h(from)g -(the)i(placement)e(of)h(adjacent)f(elements)h(to)h(dif)n(ferent)d -(processors.)37 b(Graph)0 1028 y(partitioning)20 b(can)h(be)g(used)h -(to)f(successfully)g(satisfy)h(these)g(conditions)e(by)h(\002rst)h -(modeling)e(the)h(\002nite)h(element)f(mesh)g(by)g(a)h(graph,)0 -1138 y(and)e(then)f(partitioning)g(it)h(into)g(equal)g(parts.)100 -1247 y(Graph)31 b(partitioning)g(algorithms)g(are)h(also)h(used)f(to)h -(compute)e(\002ll-reducing)f(orderings)h(of)h(sparse)g(matrices.)62 -b(These)32 b(\002ll-)0 1357 y(reducing)d(orderings)f(are)j(useful)f -(when)g(direct)g(methods)g(are)g(used)h(to)f(solv)o(e)h(sparse)f -(systems)h(of)g(linear)f(equations.)55 b(A)31 b(good)0 -1466 y(ordering)25 b(of)i(a)h(sparse)f(matrix)g(dramatically)f(reduces) -g(both)h(the)g(amount)f(of)h(memory)f(as)i(well)g(as)g(the)f(time)h -(required)d(to)j(solv)o(e)0 1576 y(the)23 b(system)g(of)g(equations.)32 -b(Furthermore,)21 b(the)i(\002ll-reducing)e(orderings)h(produced)e(by)j -(graph)e(partitioning)g(algorithms)h(are)h(par)n(-)0 -1685 y(ticularly)28 b(suited)h(for)g(parallel)g(direct)f(f)o -(actorization)g(as)i(the)o(y)e(lead)h(to)g(high)f(de)o(gree)g(of)h -(concurrenc)o(y)d(during)h(the)i(f)o(actorization)0 1795 -y(phase.)100 1905 y(Graph)19 b(partitioning)f(is)j(also)g(used)e(for)h -(solving)f(optimization)g(problems)f(arising)i(in)g(numerous)e(areas)j -(such)f(as)g(design)g(of)g(v)o(ery)0 2014 y(lar)o(ge)25 -b(scale)i(inte)o(grated)e(circuits)h(\(VLSI\),)f(storing)g(and)h -(accessing)g(spatial)h(databases)e(on)h(disks,)i(transportation)c -(management,)0 2124 y(and)c(data)g(mining.)1929 5649 -y(3)p eop -%%Page: 4 4 -4 3 bop 0 85 a FD(2)116 b(What)31 b(is)k(M)-6 b FA(E)-23 -b FD(T)g FA(I)p FD(S)2 259 y Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)34 b FL(is)d(a)f(softw)o(are)f(package)f(for)h -(partitioning)f(lar)o(ge)h(irre)o(gular)f(graphs,)i(partitioning)e(lar) -o(ge)h(meshes,)i(and)f(computing)d(\002ll-)0 369 y(reducing)21 -b(orderings)g(of)i(sparse)g(matrices.)32 b(The)23 b(algorithms)f(in)j -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 b FL(are)c(based)f(on)h -(multile)n(v)o(el)e(graph)h(partitioning)f(described)0 -478 y(in)30 b([8)o(,)f(7,)h(6)o(].)53 b(T)m(raditional)28 -b(graph)g(partitioning)f(algorithms)h(compute)g(a)i(partition)e(of)h(a) -h(graph)e(by)h(operating)e(directly)i(on)g(the)0 588 -y(original)17 b(graph)h(as)h(illustrated)f(in)h(Figure)f(1\(a\).)24 -b(These)18 b(algorithms)g(are)g(often)g(too)g(slo)n(w)h(and/or)f -(produce)e(poor)i(quality)g(partitions.)100 698 y(Multile)n(v)o(el)23 -b(partitioning)g(algorithms,)h(on)g(the)g(other)g(hand,)g(tak)o(e)g(a)h -(completely)e(dif)n(ferent)g(approach)f([5)o(,)j(8)o(,)g(7)o(].)38 -b(These)24 b(algo-)0 807 y(rithms,)19 b(as)h(illustrated)f(in)g(Figure) -f(1\(b\),)g(reduce)g(the)i(size)g(of)e(the)i(graph)d(by)i(collapsing)f -(v)o(ertices)h(and)g(edges,)f(partition)g(the)i(smaller)0 -917 y(graph,)25 b(and)f(then)h(uncoarsen)e(it)j(to)g(construct)e(a)h -(partition)f(for)h(the)g(original)f(graph.)40 b Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)30 b FL(uses)c(no)o(v)o(el)d(approaches)g -(to)j(succes-)0 1026 y(si)n(v)o(ely)h(reduce)f(the)h(size)g(of)g(the)g -(graph)f(as)i(well)f(as)h(to)f(further)f(re\002ne)h(the)g(partition)f -(during)f(the)i(uncoarsening)e(phase.)45 b(During)0 1136 -y(coarsening,)19 b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 -b FL(emplo)o(ys)19 b(algorithms)f(that)h(mak)o(e)g(it)h(easier)g(to)f -(\002nd)g(a)h(high-quality)d(partition)h(at)i(the)f(coarsest)h(graph.)j -(During)0 1246 y(re\002nement,)h Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)28 b FL(focuses)23 b(primarily)e(on)i(the)h(portion)d(of)i -(the)g(graph)f(that)i(is)g(close)f(to)h(the)f(partition)f(boundary)-5 -b(.)31 b(These)23 b(highly)0 1355 y(tuned)c(algorithms)g(allo)n(w)j -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(to)20 b(quickly)f(produce) -f(high-quality)g(partitions)h(for)h(a)g(lar)o(ge)g(v)n(ariety)f(of)h -(graphs.)450 2607 y @beginspecial 0 @llx 0 @lly 1129 -@urx 433 @ury 3600 @rwi @setspecial -%%BeginDocument: ./figures/slide78.eps -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {} def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save --48.0 455.0 translate -1 -1 scale - -/clp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/l {lineto} bind def -/m {moveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit - 0.06000 0.06000 sc -% Polyline -% -% Begin Imported EPS File: slide7.eps -% -n gs -825 1606 tr -15.284974 -15.278970 sc -0 -233 tr --35 -330 tr -save -/showpage {} def -% EPS file follows: - - - - - - - - - - - - - - - -/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2 - -copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch - -currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put - -end}bind readonly def/findresource{userdict/Resources get exch get exch get} - -bind readonly def/resourceforall{pop pop pop pop}bind readonly def - -/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch - -known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false - -}ifelse}bind readonly def end}ifelse - - - -/Pscript_Win_Driver 200 dict dup begin - - -/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div - -cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def - - -/VM? {vmstatus exch sub exch pop gt { [ - -(This job requires more memory than is available in this printer.) 100 500 - -(Try one or more of the following, and then print again:) 100 485 - -(In the PostScript dialog box, click Optimize For Portability.) 115 470 - -(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455 - -(Reduce the number of fonts in the document.) 115 440 - -(Print the document in parts.) 115 425 - -12 /Times-Roman showpage - -(%%[ PrinterError: Low Printer VM ]%%) = - -true FatalErrorIf}if} bind def - - -/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^ - -/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/- - -/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true , - -|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , | - -/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto , - -|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin - -, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow , - -|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld - -/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2 - -ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b - -/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El ! - -}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{ - -self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ | - -/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put - -/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{ - -exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{ - -transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b - -/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict - -/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[] - -0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0 - --}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b - - - -L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $ - -@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{ - -4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{ - -setrgbcolor}b/sgco{{sg}{sco}?}b}e - - - -L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}? - -setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5 - -}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $ - -idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg - -{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg - -}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering - -defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! ! - -/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering - -resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}? - -findresource setcolorrendering}b}e - - - -/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron - -/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18 - -bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase - -/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron - -/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright - -/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets - -/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section - -/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered - -/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph - -/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter - -/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis - -/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute - -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis - -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls - -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute - -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve - -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex - -/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave - -put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153 - -154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253 - -254]{/bullet put @}forall 166/bar put 176/ring put - - - -/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T | - -/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null | - -/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add - -dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding - -ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld} - -if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{ - -ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get - -StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? ` - -/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0 - -put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont - -Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font - -3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M - -currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP - -uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b - -/sRxy{: matrix astore concat 0 0 M}b/eR/; , | - - - -/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0 - -FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 | - -/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or & - -/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E - -definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^ - -/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM - -astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2 - -copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF - -mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get - -Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{ - -: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{: - -Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b - -/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D - -; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName - -~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b - - - -/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{ - -SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null | - -/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 | - -/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]| - -/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null | - -/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b - -/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep - -XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8 - -Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag - -{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps - -mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M - -MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E - -/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix - -GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal - -makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{ - -/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross - -makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}? - -|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 | - -/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0 - -Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload ! - -sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if} - -}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask - -Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $ - -/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E - -CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b - -/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{ - -/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict ` - -YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix - -currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E - -dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An - -C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2 - -~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2 - -rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~ - -|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0 - -0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b - - - -L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq - -and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}? - --1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}? - -}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp - -C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T - -hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ | - -pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint - -strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy ` - -/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr - -length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1 - -255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox | - -/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec - -;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix - -PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $ - -PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^ - -sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b - -/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^ - -M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr - -S}repeat YStep add M}repeat ! ! ! ! E}b}e - - - -L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{ - -setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern - -K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{ - -pfprep setpattern K restore N}b}e - - - -/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc - -0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b - -/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b - -/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b - -/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}| - -/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 | - -/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc - -/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc - -]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , | - -L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~ - -string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ , - -| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring - -~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ ` - -/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]| - -/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b - - - -L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b - -/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0 - -0 ih 0 0]s imagemask}b}e - - - -L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage - -where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{ - -/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E - -| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict - -/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and - -and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{ - -/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut - -~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @ - -currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @ - -3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{ - -1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~ - -|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut - -ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute} - -concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub | - -/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut - -rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255 - -V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @ - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc - -T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{ - -cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b - -/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3 - -idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut - -1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x - -defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @ - -rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor - -currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut - -stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | ! - -invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc - -nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval - -putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a - -byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a - -byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3 - -copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~ - -mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3 - -createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12 - -createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand - -,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8 - -[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length - -|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2 - -len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul - -gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0 - -smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec - -,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s - -image}?}b}e - - - -L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[ - -/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw | - -/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s | - -/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{ - -/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK - -hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 - -hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc | - -/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}? - -setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1 - -0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent - -bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{ - -/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0 - -1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 | - -/Interpolate smoothflag | E image}b}e - - - -/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~ - -|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict | - -CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar - -{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict - -/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get - -CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put - -CharProcs 3 1 $ put Metrics 3 1 $ put E}| - - - -/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{ - -/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~ - -putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ | - -/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding - -256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| & - -E currentfile eexec}bind | - - -/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length - -ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add | - -DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC - -257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{ - -mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 | - -/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC - -~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss - -readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring ! - -0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop - -mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b - -/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b - - -userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def - -}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{ - -/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix - -invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3 - -/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10 - -/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar - -130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135 - -/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE - -145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150 - -/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156 - -/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar - -167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172 - -/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178 - -/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183 - -/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187 - -/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown - -192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198 - -/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204 - -/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve - -211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash - -217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223 - -/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229 - -/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis - -236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242 - -/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248 - -/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254 - -/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{ - -pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def - -/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate - -load def/resume/initialize load def/M/moveto load def end put/Courier findfont - -10 scalefont setfont - - -end /ProcSet defineresource pop - - - - - - -Pscript_Win_Compat dup /initialize get exec - -[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec - - - - - -/mysetup [ 0.240 0 0 -0.240 8.880 592.800 ] | - - - - - - -userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; - - - - - - -114 70 N M 1 1 rr - -114 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; - -114 70 N M 1 1 rr - -114 70 N M 1 1 rr - -114 70 N M 2401 1026 rr : 0.800 1.000 0.800 sco O ; 1 Lw 0 Lc 0 Lj solid 0.800 1.000 0.800 sco K - -234 176 N M 2131 295 rr : 114 70 3000 2250 rc 0.647 0 0.129 sco %%IncludeFont: Helvetica-Bold - -(F0) cvn - -0.960 - - (Helvetica-Bold) cvn /Type1 - -T - -(Helvetica-Bold) cvn - -mF - -(F0_100) cvn - -F0 - -100 - -xF - -F0_100 - -Ji - -264 193 M - --0.100 0 (T)A - -0.100 0 (r)A - -0.400 0 (a)A - --0.100 0 (d)A - --0.800 0 (i)A - -0.700 0 (t)A - --0.800 0 (i)A - --0.100 0 (on)A - -0.400 0 (a)A - -1.000 0 32 -0.800 0 (l )D - --0.100 0 (p)A - -0.400 0 (a)A - -0.100 0 (r)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.100 0 (o)A - --1.100 0 (n)A - -0.200 0 (i)A - -0.300 0 32 -0.100 0 (ng )D - --0.600 0 (a)A - -0.200 0 (l)A - --0.100 0 (go)A - -0.100 0 (r)A - --0.800 0 (i)A - -0.700 0 (t)A - --0.100 0 (h)A - -0.100 0 (m)A - -0.800 0 32 -0.600 0 (s )D - -0.400 0 (c)A - --0.100 0 (o)A - -0.100 0 (m)A - --0.100 0 (pu)A - --0.300 0 (t)A - -0.400 0 (e)A - -; : 114 70 3000 2250 rc 0.647 0 0.129 sco F0_100 - -Ji - -339 336 M - --1.200 0 32 0.400 0 (a )D - --0.100 0 (p)A - -0.400 0 (a)A - -0.100 0 (r)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.700 0 32 -0.100 0 (on d)D - -0.200 0 (i)A - -0.100 0 (r)A - -0.400 0 (e)A - --0.600 0 (c)A - -0.700 0 (t)A - --0.800 0 (l)A - --0.200 0 32 0.400 0 (y )D - --0.700 0 32 -0.100 0 (on )D - --0.300 0 (t)A - --0.100 0 (h)A - --0.200 0 32 0.400 0 (e )D - --0.100 0 (o)A - -0.100 0 (r)A - --0.800 0 (i)A - --0.100 0 (g)A - -0.200 0 (i)A - --0.100 0 (n)A - -0.400 0 (a)A - -1.000 0 32 -0.800 0 (l )D - --0.100 0 (g)A - -0.100 0 (r)A - --0.600 0 (a)A - --0.100 0 (ph)A - -0.700 0 (!)A - -; - -428 664 N M -7 1 - -9 0 - -20 1 - -22 1 - -23 1 - -23 3 - -21 5 - -9 3 - -8 5 - -7 5 - -6 6 - -4 8 - -4 8 - -3 11 - -2 11 - -2 25 - 0 26 - 2 27 - 3 27 - 5 23 - 2 11 - 3 9 - 7 17 - 9 15 - 11 14 - 12 13 - 13 10 - 14 10 - 13 8 - 14 6 - 14 5 - 16 4 - 17 2 - 17 1 - 17 -1 - 16 -2 - 14 -4 - 13 -5 - 6 -3 - 5 -5 - 9 -11 - 8 -13 - 7 -14 - 6 -14 - 7 -14 - 7 -11 - 3 -4 - 4 -4 - 7 -4 - 7 -2 - 5 -1 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -1 - 20 -2 - 21 -1 - 21 0 - 21 0 - 21 1 - 18 3 - 9 3 - 9 4 - 17 10 - 17 12 - 16 12 - 16 11 - 7 5 - 7 4 - 7 2 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -5 - 5 -7 - 6 -9 - 5 -9 - 5 -11 - 10 -22 - 8 -24 - 6 -24 - 4 -22 - 1 -9 - 0 -9 - -1 -14 - -4 -13 - -5 -12 - -7 -11 - -10 -11 - -10 -10 - -12 -11 - -13 -11 - -14 -12 - -17 -14 - -17 -14 - -20 -14 - -20 -13 - -22 -11 - -22 -9 - -23 -6 - -12 -1 - -13 -1 - -29 1 - -31 4 - -31 5 - -31 6 - -27 7 - -13 3 - -11 2 - -10 3 - -9 2 - -7 2 - -5 2 - -5 3 - -3 2 - -4 4 - -1 5 - 0 4 - 0 4 - -2 3 - -4 2 - -5 1 - -6 0 - -12 -1 - -7 -1 - -9 0 - -11 0 - -12 1 - C : 0.502 0.502 0.502 sco O ; - -420 656 N M -7 1 - -9 0 - -20 1 - -22 1 - -23 1 - -23 3 - -21 5 - -9 3 - -8 5 - -7 5 - -6 6 - -4 8 - -4 8 - -3 11 - -2 11 - -3 24 - 0 27 - 2 27 - 4 26 - 4 24 - 3 11 - 3 9 - 7 17 - 9 15 - 11 13 - 12 13 - 13 11 - 13 9 - 14 8 - 14 7 - 14 5 - 16 3 - 17 3 - 17 0 - 17 0 - 16 -3 - 14 -3 - 13 -5 - 6 -3 - 5 -5 - 9 -11 - 8 -13 - 7 -15 - 6 -14 - 7 -13 - 7 -11 - 3 -5 - 4 -3 - 7 -5 - 6 -2 - 6 0 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -1 - 20 -2 - 20 -1 - 22 0 - 21 0 - 20 1 - 19 3 - 9 3 - 8 3 - 17 10 - 17 12 - 17 12 - 15 12 - 8 4 - 7 4 - 7 3 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -6 - 5 -7 - 6 -8 - 5 -10 - 5 -10 - 10 -23 - 8 -24 - 6 -24 - 4 -21 - 1 -10 - 0 -8 - -1 -14 - -4 -13 - -5 -12 - -7 -11 - -10 -11 - -10 -10 - -12 -11 - -13 -11 - -14 -12 - -17 -14 - -17 -14 - -20 -14 - -20 -13 - -22 -12 - -22 -8 - -23 -6 - -12 -1 - -13 -1 - -29 1 - -31 4 - -31 5 - -31 6 - -27 7 - -13 3 - -11 2 - -10 3 - -9 2 - -7 2 - -6 2 - -4 2 - -3 2 - -4 5 - -2 4 - 0 5 - 0 3 - -1 4 - -4 2 - -6 1 - -5 0 - -12 -1 - -8 -1 - -8 0 - -11 0 - -12 1 - C : 0.200 0.200 0.800 sco O ; - -1820 653 N M -7 1 - -9 0 - -20 1 - -22 1 - -23 1 - -23 3 - -21 5 - -9 4 - -8 4 - -7 6 - -6 6 - -4 8 - -4 9 - -3 11 - -2 11 - -2 26 - 0 27 - 2 28 - 3 28 - 5 24 - 2 11 - 3 10 - 7 17 - 9 16 - 11 14 - 12 13 - 13 11 - 14 10 - 13 8 - 14 7 - 15 5 - 16 4 - 16 2 - 17 1 - 17 -1 - 16 -2 - 14 -4 - 13 -5 - 6 -4 - 5 -4 - 9 -11 - 8 -14 - 7 -15 - 7 -15 - 6 -13 - 7 -12 - 3 -4 - 4 -4 - 7 -5 - 7 -2 - 5 0 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -2 - 20 -1 - 21 -1 - 22 -1 - 21 0 - 20 2 - 18 3 - 9 3 - 9 3 - 17 11 - 17 12 - 16 13 - 16 11 - 7 5 - 7 4 - 7 3 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -6 - 5 -7 - 6 -9 - 5 -10 - 5 -11 - 10 -23 - 8 -25 - 6 -25 - 4 -22 - 1 -10 - 0 -9 - -1 -15 - -3 -13 - -6 -12 - -7 -12 - -9 -11 - -11 -10 - -12 -11 - -13 -12 - -14 -13 - -17 -14 - -17 -15 - -20 -14 - -20 -13 - -22 -12 - -22 -9 - -23 -6 - -12 -2 - -13 0 - -29 1 - -31 3 - -31 6 - -30 6 - -28 7 - -13 3 - -11 3 - -10 3 - -9 2 - -7 2 - -5 2 - -5 3 - -3 2 - -4 5 - -1 4 - 0 5 - 0 3 - -2 4 - -4 2 - -5 1 - -6 0 - -5 0 - -7 -1 - -7 -1 - -9 0 - -10 0 - -13 1 - C : 0.502 0.502 0.502 sco O ; - -1812 645 N M -7 1 - -9 0 - -20 1 - -22 0 - -23 2 - -23 3 - -21 5 - -9 3 - -8 5 - -7 5 - -6 7 - -4 8 - -4 9 - -3 10 - -2 12 - -2 25 - 0 28 - 2 28 - 3 27 - 2 13 - 3 12 - 2 10 - 3 10 - 7 17 - 9 16 - 11 14 - 12 13 - 13 11 - 14 10 - 13 8 - 14 7 - 14 5 - 16 4 - 17 2 - 17 1 - 17 -1 - 16 -2 - 14 -4 - 13 -5 - 6 -4 - 5 -4 - 9 -11 - 8 -14 - 7 -15 - 6 -15 - 7 -13 - 7 -12 - 3 -4 - 4 -4 - 7 -5 - 7 -2 - 5 0 - 6 1 - 7 2 - 8 2 - 10 1 - 12 1 - 15 0 - 18 -1 - 20 -2 - 21 -1 - 21 0 - 21 0 - 21 1 - 18 3 - 9 3 - 9 4 - 17 10 - 17 12 - 16 13 - 16 12 - 7 4 - 7 4 - 7 3 - 7 1 - 6 0 - 6 -2 - 6 -4 - 6 -6 - 5 -7 - 6 -9 - 5 -10 - 5 -10 - 10 -24 - 8 -25 - 6 -24 - 4 -22 - 1 -10 - 0 -9 - -1 -15 - -4 -14 - -5 -12 - -7 -11 - -10 -11 - -10 -11 - -12 -10 - -13 -12 - -14 -13 - -17 -14 - -17 -15 - -20 -14 - -20 -14 - -22 -11 - -22 -9 - -11 -4 - -12 -2 - -12 -2 - -13 0 - -29 1 - -31 3 - -31 6 - -31 6 - -27 7 - -13 3 - -11 3 - -10 3 - -9 2 - -7 2 - -5 2 - -5 2 - -3 2 - -4 5 - -1 5 - 0 4 - 0 4 - -2 3 - -4 3 - -5 1 - -6 0 - -12 -1 - -7 -1 - -9 -1 - -11 1 - -12 1 - C : 0.200 0.200 0.800 sco O ; - -N 1929 615.500 M 2 1 rr : 0 0 0 sco O ; - -N 1928 616.500 M 4 1 rr : 0 0 0 sco O ; - -N 1927 617.500 M 6 1 rr : 0 0 0 sco O ; - -N 1926 618.500 M 8 1 rr : 0 0 0 sco O ; - -N 1927 619.500 M 8 1 rr : 0 0 0 sco O ; - -N 1928 620.500 M 8 1 rr : 0 0 0 sco O ; - -N 1929 621.500 M 7 1 rr : 0 0 0 sco O ; - -N 1930 622.500 M 7 1 rr : 0 0 0 sco O ; - -N 1931 623.500 M 7 1 rr : 0 0 0 sco O ; - -N 1931 624.500 M 8 1 rr : 0 0 0 sco O ; - -N 1932 625.500 M 8 1 rr : 0 0 0 sco O ; - -N 1933 626.500 M 8 1 rr : 0 0 0 sco O ; - -N 1934 627.500 M 8 1 rr : 0 0 0 sco O ; - -N 1935 628.500 M 8 1 rr : 0 0 0 sco O ; - -N 1936 629.500 M 9 1 rr : 0 0 0 sco O ; - -N 1937 630.500 M 9 1 rr : 0 0 0 sco O ; - -N 1938 631.500 M 9 1 rr : 0 0 0 sco O ; - -N 1940 632.500 M 8 1 rr : 0 0 0 sco O ; - -N 1941 633.500 M 8 1 rr : 0 0 0 sco O ; - -N 1942 634.500 M 8 1 rr : 0 0 0 sco O ; - -N 1943 635.500 M 8 1 rr : 0 0 0 sco O ; - -N 1944 636.500 M 8 1 rr : 0 0 0 sco O ; - -N 1945 637.500 M 8 1 rr : 0 0 0 sco O ; - -N 1946 638.500 M 7 1 rr : 0 0 0 sco O ; - -N 1947 639.500 M 7 1 rr : 0 0 0 sco O ; - -N 1948 640.500 M 7 1 rr : 0 0 0 sco O ; - -N 1948 641.500 M 8 1 rr : 0 0 0 sco O ; - -N 1949 642.500 M 8 1 rr : 0 0 0 sco O ; - -N 1950 643.500 M 8 1 rr : 0 0 0 sco O ; - -N 1951 644.500 M 8 1 rr : 0 0 0 sco O ; - -N 1952 645.500 M 8 1 rr : 0 0 0 sco O ; - -N 1953 646.500 M 7 1 rr : 0 0 0 sco O ; - -N 1954 647.500 M 7 1 rr : 0 0 0 sco O ; - -N 1955 648.500 M 7 1 rr : 0 0 0 sco O ; - -N 1955 649.500 M 8 1 rr : 0 0 0 sco O ; - -N 1956 650.500 M 8 1 rr : 0 0 0 sco O ; - -N 1957 651.500 M 8 1 rr : 0 0 0 sco O ; - -N 1958 652.500 M 7 1 rr : 0 0 0 sco O ; - -N 1959 653.500 M 7 1 rr : 0 0 0 sco O ; - -N 1960 654.500 M 7 1 rr : 0 0 0 sco O ; - -N 1960 655.500 M 8 1 rr : 0 0 0 sco O ; - -N 1961 656.500 M 7 1 rr : 0 0 0 sco O ; - -N 1962 657.500 M 7 1 rr : 0 0 0 sco O ; - -N 1963 658.500 M 7 1 rr : 0 0 0 sco O ; - -N 1963 659.500 M 8 1 rr : 0 0 0 sco O ; - -N 1964 660.500 M 7 1 rr : 0 0 0 sco O ; - -N 1965 661.500 M 7 1 rr : 0 0 0 sco O ; - -N 1966 662.500 M 7 1 rr : 0 0 0 sco O ; - -N 1966 663.500 M 8 1 rr : 0 0 0 sco O ; - -N 1967 664.500 M 7 1 rr : 0 0 0 sco O ; - -N 1968 665.500 M 7 1 rr : 0 0 0 sco O ; - -N 1969 666.500 M 7 1 rr : 0 0 0 sco O ; - -N 1969 667.500 M 7 1 rr : 0 0 0 sco O ; - -N 1971 668.500 M 6 1 rr : 0 0 0 sco O ; - -N 1971 669.500 M 6 1 rr : 0 0 0 sco O ; - -N 1972 670.500 M 6 1 rr : 0 0 0 sco O ; - -N 1972 671.500 M 6 1 rr : 0 0 0 sco O ; - -N 1973 672.500 M 6 1 rr : 0 0 0 sco O ; - -N 1973 673.500 M 6 1 rr : 0 0 0 sco O ; - -N 1974 674.500 M 6 1 rr : 0 0 0 sco O ; - -N 1974 675.500 M 6 1 rr : 0 0 0 sco O ; - -N 1974 676.500 M 7 1 rr : 0 0 0 sco O ; - -N 1975 677.500 M 6 1 rr : 0 0 0 sco O ; - -N 1975 678.500 M 7 1 rr : 0 0 0 sco O ; - -N 1976 679.500 M 6 1 rr : 0 0 0 sco O ; - -N 1976 680.500 M 7 1 rr : 0 0 0 sco O ; - -N 1977 681.500 M 6 1 rr : 0 0 0 sco O ; - -N 1977 682.500 M 7 1 rr : 0 0 0 sco O ; - -N 1978 683.500 M 6 1 rr : 0 0 0 sco O ; - -N 1978 684.500 M 7 1 rr : 0 0 0 sco O ; - -N 1979 685.500 M 6 1 rr : 0 0 0 sco O ; - -N 1979 686.500 M 7 1 rr : 0 0 0 sco O ; - -N 1980 687.500 M 6 1 rr : 0 0 0 sco O ; - -N 1980 688.500 M 7 1 rr : 0 0 0 sco O ; - -N 1981 689.500 M 6 1 rr : 0 0 0 sco O ; - -N 1981 690.500 M 7 1 rr : 0 0 0 sco O ; - -N 1982 691.500 M 6 1 rr : 0 0 0 sco O ; - -N 1982 692.500 M 7 1 rr : 0 0 0 sco O ; - -N 1983 693.500 M 6 1 rr : 0 0 0 sco O ; - -N 1983 694.500 M 6 1 rr : 0 0 0 sco O ; - -N 1983 695.500 M 7 1 rr : 0 0 0 sco O ; - -N 1984 696.500 M 6 1 rr : 0 0 0 sco O ; - -N 1984 697.500 M 7 1 rr : 0 0 0 sco O ; - -N 1985 698.500 M 6 1 rr : 0 0 0 sco O ; - -N 1985 699.500 M 7 1 rr : 0 0 0 sco O ; - -N 1986 700.500 M 6 1 rr : 0 0 0 sco O ; - -N 1986 701.500 M 7 1 rr : 0 0 0 sco O ; - -N 1987 702.500 M 6 1 rr : 0 0 0 sco O ; - -N 1987 703.500 M 6 1 rr : 0 0 0 sco O ; - -N 1987 704.500 M 7 1 rr : 0 0 0 sco O ; - -N 1988 705.500 M 6 1 rr : 0 0 0 sco O ; - -N 1988 706.500 M 7 1 rr : 0 0 0 sco O ; - -N 1989 707.500 M 6 1 rr : 0 0 0 sco O ; - -N 1989 708.500 M 7 1 rr : 0 0 0 sco O ; - -N 1990 709.500 M 6 1 rr : 0 0 0 sco O ; - -N 1990 710.500 M 6 1 rr : 0 0 0 sco O ; - -N 1990 711.500 M 7 1 rr : 0 0 0 sco O ; - -N 1991 712.500 M 6 1 rr : 0 0 0 sco O ; - -N 1991 713.500 M 7 1 rr : 0 0 0 sco O ; - -N 1992 714.500 M 6 1 rr : 0 0 0 sco O ; - -N 1992 715.500 M 7 1 rr : 0 0 0 sco O ; - -N 1993 716.500 M 6 1 rr : 0 0 0 sco O ; - -N 1993 717.500 M 7 1 rr : 0 0 0 sco O ; - -N 1994 718.500 M 6 1 rr : 0 0 0 sco O ; - -N 1994 719.500 M 7 1 rr : 0 0 0 sco O ; - -N 1995 720.500 M 6 1 rr : 0 0 0 sco O ; - -N 1995 721.500 M 7 1 rr : 0 0 0 sco O ; - -N 1996 722.500 M 6 1 rr : 0 0 0 sco O ; - -N 1996 723.500 M 7 1 rr : 0 0 0 sco O ; - -N 1997 724.500 M 6 1 rr : 0 0 0 sco O ; - -N 1997 725.500 M 7 1 rr : 0 0 0 sco O ; - -N 1998 726.500 M 6 1 rr : 0 0 0 sco O ; - -N 1998 727.500 M 7 1 rr : 0 0 0 sco O ; - -N 1999 728.500 M 6 1 rr : 0 0 0 sco O ; - -N 1999 729.500 M 7 1 rr : 0 0 0 sco O ; - -N 2000 730.500 M 6 1 rr : 0 0 0 sco O ; - -N 2000 731.500 M 7 1 rr : 0 0 0 sco O ; - -N 2001 732.500 M 6 1 rr : 0 0 0 sco O ; - -N 2001 733.500 M 6 1 rr : 0 0 0 sco O ; - -N 2001 734.500 M 7 1 rr : 0 0 0 sco O ; - -N 2002 735.500 M 6 1 rr : 0 0 0 sco O ; - -N 2002 736.500 M 7 1 rr : 0 0 0 sco O ; - -N 2003 737.500 M 6 1 rr : 0 0 0 sco O ; - -N 2003 738.500 M 7 1 rr : 0 0 0 sco O ; - -N 2004 739.500 M 6 1 rr : 0 0 0 sco O ; - -N 2004 740.500 M 7 1 rr : 0 0 0 sco O ; - -N 2005 741.500 M 6 1 rr : 0 0 0 sco O ; - -N 2005 742.500 M 7 1 rr : 0 0 0 sco O ; - -N 2006 743.500 M 6 1 rr : 0 0 0 sco O ; - -N 2006 744.500 M 7 1 rr : 0 0 0 sco O ; - -N 2007 745.500 M 6 1 rr : 0 0 0 sco O ; - -N 2007 746.500 M 7 1 rr : 0 0 0 sco O ; - -N 2008 747.500 M 7 1 rr : 0 0 0 sco O ; - -N 2008 748.500 M 7 1 rr : 0 0 0 sco O ; - -N 2009 749.500 M 7 1 rr : 0 0 0 sco O ; - -N 2010 750.500 M 6 1 rr : 0 0 0 sco O ; - -N 2010 751.500 M 7 1 rr : 0 0 0 sco O ; - -N 2011 752.500 M 7 1 rr : 0 0 0 sco O ; - -N 2011 753.500 M 7 1 rr : 0 0 0 sco O ; - -N 2012 754.500 M 7 1 rr : 0 0 0 sco O ; - -N 2013 755.500 M 7 1 rr : 0 0 0 sco O ; - -N 2013 756.500 M 8 1 rr : 0 0 0 sco O ; - -N 2014 757.500 M 7 1 rr : 0 0 0 sco O ; - -N 2015 758.500 M 7 1 rr : 0 0 0 sco O ; - -N 2016 759.500 M 7 1 rr : 0 0 0 sco O ; - -N 2016 760.500 M 9 1 rr : 0 0 0 sco O ; - -N 2017 761.500 M 9 1 rr : 0 0 0 sco O ; - -N 2018 762.500 M 9 1 rr : 0 0 0 sco O ; - -N 2019 763.500 M 9 1 rr : 0 0 0 sco O ; - -N 2020 764.500 M 10 1 rr : 0 0 0 sco O ; - -N 2022 765.500 M 9 1 rr : 0 0 0 sco O ; - -N 2023 766.500 M 9 1 rr : 0 0 0 sco O ; - -N 2024 767.500 M 10 1 rr : 0 0 0 sco O ; - -N 2025 768.500 M 10 1 rr : 0 0 0 sco O ; - -N 2027 769.500 M 9 1 rr : 0 0 0 sco O ; - -N 2028 770.500 M 10 1 rr : 0 0 0 sco O ; - -N 2029 771.500 M 10 1 rr : 0 0 0 sco O ; - -N 2031 772.500 M 10 1 rr : 0 0 0 sco O ; - -N 2032 773.500 M 10 1 rr : 0 0 0 sco O ; - -N 2033 774.500 M 10 1 rr : 0 0 0 sco O ; - -N 2035 775.500 M 10 1 rr : 0 0 0 sco O ; - -N 2036 776.500 M 10 1 rr : 0 0 0 sco O ; - -N 2038 777.500 M 9 1 rr : 0 0 0 sco O ; - -N 2039 778.500 M 10 1 rr : 0 0 0 sco O ; - -N 2040 779.500 M 10 1 rr : 0 0 0 sco O ; - -N 2042 780.500 M 9 1 rr : 0 0 0 sco O ; - -N 2043 781.500 M 9 1 rr : 0 0 0 sco O ; - -N 2044 782.500 M 8 1 rr : 0 0 0 sco O ; - -N 2046 783.500 M 7 1 rr : 0 0 0 sco O ; - -N 2047 784.500 M 7 1 rr : 0 0 0 sco O ; - -N 2047 785.500 M 7 1 rr : 0 0 0 sco O ; - -N 2048 786.500 M 7 1 rr : 0 0 0 sco O ; - -N 2049 787.500 M 7 1 rr : 0 0 0 sco O ; - -N 2049 788.500 M 7 1 rr : 0 0 0 sco O ; - -N 2050 789.500 M 7 1 rr : 0 0 0 sco O ; - -N 2051 790.500 M 6 1 rr : 0 0 0 sco O ; - -N 2051 791.500 M 7 1 rr : 0 0 0 sco O ; - -N 2052 792.500 M 6 1 rr : 0 0 0 sco O ; - -N 2052 793.500 M 7 1 rr : 0 0 0 sco O ; - -N 2053 794.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 795.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 796.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 797.500 M 7 1 rr : 0 0 0 sco O ; - -N 2054 798.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 799.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 800.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 801.500 M 7 1 rr : 0 0 0 sco O ; - -N 2055 802.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 803.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 804.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 805.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 806.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 807.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 808.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 809.500 M 7 1 rr : 0 0 0 sco O ; - -N 2056 810.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 811.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 812.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 813.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 814.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 815.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 816.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 817.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 818.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 819.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 820.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 821.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 822.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 823.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 824.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 825.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 826.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 827.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 828.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 829.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 830.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 831.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 832.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 833.500 M 7 1 rr : 0 0 0 sco O ; - -N 2055 834.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 835.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 836.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 837.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 838.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 839.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 840.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 841.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 842.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 843.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 844.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 845.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 846.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 847.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 848.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 849.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 850.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 851.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 852.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 853.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 854.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 855.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 856.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 857.500 M 7 1 rr : 0 0 0 sco O ; - -N 2054 858.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 859.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 860.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 861.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 862.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 863.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 864.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 865.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 866.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 867.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 868.500 M 7 1 rr : 0 0 0 sco O ; - -N 2053 869.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 870.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 871.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 872.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 873.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 874.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 875.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 876.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 877.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 878.500 M 6 1 rr : 0 0 0 sco O ; - -1394 762 N M 0 22 - -257 0 - 0 46 - 257 0 - 0 23 - 86 -46 - -86 -45 - C : 0.502 0.502 0.502 sco O ; - -1386 753 N M 0 23 - -257 0 - 0 46 - 257 0 - 0 22 - 85 -45 - -85 -46 - C : 0 0.800 0.600 sco O ; - -LH - -pagesave restore - - - - - - - -/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec - -Pscript_Win_Compat dup /terminate get exec - - - -restore gr -% -% End Imported PIC File: slide7.eps -% -% Polyline -% -% Begin Imported EPS File: slide8.eps -% -n gs -9900 389 tr -15.269291 -15.269767 sc -0 -430 tr --35 -150 tr -save -/showpage {} def -% EPS file follows: - - - - - - - - - - - - - - - -/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2 - -copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch - -currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put - -end}bind readonly def/findresource{userdict/Resources get exch get exch get} - -bind readonly def/resourceforall{pop pop pop pop}bind readonly def - -/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch - -known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false - -}ifelse}bind readonly def end}ifelse - - - -/Pscript_Win_Driver 200 dict dup begin - - -/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div - -cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def - - -/VM? {vmstatus exch sub exch pop gt { [ - -(This job requires more memory than is available in this printer.) 100 500 - -(Try one or more of the following, and then print again:) 100 485 - -(In the PostScript dialog box, click Optimize For Portability.) 115 470 - -(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455 - -(Reduce the number of fonts in the document.) 115 440 - -(Print the document in parts.) 115 425 - -12 /Times-Roman showpage - -(%%[ PrinterError: Low Printer VM ]%%) = - -true FatalErrorIf}if} bind def - - -/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^ - -/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/- - -/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true , - -|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , | - -/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto , - -|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin - -, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow , - -|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld - -/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2 - -ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b - -/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El ! - -}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{ - -self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ | - -/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put - -/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{ - -exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{ - -transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b - -/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict - -/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[] - -0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0 - --}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b - - - -L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $ - -@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{ - -4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{ - -setrgbcolor}b/sgco{{sg}{sco}?}b}e - - - -L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}? - -setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5 - -}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $ - -idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg - -{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg - -}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering - -defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! ! - -/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering - -resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}? - -findresource setcolorrendering}b}e - - - -/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron - -/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18 - -bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase - -/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron - -/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright - -/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets - -/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section - -/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered - -/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph - -/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter - -/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis - -/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute - -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis - -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls - -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute - -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve - -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex - -/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave - -put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153 - -154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253 - -254]{/bullet put @}forall 166/bar put 176/ring put - - - -/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T | - -/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null | - -/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add - -dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding - -ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld} - -if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{ - -ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get - -StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? ` - -/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0 - -put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont - -Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font - -3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M - -currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP - -uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b - -/sRxy{: matrix astore concat 0 0 M}b/eR/; , | - - - -/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0 - -FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 | - -/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or & - -/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E - -definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^ - -/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM - -astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2 - -copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF - -mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get - -Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{ - -: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{: - -Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b - -/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D - -; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName - -~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b - - - -/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{ - -SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null | - -/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 | - -/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]| - -/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null | - -/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b - -/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep - -XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8 - -Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag - -{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps - -mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M - -MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E - -/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix - -GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal - -makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{ - -/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross - -makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}? - -|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 | - -/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0 - -Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload ! - -sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if} - -}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask - -Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $ - -/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E - -CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b - -/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{ - -/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict ` - -YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix - -currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E - -dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An - -C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2 - -~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2 - -rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~ - -|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0 - -0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b - - - -L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq - -and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}? - --1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}? - -}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp - -C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T - -hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ | - -pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint - -strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy ` - -/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr - -length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1 - -255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox | - -/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec - -;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix - -PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $ - -PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^ - -sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b - -/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^ - -M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr - -S}repeat YStep add M}repeat ! ! ! ! E}b}e - - - -L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{ - -setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern - -K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{ - -pfprep setpattern K restore N}b}e - - - -/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc - -0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b - -/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b - -/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b - -/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}| - -/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 | - -/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc - -/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc - -]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , | - -L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~ - -string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ , - -| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring - -~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ ` - -/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]| - -/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b - - - -L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b - -/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0 - -0 ih 0 0]s imagemask}b}e - - - -L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage - -where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{ - -/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E - -| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict - -/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and - -and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{ - -/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut - -~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @ - -currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @ - -3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{ - -1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~ - -|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut - -ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute} - -concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub | - -/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut - -rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255 - -V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @ - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc - -T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{ - -cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b - -/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3 - -idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut - -1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x - -defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @ - -rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor - -currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut - -stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | ! - -invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc - -nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval - -putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a - -byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a - -byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3 - -copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~ - -mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3 - -createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12 - -createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand - -,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8 - -[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length - -|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2 - -len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul - -gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0 - -smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec - -,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s - -image}?}b}e - - - -L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[ - -/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw | - -/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s | - -/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{ - -/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK - -hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 - -hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc | - -/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}? - -setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1 - -0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent - -bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{ - -/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0 - -1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 | - -/Interpolate smoothflag | E image}b}e - - - -/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~ - -|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict | - -CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar - -{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict - -/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get - -CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put - -CharProcs 3 1 $ put Metrics 3 1 $ put E}| - - - -/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{ - -/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~ - -putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ | - -/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding - -256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| & - -E currentfile eexec}bind | - - -/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length - -ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add | - -DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC - -257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{ - -mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 | - -/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC - -~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss - -readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring ! - -0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop - -mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b - -/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b - - -userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def - -}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{ - -/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix - -invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3 - -/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10 - -/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar - -130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135 - -/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE - -145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150 - -/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156 - -/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar - -167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172 - -/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178 - -/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183 - -/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187 - -/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown - -192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198 - -/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204 - -/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve - -211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash - -217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223 - -/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229 - -/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis - -236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242 - -/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248 - -/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254 - -/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{ - -pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def - -/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate - -load def/resume/initialize load def/M/moveto load def end put/Courier findfont - -10 scalefont setfont - - -end /ProcSet defineresource pop - - - - - - -Pscript_Win_Compat dup /initialize get exec - -[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec - - - - - -/mysetup [ 0.240 0 0 -0.240 8.880 592.800 ] | - - - - - - -userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; - - - - - - -114 70 N M 1 1 rr - -114 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; - -114 70 N M 1 1 rr - -114 70 N M 1 1 rr : 114 70 3000 2250 rc - -114 70 N M 2726 1801 rr : 0.800 1.000 0.800 sco O ; 3 Lw 0 Lc 0 Lj solid 0.800 1.000 0.800 sco K ; - -1901 491 N M -7 1 - -7 0 - -18 0 - -19 1 - -21 1 - -20 2 - -18 4 - -9 3 - -7 4 - -6 5 - -5 5 - -4 6 - -3 8 - -2 9 - -2 9 - -2 22 - 0 23 - 2 23 - 2 23 - 4 20 - 3 9 - 2 8 - 6 14 - 8 14 - 10 11 - 10 11 - 12 10 - 12 8 - 12 7 - 12 5 - 13 5 - 14 3 - 15 2 - 15 1 - 14 -1 - 15 -2 - 13 -3 - 11 -5 - 9 -7 - 8 -9 - 7 -11 - 6 -13 - 6 -12 - 6 -11 - 6 -10 - 6 -7 - 7 -4 - 5 -1 - 5 -1 - 6 1 - 6 2 - 7 1 - 8 1 - 11 1 - 13 0 - 16 -1 - 18 -1 - 18 -1 - 19 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 3 - 16 9 - 14 11 - 15 10 - 13 10 - 13 7 - 6 3 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -6 - 5 -8 - 9 -17 - 9 -20 - 7 -20 - 5 -21 - 4 -18 - 1 -9 - 0 -7 - -1 -12 - -3 -11 - -5 -11 - -6 -9 - -9 -9 - -9 -9 - -10 -9 - -12 -10 - -13 -11 - -14 -11 - -16 -12 - -17 -12 - -18 -12 - -19 -9 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -26 1 - -27 3 - -27 5 - -27 5 - -25 6 - -11 2 - -10 3 - -8 2 - -8 2 - -6 2 - -5 2 - -4 1 - -3 2 - -3 4 - -1 4 - 0 4 - 0 3 - -2 3 - -3 2 - -5 1 - -5 0 - -11 -1 - -6 -1 - -8 -1 - -9 1 - -11 1 - C : 0.502 0.502 0.502 sco O ; - -1893 482 N M -7 1 - -7 0 - -18 1 - -19 1 - -21 1 - -20 2 - -18 4 - -9 3 - -7 4 - -6 5 - -5 5 - -4 6 - -3 8 - -3 9 - -2 9 - -2 22 - 0 23 - 2 23 - 3 23 - 4 20 - 2 9 - 3 8 - 6 14 - 8 14 - 10 11 - 10 11 - 12 10 - 12 8 - 12 7 - 12 5 - 13 4 - 14 3 - 14 2 - 15 1 - 15 -1 - 14 -2 - 13 -3 - 11 -4 - 10 -7 - 8 -9 - 7 -12 - 6 -12 - 6 -12 - 6 -12 - 6 -9 - 6 -7 - 6 -4 - 6 -1 - 5 -1 - 5 1 - 6 2 - 7 1 - 9 1 - 11 1 - 13 0 - 16 -1 - 17 -1 - 19 -1 - 18 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 3 - 16 9 - 14 10 - 15 11 - 14 10 - 13 7 - 6 2 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -6 - 5 -7 - 9 -18 - 8 -19 - 7 -21 - 5 -20 - 4 -19 - 1 -8 - 0 -7 - -1 -13 - -3 -11 - -5 -10 - -6 -9 - -8 -9 - -9 -9 - -11 -9 - -11 -10 - -13 -11 - -14 -12 - -16 -12 - -17 -12 - -18 -11 - -19 -9 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -26 1 - -27 3 - -28 5 - -26 5 - -25 6 - -11 2 - -10 3 - -8 2 - -8 2 - -6 2 - -5 1 - -4 2 - -3 2 - -3 4 - -2 4 - 0 3 - 0 3 - -1 3 - -4 2 - -5 1 - -4 1 - -11 -2 - -6 0 - -8 -1 - -9 0 - -11 1 - C : 0.200 0.200 0.800 sco O ; - -2010 855 N M 62 -99 - 12 Lw 0 Lc 1 Lj solid 0 0.800 0.600 sco K - -2095 773 N M 5 -63 - -53 33 - 48 30 - C : 0 0.800 0.600 sco O ; - -1805 921 N M -11 1 - -14 1 - -15 0 - -16 1 - -16 2 - -14 4 - -12 5 - -4 4 - -4 4 - -3 5 - -3 6 - -3 15 - -2 17 - 0 18 - 1 19 - 3 18 - 3 16 - 4 14 - 5 12 - 6 10 - 7 9 - 8 9 - 18 14 - 19 10 - 10 4 - 11 2 - 11 2 - 12 0 - 12 0 - 10 -2 - 10 -2 - 9 -4 - 7 -5 - 6 -8 - 6 -9 - 5 -10 - 4 -10 - 5 -9 - 4 -8 - 5 -5 - 5 -3 - 4 -2 - 4 0 - 4 1 - 5 1 - 6 1 - 7 2 - 8 0 - 10 0 - 12 -1 - 14 -1 - 14 -1 - 29 0 - 14 1 - 13 2 - 12 4 - 11 7 - 12 8 - 11 9 - 10 7 - 10 6 - 5 2 - 5 1 - 4 -1 - 4 -1 - 4 -2 - 4 -4 - 4 -5 - 4 -6 - 7 -14 - 6 -15 - 6 -17 - 4 -16 - 3 -15 - 1 -12 - -1 -10 - -2 -9 - -4 -8 - -5 -8 - -6 -7 - -8 -7 - -17 -15 - -10 -9 - -11 -9 - -12 -10 - -13 -10 - -14 -8 - -15 -8 - -15 -6 - -16 -4 - -17 -1 - -20 0 - -21 3 - -21 3 - -21 4 - -19 5 - -16 4 - -7 2 - -6 1 - -5 1 - -3 2 - -6 3 - -2 3 - -1 3 - 0 5 - -1 3 - -3 1 - -4 1 - -4 0 - -8 -1 - -5 0 - -6 -1 - -7 0 - -8 1 - C : 0.502 0.502 0.502 sco O ; - -1796 913 N M -11 1 - -13 0 - -15 1 - -16 1 - -16 1 - -14 4 - -12 5 - -5 4 - -4 4 - -3 5 - -2 6 - -4 15 - -1 17 - 0 18 - 1 19 - 2 18 - 3 16 - 4 14 - 5 12 - 6 10 - 8 10 - 8 8 - 9 8 - 9 7 - 10 5 - 9 5 - 10 3 - 11 3 - 23 2 - 22 -2 - 10 -3 - 9 -3 - 7 -5 - 6 -8 - 6 -9 - 5 -10 - 4 -10 - 5 -10 - 4 -7 - 5 -6 - 5 -3 - 4 -1 - 4 0 - 4 0 - 5 1 - 5 2 - 7 1 - 8 0 - 10 0 - 13 -1 - 13 -1 - 14 -1 - 29 0 - 14 1 - 13 2 - 12 5 - 12 7 - 11 8 - 12 9 - 10 7 - 10 6 - 5 2 - 5 1 - 4 -1 - 4 -1 - 4 -3 - 4 -4 - 4 -4 - 3 -6 - 8 -14 - 6 -16 - 5 -16 - 4 -17 - 3 -14 - 1 -13 - -1 -10 - -2 -9 - -4 -8 - -5 -7 - -6 -7 - -7 -8 - -17 -15 - -10 -8 - -11 -10 - -12 -10 - -14 -9 - -14 -9 - -14 -8 - -15 -6 - -16 -4 - -17 -1 - -20 1 - -21 2 - -21 4 - -21 4 - -19 5 - -16 4 - -7 2 - -6 1 - -5 1 - -3 2 - -6 3 - -2 3 - -1 3 - 0 5 - -1 2 - -3 2 - -4 1 - -4 0 - -8 -1 - -5 -1 - -6 0 - -7 0 - -9 1 - C : 0.200 0.200 0.800 sco O ; - -1826 1255 N M 67 -96 - 0 0.800 0.600 sco K - -1915 1178 N M 8 -63 - -55 30 - 47 33 - C : 0 0.800 0.600 sco O ; - -1663 1307 N M -7 1 - -10 0 - -10 1 - -10 0 - -11 2 - -9 2 - -8 4 - -6 5 - -3 7 - -3 10 - -1 11 - 0 13 - 1 12 - 2 12 - 2 11 - 2 9 - 3 8 - 4 7 - 11 12 - 12 9 - 13 7 - 14 4 - 15 1 - 15 -1 - 6 -2 - 6 -2 - 5 -4 - 4 -5 - 4 -6 - 3 -6 - 3 -7 - 3 -6 - 3 -5 - 3 -4 - 3 -2 - 3 -1 - 6 0 - 6 2 - 5 1 - 5 0 - 7 0 - 8 -1 - 19 -1 - 19 0 - 10 1 - 8 1 - 8 3 - 8 5 - 15 11 - 7 5 - 6 4 - 6 2 - 6 -1 - 5 -5 - 5 -7 - 5 -9 - 5 -11 - 4 -11 - 2 -11 - 2 -10 - 1 -8 - -1 -7 - -1 -6 - -6 -10 - -9 -9 - -12 -10 - -14 -12 - -16 -13 - -10 -6 - -9 -5 - -11 -4 - -10 -3 - -11 -1 - -14 0 - -14 2 - -14 2 - -14 3 - -12 3 - -11 3 - -9 2 - -6 2 - -3 2 - -2 2 - 0 2 - 0 4 - -1 1 - -2 1 - -5 1 - -6 -1 - -7 0 - -4 0 - -6 0 - C : 0.502 0.502 0.502 sco O ; - -1655 1299 N M -7 1 - -10 0 - -10 0 - -10 1 - -11 1 - -9 2 - -8 4 - -6 5 - -4 8 - -2 10 - -1 11 - 0 12 - 1 13 - 1 12 - 3 11 - 2 9 - 3 8 - 4 6 - 11 12 - 12 10 - 12 7 - 14 4 - 16 1 - 15 -1 - 6 -2 - 6 -2 - 5 -4 - 4 -5 - 7 -13 - 3 -6 - 3 -6 - 3 -5 - 3 -4 - 3 -2 - 3 -1 - 5 0 - 7 2 - 5 1 - 5 0 - 7 0 - 8 -1 - 19 -1 - 19 0 - 18 2 - 8 3 - 8 5 - 15 11 - 7 5 - 6 3 - 6 2 - 6 -1 - 5 -4 - 5 -7 - 5 -9 - 4 -11 - 7 -22 - 1 -10 - 1 -8 - -1 -7 - -1 -6 - -6 -10 - -9 -10 - -11 -10 - -14 -12 - -16 -13 - -10 -6 - -9 -5 - -11 -4 - -10 -2 - -12 -1 - -13 0 - -14 2 - -14 2 - -14 3 - -13 3 - -10 3 - -9 2 - -6 2 - -3 2 - -2 2 - 0 2 - 0 4 - -1 1 - -2 1 - -5 1 - -6 -1 - -7 -1 - -4 1 - -6 0 - C : 0.200 0.200 0.800 sco O ; - -1611 1566 N M 85 -81 - 0 0.800 0.600 sco K - -1714 1508 N M 21 -59 - -60 18 - 39 41 - C : 0 0.800 0.600 sco O ; - -1410 1556 N M -4 1 - -6 0 - -13 1 - -12 2 - -5 2 - -4 3 - -2 5 - -1 6 - -1 15 - 1 15 - 2 7 - 1 6 - 5 9 - 6 7 - 8 6 - 8 4 - 8 3 - 10 1 - 9 -1 - 8 -3 - 3 -2 - 3 -3 - 4 -8 - 4 -8 - 2 -3 - 2 -2 - 3 -2 - 4 0 - 4 1 - 6 1 - 10 0 - 11 -1 - 12 0 - 11 1 - 5 2 - 5 3 - 10 7 - 4 3 - 5 2 - 3 1 - 4 -1 - 3 -3 - 3 -4 - 3 -5 - 3 -7 - 4 -14 - 1 -6 - 0 -5 - -1 -8 - -4 -7 - -5 -6 - -7 -6 - -9 -7 - -11 -8 - -11 -7 - -7 -2 - -6 -2 - -7 -1 - -9 1 - -17 2 - -9 2 - -8 2 - -7 1 - -5 1 - -4 1 - -2 2 - -1 1 - 0 1 - -1 3 - -1 1 - -3 1 - -3 -1 - -5 0 - -7 0 - C : 0.502 0.502 0.502 sco O ; - -1402 1548 N M -4 1 - -6 0 - -13 1 - -7 0 - -6 2 - -4 2 - -4 3 - -2 5 - -2 6 - -1 7 - 0 7 - 2 16 - 1 6 - 2 6 - 4 9 - 7 8 - 7 6 - 8 4 - 9 2 - 10 1 - 9 -1 - 8 -2 - 3 -2 - 2 -4 - 4 -7 - 4 -8 - 2 -4 - 2 -2 - 4 -2 - 4 1 - 4 0 - 6 1 - 4 0 - 5 0 - 12 -1 - 12 0 - 11 1 - 5 2 - 5 3 - 9 7 - 5 3 - 4 2 - 4 2 - 3 -1 - 3 -3 - 4 -4 - 3 -6 - 2 -6 - 4 -14 - 2 -6 - 0 -5 - -1 -8 - -4 -7 - -6 -6 - -7 -6 - -9 -8 - -10 -8 - -12 -7 - -6 -2 - -7 -2 - -7 -1 - -8 1 - -18 2 - -9 2 - -8 2 - -7 2 - -5 1 - -3 1 - -2 2 - -1 1 - -1 1 - 0 3 - -1 1 - -3 1 - -4 -1 - -5 0 - -6 0 - C : 0.200 0.200 0.800 sco O ; - -1190 1427 N M 83 83 - 0 0.800 0.600 sco K - -1250 1528 N M 60 20 - -19 -60 - -41 40 - C : 0 0.800 0.600 sco O ; - -693 492 N M -7 1 - -7 0 - -18 1 - -19 1 - -21 1 - -20 2 - -18 4 - -8 3 - -7 4 - -6 5 - -5 5 - -4 7 - -3 8 - -3 9 - -2 9 - -2 22 - 0 24 - 2 24 - 3 23 - 4 21 - 2 9 - 3 8 - 6 15 - 8 13 - 9 13 - 11 11 - 11 9 - 13 9 - 12 6 - 12 6 - 13 5 - 13 3 - 15 2 - 15 1 - 15 -1 - 14 -2 - 13 -3 - 11 -5 - 9 -7 - 8 -9 - 7 -12 - 7 -13 - 5 -12 - 6 -12 - 6 -10 - 7 -7 - 6 -4 - 6 -1 - 5 -1 - 5 1 - 6 2 - 7 1 - 8 1 - 11 1 - 13 0 - 16 -1 - 18 -1 - 18 -1 - 19 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 4 - 16 8 - 14 11 - 15 11 - 13 10 - 7 4 - 6 4 - 6 2 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -7 - 5 -7 - 9 -18 - 9 -20 - 7 -21 - 5 -21 - 4 -19 - 1 -8 - 0 -8 - -1 -13 - -3 -11 - -5 -10 - -6 -10 - -9 -9 - -9 -9 - -10 -10 - -12 -10 - -13 -11 - -14 -12 - -16 -12 - -17 -12 - -18 -12 - -19 -10 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -25 1 - -27 4 - -28 4 - -27 6 - -24 6 - -11 2 - -10 3 - -9 2 - -8 2 - -6 2 - -5 2 - -4 2 - -2 1 - -4 4 - -1 4 - 0 4 - 0 3 - -1 3 - -4 2 - -5 1 - -5 1 - -11 -2 - -6 0 - -8 -1 - -9 0 - -11 1 - C : 0.502 0.502 0.502 sco O ; - -685 484 N M -7 1 - -7 0 - -18 0 - -19 1 - -21 1 - -20 2 - -18 5 - -9 3 - -7 4 - -6 4 - -5 6 - -4 7 - -3 8 - -3 9 - -1 9 - -3 22 - 1 24 - 1 24 - 3 23 - 4 21 - 3 9 - 2 8 - 6 15 - 8 13 - 10 12 - 10 11 - 12 10 - 12 8 - 12 7 - 12 6 - 13 5 - 14 3 - 15 2 - 15 1 - 14 -1 - 15 -2 - 13 -3 - 11 -5 - 9 -7 - 8 -10 - 7 -11 - 6 -13 - 6 -13 - 6 -11 - 6 -10 - 6 -7 - 6 -4 - 6 -2 - 5 0 - 5 1 - 6 1 - 7 2 - 9 1 - 11 1 - 13 0 - 16 -1 - 17 -1 - 19 -1 - 18 -1 - 19 0 - 18 1 - 16 3 - 8 2 - 7 4 - 16 8 - 14 11 - 15 11 - 14 10 - 13 7 - 6 3 - 6 1 - 6 0 - 5 -2 - 5 -3 - 5 -5 - 5 -7 - 5 -7 - 9 -18 - 8 -20 - 7 -21 - 5 -21 - 4 -19 - 1 -9 - 0 -7 - -1 -13 - -3 -11 - -5 -11 - -6 -9 - -8 -10 - -9 -9 - -10 -9 - -12 -10 - -13 -11 - -14 -12 - -16 -12 - -17 -13 - -18 -11 - -19 -10 - -20 -8 - -20 -5 - -11 -1 - -11 -1 - -26 1 - -27 3 - -28 5 - -26 5 - -25 6 - -11 2 - -10 3 - -8 2 - -8 2 - -6 2 - -5 2 - -4 2 - -3 2 - -3 4 - -1 4 - 0 4 - 0 3 - -2 3 - -3 2 - -5 1 - -5 0 - -11 -1 - -6 -1 - -8 -1 - -9 1 - -11 1 - C : 0.200 0.200 0.800 sco O ; - -873 919 N M -10 1 - -13 0 - -15 0 - -15 1 - -15 2 - -13 3 - -12 5 - -4 4 - -4 4 - -3 5 - -2 6 - -4 14 - -1 16 - 0 17 - 1 18 - 2 17 - 3 16 - 4 13 - 5 11 - 5 10 - 7 9 - 8 8 - 18 13 - 18 9 - 10 3 - 10 3 - 22 2 - 21 -2 - 10 -3 - 8 -3 - 7 -5 - 6 -7 - 5 -9 - 5 -9 - 4 -9 - 5 -9 - 4 -7 - 5 -5 - 4 -3 - 4 -2 - 4 0 - 4 1 - 4 1 - 5 1 - 7 2 - 8 0 - 10 0 - 12 -1 - 13 -1 - 13 -1 - 28 0 - 13 1 - 12 2 - 12 4 - 11 6 - 11 8 - 11 8 - 10 7 - 10 6 - 9 2 - 4 0 - 4 -1 - 4 -2 - 3 -4 - 8 -10 - 6 -13 - 7 -15 - 5 -16 - 4 -15 - 2 -14 - 1 -12 - -1 -10 - -2 -8 - -4 -8 - -4 -7 - -6 -7 - -7 -7 - -16 -14 - -10 -8 - -10 -9 - -12 -9 - -13 -9 - -13 -9 - -14 -7 - -15 -6 - -15 -4 - -16 -1 - -19 1 - -20 2 - -21 4 - -20 4 - -18 4 - -16 4 - -6 2 - -6 1 - -5 1 - -3 1 - -5 3 - -3 3 - 0 3 - 0 5 - -1 2 - -3 2 - -7 1 - -8 -1 - -5 -1 - -6 0 - -7 0 - -8 1 - C : 0.502 0.502 0.502 sco O ; - -865 910 N M -11 1 - -12 1 - -15 0 - -15 1 - -15 2 - -13 3 - -12 5 - -4 4 - -4 4 - -3 5 - -2 6 - -4 13 - -1 17 - 0 17 - 1 18 - 2 17 - 3 15 - 4 13 - 5 11 - 5 10 - 7 9 - 8 8 - 18 14 - 18 9 - 9 3 - 10 3 - 22 2 - 22 -2 - 9 -3 - 9 -3 - 7 -5 - 6 -7 - 5 -9 - 5 -9 - 4 -10 - 4 -9 - 4 -7 - 5 -5 - 5 -3 - 4 -1 - 4 0 - 4 0 - 4 1 - 5 2 - 7 1 - 8 0 - 10 0 - 11 -1 - 13 -1 - 14 -1 - 28 0 - 13 1 - 12 2 - 12 4 - 11 7 - 11 8 - 11 8 - 10 7 - 9 6 - 9 2 - 4 0 - 4 -1 - 4 -2 - 4 -4 - 4 -5 - 3 -5 - 7 -14 - 6 -15 - 6 -15 - 4 -16 - 2 -14 - 1 -12 - -1 -9 - -2 -9 - -4 -8 - -4 -7 - -6 -6 - -7 -7 - -17 -14 - -9 -8 - -11 -9 - -11 -10 - -13 -9 - -13 -8 - -15 -7 - -14 -6 - -15 -4 - -17 -1 - -19 0 - -20 2 - -20 4 - -20 4 - -18 4 - -16 4 - -6 2 - -6 1 - -5 1 - -3 2 - -5 3 - -3 3 - 0 3 - 0 5 - -1 2 - -3 1 - -4 1 - -3 0 - -8 -1 - -5 0 - -6 -1 - -7 0 - -8 1 - C : 0.200 0.200 0.800 sco O ; - -828 722 N M 72 115 - 0 0.800 0.600 sco K - -874 851 N M 54 32 - -6 -62 - -48 30 - C : 0 0.800 0.600 sco O ; - -1099 1307 N M -7 1 - -9 0 - -10 0 - -10 1 - -11 1 - -9 2 - -8 4 - -6 5 - -4 8 - -2 9 - -1 12 - 0 12 - 1 12 - 1 12 - 3 11 - 2 9 - 3 8 - 4 6 - 11 12 - 12 9 - 12 7 - 14 4 - 15 1 - 15 -1 - 13 -4 - 5 -3 - 4 -5 - 7 -13 - 5 -12 - 4 -5 - 3 -4 - 3 -2 - 3 -1 - 5 0 - 7 2 - 4 1 - 6 0 - 7 0 - 8 -1 - 18 -1 - 19 0 - 10 1 - 8 1 - 8 3 - 8 4 - 8 5 - 8 6 - 7 5 - 6 4 - 6 2 - 6 -1 - 5 -4 - 5 -7 - 5 -9 - 4 -11 - 7 -22 - 1 -10 - 1 -8 - -1 -6 - -1 -6 - -6 -10 - -9 -10 - -11 -10 - -14 -12 - -17 -12 - -9 -6 - -10 -5 - -10 -4 - -11 -3 - -11 -1 - -14 0 - -14 2 - -14 2 - -13 3 - -13 3 - -11 3 - -8 2 - -6 2 - -3 2 - -2 2 - 0 2 - 0 4 - -1 1 - -2 1 - -5 1 - -6 -1 - -7 -1 - -5 1 - -6 0 - C : 0.502 0.502 0.502 sco O ; - -1091 1299 N M -7 1 - -9 0 - -10 0 - -11 0 - -10 2 - -10 2 - -7 4 - -6 5 - -4 7 - -2 10 - -1 11 - 0 12 - 0 12 - 2 12 - 2 11 - 3 9 - 3 8 - 4 6 - 10 12 - 12 10 - 13 7 - 14 4 - 15 1 - 15 -1 - 6 -2 - 6 -2 - 5 -4 - 4 -5 - 7 -13 - 3 -6 - 3 -6 - 3 -5 - 3 -4 - 3 -2 - 3 -1 - 6 0 - 7 2 - 4 1 - 6 0 - 7 0 - 8 -1 - 18 0 - 19 -1 - 10 1 - 8 1 - 8 3 - 8 5 - 15 11 - 7 5 - 6 3 - 6 2 - 6 -1 - 6 -4 - 5 -7 - 5 -9 - 4 -10 - 4 -11 - 3 -11 - 1 -10 - 1 -8 - -1 -7 - -1 -6 - -6 -10 - -9 -9 - -12 -10 - -14 -12 - -16 -13 - -10 -6 - -9 -5 - -11 -4 - -10 -2 - -11 -1 - -14 0 - -14 2 - -14 2 - -14 3 - -12 3 - -11 3 - -9 2 - -5 2 - -4 1 - -1 2 - -1 2 - 0 4 - -1 2 - -2 1 - -5 0 - -6 0 - -7 -1 - -4 0 - -6 1 - C : 0.200 0.200 0.800 sco O ; - -988 1085 N M 73 116 - 0 0.800 0.600 sco K - -1034 1214 N M 55 32 - -7 -62 - -48 30 - C : 0 0.800 0.600 sco O ; : 114 70 3000 2250 rc 0 0.400 0 sco %%IncludeFont: Helvetica-Bold - -(F0) cvn - -0.964 - - (Helvetica-Bold) cvn /Type1 - -T - -(Helvetica-Bold) cvn - -mF - -(F0_83) cvn - -F0 - -83 - -xF - -F0_83 - -Ji - --302.300 545 825 sR - -0.074 0 (C)A - -0.287 0 (o)A - -0.852 0 (a)A - --0.287 0 (r)A - --0.148 0 (s)A - -0.852 0 (e)A - -0.287 0 (n)A - --0.074 0 (i)A - --0.361 0 32 0.287 0 (ng )D - --0.361 0 (P)A - -1.287 0 (h)A - --0.148 0 (as)A - -0.852 0 (e)A - -eR - -; - -948 1648 N M 1227 151 rr : 114 70 3000 2250 rc 0 0.400 0 sco (F0_100) cvn - -F0 - -100 - -xF - -F0_100 - -Ji - -979 1664 M - -0.200 0 (I)A - --0.100 0 (n)A - --0.800 0 (i)A - --0.300 0 (t)A - -0.200 0 (i)A - -0.400 0 (a)A - -1.000 0 32 -0.800 0 (l )D - -0.300 0 (P)A - --0.600 0 (a)A - -0.100 0 (r)A - -0.700 0 (t)A - --0.800 0 (i)A - -0.700 0 (t)A - --0.800 0 (i)A - --0.100 0 (on)A - -0.200 0 (i)A - --0.700 0 32 -0.100 0 (ng )D - -0.300 0 (P)A - --0.100 0 (h)A - -0.400 0 (a)A - --0.600 0 (s)A - -0.400 0 (e)A - -; : 114 70 3000 2250 rc 0 0.400 0 sco F0_100 - -Ji - --60.400 2049 1326 sR - --0.200 0 (R)A - -0.400 0 (e)A - --0.300 0 (f)A - -0.200 0 (i)A - --0.100 0 (n)A - -0.400 0 (e)A - -0.100 0 (m)A - --0.600 0 (e)A - --0.100 0 (n)A - --1.500 0 32 0.700 0 (t )D - -0.300 0 (P)A - --0.100 0 (h)A - -0.400 0 (a)A - --0.600 0 (s)A - -0.400 0 (e)A - -eR - -; - -N 1425 1541.500 M 3 1 rr : 1.000 0 0 sco O ; - -N 1423 1542.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1422 1543.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1423 1544.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1424 1545.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1425 1546.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1426 1547.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1427 1548.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1428 1549.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1429 1550.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1430 1551.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1431 1552.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1433 1553.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1434 1554.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1435 1555.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1436 1556.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1437 1557.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1438 1558.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1439 1559.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1441 1560.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1442 1561.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1443 1562.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1444 1563.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1445 1564.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1446 1565.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1447 1566.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1448 1567.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1449 1568.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1449 1569.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1450 1570.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1450 1571.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1450 1572.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1450 1573.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1450 1574.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1450 1575.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1449 1576.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1449 1577.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1449 1578.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1449 1579.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1449 1580.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1448 1581.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1448 1582.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1448 1583.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1448 1584.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1448 1585.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1448 1586.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1449 1587.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1450 1588.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1449 1589.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1450 1590.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1451 1591.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1451 1592.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1452 1593.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1453 1594.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1453 1595.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1454 1596.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1455 1597.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1456 1598.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1457 1599.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1458 1600.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1459 1601.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1460 1602.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1461 1603.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1462 1604.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1464 1605.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1465 1606.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1466 1607.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1467 1608.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1469 1609.500 M 3 1 rr : 1.000 0 0 sco O ; - -N 1470 1610.500 M 2 1 rr : 1.000 0 0 sco O ; - -N 1690 1287.500 M 2 1 rr : 0 0 0 sco O ; - -N 1690 1288.500 M 3 1 rr : 0 0 0 sco O ; - -N 1689 1289.500 M 5 1 rr : 0 0 0 sco O ; - -N 1689 1290.500 M 6 1 rr : 0 0 0 sco O ; - -N 1688 1291.500 M 9 1 rr : 0 0 0 sco O ; - -N 1689 1292.500 M 9 1 rr : 0 0 0 sco O ; - -N 1690 1293.500 M 9 1 rr : 0 0 0 sco O ; - -N 1691 1294.500 M 10 1 rr : 0 0 0 sco O ; - -N 1692 1295.500 M 10 1 rr : 0 0 0 sco O ; - -N 1694 1296.500 M 9 1 rr : 0 0 0 sco O ; - -N 1695 1297.500 M 10 1 rr : 0 0 0 sco O ; - -N 1696 1298.500 M 10 1 rr : 0 0 0 sco O ; - -N 1698 1299.500 M 9 1 rr : 0 0 0 sco O ; - -N 1699 1300.500 M 9 1 rr : 0 0 0 sco O ; - -N 1700 1301.500 M 10 1 rr : 0 0 0 sco O ; - -N 1702 1302.500 M 9 1 rr : 0 0 0 sco O ; - -N 1703 1303.500 M 9 1 rr : 0 0 0 sco O ; - -N 1704 1304.500 M 9 1 rr : 0 0 0 sco O ; - -N 1705 1305.500 M 9 1 rr : 0 0 0 sco O ; - -N 1707 1306.500 M 8 1 rr : 0 0 0 sco O ; - -N 1708 1307.500 M 8 1 rr : 0 0 0 sco O ; - -N 1709 1308.500 M 8 1 rr : 0 0 0 sco O ; - -N 1710 1309.500 M 8 1 rr : 0 0 0 sco O ; - -N 1711 1310.500 M 8 1 rr : 0 0 0 sco O ; - -N 1712 1311.500 M 8 1 rr : 0 0 0 sco O ; - -N 1713 1312.500 M 8 1 rr : 0 0 0 sco O ; - -N 1714 1313.500 M 9 1 rr : 0 0 0 sco O ; - -N 1715 1314.500 M 9 1 rr : 0 0 0 sco O ; - -N 1716 1315.500 M 9 1 rr : 0 0 0 sco O ; - -N 1717 1316.500 M 9 1 rr : 0 0 0 sco O ; - -N 1718 1317.500 M 9 1 rr : 0 0 0 sco O ; - -N 1720 1318.500 M 8 1 rr : 0 0 0 sco O ; - -N 1721 1319.500 M 8 1 rr : 0 0 0 sco O ; - -N 1722 1320.500 M 8 1 rr : 0 0 0 sco O ; - -N 1723 1321.500 M 7 1 rr : 0 0 0 sco O ; - -N 1724 1322.500 M 7 1 rr : 0 0 0 sco O ; - -N 1725 1323.500 M 7 1 rr : 0 0 0 sco O ; - -N 1725 1324.500 M 8 1 rr : 0 0 0 sco O ; - -N 1726 1325.500 M 7 1 rr : 0 0 0 sco O ; - -N 1727 1326.500 M 7 1 rr : 0 0 0 sco O ; - -N 1728 1327.500 M 7 1 rr : 0 0 0 sco O ; - -N 1729 1328.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1329.500 M 7 1 rr : 0 0 0 sco O ; - -N 1730 1330.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1331.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1332.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1333.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1334.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1335.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1336.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1337.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1338.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1339.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1340.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1341.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1342.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1343.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1344.500 M 7 1 rr : 0 0 0 sco O ; - -N 1731 1345.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1346.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1347.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1348.500 M 6 1 rr : 0 0 0 sco O ; - -N 1731 1349.500 M 6 1 rr : 0 0 0 sco O ; - -N 1730 1350.500 M 7 1 rr : 0 0 0 sco O ; - -N 1730 1351.500 M 6 1 rr : 0 0 0 sco O ; - -N 1730 1352.500 M 6 1 rr : 0 0 0 sco O ; - -N 1730 1353.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1354.500 M 7 1 rr : 0 0 0 sco O ; - -N 1729 1355.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1356.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1357.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1358.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1359.500 M 6 1 rr : 0 0 0 sco O ; - -N 1729 1360.500 M 7 1 rr : 0 0 0 sco O ; - -N 1729 1361.500 M 7 1 rr : 0 0 0 sco O ; - -N 1730 1362.500 M 6 1 rr : 0 0 0 sco O ; - -N 1730 1363.500 M 7 1 rr : 0 0 0 sco O ; - -N 1731 1364.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1365.500 M 6 1 rr : 0 0 0 sco O ; - -N 1732 1366.500 M 6 1 rr : 0 0 0 sco O ; - -N 1733 1367.500 M 6 1 rr : 0 0 0 sco O ; - -N 1733 1368.500 M 7 1 rr : 0 0 0 sco O ; - -N 1733 1369.500 M 8 1 rr : 0 0 0 sco O ; - -N 1734 1370.500 M 8 1 rr : 0 0 0 sco O ; - -N 1735 1371.500 M 8 1 rr : 0 0 0 sco O ; - -N 1736 1372.500 M 8 1 rr : 0 0 0 sco O ; - -N 1737 1373.500 M 8 1 rr : 0 0 0 sco O ; - -N 1738 1374.500 M 9 1 rr : 0 0 0 sco O ; - -N 1739 1375.500 M 9 1 rr : 0 0 0 sco O ; - -N 1740 1376.500 M 9 1 rr : 0 0 0 sco O ; - -N 1741 1377.500 M 9 1 rr : 0 0 0 sco O ; - -N 1742 1378.500 M 9 1 rr : 0 0 0 sco O ; - -N 1744 1379.500 M 8 1 rr : 0 0 0 sco O ; - -N 1745 1380.500 M 8 1 rr : 0 0 0 sco O ; - -N 1746 1381.500 M 8 1 rr : 0 0 0 sco O ; - -N 1747 1382.500 M 8 1 rr : 0 0 0 sco O ; - -N 1748 1383.500 M 8 1 rr : 0 0 0 sco O ; - -N 1749 1384.500 M 8 1 rr : 0 0 0 sco O ; - -N 1750 1385.500 M 8 1 rr : 0 0 0 sco O ; - -N 1751 1386.500 M 8 1 rr : 0 0 0 sco O ; - -N 1752 1387.500 M 8 1 rr : 0 0 0 sco O ; - -N 1753 1388.500 M 8 1 rr : 0 0 0 sco O ; - -N 1754 1389.500 M 9 1 rr : 0 0 0 sco O ; - -N 1755 1390.500 M 9 1 rr : 0 0 0 sco O ; - -N 1756 1391.500 M 9 1 rr : 0 0 0 sco O ; - -N 1757 1392.500 M 9 1 rr : 0 0 0 sco O ; - -N 1758 1393.500 M 9 1 rr : 0 0 0 sco O ; - -N 1760 1394.500 M 6 1 rr : 0 0 0 sco O ; - -N 1761 1395.500 M 4 1 rr : 0 0 0 sco O ; - -N 1762 1396.500 M 2 1 rr : 0 0 0 sco O ; - -N 1726 1278.500 M 5 1 rr : 1.000 0 0 sco O ; - -N 1724 1279.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1725 1280.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1725 1281.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1726 1282.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1726 1283.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1727 1284.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1728 1285.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1729 1286.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1730 1287.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1730 1288.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1731 1289.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1732 1290.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1733 1291.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1733 1292.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1734 1293.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1735 1294.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1735 1295.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1736 1296.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1737 1297.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1737 1298.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1738 1299.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1738 1300.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1739 1301.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1739 1302.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1740 1303.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1740 1304.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1741 1305.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1741 1306.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1742 1307.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1742 1308.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1742 1309.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1743 1310.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1311.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1312.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1313.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1314.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1315.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1316.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1317.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1743 1318.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1742 1319.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1742 1320.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1742 1321.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1742 1322.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1741 1323.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1741 1324.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1740 1325.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1740 1326.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1738 1327.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1738 1328.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1737 1329.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1736 1330.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1736 1331.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1735 1332.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1734 1333.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1734 1334.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1733 1335.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1733 1336.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1732 1337.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1732 1338.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1731 1339.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1730 1340.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1730 1341.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1729 1342.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1729 1343.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1728 1344.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1728 1345.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1727 1346.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1726 1347.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1726 1348.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1725 1349.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1724 1350.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1724 1351.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1723 1352.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1722 1353.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1722 1354.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1721 1355.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1721 1356.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1720 1357.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1720 1358.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1719 1359.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1719 1360.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1719 1361.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1719 1362.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1363.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1364.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1365.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1366.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1367.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1368.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1369.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1370.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1371.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1372.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1718 1373.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1719 1374.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1719 1375.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1719 1376.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1720 1377.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1720 1378.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1721 1379.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1721 1380.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1722 1381.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1722 1382.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1723 1383.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1723 1384.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1724 1385.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1724 1386.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1725 1387.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1726 1388.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1726 1389.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1727 1390.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1728 1391.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1729 1392.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1729 1393.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1730 1394.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1731 1395.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1731 1396.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1731 1397.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1732 1398.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1732 1399.500 M 3 1 rr : 1.000 0 0 sco O ; - -N 1905 881.500 M 4 1 rr : 0 0 0 sco O ; - -N 1903 882.500 M 6 1 rr : 0 0 0 sco O ; - -N 1904 883.500 M 6 1 rr : 0 0 0 sco O ; - -N 1904 884.500 M 6 1 rr : 0 0 0 sco O ; - -N 1905 885.500 M 6 1 rr : 0 0 0 sco O ; - -N 1905 886.500 M 7 1 rr : 0 0 0 sco O ; - -N 1905 887.500 M 7 1 rr : 0 0 0 sco O ; - -N 1906 888.500 M 7 1 rr : 0 0 0 sco O ; - -N 1907 889.500 M 7 1 rr : 0 0 0 sco O ; - -N 1907 890.500 M 8 1 rr : 0 0 0 sco O ; - -N 1908 891.500 M 7 1 rr : 0 0 0 sco O ; - -N 1909 892.500 M 7 1 rr : 0 0 0 sco O ; - -N 1910 893.500 M 7 1 rr : 0 0 0 sco O ; - -N 1910 894.500 M 8 1 rr : 0 0 0 sco O ; - -N 1911 895.500 M 7 1 rr : 0 0 0 sco O ; - -N 1912 896.500 M 7 1 rr : 0 0 0 sco O ; - -N 1913 897.500 M 7 1 rr : 0 0 0 sco O ; - -N 1913 898.500 M 7 1 rr : 0 0 0 sco O ; - -N 1914 899.500 M 7 1 rr : 0 0 0 sco O ; - -N 1915 900.500 M 7 1 rr : 0 0 0 sco O ; - -N 1915 901.500 M 8 1 rr : 0 0 0 sco O ; - -N 1916 902.500 M 7 1 rr : 0 0 0 sco O ; - -N 1917 903.500 M 7 1 rr : 0 0 0 sco O ; - -N 1918 904.500 M 7 1 rr : 0 0 0 sco O ; - -N 1918 905.500 M 7 1 rr : 0 0 0 sco O ; - -N 1919 906.500 M 7 1 rr : 0 0 0 sco O ; - -N 1920 907.500 M 7 1 rr : 0 0 0 sco O ; - -N 1920 908.500 M 7 1 rr : 0 0 0 sco O ; - -N 1921 909.500 M 7 1 rr : 0 0 0 sco O ; - -N 1922 910.500 M 6 1 rr : 0 0 0 sco O ; - -N 1922 911.500 M 7 1 rr : 0 0 0 sco O ; - -N 1923 912.500 M 6 1 rr : 0 0 0 sco O ; - -N 1923 913.500 M 7 1 rr : 0 0 0 sco O ; - -N 1924 914.500 M 6 1 rr : 0 0 0 sco O ; - -N 1924 915.500 M 7 1 rr : 0 0 0 sco O ; - -N 1925 916.500 M 6 1 rr : 0 0 0 sco O ; - -N 1925 917.500 M 7 1 rr : 0 0 0 sco O ; - -N 1926 918.500 M 6 1 rr : 0 0 0 sco O ; - -N 1926 919.500 M 7 1 rr : 0 0 0 sco O ; - -N 1927 920.500 M 6 1 rr : 0 0 0 sco O ; - -N 1927 921.500 M 6 1 rr : 0 0 0 sco O ; - -N 1927 922.500 M 7 1 rr : 0 0 0 sco O ; - -N 1928 923.500 M 6 1 rr : 0 0 0 sco O ; - -N 1928 924.500 M 7 1 rr : 0 0 0 sco O ; - -N 1929 925.500 M 6 1 rr : 0 0 0 sco O ; - -N 1929 926.500 M 6 1 rr : 0 0 0 sco O ; - -N 1929 927.500 M 7 1 rr : 0 0 0 sco O ; - -N 1930 928.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 929.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 930.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 931.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 932.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 933.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 934.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 935.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 936.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 937.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 938.500 M 6 1 rr : 0 0 0 sco O ; - -N 1930 939.500 M 6 1 rr : 0 0 0 sco O ; - -N 1929 940.500 M 6 1 rr : 0 0 0 sco O ; - -N 1929 941.500 M 6 1 rr : 0 0 0 sco O ; - -N 1929 942.500 M 6 1 rr : 0 0 0 sco O ; - -N 1929 943.500 M 6 1 rr : 0 0 0 sco O ; - -N 1928 944.500 M 6 1 rr : 0 0 0 sco O ; - -N 1928 945.500 M 6 1 rr : 0 0 0 sco O ; - -N 1928 946.500 M 6 1 rr : 0 0 0 sco O ; - -N 1927 947.500 M 7 1 rr : 0 0 0 sco O ; - -N 1927 948.500 M 6 1 rr : 0 0 0 sco O ; - -N 1926 949.500 M 7 1 rr : 0 0 0 sco O ; - -N 1926 950.500 M 6 1 rr : 0 0 0 sco O ; - -N 1925 951.500 M 7 1 rr : 0 0 0 sco O ; - -N 1925 952.500 M 6 1 rr : 0 0 0 sco O ; - -N 1924 953.500 M 7 1 rr : 0 0 0 sco O ; - -N 1924 954.500 M 6 1 rr : 0 0 0 sco O ; - -N 1924 955.500 M 6 1 rr : 0 0 0 sco O ; - -N 1923 956.500 M 7 1 rr : 0 0 0 sco O ; - -N 1923 957.500 M 6 1 rr : 0 0 0 sco O ; - -N 1922 958.500 M 7 1 rr : 0 0 0 sco O ; - -N 1921 959.500 M 7 1 rr : 0 0 0 sco O ; - -N 1921 960.500 M 7 1 rr : 0 0 0 sco O ; - -N 1920 961.500 M 7 1 rr : 0 0 0 sco O ; - -N 1920 962.500 M 6 1 rr : 0 0 0 sco O ; - -N 1919 963.500 M 7 1 rr : 0 0 0 sco O ; - -N 1918 964.500 M 7 1 rr : 0 0 0 sco O ; - -N 1918 965.500 M 7 1 rr : 0 0 0 sco O ; - -N 1917 966.500 M 7 1 rr : 0 0 0 sco O ; - -N 1916 967.500 M 7 1 rr : 0 0 0 sco O ; - -N 1916 968.500 M 7 1 rr : 0 0 0 sco O ; - -N 1915 969.500 M 7 1 rr : 0 0 0 sco O ; - -N 1914 970.500 M 7 1 rr : 0 0 0 sco O ; - -N 1913 971.500 M 8 1 rr : 0 0 0 sco O ; - -N 1913 972.500 M 7 1 rr : 0 0 0 sco O ; - -N 1912 973.500 M 7 1 rr : 0 0 0 sco O ; - -N 1911 974.500 M 7 1 rr : 0 0 0 sco O ; - -N 1911 975.500 M 7 1 rr : 0 0 0 sco O ; - -N 1910 976.500 M 7 1 rr : 0 0 0 sco O ; - -N 1910 977.500 M 6 1 rr : 0 0 0 sco O ; - -N 1909 978.500 M 7 1 rr : 0 0 0 sco O ; - -N 1908 979.500 M 7 1 rr : 0 0 0 sco O ; - -N 1908 980.500 M 7 1 rr : 0 0 0 sco O ; - -N 1907 981.500 M 7 1 rr : 0 0 0 sco O ; - -N 1907 982.500 M 6 1 rr : 0 0 0 sco O ; - -N 1906 983.500 M 7 1 rr : 0 0 0 sco O ; - -N 1905 984.500 M 7 1 rr : 0 0 0 sco O ; - -N 1905 985.500 M 7 1 rr : 0 0 0 sco O ; - -N 1904 986.500 M 7 1 rr : 0 0 0 sco O ; - -N 1903 987.500 M 7 1 rr : 0 0 0 sco O ; - -N 1903 988.500 M 7 1 rr : 0 0 0 sco O ; - -N 1902 989.500 M 7 1 rr : 0 0 0 sco O ; - -N 1901 990.500 M 7 1 rr : 0 0 0 sco O ; - -N 1901 991.500 M 7 1 rr : 0 0 0 sco O ; - -N 1900 992.500 M 7 1 rr : 0 0 0 sco O ; - -N 1900 993.500 M 6 1 rr : 0 0 0 sco O ; - -N 1899 994.500 M 7 1 rr : 0 0 0 sco O ; - -N 1899 995.500 M 6 1 rr : 0 0 0 sco O ; - -N 1898 996.500 M 7 1 rr : 0 0 0 sco O ; - -N 1898 997.500 M 6 1 rr : 0 0 0 sco O ; - -N 1897 998.500 M 7 1 rr : 0 0 0 sco O ; - -N 1897 999.500 M 6 1 rr : 0 0 0 sco O ; - -N 1896 1000.500 M 7 1 rr : 0 0 0 sco O ; - -N 1896 1001.500 M 6 1 rr : 0 0 0 sco O ; - -N 1895 1002.500 M 7 1 rr : 0 0 0 sco O ; - -N 1895 1003.500 M 6 1 rr : 0 0 0 sco O ; - -N 1895 1004.500 M 6 1 rr : 0 0 0 sco O ; - -N 1894 1005.500 M 7 1 rr : 0 0 0 sco O ; - -N 1894 1006.500 M 6 1 rr : 0 0 0 sco O ; - -N 1894 1007.500 M 6 1 rr : 0 0 0 sco O ; - -N 1894 1008.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1009.500 M 7 1 rr : 0 0 0 sco O ; - -N 1893 1010.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1011.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1012.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1013.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1014.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1015.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1016.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1017.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1018.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1019.500 M 6 1 rr : 0 0 0 sco O ; - -N 1893 1020.500 M 7 1 rr : 0 0 0 sco O ; - -N 1894 1021.500 M 6 1 rr : 0 0 0 sco O ; - -N 1894 1022.500 M 6 1 rr : 0 0 0 sco O ; - -N 1894 1023.500 M 6 1 rr : 0 0 0 sco O ; - -N 1894 1024.500 M 7 1 rr : 0 0 0 sco O ; - -N 1895 1025.500 M 6 1 rr : 0 0 0 sco O ; - -N 1895 1026.500 M 6 1 rr : 0 0 0 sco O ; - -N 1895 1027.500 M 6 1 rr : 0 0 0 sco O ; - -N 1895 1028.500 M 7 1 rr : 0 0 0 sco O ; - -N 1896 1029.500 M 6 1 rr : 0 0 0 sco O ; - -N 1896 1030.500 M 7 1 rr : 0 0 0 sco O ; - -N 1897 1031.500 M 6 1 rr : 0 0 0 sco O ; - -N 1897 1032.500 M 7 1 rr : 0 0 0 sco O ; - -N 1898 1033.500 M 7 1 rr : 0 0 0 sco O ; - -N 1898 1034.500 M 7 1 rr : 0 0 0 sco O ; - -N 1899 1035.500 M 7 1 rr : 0 0 0 sco O ; - -N 1900 1036.500 M 6 1 rr : 0 0 0 sco O ; - -N 1900 1037.500 M 7 1 rr : 0 0 0 sco O ; - -N 1901 1038.500 M 6 1 rr : 0 0 0 sco O ; - -N 1901 1039.500 M 7 1 rr : 0 0 0 sco O ; - -N 1902 1040.500 M 7 1 rr : 0 0 0 sco O ; - -N 1902 1041.500 M 7 1 rr : 0 0 0 sco O ; - -N 1903 1042.500 M 7 1 rr : 0 0 0 sco O ; - -N 1904 1043.500 M 7 1 rr : 0 0 0 sco O ; - -N 1904 1044.500 M 7 1 rr : 0 0 0 sco O ; - -N 1905 1045.500 M 7 1 rr : 0 0 0 sco O ; - -N 1906 1046.500 M 7 1 rr : 0 0 0 sco O ; - -N 1906 1047.500 M 7 1 rr : 0 0 0 sco O ; - -N 1907 1048.500 M 7 1 rr : 0 0 0 sco O ; - -N 1908 1049.500 M 7 1 rr : 0 0 0 sco O ; - -N 1908 1050.500 M 7 1 rr : 0 0 0 sco O ; - -N 1909 1051.500 M 7 1 rr : 0 0 0 sco O ; - -N 1910 1052.500 M 7 1 rr : 0 0 0 sco O ; - -N 1910 1053.500 M 7 1 rr : 0 0 0 sco O ; - -N 1911 1054.500 M 7 1 rr : 0 0 0 sco O ; - -N 1912 1055.500 M 6 1 rr : 0 0 0 sco O ; - -N 1912 1056.500 M 7 1 rr : 0 0 0 sco O ; - -N 1913 1057.500 M 7 1 rr : 0 0 0 sco O ; - -N 1913 1058.500 M 8 1 rr : 0 0 0 sco O ; - -N 1914 1059.500 M 7 1 rr : 0 0 0 sco O ; - -N 1915 1060.500 M 7 1 rr : 0 0 0 sco O ; - -N 1915 1061.500 M 7 1 rr : 0 0 0 sco O ; - -N 1916 1062.500 M 2 1 rr : 0 0 0 sco O ; - -N 1871 885.500 M 2 1 rr : 1.000 0 0 sco O ; - -N 1870 886.500 M 4 1 rr : 1.000 0 0 sco O ; - -N 1869 887.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1868 888.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1869 889.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1870 890.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1871 891.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1872 892.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1873 893.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1874 894.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1875 895.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1876 896.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1877 897.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1878 898.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1879 899.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1880 900.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1881 901.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1882 902.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1883 903.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1884 904.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1885 905.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1886 906.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1886 907.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1887 908.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1888 909.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1889 910.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1890 911.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1891 912.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1892 913.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1892 914.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1893 915.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1894 916.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1895 917.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1896 918.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1896 919.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1897 920.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1898 921.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1898 922.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1899 923.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1899 924.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1900 925.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1900 926.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1901 927.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1901 928.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1902 929.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1902 930.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1903 931.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1903 932.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1904 933.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1904 934.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1905 935.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1905 936.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1906 937.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1906 938.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1907 939.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1907 940.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1908 941.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1908 942.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1909 943.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1909 944.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1910 945.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1910 946.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1911 947.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1911 948.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1912 949.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1912 950.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1913 951.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1913 952.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1914 953.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1914 954.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1915 955.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1915 956.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1916 957.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1916 958.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1917 959.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1917 960.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1918 961.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1918 962.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1919 963.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1919 964.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1919 965.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1920 966.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1920 967.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1921 968.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1921 969.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1922 970.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1922 971.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1923 972.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1924 973.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1924 974.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1925 975.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1925 976.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1926 977.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1926 978.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1927 979.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1928 980.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1929 981.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1929 982.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1930 983.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1931 984.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 1932 985.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1933 986.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1934 987.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1935 988.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1936 989.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1938 990.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1939 991.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1940 992.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1942 993.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1943 994.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 1945 995.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1946 996.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1947 997.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 1949 998.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1950 999.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1951 1000.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1951 1001.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1952 1002.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1953 1003.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1953 1004.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1954 1005.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1006.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1007.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1008.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1955 1009.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1010.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1011.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1012.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1013.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1014.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1015.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1956 1016.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1017.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1018.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1019.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1020.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1021.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1022.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1023.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1024.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1025.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1026.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1027.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1028.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1029.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1030.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1031.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1032.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1033.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1034.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1035.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1036.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1037.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1038.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1956 1039.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1040.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1955 1041.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1042.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1043.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1044.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1045.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1046.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1047.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1048.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1049.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1050.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1051.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1052.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1955 1053.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1054.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 1954 1055.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1056.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1057.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1058.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1059.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1060.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1954 1061.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 1996 458.500 M 3 1 rr : 0 0 0 sco O ; - -N 1994 459.500 M 5 1 rr : 0 0 0 sco O ; - -N 1993 460.500 M 7 1 rr : 0 0 0 sco O ; - -N 1994 461.500 M 7 1 rr : 0 0 0 sco O ; - -N 1994 462.500 M 8 1 rr : 0 0 0 sco O ; - -N 1995 463.500 M 8 1 rr : 0 0 0 sco O ; - -N 1996 464.500 M 8 1 rr : 0 0 0 sco O ; - -N 1997 465.500 M 9 1 rr : 0 0 0 sco O ; - -N 1998 466.500 M 9 1 rr : 0 0 0 sco O ; - -N 1999 467.500 M 9 1 rr : 0 0 0 sco O ; - -N 2000 468.500 M 9 1 rr : 0 0 0 sco O ; - -N 2001 469.500 M 9 1 rr : 0 0 0 sco O ; - -N 2003 470.500 M 9 1 rr : 0 0 0 sco O ; - -N 2004 471.500 M 9 1 rr : 0 0 0 sco O ; - -N 2005 472.500 M 9 1 rr : 0 0 0 sco O ; - -N 2006 473.500 M 9 1 rr : 0 0 0 sco O ; - -N 2007 474.500 M 9 1 rr : 0 0 0 sco O ; - -N 2009 475.500 M 8 1 rr : 0 0 0 sco O ; - -N 2010 476.500 M 8 1 rr : 0 0 0 sco O ; - -N 2011 477.500 M 8 1 rr : 0 0 0 sco O ; - -N 2012 478.500 M 8 1 rr : 0 0 0 sco O ; - -N 2013 479.500 M 8 1 rr : 0 0 0 sco O ; - -N 2014 480.500 M 7 1 rr : 0 0 0 sco O ; - -N 2015 481.500 M 7 1 rr : 0 0 0 sco O ; - -N 2016 482.500 M 7 1 rr : 0 0 0 sco O ; - -N 2016 483.500 M 8 1 rr : 0 0 0 sco O ; - -N 2017 484.500 M 8 1 rr : 0 0 0 sco O ; - -N 2018 485.500 M 8 1 rr : 0 0 0 sco O ; - -N 2019 486.500 M 8 1 rr : 0 0 0 sco O ; - -N 2020 487.500 M 8 1 rr : 0 0 0 sco O ; - -N 2021 488.500 M 7 1 rr : 0 0 0 sco O ; - -N 2022 489.500 M 7 1 rr : 0 0 0 sco O ; - -N 2023 490.500 M 7 1 rr : 0 0 0 sco O ; - -N 2023 491.500 M 8 1 rr : 0 0 0 sco O ; - -N 2024 492.500 M 8 1 rr : 0 0 0 sco O ; - -N 2025 493.500 M 7 1 rr : 0 0 0 sco O ; - -N 2026 494.500 M 7 1 rr : 0 0 0 sco O ; - -N 2027 495.500 M 7 1 rr : 0 0 0 sco O ; - -N 2027 496.500 M 8 1 rr : 0 0 0 sco O ; - -N 2028 497.500 M 7 1 rr : 0 0 0 sco O ; - -N 2029 498.500 M 7 1 rr : 0 0 0 sco O ; - -N 2030 499.500 M 7 1 rr : 0 0 0 sco O ; - -N 2030 500.500 M 8 1 rr : 0 0 0 sco O ; - -N 2031 501.500 M 7 1 rr : 0 0 0 sco O ; - -N 2032 502.500 M 7 1 rr : 0 0 0 sco O ; - -N 2033 503.500 M 6 1 rr : 0 0 0 sco O ; - -N 2033 504.500 M 7 1 rr : 0 0 0 sco O ; - -N 2034 505.500 M 6 1 rr : 0 0 0 sco O ; - -N 2034 506.500 M 7 1 rr : 0 0 0 sco O ; - -N 2035 507.500 M 7 1 rr : 0 0 0 sco O ; - -N 2035 508.500 M 7 1 rr : 0 0 0 sco O ; - -N 2036 509.500 M 7 1 rr : 0 0 0 sco O ; - -N 2037 510.500 M 6 1 rr : 0 0 0 sco O ; - -N 2037 511.500 M 7 1 rr : 0 0 0 sco O ; - -N 2038 512.500 M 6 1 rr : 0 0 0 sco O ; - -N 2038 513.500 M 7 1 rr : 0 0 0 sco O ; - -N 2039 514.500 M 6 1 rr : 0 0 0 sco O ; - -N 2039 515.500 M 7 1 rr : 0 0 0 sco O ; - -N 2040 516.500 M 6 1 rr : 0 0 0 sco O ; - -N 2040 517.500 M 7 1 rr : 0 0 0 sco O ; - -N 2041 518.500 M 6 1 rr : 0 0 0 sco O ; - -N 2041 519.500 M 7 1 rr : 0 0 0 sco O ; - -N 2042 520.500 M 6 1 rr : 0 0 0 sco O ; - -N 2042 521.500 M 7 1 rr : 0 0 0 sco O ; - -N 2043 522.500 M 6 1 rr : 0 0 0 sco O ; - -N 2043 523.500 M 7 1 rr : 0 0 0 sco O ; - -N 2044 524.500 M 6 1 rr : 0 0 0 sco O ; - -N 2044 525.500 M 7 1 rr : 0 0 0 sco O ; - -N 2045 526.500 M 6 1 rr : 0 0 0 sco O ; - -N 2045 527.500 M 7 1 rr : 0 0 0 sco O ; - -N 2046 528.500 M 6 1 rr : 0 0 0 sco O ; - -N 2046 529.500 M 7 1 rr : 0 0 0 sco O ; - -N 2047 530.500 M 6 1 rr : 0 0 0 sco O ; - -N 2047 531.500 M 7 1 rr : 0 0 0 sco O ; - -N 2048 532.500 M 6 1 rr : 0 0 0 sco O ; - -N 2048 533.500 M 7 1 rr : 0 0 0 sco O ; - -N 2049 534.500 M 6 1 rr : 0 0 0 sco O ; - -N 2049 535.500 M 7 1 rr : 0 0 0 sco O ; - -N 2050 536.500 M 6 1 rr : 0 0 0 sco O ; - -N 2050 537.500 M 7 1 rr : 0 0 0 sco O ; - -N 2051 538.500 M 6 1 rr : 0 0 0 sco O ; - -N 2051 539.500 M 7 1 rr : 0 0 0 sco O ; - -N 2052 540.500 M 6 1 rr : 0 0 0 sco O ; - -N 2052 541.500 M 7 1 rr : 0 0 0 sco O ; - -N 2053 542.500 M 6 1 rr : 0 0 0 sco O ; - -N 2053 543.500 M 7 1 rr : 0 0 0 sco O ; - -N 2054 544.500 M 6 1 rr : 0 0 0 sco O ; - -N 2054 545.500 M 7 1 rr : 0 0 0 sco O ; - -N 2055 546.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 547.500 M 6 1 rr : 0 0 0 sco O ; - -N 2055 548.500 M 7 1 rr : 0 0 0 sco O ; - -N 2056 549.500 M 6 1 rr : 0 0 0 sco O ; - -N 2056 550.500 M 7 1 rr : 0 0 0 sco O ; - -N 2057 551.500 M 6 1 rr : 0 0 0 sco O ; - -N 2057 552.500 M 7 1 rr : 0 0 0 sco O ; - -N 2058 553.500 M 6 1 rr : 0 0 0 sco O ; - -N 2058 554.500 M 7 1 rr : 0 0 0 sco O ; - -N 2059 555.500 M 6 1 rr : 0 0 0 sco O ; - -N 2059 556.500 M 6 1 rr : 0 0 0 sco O ; - -N 2059 557.500 M 7 1 rr : 0 0 0 sco O ; - -N 2060 558.500 M 7 1 rr : 0 0 0 sco O ; - -N 2060 559.500 M 7 1 rr : 0 0 0 sco O ; - -N 2061 560.500 M 7 1 rr : 0 0 0 sco O ; - -N 2062 561.500 M 6 1 rr : 0 0 0 sco O ; - -N 2062 562.500 M 7 1 rr : 0 0 0 sco O ; - -N 2063 563.500 M 7 1 rr : 0 0 0 sco O ; - -N 2063 564.500 M 7 1 rr : 0 0 0 sco O ; - -N 2064 565.500 M 7 1 rr : 0 0 0 sco O ; - -N 2065 566.500 M 7 1 rr : 0 0 0 sco O ; - -N 2065 567.500 M 7 1 rr : 0 0 0 sco O ; - -N 2066 568.500 M 7 1 rr : 0 0 0 sco O ; - -N 2067 569.500 M 6 1 rr : 0 0 0 sco O ; - -N 2067 570.500 M 7 1 rr : 0 0 0 sco O ; - -N 2068 571.500 M 7 1 rr : 0 0 0 sco O ; - -N 2068 572.500 M 7 1 rr : 0 0 0 sco O ; - -N 2069 573.500 M 7 1 rr : 0 0 0 sco O ; - -N 2070 574.500 M 7 1 rr : 0 0 0 sco O ; - -N 2070 575.500 M 7 1 rr : 0 0 0 sco O ; - -N 2071 576.500 M 7 1 rr : 0 0 0 sco O ; - -N 2072 577.500 M 8 1 rr : 0 0 0 sco O ; - -N 2072 578.500 M 9 1 rr : 0 0 0 sco O ; - -N 2073 579.500 M 9 1 rr : 0 0 0 sco O ; - -N 2074 580.500 M 10 1 rr : 0 0 0 sco O ; - -N 2075 581.500 M 10 1 rr : 0 0 0 sco O ; - -N 2077 582.500 M 10 1 rr : 0 0 0 sco O ; - -N 2078 583.500 M 11 1 rr : 0 0 0 sco O ; - -N 2079 584.500 M 11 1 rr : 0 0 0 sco O ; - -N 2081 585.500 M 11 1 rr : 0 0 0 sco O ; - -N 2082 586.500 M 11 1 rr : 0 0 0 sco O ; - -N 2084 587.500 M 10 1 rr : 0 0 0 sco O ; - -N 2086 588.500 M 10 1 rr : 0 0 0 sco O ; - -N 2087 589.500 M 10 1 rr : 0 0 0 sco O ; - -N 2089 590.500 M 9 1 rr : 0 0 0 sco O ; - -N 2090 591.500 M 10 1 rr : 0 0 0 sco O ; - -N 2091 592.500 M 10 1 rr : 0 0 0 sco O ; - -N 2093 593.500 M 9 1 rr : 0 0 0 sco O ; - -N 2094 594.500 M 9 1 rr : 0 0 0 sco O ; - -N 2095 595.500 M 9 1 rr : 0 0 0 sco O ; - -N 2097 596.500 M 8 1 rr : 0 0 0 sco O ; - -N 2098 597.500 M 7 1 rr : 0 0 0 sco O ; - -N 2099 598.500 M 7 1 rr : 0 0 0 sco O ; - -N 2100 599.500 M 7 1 rr : 0 0 0 sco O ; - -N 2100 600.500 M 7 1 rr : 0 0 0 sco O ; - -N 2101 601.500 M 7 1 rr : 0 0 0 sco O ; - -N 2102 602.500 M 6 1 rr : 0 0 0 sco O ; - -N 2102 603.500 M 7 1 rr : 0 0 0 sco O ; - -N 2103 604.500 M 6 1 rr : 0 0 0 sco O ; - -N 2103 605.500 M 7 1 rr : 0 0 0 sco O ; - -N 2104 606.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 607.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 608.500 M 7 1 rr : 0 0 0 sco O ; - -N 2105 609.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 610.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 611.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 612.500 M 7 1 rr : 0 0 0 sco O ; - -N 2106 613.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 614.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 615.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 616.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 617.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 618.500 M 7 1 rr : 0 0 0 sco O ; - -N 2107 619.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 620.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 621.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 622.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 623.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 624.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 625.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 626.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 627.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 628.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 629.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 630.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 631.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 632.500 M 6 1 rr : 0 0 0 sco O ; - -N 2107 633.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 634.500 M 7 1 rr : 0 0 0 sco O ; - -N 2106 635.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 636.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 637.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 638.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 639.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 640.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 641.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 642.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 643.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 644.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 645.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 646.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 647.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 648.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 649.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 650.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 651.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 652.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 653.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 654.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 655.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 656.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 657.500 M 6 1 rr : 0 0 0 sco O ; - -N 2106 658.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 659.500 M 7 1 rr : 0 0 0 sco O ; - -N 2105 660.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 661.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 662.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 663.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 664.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 665.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 666.500 M 6 1 rr : 0 0 0 sco O ; - -N 2105 667.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 668.500 M 7 1 rr : 0 0 0 sco O ; - -N 2104 669.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 670.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 671.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 672.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 673.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 674.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 675.500 M 6 1 rr : 0 0 0 sco O ; - -N 2104 676.500 M 6 1 rr : 0 0 0 sco O ; - -N 2046 440.500 M 3 1 rr : 1.000 0 0 sco O ; - -N 2044 441.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2043 442.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2044 443.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2045 444.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2045 445.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2046 446.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2047 447.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2048 448.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2049 449.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2049 450.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2050 451.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2051 452.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2052 453.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2053 454.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2053 455.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2054 456.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2055 457.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2056 458.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2056 459.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2057 460.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2058 461.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2059 462.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2059 463.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2060 464.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2061 465.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2062 466.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2062 467.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2063 468.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2064 469.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2064 470.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2065 471.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2066 472.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2067 473.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2067 474.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2068 475.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2069 476.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2069 477.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2070 478.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2071 479.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2071 480.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2072 481.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2073 482.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2074 483.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2074 484.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2075 485.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2076 486.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2076 487.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2077 488.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2078 489.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2078 490.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2079 491.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2079 492.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2080 493.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2081 494.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2081 495.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2082 496.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2082 497.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2082 498.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2083 499.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2083 500.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2083 501.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2084 502.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2084 503.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2084 504.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2084 505.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2085 506.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2085 507.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2085 508.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2086 509.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 510.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 511.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 512.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2087 513.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 514.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 515.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 516.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 517.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 518.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 519.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 520.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 521.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 522.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 523.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 524.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 525.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 526.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 527.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 528.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 529.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 530.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 531.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 532.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 533.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 534.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 535.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2087 536.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 537.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2086 538.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 539.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 540.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 541.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 542.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 543.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2086 544.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2085 545.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2085 546.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2085 547.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2084 548.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2084 549.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2084 550.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2084 551.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2084 552.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2083 553.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2083 554.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2083 555.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2082 556.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2082 557.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2081 558.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2080 559.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2080 560.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2079 561.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2077 562.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2076 563.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 2074 564.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 2072 565.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2071 566.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2069 567.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2068 568.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2066 569.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2064 570.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2063 571.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2061 572.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2060 573.500 M 11 1 rr : 1.000 0 0 sco O ; - -N 2059 574.500 M 10 1 rr : 1.000 0 0 sco O ; - -N 2058 575.500 M 9 1 rr : 1.000 0 0 sco O ; - -N 2058 576.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2057 577.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2056 578.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2055 579.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2054 580.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2053 581.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2052 582.500 M 8 1 rr : 1.000 0 0 sco O ; - -N 2052 583.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2051 584.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2051 585.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2050 586.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2049 587.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2049 588.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2049 589.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 590.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2048 591.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 592.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 593.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 594.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2047 595.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2047 596.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2047 597.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2047 598.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2047 599.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2047 600.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 601.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 602.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 603.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 604.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 605.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2048 606.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2049 607.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2049 608.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2049 609.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2049 610.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2050 611.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2050 612.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2050 613.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2050 614.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2051 615.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2051 616.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2051 617.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2052 618.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2052 619.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2052 620.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2053 621.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2053 622.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2053 623.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2054 624.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2054 625.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2054 626.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2055 627.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2055 628.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2055 629.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2056 630.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2056 631.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2056 632.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2057 633.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2057 634.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2058 635.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2058 636.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2059 637.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2059 638.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2060 639.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2060 640.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2060 641.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2061 642.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2061 643.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2062 644.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2062 645.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2062 646.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2063 647.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2063 648.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2064 649.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2064 650.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2064 651.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2065 652.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2065 653.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2066 654.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2066 655.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2066 656.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2067 657.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2067 658.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2068 659.500 M 6 1 rr : 1.000 0 0 sco O ; - -N 2068 660.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2068 661.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2069 662.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2069 663.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2070 664.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2070 665.500 M 7 1 rr : 1.000 0 0 sco O ; - -N 2071 666.500 M 2 1 rr : 1.000 0 0 sco O ; - -164 95 N M 2601 271 rr : 114 70 3000 2250 rc 0.647 0 0.129 sco F0_100 - -Ji - -201 111 M - --0.300 0 (M)A - --0.100 0 (u)A - -0.200 0 (l)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.800 0 (l)A - -0.400 0 (eve)A - -1.000 0 32 -0.800 0 (l )D - --0.100 0 (p)A - --0.600 0 (a)A - -0.100 0 (r)A - -0.700 0 (t)A - --0.800 0 (i)A - -0.700 0 (t)A - --0.800 0 (i)A - --0.100 0 (on)A - -0.200 0 (i)A - --0.700 0 32 -0.100 0 (ng )D - -0.400 0 (a)A - -0.200 0 (l)A - --0.100 0 (g)A - --1.100 0 (o)A - -1.100 0 (r)A - --0.800 0 (i)A - --0.300 0 (t)A - --0.100 0 (h)A - -0.100 0 (m)A - --0.200 0 32 0.400 0 (s c)D - --1.100 0 (o)A - -1.100 0 (m)A - --1.100 0 (p)A - --0.100 0 (u)A - -0.700 0 (t)A - -0.800 0 32 -0.600 0 (e )D - --1.200 0 32 0.400 0 (a )D - --0.100 0 (p)A - -0.400 0 (a)A - -0.100 0 (r)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.300 0 (t)A - -0.200 0 (i)A - --0.100 0 (on)A - -; : 114 70 3000 2250 rc 0.647 0 0.129 sco F0_100 - -Ji - -273 231 M - -0.400 0 (a)A - -0.500 0 32 -0.300 0 (t t)D - --0.100 0 (h)A - --1.200 0 32 0.400 0 (e c)D - --0.100 0 (o)A - -0.400 0 (a)A - -0.100 0 (r)A - --0.600 0 (s)A - -0.400 0 (es)A - -0.500 0 32 -0.300 0 (t )D - --0.100 0 (g)A - -0.100 0 (r)A - -0.400 0 (a)A - --1.100 0 (p)A - -0.300 0 32 -0.100 0 (h )D - -0.400 0 (a)A - --0.700 0 32 -0.100 0 (nd )D - -0.700 0 (t)A - --1.100 0 (h)A - -0.400 0 (e)A - -0.300 0 32 -0.100 0 (n )D - -0.100 0 (r)A - --0.600 0 (e)A - -0.700 0 (f)A - --0.800 0 (i)A - --0.100 0 (n)A - --0.200 0 32 0.400 0 (e )D - --0.300 0 (t)A - --0.100 0 (h)A - --1.200 0 32 0.400 0 (e s)D - --0.100 0 (o)A - -0.200 0 (l)A - --1.100 0 (u)A - -0.700 0 (t)A - --0.800 0 (i)A - --0.100 0 (on)A - -0.700 0 (!)A - -; - -LH - -pagesave restore - - - - - - - -/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec - -Pscript_Win_Compat dup /terminate get exec - - - -restore gr -% -% End Imported PIC File: slide8.eps -% -/Helvetica-Bold findfont 300.00 scalefont setfont -14550 7514 m -gs 1 -1 sc (\(b\)) col-1 show gr -/Helvetica-Bold findfont 300.00 scalefont setfont -5100 5864 m -gs 1 -1 sc (\(a\)) col-1 show gr -$F2psEnd -restore -%%EndDocument - @endspecial 678 2789 a Fy(Figure)e(1)p FL(:)26 b Fx(\(a\))18 -b(T)-8 b(r)o(aditional)18 b(par)s(titioning)g(algor)q(ithms)o(.)k -(\(b\))c(Multile)n(v)n(el)h(par)s(titioning)f(algor)q(ithms)o(.)100 -2982 y FL(The)h(adv)n(antages)g(of)j Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)24 b FL(compared)19 b(to)h(other)f(similar)i -(packages)e(are)h(the)g(follo)n(wing:)88 3167 y Fw(+)42 -b FC(Pr)o(o)o(vides)19 b(high)i(quality)f(partitions!)208 -3277 y FL(Experiments)j(on)i(a)h(lar)o(ge)f(number)e(of)j(graphs)e -(arising)h(in)g(v)n(arious)g(domains)f(including)g(\002nite)i(element)f -(methods,)g(linear)208 3386 y(programming,)g(VLSI,)i(and)g -(transportation)e(sho)n(w)h(that)k Fz(M)l FG(E)-17 b -Fz(T)g FG(I)p Fz(S)31 b FL(produces)26 b(partitions)g(that)i(are)f -(consistently)f(better)h(than)208 3496 y(those)g(produced)f(by)h(other) -g(widely)g(used)h(algorithms.)47 b(The)27 b(partitions)g(produced)e(by) -30 b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)32 b FL(are)c(consistently)f -(10\045)g(to)208 3606 y(50\045)19 b(better)h(than)g(those)g(produced)e -(by)h(spectral)h(partitioning)f(algorithms)g([1)o(,)h(4].)88 -3790 y Fw(+)42 b FC(It)20 b(is)h(extr)o(emely)e(fast!)208 -3900 y FL(Experiments)d(on)i(a)g(wide)g(range)f(of)h(graphs)f(has)i -(sho)n(wn)e(that)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)23 -b FL(is)c(one)e(to)i(tw)o(o)f(orders)f(of)h(magnitude)e(f)o(aster)j -(than)e(other)208 4010 y(widely)h(used)h(partitioning)e(algorithms.)24 -b(Figure)18 b(2)i(sho)n(ws)f(the)g(amount)f(of)h(time)g(required)e(to)j -(partition)e(a)i(v)n(ariety)e(of)h(graphs)208 4119 y(in)h(256)g(parts)h -(for)f(tw)o(o)g(dif)n(ferent)f(architectures,)g(an)i(R10000-based)d -(SGI)j(Challenge)f(and)g(a)h(Pentium)f(Pro-based)f(personal)208 -4229 y(computer)-5 b(.)30 b(Graphs)21 b(containing)g(up)h(to)g(four)f -(million)h(v)o(ertices)g(can)g(be)g(partitioned)f(in)i(256)e(parts)h -(in)h(well)g(under)e(a)h(minute)208 4338 y(on)g(today')-5 -b(s)22 b(scienti\002c)h(w)o(orkstations.)33 b(The)22 -b(run)g(time)h(of)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 -b FL(is)d(comparable)c(to)j(\(or)g(e)n(v)o(en)f(smaller)g(than\))g(the) -h(run)f(time)208 4448 y(of)d(some)h(geometric)f(partitioning)f -(algorithms)h(that)i(often)e(produce)f(much)h(w)o(orse)i(partitions.)88 -4633 y Fw(+)42 b FC(Pr)o(o)o(vides)19 b(lo)o(w)h(\002ll)i(orderings!) -208 4742 y FL(The)29 b(\002ll-reducing)f(orderings)g(produced)f(by)32 -b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)34 b FL(are)c(substantially)f -(better)g(than)h(those)f(produced)f(by)h(other)g(widely)208 -4852 y(used)18 b(algorithms)g(including)g(multiple)g(minimum)g(de)o -(gree.)23 b(F)o(or)18 b(man)o(y)g(classes)j(of)d(problems)g(arising)h -(in)g(scienti\002c)g(compu-)208 4962 y(tations)k(and)g(linear)g -(programming,)f Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 -b FL(is)e(able)e(to)g(reduce)g(the)g(storage)f(and)h(computational)e -(requirements)g(of)j(sparse)208 5071 y(matrix)e(f)o(actorization)f -(methods)g(by)h(up)h(to)g(an)f(order)g(of)g(magnitude.)31 -b(Moreo)o(v)o(er)m(,)20 b(unlik)o(e)i(multiple)g(minimum)f(de)o(gree,)h -(the)208 5181 y(elimination)f(trees)h(produced)e(by)k -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 b FL(are)22 b(suited)g(for)g -(parallel)g(direct)f(f)o(actorization.)30 b(Furthermore,)20 -b(as)j(Figure)f(2)g(illus-)208 5290 y(trates,)g Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 b FL(is)d(able)e(to)h(compute)f(these) -h(ordering)e(v)o(ery)g(f)o(ast.)26 b(Matrices)20 b(with)g(o)o(v)o(er)e -(tw)o(o)i(hundred)e(thousand)g(ro)n(ws)i(can)g(be)208 -5400 y(reordered)d(in)k(just)f(a)h(fe)n(w)f(seconds)g(on)g(current)e -(generation)h(w)o(orkstations)g(and)g(PCs.)1929 5649 -y(4)p eop -%%Page: 5 5 -5 4 bop 690 3717 a @beginspecial 0 @llx 0 @lly 716 @urx -1056 @ury 3024 @rwi @setspecial -%%BeginDocument: ./figures/slides.eps -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save --30.0 1113.0 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -n -1000 19537 m -1000 -1000 l 13423 -1000 l 13423 19537 l cp clip - 0.06000 0.06000 sc -% Polyline -% -% Begin Imported EPS File: slide1.eps -% -n gs -525 973 tr -16.646067 -16.638623 sc -0 -523 tr --40 -50 tr -sa -n 40 50 m 752 50 l 752 573 l 40 573 l cp clip -countdictstack -mark -/showpage {} def -% EPS file follows: - - - - - - - - - - - - - - - -/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2 - -copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch - -currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put - -end}bind readonly def/findresource{userdict/Resources get exch get exch get} - -bind readonly def/resourceforall{pop pop pop pop}bind readonly def - -/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch - -known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false - -}ifelse}bind readonly def end}ifelse - - - -/Pscript_Win_Driver 200 dict dup begin - - -/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div - -cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def - - -/VM? {vmstatus exch sub exch pop gt { [ - -(This job requires more memory than is available in this printer.) 100 500 - -(Try one or more of the following, and then print again:) 100 485 - -(In the PostScript dialog box, click Optimize For Portability.) 115 470 - -(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455 - -(Reduce the number of fonts in the document.) 115 440 - -(Print the document in parts.) 115 425 - -12 /Times-Roman showpage - -(%%[ PrinterError: Low Printer VM ]%%) = - -true FatalErrorIf}if} bind def - - -/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^ - -/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/- - -/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true , - -|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , | - -/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto , - -|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin - -, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow , - -|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld - -/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2 - -ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b - -/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El ! - -}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{ - -self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ | - -/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put - -/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{ - -exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{ - -transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b - -/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict - -/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[] - -0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0 - --}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b - - - -L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $ - -@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{ - -4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{ - -setrgbcolor}b/sgco{{sg}{sco}?}b}e - - - -L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}? - -setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5 - -}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $ - -idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg - -{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg - -}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering - -defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! ! - -/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering - -resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}? - -findresource setcolorrendering}b}e - - - -/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron - -/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18 - -bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase - -/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron - -/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright - -/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets - -/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section - -/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered - -/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph - -/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter - -/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis - -/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute - -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis - -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls - -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute - -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve - -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex - -/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave - -put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153 - -154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253 - -254]{/bullet put @}forall 166/bar put 176/ring put - - - -/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T | - -/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null | - -/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add - -dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding - -ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld} - -if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{ - -ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get - -StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? ` - -/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0 - -put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont - -Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font - -3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M - -currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP - -uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b - -/sRxy{: matrix astore concat 0 0 M}b/eR/; , | - - - -/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0 - -FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 | - -/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or & - -/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E - -definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^ - -/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM - -astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2 - -copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF - -mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get - -Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{ - -: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{: - -Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b - -/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D - -; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName - -~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b - - - -/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{ - -SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null | - -/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 | - -/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]| - -/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null | - -/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b - -/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep - -XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8 - -Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag - -{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps - -mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M - -MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E - -/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix - -GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal - -makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{ - -/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross - -makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}? - -|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 | - -/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0 - -Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload ! - -sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if} - -}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask - -Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $ - -/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E - -CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b - -/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{ - -/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict ` - -YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix - -currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E - -dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An - -C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2 - -~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2 - -rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~ - -|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0 - -0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b - - - -L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq - -and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}? - --1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}? - -}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp - -C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T - -hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ | - -pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint - -strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy ` - -/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr - -length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1 - -255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox | - -/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec - -;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix - -PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $ - -PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^ - -sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b - -/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^ - -M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr - -S}repeat YStep add M}repeat ! ! ! ! E}b}e - - - -L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{ - -setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern - -K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{ - -pfprep setpattern K restore N}b}e - - - -/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc - -0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b - -/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b - -/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b - -/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}| - -/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 | - -/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc - -/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc - -]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , | - -L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~ - -string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ , - -| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring - -~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ ` - -/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]| - -/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b - - - -L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b - -/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0 - -0 ih 0 0]s imagemask}b}e - - - -L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage - -where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{ - -/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E - -| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict - -/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and - -and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{ - -/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut - -~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @ - -currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @ - -3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{ - -1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~ - -|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut - -ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute} - -concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub | - -/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut - -rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255 - -V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @ - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc - -T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{ - -cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b - -/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3 - -idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut - -1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x - -defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @ - -rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor - -currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut - -stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | ! - -invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc - -nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval - -putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a - -byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a - -byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3 - -copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~ - -mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3 - -createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12 - -createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand - -,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8 - -[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length - -|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2 - -len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul - -gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0 - -smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec - -,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s - -image}?}b}e - - - -L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[ - -/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw | - -/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s | - -/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{ - -/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK - -hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 - -hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc | - -/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}? - -setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1 - -0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent - -bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{ - -/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0 - -1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 | - -/Interpolate smoothflag | E image}b}e - - - -/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~ - -|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict | - -CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar - -{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict - -/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get - -CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put - -CharProcs 3 1 $ put Metrics 3 1 $ put E}| - - - -/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{ - -/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~ - -putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ | - -/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding - -256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| & - -E currentfile eexec}bind | - - -/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length - -ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add | - -DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC - -257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{ - -mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 | - -/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC - -~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss - -readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring ! - -0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop - -mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b - -/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b - - -userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def - -}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{ - -/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix - -invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3 - -/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10 - -/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar - -130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135 - -/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE - -145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150 - -/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156 - -/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar - -167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172 - -/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178 - -/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183 - -/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187 - -/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown - -192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198 - -/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204 - -/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve - -211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash - -217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223 - -/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229 - -/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis - -236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242 - -/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248 - -/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254 - -/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{ - -pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def - -/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate - -load def/resume/initialize load def/M/moveto load def end put/Courier findfont - -10 scalefont setfont - - -end /ProcSet defineresource pop - - - - - - -Pscript_Win_Compat dup /initialize get exec - -[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec - - - - - -/mysetup [ 0.240 0 0 -0.240 7.920 592.800 ] | - - - - - - -userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; - - - - - - -116 70 N M 1 1 rr - -116 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; - -116 70 N M 1 1 rr - -116 70 N M 1 1 rr - -134 87 N M 2960 2172 rr 11 Lw 0 Lc 0 Lj solid 0 0 0 sco K - -455 462 N M 2600 1570 rr : 1.000 0.800 0.600 sco O ; - -455 462 N M 2600 0 - 4 Lw 1 Lc 1 Lj solid 0 0 0 sco K - -3055 462 N M 0 1570 - 0 0 0 sco K - -3055 2032 N M -2600 0 - 0 0 0 sco K - -455 2032 N M 0 -1570 - 0 0 0 sco K - -455 1963 N M 40 54 rr : 1.000 1.000 0 sco O ; 0 Lc 0 Lj 0 0 0 sco K - -455 1790 N M 54 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 1613 N M 105 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 1440 N M 115 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 1267 N M 202 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 1090 N M 296 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 917 N M 411 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 744 N M 461 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 567 N M 1229 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -455 1877 N M 65 57 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 1703 N M 97 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 1527 N M 151 57 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 1353 N M 155 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 1180 N M 393 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 1003 N M 440 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 830 N M 505 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 657 N M 808 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 480 N M 2351 58 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -455 462 N M 0 1570 - 1 Lc 1 Lj 0 0 0 sco K - -433 2032 N M 22 0 - 0 0 0 sco K - -433 1858 N M 22 0 - 0 0 0 sco K - -433 1682 N M 22 0 - 0 0 0 sco K - -433 1509 N M 22 0 - 0 0 0 sco K - -433 1335 N M 22 0 - 0 0 0 sco K - -433 1159 N M 22 0 - 0 0 0 sco K - -433 985 N M 22 0 - 0 0 0 sco K - -433 812 N M 22 0 - 0 0 0 sco K - -433 635 N M 22 0 - 0 0 0 sco K - -433 462 N M 22 0 - 0 0 0 sco K : 560 170 2116 150 rc 0.502 0 0 sco %%IncludeFont: Helvetica-Bold - -(F0) cvn - -0.931 - - (Helvetica-Bold) cvn /Type1 - -T - -(Helvetica-Bold) cvn - -mF - -(F0_130) cvn - -F0 - -130 - -xF - -F0_130 - -Ji - -581 170 M - --3.290 0 (M)A - --0.710 0 (E)A - -3.570 0 (T)A - --4.140 0 (I)A - -0.290 0 (S)A - -1.060 0 (')A - -3.140 0 32 -3.280 0 (s )D - -0.290 0 (P)A - -2.720 0 (a)A - -0.430 0 (r)A - --0.290 0 (t)A - --4.140 0 (i)A - -0.710 0 (t)A - --4.140 0 (i)A - -0.570 0 (o)A - --4.430 0 (n)A - --3.140 0 (i)A - --4.430 0 (n)A - --0.710 0 32 0.570 0 (g )D - --0.710 0 (P)A - --0.280 0 (e)A - -0.430 0 (r)A - -3.710 0 (f)A - --0.430 0 (o)A - -0.430 0 (r)A - -3.430 0 (m)A - -2.720 0 (a)A - --3.430 0 (n)A - -0.140 0 32 -0.280 0 (ce )D - -; : 498 1959 188 55 rc 0 0 0 sco (F0_47) cvn - -F0 - -47 - -xF - -F0_47 - -Ji - -509 1959 M - --1.132 0 (1)A - -1.934 0 (.)A - --1.132 0 (57)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 513 1786 187 55 rc 0 0 0 sco F0_47 - -Ji - -523 1786 M - --1.132 0 (2)A - -1.934 0 (.)A - --1.132 0 (10)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 563 1610 188 55 rc 0 0 0 sco F0_47 - -Ji - -574 1610 M - --1.132 0 (4)A - -1.934 0 (.)A - --1.132 0 (00)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 574 1436 187 55 rc 0 0 0 sco F0_47 - -Ji - -585 1436 M - --1.132 0 (4)A - -1.934 0 (.)A - --1.132 0 (42)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 660 1263 188 55 rc 0 0 0 sco F0_47 - -Ji - -671 1263 M - --1.132 0 (7)A - -1.934 0 (.)A - --1.132 0 (79)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 754 1086 213 55 rc 0 0 0 sco F0_47 - -Ji - -765 1086 M - --1.132 0 (11)A - -1.934 0 (.)A - --1.132 0 (32)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 870 913 212 55 rc 0 0 0 sco F0_47 - -Ji - -880 913 M - --1.132 0 (15)A - -1.934 0 (.)A - --1.132 0 (76)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 920 740 213 55 rc 0 0 0 sco F0_47 - -Ji - -931 740 M - --1.132 0 (17)A - -1.934 0 (.)A - --1.132 0 (81)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 1688 563 213 55 rc 0 0 0 sco F0_47 - -Ji - -1699 563 M - --1.132 0 (47)A - -1.934 0 (.)A - --1.132 0 (34)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 523 1873 188 55 rc 0 0 0 sco F0_47 - -Ji - -534 1873 M - --1.132 0 (2)A - -1.934 0 (.)A - --1.132 0 (55)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 556 1700 187 55 rc 0 0 0 sco F0_47 - -Ji - -567 1700 M - --1.132 0 (3)A - -1.934 0 (.)A - --1.132 0 (79)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 610 1527 187 55 rc 0 0 0 sco F0_47 - -Ji - -621 1527 M - --1.132 0 (5)A - -1.934 0 (.)A - --1.132 0 (87)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 614 1353 187 55 rc 0 0 0 sco F0_47 - -Ji - -624 1353 M - --1.132 0 (5)A - -1.934 0 (.)A - --1.132 0 (96)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 852 1177 212 55 rc 0 0 0 sco F0_47 - -Ji - -862 1177 M - --1.132 0 (15)A - -1.934 0 (.)A - --1.132 0 (12)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 898 1000 213 55 rc 0 0 0 sco F0_47 - -Ji - -909 1000 M - --1.132 0 (16)A - -1.934 0 (.)A - --1.132 0 (95)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 963 827 213 55 rc 0 0 0 sco F0_47 - -Ji - -974 827 M - --1.132 0 (19)A - -1.934 0 (.)A - --1.132 0 (40)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 1266 653 213 55 rc 0 0 0 sco F0_47 - -Ji - -1277 653 M - --1.132 0 (31)A - -1.934 0 (.)A - --1.132 0 (11)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 2809 480 213 55 rc 0 0 0 sco F0_47 - -Ji - -2820 480 M - --1.132 0 (90)A - -1.934 0 (.)A - --1.132 0 (45)A - --4.132 0 (s)A - -2.868 0 (e)A - --1.132 0 (c)A - -; : 116 1905 3000 77 rc 0 0 0 sco %%IncludeFont: Helvetica - -(F3) cvn - -0.899 - - (Helvetica) cvn /Type1 - -T - -(Helvetica) cvn - -mF - -(F3_69) cvn - -F3 - -69 - -xF - -F3_69 - -Ji - -188 1905 M - -0.977 0 (B)A - --0.977 0 (r)A - --2.364 0 (a)A - -1.500 0 (c)A - --2.500 0 (k)A - -1.636 0 (2)A - -; : 116 1729 3000 77 rc 0 0 0 sco F3_69 - -Ji - -199 1729 M - -0.318 0 (O)A - -1.500 0 (c)A - -1.636 0 (e)A - --2.364 0 (an)A - -; : 159 1555 2957 77 rc 0 0 0 sco F3_69 - -Ji - -282 1555 M - -1.636 0 (1)A - -0.636 0 (4)A - -1.636 0 (4)A - -; : 116 1382 3000 77 rc 0 0 0 sco F3_69 - -Ji - -181 1382 M - --3.477 0 (M)A - -1.636 0 (d)A - --2.364 0 (ua)A - --1.318 0 (l)A - -1.636 0 (1)A - -; : 144 1205 2972 77 rc 0 0 0 sco F3_69 - -Ji - -267 1205 M - -0.841 0 (T)A - --0.977 0 (r)A - -1.636 0 (o)A - --1.318 0 (ll)A - -; : 137 1032 2979 77 rc 0 0 0 sco F3_69 - -Ji - -260 1032 M - -0.977 0 (A)A - --2.364 0 (u)A - --1.182 0 (t)A - -1.636 0 (o)A - -; : 116 859 3000 77 rc 0 0 0 sco F3_69 - -Ji - -181 859 M - --3.477 0 (M)A - -1.636 0 (d)A - --2.364 0 (ua)A - --1.318 0 (l)A - -1.636 0 (2)A - -; : 177 682 2939 77 rc 0 0 0 sco F3_69 - -Ji - -300 682 M - -0.977 0 (B)A - --1.318 0 (i)A - -1.636 0 (g)A - -; : 116 509 3000 77 rc 0 0 0 sco F3_69 - -Ji - -181 509 M - --3.477 0 (M)A - -1.636 0 (d)A - --2.364 0 (ua)A - --1.318 0 (l)A - -1.636 0 (3)A - -; - -729 2075 N M 2044 133 rr : 1.000 1.000 1.000 sco O ; 0 Lc 0 Lj 0 0 0 sco K - -758 2118 N M 54 54 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K : 729 2097 2048 100 rc 0 0 0 sco (F0_87) cvn - -F0 - -87 - -xF - -F0_87 - -Ji - -837 2097 M - -3.529 0 (M)A - -0.814 0 (I)A - --0.029 0 (P)A - -2.843 0 32 -1.029 0 (S )D - --1.814 0 (R)A - --1.372 0 (100)A - --2.372 0 (0)A - --1.372 0 (0)A - --1.825 0 (@)A - --1.372 0 (200)A - -3.529 0 (M)A - --1.814 0 (H)A - --0.500 0 (z)A - -; - -1818 2118 N M 54 54 rr : 0 0 1.000 sco O ; 0 0 0 sco K : 1789 2097 988 100 rc 0 0 0 sco F0_87 - -Ji - -1897 2097 M - -0.814 0 (I)A - -0.843 0 (n)A - -0.029 0 (t)A - --1.372 0 (e)A - -1.000 0 32 0.814 0 (l )D - --1.029 0 (P)A - --0.029 0 (P)A - --1.814 0 (R)A - --2.686 0 (O)A - --1.825 0 (@)A - --1.372 0 (200)A - -2.529 0 (M)A - --0.814 0 (H)A - --0.500 0 (z)A - -; - -1721 889 N M 350 42 rr : 0.502 0 0 sco O ; - -1721 931 N M 350 69 rr : 0.502 0 0 sco O ; - -1721 1000 N M 350 43 rr : 0.502 0 0 sco O ; - -2071 889 N M 430 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco %%IncludeFont: Helvetica-BoldOblique - -(F6) cvn - -0.909 - - (Helvetica-BoldOblique) cvn /Type1 - -T - -(Helvetica-BoldOblique) cvn - -mF - -(F6_66) cvn - -F6 - -66 - -xF - -F6_66 - -Ji - -2121 891 M - -0.348 0 (N)A - --0.326 0 (u)A - --0.674 0 (m)A - -0.674 0 (b)A - --0.696 0 (e)A - --0.674 0 32 0.326 0 (r )D - --0.326 0 (o)A - -0.022 0 (f)A - -; - -2071 966 N M 430 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco F6_66 - -Ji - -2159 967 M - --0.022 0 (V)A - --0.696 0 (e)A - --0.674 0 (r)A - -0.022 0 (t)A - -0.652 0 (i)A - -0.304 0 (c)A - --0.696 0 (e)A - -0.304 0 (s)A - -; - -2501 889 N M 431 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco F6_66 - -Ji - -2551 891 M - -0.348 0 (N)A - --0.326 0 (u)A - --0.674 0 (m)A - -0.674 0 (b)A - --0.696 0 (e)A - --0.674 0 32 0.326 0 (r )D - --0.326 0 (o)A - -0.022 0 (f)A - -; - -2501 966 N M 431 77 rr : 0.502 0 0 sco O ; : 1697 889 1319 1131 rc 1.000 1.000 1.000 sco F6_66 - -Ji - -2618 967 M - --0.022 0 (E)A - --0.326 0 (dg)A - -0.304 0 (e)A - --0.696 0 (s)A - -; - -1721 1047 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1063 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco (F0_60) cvn - -F0 - -60 - -xF - -F0_60 - -Ji - -1738 1061 M - -0.020 0 (M)A - --0.660 0 (d)A - -0.340 0 (u)A - --0.360 0 (a)A - --0.680 0 (l)A - --0.360 0 (3)A - -; - -1721 1131 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1047 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1063 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1043 430 88 rc 0.004 0 0 sco (F3_60) cvn - -F3 - -60 - -xF - -F3_60 - -Ji - -2219 1065 M - --0.360 0 (4)A - -0.320 0 (,)A - --0.360 0 (039)A - --0.680 0 (,)A - -0.640 0 (1)A - --0.360 0 (60)A - -; - -2071 1131 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1047 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1063 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1043 431 88 rc 0.004 0 0 sco F3_60 - -Ji - -2649 1065 M - --0.360 0 (8)A - -0.320 0 (,)A - --0.360 0 (016)A - --0.680 0 (,)A - -0.640 0 (8)A - --0.360 0 (48)A - -; - -2501 1131 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1043 N M 350 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -1721 1043 N M 350 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2071 1043 N M 4 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2071 1043 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc - -2071 1043 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2075 1043 N M 426 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2075 1043 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2501 1043 N M 5 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2501 1043 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc - -2501 1043 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2506 1043 N M 426 4 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2506 1043 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -1721 1147 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1163 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1161 M - --0.320 0 (B)A - --0.680 0 (i)A - -0.340 0 (g)A - -; - -1721 1231 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1147 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1163 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1147 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2269 1165 M - --0.360 0 (2)A - -0.640 0 (9)A - --0.360 0 (5)A - --0.680 0 (,)A - --0.360 0 (433)A - -; - -2071 1231 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1147 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1163 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1147 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2649 1165 M - --0.360 0 (7)A - -0.320 0 (,)A - --0.360 0 (953)A - --0.680 0 (,)A - -0.640 0 (4)A - --0.360 0 (53)A - -; - -2501 1231 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1247 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1263 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1261 M - -0.020 0 (M)A - --0.660 0 (d)A - -0.340 0 (u)A - --0.360 0 (a)A - --0.680 0 (l)A - --0.360 0 (2)A - -; - -1721 1331 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1247 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1263 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1247 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2219 1265 M - --0.360 0 (1)A - -0.320 0 (,)A - --0.360 0 (017)A - --0.680 0 (,)A - -0.640 0 (2)A - --0.360 0 (53)A - -; - -2071 1331 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1247 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1263 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1247 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2649 1265 M - --0.360 0 (2)A - -0.320 0 (,)A - --0.360 0 (015)A - --0.680 0 (,)A - -0.640 0 (7)A - --0.360 0 (14)A - -; - -2501 1331 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1347 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1363 N M 350 68 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1361 M - --1.320 0 (A)A - --0.660 0 (u)A - -0.020 0 (t)A - -0.340 0 (o)A - -; - -1721 1431 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1347 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1363 N M 430 68 rr : 1.000 1.000 0.800 sco O ; : 2071 1347 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2269 1365 M - --0.360 0 (4)A - -0.640 0 (4)A - --0.360 0 (8)A - --0.680 0 (,)A - --0.360 0 (695)A - -; - -2071 1431 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1347 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1363 N M 431 68 rr : 1.000 1.000 0.800 sco O ; : 2501 1347 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2649 1365 M - --0.360 0 (3)A - -0.320 0 (,)A - --0.360 0 (314)A - --0.680 0 (,)A - -0.640 0 (6)A - --0.360 0 (11)A - -; - -2501 1431 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1447 N M 350 15 rr : 1.000 1.000 0.800 sco O ; - -1721 1462 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1461 M - --0.660 0 (T)A - --0.340 0 (r)A - -0.340 0 (o)A - --0.680 0 (l)A - -0.320 0 (l)A - -; - -1721 1531 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1447 N M 430 15 rr : 1.000 1.000 0.800 sco O ; - -2071 1462 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1447 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2269 1465 M - --0.360 0 (2)A - -0.640 0 (1)A - --0.360 0 (3)A - --0.680 0 (,)A - --0.360 0 (453)A - -; - -2071 1531 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1447 N M 431 15 rr : 1.000 1.000 0.800 sco O ; - -2501 1462 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1447 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2649 1465 M - --0.360 0 (5)A - -0.320 0 (,)A - --0.360 0 (885)A - --0.680 0 (,)A - -0.640 0 (8)A - --0.360 0 (29)A - -; - -2501 1531 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1547 N M 350 15 rr : 1.000 1.000 0.800 sco O ; - -1721 1562 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1561 M - -0.020 0 (M)A - --0.660 0 (d)A - -0.340 0 (u)A - --0.360 0 (a)A - --0.680 0 (l)A - --0.360 0 (1)A - -; - -1721 1631 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1547 N M 430 15 rr : 1.000 1.000 0.800 sco O ; - -2071 1562 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1547 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2269 1565 M - --0.360 0 (2)A - -0.640 0 (5)A - --0.360 0 (7)A - --0.680 0 (,)A - --0.360 0 (000)A - -; - -2071 1631 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1547 N M 431 15 rr : 1.000 1.000 0.800 sco O ; - -2501 1562 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1547 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2699 1565 M - --0.360 0 (5)A - -0.640 0 (0)A - --0.360 0 (5)A - --0.680 0 (,)A - --0.360 0 (048)A - -; - -2501 1631 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1647 N M 350 15 rr : 1.000 1.000 0.800 sco O ; - -1721 1662 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1661 M - --0.360 0 (1)A - -0.640 0 (4)A - --0.360 0 (4)A - -; - -1721 1731 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1647 N M 430 15 rr : 1.000 1.000 0.800 sco O ; - -2071 1662 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1647 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2269 1665 M - --0.360 0 (1)A - -0.640 0 (4)A - --0.360 0 (4)A - --0.680 0 (,)A - --0.360 0 (649)A - -; - -2071 1731 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1647 N M 431 15 rr : 1.000 1.000 0.800 sco O ; - -2501 1662 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1647 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2649 1665 M - --0.360 0 (1)A - -0.320 0 (,)A - --0.360 0 (074)A - --0.680 0 (,)A - -0.640 0 (3)A - --0.360 0 (93)A - -; - -2501 1731 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1747 N M 350 15 rr : 1.000 1.000 0.800 sco O ; - -1721 1762 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1761 M - --0.680 0 (O)A - --0.360 0 (ce)A - -0.640 0 (a)A - --0.660 0 (n)A - -; - -1721 1831 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1747 N M 430 15 rr : 1.000 1.000 0.800 sco O ; - -2071 1762 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1747 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2269 1765 M - --0.360 0 (1)A - -0.640 0 (4)A - --0.360 0 (3)A - --0.680 0 (,)A - --0.360 0 (437)A - -; - -2071 1831 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1747 N M 431 15 rr : 1.000 1.000 0.800 sco O ; - -2501 1762 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1747 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2699 1765 M - --0.360 0 (4)A - -0.640 0 (0)A - --0.360 0 (9)A - --0.680 0 (,)A - --0.360 0 (593)A - -; - -2501 1831 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1847 N M 350 15 rr : 1.000 1.000 0.800 sco O ; - -1721 1862 N M 350 69 rr : 1.000 1.000 0.800 sco O ; : 1697 889 1319 1131 rc 0.004 0 0 sco F0_60 - -Ji - -1738 1861 M - --0.320 0 (B)A - --0.340 0 (r)A - --0.360 0 (ack)A - -0.640 0 (2)A - -; - -1721 1931 N M 350 16 rr : 1.000 1.000 0.800 sco O ; - -2071 1847 N M 430 15 rr : 1.000 1.000 0.800 sco O ; - -2071 1862 N M 430 69 rr : 1.000 1.000 0.800 sco O ; : 2071 1847 430 84 rc 0.004 0 0 sco F3_60 - -Ji - -2302 1865 M - --0.360 0 (6)A - -0.640 0 (2)A - --0.680 0 (,)A - --0.360 0 (631)A - -; - -2071 1931 N M 430 16 rr : 1.000 1.000 0.800 sco O ; - -2501 1847 N M 431 15 rr : 1.000 1.000 0.800 sco O ; - -2501 1862 N M 431 69 rr : 1.000 1.000 0.800 sco O ; : 2501 1847 431 84 rc 0.004 0 0 sco F3_60 - -Ji - -2699 1865 M - --0.360 0 (3)A - -0.640 0 (6)A - --0.360 0 (6)A - --0.680 0 (,)A - --0.360 0 (559)A - -; - -2501 1931 N M 431 16 rr : 1.000 1.000 0.800 sco O ; - -1721 1947 N M 350 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -1721 1947 N M 350 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2071 1947 N M 4 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2071 1947 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc - -2071 1947 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2075 1947 N M 426 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2075 1947 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2501 1947 N M 5 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2501 1947 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1697 889 1319 1131 rc - -2501 1947 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2506 1947 N M 426 5 rr : 0 0 0 sco O ; : 1697 889 1319 1131 rc - -2506 1947 N M 426 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -LH - -pagesave restore - - - - - - - -/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec - -Pscript_Win_Compat dup /terminate get exec - - -cleartomark -countdictstack exch sub { end } repeat -restore grestore -% -% End Imported PIC File: slide1.eps -% -% Polyline -% -% Begin Imported EPS File: slide2.eps -% -n gs -525 9750 tr -16.980000 -16.972921 sc -0 -517 tr --39 -55 tr -sa -n 39 55 m 739 55 l 739 572 l 39 572 l cp clip -countdictstack -mark -/showpage {} def -% EPS file follows: - - - - - - - - - - - - - - -/defineresource where{pop}{userdict begin/defineresource{userdict/Resources 2 - -copy known{get begin}{15 dict dup begin put}ifelse exch readonly exch - -currentdict 1 index known not{dup 30 dict def}if load 3 -1 roll 2 index put - -end}bind readonly def/findresource{userdict/Resources get exch get exch get} - -bind readonly def/resourceforall{pop pop pop pop}bind readonly def - -/resourcestatus{userdict/Resources 2 copy known{get exch 2 copy known{get exch - -known{0 -1 true}{pop pop false}ifelse}{pop pop pop false}ifelse}{pop pop false - -}ifelse}bind readonly def end}ifelse - - - -/Pscript_Win_Driver 200 dict dup begin - - -/FatalErrorIf{{initgraphics findfont exch scalefont setfont counttomark 3 div - -cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def - - -/VM? {vmstatus exch sub exch pop gt { [ - -(This job requires more memory than is available in this printer.) 100 500 - -(Try one or more of the following, and then print again:) 100 485 - -(In the PostScript dialog box, click Optimize For Portability.) 115 470 - -(In the Device Options dialog box, make sure the Available Printer Memory is accurate.) 115 455 - -(Reduce the number of fonts in the document.) 115 440 - -(Print the document in parts.) 115 425 - -12 /Times-Roman showpage - -(%%[ PrinterError: Low Printer VM ]%%) = - -true FatalErrorIf}if} bind def - - -/|/def load def/,/load load |/~/exch , |/?/ifelse , |/!/pop , |/`/begin , |/^ - -/index , |/@/dup , |/+/translate , |/$/roll , |/U/userdict , |/M/moveto , |/- - -/rlineto , |/&/currentdict , |/:/gsave , |/;/grestore , |/F/false , |/T/true , - -|/N/newpath , |/E/end , |/Ac/arc , |/An/arcn , |/A/ashow , |/D/awidthshow , | - -/C/closepath , |/V/div , |/O/eofill , |/L/fill , |/I/lineto , |/-C/rcurveto , - -|/-M/rmoveto , |/+S/scale , |/Ji/setfont , |/Lc/setlinecap , |/Lj/setlinejoin - -, |/Lw/setlinewidth , |/S/show , |/LH/showpage , |/K/stroke , |/W/widthshow , - -|/R/rotate , |/b{bind |}bind |/bd{bind |}bind |/xd{~ |}bd/ld{, |}bd/lw/Lw ld - -/lc/Lc ld/lj/Lj ld/sg/setgray ld/L2? F/languagelevel where{! languagelevel 2 - -ge{! T}if}if |/g{@ not{U/DefIf_save save put}if U/DefIf_bool 2 ^ put}b - -/DefIf_El{if U/DefIf_bool get not @{U/DefIf_save get restore}if}b/e{DefIf_El ! - -}b/self & |/reinitialize{[/TextInit/GraphInit/UtilsInit counttomark{@ where{ - -self eq}{F}?{cvx exec}{!}?}repeat cleartomark}b/initialize{`{/ADO_mxRot ~ | - -/TextInitialised? F | reinitialize E}{U/Pscript_Win_Data 200 dict @ ` put - -/ADO_mxRot ~ |/TextInitialised? F | reinitialize}?}b/terminate{!{& self eq{ - -exit}{E}?}loop E}b/suspend/terminate , |/resume{` Pscript_Win_Data `}b/snap{ - -transform 0.25 sub round 0.25 add ~ 0.25 sub round 0.25 add ~ itransform}b - -/dsnap{dtransform round ~ round ~ idtransform}b<04>cvn{}|/setjn{{statusdict - -/jobname known{statusdict/jobname 3 -1 $ put}if}stopped cleartomark}b/solid{[] - -0 setdash}b/setdsh{0 setdash}b/colspRefresh{}b/rp{4 2 $ M 1 ^ 0 - 0 ~ - neg 0 - --}b/rr{1 ^ 0 - 0 ~ - neg 0 - C}b - - - -L2? not g{/rf{N rp L}b/fx{1 1 dtransform @ 0 ge{1 sub 1}{1 add -0.25}? 3 -1 $ - -@ 0 ge{1 sub 1}{1 add -0.25}? 3 1 $ 4 1 $ idtransform 4 -2 $ idtransform}b/BZ{ - -4 -2 $ snap + +S fx rf}b/rs{N rp C K}b/rc{N rp clip N}b/sg{setgray}b/sco{ - -setrgbcolor}b/sgco{{sg}{sco}?}b}e - - - -L2? g{/colspA/DeviceGray |/colspABC/DeviceRGB |/setAorABC{{colspA}{colspABC}? - -setcolorspace}b/rf/rectfill , |/fx{1 1 dtransform @ 0 ge{1 sub 0.5}{1 add -0.5 - -}? 3 -1 $ @ 0 ge{1 sub 0.5}{1 add -0.5}? 3 1 $ 4 1 $ idtransform 4 -2 $ - -idtransform}b/BZ{4 -2 $ snap + +S fx rf}b/rs/rectstroke , |/rc/rectclip , |/sg - -{@ @ setcolor}b/sco{setcolor}b/colspRefresh{colspABC setcolorspace}b/sgco{{sg - -}{sco}?}b/UtilsInit{F setglobal}b/definecolorrendering{/ColorRendering - -defineresource !}b/findcolorrendering{@/ColorRendering resourcestatus{! ! - -/ColorRendering findresource T}{! F}?}b/selectcolorrendering{@/ColorRendering - -resourcestatus{! !/ColorRendering}{!/DefaultColorRendering/ColorRendering}? - -findresource setcolorrendering}b}e - - - -/bullets{{/bullet}repeat}b/ANSIEncoding[/grave/acute/circumflex/tilde/macron - -/breve/dotaccent/dieresis/ring/cedilla/hungarumlaut/ogonek/caron/dotlessi 18 - -bullets StandardEncoding 32 95 getinterval aload ! 3 bullets/quotesinglbase - -/florin/quotedblbase/ellipsis/dagger/daggerdbl/circumflex/perthousand/Scaron - -/guilsinglleft/OE 4 bullets/quoteleft/quoteright/quotedblleft/quotedblright - -/bullet/endash/emdash/tilde/trademark/scaron/guilsinglright/oe 2 bullets - -/Ydieresis/space/exclamdown/cent/sterling/currency/yen/brokenbar/section - -/dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered - -/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph - -/periodcentered/cedilla/onesuperior/ordmasculine/guillemotright/onequarter - -/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis - -/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute - -/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis - -/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls - -/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute - -/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve - -/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex - -/udieresis/yacute/thorn/ydieresis]| ANSIEncoding @ 39/quotesingle put 96/grave - -put/ANSIEncodingOld ANSIEncoding 256 array copy | ANSIEncodingOld @[138 153 - -154 169 172 174 177 178 179 181 185 188 189 190 208 215 221 222 240 247 253 - -254]{/bullet put @}forall 166/bar put 176/ring put - - - -/TextInit{TextInitialised? not{/Pscript_Windows_Font & |/TextInitialised? T | - -/fM[1 0 0 -1 0 0]|/mFM matrix |/iMat[1 0 0.212557 neg 1 0 0]|}if}b/xUP null | - -/yUP null |/uW null |/xSP null |/ySP null |/sW null |/copyfont{1 ^ length add - -dict `{1 ^/FID ne{|}{! !}?}forall & E}b/rF{3 copyfont @ `/Encoding - -ANSIEncoding &/CharStrings known{CharStrings/Eth known not{! ANSIEncodingOld} - -if}if | E}b/mF{findfont ~{@/Encoding get @ StandardEncoding eq{! T}{{ - -ISOLatin1Encoding}stopped{! F}{eq}?{T}{@ ` T 32 1 127{Encoding 1 ^ get - -StandardEncoding 3 -1 $ get eq and}for E}?}?}{F}?{rF}{3 copyfont}? ` - -/OrigFontType ~ |/OrigFontName ~ | & E 2 ^ ~ definefont fM 5 4 -1 $ put fM 4 0 - -put fM makefont Pscript_Windows_Font 3 1 $ put}b/xF{scalefont - -Pscript_Windows_Font 3 1 $ put}b/xMF{mFM astore makefont Pscript_Windows_Font - -3 1 $ put}b/xF2/scalefont , |/xMF2{mFM astore makefont}b/sLT{: Lw -M - -currentpoint snap M 0 - 0 Lc K ;}b/sSU{N/uW ~ |/yUP ~ |/xUP ~ |}b/sU{xUP yUP - -uW sLT}b/sST{N/sW ~ |/ySP ~ |/xSP ~ |}b/sT{xSP ySP sW sLT}b/sR{: + R 0 0 M}b - -/sRxy{: matrix astore concat 0 0 M}b/eR/; , | - - - -/mBF{@ 4 copyfont `/FontName ~ |/OrigFontType ~ |/OrigFontName ~ | 0 - -FontMatrix idtransform ! &/PaintType known{PaintType 0 eq{/PaintType 2 | - -/StrokeWidth ~ |}{PaintType 1 eq PaintType 2 eq or PaintType 3 eq or & - -/StrokeWidth known and{StrokeWidth add/StrokeWidth ~ |}{!}?}?}{!}? @ & E - -definefont Pscript_Windows_Font 3 1 $ put}b/xBF{Pscript_Windows_Font ` 1 ^ - -/FontName get 1 ^ scalefont 3 1 $ scalefont 2 copy ~ | ~ ! | E}b/xMBF{mFM - -astore Pscript_Windows_Font ` 1 ^/FontName get 1 ^ makefont 3 1 $ makefont 2 - -copy ~ | ~ ! | E}b/xBF2{/sB0 ~ mBF/sB1 sB0 3 -1 $ xBF sB1}b/xMBF2{/sB0 ~ mBF - -mFM astore/sB1 sB0 3 -1 $ xMBF sB1}b/sB{: Pscript_Windows_Font currentfont get - -Ji @ S ; S}b/asB{: Pscript_Windows_Font currentfont get Ji 3 copy A ; A}b/wsB{ - -: Pscript_Windows_Font currentfont get Ji 4 copy W ; W}b/awsB{: - -Pscript_Windows_Font currentfont get Ji 6 copy D ; D}b/sBT3{: @ S ; 1 1 -M S}b - -/asBT3{: 3 copy A ; 1 1 -M A}b/wsBT3{: 4 copy W ; 1 1 -M W}b/awsBT3{: 6 copy D - -; 1 1 -M D}b/mIF{iMat 4 3 -1 $ put 2 copyfont `/OrigFontType ~ |/OrigFontName - -~ | @ & E definefont iMat makefont Pscript_Windows_Font 3 1 $ put}b - - - -/SavedCTM null |/CTMsave{/SavedCTM SavedCTM currentmatrix |}b/CTMrestore{ - -SavedCTM setmatrix}b/mp null |/ADO_mxRot null |/GDIHMatrix null | - -/GDIHPatternDict 22 dict | GDIHPatternDict `/PatternType 1 |/PaintType 2 | - -/Reps L2?{1}{5}? |/XStep 8 Reps mul |/YStep XStep |/BBox[0 0 XStep YStep]| - -/TilingType 1 |/PaintProc{` 1 Lw[]0 setdash PaintData , exec E}b/FGnd null | - -/BGnd null |/HS_Horizontal{horiz}b/HS_Vertical{vert}b/HS_FDiagonal{fdiag}b - -/HS_BDiagonal{biag}b/HS_Cross{horiz vert}b/HS_DiagCross{fdiag biag}b/MaxXYStep - -XStep YStep gt{XStep}{YStep}? |/horiz{Reps{0 4 M XStep 0 - 0 8 +}repeat 0 -8 - -Reps mul + K}b/vert{Reps{4 0 M 0 YStep - 8 0 +}repeat 0 -8 Reps mul + K}b/biag - -{Reps{0 0 M MaxXYStep @ - 0 YStep neg M MaxXYStep @ - 0 8 +}repeat 0 -8 Reps - -mul + 0 YStep M 8 8 - K}b/fdiag{Reps{0 0 M MaxXYStep @ neg - 0 YStep M - -MaxXYStep @ neg - 0 8 +}repeat 0 -8 Reps mul + MaxXYStep @ M 8 -8 - K}b E - -/makehatch{GDIHPatternDict/PaintData 3 -1 $ put CTMsave GDIHMatrix setmatrix - -GDIHPatternDict matrix mp CTMrestore ~ U ~ 2 ^ put}b/h0{/h0/HS_Horizontal - -makehatch}b/h1{/h1/HS_Vertical makehatch}b/h2{/h2/HS_FDiagonal makehatch}b/h3{ - -/h3/HS_BDiagonal makehatch}b/h4{/h4/HS_Cross makehatch}b/h5{/h5/HS_DiagCross - -makehatch}b/GDIBWPatternDict 17 dict @ `/PatternType 1 |/PaintType L2?{1}{2}? - -|/RepsV L2?{1}{6}? |/RepsH L2?{1}{5}? |/BBox[0 0 RepsH 1]|/TilingType 1 | - -/XStep 1 |/YStep 1 |/Height 8 RepsV mul |/Width 8 |/mx[Width 0 0 Height neg 0 - -Height]|/FGnd null |/BGnd null |/SetBGndFGnd L2?{{BGnd null ne{BGnd aload ! - -sgco BBox aload ! 2 ^ sub ~ 3 ^ sub ~ rf}if FGnd null ne{FGnd aload ! sgco}if} - -}{{}}? b/PaintProc{` SetBGndFGnd RepsH{Width Height F mx PaintData imagemask - -Width 0 +}repeat E}b E |/GDIBWPatternMx null |/pfprep{save 4 1 $ - -/PatternOfTheDay 4 1 $ GDIBWPatternDict `/PaintData ~ |/BGnd ~ |/FGnd ~ | E - -CTMsave GDIBWPatternMx setmatrix GDIBWPatternDict matrix mp CTMrestore ~ !}b - -/hrf null |/prf{pfprep ~ 6 1 $ 5 hrf restore}b/GraphInit{GDIHMatrix null eq{ - -/SavedCTM matrix | : ADO_mxRot concat 0 0 snap + : 0.48 @ GDIHPatternDict ` - -YStep mul ~ XStep mul ~ dsnap YStep V ~ XStep V ~ E +S/GDIHMatrix matrix - -currentmatrix readonly | ; : 0.24 -0.24 +S GDIBWPatternDict ` Width Height E - -dsnap +S/GDIBWPatternMx matrix currentmatrix readonly | ; ;}if}b/cirp{360 0 An - -C}b/ellp{CTMsave + +S 0.5 0 M 0 0 0.5 360 0 An C CTMrestore}b/rrp{/rad ~ |/y2 - -~ |/x2 ~ |/y1 ~ |/x1 ~ | x2 x1 add 2 V y1 M x1 y1 x1 y2 rad arct x1 y2 x2 y2 - -rad arct x2 y2 x2 y1 rad arct x2 y1 x1 y1 rad arct C}b/RRp{CTMsave + +S/dyS ~ - -|/dxS ~ | dxS 2 V 0 M 0 0 0 dyS 0.5 arct 0 dyS dxS dyS 0.5 arct dxS dyS dxS 0 - -0.5 arct dxS 0 0 0 0.5 arct C CTMrestore}b - - - -L2? not g{/arct{arcto ! ! ! !}b/GDIpattfill{@ ` BGnd null ne PaintType 2 eq - -and{: BGnd aload ! sgco fEOFill{O}{L}? ; FGnd aload ! U/fGray 2 ^ put{2}{4}? - --1 $}if E @ patterncalc : 4 ^/PaintType get 2 eq{fGray{6 -1 $ sg}{8 -3 $ sco}? - -}if fEOFill{eoclip}{clip}? N patternfill ; N}b/hrf{/fGray 1 ^ 6 eq | -4 $ N rp - -C/fEOFill F | GDIpattfill}b/hfMain{/fEOFill ~ |/fGray ~ | GDIpattfill}b/hf{T - -hfMain}b/hfW{F hfMain}b/hs{currentpoint strokepath M hfW}b/pfMain{/fEOFill ~ | - -pfprep GDIpattfill restore N}b/pf{T pfMain}b/pfW{F pfMain}b/ps{currentpoint - -strokepath M pfW}b/mpstr 1 string |/mp{~ @ length 12 add dict copy ` - -/PatternCTM matrix currentmatrix |/PatternMatrix ~ |/PatWidth XStep mpstr - -length mul |/PatHeight YStep |/FontType 3 |/Encoding 256 array | 3 string 0 1 - -255{Encoding ~ @ 3 ^ cvs cvn put}for !/FontMatrix matrix |/FontBBox BBox | - -/BuildChar{! @ ` XStep 0 FontBBox aload ! setcachedevice/PaintProc , E : exec - -;}b & E ~ @ 3 -1 $ definefont}b/patterncalc{` : PatternCTM setmatrix - -PatternMatrix concat BBox aload ! ! ! + pathbbox ; PatHeight V ceiling 4 1 $ - -PatWidth V ceiling 4 1 $ PatHeight V floor 4 1 $ PatWidth V floor 4 1 $ 2 ^ - -sub cvi abs ~ 3 ^ sub cvi abs ~ 4 2 $ PatHeight mul ~ PatWidth mul ~ E}b - -/patternfill{5 -1 $ @ ` Ji PatternCTM setmatrix PatternMatrix concat 0 2 ^ 2 ^ - -M 0 1 mpstr length 1 sub{1 ^ mpstr 3 1 $ put}for ! 2 ^{currentpoint 5 ^{mpstr - -S}repeat YStep add M}repeat ! ! ! ! E}b}e - - - -L2? g{/mp/makepattern , |/hrf{6 eq setAorABC setpattern rectfill}b/hf{ - -setAorABC setpattern O}b/hfW{setAorABC setpattern L}b/hs{setAorABC setpattern - -K}b/pf{pfprep setpattern O restore N}b/pfW{pfprep setpattern L restore N}b/ps{ - -pfprep setpattern K restore N}b}e - - - -/iw 0 |/ih 0 |/im_save 0 |/s 0 |/polarity 0 |/smoothflag 0 |/mystring 0 |/bpc - -0 |/setup1asciiproc{[currentfile mystring/readhexstring cvx/! cvx]cvx bind}b - -/setup1binaryproc{[currentfile mystring/readstring cvx/! cvx]cvx bind}b - -/setup2asciiproc{currentfile/ASCII85Decode filter/RunLengthDecode filter}b - -/setup2binaryproc{currentfile/RunLengthDecode filter}b/mycolorspace{colspABC}| - -/myimagedict{/myimagedict 10 dict | myimagedict @ `/ImageType 1 | - -/MultipleDataSource F | E}b/imageprocarray[/setup1binaryproc/setup1asciiproc - -/setup2binaryproc/setup2asciiproc/setup1binarydecodeproc/setup1asciidecodeproc - -]|/L2Polarity{{[1 0]}{[0 1]}?}b/Q{/im_save save | imageprocarray ~ get/s ~ , | - -L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring ~ - -string |/bpc ~ |/ih ~ |/iw ~ |}b/X{/im_save save | imageprocarray ~ get/s ~ , - -| L2Polarity/polarity ~ |/smoothflag ~ | snap +/dx 2 ^ |/dy 1 ^ | +S/mystring - -~ string |/bpc ~ |/ih ~ |/iw ~ |}b/Z{im_save restore}b/Y{sgco myimagedict @ ` - -/Width iw |/Height ih |/Decode polarity |/ImageMatrix[iw 0 0 ih 0 0]| - -/DataSource s |/BitsPerComponent 1 |/Interpolate smoothflag | E imagemask}b - - - -L2? not g{/setup2asciiproc{[/Level2ImagesError , aload ! T FatalErrorIf}b - -/setup2binaryproc/setup2asciiproc , |/L2Polarity{}|/Y{sgco iw ih polarity[iw 0 - -0 ih 0 0]s imagemask}b}e - - - -L2? not g{/testsystemdict{where{systemdict eq{T}{F}?}{F}?}b/c 1 |/colorimage - -where{! T}{F}?{/c 0 statusdict `/processcolors where{! ! processcolors}{ - -/deviceinfo where{! deviceinfo/Colors known{!{deviceinfo/Colors get}}if}if}? E - -| c 0 ne{/colorimage testsystemdict/setcolortransfer testsystemdict - -/currentcolortransfer testsystemdict/currentcmykcolor testsystemdict and and - -and not{/c 0 |}if}if}if c @ 1 ne ~ @ 3 ne ~ 4 ne and and{/c 0 |}if c 1 eq g{ - -/expandbw{expandfactor mul round cvi bwclut ~ get 255 V}b/doclutimage{!/bwclut - -~ | bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/expandfactor ~ |[/expandbw ,/exec , @ - -currenttransfer ~]cvx bind settransfer iw ih bpc[iw 0 0 ih 0 0]s image}b}e c @ - -3 eq ~ 4 eq or g{/nullproc{{}}|/concatutil{/exec , 7 -1 $/exec ,}b/defsubclut{ - -1 add getinterval |}b/spconcattransfer{/Dclut ~ |/Cclut ~ |/Bclut ~ |/Aclut ~ - -|/ncompute ~ , | currentcolortransfer[{Aclut ncompute}concatutil]cvx[{Bclut - -ncompute}concatutil]cvx[{Cclut ncompute}concatutil]cvx[{Dclut ncompute} - -concatutil]cvx setcolortransfer}b/setuprgbcluts{/bit3x rgbclut length 3 sub | - -/bit1x bit3x 3 idiv |/rclut rgbclut |/gclut rclut 1 bit3x defsubclut/bclut - -rclut 2 bit3x defsubclut}b}e c 3 eq g{/3compute{~ bit3x mul round cvi get 255 - -V}b/doclutimage{/rgbclut ~ | ! setuprgbcluts/3compute rclut gclut bclut @ - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @]cvx nullproc nullproc - -T 3 colorimage}b}e c 4 eq g{/ftoint{1 ~ sub 255 mul round cvi}b/stuffclut{ - -cmykindex 3 -1 $ put}b/4compute{~ bit4x mul round cvi get 255 V}b - -/invalidcolortable? T |/computecmykclut{setuprgbcluts/bit4x rgbclut length 3 - -idiv 4 mul 4 sub |/cmykclut bit4x 4 add string |/cclut cmykclut |/mclut cclut - -1 bit4x defsubclut/yclut cclut 2 bit4x defsubclut/kclut cclut 3 bit4x - -defsubclut/cmykindex 0 | 0 1 bit1x{@/cmykindex ~ bit1x ~ sub 4 mul | 3 mul @ - -rclut ~ get 255 V ~ @ gclut ~ get 255 V ~ bclut ~ get 255 V setrgbcolor - -currentcmykcolor ftoint kclut stuffclut ftoint yclut stuffclut ftoint mclut - -stuffclut ftoint cclut stuffclut}for}b/doclutimage{/rgbclut ~ | ! - -invalidcolortable?{computecmykclut}if/4compute cclut mclut yclut kclut - -spconcattransfer iw ih bpc[iw 0 0 ih 0 0][s/exec ,/@ , @ @]cvx nullproc - -nullproc nullproc T 4 colorimage}b}e c 0 eq g{/a{3 mul 3 getinterval - -putinterval ~ 3 add ~ 3 copy}b/8lookup/a , |/4lookup{/byte 1 ^ | -4 bitshift a - -byte 15 and a}b/2lookup{/byte 1 ^ | -6 bitshift a byte -4 bitshift 3 and a - -byte -2 bitshift 3 and a byte 3 and a}b/colorexpand{mystringexp 0 rgbclut 3 - -copy 7 -1 $/mylookup , forall ! ! ! ! !}b/createexpandstr{/mystringexp ~ - -mystring length mul string |}b/doclutimage{/rgbclut ~ | !/mylookup bpc 8 eq{3 - -createexpandstr/8lookup}{bpc 4 eq{6 createexpandstr/4lookup}{12 - -createexpandstr/2lookup}?}? , | iw ih bpc[iw 0 0 ih 0 0][s/exec ,/colorexpand - -,/exec ,]cvx F 3 colorimage}b}e/colorimage where{! T}{F}? g{/do24image{iw ih 8 - -[iw 0 0 ih 0 0]s F 3 colorimage}b}DefIf_El{/rgbtogray{/str ~ |/len str length - -|/smlen len 3 idiv |/rstr str |/gstr str 1 len 1 sub getinterval |/bstr str 2 - -len 2 sub getinterval | str @ 0 1 smlen 1 sub{@ 3 mul rstr 1 ^ get 0.3 mul - -gstr 2 ^ get 0.59 mul add bstr 3 -1 $ get 0.11 mul add round cvi put @}for ! 0 - -smlen getinterval}b/do24image{iw ih 8[iw 0 0 ih 0 0][s/exec ,/rgbtogray ,/exec - -,]cvx bind image}b}e/doNimage{bpc 24 eq{do24image}{iw ih bpc[iw 0 0 ih 0 0]s - -image}?}b}e - - - -L2? g{/doclutimage{/rgbclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[ - -/Indexed colspABC hival rgbclut]setcolorspace myimagedict @ `/Width iw | - -/Height ih |/Decode[0 hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s | - -/BitsPerComponent bpc |/Interpolate smoothflag | E image}b/doCMYKclutimage{ - -/CMYKclut ~ | ! bpc @ 8 eq{! 255}{4 eq{15}{3}?}?/hival ~ |[/Indexed/DeviceCMYK - -hival CMYKclut]setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 - -hival]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent bpc | - -/Interpolate smoothflag | E image}b/doNimage{bpc 24 eq{colspABC}{colspA}? - -setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode bpc 24 eq{[0 1 0 1 - -0 1]}{[0 1]}? |/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent - -bpc 24 eq{8}{bpc}? |/Interpolate smoothflag | E image}b/doCMYKimage{ - -/DeviceCMYK setcolorspace myimagedict @ `/Width iw |/Height ih |/Decode[0 1 0 - -1 0 1 0 1]|/ImageMatrix[iw 0 0 ih 0 0]|/DataSource s |/BitsPerComponent 8 | - -/Interpolate smoothflag | E image}b}e - - - -/GreNewFont{10 dict @ 3 1 $ | @ ` 4 1 $/FontType 3 |/FontMatrix ~ |/FontBBox ~ - -|/Encoding 256 array | 0 1 255{Encoding ~/.notdef put}for/CharProcs 257 dict | - -CharProcs/.notdef{}put/Metrics 257 dict | Metrics/.notdef 3 -1 $ put/BuildChar - -{/char ~ |/fontdict ~ |/charname fontdict/Encoding get char get | fontdict - -/Metrics get charname get aload ! setcachedevice fontdict ` Encoding char get - -CharProcs ~ get E exec}| E definefont !}|/AddChar{` Encoding 3 1 $ put - -CharProcs 3 1 $ put Metrics 3 1 $ put E}| - - - -/FEbuf 2 string |/FEglyph 3 string |/FE{(G00)FEglyph copy ! 1 ~{@ 16 lt{ - -/offset 2 store}{/offset 1 store}? @ 16 FEbuf cvrs FEglyph ~ offset ~ - -putinterval 1 ^ ~ FEglyph cvn put}for}bind |/Type1Hdr{11 dict `/FontName ~ | - -/PaintType ~ |/FontType 1 |/FontMatrix[1 3 ^ V 0 0 1 6 ^ V 0 0]| !/Encoding - -256 array 0 1 255{1 ^ ~/.notdef put}for 3 ^ 3 ^ FE | ! !/FontBBox{0 0 0 0}| & - -E currentfile eexec}bind | - - -/pp 1 string |/ss 1 string |/rledecodebinary{/DC 0 |/BC 0 |{DC mystring length - -ge{exit}if currentfile ss readstring ! 0 get/BC ~ | BC 127 le{/BC BC 1 add | - -DC 1 DC BC add 1 sub{mystring ~ currentfile ss readstring ! 0 get put}for}{/BC - -257 BC sub | currentfile ss readstring ! 0 get/pp ~ | DC 1 DC BC add 1 sub{ - -mystring ~ pp put}for}?/DC DC BC add |}loop mystring}b/rledecodeascii{/DC 0 | - -/BC 0 |{DC mystring length ge{exit}if currentfile ss readhexstring ! 0 get/BC - -~ | BC 127 le{/BC BC 1 add | DC 1 DC BC add 1 sub{mystring ~ currentfile ss - -readhexstring ! 0 get put}for}{/BC 257 BC sub | currentfile ss readhexstring ! - -0 get/pp ~ | DC 1 DC BC add 1 sub{mystring ~ pp put}for}?/DC DC BC add |}loop - -mystring}b/setup1asciidecodeproc{[/rledecodeascii cvx]cvx bind}b - -/setup1binarydecodeproc{[/rledecodebinary cvx]cvx bind}b - - -userdict/Pscript_Win_Compat 13 dict dup begin/bd{bind def}bind def/ld{load def - -}bd/CB{pop pop pop pop}bind def/B{pop pop pop pop}bind def/$x matrix def/SS{ - -/pagesave save def}bind def/RS{/pagesave where{pop pagesave restore}{$x matrix - -invertmatrix concat}ifelse}bind def/ANSIVec[0/grave 1/acute 2/circumflex 3 - -/tilde 4/macron 5/breve 6/dotaccent 7/dieresis 8/ring 9/cedilla 10 - -/hungarumlaut 11/ogonek 12/caron 13/dotlessi 39/quotesingle 96/grave 124/bar - -130/quotesinglbase 131/florin 132/quotedblbase 133/ellipsis 134/dagger 135 - -/daggerdbl 136/circumflex 137/perthousand 138/Scaron 139/guilsinglleft 140/OE - -145/quoteleft 146/quoteright 147/quotedblleft 148/quotedblright 149/bullet 150 - -/endash 151/emdash 152/tilde 153/trademark 154/scaron 155/guilsinglright 156 - -/oe 159/Ydieresis 160/space 161/exclamdown 164/currency 165/yen 166/brokenbar - -167/section 168/dieresis 169/copyright 170/ordfeminine 171/guillemotleft 172 - -/logicalnot 173/hyphen 174/registered 175/macron 176/degree 177/plusminus 178 - -/twosuperior 179/threesuperior 180/acute 181/mu 182/paragraph 183 - -/periodcentered 184/cedilla 185/onesuperior 186/ordmasculine 187 - -/guillemotright 188/onequarter 189/onehalf 190/threequarters 191/questiondown - -192/Agrave 193/Aacute 194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198 - -/AE 199/Ccedilla 200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204 - -/Igrave 205/Iacute 206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve - -211/Oacute 212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash - -217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn 223 - -/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde 228/adieresis 229 - -/aring 230/ae 231/ccedilla 232/egrave 233/eacute 234/ecircumflex 235/edieresis - -236/igrave 237/iacute 238/icircumflex 239/idieresis 240/eth 241/ntilde 242 - -/ograve 243/oacute 244/ocircumflex 245/otilde 246/odieresis 247/divide 248 - -/oslash 249/ugrave 250/uacute 251/ucircumflex 252/udieresis 253/yacute 254 - -/thorn 255/ydieresis]def currentdict{dup type/operatortype eq{[exch]cvx def}{ - -pop pop}ifelse}forall/initialize{currentdict exch begin begin}bind def - -/terminate{/@FL where not{pop end end}{pop}ifelse}bind def/suspend/terminate - -load def/resume/initialize load def/M/moveto load def end put/Courier findfont - -10 scalefont setfont - - -end /ProcSet defineresource pop - - - - - - -Pscript_Win_Compat dup /initialize get exec - -[ 0 1.000 -1.000 0 0 0 ] false /Pscript_Win_Driver /ProcSet findresource dup /initialize get exec - - - - - -/mysetup [ 0.240 0 0 -0.240 7.920 592.800 ] | - - - - - - -userdict begin /pagesave save def end mysetup concat colspRefresh : 1.000 1.000 1.000 sco 0 0 2550 3300 rf ; - - - - - - -116 70 N M 1 1 rr - -116 70 N M 3000 2250 rr : 1.000 1.000 1.000 sco O ; - -116 70 N M 1 1 rr - -116 70 N M 1 1 rr - -133 87 N M 2904 2146 rr 10 Lw 0 Lc 0 Lj solid 0 0 0 sco K - -579 456 N M 2416 1561 rr : 1.000 0.800 0.600 sco O ; - -579 456 N M 2416 0 - 3 Lw 1 Lc 1 Lj solid 0 0 0 sco K - -2995 456 N M 0 1561 - 0 0 0 sco K - -2995 2017 N M -2416 0 - 0 0 0 sco K - -579 2017 N M 0 -1561 - 0 0 0 sco K - -579 1947 N M 73 56 rr : 1.000 1.000 0 sco O ; 0 Lc 0 Lj 0 0 0 sco K - -579 1774 N M 177 55 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 1600 N M 215 55 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 1426 N M 274 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 1252 N M 285 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 1082 N M 319 55 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 908 N M 476 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 734 N M 845 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 560 N M 1074 56 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K - -579 1864 N M 121 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 1690 N M 319 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 1516 N M 274 53 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 1343 N M 330 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 1169 N M 532 55 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 998 N M 528 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 824 N M 911 53 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 651 N M 1617 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 477 N M 1968 52 rr : 0 0 1.000 sco O ; 0 0 0 sco K - -579 456 N M 0 1561 - 1 Lc 1 Lj 0 0 0 sco K - -558 2017 N M 21 0 - 0 0 0 sco K - -558 1843 N M 21 0 - 0 0 0 sco K - -558 1669 N M 21 0 - 0 0 0 sco K - -558 1495 N M 21 0 - 0 0 0 sco K - -558 1322 N M 21 0 - 0 0 0 sco K - -558 1151 N M 21 0 - 0 0 0 sco K - -558 977 N M 21 0 - 0 0 0 sco K - -558 804 N M 21 0 - 0 0 0 sco K - -558 630 N M 21 0 - 0 0 0 sco K - -558 456 N M 21 0 - 0 0 0 sco K : 610 167 1954 149 rc 0.502 0 0 sco %%IncludeFont: Helvetica-Bold - -(F0) cvn - -0.930 - - (Helvetica-Bold) cvn /Type1 - -T - -(Helvetica-Bold) cvn - -mF - -(F0_129) cvn - -F0 - -129 - -xF - -F0_129 - -Ji - -634 167 M - -0.543 0 (M)A - -0.957 0 (E)A - -1.181 0 (T)A - --4.862 0 (I)A - -0.957 0 (S)A - -0.298 0 (')A - --2.138 0 32 1.276 0 (s )D - -0.638 0 (O)A - --1.181 0 (r)A - -1.181 0 (d)A - -1.276 0 (e)A - --2.181 0 (r)A - --0.862 0 (i)A - --2.043 0 32 1.181 0 (ng )D - -0.957 0 (P)A - -1.276 0 (e)A - --2.181 0 (r)A - --0.957 0 (f)A - -1.181 0 (o)A - --1.181 0 (r)A - -0.319 0 (m)A - -1.276 0 (a)A - -1.181 0 (n)A - --3.138 0 32 1.276 0 (ce )D - -; : 655 1947 181 53 rc 0 0 0 sco (F0_45) cvn - -F0 - -45 - -xF - -F0_45 - -Ji - -665 1947 M - --1.020 0 (0)A - -1.490 0 (.)A - --0.020 0 (9)A - --1.020 0 (0)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 759 1774 181 53 rc 0 0 0 sco F0_45 - -Ji - -770 1774 M - --1.020 0 (2)A - -1.490 0 (.)A - --0.020 0 (1)A - --1.020 0 (9)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 798 1600 180 53 rc 0 0 0 sco F0_45 - -Ji - -808 1600 M - --1.020 0 (2)A - -1.490 0 (.)A - --0.020 0 (6)A - --1.020 0 (7)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 857 1426 181 53 rc 0 0 0 sco F0_45 - -Ji - -867 1426 M - --1.020 0 (3)A - -1.490 0 (.)A - --0.020 0 (4)A - --1.020 0 (3)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 867 1252 181 53 rc 0 0 0 sco F0_45 - -Ji - -878 1252 M - --1.020 0 (3)A - -1.490 0 (.)A - --0.020 0 (5)A - --1.020 0 (5)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 902 1078 181 53 rc 0 0 0 sco F0_45 - -Ji - -912 1078 M - --1.020 0 (3)A - -1.490 0 (.)A - --0.020 0 (9)A - --1.020 0 (6)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 1058 904 181 53 rc 0 0 0 sco F0_45 - -Ji - -1069 904 M - --1.020 0 (5)A - -1.490 0 (.)A - --0.020 0 (9)A - --1.020 0 (0)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 1427 731 205 53 rc 0 0 0 sco F0_45 - -Ji - -1437 731 M - --1.020 0 (1)A - --0.020 0 (0)A - -1.490 0 (.)A - --1.020 0 (51)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 1657 557 205 53 rc 0 0 0 sco F0_45 - -Ji - -1667 557 M - --1.020 0 (1)A - --0.020 0 (3)A - -1.490 0 (.)A - --1.020 0 (34)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 704 1861 181 53 rc 0 0 0 sco F0_45 - -Ji - -714 1861 M - --1.020 0 (1)A - -1.490 0 (.)A - --0.020 0 (5)A - --1.020 0 (2)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 902 1687 181 53 rc 0 0 0 sco F0_45 - -Ji - -912 1687 M - --1.020 0 (3)A - -1.490 0 (.)A - --0.020 0 (9)A - --1.020 0 (5)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 857 1513 181 53 rc 0 0 0 sco F0_45 - -Ji - -867 1513 M - --1.020 0 (3)A - -1.490 0 (.)A - --0.020 0 (4)A - --1.020 0 (2)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 912 1339 181 53 rc 0 0 0 sco F0_45 - -Ji - -923 1339 M - --1.020 0 (4)A - -1.490 0 (.)A - --0.020 0 (1)A - --1.020 0 (0)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 1114 1169 181 53 rc 0 0 0 sco F0_45 - -Ji - -1124 1169 M - --1.020 0 (6)A - -1.490 0 (.)A - --0.020 0 (5)A - --1.020 0 (9)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 1111 995 180 53 rc 0 0 0 sco F0_45 - -Ji - -1121 995 M - --1.020 0 (6)A - -1.490 0 (.)A - --0.020 0 (5)A - --1.020 0 (5)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 1493 821 205 53 rc 0 0 0 sco F0_45 - -Ji - -1504 821 M - --1.020 0 (1)A - --0.020 0 (1)A - -1.490 0 (.)A - --1.020 0 (32)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 2199 647 205 53 rc 0 0 0 sco F0_45 - -Ji - -2209 647 M - --1.020 0 (2)A - --0.020 0 (0)A - -1.490 0 (.)A - --1.020 0 (07)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 2550 473 205 53 rc 0 0 0 sco F0_45 - -Ji - -2561 473 M - --1.020 0 (2)A - --0.020 0 (4)A - -1.490 0 (.)A - --1.020 0 (43)A - --4.020 0 (s)A - -2.980 0 (e)A - --1.020 0 (c)A - -; : 217 1892 2841 74 rc 0 0 0 sco %%IncludeFont: Helvetica - -(F3) cvn - -0.909 - - (Helvetica) cvn /Type1 - -T - -(Helvetica) cvn - -mF - -(F3_66) cvn - -F3 - -66 - -xF - -F3_66 - -Ji - -335 1892 M - -2.652 0 (I)A - --1.696 0 (n)A - -1.304 0 (p)A - --0.978 0 (r)A - -1.304 0 (o1)A - -; : 116 1718 2942 74 rc 0 0 0 sco F3_66 - -Ji - -179 1718 M - -0.978 0 (B)A - -1.348 0 (C)A - -0.978 0 (SS)A - -1.674 0 (T)A - -0.978 0 (K)A - -2.304 0 (3)A - -1.304 0 (0)A - -; : 116 1544 2942 74 rc 0 0 0 sco F3_66 - -Ji - -179 1544 M - -0.978 0 (B)A - -1.348 0 (C)A - -0.978 0 (SS)A - -1.674 0 (T)A - -0.978 0 (K)A - -2.304 0 (3)A - -1.304 0 (2)A - -; : 116 1370 2942 74 rc 0 0 0 sco F3_66 - -Ji - -179 1370 M - -0.978 0 (B)A - -1.348 0 (C)A - -0.978 0 (SS)A - -1.674 0 (T)A - -0.978 0 (K)A - -2.304 0 (3)A - -1.304 0 (1)A - -; : 172 1196 2886 74 rc 0 0 0 sco F3_66 - -Ji - -290 1196 M - -0.978 0 (P)A - -1.348 0 (D)A - -0.978 0 (S)A - --0.978 0 (-)A - -1.304 0 (20)A - -; : 196 1026 2862 74 rc 0 0 0 sco F3_66 - -Ji - -314 1026 M - -0.978 0 (KE)A - --1.652 0 (N)A - -1.304 0 (18)A - -; : 148 852 2910 74 rc 0 0 0 sco F3_66 - -Ji - -266 852 M - -1.674 0 (F)A - -0.652 0 (O)A - -1.348 0 (R)A - -0.674 0 (T)A - -2.304 0 (1)A - -1.304 0 (7)A - -; : 280 678 2778 74 rc 0 0 0 sco F3_66 - -Ji - -398 678 M - -1.674 0 (T)A - --0.978 0 (r)A - -1.304 0 (o)A - --0.652 0 (ll)A - -; : 214 505 2844 74 rc 0 0 0 sco F3_66 - -Ji - -332 505 M - -0.652 0 (O)A - -2.000 0 (c)A - -1.304 0 (e)A - --1.696 0 (an)A - -; - -784 2059 N M 1971 128 rr : 1.000 1.000 1.000 sco O ; 0 Lc 0 Lj 0 0 0 sco K - -812 2100 N M 52 53 rr : 1.000 1.000 0 sco O ; 0 0 0 sco K : 785 2080 1974 96 rc 0 0 0 sco (F0_83) cvn - -F0 - -83 - -xF - -F0_83 - -Ji - -888 2080 M - -3.861 0 (M)A - -0.926 0 (I)A - -0.287 0 32 0.639 0 (PS )D - --0.926 0 (R)A - --1.148 0 (1)A - --0.148 0 (0)A - --1.148 0 (000)A - --0.925 0 (@)A - --1.148 0 (2)A - --0.148 0 (0)A - --1.148 0 (0)A - -3.861 0 (M)A - --0.926 0 (H)A - -0.500 0 (z)A - -; - -1834 2100 N M 52 53 rr : 0 0 1.000 sco O ; 0 0 0 sco K : 1807 2080 952 96 rc 0 0 0 sco F0_83 - -Ji - -1910 2080 M - -0.926 0 (I)A - -2.287 0 (n)A - --0.639 0 (t)A - --0.148 0 (e)A - -0.926 0 (l )A - -0.639 0 (PP)A - --0.926 0 (R)A - --2.574 0 (O)A - --0.925 0 (@)A - --1.148 0 (2)A - --0.148 0 (0)A - --1.148 0 (0)A - -3.861 0 (M)A - --0.926 0 (H)A - -0.500 0 (z)A - -; - -1538 1010 N M 320 38 rr : 0.502 0 0 sco O ; - -1538 1048 N M 320 61 rr : 0.502 0 0 sco O ; - -1538 1109 N M 320 37 rr : 0.502 0 0 sco O ; - -1858 1010 N M 361 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco %%IncludeFont: Helvetica-BoldOblique - -(F6) cvn - -0.915 - - (Helvetica-BoldOblique) cvn /Type1 - -T - -(Helvetica-BoldOblique) cvn - -mF - -(F6_59) cvn - -F6 - -59 - -xF - -F6_59 - -Ji - -1888 1011 M - -0.402 0 (N)A - -0.951 0 (u)A - -1.549 0 (m)A - -0.951 0 (b)A - -0.196 0 (e)A - -0.549 0 32 0.049 0 (r )D - -0.951 0 (o)A - -0.353 0 (f)A - -; - -1858 1078 N M 361 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59 - -Ji - -1922 1080 M - -0.647 0 (V)A - -0.196 0 (e)A - -0.049 0 (r)A - -1.353 0 (t)A - -0.598 0 (i)A - -0.196 0 (ce)A - -1.196 0 (s)A - -; - -2219 1010 N M 362 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59 - -Ji - -2250 1011 M - -0.402 0 (N)A - -0.951 0 (u)A - -1.549 0 (m)A - -0.951 0 (b)A - -0.196 0 (e)A - -0.549 0 32 0.049 0 (r )D - -0.951 0 (o)A - -0.353 0 (f)A - -; - -2219 1078 N M 362 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59 - -Ji - -2311 1080 M - -0.647 0 (E)A - -0.951 0 (dg)A - -0.196 0 (es)A - -; - -2581 1010 N M 360 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59 - -Ji - -2620 1011 M - -1.098 0 (O)A - -0.951 0 (p)A - -0.196 0 (e)A - -0.049 0 (r)A - -1.196 0 (a)A - -0.353 0 (t)A - -0.598 0 (i)A - -0.951 0 (o)A - --0.049 0 (n)A - -; - -2581 1078 N M 360 68 rr : 0.502 0 0 sco O ; : 1516 1010 1425 985 rc 1.000 1.000 1.000 sco F6_59 - -Ji - -2675 1080 M - -0.402 0 (C)A - -0.951 0 (oun)A - -0.353 0 (t)A - -; - -1538 1151 N M 320 13 rr : 1.000 1.000 0.800 sco O ; - -1538 1164 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco (F0_53) cvn - -F0 - -53 - -xF - -F0_53 - -Ji - -1554 1163 M - -0.766 0 (O)A - -0.532 0 (c)A - -1.532 0 (e)A - -0.532 0 (a)A - -0.617 0 (n)A - -; - -1538 1225 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1151 N M 361 13 rr : 1.000 1.000 0.800 sco O ; - -1858 1164 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1146 361 79 rc 0.004 0 0 sco (F3_53) cvn - -F3 - -53 - -xF - -F3_53 - -Ji - -2007 1166 M - -0.532 0 (1)A - -1.532 0 (4)A - -0.532 0 (3)A - -0.266 0 (,)A - -0.532 0 (43)A - -1.532 0 (7)A - -; - -1858 1225 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1151 N M 362 13 rr : 1.000 1.000 0.800 sco O ; - -2219 1164 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1146 362 79 rc 0.004 0 0 sco F3_53 - -Ji - -2369 1166 M - -0.532 0 (4)A - -1.532 0 (0)A - -0.532 0 (9)A - -0.266 0 (,)A - -0.532 0 (59)A - -1.532 0 (3)A - -; - -2219 1225 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1151 N M 360 13 rr : 1.000 1.000 0.800 sco O ; - -2581 1164 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1146 360 79 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1166 M - -0.532 0 (1)A - -1.266 0 (.)A - -0.532 0 (26e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (8)A - -; - -2581 1225 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1146 N M 320 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -1538 1146 N M 320 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -1858 1146 N M 4 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -1858 1146 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc - -1858 1146 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -1862 1146 N M 357 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -1862 1146 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2219 1146 N M 5 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2219 1146 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc - -2219 1146 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2224 1146 N M 357 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2224 1146 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2581 1146 N M 5 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2581 1146 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc - -2581 1146 N M 0 5 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2586 1146 N M 355 5 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2586 1146 N M 355 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -1538 1239 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1253 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1251 M - -0.617 0 (T)A - -0.383 0 (r)A - -1.617 0 (o)A - -0.266 0 (ll)A - -; - -1538 1314 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1239 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1253 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1239 361 75 rc 0.004 0 0 sco F3_53 - -Ji - -2007 1255 M - -0.532 0 (2)A - -1.532 0 (1)A - -0.532 0 (3)A - -0.266 0 (,)A - -0.532 0 (45)A - -1.532 0 (3)A - -; - -1858 1314 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1239 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1253 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1239 362 75 rc 0.004 0 0 sco F3_53 - -Ji - -2323 1255 M - -0.532 0 (5)A - -1.266 0 (,)A - -0.532 0 (885)A - -0.266 0 (,)A - -1.532 0 (8)A - -0.532 0 (29)A - -; - -2219 1314 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1239 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1253 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1239 360 75 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1255 M - -0.532 0 (5)A - -1.266 0 (.)A - -0.532 0 (53e)A - -1.048 0 (+)A - -0.532 0 (1)A - -1.532 0 (0)A - -; - -2581 1314 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1328 N M 320 13 rr : 1.000 1.000 0.800 sco O ; - -1538 1341 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1340 M - -0.617 0 (F)A - -1.617 0 (o)A - -0.383 0 (r)A - -0.351 0 (t)A - -0.532 0 (17)A - -; - -1538 1402 N M 320 15 rr : 1.000 1.000 0.800 sco O ; - -1858 1328 N M 361 13 rr : 1.000 1.000 0.800 sco O ; - -1858 1341 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1328 361 74 rc 0.004 0 0 sco F3_53 - -Ji - -2037 1344 M - -0.532 0 (8)A - -1.532 0 (6)A - -0.266 0 (,)A - -0.532 0 (650)A - -; - -1858 1402 N M 361 15 rr : 1.000 1.000 0.800 sco O ; - -2219 1328 N M 362 13 rr : 1.000 1.000 0.800 sco O ; - -2219 1341 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1328 362 74 rc 0.004 0 0 sco F3_53 - -Ji - -2369 1344 M - -0.532 0 (2)A - -1.532 0 (4)A - -0.532 0 (7)A - -0.266 0 (,)A - -0.532 0 (42)A - -1.532 0 (4)A - -; - -2219 1402 N M 362 15 rr : 1.000 1.000 0.800 sco O ; - -2581 1328 N M 360 13 rr : 1.000 1.000 0.800 sco O ; - -2581 1341 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1328 360 74 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1344 M - -0.532 0 (8)A - -1.266 0 (.)A - -0.532 0 (05e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (6)A - -; - -2581 1402 N M 360 15 rr : 1.000 1.000 0.800 sco O ; - -1538 1417 N M 320 13 rr : 1.000 1.000 0.800 sco O ; - -1538 1430 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1429 M - -0.734 0 (K)A - -0.532 0 (e)A - -1.617 0 (n)A - -0.532 0 (1)A - -1.532 0 (8)A - -; - -1538 1491 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1417 N M 361 13 rr : 1.000 1.000 0.800 sco O ; - -1858 1430 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1417 361 74 rc 0.004 0 0 sco F3_53 - -Ji - -2007 1432 M - -0.532 0 (1)A - -1.532 0 (0)A - -0.532 0 (5)A - -0.266 0 (,)A - -0.532 0 (12)A - -1.532 0 (7)A - -; - -1858 1491 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1417 N M 362 13 rr : 1.000 1.000 0.800 sco O ; - -2219 1430 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1417 362 74 rc 0.004 0 0 sco F3_53 - -Ji - -2369 1432 M - -0.532 0 (2)A - -1.532 0 (5)A - -0.532 0 (2)A - -0.266 0 (,)A - -0.532 0 (07)A - -1.532 0 (2)A - -; - -2219 1491 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1417 N M 360 13 rr : 1.000 1.000 0.800 sco O ; - -2581 1430 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1417 360 74 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1432 M - -0.532 0 (2)A - -1.266 0 (.)A - -0.532 0 (85e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (8)A - -; - -2581 1491 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1505 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1519 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1517 M - -0.649 0 (P)A - -0.734 0 (D)A - -0.649 0 (S)A - -1.351 0 (-)A - -0.532 0 (20)A - -; - -1538 1580 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1505 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1519 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1505 361 75 rc 0.004 0 0 sco F3_53 - -Ji - -2037 1521 M - -0.532 0 (3)A - -1.532 0 (3)A - -0.266 0 (,)A - -0.532 0 (798)A - -; - -1858 1580 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1505 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1519 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1505 362 75 rc 0.004 0 0 sco F3_53 - -Ji - -2369 1521 M - -0.532 0 (1)A - -1.532 0 (4)A - -0.532 0 (3)A - -0.266 0 (,)A - -0.532 0 (16)A - -1.532 0 (1)A - -; - -2219 1580 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1505 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1519 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1505 360 75 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1521 M - -0.532 0 (3)A - -1.266 0 (.)A - -0.532 0 (82e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (9)A - -; - -2581 1580 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1594 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1608 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1538 1594 320 75 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1606 M - -0.734 0 (BC)A - -0.649 0 (S)A - -1.649 0 (S)A - -0.617 0 (T)A - -0.734 0 (K)A - -0.532 0 (3)A - -1.532 0 (1)A - -; - -1538 1669 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1594 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1608 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1594 361 75 rc 0.004 0 0 sco F3_53 - -Ji - -2037 1610 M - -0.532 0 (3)A - -1.532 0 (5)A - -0.266 0 (,)A - -0.532 0 (588)A - -; - -1858 1669 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1594 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1608 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1594 362 75 rc 0.004 0 0 sco F3_53 - -Ji - -2369 1610 M - -0.532 0 (5)A - -1.532 0 (7)A - -0.532 0 (2)A - -0.266 0 (,)A - -0.532 0 (91)A - -1.532 0 (4)A - -; - -2219 1669 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1594 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1608 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1594 360 75 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1610 M - -0.532 0 (1)A - -1.266 0 (.)A - -0.532 0 (16e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (9)A - -; - -2581 1669 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1683 N M 320 13 rr : 1.000 1.000 0.800 sco O ; - -1538 1696 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1538 1683 320 74 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1695 M - -0.734 0 (BC)A - -0.649 0 (S)A - -1.649 0 (S)A - -0.617 0 (T)A - -0.734 0 (K)A - -0.532 0 (3)A - -1.532 0 (2)A - -; - -1538 1757 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1683 N M 361 13 rr : 1.000 1.000 0.800 sco O ; - -1858 1696 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1683 361 74 rc 0.004 0 0 sco F3_53 - -Ji - -2037 1698 M - -0.532 0 (4)A - -1.532 0 (4)A - -0.266 0 (,)A - -0.532 0 (609)A - -; - -1858 1757 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1683 N M 362 13 rr : 1.000 1.000 0.800 sco O ; - -2219 1696 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1683 362 74 rc 0.004 0 0 sco F3_53 - -Ji - -2369 1698 M - -0.532 0 (9)A - -1.532 0 (8)A - -0.532 0 (5)A - -0.266 0 (,)A - -0.532 0 (04)A - -1.532 0 (6)A - -; - -2219 1757 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1683 N M 360 13 rr : 1.000 1.000 0.800 sco O ; - -2581 1696 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1683 360 74 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1698 M - -0.532 0 (1)A - -1.266 0 (.)A - -0.532 0 (32e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (9)A - -; - -2581 1757 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1771 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1785 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1538 1771 320 75 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1784 M - -0.734 0 (BC)A - -0.649 0 (S)A - -1.649 0 (S)A - -0.617 0 (T)A - -0.734 0 (K)A - -0.532 0 (3)A - -1.532 0 (0)A - -; - -1538 1846 N M 320 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1771 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -1858 1785 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1771 361 75 rc 0.004 0 0 sco F3_53 - -Ji - -2037 1787 M - -0.532 0 (2)A - -1.532 0 (8)A - -0.266 0 (,)A - -0.532 0 (294)A - -; - -1858 1846 N M 361 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1771 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2219 1785 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1771 362 75 rc 0.004 0 0 sco F3_53 - -Ji - -2323 1787 M - -0.532 0 (1)A - -1.266 0 (,)A - -0.532 0 (007)A - -0.266 0 (,)A - -1.532 0 (2)A - -0.532 0 (84)A - -; - -2219 1846 N M 362 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1771 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -2581 1785 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1771 360 75 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1787 M - -0.532 0 (1)A - -1.266 0 (.)A - -0.532 0 (17e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (9)A - -; - -2581 1846 N M 360 14 rr : 1.000 1.000 0.800 sco O ; - -1538 1860 N M 320 16 rr : 1.000 1.000 0.800 sco O ; - -1538 1876 N M 320 61 rr : 1.000 1.000 0.800 sco O ; : 1516 1010 1425 985 rc 0.004 0 0 sco F0_53 - -Ji - -1554 1874 M - -0.266 0 (I)A - -0.617 0 (n)A - -1.617 0 (p)A - -0.383 0 (r)A - -0.617 0 (o)A - -0.532 0 (1)A - -; - -1538 1937 N M 320 17 rr : 1.000 1.000 0.800 sco O ; - -1858 1860 N M 361 16 rr : 1.000 1.000 0.800 sco O ; - -1858 1876 N M 361 61 rr : 1.000 1.000 0.800 sco O ; : 1858 1860 361 77 rc 0.004 0 0 sco F3_53 - -Ji - -2037 1878 M - -0.532 0 (4)A - -1.532 0 (6)A - -0.266 0 (,)A - -0.532 0 (949)A - -; - -1858 1937 N M 361 17 rr : 1.000 1.000 0.800 sco O ; - -2219 1860 N M 362 16 rr : 1.000 1.000 0.800 sco O ; - -2219 1876 N M 362 61 rr : 1.000 1.000 0.800 sco O ; : 2219 1860 362 77 rc 0.004 0 0 sco F3_53 - -Ji - -2323 1878 M - -0.532 0 (1)A - -1.266 0 (,)A - -0.532 0 (117)A - -0.266 0 (,)A - -1.532 0 (8)A - -0.532 0 (09)A - -; - -2219 1937 N M 362 17 rr : 1.000 1.000 0.800 sco O ; - -2581 1860 N M 360 16 rr : 1.000 1.000 0.800 sco O ; - -2581 1876 N M 360 61 rr : 1.000 1.000 0.800 sco O ; : 2581 1860 360 77 rc 0.004 0 0 sco F3_53 - -Ji - -2699 1878 M - -0.532 0 (1)A - -1.266 0 (.)A - -0.532 0 (24e)A - -1.048 0 (+)A - -0.532 0 (0)A - -1.532 0 (9)A - -; - -2581 1937 N M 360 17 rr : 1.000 1.000 0.800 sco O ; - -1538 1954 N M 320 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -1538 1954 N M 320 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -1858 1954 N M 4 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -1858 1954 N M 4 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc - -1858 1954 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -1862 1954 N M 357 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -1862 1954 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2219 1954 N M 5 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2219 1954 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc - -2219 1954 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2224 1954 N M 357 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2224 1954 N M 357 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2581 1954 N M 5 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2581 1954 N M 5 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; : 1516 1010 1425 985 rc - -2581 1954 N M 0 4 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -2586 1954 N M 355 4 rr : 0 0 0 sco O ; : 1516 1010 1425 985 rc - -2586 1954 N M 355 0 - 1 Lw 1 Lc 1 Lj solid 0 0 0 sco K ; - -LH - -pagesave restore - - - - - - - -/Pscript_Win_Driver /ProcSet findresource dup /terminate get exec - -Pscript_Win_Compat dup /terminate get exec - - -cleartomark -countdictstack exch sub { end } repeat -restore grestore -% -% End Imported PIC File: slide2.eps -% -$F2psEnd -rs -%%EndDocument - @endspecial 0 3899 a Fy(Figure)19 b(2)p FL(:)28 b Fx(The)19 -b(amount)g(of)h(time)g(required)f(b)o(y)i(M)l Fv(E)-17 -b Fx(T)g Fv(I)p Fx(S)23 b(to)d(par)s(tition)f(v)n(ar)q(ious)h(g)o(r)o -(aphs)f(in)h(256)g(par)s(ts)f(and)h(the)f(amount)g(of)h(time)g -(required)e(b)o(y)k(M)l Fv(E)-17 b Fx(T)g Fv(I)p Fx(S)0 -3999 y(to)19 b(compute)f(\002ll-reducing)g(order)q(ings)f(f)n(or)i(v)n -(ar)q(ious)f(sparse)h(matr)q(ices)o(.)100 4183 y FL(The)i(rest)h(of)f -(this)i(manual)d(is)j(or)o(ganized)c(as)j(follo)n(ws:)28 -b(Section)21 b(4)h(describes)f(the)h(user)f(interf)o(ace)g(to)h(the)f -(stand-alone)f(programs)0 4292 y(pro)o(vided)i(by)k Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(.)26 b(Section)e(5)g(describes)g -(the)g(stand-alone)f(library)g(that)i(implements)e(the)h(v)n(arious)f -(algorithms)g(implemented)0 4402 y(in)f Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)r FL(.)23 b(Finally)-5 b(,)19 b(Section)h(6)g -(describes)g(the)g(system)g(requirements)f(for)g(the)j -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(package.)1929 -5649 y(5)p eop -%%Page: 6 6 -6 5 bop 0 85 a FD(3)116 b(What)31 b(is)h(Ne)n(w)h(in)g(This)f(V)-6 -b(er)n(sion)0 261 y FL(The)19 b(latest)i(v)o(ersion)d(of)j -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 b FL(contains)19 -b(a)h(number)d(of)i(changes)g(o)o(v)o(er)f(the)i(pre)n(vious)e(major)g -(release)i(\(v)o(ersion)e(3.0\).)23 b(Most)d(of)f(these)0 -370 y(changes)h(are)g(concentrated)e(on)i(the)h(graph)e(and)h(mesh)g -(partitioning)f(routines)h(and)g(the)o(y)f(mar)o(ginally)g(af)n(fect)h -(the)g(sparse)h(matrix)f(re-)0 480 y(ordering)c(routines.)23 -b(T)-7 b(able)18 b(1)h(describes)e(which)h(programs)e(and)i(routines)f -(of)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)21 b -FL(ha)n(v)o(e)d(been)f(changed)g(and)g(the)i(ne)n(w)f(routines)0 -590 y(in)k Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)p -FL(.)29 b(In)20 b(the)g(rest)g(of)g(this)h(section)f(we)g(brie\003y)g -(describe)f(some)h(of)g(the)h(major)e(changes.)0 799 -y FB(Multi-Constraint)24 b(P)n(ar)r(titioning)100 b Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)26 b FL(no)n(w)c(includes)f(partitioning) -f(routines)h(that)h(can)g(be)g(used)g(to)g(partition)f(a)i(graph)d(in)0 -908 y(the)e(presence)e(of)h(multiple)g(balancing)f(constraints.)24 -b(The)17 b(idea)g(is)i(that)e(each)g(v)o(erte)o(x)g(has)g(a)h(v)o -(ector)f(of)g(weights)g(of)h(size)g Ft(m)23 b FL(associated)0 -1018 y(with)g(it,)i(and)d(the)h(objecti)n(v)o(e)f(of)h(the)g -(partitioning)e(algorithm)h(is)i(to)f(minimize)g(the)g(edgecut)f -(subject)h(to)g(the)g(constraints)g(that)g(each)0 1128 -y(one)i(of)g(the)h Ft(m)31 b FL(weights)25 b(is)i(equally)e(distrib)n -(uted)f(among)g(the)i(domains.)40 b(F)o(or)25 b(e)o(xample,)h(if)f(the) -h(\002rst)g(weight)f(corresponds)f(to)i(the)0 1237 y(amount)c(of)i -(computation)d(and)i(the)g(second)g(weight)g(corresponds)f(to)h(the)h -(amount)e(of)i(storage)e(required)g(for)h(each)g(element,)h(then)0 -1347 y(the)19 b(partitioning)f(computed)f(by)i(the)g(ne)n(w)g -(algorithms)f(will)i(balance)e(both)h(the)g(computation)e(performed)g -(in)i(each)g(domain)f(as)i(well)0 1456 y(as)f(the)e(amount)g(of)g -(memory)f(that)i(it)h(requires.)k(Also,)18 b(multi-phase)f -(\(multi-physics\))e(computations)h(can)h(use)h(the)g(ne)n(w)g -(partitioning)0 1566 y(algorithm)28 b(to)i(simultaneously)e(balance)h -(the)h(computations)e(performed)f(in)j(each)f(phase.)53 -b(The)30 b(multi-constraint)e(partitioning)0 1675 y(algorithms)19 -b(and)h(their)f(applications)g(are)i(further)d(described)h(in)i([6)o -(].)100 1785 y(The)46 b(multi-constraint)f(partitioning)g(algorithm)h -(is)i(implemented)d(by)h(the)h Fz(METIS)p 2781 1785 25 -4 v 31 w(mCP)m(ar)s(tGr)o(aphRecursiv)n(e)g FL(and)0 -1895 y Fz(METIS)p 258 1895 V 31 w(mCP)m(ar)s(tGr)o(aphKw)o(a)n(y)25 -b FL(routines)g(that)h(are)g(based)g(on)f(the)h(multile)n(v)o(el)f -(recursi)n(v)o(e)f(bisection)h(and)g(the)h(multile)n(v)o(el)f -Ft(k)5 b FL(-w)o(ay)0 2004 y(partitioning)21 b(paradigms,)i(respecti)n -(v)o(ely)-5 b(.)32 b(Also,)24 b(the)g Fz(pmetis)g FL(and)f(the)g -Fz(kmetis)h FL(programs)d(ha)n(v)o(e)i(been)g(o)o(v)o(erloaded)d(to)j -(in)m(v)n(ok)o(e)g(the)0 2114 y(multi-constraint)h(partitioner)g(when)i -(the)g(input)f(graph)g(contains)g(multiple)g(v)o(erte)o(x)g(weights)h -(\(Section)f(4.5.1)g(describes)g(ho)n(w)h(the)0 2223 -y(format)19 b(of)h(the)g(input)g(graph)e(\002le)j(has)g(been)e(e)o -(xtended)f(to)j(allo)n(w)f(you)f(to)i(specify)e(multiple)h(v)o(erte)o -(x)e(weights\).)0 2433 y FB(Minimizing)25 b(the)g(T)-7 -b(otal)25 b(Comm)n(unication)f(V)-7 b(olume)99 b FL(The)22 -b(objecti)n(v)o(e)f(of)i(the)f(traditional)f(graph)g(partitioning)g -(problem)g(is)0 2542 y(to)f(compute)e(a)i(balanced)e -Ft(k)5 b FL(-w)o(ay)19 b(partitioning)f(such)h(that)h(the)g(number)d -(of)j(edges)f(\(or)g(in)h(the)f(case)h(of)g(weighted)e(graphs)h(the)g -(sum)h(of)0 2652 y(their)f(weights\))g(that)h(straddle)f(dif)n(ferent)f -(partitions)h(is)i(minimized.)i(When)d(partitioning)d(is)k(used)e(to)h -(distrib)n(ute)f(a)h(graph)e(or)i(a)g(mesh)0 2761 y(among)f(the)i -(processors)f(of)h(a)g(parallel)f(computer)m(,)f(the)i(objecti)n(v)o(e) -e(of)i(minimizing)e(the)i(edgecut)f(is)h(only)f(an)h(approximation)d -(of)j(the)0 2871 y(true)j(communication)e(cost)i(resulting)g(from)f -(the)i(partitioning.)36 b(Despite)24 b(that,)i(for)d(a)i(wide)g(range)e -(of)h(problems,)g(by)g(minimizing)0 2981 y(the)c(edgecut,)f(the)h -(partitioning)e(algorithms)h(also)i(minimize)e(the)h(communication)e -(cost)i(reasonably)f(well.)100 3090 y(Ho)n(we)n(v)o(er)m(,)29 -b(there)f(are)h(cases)h(in)f(which)f(a)i(partitioning)d(algorithm)g -(can)i(signi\002cantly)f(reduce)g(the)h(communication)d(cost)j(by)0 -3200 y(directly)24 b(minimizing)f(this)j(objecti)n(v)o(e)d(\(as)i -(opposed)e(to)i(the)g(edgecut\).)39 b Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)29 b FL(no)n(w)c(pro)o(vides)e(the)i -Fz(METIS)p 3238 3200 V 30 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)0 -3309 y FL(and)32 b Fz(METIS)p 411 3309 V 30 w(WP)m(ar)s(tGr)o(aphVKw)o -(a)n(y)h FL(routines)e(that)h(directly)g(minimize)f(the)h -(communication)d(cost)k(as)g(de\002ned)e(by)g(the)h(total)0 -3419 y(communication)16 b(v)n(olume)i(resulted)g(by)h(the)g -(partitioning)e(\(see)i(Section)g(5.3)f(for)g(a)i(precise)e -(de\002nition)g(of)h(this)g(objecti)n(v)o(e)f(function\).)0 -3529 y(Note)24 b(that)g(for)f(these)h(routines)f(to)g(pro)o(vide)f -(meaningful)g(partitionings,)g(the)i(connecti)n(vity)e(of)h(the)h -(graph)f(should)f(re\003ect)i(the)g(true)0 3638 y(information)18 -b(e)o(xchange)g(requirements)g(of)i(the)g(underlying)e(computation.)0 -3847 y FB(Minimizing)28 b(the)g(Maxim)n(um)h(Connectivity)f(of)g(the)h -(Subdomains)99 b FL(The)25 b(communication)d(cost)k(resulting)e(from)h -(a)h Ft(k)5 b FL(-)0 3957 y(w)o(ay)23 b(partitioning)e(in)j(general)e -(depends)g(on)g(the)i(follo)n(wing)d(f)o(actors:)31 b(\(i\))23 -b(the)g(total)h(communication)c(v)n(olume,)j(\(ii\))g(the)g(maximum)0 -4067 y(amount)e(of)i(data)f(that)h(an)o(y)f(particular)f(processor)g -(needs)h(to)h(send)g(and)f(recei)n(v)o(e;)h(and)f(\(iii\))g(the)h -(number)e(of)h(messages)h(a)g(processor)0 4176 y(needs)f(to)h(send)g -(and)f(recei)n(v)o(e.)31 b(The)23 b(partitioning)d(routines)i(in)h -(earlier)f(v)o(ersions)g(of)i Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)27 b FL(concentrated)21 b(only)h(on)g(the)h(\002rst)g(f)o -(actor)0 4286 y(\(by)30 b(minimizing)f(the)h(edgecut\).)54 -b(In)30 b(this)h(release,)k Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)35 b FL(also)c(pro)o(vides)d(support)i(for)f(minimizing)g -(the)i(third)f(f)o(actor)f(\(which)0 4395 y(essentially)21 -b(reduces)f(the)h(number)e(of)h(startups\))g(and)h(indirectly)e(\(up)h -(to)h(a)g(point\))f(reduces)g(the)h(second)f(f)o(actor)-5 -b(.)26 b(Experiments)19 b(ha)n(v)o(e)0 4505 y(sho)n(wn)26 -b(that)h(for)f(most)h(graphs)e(corresponding)e(to)k(\002nite)g(element) -f(meshes,)i(the)f(ne)n(w)g(release)f(of)j Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)31 b FL(is)d(able)e(to)h(reduce)f(the)0 -4614 y(maximum)i(\(and)g(total\))h(number)f(of)h(adjacent)f(subdomains) -g(considerably\227especially)e(when)j(the)g(graph)f(is)i(partitioned)e -(in)h(a)0 4724 y(relati)n(v)o(ely)18 b(lar)o(ge)g(number)f(of)i -(partitions)f(\()p Fs(e)o(.g)o FL(.,)h(greater)f(than)h(30\).)24 -b(F)o(or)19 b(most)g(3D)g(\002nite)g(elements)g(graphs,)f(the)h -(maximum)e(number)0 4834 y(of)j(subdomains)e(for)i(a)h(50-w)o(ay)d -(partition)i(has)g(been)f(reduced)g(from)g(around)f(25)i(to)h(around)d -(16.)100 4943 y(This)66 b(enhancement)d(is)j(pro)o(vided)e(as)i(a)g -(re\002nement)e(option)h(for)g(both)g(the)h Fz(METIS)p -3041 4943 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g FL(and)0 -5053 y Fz(METIS)p 258 5053 V 31 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)20 -b FL(routines,)f(and)h(is)h(the)f(def)o(ault)g(option)f(of)g -Fz(kmetis)i FL(and)f Fz(METIS)p 2822 5053 V 30 w(P)m(ar)s(tGr)o(aphKw)o -(a)n(y)p FL(.)0 5262 y FB(Reducing)28 b(the)h(Number)g(of)f -(Non-Contiguous)e(Subdomains)99 b FL(A)26 b Ft(k)5 b -FL(-w)o(ay)25 b(partitioning)f(of)h(a)h(contiguous)e(graph)g(can)0 -5372 y(often)h(lead)g(to)h(some)f(subdomains)f(being)g(assigned)h -(non-contiguous)d(portions)i(of)i(the)f(graph.)40 b(F)o(or)25 -b(man)o(y)f(problems,)h(the)h(non-)1929 5649 y(6)p eop -%%Page: 7 7 -7 6 bop 120 100 3661 17 v 120 199 a Fr(Chang)q(es)28 -b(in)i(M)-6 b Fq(E)-21 b Fr(T)g Fq(I)o Fr(S)r(')-6 b(s)33 -b(stand-alone)c(pr)n(ograms)p 120 257 V 120 357 a Fz(pmetis)1016 -b FL(It)24 b(has)f(been)g(o)o(v)o(er)n(-loaded)d(to)j(in)m(v)n(ok)o(e)f -(the)i(multi-constraint)d(partitioning)g(algo-)1380 457 -y(rithm)f(when)f(the)h(graph)f(contains)h(multiple)f(v)o(erte)o(x)g -(weights.)120 643 y Fz(kmetis)1020 b FL(It)24 b(has)f(been)g(o)o(v)o -(er)n(-loaded)d(to)j(in)m(v)n(ok)o(e)f(the)i(multi-constraint)d -(partitioning)g(algo-)1380 742 y(rithm)f(when)f(the)h(graph)f(contains) -h(multiple)f(v)o(erte)o(x)g(weights.)1380 842 y(The)k(partitioning)e -(algorithm)h(has)h(been)f(modi\002ed)g(to)i(also)f(minimize)f(the)h -(con-)1380 941 y(necti)n(vity)c(of)h(the)g(subdomains.)1380 -1041 y(A)f(pre-)e(and)g(post-re\002nement)f(step)i(is)h(applied)e(that) -i(tries)f(to)g(reduce)f(the)h(number)1380 1141 y(of)i(non-contiguous)c -(subdomains.)120 1327 y Fz(par)s(tnmesh)120 1426 y(par)s(tdmesh)1380 -1327 y FL(The)23 b(partitioning)e(algorithm)h(has)h(been)f(modi\002ed)g -(to)i(also)f(minimize)f(the)h(con-)1380 1426 y(necti)n(vity)c(of)h(the) -g(subdomains.)p 120 1469 V 120 1768 V 120 1868 a Fr(Chang)q(es)28 -b(in)i(M)-6 b Fq(E)-21 b Fr(T)g Fq(I)o Fr(S)r(lib')-6 -b(s)32 b(r)n(outines)p 120 1926 V 120 2025 a Fz(METIS)p -378 2025 25 4 v 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)120 -2125 y(METIS)p 378 2125 V 31 w(WP)m(ar)s(tGr)o(aphKw)o(a)n(y)1380 -2025 y FL(A)19 b(ne)n(w)f(re\002nement)f(algorithm)f(has)j(been)e -(added)h(that)g(also)g(minimizes)g(the)g(con-)1380 2125 -y(necti)n(vity)j(of)i(the)f(subdomains.)30 b(This)22 -b(ne)n(w)h(algorithm)d(has)j(been)f(made)g(the)g(de-)1380 -2225 y(f)o(ault)e(option.)1380 2324 y(A)f(pre-)e(and)g -(post-re\002nement)f(step)i(is)h(applied)e(that)i(tries)f(to)g(reduce)f -(the)h(number)1380 2424 y(of)i(non-contiguous)c(subdomains.)120 -2611 y Fz(METIS)p 378 2611 V 31 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)120 -2710 y(METIS)p 378 2710 V 31 w(WP)m(ar)s(tGr)o(aphVKw)o(a)n(y)1380 -2611 y FL(This)28 b(is)h(a)f(ne)n(w)g(set)g(of)g(routines)f(that)h -(compute)e(a)j Ft(k)5 b FL(-w)o(ay)27 b(partitioning)f(whose)1380 -2710 y(objecti)n(v)o(e)19 b(is)i(to)f(minimize)g(the)g(total)g -(communication)e(v)n(olume.)120 2898 y Fz(METIS)p 378 -2898 V 31 w(mCP)m(ar)s(tGr)o(aphRecursiv)n(e)120 2997 -y(METIS)p 378 2997 V 31 w(mCP)m(ar)s(tGr)o(aphKw)o(a)n(y)1380 -2898 y FL(This)h(is)h(a)f(ne)n(w)g(set)h(of)e(routines)g(that)h -(compute)f(a)h Ft(k)5 b FL(-w)o(ay)19 b(partitioning)e(subject)h(to) -1380 2997 y(multiple)i(balancing)e(constraints.)p 120 -3040 3661 17 v 1105 3276 a Fy(T)-5 b(ab)o(le)18 b(1)p -FL(:)26 b Fx(Summar)r(y)18 b(of)h(the)f(changes)h(in)h(M)l -Fv(E)-17 b Fx(T)g Fv(I)p Fx(S)22 b(and)f(M)l Fv(E)-17 -b Fx(T)g Fv(I)p Fx(S)r(lib.)0 3459 y FL(contiguity)23 -b(is)j(a)f(result)g(of)g(the)g(underlying)d(geometry)h(and)i(often)f -(leads)h(to)g(better)g(quality)f(partitions.)38 b(Ne)n(v)o(ertheless,) -25 b(there)g(are)0 3569 y(cases)32 b(in)g(which)e(the)i(partitioning)d -(algorithm)h(is)i(fooled)e(and)h(breaks)f(certain)h(domains.)59 -b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)36 b FL(no)n(w)31 -b(pro)o(vides)e(support)h(for)0 3678 y(eliminating)19 -b(such)h(spurious)f(non-contiguous)d(subdomains.)100 -3788 y(This)j(support)f(is)i(pro)o(vided)c(as)k(a)f(def)o(ault)g -(option)f(for)g(both)g(the)h Fz(METIS)p 2213 3788 25 -4 v 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g FL(and)g Fz(METIS)p -3238 3788 V 30 w(P)m(ar)s(tGr)o(aphVKw)o(a)n(y)0 3898 -y FL(routines,)g(and)h(the)g Fz(kmetis)g FL(program.)1929 -5649 y(7)p eop -%%Page: 8 8 -8 7 bop 0 85 a FD(4)119 b(M)-6 b FA(E)-23 b FD(T)g FA(I)p -FD(S)s(')-7 b(s)31 b(Stand-Alone)g(Pr)n(ograms)2 261 -y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)32 b FL(pro)o(vides)27 -b(a)h(v)n(ariety)f(of)h(programs)e(that)i(can)g(be)g(used)g(to)g -(partition)f(graphs,)h(partition)f(meshes,)j(compute)d(\002ll-reducing) -0 370 y(orderings)21 b(of)i(sparse)h(matrices,)f(as)h(well)g(as)g -(programs)d(to)j(con)m(v)o(ert)d(meshes)i(into)g(graphs)f(appropriate)f -(for)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(')-5 -b(s)26 b(graph)c(parti-)0 480 y(tioning)d(programs.)100 -590 y(The)j(rest)h(of)f(this)h(section)f(pro)o(vides)e(detailed)i -(descriptions)f(about)h(the)g(functionality)f(of)h(these)g(programs,)f -(ho)n(w)h(to)h(use)f(them,)0 699 y(the)e(format)f(of)h(the)g(input)g -(\002les)h(required)d(by)i(them,)g(and)f(the)i(format)e(of)h(the)g -(produced)d(output)i(\002les.)0 927 y Fr(4.1)100 b(Graph)27 -b(P)m(ar)r(titioning)g(Pr)n(ograms)2 1086 y Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)30 b FL(pro)o(vides)25 b(tw)o(o)h(programs)e -Fp(pmetis)i FL(and)g Fp(kmetis)f FL(for)h(partitioning)e(an)i -(unstructured)d(graph)i(into)h Ft(k)32 b FL(equal)25 -b(size)i(parts.)0 1196 y(The)c(partitioning)f(algorithm)h(used)g(by)h -Fp(pmetis)f FL(is)i(based)e(on)g(multile)n(v)o(el)g(recursi)n(v)o(e)g -(bisection)g(described)f(in)i([8)o(],)h(whereas)f(the)0 -1305 y(partitioning)j(algorithm)h(used)h(by)f Fp(kmetis)h -FL(is)h(based)f(on)g(multile)n(v)o(el)f Ft(k)5 b FL(-w)o(ay)29 -b(partitioning)e(described)h(in)h([7)o(].)52 b(Both)29 -b(of)g(these)0 1415 y(programs)24 b(are)i(able)g(to)g(produce)e(high)h -(quality)g(partitions.)41 b(Ho)n(we)n(v)o(er)m(,)26 b(depending)d(on)i -(the)h(application,)g(one)f(program)f(may)i(be)0 1524 -y(preferable)16 b(than)i(the)g(other)-5 b(.)23 b(In)18 -b(general,)f Fp(kmetis)h FL(is)h(preferred)c(when)j(it)g(is)h -(necessary)f(to)g(partition)f(graphs)g(into)g(more)g(than)h(eight)0 -1634 y(partitions.)37 b(F)o(or)25 b(such)f(cases,)i Fp(kmetis)e -FL(is)i(considerably)c(f)o(aster)j(than)f Fp(pmetis)p -FL(.)38 b(On)24 b(the)h(other)f(hand,)g Fp(pmetis)g FL(is)i(preferable) -0 1744 y(for)20 b(partitioning)e(a)i(graph)f(into)h(a)h(small)f(number) -f(of)h(partitions.)100 1853 y(Both)g Fp(pmetis)f FL(and)h -Fp(kmetis)g FL(are)g(in)m(v)n(ok)o(ed)e(by)i(pro)o(viding)d(tw)o(o)k -(ar)o(guments)d(at)j(the)f(command)e(line)i(as)h(follo)n(ws:)257 -2046 y FB(pmetis)124 b Fs(Gr)o(aphF)l(ile)f(Nparts)257 -2155 y FB(kmetis)129 b Fs(Gr)o(aphF)l(ile)123 b(Nparts)100 -2348 y FL(The)30 b(\002rst)h(ar)o(gument)e Fs(Gr)o(aphF)l(ile)p -FL(,)j(is)f(the)g(name)f(of)g(the)h(\002le)g(that)g(stores)g(the)f -(graph)f(\(whose)h(format)g(is)h(described)f(in)g(Sec-)0 -2458 y(tion)19 b(4.5.1\),)f(while)i(the)f(second)g(ar)o(gument)e -Fs(Nparts)p FL(,)j(is)h(the)e(number)f(of)h(partitions)g(that)h(is)g -(desired.)k(Both)c Fp(pmetis)f FL(and)g Fp(kmetis)0 2567 -y FL(can)i(partition)g(a)h(graph)e(into)h(an)g(arbitrary)f(number)g(of) -h(partitions.)28 b(Upon)21 b(successful)g(e)o(x)o(ecution,)e(both)i -(programs)f(display)h(statis-)0 2677 y(tics)i(re)o(garding)c(the)j -(quality)f(of)h(the)g(computed)e(partitioning)f(and)j(the)g(amount)e -(of)i(time)g(tak)o(en)g(to)g(perform)e(the)i(partitioning.)28 -b(The)0 2786 y(actual)20 b(partitioning)e(is)j(stored)f(in)g(a)h -(\002le)g(named)e Fo(GraphF)m(ile.part.Nparts)p FL(,)f(whose)i(format)f -(is)j(described)c(in)j(Section)f(4.6.1.)100 2896 y(Figure)k(3)h(sho)n -(ws)g(the)g(output)f(of)g Fp(pmetis)h FL(and)f Fp(kmetis)h -FL(for)f(partitioning)f(a)i(graph)f(into)h(100)f(parts.)39 -b(From)24 b(this)i(\002gure)e(we)0 3006 y(see)19 b(that)g(both)e -(programs)g(initially)h(print)g(information)e(about)i(the)g(graph,)f -(such)i(as)g(its)g(name,)f(the)h(number)d(of)j(v)o(ertices)f(\()p -Fs(#V)-9 b(ertices)p FL(\),)0 3115 y(the)22 b(number)f(of)h(edges)g(\() -p Fs(#Edg)o(es)p FL(\),)f(and)g(also)i(the)f(number)f(of)h(desired)f -(partitions)h(\()p Fs(#P)-7 b(arts)p FL(\).)30 b(Ne)o(xt,)23 -b(the)o(y)e(print)h(some)g(information)0 3225 y(re)o(garding)h(the)j -(quality)f(of)h(the)g(partitioning.)40 b(Speci\002cally)-5 -b(,)26 b(the)o(y)g(report)e(the)i(number)f(of)g(edges)h(being)f(cut)h -(\()p Fs(Edg)o(e-Cut)p FL(\))e(by)i(the)0 3334 y(partitioning,)j(as)g -(well)g(as)h(the)e(balance)g(of)h(the)f(partitioning)1841 -3304 y Fn(1)1875 3334 y FL(.)51 b(Finally)-5 b(,)30 b(both)d -Fp(pmetis)i FL(and)f Fp(kmetis)g FL(sho)n(w)g(the)h(time)g(tak)o(en)0 -3444 y(by)e(the)g(v)n(arious)f(phases)h(of)g(the)g(algorithm.)44 -b(All)27 b(times)h(are)f(in)g(seconds.)45 b(F)o(or)27 -b(this)g(particular)f(e)o(xample,)h Fp(pmetis)g FL(required)e(a)0 -3553 y(total)g(of)g(17.070)d(seconds,)j(of)g(which)f(13.850)f(seconds)h -(w)o(as)i(tak)o(en)e(by)h(the)g(partitioning)e(algorithm)g(itself,)j -(and)f(the)f(rest)i(w)o(as)f(to)0 3663 y(read)d(the)g(graph)f(itself.) -31 b(Similarly)-5 b(,)22 b Fp(kmetis)g FL(required)e(a)j(total)f(of)g -(6.790)e(seconds,)i(of)g(which)g(3.570)e(seconds)i(w)o(as)h(tak)o(en)f -(by)g(the)0 3773 y(partitioning)e(algorithm)g(itself.)31 -b(As)23 b(you)e(can)h(see)g(from)f(this)i(e)o(xample,)d -Fp(kmetis)i FL(is)h(considerably)c(f)o(aster)j(than)g -Fp(pmetis)p FL(,)f(and)h(it)0 3882 y(produces)c(a)j(partitioning)d -(that)j(is)g(slightly)f(better)f(than)h(that)g(produced)e(by)i -Fp(pmetis)p FL(.)100 3992 y(Figure)e(4)g(sho)n(ws)h(the)f(output)g(of)g -Fp(pmetis)g FL(and)g Fp(kmetis)g FL(for)g(partitioning)f(a)i(graph)e -(into)h(16)g(parts)h(subject)f(to)h(three)f(balancing)0 -4101 y(constraints.)41 b(Both)26 b Fp(pmetis)f FL(and)h -Fp(kmetis)f FL(ha)n(v)o(e)g(been)g Fs(o)o(ver)n(-loaded)f -FL(to)i(in)m(v)n(ok)o(e)f(the)h(multi-constraint)e(partitioning)g -(routines)0 4211 y(whene)n(v)o(er)c(the)i(input)g(graph)e(\002le)j -(speci\002es)g(more)e(that)h(one)g(set)h(of)f(v)o(erte)o(x)f(weights.) -30 b(Comparing)21 b(the)h(output)f(of)g(Figure)h(4)g(to)g(that)0 -4321 y(of)c(Figure)f(3)h(we)g(see)h(that)f(when)f Fp(pmetis)h -FL(and)f Fp(kmetis)h FL(operate)e(in)j(the)f(multi-constraint)d(mode)i -(the)o(y)h(display)f(some)h(additional)0 4430 y(information)d(re)o -(garding)g(the)j(number)e(of)i(constraints)f(and)h(also)g(the)g -(balance)f(of)g(the)h(computed)e(partitioning)g(with)i(respect)g(to)g -(each)0 4540 y(one)j(of)h(these)g(constraints.)28 b(In)22 -b(this)g(e)o(xample,)f Fp(pmetis)g FL(w)o(as)h(able)g(to)g(balance)f -(the)g(three)h(constraints)f(within)g(1\045,)h(3\045,)g(and)g(2\045,)0 -4649 y(respecti)n(v)o(ely)-5 b(.)22 b(Note)c(that)g(for)g -(multi-constraint)e(partitioning,)g(for)h(small)i(number)d(of)i -(partitions)f Fp(pmetis)h FL(outperforms)d Fp(kmetis)0 -4759 y FL(in)20 b(terms)h(of)f(partitioning)e(quality)-5 -b(.)24 b(Ho)n(we)n(v)o(er)m(,)18 b(for)i(lar)o(ger)f(number)f(of)i -(partitions)g Fp(kmetis)g FL(achie)n(v)o(es)f(better)h(quality)f(and)h -(is)h(more)0 4869 y(rob)n(ust)f(in)g(simultaneously)f(balancing)f(the)i -(v)n(arious)f(constraints.)p 0 5031 1560 4 v 87 5091 -a Fm(1)120 5115 y FF(F)o(or)d(a)h Fk(k)k FF(w)o(ay)c(partition)j(of)c -(a)h(graph)h(with)f Fk(n)j FF(v)o(ertices,)f(let)e Fk(m)k -FF(be)c(the)g(size)h(of)f(the)g(lar)o(gest)h(part)g(produced)g(by)f -(the)h Fk(k)5 b FF(-w)o(ay)17 b(partitioning)j(algorithm.)j(The)16 -b(balance)0 5194 y(of)i(the)h(partitioning)i(is)d(de\002ned)h(as)f -Fk(k)5 b(m)t Fl(=)t Fk(n)s FF(,)17 b(and)i(is)f(essentially)j(the)d -(load)h(imbalance)i(induced)f(by)e(non-equal)i(partitions.)26 -b Fj(pmetis)17 b FF(produces)i(partitions)i(that)e(are)0 -5273 y(perfectly)h(balanced)g(at)d(each)i(bisection)g(le)n(v)o(el,)g -(ho)n(we)n(v)o(er)m(,)g(some)e(small)h(load)g(imbalance)i(may)d(result) -h(due)g(to)g(the)f(log)12 b Fk(k)22 b FF(le)n(v)o(els)d(of)e(recursi)n -(v)o(e)i(bisection.)24 b(In)17 b(general,)0 5352 y(the)g(load)g -(imbalance)h(is)e(less)h(than)f(1\045.)21 b Fj(kmetis)15 -b FF(produces)i(partitions)i(that)e(are)f(not)h(perfectly)i(balanced,)f -(b)o(ut)e(the)h(algorithm)h(limits)f(the)g(load)g(imbalance)h(to)f -(3\045.)1929 5649 y FL(8)p eop -%%Page: 9 9 -9 8 bop 478 90 a Fi(')p 478 2466 7 2214 v 478 2635 a(&)3415 -90 y($)p 3415 2466 V 3415 2635 a(\045)p 648 2635 2605 -7 v 648 90 V 590 159 a Fj(prompt\045)39 b(pmetis)f(brack2.graph)h(100) -590 237 y(******************************************)o(*******)o -(******)o(*******)o(*******)o(*)669 316 y(METIS)h(4.0)119 -b(Copyright)38 b(1998,)h(Regents)g(of)h(the)f(University)f(of)i -(Minnesota)590 474 y(Graph)f(Information)f -(--------------------------------------------)o(-------)669 -553 y(Name:)i(brack2.graph,)d(#Vertices:)i(62631,)g(#Edges:)g(366559,)f -(#Parts:)h(100)590 711 y(Recursive)f(Partitioning...)g -(-------------------------------------------)669 790 -y(100-way)h(Edge-Cut:)118 b(37494,)39 b(Balance:)79 b(1.00)590 -947 y(Timing)39 b(Information)f -(-------------------------------------------)o(-------)669 -1026 y(I/O:)1155 b(0.820)669 1105 y(Partitioning:)795 -b(6.110)119 b(\(PMETIS)39 b(time\))669 1184 y(Total:)1075 -b(6.940)590 1263 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)590 1421 y(prompt\045)39 -b(kmetis)f(brack2.graph)h(100)590 1499 y -(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 1578 y(METIS)h(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -1736 y(Graph)f(Information)f -(--------------------------------------------)o(-------)669 -1815 y(Name:)i(brack2.graph,)d(#Vertices:)i(62631,)g(#Edges:)g(366559,) -f(#Parts:)h(100)590 1973 y(K-way)g(Partitioning...)e -(-----------------------------------------------)669 -2052 y(100-way)i(Edge-Cut:)118 b(37310,)39 b(Balance:)79 -b(1.03)590 2209 y(Timing)39 b(Information)f -(-------------------------------------------)o(-------)669 -2288 y(I/O:)1155 b(0.820)669 2367 y(Partitioning:)795 -b(1.750)119 b(\(KMETIS)39 b(time\))669 2446 y(Total:)1075 -b(2.570)590 2525 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)546 2871 y -Fy(Figure)18 b(3)p FL(:)25 b Fx(Output)19 b(of)f Fp(pmetis)g -Fx(and)h Fp(kmetis)e Fx(f)n(or)i(g)o(r)o(aph)g Fh(br)o(ac)n(k2.g)o(r)o -(aph)g Fx(and)f(a)h(100-w)o(a)n(y)g(par)s(tition.)0 3055 -y Fr(4.2)100 b(Mesh)28 b(P)m(ar)r(titioning)g(Pr)n(ograms)2 -3214 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)34 b FL(pro)o(vides)28 -b(tw)o(o)i(programs)d Fp(partnmesh)i FL(and)g Fp(partdmesh)f -FL(for)h(partitioning)f(meshes)h(\()p Fs(e)o(.g)o FL(.,)j(those)d -(arising)h(in)f(\002nite)0 3324 y(element)20 b(or)g(\002nite)g(v)n -(olume)g(methods\))e(into)j Ft(k)k FL(equal)20 b(size)h(parts.)k(These) -20 b(programs)f(tak)o(e)h(as)h(input)f(the)g(element)g(node)f(array)h -(of)g(the)0 3434 y(mesh)i(and)f(compute)f(a)j(partitioning)c(for)j -(both)f(its)h(elements)g(and)f(its)i(nodes.)31 b Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)26 b FL(currently)21 b(supports)f(four)h -(dif)n(ferent)f(types)i(of)0 3543 y(mesh)e(elements)g(which)g(are)g -(triangles,)f(tetrahedra,)g(he)o(xahedra)e(\(bricks\),)i(and)h -(quadrilaterals.)100 3653 y(These)j(programs)f(\002rst)j(con)m(v)o(ert) -c(the)j(mesh)g(into)f(a)h(graph,)f(and)h(then)f(use)h -Fp(kmetis)f FL(to)h(partition)f(this)h(graph.)34 b(The)24 -b(dif)n(ference)0 3762 y(between)g(these)h(tw)o(o)g(programs)e(is)j -(that)f Fp(partnmesh)f FL(con)m(v)o(erts)f(the)i(mesh)g(into)f(a)i -(nodal)e(graph)f(\()p Fs(i.e)p FL(.,)j(each)e(node)g(of)h(the)g(mesh)0 -3872 y(becomes)17 b(a)h(v)o(erte)o(x)f(of)g(the)h(graph\),)e(whereas)i -Fp(partdmesh)f FL(con)m(v)o(erts)f(the)i(mesh)f(into)h(a)g(dual)g -(graph)e(\()p Fs(i.e)o FL(.,)j(each)e(element)h(becomes)0 -3981 y(a)f(v)o(erte)o(x)f(of)h(the)g(graph\).)22 b(In)17 -b(the)g(case)g(of)g Fp(partnmesh)p FL(,)g(the)g(partitioning)e(of)i -(the)g(nodal)f(graph)f(is)j(used)f(to)g(deri)n(v)o(e)f(a)i -(partitioning)d(of)0 4091 y(the)h(elements.)23 b(In)16 -b(the)g(case)g(of)f Fp(partdmesh)p FL(,)h(the)g(partitioning)e(of)h -(the)h(dual)f(graph)g(is)i(used)e(to)h(deri)n(v)o(e)f(a)h(partitioning) -e(of)i(the)g(nodes.)0 4201 y(Both)21 b(of)f(these)h(programs)e(produce) -f(partitioning)h(of)h(comparable)f(quality)-5 b(,)19 -b(with)i Fp(partnmesh)e FL(being)h(considerably)e(f)o(aster)j(than)0 -4310 y Fp(partdmesh)p FL(.)41 b(Ho)n(we)n(v)o(er)m(,)25 -b(in)h(some)g(cases,)h Fp(partnmesh)e FL(may)g(produce)f(partitions)h -(that)h(ha)n(v)o(e)g(higher)e(load)h(imbalance)g(than)0 -4420 y Fp(partdmesh)p FL(.)100 4529 y(Both)20 b Fp(partnmesh)f -FL(and)h Fp(partdmesh)f FL(are)h(in)m(v)n(ok)o(ed)e(by)i(pro)o(viding)d -(tw)o(o)k(ar)o(guments)d(at)j(the)f(command)e(line)i(as)h(follo)n(ws:) -257 4722 y FB(par)r(tnmesh)124 b Fs(MeshF)l(ile)g(Nparts)257 -4832 y FB(par)r(tdmesh)g Fs(MeshF)l(ile)g(Nparts)100 -5024 y FL(The)15 b(\002rst)i(ar)o(gument)c Fs(MeshF)l(ile)p -FL(,)k(is)g(the)f(name)f(of)g(the)h(\002le)h(that)e(stores)i(the)e -(mesh)h(\(whose)f(format)g(is)i(described)d(in)i(Section)g(4.5.2\),)0 -5134 y(while)h(the)f(second)g(ar)o(gument)e Fs(Nparts)p -FL(,)j(is)h(the)e(number)f(of)h(partitions)g(that)g(is)i(desired.)23 -b(Both)16 b Fp(partnmesh)g FL(and)f Fp(partdmesh)h FL(can)0 -5243 y(partition)24 b(a)i(mesh)f(into)g(an)g(arbitrary)e(number)h(of)h -(partitions.)39 b(Upon)24 b(successful)h(e)o(x)o(ecution,)f(both)g -(programs)f(display)i(statistics)0 5353 y(re)o(garding)h(the)j(quality) -g(of)g(the)g(computed)e(partitioning)g(and)i(the)g(amount)f(of)h(time)g -(tak)o(en)g(to)h(perform)d(the)i(partitioning.)50 b(The)1929 -5649 y(9)p eop -%%Page: 10 10 -10 9 bop 478 90 a Fi(')p 478 2624 7 2372 v 478 2793 a(&)3415 -90 y($)p 3415 2624 V 3415 2793 a(\045)p 648 2793 2605 -7 v 648 90 V 590 159 a Fj(prompt\045)39 b(pmetis)f(m14.graph3)h(16)590 -237 y(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 316 y(METIS)h(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -474 y(Graph)f(Information)f -(--------------------------------------------)o(-------)669 -553 y(Name:)i(m14.graph3,)e(#Vertices:)g(214765,)h(#Edges:)g(1679018,)f -(#Parts:)h(16)669 632 y(Balancing)g(Constraints:)f(3)590 -790 y(Recursive)g(Partitioning...)g -(-------------------------------------------)669 868 -y(16-way)h(Edge-Cut:)119 b(74454,)39 b(Balance:)78 b(1.01)h(1.03)g -(1.02)590 1026 y(Timing)39 b(Information)f -(-------------------------------------------)o(-------)669 -1105 y(I/O:)1155 b(4.310)669 1184 y(Partitioning:)756 -b(28.410)118 b(\(PMETIS)39 b(time\))669 1263 y(Total:)1036 -b(32.830)590 1342 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)590 1499 y(prompt\045)39 -b(kmetis)f(m14.graph3)h(16)590 1578 y -(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 1657 y(METIS)h(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -1815 y(Graph)f(Information)f -(--------------------------------------------)o(-------)669 -1894 y(Name:)i(m14.graph3,)e(#Vertices:)g(214765,)h(#Edges:)g(1679018,) -f(#Parts:)h(16)669 1973 y(Balancing)g(Constraints:)f(3)590 -2130 y(K-way)h(Partitioning...)e -(-----------------------------------------------)669 -2209 y(16-way)i(Edge-Cut:)119 b(71410,)39 b(Balance:)78 -b(1.04)h(1.04)g(1.04)590 2367 y(Timing)39 b(Information)f -(-------------------------------------------)o(-------)669 -2446 y(I/O:)1155 b(4.020)669 2525 y(Partitioning:)795 -b(7.430)119 b(\(KMETIS)39 b(time\))669 2604 y(Total:)1036 -b(11.550)590 2682 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)172 3028 y -Fy(Figure)18 b(4)p FL(:)26 b Fx(Output)18 b(of)h Fp(pmetis)f -Fx(and)g Fp(kmetis)g Fx(f)n(or)h(a)f(m)o(ulti-constr)o(aint)h(g)o(r)o -(aph)f(with)h(three)g(constr)o(aints)f(and)h(a)f(16-w)o(a)n(y)h(par)s -(tition.)0 3213 y FL(actual)f(partitioning)f(is)j(stored)e(in)h(tw)o(o) -g(\002les)g(named:)24 b Fo(MeshF)m(ile.npart.Nparts)18 -b FL(which)g(stores)h(the)f(partitioning)f(of)h(the)h(nodes,)f(and)0 -3322 y Fo(MeshF)m(ile.epart.Nparts)j FL(which)f(stores)i(the)f -(partitioning)f(of)h(the)g(elements.)28 b(The)21 b(format)f(of)i(the)f -(partitioning)e(\002les)k(is)f(described)0 3432 y(in)e(Section)g -(4.6.1.)100 3541 y(Figure)d(5)g(sho)n(ws)h(the)g(output)e(of)h -Fp(partnmesh)g FL(and)g Fp(partdmesh)f FL(for)h(partitioning)f(a)i -(mesh)f(with)h(tetrahedron)d(elements)j(into)0 3651 y(100)h(parts.)25 -b(From)20 b(this)h(\002gure)e(we)i(see)f(that)h(both)e(programs)f -(initially)j(print)e(information)f(about)h(the)h(mesh,)g(such)g(as)h -(its)g(name,)f(the)0 3761 y(number)d(of)i(elements)f(\()p -Fs(#Elements)p FL(\),)g(the)h(number)e(of)h(nodes)g(\()p -Fs(#Nodes)p FL(\),)g(and)g(the)h(type)g(of)f(elements)h(\()p -Fs(e)o(.g)n FL(.,)h Fs(TET)p FL(\).)e(Ne)o(xt,)h(the)o(y)f(print)0 -3870 y(some)27 b(information)d(re)o(garding)g(the)j(quality)f(of)h(the) -f(partitioning.)43 b(Speci\002cally)-5 b(,)28 b(the)o(y)e(report)g(the) -h(number)e(of)h(edges)h(being)f(cut)0 3980 y(\()p Fs(Edg)o(e-Cut)p -FL(\))21 b(by)h(the)h(partitioning)1017 3950 y Fn(2)1050 -3980 y FL(,)h(as)g(well)f(as)h(the)e(balance)g(of)h(the)g -(partitioning.)31 b(F)o(or)22 b(both)g Fp(partnmesh)g -FL(and)g Fp(partdmesh)p FL(,)0 4089 y(the)h(balance)e(is)j(computed)c -(with)j(respect)f(to)h(the)f(number)f(of)h(elements.)32 -b(The)22 b(balance)g(with)g(respect)h(to)f(the)h(number)e(of)h(nodes)g -(is)0 4199 y(not)e(sho)n(wn,)f(b)n(ut)h(it)h(is)g(in)g(general)e -(similar)h(to)g(the)h(element)e(balance.)100 4309 y(Finally)-5 -b(,)20 b(both)h Fp(partnmesh)f FL(and)g Fp(partdmesh)g -FL(sho)n(w)h(the)g(time)h(that)f(w)o(as)h(tak)o(en)e(by)h(the)g(v)n -(arious)f(phases)h(of)g(the)g(algorithm.)0 4418 y(All)k(times)h(are)e -(in)h(seconds.)38 b(In)25 b(this)g(particular)f(e)o(xample,)g(it)h -(took)f Fp(partnmesh)g FL(23.370)f(seconds)h(to)h(partition)e(the)i -(mesh)g(into)0 4528 y(100)17 b(parts.)25 b(Note)18 b(that)g(this)h -(time)f(includes)g(the)g(time)g(required)f(both)g(to)i(construct)e(the) -h(nodal)f(graph)g(and)h(to)g(partition)g(it.)25 b(Similarly)-5 -b(,)0 4637 y(it)24 b(took)f Fp(partdmesh)g FL(74.560)e(seconds)i(to)h -(partition)e(the)i(same)g(mesh.)35 b(Again,)23 b(this)h(time)g -(includes)f(the)g(time)h(required)e(both)g(to)0 4747 -y(construct)j(the)h(dual)g(graph)e(and)i(to)g(partition)f(it.)43 -b(As)27 b(you)f(can)f(see)i(from)e(this)i(e)o(xample,)f -Fp(partnmesh)f FL(is)i(considerably)c(f)o(aster)0 4857 -y(than)g Fp(partdmesh)p FL(.)32 b(This)23 b(is)h(because)e(of)h(tw)o(o) -g(reasons:)31 b(\(i\))23 b(the)g(time)g(required)e(to)i(construct)f -(the)h(nodal)f(graph)g(is)i(smaller)f(than)0 4966 y(the)d(time)h -(required)d(to)i(construct)f(the)i(dual)e(graph;)g(\(ii\))h(the)h -(nodal)e(graph)g(is)i(smaller)f(than)g(the)g(dual)g(graph.)p -0 5129 1560 4 v 87 5189 a Fm(2)120 5213 y FF(The)15 b(edgecut)j(that)f -(is)f(reported)i(by)e Fj(partnmesh)e FF(is)h(that)i(of)f(the)h(nodal)g -(graph,)f(whereas)h(the)g(edgecut)h(reported)f(by)f Fj(partdmesh)e -FF(is)i(that)h(of)f(the)g(dual)h(graph.)0 5292 y(These)g(tw)o(o)h -(edgecuts)h(cannot)f(be)g(compared)g(with)g(each)g(other)m(,)g(as)f -(the)o(y)h(correspond)h(to)e(partitionings)k(of)16 b(tw)o(o)i(totally)h -(dif)n(ferent)h(graphs.)1908 5649 y FL(10)p eop -%%Page: 11 11 -11 10 bop -18 83 a FB(Note)41 b FL(If)23 b(you)g(need)h(to)g(compute)e -(multiple)h(partitionings)g(of)g(the)h(same)g(mesh,)h(it)g(may)e(be)h -(preferable)e(to)i(\002rst)h(use)f(one)f(of)208 193 y(the)18 -b(mesh)f(con)m(v)o(ersion)f(programs)g(described)h(in)h(Section)f(4.4)h -(to)g(\002rst)h(con)m(v)o(ert)d(the)i(mesh)g(into)f(a)i(graph,)e(and)g -(then)h(use)208 302 y Fp(kmetis)h FL(to)i(partition)e(it.)25 -b(By)c(doing)e(this,)h(you)g(pay)f(the)h(cost)h(of)f(con)m(v)o(erting)d -(the)j(mesh)g(into)g(a)h(graph)e(only)g(once.)478 555 -y Fi(')p 478 2772 7 2054 v 478 2941 a(&)3415 555 y($)p -3415 2772 V 3415 2941 a(\045)p 648 2941 2605 7 v 648 -555 V 590 622 a Fj(prompt\045)39 b(partnmesh)f(144.mesh)h(100)590 -701 y(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 780 y(METIS)h(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -938 y(Mesh)f(Information)f -(---------------------------------------------)o(-------)669 -1016 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g -(Etype:)g(TET)590 1174 y(Partitioning)f(Nodal)h(Graph...)g -(-----------------------------------------)669 1253 y(100-way)g -(Edge-Cut:)79 b(105207,)38 b(Balance:)79 b(1.03)590 1411 -y(Timing)39 b(Information)f -(-------------------------------------------)o(-------)669 -1490 y(I/O:)1116 b(13.210)669 1569 y(Partitioning:)795 -b(7.950)590 1647 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)590 1805 y(prompt\045)39 -b(partdmesh)f(144.mesh)h(100)590 1884 y -(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 1963 y(METIS)h(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -2121 y(Mesh)f(Information)f -(---------------------------------------------)o(-------)669 -2199 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g -(Etype:)g(TET)590 2357 y(Partitioning)f(Dual)h(Graph...)g -(------------------------------------------)669 2436 -y(100-way)g(Edge-Cut:)118 b(52474,)39 b(Balance:)79 b(1.03)590 -2594 y(Timing)39 b(Information)f -(-------------------------------------------)o(-------)669 -2673 y(I/O:)1116 b(11.540)669 2752 y(Partitioning:)756 -b(28.220)590 2830 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)447 3176 y -Fy(Figure)18 b(5)p FL(:)25 b Fx(Output)19 b(of)f Fp(partnmesh)f -Fx(and)i Fp(partdmesh)e Fx(f)n(or)i(mesh)f Fh(144.mesh)h -Fx(and)g(a)f(100-w)o(a)n(y)h(par)s(tition.)0 3491 y Fr(4.3)100 -b(Spar)o(se)29 b(Matrix)f(Reor)n(dering)f(Pr)n(ograms)102 -3647 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 b FL(pro)o(vides)20 -b(tw)o(o)j(programs)e Fp(oemetis)h FL(and)g Fp(onmetis)g -FL(for)g(computing)e(\002ll-reducing)h(orderings)g(of)h(sparse)h -(matrices.)0 3756 y(Both)d(of)f(these)h(programs)d(use)j(multile)n(v)o -(el)e(nested)i(dissection)f(to)h(compute)e(a)i(\002ll-reducing)d -(ordering)g([8].)25 b(The)19 b(nested)g(dissection)0 -3866 y(paradigm)k(is)j(based)f(on)f(computing)f(a)i(v)o(erte)o -(x-separator)d(for)i(the)h(the)g(graph)e(corresponding)f(to)j(the)g -(matrix.)39 b(The)24 b(nodes)g(in)i(the)0 3975 y(separator)18 -b(are)i(mo)o(v)o(ed)d(to)j(the)f(end)g(of)h(the)f(matrix,)g(and)g(a)h -(similar)f(process)g(is)i(applied)d(recursi)n(v)o(ely)g(for)h(each)g -(one)g(of)g(the)h(other)e(tw)o(o)0 4085 y(parts.)100 -4195 y(Ev)o(en)j(though)f(both)h(programs)f(are)i(based)g(on)g(multile) -n(v)o(el)f(nested)h(dissection,)f(the)o(y)h(dif)n(fer)f(on)g(ho)n(w)h -(the)o(y)f(compute)g(the)h(v)o(erte)o(x)0 4304 y(separators.)38 -b(The)24 b Fp(oemetis)g FL(program)f(\002nds)i(a)g(v)o(erte)o(x)e -(separator)h(by)g(\002rst)h(computing)e(an)i(edge)f(separator)f(using)h -(a)i(multile)n(v)o(el)0 4414 y(algorithm,)f(whereas)f(the)h -Fp(onmetis)g FL(program)e(uses)j(the)f(multile)n(v)o(el)f(paradigm)f -(to)i(directly)g(\002nd)g(a)g(v)o(erte)o(x)f(separator)-5 -b(.)39 b(The)25 b(or)n(-)0 4523 y(derings)20 b(produced)f(by)i -Fp(onmetis)f FL(generally)g(incur)g(less)j(\002ll)f(than)f(those)g -(produced)d(by)j Fp(oemetis)p FL(.)28 b(In)20 b(particular)m(,)g(for)h -(matrices)0 4633 y(arising)g(in)g(linear)g(programming)d(problems)i -(the)h(orderings)f(computed)f(by)i Fp(onmetis)f FL(are)h -(signi\002cantly)g(better)g(than)g(those)g(pro-)0 4742 -y(duced)f(by)g Fp(oemetis)p FL(.)26 b(Furthermore,)18 -b Fp(onmetis)i FL(utilizes)i(compression)d(techniques)g(to)i(reduce)f -(the)g(size)i(of)e(the)h(graph)f(prior)f(to)0 4852 y(computing)f(the)j -(ordering.)j(Sparse)c(matrices)g(arising)g(in)h(man)o(y)e(application)g -(domains)h(are)g(such)g(that)h(certain)f(ro)n(ws)g(of)h(the)f(matrix)0 -4962 y(ha)n(v)o(e)27 b(the)g(same)g(sparsity)g(pattern.)45 -b(Such)27 b(matrices)g(can)g(be)g(represented)e(by)i(a)h(much)e -(smaller)h(graph)f(in)h(which)g(all)g(ro)n(ws)g(with)0 -5071 y(identical)d(sparsity)g(pattern)g(are)g(represented)f(by)h(just)h -(a)g(single)g(v)o(erte)o(x)e(whose)h(weight)g(is)h(equal)f(to)h(the)f -(number)f(of)h(ro)n(ws.)38 b(Such)0 5181 y(compression)21 -b(techniques)g(can)h(signi\002cantly)g(reduce)f(the)i(size)g(of)g(the)f -(graph,)g(whene)n(v)o(er)e(applicable,)i(and)g(substantially)g(reduce)0 -5290 y(the)k(amount)f(of)g(time)i(required)d(by)h Fp(onmetis)p -FL(.)42 b(Ho)n(we)n(v)o(er)m(,)25 b(when)h(there)f(is)i(no)f(reduction) -e(in)i(graph)e(size,)k Fp(oemetis)e FL(is)h(about)0 5400 -y(20\045)19 b(to)h(30\045)f(f)o(aster)g(than)g Fp(onmetis)p -FL(.)24 b(Furthermore,)17 b(for)i(lar)o(ge)f(matrices)h(arising)g(in)h -(three-dimensional)c(problems,)i(the)h(quality)1908 5649 -y(11)p eop -%%Page: 12 12 -12 11 bop 478 7 a Fi(')p 478 2541 7 2372 v 478 2710 a(&)3415 -7 y($)p 3415 2541 V 3415 2710 a(\045)p 648 2710 2605 -7 v 648 7 V 590 76 a Fj(prompt\045)39 b(oemetis)f(bcsstk31.graph)590 -154 y(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 233 y(METIS)i(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -391 y(Graph)f(Information)f -(--------------------------------------------)o(-------)669 -470 y(Name:)i(bcsstk31.graph,)d(#Vertices:)h(35588,)h(#Edges:)g(572914) -590 628 y(Edge-Based)f(Ordering...)g -(----------------------------------------------)669 707 -y(Nonzeros:)h(4693428,)158 b(Operation)39 b(Count:)g(1.4356e+09)590 -864 y(Timing)g(Information)f -(-------------------------------------------)o(-------)669 -943 y(I/O:)1155 b(1.160)669 1022 y(Ordering:)955 b(7.380)119 -b(\(OEMETIS)39 b(time\))669 1101 y(Symbolic)g(Factorization:)396 -b(0.440)669 1180 y(Total:)1075 b(8.980)590 1259 y -(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)590 1416 y(prompt\045)39 b(onmetis)f -(bcsstk31.graph)590 1495 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)669 1574 y(METIS)i(4.0)119 -b(Copyright)38 b(1998,)h(Regents)g(of)h(the)f(University)f(of)i -(Minnesota)590 1732 y(Graph)f(Information)f -(--------------------------------------------)o(-------)669 -1811 y(Name:)i(bcsstk31.graph,)d(#Vertices:)h(35588,)h(#Edges:)g -(572914)590 1968 y(Node-Based)f(Ordering...)g -(----------------------------------------------)669 2047 -y(Nonzeros:)h(4330669,)158 b(Operation)39 b(Count:)g(1.1564e+09)590 -2205 y(Timing)g(Information)f -(-------------------------------------------)o(-------)669 -2284 y(I/O:)1155 b(1.080)669 2363 y(Ordering:)955 b(4.540)119 -b(\(ONMETIS)39 b(time\))669 2442 y(Symbolic)g(Factorization:)396 -b(0.440)669 2521 y(Total:)1075 b(6.060)590 2599 y -(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)826 2945 y Fy(Figure)18 b(6)p -FL(:)25 b Fx(Output)19 b(of)f Fp(oemetis)g Fx(and)g Fp(onmetis)g -Fx(f)n(or)g(g)o(r)o(aph)h Fh(bcsstk31.g)o(r)o(aph)q Fx(.)0 -3130 y FL(of)h(orderings)e(produced)g(by)i(the)g(tw)o(o)g(algorithms)f -(is)i(quite)f(similar)-5 b(.)100 3239 y(Both)20 b Fp(oemetis)f -FL(and)h Fp(onmetis)f FL(are)i(in)m(v)n(ok)o(ed)d(by)i(pro)o(viding)d -(one)j(ar)o(gument)e(at)i(the)g(command)f(line)h(as)h(follo)n(ws:)257 -3432 y FB(oemetis)124 b Fs(Gr)o(aphF)l(ile)257 3541 y -FB(onmetis)119 b Fs(Gr)o(aphF)l(ile)100 3734 y FL(The)23 -b(only)f(ar)o(gument)f(of)i(these)h(programs)d Fs(Gr)o(aphF)l(ile)p -FL(,)i(is)i(the)e(name)g(of)g(the)g(\002le)h(that)g(stores)g(the)f -(sparse)g(matrix)g(in)h(the)f(graph)0 3844 y(format)g(described)g(in)h -(Section)f(4.5.1.)35 b(Upon)24 b(successful)f(e)o(x)o(ecution,)g(both)g -(programs)f(display)i(statistics)h(re)o(garding)c(the)j(quality)0 -3953 y(of)19 b(the)f(computed)f(orderings)g(and)h(the)h(amount)e(of)i -(time)g(tak)o(en)f(to)h(perform)e(the)i(ordering.)j(The)d(actual)f -(ordering)f(is)i(stored)g(in)g(a)g(\002le)0 4063 y(named)g -Fo(GraphF)m(ile.iperm)p FL(,)g(whose)h(format)f(is)i(described)e(in)i -(Section)e(4.6.2.)100 4172 y(Figure)i(6)g(sho)n(ws)h(the)g(output)e(of) -h Fp(oemetis)g FL(and)g Fp(onmetis)g FL(for)g(computing)f(a)i -(\002ll-reducing)d(ordering)h(of)h(a)h(sample)f(matrix.)0 -4282 y(From)i(this)h(\002gure)f(we)h(see)g(that)f(both)g(programs)f -(initially)h(print)g(information)e(about)i(the)g(graph,)g(such)h(as)g -(its)g(name,)g(the)f(number)0 4392 y(of)e(v)o(ertices)g(\()p -Fs(#V)-9 b(ertices)p FL(\),)20 b(and)g(the)i(number)d(of)i(edges)g(\()p -Fs(#Edg)o(es)p FL(\).)26 b(Ne)o(xt,)21 b(the)o(y)f(print)g(some)h -(information)e(re)o(garding)f(the)k(quality)e(of)0 4501 -y(the)f(ordering.)k(Speci\002cally)-5 b(,)18 b(the)o(y)g(report)g(the)h -(number)f(of)g(non-zeros)f(that)j(are)f(required)e(in)i(the)g(lo)n(wer) -g(triangular)f(matrix,)g(and)h(the)0 4611 y(number)e(of)i(operations)e -(\()p Fs(OPC)p FL(\))i(required)e(to)i(f)o(actor)f(the)h(matrix)g -(using)f(Cholesk)o(y)g(f)o(actorization.)23 b(Note)c(that)g(number)e -(of)h(nonzeros)0 4720 y(includes)26 b(both)g(the)i(original)d -(non-zeros)g(and)i(the)g(ne)n(w)g(non-zeros)e(due)h(to)h(the)g(\002ll.) -46 b(Finally)-5 b(,)28 b(both)f Fp(oemetis)f FL(and)g -Fp(onmetis)0 4830 y FL(sho)n(w)h(the)g(time)h(that)f(w)o(as)h(tak)o(en) -f(by)g(the)g(v)n(arious)g(phases)g(of)g(the)g(algorithm.)45 -b(All)28 b(times)g(are)f(in)g(seconds.)46 b(F)o(or)27 -b(this)h(particular)0 4940 y(e)o(xample,)e Fp(oemetis)f -FL(tak)o(es)i(a)f(total)g(of)g(23.290)e(seconds,)j(of)f(which)f(17.760) -f(seconds)i(w)o(as)h(tak)o(en)e(by)h(the)g(ordering)e(algorithm)0 -5049 y(itself.)41 b(F)o(or)25 b(the)g(same)h(e)o(xample)e -Fp(onmetis)g FL(tak)o(es)i(a)f(total)h(of)f(17.340)e(seconds,)j(of)f -(which)g(11.810)e(seconds)i(w)o(as)h(tak)o(en)f(by)g(the)0 -5159 y(partitioning)d(algorithm)h(itself.)38 b(Note)24 -b(that)g(in)h(this)g(case)f Fp(onmetis)g FL(is)h(f)o(aster)f(than)g -Fp(oemetis)p FL(,)g(because)g Fp(onmetis)g FL(w)o(as)h(able)0 -5268 y(to)20 b(compress)g(the)g(matrix.)k(Also)d(note)e(that)i(the)f -(quality)f(of)h(the)g(\002ll-reducing)e(ordering)g(produced)g(by)i -Fp(onmetis)f FL(is)i(signi\002cantly)0 5378 y(better)j(than)g(that)g -(produced)e(by)i Fp(oemetis)p FL(.)37 b(In)24 b(f)o(act,)i(the)e -(ordering)e(produced)g(by)i Fp(onmetis)g FL(results)h(in)f(8\045)h(fe)n -(wer)f(non-zeros)1908 5649 y(12)p eop -%%Page: 13 13 -13 12 bop 0 83 a FL(and)20 b(20\045)g(fe)n(wer)f(operations.)0 -314 y Fr(4.4)100 b(A)m(uxiliar)q(y)28 b(Pr)n(ograms)0 -470 y FB(4.4.1)84 b(Mesh)23 b(T)-7 b(o)23 b(Graph)f(Con)m(ver)o(sion) -478 593 y Fi(')p 478 2809 7 2054 v 478 2979 a(&)3415 -593 y($)p 3415 2809 V 3415 2979 a(\045)p 648 2979 2605 -7 v 648 593 V 590 660 a Fj(prompt\045)39 b(mesh2nodal)f(144.mesh)590 -739 y(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 818 y(METIS)i(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -975 y(Mesh)f(Information)f -(---------------------------------------------)o(-------)669 -1054 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g -(Etype:)g(TET)590 1212 y(Forming)g(Nodal)g(Graph...)f -(----------------------------------------------)669 1291 -y(Nodal)i(Information:)e(#Vertices:)g(144649,)h(#Edges:)g(1074393)590 -1449 y(Timing)g(Information)f -(-------------------------------------------)o(-------)669 -1527 y(I/O:)1116 b(15.290)669 1606 y(Nodal)40 b(Creation:)715 -b(3.030)590 1685 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)590 1843 y(prompt\045)39 -b(mesh2dual)f(144.mesh)590 1922 y -(******************************************)o(*******)o(******)o -(*******)o(*******)o(*)669 2001 y(METIS)i(4.0)119 b(Copyright)38 -b(1998,)h(Regents)g(of)h(the)f(University)f(of)i(Minnesota)590 -2158 y(Mesh)f(Information)f -(---------------------------------------------)o(-------)669 -2237 y(Name:)i(144.mesh,)e(#Elements:)g(905410,)h(#Nodes:)g(144649,)g -(Etype:)g(TET)590 2395 y(Forming)g(Dual)g(Graph...)f -(-----------------------------------------------)669 -2474 y(Dual)i(Information:)e(#Vertices:)g(905410,)h(#Edges:)g(1786484) -590 2632 y(Timing)g(Information)f -(-------------------------------------------)o(-------)669 -2710 y(I/O:)1116 b(19.200)669 2789 y(Dual)40 b(Creation:)716 -b(10.880)590 2868 y(******************************************)o -(*******)o(******)o(*******)o(*******)o(*)785 3214 y -Fy(Figure)18 b(7)p FL(:)25 b Fx(Output)19 b(of)g Fp(mesh2nodal)e -Fx(and)h Fp(mesh2dual)f Fx(f)n(or)i(mesh)f Fh(144.mesh)q -Fx(.)102 3408 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)27 -b FL(pro)o(vides)21 b(tw)o(o)j(programs)d Fp(mesh2nodal)h -FL(and)g Fp(mesh2dual)g FL(for)h(con)m(v)o(erting)d(a)j(mesh)g(into)g -(the)g(graph)f(format)g(used)0 3518 y(by)i Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)r FL(.)24 b(In)e(particular)m(,)f -Fp(mesh2nodal)g FL(con)m(v)o(erts)g(the)h(element)g(node)f(array)g(of)h -(a)h(mesh)f(into)g(a)h(nodal)e(graph;)h Fs(i.e)p FL(.,)h(each)f(node)0 -3627 y(of)30 b(the)f(mesh)h(corresponds)e(to)i(a)g(v)o(erte)o(x)e(in)i -(the)g(graph)e(and)i(tw)o(o)g(v)o(ertices)f(are)h(connected)e(by)h(an)h -(edge)f(if)h(the)g(corresponding)0 3737 y(nodes)c(are)h(connected)d(by) -j(lines)g(in)g(the)f(mesh.)45 b(Similarly)-5 b(,)27 b -Fp(mesh2dual)f FL(con)m(v)o(erts)e(the)j(element)f(node)g(array)g(of)g -(a)h(mesh)g(into)0 3847 y(a)g(dual)f(graph;)i Fs(i.e)p -FL(.,)g(each)e(element)g(of)g(the)h(mesh)f(corresponds)f(to)h(a)h(v)o -(erte)o(x)e(in)i(the)f(graph)f(and)h(tw)o(o)h(v)o(ertices)f(are)h -(connected)d(if)0 3956 y(the)c(corresponding)d(elements)j(in)h(the)f -(mesh)h(share)f(a)h(f)o(ace.)k(These)c(mesh-to-graph)c(con)m(v)o -(ersion)g(programs)i(support)g(meshes)h(with)0 4066 y(triangular)m(,)e -(tetrahedra,)g(and)i(he)o(xahedra)e(\(bricks\))h(elements.)100 -4175 y(Both)h Fp(mesh2nodal)f FL(and)g Fp(mesh2dual)g -FL(are)i(in)m(v)n(ok)o(ed)d(by)i(pro)o(viding)d(one)j(ar)o(gument)e(at) -i(the)h(command)d(line)i(as)h(follo)n(ws:)257 4349 y -FB(mesh2nodal)124 b Fs(MeshF)l(ile)257 4459 y FB(mesh2dual)175 -b Fs(MeshF)l(ile)100 4633 y FL(The)30 b(only)h(ar)o(gument)d(of)j -(these)g(programs)e Fs(MeshF)l(ile)p FL(,)34 b(is)e(the)f(name)g(of)f -(the)h(\002le)h(that)f(stores)g(the)h(mesh)e(\(whose)h(format)f(is)0 -4742 y(described)15 b(in)h(Section)g(4.5.2\).)22 b(Upon)15 -b(successful)h(e)o(x)o(ecution,)f(both)g(programs)g(display)g -(information)f(about)h(the)h(generated)f(graphs,)0 4852 -y(and)k(the)h(amount)f(of)g(time)h(tak)o(en)g(to)g(perform)e(the)i(con) -m(v)o(ersion.)i(The)e(actual)f(graph)g(is)i(stored)e(in)h(a)g(\002le)h -(named:)j Fo(MeshF)m(ile.ngraph)0 4962 y FL(in)g(the)g(case)g(of)f -Fp(mesh2nodal)f FL(and)i Fo(MeshF)m(ile.dgraph)e FL(in)i(the)g(case)g -(of)f Fp(mesh2dual)p FL(.)35 b(The)23 b(format)f(of)i(these)g(graph)e -(\002les)j(are)0 5071 y(compatible)19 b(with)j Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(and)19 b(is)i(described)e(in)i -(Section)e(4.5.1.)100 5181 y(Figure)e(7)g(sho)n(ws)h(the)g(output)e(of) -i Fp(mesh2nodal)e FL(and)h Fp(mesh2dual)g FL(for)g(generating)f(the)h -(nodal)g(and)g(dual)h(graphs)e(of)i(a)g(sample)0 5290 -y(mesh.)30 b(Note)22 b(that)g(the)g(sizes)h(of)e(the)h(generated)e -(graphs)h(are)h(dif)n(ferent,)e(as)j(the)f(dual)f(graph)g(is)i(lar)o -(ger)d(than)i(the)g(nodal)f(graph.)28 b(Also)0 5400 y(note)20 -b(that)g(generating)e(the)i(nodal)g(graph)e(is)k(considerably)c(f)o -(aster)i(than)g(generating)e(the)i(dual)g(graph.)1908 -5649 y(13)p eop -%%Page: 14 14 -14 13 bop 0 83 a FB(4.4.2)84 b(Graph)22 b(Chec)n(ker)2 -209 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(pro)o(vide)18 -b(a)j(program)d(called)j Fp(graphchk)e FL(to)i(check)f(whether)f(or)h -(not)g(the)h(format)e(of)h(a)h(graph)e(is)j(appropriate)c(for)i(use)g -(with)2 319 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r -FL(.)24 b(This)e(program)e(should)h(be)h(used)g(whene)n(v)o(er)e(there) -i(is)h(an)o(y)e(doubt)f(about)i(the)g(format)f(of)g(an)o(y)h(graph)e -(\002le.)31 b(It)23 b(is)g(in)m(v)n(ok)o(ed)d(by)0 428 -y(pro)o(viding)d(one)j(ar)o(gument)e(at)j(the)f(command)e(line)i(as)h -(follo)n(ws:)257 621 y FB(graphc)o(hk)124 b Fs(Gr)o(aphF)l(ile)0 -814 y FL(where)20 b Fs(Gr)o(aphF)l(ile)f FL(is)i(the)f(name)g(of)g(the) -g(\002le)h(that)f(stores)g(the)h(graph.)1908 5649 y(14)p -eop -%%Page: 15 15 -15 14 bop 0 83 a Fr(4.5)100 b(Input)27 b(File)h(Formats)0 -242 y FL(The)d(v)n(arious)f(programs)g(in)k Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)29 b FL(require)24 b(as)i(input)f(either)g(a)h -(\002le)g(storing)f(a)h(graph)e(or)h(a)h(\002le)g(storing)e(a)i(mesh.) -40 b(The)26 b(format)e(of)0 352 y(these)c(\002les)i(are)e(described)f -(in)h(the)g(follo)n(wing)f(sections.)0 561 y FB(4.5.1)84 -b(Graph)22 b(File)0 687 y FL(The)j(primary)f(input)g(of)i(the)f -(partitioning)e(and)i(\002ll-reducing)f(ordering)f(programs)g(in)28 -b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)30 b FL(is)c(the)f(graph)f(to)i -(be)f(partitioned)f(or)0 797 y(ordered.)f(This)d(graph)f(is)i(stored)f -(in)g(a)h(\002le)g(and)e(is)j(supplied)d(to)h(the)g(v)n(arious)f -(programs)g(as)i(one)e(of)h(the)g(command)f(line)h(parameters.)100 -907 y(A)i(graph)h Ft(G)32 b FM(D)26 b Fu(.)r Ft(V)8 b -Fu(;)20 b Ft(E)7 b Fu(/)24 b FL(with)e Ft(n)k FL(v)o(ertices)c(and)f -Ft(m)28 b FL(edges)22 b(is)h(stored)f(in)g(a)h(plain)f(te)o(xt)g -(\002le)h(that)f(contains)f Ft(n)j FM(C)19 b FL(1)k(lines)f(\(e)o -(xcluding)0 1016 y(comment)i(lines\).)40 b(The)25 b(\002rst)h(line)f -(contains)g(information)e(about)h(the)h(size)h(and)f(the)g(type)g(of)g -(the)g(graph,)g(while)g(the)g(remaining)f Ft(n)0 1126 -y FL(lines)d(contain)e(information)f(for)h(each)h(v)o(erte)o(x)f(of)j -Ft(G)5 b FL(.)25 b(An)o(y)19 b(line)i(that)f(starts)h(with)f(`\045')h -(is)g(a)f(comment)f(line)h(and)g(is)h(skipped.)100 1235 -y(The)g(\002rst)h(line)f(contains)g(either)g(tw)o(o)h(\()p -Ft(n)s FL(,)g Ft(m)5 b FL(\),)21 b(three)g(\()p Ft(n)s -FL(,)h Ft(m)5 b FL(,)22 b Fs(fmt)p FL(\),)g(or)f(four)f(\()p -Ft(n)s FL(,)i Ft(m)5 b FL(,)22 b Fs(fmt)p FL(,)g Fs(ncon)p -FL(\))e(inte)o(gers.)28 b(The)21 b(\002rst)h(tw)o(o)f(inte)o(gers)0 -1345 y(\()p Ft(n)s FL(,)f Ft(m)5 b FL(\))19 b(are)g(the)g(number)e(of)i -(v)o(ertices)f(and)h(the)g(number)e(of)i(edges,)g(respecti)n(v)o(ely)-5 -b(.)22 b(Note)d(that)h(in)f(determining)e(the)i(number)e(of)i(edges)0 -1455 y Ft(m)5 b FL(,)26 b(an)e(edge)g(between)g(an)o(y)f(pair)h(of)h(v) -o(ertices)f Fu(v)k FL(and)c Ft(u)29 b FL(is)d(counted)d -FC(only)h(once)g FL(and)g(not)g(twice)h(\()p Fs(i.e)p -FL(.,)g(we)g(do)f(not)g(count)g(the)g(edge)0 1564 y Fu(.v)s(;)14 -b Ft(u)t Fu(/)22 b FL(separately)e(from)g Fu(.)p Ft(u)t -Fu(;)14 b(v)s(/)p FL(\).)28 b(F)o(or)20 b(e)o(xample,)f(the)i(graph)f -(in)h(Figure)f(8)g(contains)h(11)f(v)o(ertices.)26 b(The)21 -b(third)f(inte)o(ger)f(\()p Fs(fmt)p FL(\))i(is)h(used)0 -1674 y(to)h(specify)g(whether)f(or)h(not)g(the)g(graph)f(has)i(weights) -f(associated)g(with)g(its)h(v)o(ertices,)g(its)g(edges,)f(or)g(both.)33 -b(T)-7 b(able)24 b(2)f(describes)g(the)0 1783 y(possible)i(v)n(alues)g -(of)h Fs(fmt)g FL(and)f(their)g(meaning.)40 b(Note)25 -b(that)h(if)g(the)g(graph)e(is)i(unweighted)e(\()p Fs(i.e)o -FL(.,)j(all)f(v)o(ertices)f(and)g(edges)h(ha)n(v)o(e)f(the)0 -1893 y(same)d(weight\),)f(then)h(the)f Fs(fmt)j FL(parameter)d(can)g -(be)h(omitted.)29 b(Finally)-5 b(,)22 b(the)g(fourth)e(inte)o(ger)h(\() -p Fs(ncon)p FL(\))f(is)j(used)e(to)h(specify)g(the)f(number)0 -2003 y(of)e(weights)g(associated)f(with)i(each)e(v)o(erte)o(x)g(of)g -(the)h(graph.)24 b(The)18 b(v)n(alue)h(of)f(this)i(parameter)d -(determines)h(whether)g(or)h(not)i Fz(M)l FG(E)-17 b -Fz(T)g FG(I)p Fz(S)23 b FL(will)0 2112 y(use)e(the)f(multi-constraint)e -(partitioning)h(algorithms)g(described)g(in)i(Section)f(3.)26 -b(If)20 b(the)g(v)o(ertices)g(of)g(the)h(graph)e(ha)n(v)o(e)h(no)g -(weights)g(or)0 2222 y(only)h(a)h(single)f(weight,)g(then)g(the)h -Fs(ncon)f FL(parameter)f(can)h(be)g(omitted.)29 b(Ho)n(we)n(v)o(er)m(,) -19 b(if)j Fs(ncon)f FL(is)h(greater)f(than)g(0,)h(then)f(the)g(\002le)i -(should)0 2331 y(contain)18 b(the)h(required)f(v)o(erte)o(x)g(weights)h -(and)f(the)h Fs(fmt)h FL(parameter)e(should)g(be)h(set)h(appropriately) -d(\()p Fs(i.e)o FL(.,)j(it)f(should)g(be)g(set)h(to)f(either)g(10)0 -2441 y(or)h(11\).)p 590 2625 2721 4 v 588 2725 4 100 -v 640 2695 a Fs(fmt)p 794 2725 V 99 w FL(Meaning)p 3309 -2725 V 590 2728 2721 4 v 588 2828 4 100 v 672 2798 a(0)p -794 2828 V 131 w(The)g(graph)f(has)h(no)g(weights)g(associated)g(with)h -(either)e(the)i(edges)e(or)h(the)g(v)o(ertices)p 3309 -2828 V 590 2831 2721 4 v 588 2930 4 100 v 672 2901 a(1)p -794 2930 V 131 w(The)g(graph)f(has)h(weights)g(associated)g(with)h(the) -f(edges)p 3309 2930 V 590 2934 2721 4 v 588 3033 4 100 -v 651 3004 a(10)p 794 3033 V 110 w(The)g(graph)f(has)h(weights)g -(associated)g(with)h(the)f(v)o(ertices)p 3309 3033 V -590 3037 2721 4 v 588 3136 4 100 v 651 3106 a(11)p 794 -3136 V 110 w(The)g(graph)f(has)h(weights)g(associated)g(with)h(both)e -(the)h(edges)g(&)g(v)o(ertices)p 3309 3136 V 590 3140 -2721 4 v 776 3292 a Fy(T)-5 b(ab)o(le)17 b(2)p FL(:)26 -b Fx(The)18 b(v)n(ar)q(ious)h(possib)o(le)f(v)n(alues)h(f)n(or)g(the)f -Fh(fmt)h Fx(par)o(ameter)e(and)i(their)f(meaning.)100 -3571 y FL(The)f(remaining)g Ft(n)22 b FL(lines)c(store)h(information)c -(about)j(the)g(actual)g(structure)f(of)h(the)g(graph.)23 -b(In)18 b(particular)m(,)f(the)g Ft(i)9 b FL(th)18 b(line)g(\(e)o -(xcluding)0 3680 y(comment)25 b(lines\))h(contains)f(information)f -(that)i(is)h(rele)n(v)n(ant)e(to)h(the)f Ft(i)9 b FL(th)26 -b(v)o(erte)o(x.)41 b(Depending)24 b(on)i(the)g(v)n(alue)f(of)h(the)g -Fs(fmt)h FL(and)f Fs(ncon)0 3790 y FL(parameters,)d(the)h(information)e -(stored)h(at)h(each)g(line)g(is)h(some)n(what)e(dif)n(ferent.)34 -b(In)23 b(the)h(most)g(general)f(form)g(\(when)g Fs(fmt)h(=)h(11)e -FL(and)0 3899 y Fs(ncon)c Fu(>)i Fs(1)p FL(\))f(each)f(line)i(will)g -(ha)n(v)o(e)e(the)h(follo)n(wing)f(structure:)1225 4100 -y Fu(w)1286 4112 y Fn(1)1322 4100 y Fu(;)14 b(w)1424 -4112 y Fn(2)1460 4100 y Fu(;)g(:)g(:)g(:)f(w)1672 4112 -y Ff(n)r(c)q(o)q(n)1806 4100 y Fu(;)38 b(v)1911 4112 -y Fn(1)1947 4100 y Fu(;)14 b Ft(e)2025 4112 y Fn(1)2061 -4100 y Fu(;)g(v)2142 4112 y Fn(2)2178 4100 y Fu(;)g Ft(e)2256 -4112 y Fn(2)2292 4100 y Fu(;)g(:)g(:)g(:)f(;)h(v)2524 -4112 y Ff(k)2561 4100 y Fu(;)g Ft(e)2639 4112 y Ff(k)0 -4301 y FL(where)20 b Fu(w)285 4313 y Fn(1)321 4301 y -Fu(;)14 b(w)423 4313 y Fn(2)459 4301 y Fu(;)g(:)g(:)g(:)f(;)h(w)712 -4313 y Ff(n)r(c)q(o)q(n)869 4301 y FL(are)21 b(the)g -Fs(ncon)f FL(v)o(erte)o(x)f(weights)i(associated)g(with)g(this)h(v)o -(erte)o(x,)d Fu(v)2765 4313 y Fn(1)2801 4301 y Fu(;)14 -b(v)2882 4313 y Fn(2)2919 4301 y Fu(;)g(:)g(:)g(:)f(;)h(v)3151 -4313 y Ff(k)3210 4301 y FL(are)20 b(the)i(v)o(ertices)e(adja-)0 -4411 y(cent)h(to)f(this)h(v)o(erte)o(x,)f(and)g Ft(e)812 -4423 y Fn(1)847 4411 y Fu(;)14 b Ft(e)925 4423 y Fn(2)961 -4411 y Fu(;)g(:)g(:)g(:)f(;)h Ft(e)1190 4423 y Ff(k)1248 -4411 y FL(are)20 b(the)h(weights)f(of)h(these)g(edges.)k(In)c(the)f -(remaining)f(of)i(this)g(section)f(we)h(illustrate)g(this)0 -4520 y(format)e(by)h(a)h(sequence)e(of)h(e)o(xamples.)k(Note)d(that)f -(the)g(v)o(ertices)g(are)g(numbered)e(starting)i(from)g(1)g(\(not)g -(from)f(0)h(as)h(is)h(often)d(done)g(in)0 4630 y(C\).)j(Furthermore,)d -(the)i(v)o(erte)o(x-weights)e(must)i(be)h(inte)o(gers)e(greater)h(or)g -(equal)g(to)g(0,)h(whereas)f(the)g(edge-weights)f(must)h(be)g(strictly) -0 4740 y(greater)e(than)h(0.)100 4849 y(The)k(simplest)g(format)g(for)f -(a)i(graph)g Ft(G)30 b FL(is)25 b(when)f(the)h(weight)e(of)i(all)f(v)o -(ertices)g(and)g(the)h(weight)f(of)g(all)h(the)f(edges)g(is)h(the)g -(same.)0 4959 y(This)20 b(format)f(is)j(illustrated)d(in)i(Figure)e -(8\(a\).)24 b(Note,)c(the)h(optional)d Fs(fmt)23 b FL(parameter)18 -b(is)k(skipped)d(in)h(this)h(case.)100 5068 y(Ho)n(we)n(v)o(er)m(,)30 -b(there)g(are)g(cases)h(in)f(which)g(the)g(edges)g(in)i -Ft(G)k FL(ha)n(v)o(e)30 b(dif)n(ferent)e(weights.)55 -b(This)30 b(is)i(accommodated)27 b(as)k(sho)n(wn)e(in)0 -5178 y(Figure)21 b(8\(b\).)30 b(No)n(w)-5 b(,)22 b(the)g(adjacenc)o(y)f -(list)i(of)f(each)f(v)o(erte)o(x)g(contains)h(the)g(weight)f(of)h(the)g -(edges)g(in)g(addition)f(to)i(the)f(v)o(ertices)f(that)i(is)0 -5288 y(connected)18 b(with.)25 b(If)20 b Fu(v)25 b FL(has)20 -b Ft(k)26 b FL(v)o(ertices)19 b(adjacent)g(to)i(it,)f(then)g(the)g -(line)g(for)g Fu(v)k FL(in)c(the)g(graph)f(\002le)i(contains)e(2)f -FM(\003)g Ft(k)26 b FL(numbers,)18 b(each)i(pair)0 5397 -y(of)j(numbers)f(stores)i(the)f(v)o(erte)o(x)f(that)i -Fu(v)k FL(is)c(connected)e(to,)i(and)f(the)h(weight)f(of)g(the)g(edge.) -35 b(Note)23 b(that)h(the)f Fs(fmt)j FL(parameter)c(is)i(equal)1908 -5649 y(15)p eop -%%Page: 16 16 -16 15 bop 600 3819 a @beginspecial 0 @llx 0 @lly 673 -@urx 952 @ury 3240 @rwi @setspecial -%%BeginDocument: ./figures/graph00.eps -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {0 setgray} bind def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save --8.0 955.0 translate -1 -1 scale - -/cp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/sa {save} bind def -/rs {restore} bind def -/l {lineto} bind def -/m {moveto} bind def -/rm {rmoveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/sh {show} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/sd {setdash} bind def -/ff {findfont} bind def -/sf {setfont} bind def -/scf {scalefont} bind def -/sw {stringwidth} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/reencdict 12 dict def /ReEncode { reencdict begin -/newcodesandnames exch def /newfontname exch def /basefontname exch def -/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def -basefontdict { exch dup /FID ne { dup /Encoding eq -{ exch dup length array copy newfont 3 1 roll put } -{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall -newfont /FontName newfontname put newcodesandnames aload pop -128 1 255 { newfont /Encoding get exch /.notdef put } for -newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat -newfontname newfont definefont pop end } def -/isovec [ -8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde -8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis -8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron -8#220 /dotlessi 8#230 /oe 8#231 /OE -8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling -8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis -8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot -8#255 /endash 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus -8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph -8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine -8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf -8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute -8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring -8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute -8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute -8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve -8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply -8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex -8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave -8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring -8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute -8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute -8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve -8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide -8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex -8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def -/Times-BoldItalic /Times-BoldItalic-iso isovec ReEncode -/Times-Roman /Times-Roman-iso isovec ReEncode -/Helvetica-Bold /Helvetica-Bold-iso isovec ReEncode -/Courier /Courier-iso isovec ReEncode -/Helvetica /Helvetica-iso isovec ReEncode -/Times-Bold /Times-Bold-iso isovec ReEncode -/Helvetica-BoldOblique /Helvetica-BoldOblique-iso isovec ReEncode - /DrawEllipse { - /endangle exch def - /startangle exch def - /yrad exch def - /xrad exch def - /y exch def - /x exch def - /savematrix mtrx currentmatrix def - x y tr xrad yrad sc 0 0 1 startangle endangle arc - closepath - savematrix setmatrix - } def - -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit -n -1000 16912 m -1000 -1000 l 12337 -1000 l 12337 16912 l cp clip - 0.06000 0.06000 sc -% Polyline -7.500 slw -n 826 3151 m 2026 2026 l gs col-1 s gr -% Polyline -n 901 3151 m 2926 2926 l gs col-1 s gr -% Polyline -n 2926 2926 m 2026 2026 l gs col-1 s gr -% Polyline -n 901 1276 m 1951 526 l gs col-1 s gr -% Polyline -n 1951 526 m 3226 1126 l gs col-1 s gr -% Polyline -n 1951 526 m 2026 2026 l gs col-1 s gr -% Polyline -n 2026 2026 m 976 1276 l gs col-1 s gr -% Polyline -n 3226 1126 m 2926 2926 l gs col-1 s gr -% Polyline -n 2926 2926 m 3976 2401 l gs col-1 s gr -% Polyline -n 3976 2401 m 3226 1126 l gs col-1 s gr -% Polyline -n 901 1276 m 826 3151 l gs col-1 s gr -% Polyline -n 7352 11402 m 8552 10277 l gs col-1 s gr -% Polyline -n 7427 11402 m 9452 11177 l gs col-1 s gr -% Polyline -n 9452 11177 m 8552 10277 l gs col-1 s gr -% Polyline -n 7427 9527 m 8477 8777 l gs col-1 s gr -% Polyline -n 8477 8777 m 9752 9377 l gs col-1 s gr -% Polyline -n 8477 8777 m 8552 10277 l gs col-1 s gr -% Polyline -n 8552 10277 m 7502 9527 l gs col-1 s gr -% Polyline -n 9752 9377 m 9452 11177 l gs col-1 s gr -% Polyline -n 9452 11177 m 10502 10652 l gs col-1 s gr -% Polyline -n 10502 10652 m 9752 9377 l gs col-1 s gr -% Polyline -n 7427 9527 m 7352 11402 l gs col-1 s gr -% Polyline -n 7126 3152 m 8326 2027 l gs col-1 s gr -% Polyline -n 7201 3152 m 9226 2927 l gs col-1 s gr -% Polyline -n 9226 2927 m 8326 2027 l gs col-1 s gr -% Polyline -n 7201 1277 m 8251 527 l gs col-1 s gr -% Polyline -n 8251 527 m 9526 1127 l gs col-1 s gr -% Polyline -n 8251 527 m 8326 2027 l gs col-1 s gr -% Polyline -n 8326 2027 m 7276 1277 l gs col-1 s gr -% Polyline -n 9526 1127 m 9226 2927 l gs col-1 s gr -% Polyline -n 9226 2927 m 10276 2402 l gs col-1 s gr -% Polyline -n 10276 2402 m 9526 1127 l gs col-1 s gr -% Polyline -n 7201 1277 m 7126 3152 l gs col-1 s gr -% Polyline -n 977 11252 m 2177 10127 l gs col-1 s gr -% Polyline -n 1052 11252 m 3077 11027 l gs col-1 s gr -% Polyline -n 3077 11027 m 2177 10127 l gs col-1 s gr -% Polyline -n 1052 9377 m 2102 8627 l gs col-1 s gr -% Polyline -n 2102 8627 m 3377 9227 l gs col-1 s gr -% Polyline -n 2102 8627 m 2177 10127 l gs col-1 s gr -% Polyline -n 2177 10127 m 1127 9377 l gs col-1 s gr -% Polyline -n 3377 9227 m 3077 11027 l gs col-1 s gr -% Polyline -n 3077 11027 m 4127 10502 l gs col-1 s gr -% Polyline -n 4127 10502 m 3377 9227 l gs col-1 s gr -% Polyline -n 1052 9377 m 977 11252 l gs col-1 s gr -% Ellipse -n 2008 2008 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 901 1276 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 1933 508 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 3208 1108 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 2908 2908 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 3958 2383 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 808 3133 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 8534 10259 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 7427 9527 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 8459 8759 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 9734 9359 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 9434 11159 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 10484 10634 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 7334 11384 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 8308 2009 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 7201 1277 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 8233 509 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 9508 1109 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 9208 2909 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 10258 2384 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 7108 3134 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 2159 10109 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 1052 9377 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 2084 8609 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 3359 9209 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 3059 11009 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 4109 10484 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -% Ellipse -n 959 11234 168 168 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr - -/Helvetica-iso ff 210.00 scf sf -1951 2101 m -gs 1 -1 sc (3) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -2851 3001 m -gs 1 -1 sc (4) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -1876 601 m -gs 1 -1 sc (5) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -3151 1201 m -gs 1 -1 sc (6) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -751 3226 m -gs 1 -1 sc (2) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -3901 2476 m -gs 1 -1 sc (7) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -863 1351 m -gs 1 -1 sc (1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 4727 m -gs 1 -1 sc (7 11) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 4997 m -gs 1 -1 sc (5 3 2) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 5267 m -gs 1 -1 sc (1 3 4) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 5807 m -gs 1 -1 sc (2 3 6 7) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 6077 m -gs 1 -1 sc (1 3 6) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 6347 m -gs 1 -1 sc (5 4 7) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 6617 m -gs 1 -1 sc (6 4) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1202 5537 m -gs 1 -1 sc (5 4 2 1) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -8477 10352 m -gs 1 -1 sc (3) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -9377 11252 m -gs 1 -1 sc (4) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -8402 8852 m -gs 1 -1 sc (5) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -9677 9452 m -gs 1 -1 sc (6) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -7277 11477 m -gs 1 -1 sc (2) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -10427 10727 m -gs 1 -1 sc (7) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -7389 9602 m -gs 1 -1 sc (1) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -8251 2102 m -gs 1 -1 sc (3) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -9151 3002 m -gs 1 -1 sc (4) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -8176 602 m -gs 1 -1 sc (5) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -9451 1202 m -gs 1 -1 sc (6) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -7051 3227 m -gs 1 -1 sc (2) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -10201 2477 m -gs 1 -1 sc (7) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -7163 1352 m -gs 1 -1 sc (1) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -7651 827 m -gs 1 -1 sc (1) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -8926 752 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -8401 1352 m -gs 1 -1 sc (3) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -7801 1577 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -7726 2477 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -8176 3002 m -gs 1 -1 sc (1) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -8776 2402 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -9226 2027 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -9676 2627 m -gs 1 -1 sc (5) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -9976 1727 m -gs 1 -1 sc (6) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -6976 2177 m -gs 1 -1 sc (1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 4728 m -gs 1 -1 sc (7 11 1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 4998 m -gs 1 -1 sc (5 1 3 2 2 1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 5268 m -gs 1 -1 sc (1 1 3 2 4 1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 5538 m -gs 1 -1 sc (5 3 4 2 2 2 1 2) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 5808 m -gs 1 -1 sc (2 1 3 2 6 2 7 5) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 6078 m -gs 1 -1 sc (1 1 3 3 6 2) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 6348 m -gs 1 -1 sc (5 2 4 2 7 6) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7502 6618 m -gs 1 -1 sc (6 6 4 5) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -2102 10202 m -gs 1 -1 sc (3) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -3002 11102 m -gs 1 -1 sc (4) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -2027 8702 m -gs 1 -1 sc (5) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -3302 9302 m -gs 1 -1 sc (6) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -902 11327 m -gs 1 -1 sc (2) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -4052 10577 m -gs 1 -1 sc (7) col-1 sh gr -/Helvetica-iso ff 210.00 scf sf -1014 9452 m -gs 1 -1 sc (1) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -1502 8927 m -gs 1 -1 sc (1) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -2777 8852 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -2252 9452 m -gs 1 -1 sc (3) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -1652 9677 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -1577 10577 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -2027 11102 m -gs 1 -1 sc (1) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -2627 10502 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -3077 10127 m -gs 1 -1 sc (2) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -3527 10727 m -gs 1 -1 sc (5) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -3827 9827 m -gs 1 -1 sc (6) col-1 sh gr -/Times-Bold-iso ff 210.00 scf sf -827 10277 m -gs 1 -1 sc (1) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -750 9150 m -gs 1 -1 sc ([4]) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -600 11025 m -gs 1 -1 sc ([2]) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -1950 8325 m -gs 1 -1 sc ([1]) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -3300 8925 m -gs 1 -1 sc ([6]) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -2325 9900 m -gs 1 -1 sc ([5]) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -2925 11400 m -gs 1 -1 sc ([3]) col-1 sh gr -/Helvetica-BoldOblique-iso ff 210.00 scf sf -4350 10500 m -gs 1 -1 sc ([2]) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 12828 m -gs 1 -1 sc (7 11 11) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 13098 m -gs 1 -1 sc (4 5 1 3 2 2 1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 13368 m -gs 1 -1 sc (2 1 1 3 2 4 1) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 13638 m -gs 1 -1 sc (5 5 3 4 2 2 2 1 2) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 13908 m -gs 1 -1 sc (3 2 1 3 2 6 2 7 5) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 14178 m -gs 1 -1 sc (1 1 1 3 3 6 2) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 14448 m -gs 1 -1 sc (6 5 2 4 2 7 6) col-1 sh gr -/Courier-iso ff 210.00 scf sf -1353 14718 m -gs 1 -1 sc (2 6 6 4 5) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 12978 m -gs 1 -1 sc (7 11 10 3) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 13248 m -gs 1 -1 sc (1 2 0 5 3 2) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 13518 m -gs 1 -1 sc (0 2 2 1 3 4) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 14058 m -gs 1 -1 sc (2 2 3 2 3 6 7) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 14328 m -gs 1 -1 sc (1 1 1 1 3 6) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 14598 m -gs 1 -1 sc (2 2 1 5 4 7) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 14868 m -gs 1 -1 sc (1 2 1 6 4) col-1 sh gr -/Courier-iso ff 210.00 scf sf -7728 13788 m -gs 1 -1 sc (4 1 1 5 4 2 1) col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -1501 7351 m -gs 1 -1 sc (\(a\)) dup sw pop neg 0 rm col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -1801 7351 m -gs 1 -1 sc (Unweighted Graph) col-1 sh gr -% Polyline -n 301 3826 m 4351 3826 l gs col-1 s gr -/Times-Roman-iso ff 180.00 scf sf -600 4350 m -gs 1 -1 sc (Graph File:) col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -1052 15377 m -gs 1 -1 sc (\(c\)) dup sw pop neg 0 rm col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -1352 15377 m -gs 1 -1 sc (Weighted Graph) col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -1352 15647 m -gs 1 -1 sc (Weights both on vertices and edges) col-1 sh gr -% Polyline -n 452 11927 m 4652 11927 l gs col-1 s gr -/Times-Roman-iso ff 180.00 scf sf -751 12451 m -gs 1 -1 sc (Graph File:) col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -8026 7276 m -gs 1 -1 sc (\(b\)) dup sw pop neg 0 rm col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -8326 7276 m -gs 1 -1 sc (Weighted Graph) col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -8326 7546 m -gs 1 -1 sc (Weights on edges) col-1 sh gr -% Polyline -n 6827 12077 m 10877 12077 l gs col-1 s gr -% Polyline -n 6601 3827 m 10726 3827 l gs col-1 s gr -% Polyline -n 6450 8100 m 11325 8100 l 11325 15900 l 6450 15900 l cp gs col0 s gr -% Polyline -n 150 8100 m 5025 8100 l 5025 15900 l 150 15900 l cp gs col0 s gr -% Polyline -n 150 75 m 5025 75 l 5025 7875 l 150 7875 l cp gs col0 s gr -% Polyline -n 6450 75 m 11325 75 l 11325 7875 l 6450 7875 l cp gs col0 s gr -/Times-BoldItalic-iso ff 210.00 scf sf -6600 11100 m -gs 1 -1 sc ([0, 2, 2]) col0 sh gr -/Times-BoldItalic-iso ff 210.00 scf sf -7050 9225 m -gs 1 -1 sc ([1, 2, 0]) col0 sh gr -/Times-BoldItalic-iso ff 210.00 scf sf -8175 8475 m -gs 1 -1 sc ([1, 1, 1]) col0 sh gr -/Times-BoldItalic-iso ff 210.00 scf sf -9525 9075 m -gs 1 -1 sc ([2, 2, 1]) col0 sh gr -/Times-BoldItalic-iso ff 210.00 scf sf -8700 10050 m -gs 1 -1 sc ([4, 1, 1]) col0 sh gr -/Times-BoldItalic-iso ff 210.00 scf sf -10425 10350 m -gs 1 -1 sc ([1, 2, 1]) col0 sh gr -/Times-BoldItalic-iso ff 210.00 scf sf -9225 11550 m -gs 1 -1 sc ([2, 2, 3]) col0 sh gr -/Times-Roman-iso ff 180.00 scf sf -7126 12601 m -gs 1 -1 sc (Graph File:) col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -8027 15602 m -gs 1 -1 sc (\(d\)) dup sw pop neg 0 rm col-1 sh gr -/Helvetica-Bold-iso ff 180.00 scf sf -8327 15602 m -gs 1 -1 sc (Multi-Constraint Graph) col-1 sh gr -/Times-Roman-iso ff 180.00 scf sf -6900 4351 m -gs 1 -1 sc (Graph File:) col-1 sh gr -$F2psEnd -rs -%%EndDocument - @endspecial 1168 4002 a Fy(Figure)18 b(8)p FL(:)25 b -Fx(Stor)o(age)19 b(f)n(or)r(mat)f(f)n(or)g(v)n(ar)q(ious)h(type)g(of)f -(g)o(r)o(aphs)o(.)0 4186 y FL(to)i(1,)g(indicating)f(the)h(f)o(act)h -(that)h Ft(G)k FL(has)20 b(weights)g(on)g(the)g(edges.)100 -4296 y(In)e(addition)g(to)h(ha)n(ving)f(weights)g(on)h(the)g(edges,)f -(weights)h(on)f(the)h(v)o(ertices)g(are)f(also)i(allo)n(wed,)e(as)h -(illustrated)g(in)g(Figure)f(8\(c\).)24 b(In)0 4406 y(this)f(case,)h -(the)f(v)n(alue)f(of)g Fs(fmt)j FL(is)f(equal)e(to)h(11,)g(and)f(each)g -(line)h(of)g(the)f(graph)g(\002le)h(\002rst)h(stores)f(the)g(weight)f -(of)g(the)h(v)o(erte)o(x,)f(and)g(then)0 4515 y(the)e(weighted)f -(adjacenc)o(y)g(list.)100 4625 y(Finally)-5 b(,)22 b(Figure)h(8\(d\))f -(illustrates)h(the)g(format)f(of)h(the)g(input)f(\002le)h(when)g(the)g -(v)o(ertices)f(of)h(the)g(graph)e(contain)h(multiple)h(weights)0 -4734 y(\(3)h(in)g(this)g(e)o(xample\).)34 b(In)24 b(this)g(case,)h(the) -f(v)n(alue)f(of)g Fs(fmt)i FL(is)g(equal)e(to)h(10)f(\(we)h(do)g(not)f -(ha)n(v)o(e)g(weights)h(associated)g(with)g(the)g(edges\),)0 -4844 y(and)e(the)g(v)n(alue)f(of)h Fs(ncon)f FL(is)i(equal)e(to)i(3)f -(\(since)g(we)g(ha)n(v)o(e)g(three)f(sets)i(of)f(v)o(erte)o -(x-weights\).)28 b(Each)22 b(line)g(of)g(the)g(graph)e(\002le)j(stores) -g(the)0 4954 y(three)d(weights)g(of)g(the)g(v)o(ertices)g(follo)n(wed)e -(by)i(the)g(adjacenc)o(y)f(list.)0 5163 y FB(4.5.2)84 -b(Mesh)23 b(File)0 5289 y FL(The)h(primary)g(input)g(of)g(the)h(mesh)f -(partitioning)f(programs)g(in)k Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)29 b FL(is)c(the)g(mesh)g(to)g(be)f(partitioned.)37 -b(This)25 b(mesh)g(is)g(stored)f(in)0 5399 y(a)f(\002le)h(in)f(the)g -(form)f(of)h(the)g(element)g(node)f(array)-5 b(.)32 b(A)23 -b(mesh)g(with)g Ft(n)k FL(elements)c(is)h(stored)e(in)h(a)h(plain)e(te) -o(xt)h(\002le)h(that)f(contains)f Ft(n)i FM(C)c FL(1)1908 -5649 y(16)p eop -%%Page: 17 17 -17 16 bop 0 83 a FL(lines.)30 b(The)22 b(\002rst)g(line)g(contains)f -(information)f(about)g(the)i(size)h(and)e(the)h(type)f(of)h(the)f -(mesh,)h(while)g(the)g(remaining)e Ft(n)25 b FL(lines)e(contain)0 -193 y(the)d(nodes)g(that)g(mak)o(e)g(up)f(each)h(element.)100 -302 y(The)i(\002rst)h(line)f(contains)g(tw)o(o)g(inte)o(gers.)31 -b(The)22 b(\002rst)h(inte)o(ger)e(is)i(the)g(number)d(of)i(elements)g -Ft(n)k FL(in)d(the)f(mesh.)31 b(The)22 b(second)g(inte)o(ger)0 -412 y Fs(etype)e FL(is)h(used)f(to)g(denote)f(the)h(type)f(of)h -(elements)g(that)g(the)g(mesh)g(is)h(made)e(of)n(f.)25 -b Fs(Etype)19 b FL(can)h(either)g(tak)o(e)g(the)g(v)n(alues)f(of)h(1,)g -(2,)g(3,)g(or)g(4,)0 521 y(indicating)f(that)h(the)g(mesh)g(consists)h -(of)f(either)g(triangles,)f(tetrahedra,)g(he)o(xahedra)e(\(bricks\),)i -(or)h(quadrilaterals,)e(respecti)n(v)o(ely)-5 b(.)100 -631 y(After)21 b(the)g(\002rst)h(line,)f(the)h(remaining)d -Ft(n)25 b FL(lines)d(store)f(the)g(element)g(node)f(array)-5 -b(.)27 b(In)21 b(particular)f(for)h(element)e Ft(i)9 -b FL(,)22 b(line)e Ft(i)28 b FM(C)19 b FL(1)i(stores)0 -741 y(the)j(nodes)g(that)g(this)h(element)f(is)h(made)e(of)n(f.)37 -b(Depending)22 b(on)i Fs(etype)p FL(,)h(each)f(line)g(can)g(either)g -(ha)n(v)o(e)g(three)f(inte)o(gers)h(\(in)g(the)g(case)h(of)0 -850 y(triangles\),)e(four)g(inte)o(gers)g(\(in)g(the)g(case)h(of)g -(tetrahedra)e(and)h(quadrilaterals\),)f(or)h(eight)h(inte)o(gers)e -(\(in)i(the)f(case)h(of)g(he)o(xahedra\).)32 b(In)0 960 -y(the)22 b(case)g(of)g(triangles)f(and)g(tetrahedra,)g(the)h(ordering)d -(of)j(the)g(nodes)f(for)g(each)h(element)f(does)h(not)f(matter)-5 -b(.)30 b(Ho)n(we)n(v)o(er)m(,)20 b(in)i(the)g(case)0 -1069 y(of)f(he)o(xahedra)e(and)i(quadrilaterals,)f(the)i(nodes)e(for)h -(each)g(element)g(should)g(be)g(ordered)f(according)f(to)j(the)f -(numbering)e(illustrated)0 1179 y(in)h(Figure)g(9\(b\).)k(Note)c(that)g -(the)g(node)f(numbering)f(starts)j(from)e(1.)100 1289 -y(Figure)h(9)h(illustrates)h(this)g(format)e(for)g(a)i(small)f(mesh)g -(with)g(triangular)f(elements.)27 b(Note)21 b(that)h(the)f -Fs(etype)g FL(\002eld)g(of)g(the)g(mesh)g(\002le)0 1398 -y(is)g(set)g(to)f(1)h(indicating)e(that)h(the)g(mesh)g(consists)h(of)f -(triangular)e(elements.)750 2599 y @beginspecial 0 @llx -0 @lly 469 @urx 215 @ury 2880 @rwi @setspecial -%%BeginDocument: ./figures/meshformat.eps -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {} def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save --32.0 264.0 translate -1 -1 scale - -/clp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/l {lineto} bind def -/m {moveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit - 0.06000 0.06000 sc -/Times-Roman findfont 180.00 scalefont setfont -750 2850 m -gs 1 -1 sc (Mesh File:) col-1 show gr -/Helvetica-Bold findfont 210.00 scalefont setfont -1650 4350 m -gs 1 -1 sc (\(a\) Sample Mesh File) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -4350 2566 m -gs 1 -1 sc (2) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -5430 2700 m -gs 1 -1 sc (3) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -1605 2288 m -gs 1 -1 sc (1) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -1597 1268 m -gs 1 -1 sc (6) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -2183 1860 m -gs 1 -1 sc (3) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -2145 952 m -gs 1 -1 sc (5) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -1043 930 m -gs 1 -1 sc (4) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -6053 2310 m -gs 1 -1 sc (4) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -8228 2385 m -gs 1 -1 sc (4) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -7050 1441 m -gs 1 -1 sc (2) col-1 show gr -/Helvetica-Bold findfont 210.00 scalefont setfont -6450 3375 m -gs 1 -1 sc (\(b\) Ordering of nodes) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -7043 2378 m -gs 1 -1 sc (1) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -8205 1425 m -gs 1 -1 sc (3) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -4958 1312 m -gs 1 -1 sc (5) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -4350 1650 m -gs 1 -1 sc (6) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -5468 1800 m -gs 1 -1 sc (7) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -6030 1379 m -gs 1 -1 sc (8) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -4943 2228 m -gs 1 -1 sc (1) col-1 show gr -/Helvetica findfont 180.00 scalefont setfont -1050 1875 m -gs 1 -1 sc (2) col-1 show gr -/Courier findfont 180.00 scalefont setfont -1725 3900 m -gs 1 -1 sc (5 6 3) col-1 show gr -7.500 slw -% Polyline -n 1200 900 m 1200 1800 l 2100 1800 l 2100 900 l 1200 900 l gs col-1 s gr -% Polyline -n 1200 900 m 2100 1800 l gs col-1 s gr -% Polyline -n 1650 1350 m 1200 1800 l gs col-1 s gr -/Courier findfont 180.00 scalefont setfont -1725 3690 m -gs 1 -1 sc (4 5 6) col-1 show gr -/Courier findfont 180.00 scalefont setfont -1725 2850 m -gs 1 -1 sc (5 1) col-1 show gr -/Courier findfont 180.00 scalefont setfont -1725 3060 m -gs 1 -1 sc (1 2 3) col-1 show gr -/Courier findfont 180.00 scalefont setfont -1725 3270 m -gs 1 -1 sc (2 4 6) col-1 show gr -/Courier findfont 180.00 scalefont setfont -1725 3480 m -gs 1 -1 sc (2 6 3) col-1 show gr -% Polyline -n 2100 900 m 1650 1350 l gs col-1 s gr -% Polyline -n 5100 1335 m 4500 1635 l gs col-1 s gr -% Polyline -n 6000 1335 m 5400 1635 l gs col-1 s gr -% Polyline -n 5100 2235 m 4500 2535 l gs col-1 s gr -% Polyline -n 6000 2235 m 5400 2535 l gs col-1 s gr -% Polyline -n 4500 1635 m 5400 1635 l 5400 2535 l 4500 2535 l clp gs col-1 s gr -% Polyline -n 1200 1800 m 1650 2400 l gs col-1 s gr -% Polyline -n 2100 1800 m 1650 2400 l gs col-1 s gr -% Polyline -n 600 2550 m 2550 2550 l gs col-1 s gr -% Polyline -n 7200 1500 m 8100 1500 l 8100 2400 l 7200 2400 l clp gs col-1 s gr -% Polyline -n 5100 1335 m 6000 1335 l 6000 2235 l 5100 2235 l clp gs col-1 s gr -$F2psEnd -restore -%%EndDocument - @endspecial 180 2782 a Fy(Figure)g(9)p FL(:)25 b Fx(\(a\))19 -b(The)f(\002le)h(that)f(stores)h(the)f(mesh.)23 b(\(b\))18 -b(The)g(order)q(ing)g(of)h(the)f(nodes)h(in)g(the)f(case)h(of)g(he)n -(xahedr)o(a)f(and)g(quadr)q(ilater)o(als)o(.)0 3093 y -Fr(4.6)100 b(Output)27 b(File)h(Formats)0 3252 y FL(The)h(output)f(of)k -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)33 b FL(is)e(either)e(a)h -(partition)e(or)i(an)f(ordering)e(\002le,)33 b(depending)27 -b(on)i(whether)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)34 -b FL(is)c(used)g(for)f(graph/mesh)0 3362 y(partitioning)18 -b(or)i(for)g(sparse)g(matrix)f(ordering.)k(The)d(format)f(of)h(these)g -(\002les)i(are)e(described)f(in)h(the)g(follo)n(wing)f(sections.)0 -3571 y FB(4.6.1)84 b(P)n(ar)r(tition)22 b(File)0 3697 -y FL(The)28 b(partition)g(\002le)i(of)e(a)h(graph)f(with)h -Ft(n)j FL(v)o(ertices)d(consists)g(of)f Ft(n)33 b FL(lines)c(with)g(a)g -(single)g(number)e(per)h(line.)51 b(The)28 b Ft(i)9 b -FL(th)28 b(line)h(of)g(the)0 3807 y(\002le)d(contains)e(the)h -(partition)e(number)g(that)i(the)f Ft(i)9 b FL(th)25 -b(v)o(erte)o(x)e(belongs)h(to.)39 b(P)o(artition)24 b(numbers)f(start)j -(from)e(0)g(up)h(to)g(the)g(number)e(of)0 3916 y(partitions)c(minus)h -(one.)0 4126 y FB(4.6.2)84 b(Or)n(dering)23 b(File)0 -4252 y FL(The)28 b(ordering)f(\002le)j(of)e(a)h(graph)f(with)h -Ft(n)j FL(v)o(ertices)d(consists)g(of)f Ft(n)33 b FL(lines)c(with)g(a)g -(single)g(number)e(per)h(line.)51 b(The)28 b Ft(i)9 b -FL(th)28 b(line)h(of)g(the)0 4361 y(ordering)18 b(\002le)j(contains)e -(the)i(ne)n(w)f(order)e(of)i(the)g Ft(i)9 b FL(th)20 -b(v)o(erte)o(x)e(of)i(the)g(graph.)k(The)c(numbering)d(in)k(the)f -(ordering)e(\002le)j(starts)g(from)e(0.)100 4471 y(Note)g(that)g(the)g -(ordering)d(\002le)k(stores)f(what)g(is)h(referred)d(to)i(as)h(the)f -(the)g(in)m(v)o(erse)f(permutation)e(v)o(ector)i Fs(iperm)h -FL(of)g(the)g(ordering.)j(Let)8 4581 y Ft(A)g FL(be)e(a)g(matrix)f(and) -g(let)29 b Ft(A)779 4550 y Fe(0)820 4581 y FL(be)20 b(the)f(reordered)f -(matrix.)24 b(The)19 b(in)m(v)o(erse)g(permutation)f(v)o(ector)g(maps)i -(the)f Ft(i)9 b FL(th)19 b(ro)n(w)h(\(column\))d(of)28 -b Ft(A)22 b FL(into)0 4690 y(the)e Fs(iperm)p FM(T)o -Ft(i)9 b FM(U)19 b FL(ro)n(w)h(\(column\))e(of)28 b Ft(A)1046 -4660 y Fe(0)1067 4690 y FL(.)1908 5649 y(17)p eop -%%Page: 18 18 -18 17 bop 0 85 a FD(5)119 b(M)-6 b FA(E)-23 b FD(T)g -FA(I)p FD(S)s(')-7 b(s)31 b(Librar)q(y)h(Interface)0 -261 y FL(The)17 b(v)n(arious)g(programs)f(pro)o(vided)f(in)20 -b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)22 b FL(can)c(also)g(be)f -(directly)g(accessed)h(from)f(a)h(C)g(or)g(F)o(ortran)e(program)g(by)h -(using)g(the)h(stand-)0 370 y(alone)27 b(library)h Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)p FL(.)49 b(Furthermore,)29 -b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)30 b FL(e)o(xtends)d(the)g -(functionality)e(pro)o(vided)g(by)k Fz(M)l FG(E)-17 b -Fz(T)g FG(I)p Fz(S)r FL(')-5 b(s)30 b(stand-alone)25 -b(programs)0 480 y(in)h(tw)o(o)h(dif)n(ferent)d(w)o(ays.)43 -b(First,)29 b(it)d(allo)n(ws)h(the)f(user)g(to)g(alter)h(the)f(beha)n -(vior)e(of)i(the)g(v)n(arious)f(algorithms)g(in)k Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(,)28 b(and)d(second)2 -590 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)31 b -FL(pro)o(vides)26 b(additional)g(routines)h(that)g(can)h(be)f(used)g -(to)h(partition)f(graphs)f(into)i(unequal-size)d(partitions)i(and)g -(compute)0 699 y(partitionings)19 b(that)h(directly)f(minimize)h(the)g -(total)g(communication)d(v)n(olume.)100 809 y(In)24 b(the)g(rest)g(of)g -(this)h(section)f(we)h(describe)e(the)h(interf)o(ace)f(to)i(the)f -(routines)f(in)k Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)27 -b FL(by)d(\002rst)h(describing)d(the)j(v)n(arious)e(data)0 -918 y(structures)e(used)h(to)g(pass)g(information)e(into)h(and)h(get)f -(information)f(out)h(of)h(the)g(routines,)f(follo)n(wed)f(by)i(a)g -(detailed)f(description)g(of)0 1028 y(the)f(calling)g(sequence)f(of)h -(the)g(v)n(arious)f(routines.)0 1255 y Fr(5.1)100 b(Graph)27 -b(Data)i(Structure)0 1415 y FL(All)24 b(of)f(the)h(graph)e -(partitioning)f(and)i(sparse)h(matrix)f(ordering)e(routines)h(in)k -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)27 b FL(tak)o(e)c(as)h -(input)f(the)h(adjacenc)o(y)d(structure)i(of)0 1524 y(the)d(graph)f -(and)h(the)g(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(\(if)g -(an)o(y\).)100 1634 y(The)25 b(adjacenc)o(y)e(structure)h(of)h(the)h -(graph)e(is)i(stored)f(using)f(the)i(compressed)d(storage)i(format)f -(\(CSR\).)i(The)f(CSR)i(format)d(is)i(a)0 1744 y(widely)e(used)h -(scheme)g(for)f(storing)g(sparse)h(graphs.)38 b(In)24 -b(this)i(format)e(the)g(adjacenc)o(y)g(structure)g(of)g(a)h(graph)f -(with)h Ft(n)k FL(v)o(ertices)24 b(and)0 1853 y Ft(m)k -FL(edges)22 b(is)h(represented)e(using)h(tw)o(o)g(arrays)g -Fp(xadj)h FL(and)e Fp(adjncy)p FL(.)32 b(The)22 b Fp(xadj)g -FL(array)f(is)j(of)e(size)h Ft(n)g FM(C)d FL(1)j(whereas)f(the)g -Fp(adjncy)0 1963 y FL(array)d(is)i(of)f(size)h(2)p Ft(m)k -FL(\(this)c(is)g(because)e(for)h(each)g(edge)f(between)h(v)o(ertices)f -Fu(v)25 b FL(and)19 b Ft(u)25 b FL(we)c(actually)e(store)h(both)g -Fu(.v)s(;)14 b Ft(u)t Fu(/)21 b FL(and)f Fu(.)p Ft(u)t -Fu(;)14 b(v)s(/)p FL(\).)100 2072 y(The)21 b(adjacenc)o(y)e(structure)i -(of)g(the)g(graph)f(is)j(stored)e(as)h(follo)n(ws.)28 -b(Assuming)21 b(that)g(v)o(erte)o(x)f(numbering)f(starts)j(from)e(0)i -(\(C)g(style\),)0 2182 y(then)32 b(the)g(adjacenc)o(y)f(list)j(of)e(v)o -(erte)o(x)e Ft(i)42 b FL(is)33 b(stored)f(in)h(array)e -Fp(adjncy)h FL(starting)g(at)h(inde)o(x)e Fp(xadj[)o -Ft(i)9 b Fp(])32 b FL(and)g(ending)f(at)i(\(b)n(ut)f(not)0 -2292 y(including\))17 b(inde)o(x)g Fp(xadj[)o Ft(i)22 -b FM(C)14 b FL(1)p Fp(])k FL(\()p Fs(i.e)o FL(.,)h Fp(adjncy[xadj[)o -Ft(i)9 b Fp(]])17 b FL(through)g(and)h(including)f Fp(adjncy[xadj[)o -Ft(i)j FM(C)14 b FL(1)p Fp(]-1])p FL(\).)23 b(That)0 -2401 y(is,)h(for)e(each)h(v)o(erte)o(x)d Ft(i)9 b FL(,)24 -b(its)g(adjacenc)o(y)d(list)j(is)g(stored)e(in)h(consecuti)n(v)o(e)e -(locations)h(in)h(the)g(array)f Fp(adjncy)p FL(,)h(and)f(the)h(array)f -Fp(xadj)h FL(is)0 2511 y(used)i(to)h(point)f(to)h(where)f(it)h(be)o -(gins)f(and)g(where)g(it)h(ends.)41 b(Figure)25 b(10\(b\))f -(illustrates)i(the)g(CSR)h(format)d(for)h(the)h(15-v)o(erte)o(x)d -(graph)0 2620 y(sho)n(wn)c(in)i(Figure)e(10\(a\).)450 -3789 y @beginspecial 0 @llx 0 @lly 506 @urx 180 @ury -3600 @rwi @setspecial -%%BeginDocument: ./figures/csr.eps -/$F2psDict 200 dict def -$F2psDict begin -$F2psDict /mtrx matrix put -/col-1 {} def -/col0 {0.000 0.000 0.000 srgb} bind def -/col1 {0.000 0.000 1.000 srgb} bind def -/col2 {0.000 1.000 0.000 srgb} bind def -/col3 {0.000 1.000 1.000 srgb} bind def -/col4 {1.000 0.000 0.000 srgb} bind def -/col5 {1.000 0.000 1.000 srgb} bind def -/col6 {1.000 1.000 0.000 srgb} bind def -/col7 {1.000 1.000 1.000 srgb} bind def -/col8 {0.000 0.000 0.560 srgb} bind def -/col9 {0.000 0.000 0.690 srgb} bind def -/col10 {0.000 0.000 0.820 srgb} bind def -/col11 {0.530 0.810 1.000 srgb} bind def -/col12 {0.000 0.560 0.000 srgb} bind def -/col13 {0.000 0.690 0.000 srgb} bind def -/col14 {0.000 0.820 0.000 srgb} bind def -/col15 {0.000 0.560 0.560 srgb} bind def -/col16 {0.000 0.690 0.690 srgb} bind def -/col17 {0.000 0.820 0.820 srgb} bind def -/col18 {0.560 0.000 0.000 srgb} bind def -/col19 {0.690 0.000 0.000 srgb} bind def -/col20 {0.820 0.000 0.000 srgb} bind def -/col21 {0.560 0.000 0.560 srgb} bind def -/col22 {0.690 0.000 0.690 srgb} bind def -/col23 {0.820 0.000 0.820 srgb} bind def -/col24 {0.500 0.190 0.000 srgb} bind def -/col25 {0.630 0.250 0.000 srgb} bind def -/col26 {0.750 0.380 0.000 srgb} bind def -/col27 {1.000 0.500 0.500 srgb} bind def -/col28 {1.000 0.630 0.630 srgb} bind def -/col29 {1.000 0.750 0.750 srgb} bind def -/col30 {1.000 0.880 0.880 srgb} bind def -/col31 {1.000 0.840 0.000 srgb} bind def - -end -save --8.0 206.0 translate -1 -1 scale - -/clp {closepath} bind def -/ef {eofill} bind def -/gr {grestore} bind def -/gs {gsave} bind def -/l {lineto} bind def -/m {moveto} bind def -/n {newpath} bind def -/s {stroke} bind def -/slc {setlinecap} bind def -/slj {setlinejoin} bind def -/slw {setlinewidth} bind def -/srgb {setrgbcolor} bind def -/rot {rotate} bind def -/sc {scale} bind def -/tr {translate} bind def -/tnt {dup dup currentrgbcolor - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add - 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} - bind def -/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul - 4 -2 roll mul srgb} bind def -/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def -/$F2psEnd {$F2psEnteredState restore end} def - -$F2psBegin -10 setmiterlimit - 0.06000 0.06000 sc -/Times-Roman findfont 150.00 scalefont setfont -4725 2850 m -gs 1 -1 sc (3) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4500 2850 m -gs 1 -1 sc (12) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4350 2850 m -gs 1 -1 sc (8) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4200 2850 m -gs 1 -1 sc (6) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4875 2850 m -gs 1 -1 sc (7) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -5550 2850 m -gs 1 -1 sc (8) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -5400 2850 m -gs 1 -1 sc (4) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -5175 2850 m -gs 1 -1 sc (13) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -5025 2850 m -gs 1 -1 sc (9) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4050 2850 m -gs 1 -1 sc (2) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2700 2850 m -gs 1 -1 sc (9) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2250 2850 m -gs 1 -1 sc (4) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2100 2850 m -gs 1 -1 sc (2) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1050 2850 m -gs 1 -1 sc (5) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2550 2850 m -gs 1 -1 sc (3) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3825 2850 m -gs 1 -1 sc (11) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3675 2850 m -gs 1 -1 sc (7) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3525 2850 m -gs 1 -1 sc (5) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3375 2850 m -gs 1 -1 sc (1) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2400 2850 m -gs 1 -1 sc (8) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -5700 2850 m -gs 1 -1 sc (14) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -8100 2850 m -gs 1 -1 sc (9) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -7875 2850 m -gs 1 -1 sc (14) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -7650 2850 m -gs 1 -1 sc (12) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -7500 2850 m -gs 1 -1 sc (8) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -8250 2850 m -gs 1 -1 sc (13) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -600 2850 m -gs 1 -1 sc (adjncy) dup stringwidth pop neg 0 rmoveto col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -600 2550 m -gs 1 -1 sc (xadj) dup stringwidth pop neg 0 rmoveto col-1 show gr -/Helvetica-Bold findfont 210.00 scalefont setfont -3900 3375 m -gs 1 -1 sc (\(b CSR format) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr -/Helvetica-Bold findfont 210.00 scalefont setfont -3900 1500 m -gs 1 -1 sc (\(a\) A sample graph) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr -7.500 slw -% Polyline -n 150 2250 m 8550 2250 l 8550 3000 l 150 3000 l clp gs col-1 s gr -/Times-Roman findfont 150.00 scalefont setfont -7275 2850 m -gs 1 -1 sc (13) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -5925 2850 m -gs 1 -1 sc (5) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3150 2850 m -gs 1 -1 sc (10) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3000 2850 m -gs 1 -1 sc (6) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2850 2850 m -gs 1 -1 sc (0) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -6075 2850 m -gs 1 -1 sc (11) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -7050 2850 m -gs 1 -1 sc (11) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -6900 2850 m -gs 1 -1 sc (7) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -6675 2850 m -gs 1 -1 sc (12) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -6450 2850 m -gs 1 -1 sc (10) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -6300 2850 m -gs 1 -1 sc (6) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1950 2850 m -gs 1 -1 sc (7) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4350 1125 m -gs 1 -1 sc (14) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4050 1125 m -gs 1 -1 sc (13) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3750 1125 m -gs 1 -1 sc (12) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3450 1125 m -gs 1 -1 sc (11) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3225 525 m -gs 1 -1 sc (0) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4425 525 m -gs 1 -1 sc (4) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4125 525 m -gs 1 -1 sc (3) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3825 525 m -gs 1 -1 sc (2) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3525 525 m -gs 1 -1 sc (1) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3150 1125 m -gs 1 -1 sc (10) col-1 show gr -% Polyline -n 4200 525 m 4200 1125 l gs col-1 s gr -% Polyline -n 3900 525 m 3900 1125 l gs col-1 s gr -% Polyline -n 3600 525 m 3600 1125 l gs col-1 s gr -% Polyline -n 3300 525 m 4500 525 l 4500 1125 l 3300 1125 l 3300 525 l gs col-1 s gr -% Polyline -n 3300 825 m 4500 825 l gs col-1 s gr -/Times-Roman findfont 150.00 scalefont setfont -4425 825 m -gs 1 -1 sc (9) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -4125 825 m -gs 1 -1 sc (8) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3825 825 m -gs 1 -1 sc (7) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3525 825 m -gs 1 -1 sc (6) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3225 825 m -gs 1 -1 sc (5) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -900 2550 m -gs 1 -1 sc (0) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3975 2550 m -gs 1 -1 sc (44) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3750 2550 m -gs 1 -1 sc (42) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3525 2550 m -gs 1 -1 sc (39) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3300 2550 m -gs 1 -1 sc (36) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -900 2850 m -gs 1 -1 sc (1) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1800 2850 m -gs 1 -1 sc (3) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1650 2850 m -gs 1 -1 sc (1) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1500 2850 m -gs 1 -1 sc (6) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1350 2850 m -gs 1 -1 sc (2) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1200 2850 m -gs 1 -1 sc (0) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -3075 2550 m -gs 1 -1 sc (33) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1500 2550 m -gs 1 -1 sc (11) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1350 2550 m -gs 1 -1 sc (8) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1200 2550 m -gs 1 -1 sc (5) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1050 2550 m -gs 1 -1 sc (2) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1725 2550 m -gs 1 -1 sc (13) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2850 2550 m -gs 1 -1 sc (31) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2625 2550 m -gs 1 -1 sc (28) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2400 2550 m -gs 1 -1 sc (24) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -2175 2550 m -gs 1 -1 sc (20) col-1 show gr -/Times-Roman findfont 150.00 scalefont setfont -1950 2550 m -gs 1 -1 sc (16) col-1 show gr -$F2psEnd -restore -%%EndDocument - @endspecial 920 3971 a Fy(Figure)f(10)p FL(:)25 b Fx(An)20 -b(e)n(xample)e(of)g(the)h(CSR)h(f)n(or)r(mat)d(f)n(or)i(stor)q(ing)f -(sparse)g(g)o(r)o(aphs)o(.)100 4164 y FL(The)h(weights)h(of)g(the)g(v)o -(ertices)g(\(if)g(an)o(y\))f(are)h(stored)f(in)h(an)g(additional)f -(array)g(called)h Fp(vwgt)p FL(.)25 b(If)20 b Fs(ncon)f -FL(is)i(the)f(number)e(of)i(weights)0 4274 y(associated)h(with)h(each)f -(v)o(erte)o(x,)f(the)i(array)f Fp(vwgt)g FL(contains)g -Ft(n)h FM(\003)e Fs(ncon)h FL(elements)g(\(recall)g(that)g -Ft(n)26 b FL(is)c(the)g(number)e(of)h(v)o(ertices\).)28 -b(The)0 4383 y(weights)e(of)h(the)e Ft(i)9 b FL(th)26 -b(v)o(erte)o(x)g(are)g(stored)g(in)h Fs(ncon)e FL(consecuti)n(v)o(e)g -(entries)h(starting)h(at)g(location)e Fp(vwgt[)o Ft(i)31 -b FM(\003)23 b Fd(ncon)p Fp(])p FL(.)44 b(Note)27 b(that)f(if)0 -4493 y(each)d(v)o(erte)o(x)g(has)h(only)f(a)h(single)f(weight,)h(then)g -Fp(vwgt)f FL(will)i(contain)d Ft(n)28 b FL(elements,)c(and)f -Fp(vwgt[)o Ft(i)9 b Fp(])23 b FL(will)h(store)g(the)g(weight)f(of)h -(the)-1 4603 y Ft(i)9 b FL(th)21 b(v)o(erte)o(x.)26 b(The)21 -b(v)o(erte)o(x-weights)d(must)j(be)g(inte)o(gers)f(greater)h(or)f -(equal)h(to)g(zero.)27 b(If)21 b(all)h(the)f(v)o(ertices)f(of)h(the)g -(graph)f(ha)n(v)o(e)g(the)h(same)0 4712 y(weight)f(\()p -Fs(i.e)o FL(.,)g(the)h(graph)d(is)j(unweighted\),)d(then)i(the)g -Fp(vwgt)g FL(can)g(be)g(set)h(to)f(NULL.)100 4822 y(The)c(weights)h(of) -g(the)h(edges)e(\(if)h(an)o(y\))f(are)i(stored)e(in)h(an)h(additional)d -(array)i(called)g Fp(adjwgt)p FL(.)23 b(This)17 b(array)g(contains)f(2) -p Ft(m)22 b FL(elements,)0 4931 y(and)j(the)g(weight)g(of)g(edge)g -Fp(adjncy[)14 b Ft(j)9 b Fp(])23 b FL(is)j(stored)f(at)h(location)e -Fp(adjwgt[)14 b Ft(j)9 b Fp(])p FL(.)39 b(The)25 b(edge-weights)e(must) -j(be)f(inte)o(gers)g(greater)0 5041 y(than)c(zero.)27 -b(If)21 b(all)h(the)f(edges)f(of)h(the)g(graph)f(ha)n(v)o(e)h(the)g -(same)g(weight)g(\()p Fs(i.e)o FL(.,)h(the)f(graph)f(is)i -(unweighted\),)c(then)j(the)g Fp(adjwgt)g FL(can)g(be)0 -5150 y(set)g(to)f(NULL.)100 5260 y(All)26 b(of)f(these)h(four)e(arrays) -h(\()p Fs(xadj)p FL(,)g Fs(adjncy)p FL(,)h Fs(vwgt)p -FL(,)h(and)e Fs(adjwgt)p FL(\))f(are)i(de\002ned)e(in)k -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)29 b FL(to)c(be)h(of)f(of)g -(type)g Fp(idxtype)p FL(.)40 b(By)0 5370 y(def)o(ault)27 -b Fp(idxtype)g FL(is)h(set)h(to)e(be)h(equi)n(v)n(alent)e(to)i(type)f -Fp(int)g FL(\()p Fs(i.e)p FL(.,)i(the)f(inte)o(ger)e(datatype)h(of)g -(C\).)h(Ho)n(we)n(v)o(er)m(,)f Fp(idxtype)g FL(can)h(be)1908 -5649 y(18)p eop -%%Page: 19 19 -19 18 bop 0 83 a FL(made)18 b(to)h(be)f(equi)n(v)n(alent)f(to)i(a)g -Fp(short)49 b(int)19 b FL(for)f(certain)g(architectures)f(that)i(use)g -(64-bit)f(inte)o(gers)g(by)g(def)o(ault.)24 b(The)18 -b(con)m(v)o(ersion)e(of)0 193 y Fp(idxtype)j FL(from)f -Fp(int)i FL(to)f Fp(short)g FL(can)h(be)f(done)g(by)g(modifying)e(the)i -(\002le)h Fp(Lib/struct.h)e FL(\(instructions)g(are)i(included)e -(there\).)0 302 y(The)i(same)g Fp(idxtype)g FL(is)h(used)f(for)f(the)h -(arrays)g(that)g(are)g(used)g(to)h(store)f(the)g(computed)e(partition)h -(and)h(permutation)e(v)o(ector)-5 b(.)0 530 y Fr(5.2)100 -b(Mesh)28 b(Data)h(Structure)0 689 y FL(All)21 b(of)e(the)h(mesh)g -(partitioning)e(and)h(mesh)h(con)m(v)o(ersion)d(routines)i(in)k -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)23 b FL(tak)o(e)d(as)g -(input)g(the)g(element)f(node)g(array)g(of)h(a)g(mesh.)0 -799 y(This)e(element)f(node)g(array)g(is)i(stored)e(using)h(an)f(array) -g(called)h Fp(elmnts)p FL(.)24 b(F)o(or)17 b(a)h(mesh)g(with)g -Ft(n)k FL(elements)17 b(and)h Ft(k)23 b FL(nodes)17 b(per)g(element,)0 -908 y(the)k(size)i(of)e(the)g Fp(elmnts)g FL(array)g(is)h -Ft(n)h FM(\003)c Ft(k)5 b FL(.)29 b(Note)22 b(that)f(since)h(the)f -(supported)f(elements)h(in)j Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)25 b FL(are)d(only)e(triangles,)h(tetrahedra,)0 -1018 y(he)o(xahedra,)c(and)j(quadrilaterals,)e(the)j(possible)f(v)n -(alues)f(for)h Ft(k)25 b FL(are)c(3,)f(4,)g(8,)g(and)f(4,)h(respecti)n -(v)o(ely)-5 b(.)100 1127 y(The)21 b(element)g(node)g(array)g(of)h(the)f -(mesh)h(is)h(stored)e(in)h Fp(elmnts)f FL(as)i(follo)n(ws.)29 -b(Assuming)22 b(that)g(the)f(element)h(numbering)d(starts)0 -1237 y(from)e(0)i(\(C)f(style\),)h(then)f(the)g Ft(k)24 -b FL(nodes)17 b(that)i(mak)o(e)f(up)f(element)g Ft(i)28 -b FL(are)18 b(stored)g(in)g(array)f Fp(elmnts)h FL(starting)g(at)h -(inde)o(x)d Ft(i)k FM(\003)11 b Ft(k)24 b FL(and)18 b(ending)0 -1347 y(\(b)n(ut)23 b(not)h(including\))d(inde)o(x)i Fu(.)o -Ft(i)29 b FM(C)21 b FL(1)p Fu(/)f FM(\003)i Ft(k)5 b -FL(.)36 b(As)24 b(it)g(w)o(as)h(the)f(case)g(with)g(the)f(format)g(of)g -(the)h(mesh)f(\002le)i(described)d(in)i(Section)f(4.5.2,)0 -1456 y(the)d(ordering)e(of)h(the)h(nodes)f(is)i(not)f(important)e(for)h -(triangle)g(and)h(tetrahedra)e(elements.)25 b(Ho)n(we)n(v)o(er)m(,)17 -b(in)k(the)e(case)i(of)e(he)o(xahedra,)f(the)0 1566 y(nodes)h(for)h -(each)g(element)f(must)i(be)f(ordered)e(according)g(to)j(the)f -(numbering)d(illustrated)j(in)g(Figure)g(9\(b\).)100 -1675 y(The)h(array)g(that)h(describes)f(the)g(element)h(node)e(array)h -(of)g(the)h(mesh)g(is)g(de\002ned)f(in)j Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)r(lib)25 b FL(to)d(be)f(of)h(type)f -Fp(idxtype)p FL(,)g(which)0 1785 y(by)f(def)o(ault)f(is)i(equi)n(v)n -(alent)e(to)h Fp(int)g FL(\()p Fs(i.e)p FL(.,)g(inte)o(gers\).)0 -2012 y Fr(5.3)100 b(P)m(ar)r(titioning)27 b(Objectives)0 -2172 y FL(The)d(partitioning)e(algorithms)h(in)j Fz(M)l -FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)27 b FL(can)d(be)g(used)g(to)g -(compute)e(a)j(balanced)e Ft(k)5 b FL(-w)o(ay)23 b(partitioning)f(that) -i(minimizes)g(either)0 2281 y(the)g(number)d(of)j(edges)f(that)g -(straddle)g(partitions)g(\()p Fs(edg)o(ecut)p FL(\))f(or)h(the)h(total) -g(communication)c(v)n(olume)j(\()p Fs(totalv)p FL(\).)34 -b(In)23 b(the)h(rest)g(of)f(this)0 2391 y(section)d(we)h(brie\003y)e -(describe)g(these)i(tw)o(o)f(objecti)n(v)o(es)f(and)h(pro)o(vide)e -(some)i(suggestions)f(on)h(when)g(the)o(y)f(should)g(be)h(used.)0 -2600 y FB(Minimizing)j(the)h(Edg)q(e-Cut)99 b FL(Consider)20 -b(a)i(graph)g Ft(G)30 b FM(D)25 b Fu(.)r Ft(V)8 b Fu(;)20 -b Ft(E)7 b Fu(/)p FL(,)22 b(and)f(let)29 b Ft(P)f FL(be)21 -b(a)h(v)o(ector)e(of)h(size)h FM(j)r Ft(V)13 b FM(j)21 -b FL(such)g(that)29 b Ft(P)6 b FM(T)o Ft(i)j FM(U)21 -b FL(stores)0 2710 y(the)f(number)f(of)h(the)g(partition)g(that)g(v)o -(erte)o(x)e Ft(i)29 b FL(belongs)19 b(to.)26 b(The)20 -b Fs(edg)o(ecut)f FL(of)h(this)h(partitioning)d(is)k(de\002ned)d(as)i -(the)f(number)f(of)h(edges)0 2819 y(that)d(straddle)f(partitions.)23 -b(That)16 b(is,)i(the)e(number)f(of)i(edges)f Fu(.v)s(;)e -Ft(u)t Fu(/)k FL(for)e(which)23 b Ft(P)6 b FM(T)p Fu(v)s -FM(U)24 b(6)r(D)30 b Ft(P)6 b FM(T)p Ft(u)t FM(U)p FL(.)24 -b(If)17 b(the)f(graph)g(has)g(weights)h(associated)0 -2929 y(with)j(the)h(edges,)e(then)h(the)g(edgecut)f(is)i(de\002ned)e -(as)i(the)f(sum)h(of)e(the)i(weight)e(of)h(these)h(straddling)e(edges.) -0 3138 y FB(Minimizing)26 b(the)h(T)-7 b(otal)28 b(Comm)n(unication)e -(V)-7 b(olume)99 b FL(Consider)23 b(a)i(graph)f Ft(G)36 -b FM(D)30 b Fu(.)r Ft(V)8 b Fu(;)20 b Ft(E)7 b Fu(/)p -FL(,)26 b(and)d(let)32 b Ft(P)f FL(be)25 b(a)f(v)o(ector)f(of)h(size)0 -3248 y FM(j)r Ft(V)12 b FM(j)20 b FL(such)f(that)26 b -Ft(P)6 b FM(T)o Ft(i)j FM(U)19 b FL(stores)g(the)g(number)f(of)g(the)h -(partition)f(that)i(v)o(erte)o(x)c Ft(i)28 b FL(belongs)18 -b(to.)25 b(Let)c Ft(V)2726 3260 y Ff(b)2786 3248 y FM(\032)k -Ft(V)32 b FL(be)19 b(the)g(subset)g(of)g(interf)o(ace)f(\(or)0 -3357 y(boarder\))i(v)o(ertices.)32 b(That)23 b(is,)h(each)e(v)o(erte)o -(x)g Fu(v)31 b FM(2)f Ft(V)1497 3369 y Ff(b)1557 3357 -y FL(is)24 b(connected)d(to)h(at)i(least)f(one)f(v)o(erte)o(x)f(that)i -(belongs)f(to)h(a)g(dif)n(ferent)e(partition.)0 3467 -y(F)o(or)h(each)g(v)o(erte)o(x)e Fu(v)31 b FM(2)e Ft(V)740 -3479 y Ff(b)799 3467 y FL(let)g Ft(N)8 b(a)t(d)k(j)d -FM(T)p Fu(v)s FM(U)22 b FL(be)g(the)g(number)e(of)i(domains)f(other)h -(than)28 b Ft(P)6 b FM(T)p Fu(v)s FM(U)24 b FL(that)e(the)g(v)o -(ertices)g(adjacent)f(to)i Fu(v)j FL(belong)0 3577 y(to.)f(The)20 -b Fs(totalv)g FL(of)g(this)g(partitioning)f(is)i(de\002ned)e(as:)1561 -3778 y Fs(totalv)j FM(D)1873 3699 y Fc(X)1861 3872 y -Fg(v)s Fe(2)r Ff(V)1974 3882 y Fa(b)2023 3778 y Ft(N)8 -b(a)t(d)k(j)d FM(T)p Fu(v)s FM(U)p Fu(:)1463 b FL(\(1\))0 -4048 y(Equation)19 b(1)i(corresponds)e(to)i(the)g(total)g -(communication)d(v)n(olume)i(incurred)f(by)h(the)h(partitioning)e -(because)h(each)h(interf)o(ace)f(v)o(erte)o(x)0 4158 -y Fu(v)25 b FL(needs)19 b(to)i(be)f(sent)g(to)h(all)f(of)g(its)28 -b Ft(N)8 b(a)t(d)k(j)d FM(T)p Fu(v)s FM(U)19 b FL(partitions.)100 -4267 y(The)k(abo)o(v)o(e)e(model)i(can)g(be)g(e)o(xtended)e(to)j -(instances)f(in)h(which)e(the)i(amount)e(of)h(data)g(that)g(needs)g(to) -h(be)f(sent)h(for)e(each)h(node)g(is)0 4377 y(dif)n(ferent.)g(In)c -(particular)m(,)f(if)i Fu(w)907 4389 y Fg(v)964 4377 -y FL(is)h(the)e(amount)f(of)h(data)h(that)f(needs)g(to)h(be)f(sent)h -(for)f(v)o(erte)o(x)f Fu(v)s FL(,)j(then)e(Equation)e(1)j(can)f(be)h -(re-written)0 4487 y(as:)1512 4596 y Fs(totalv)i FM(D)1824 -4517 y Fc(X)1812 4691 y Fg(v)s Fe(2)r Ff(V)1925 4701 -y Fa(b)1967 4596 y Fu(w)2028 4608 y Fg(v)2072 4596 y -Ft(N)8 b(a)t(d)k(j)d FM(T)p Fu(v)s FM(U)p Fu(:)1414 b -FL(\(2\))2 4835 y Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)24 -b FL(supports)19 b(this)j(weighted)d(totalv)h(model)g(by)g(using)h(an)f -(array)g(called)g Fp(vsize)g FL(such)h(that)g(the)f(amount)f(of)i(data) -f(that)h(needs)0 4944 y(to)h(be)f(sent)h(due)f(to)h(the)f -Ft(i)9 b FL(th)21 b(v)o(erte)o(x)f(is)j(stored)e(in)h -Fp(vsize[)o Ft(i)9 b Fp(])p FL(.)28 b(Note)22 b(that)f(the)h(amount)e -(of)i(data)f(that)h(needs)f(to)h(be)g(sent)g(is)g(dif)n(ferent)0 -5054 y(from)j(the)g Fs(weight)h FL(of)f(the)h(v)o(erte)o(x.)39 -b(The)25 b(former)g(corresponds)e(to)j(communication)c(cost)k(whereas)f -(the)h(later)g(corresponds)d(to)j(the)0 5164 y(computational)18 -b(cost.)100 5273 y(Note)j(that)h(for)f(partitioning)e(algorithms)h(to)i -(correctly)e(minimize)h(the)h(totalv)-5 b(,)20 b(the)i(graph)e(should)h -(re\003ect)g(the)h(true)f(information)0 5383 y(e)o(xchange)c -(requirements)g(of)i(the)g(underlying)e(computations.)23 -b(F)o(or)18 b(instance,)h(the)h(dual)e(graph)g(of)h(a)h(\002nite)f -(element)g(mesh)g(does)g(not)1908 5649 y(19)p eop -%%Page: 20 20 -20 19 bop 0 83 a FL(correctly)19 b(model)g(the)h(underlying)e -(communication,)f(whereas)j(the)g(nodal)f(graph)g(does.)0 -292 y FB(Whic)o(h)h(one)e(is)i(Better?)99 b FL(When)17 -b(partitioning)d(is)k(used)f(to)g(distrib)n(ute)f(a)h(graph)e(or)i(a)g -(mesh)g(among)e(the)i(processors)e(of)i(a)g(parallel)0 -402 y(computer)m(,)24 b(the)i(edgecut)e(is)i(only)e(an)i(approximation) -c(of)j(the)g(true)g(communication)e(cost)i(resulting)g(from)f(the)h -(partitioning.)39 b(On)0 511 y(the)25 b(other)e(hand,)i(by)f -(minimizing)f(the)h(totalv)g(we)h(can)g(directly)e(minimize)h(the)h(o)o -(v)o(erall)e(communication)e(cost.)39 b(Despite)24 b(of)h(that,)0 -621 y(for)i(man)o(y)f(graphs)h(the)g(solutions)g(obtained)f(by)h -(minimizing)f(the)i(edgecut)e(or)h(minimizing)f(the)i(totalv)-5 -b(,)28 b(are)g(comparable.)44 b(This)0 731 y(is)27 b(especially)g(true) -f(for)g(graphs)f(corresponding)e(to)k(well-shaped)e(\002nite)i(element) -f(meshes.)43 b(This)27 b(is)h(because)d(for)h(these)h(graphs,)0 -840 y(the)e(de)o(grees)f(of)g(the)h(v)n(arious)f(v)o(ertices)h(are)g -(similar)g(and)f(the)h(objecti)n(v)o(es)f(of)h(minimizing)e(the)i -(edgecut)f(or)g(the)h(totalv)g(beha)n(v)o(e)f(the)0 950 -y(same.)38 b(On)25 b(the)g(other)e(hand,)i(if)g(the)f(v)o(erte)o(x)f -(de)o(grees)h(v)n(ary)f(signi\002cantly)h(\()p Fs(e)o(.g)o -FL(.,)h(graphs)f(corresponding)d(to)k(linear)f(programming)0 -1059 y(matrices\),)19 b(then)h(by)g(minimizing)f(the)h(totalv)g(we)g -(can)g(obtain)g(a)g(signi\002cant)g(reduction)e(in)j(the)f(total)g -(communication)d(v)n(olume.)100 1169 y(In)j(terms)i(of)e(the)i(amount)d -(of)i(time)g(required)f(by)g(these)i(tw)o(o)f(partitioning)e(objecti)n -(v)o(es,)h(minimizing)g(the)h(edgecut)f(is)i(f)o(aster)f(than)0 -1279 y(minimizing)28 b(the)h(totalv)-5 b(.)52 b(F)o(or)29 -b(this)h(reason,)h(the)f(totalv)f(objecti)n(v)o(e)f(should)g(be)i(used) -f(only)g(for)f(problems)g(in)i(which)f(it)h(actually)0 -1388 y(reduces)19 b(the)i(o)o(v)o(erall)d(communication)g(v)n(olume.) -1908 5649 y(20)p eop -%%Page: 21 21 -21 20 bop 0 83 a Fr(5.4)100 b(Graph)27 b(P)m(ar)r(titioning)g(Routines) -0 240 y FB(METIS)p 258 240 25 4 v 31 w(P)n(ar)r(tGraphRecur)o(sive)20 -b FL(\(int)g(*n,)g(idxtype)f(*xadj,)g(idxtype)f(*adjnc)o(y)-5 -b(,)18 b(idxtype)h(*vwgt,)g(idxtype)g(*adjwgt,)g(int)h(*wgt\003ag,)1105 -350 y(int)h(*num\003ag,)d(int)i(*nparts,)f(int)h(*options,)f(int)h -(*edgecut,)f(idxtype)f(*part\))0 587 y FB(Description)208 -697 y FL(It)23 b(is)i(used)e(to)h(partition)f(a)h(graph)e(into)h -Ft(k)29 b FL(equal-size)23 b(parts)g(using)g(multile)n(v)o(el)g -(recursi)n(v)o(e)f(bisection.)35 b(It)23 b(pro)o(vides)f(the)i(func-) -208 806 y(tionality)c(of)i(the)f Fp(pmetis)g FL(program.)27 -b(The)21 b(objecti)n(v)o(e)f(of)i(the)f(partitioning)f(is)i(to)g -(minimize)e(the)i(edgecut)e(\(as)i(described)e(in)208 -916 y(Section)f(5.3\).)0 1087 y FB(P)n(arameter)o(s)208 -1202 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h -(graph.)208 1314 y FC(xadj,)e(adjncy)581 1423 y FL(The)h(adjacenc)o(y)e -(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.) -208 1535 y FC(vwgt,)f(adjwgt)581 1645 y FL(Information)f(about)h(the)h -(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h -(Section)g(5.1.)208 1783 y FC(wgt\003ag)113 b FL(Used)21 -b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 1921 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h -(are)g(NULL\))581 2045 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g -(only)g(\(vwgts)f(=)i(NULL\))581 2168 y(2)83 b(W)-7 b(eights)21 -b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581 -2292 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h -(edges.)208 2430 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g -(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f -(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 -2540 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:) -581 2678 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g -(starts)h(from)e(0)581 2802 y(1)83 b(F)o(ortran-style)18 -b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208 -2940 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h -(partition)e(the)h(graph.)208 3078 y FC(options)114 b -FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i(used) -e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g(the)g -(algorithm.)581 3187 y(If)j Fs(options[0]=0)e FL(then)h(def)o(ault)g(v) -n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p -FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581 -3297 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -3435 y(options[1])108 b(Determines)20 b(matching)e(type.)25 -b(Possible)20 b(v)n(alues)g(are:)1033 3559 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 3683 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 3806 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 3930 y(Experiments)f(has)h -(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.) -581 4054 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g -(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 -4178 y(1)83 b(Re)o(gion)19 b(Gro)n(wing)g(\(Def)o(ault\))581 -4302 y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h -(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 4425 -y(1)83 b(Early-Exit)18 b(Boundary)h(FM)h(re\002nement)f(\(Def)o(ault\)) -581 4549 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 -b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208 -4687 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j -(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h -(by)e(the)i(partition.)208 4825 y FC(part)220 b FL(This)18 -b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h -(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.) -23 b(The)581 4935 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i -(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)0 5106 y FB(Note)208 5216 y FL(This)d(function)f -(should)h(be)g(used)g(to)h(partition)f(a)g(graph)g(into)g(a)h(small)g -(number)e(of)h(partitions)g(\(less)h(than)f(8\).)23 b(If)17 -b(a)g(lar)o(ge)e(number)208 5325 y(of)k(partitions)h(is)h(desired,)e -(the)h Fz(METIS)p 1369 5325 V 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g -FL(should)f(be)i(used)e(instead,)h(as)h(it)g(is)g(signi\002cantly)e(f)o -(aster)-5 b(.)1908 5649 y(21)p eop -%%Page: 22 22 -22 21 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(P)n(ar)r(tGraphKwa)n(y) -20 b FL(\(int)g(*n,)f(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5 -b(,)18 b(idxtype)g(*vwgt,)i(idxtype)e(*adjwgt,)h(int)i(*wgt\003ag,)925 -193 y(int)f(*num\003ag,)e(int)j(*nparts,)e(int)h(*options,)f(int)h -(*edgecut,)e(idxtype)h(*part\))0 380 y FB(Description)208 -490 y FL(It)32 b(is)i(used)e(to)g(partition)g(a)g(graph)f(into)i -Ft(k)k FL(equal-size)32 b(parts)g(using)g(the)h(multile)n(v)o(el)e -Ft(k)5 b FL(-w)o(ay)32 b(partitioning)e(algorithm.)60 -b(It)208 600 y(pro)o(vides)17 b(the)j(functionality)e(of)h(the)h -Fp(kmetis)f FL(program.)j(The)e(objecti)n(v)o(e)e(of)h(the)h -(partitioning)e(is)i(to)g(minimize)f(the)h(edgecut)208 -709 y(\(as)g(described)f(in)h(Section)g(5.3\).)0 869 -y FB(P)n(arameter)o(s)208 973 y FC(n)327 b FL(The)20 -b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1074 -y FC(xadj,)e(adjncy)581 1183 y FL(The)h(adjacenc)o(y)e(structure)i(of)g -(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208 -1284 y FC(vwgt,)f(adjwgt)581 1394 y FL(Information)f(about)h(the)h -(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h -(Section)g(5.1.)208 1521 y FC(wgt\003ag)113 b FL(Used)21 -b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 1648 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h -(are)g(NULL\))581 1766 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g -(only)g(\(vwgts)f(=)i(NULL\))581 1884 y(2)83 b(W)-7 b(eights)21 -b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581 -2003 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h -(edges.)208 2129 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g -(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f -(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 -2239 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:) -581 2366 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g -(starts)h(from)e(0)581 2484 y(1)83 b(F)o(ortran-style)18 -b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208 -2611 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h -(partition)e(the)h(graph.)208 2738 y FC(options)114 b -FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i(used) -e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g(the)g -(algorithm.)581 2848 y(If)j Fs(options[0]=0)e FL(then)h(def)o(ault)g(v) -n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p -FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581 -2957 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -3084 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24 -b(Possible)d(v)n(alues)e(are:)1033 3203 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 3321 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 3439 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 3557 y(Experiments)f(has)h -(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.) -581 3676 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g -(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 -3794 y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g -(\(Def)o(ault\))581 3912 y(options[3])108 b(Determines)20 -b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g -(are:)1033 4030 y(1)83 b(Random)19 b(boundary)e(re\002nement)1033 -4149 y(2)83 b(Greedy)19 b(boundary)e(re\002nement)1033 -4267 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h -(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158 -4377 y(domains)f(\(Def)o(ault\))581 4495 y(options[4])108 -b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g -(it)g(to)f(0)h(\(Def)o(ault\).)208 4622 y FC(edgecut)100 -b FL(Upon)19 b(successful)h(completion,)e(this)j(v)n(ariable)e(stores)i -(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h(by)e(the)i(partition.) -208 4749 y FC(part)220 b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i(size)g -Fs(n)g FL(that)g(upon)e(successful)h(completion)f(stores)i(the)g -(partition)f(v)o(ector)f(of)h(the)h(graph.)23 b(The)581 -4858 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h -(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)0 5019 y FB(Note)208 5128 y FL(This)24 -b(function)f(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h -(a)h(lar)o(ge)f(number)e(of)j(partitions)e(\(greater)g(than)h(8\).)38 -b(If)24 b(a)h(small)208 5238 y(number)17 b(of)i(partitions)g(is)h -(desired,)f(the)g Fz(METIS)p 1639 5238 V 31 w(P)m(ar)s(tGr)o -(aphRecursiv)n(e)g FL(should)g(be)g(used)g(instead,)g(as)h(it)g -(produces)e(some-)208 5347 y(what)i(better)f(partitions.)1908 -5649 y(22)p eop -%%Page: 23 23 -23 22 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(P)n(ar)r(tGraphVKwa)n(y) -20 b FL(\(int)g(*n,)g(idxtype)e(*xadj,)h(idxtype)g(*adjnc)o(y)-5 -b(,)18 b(idxtype)h(*vwgt,)g(idxtype)g(*vsize,)g(int)i(*wgt\003ag,)980 -193 y(int)f(*num\003ag,)f(int)h(*nparts,)f(int)h(*options,)f(int)h(*v)n -(olume,)f(idxtype)g(*part\))0 452 y FB(Description)208 -561 y FL(It)28 b(is)h(used)f(to)h(partition)e(a)i(graph)e(into)h -Ft(k)33 b FL(equal-size)28 b(parts)g(using)g(the)g(multile)n(v)o(el)f -Ft(k)5 b FL(-w)o(ay)28 b(partitioning)e(algorithm.)48 -b(The)208 671 y(objecti)n(v)o(e)18 b(of)i(the)g(partitioning)f(is)i(to) -f(minimize)g(the)g(total)g(communication)d(v)n(olume)j(\(as)g -(described)f(in)h(Section)g(5.3\).)0 847 y FB(P)n(arameter)o(s)208 -966 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h -(graph.)208 1083 y FC(xadj,)e(adjncy)581 1193 y FL(The)h(adjacenc)o(y)e -(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Sections)f(5.1)f -(and)h(5.3.)208 1309 y FC(vwgt,)f(vsize)581 1419 y FL(Information)h -(about)j(the)g(weights)g(of)g(the)g(v)o(ertices)f(related)h(to)g(the)g -(computation)e(and)i(communication)d(as)k(de-)581 1529 -y(scribed)c(in)g(Section)g(5.1.)208 1671 y FC(wgt\003ag)113 -b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 1814 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(vsize)i -(are)f(NULL\))581 1940 y(1)83 b(Communication)18 b(weights)i(only)f -(\(vwgts)h(=)g(NULL\))581 2067 y(2)83 b(Computation)18 -b(weights)i(only)f(\(vsize)h(=)h(NULL\))581 2193 y(3)83 -b(Both)20 b(communication)d(and)j(computation)e(weights.)208 -2335 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2445 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -2588 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 2714 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 2857 y FC(nparts)142 -b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208 -3000 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o -(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n -(arious)f(phases)h(of)g(the)g(algorithm.)581 3109 y(If)j -Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 -b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h -(elements)g(of)581 3219 y Fs(options)c FL(are)i(interpreted)d(as)j -(follo)n(ws:)581 3362 y(options[1])108 b(Determines)20 -b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033 -3488 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 3614 -y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 3740 -y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o -(ault\))1033 3866 y(Experiments)f(has)h(sho)n(wn)g(that)g(both)f(HEM)h -(and)g(SHEM)g(perform)f(quite)g(well.)581 3993 y(options[2])108 -b(Determines)20 b(the)g(algorithm)f(used)g(during)g(initial)i -(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 4119 -y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g(\(Def)o -(ault\))581 4245 y(options[3])108 b(Determines)20 b(the)g(algorithm)f -(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 -4371 y(1)83 b(Random)19 b(boundary)e(re\002nement)i(\(Def)o(ault\))1033 -4497 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h -(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158 -4607 y(domains)581 4733 y(options[4])108 b(Used)21 b(for)e(deb)n -(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o -(ault\).)208 4876 y FC(v)o(olume)115 b FL(Upon)28 b(successful)h -(completion,)g(this)g(v)n(ariable)f(stores)h(the)g(total)g -(communication)d(v)n(olume)h(requires)h(by)h(the)581 -4986 y(partition.)208 5128 y FC(part)220 b FL(This)18 -b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h -(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.) -23 b(The)581 5238 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i -(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)1908 5649 y(23)p eop -%%Page: 24 24 -24 23 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(mCP)n(ar)r(tGraphRecur)o -(sive)20 b FL(\(int)g(*n,)f(int)i(*ncon,)d(idxtype)h(*xadj,)g(idxtype)g -(*adjnc)o(y)-5 b(,)18 b(idxtype)g(*vwgt,)i(idxtype)e(*adjwgt,)1239 -193 y(int)i(*wgt\003ag,)f(int)i(*num\003ag,)d(int)i(*nparts,)f(int)i -(*options,)d(int)j(*edgecut,)d(idxtype)h(*part\))0 447 -y FB(Description)208 557 y FL(It)g(is)h(used)f(to)h(partition)e(a)h -(graph)f(into)h Ft(k)25 b FL(parts)19 b(such)g(that)g(multiple)g -(balancing)e(constraints)i(are)g(satis\002ed.)25 b(It)20 -b(uses)g(the)f(multi-)208 666 y(constraint)h(multile)n(v)o(el)h -(recursi)n(v)o(e)f(bisection)h(algorithm.)27 b(It)22 -b(pro)o(vides)e(the)h(functionality)f(of)h(the)h Fp(pmetis)f -FL(program)e(when)208 776 y(it)g(is)g(used)g(to)f(compute)f(a)i -(multi-constraint)e(partitioning.)22 b(The)d(objecti)n(v)o(e)e(of)h -(the)h(partitioning)d(is)k(to)e(minimize)g(the)h(edgecut)208 -885 y(\(as)h(described)f(in)h(Section)g(5.3\).)0 1060 -y FB(P)n(arameter)o(s)208 1179 y FC(n)327 b FL(The)20 -b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1321 -y FC(ncon)202 b FL(The)20 b(number)e(of)i(constraints.)25 -b(This)20 b(should)f(be)h(greater)f(than)h(one)g(and)f(smaller)i(than)e -(15.)208 1436 y FC(xadj,)g(adjncy)581 1546 y FL(The)h(adjacenc)o(y)e -(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.) -208 1662 y FC(vwgt,)f(adjwgt)581 1771 y FL(Information)k(about)h(the)h -(weights)g(of)g(the)h(v)o(ertices)e(and)h(edges)g(as)h(described)e(in)h -(Section)g(5.1.)40 b(Note)25 b(that)h(the)581 1881 y(weight)20 -b(v)o(ector)f(must)h(be)g(supplied)f(and)h(it)h(should)e(be)h(of)g -(size)h Fz(n*ncon)p FL(.)208 2023 y FC(wgt\003ag)113 -b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 2164 y(0)83 b(No)20 b(weights)g(\(adjwgt)f(is)i(NULL\))581 -2290 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges.)208 -2432 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2541 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -2683 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 2809 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 2951 y FC(nparts)142 -b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208 -3092 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o -(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n -(arious)f(phases)h(of)g(the)g(algorithm.)581 3202 y(If)j -Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 -b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h -(elements)g(of)581 3312 y Fs(options)c FL(are)i(interpreted)d(as)j -(follo)n(ws:)581 3453 y(options[1])108 b(Determines)20 -b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033 -3579 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 3705 -y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 3830 -y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o -(ault\))1033 3956 y(5)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h -(follo)n(wed)g(by)h(1-norm)e(Balanced-edge)g(\(SHEBM1N\))1033 -4082 y(6)83 b(Sorted)28 b(Hea)n(vy-Edge)f(Matching)h(follo)n(wed)g(by)h -FM(1)p FL(-norm)e(Balanced-edge)g(\(SHEBMIN\))1158 4191 -y(\(Def)o(ault\))1033 4317 y(7)83 b(1-norm)18 b(Balanced-edge)g(follo)n -(wed)h(by)h(Hea)n(vy-Edge)e(Matching)h(\(SBHEM1N\))1033 -4443 y(8)83 b FM(1)p FL(-norm)18 b(Balanced-edge)g(follo)n(wed)h(by)h -(Hea)n(vy-Edge)e(Matching)h(\(SBHEMIN\))1033 4568 y(Experiments)g(has)j -(sho)n(wn)e(that)h(for)g(simple)g(balancing)e(problems,)h(the)h -(schemes)g(that)g(gi)n(v)o(e)f(pri-)1033 4678 y(ority)15 -b(to)h(hea)n(vy)e(edges)h(\()p Fs(e)o(.g)o FL(.,)h(SHEM,)g(SHEBM1N,)f -(SHEBMIN\))g(perform)e(better)m(,)j(and)f(for)f(hard)1033 -4788 y(balancing)i(problems,)f(the)i(schemes)g(that)g(gi)n(v)o(e)g -(priority)e(to)i(balanced)f(edges)h(\()p Fs(e)o(.g)n -FL(.,)h(SBHEM1N,)1033 4897 y(SBHEMIN\))i(perform)e(better)-5 -b(.)581 5023 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used) -g(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 -5149 y(1)83 b(Multi-constraint)18 b(Greedy)h(Graph)g(Gro)n(wing)1033 -5274 y(2)83 b(Random)19 b(\(Def)o(ault\))581 5400 y(options[3])108 -b(Determines)20 b(the)g(algorithm)f(used)g(for)h(re\002nement.)k -(Possible)c(v)n(alues)g(are:)1908 5649 y(24)p eop -%%Page: 25 25 -25 24 bop 1033 83 a FL(1)83 b(Early-Exit)18 b(Boundary)h(FM)h -(re\002nement)f(\(Def)o(ault\))581 209 y(options[4])108 -b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g -(it)g(to)f(0)h(\(Def)o(ault\).)208 352 y FC(edgecut)100 -b FL(Upon)19 b(successful)h(completion,)e(this)j(v)n(ariable)e(stores)i -(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h(by)e(the)i(partition.) -208 495 y FC(part)220 b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i(size)g -Fs(n)g FL(that)g(upon)e(successful)h(completion)f(stores)i(the)g -(partition)f(v)o(ector)f(of)h(the)h(graph.)23 b(The)581 -604 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h -(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)0 780 y FB(Note)208 890 y FL(This)d(function)f -(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h(a)h(small)g -(number)e(of)h(partitions.)23 b(If)16 b(a)h(lar)o(ge)e(number)g(of)h -(partitions)208 1000 y(is)24 b(desired,)g(the)g Fz(METIS)p -957 1000 25 4 v 31 w(mCP)m(ar)s(tGr)o(aphKw)o(a)n(y)g -FL(should)f(be)h(used)g(instead,)g(as)h(it)f(produces)f(some)n(what)g -(better)g(partitions)208 1109 y(\(both)c(in)h(terms)g(of)g(quality)f -(and)h(balance\).)1908 5649 y(25)p eop -%%Page: 26 26 -26 25 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(mCP)n(ar)r(tGraphKwa)n -(y)19 b FL(\(int)i(*n,)e(int)h(*ncon,)f(idxtype)g(*xadj,)g(idxtype)g -(*adjnc)o(y)-5 b(,)17 b(idxtype)i(*vwgt,)g(idxtype)g(*adjwgt,)1058 -193 y(int)i(*wgt\003ag,)e(int)h(*num\003ag,)f(int)h(*nparts,)f(\003oat) -h(*ub)o(v)o(ec,)e(int)i(*options,)f(int)h(*edgecut,)1058 -302 y(idxtype)f(*part\))0 560 y FB(Description)208 669 -y FL(It)g(is)h(used)f(to)h(partition)e(a)h(graph)f(into)h -Ft(k)25 b FL(parts)19 b(such)g(that)g(multiple)g(balancing)e -(constraints)i(are)g(satis\002ed.)25 b(It)20 b(uses)g(the)f(multi-)208 -779 y(constraint)i(multile)n(v)o(el)g Ft(k)5 b FL(-w)o(ay)21 -b(partitioning)f(algorithm.)29 b(It)22 b(pro)o(vides)e(the)i -(functionality)e(of)i(the)g Fp(kmetis)f FL(program)f(when)208 -889 y(it)f(is)g(used)g(to)f(compute)f(a)i(multi-constraint)e -(partitioning.)22 b(The)d(objecti)n(v)o(e)e(of)h(the)h(partitioning)d -(is)k(to)e(minimize)g(the)h(edgecut)208 998 y(\(as)h(described)f(in)h -(Section)g(5.3\).)0 1174 y FB(P)n(arameter)o(s)208 1293 -y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.) -208 1436 y FC(ncon)202 b FL(The)20 b(number)e(of)i(constraints.)25 -b(This)20 b(should)f(be)h(greater)f(than)h(one)g(and)f(smaller)i(than)e -(15.)208 1552 y FC(xadj,)g(adjncy)581 1662 y FL(The)h(adjacenc)o(y)e -(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.) -208 1778 y FC(vwgt,)f(adjwgt)581 1887 y FL(Information)k(about)h(the)h -(weights)g(of)g(the)h(v)o(ertices)e(and)h(edges)g(as)h(described)e(in)h -(Section)g(5.1.)40 b(Note)25 b(that)h(the)581 1997 y(weight)20 -b(v)o(ector)f(must)h(be)g(supplied)f(and)h(it)h(should)e(be)h(of)g -(size)h Fz(n*ncon)p FL(.)208 2140 y FC(wgt\003ag)113 -b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 2282 y(0)83 b(No)20 b(weights)g(\(adjwgt)f(is)i(NULL\))581 -2408 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges.)208 -2551 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2660 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -2803 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 2929 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 3071 y FC(nparts)142 -b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208 -3214 y FC(ub)o(v)o(ec)167 b FL(This)24 b(is)h(a)g(v)o(ector)e(of)g -(size)i Fz(ncon)g FL(that)f(speci\002es)g(the)g(load)g(imbalance)f -(tolerances)g(for)g(each)h(one)f(of)h(the)g Fz(ncon)581 -3323 y FL(constraints.)g(Each)c(tolerance)f(should)g(be)h(greater)g -(than)f(1.0)h(\(preferably)d(greater)j(than)f(1.03\).)208 -3466 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o -(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n -(arious)f(phases)h(of)g(the)g(algorithm.)581 3575 y(If)j -Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 -b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h -(elements)g(of)581 3685 y Fs(options)c FL(are)i(interpreted)d(as)j -(follo)n(ws:)581 3827 y(options[1])108 b(Determines)20 -b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033 -3953 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 4079 -y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 4205 -y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o -(ault\))1033 4331 y(5)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h -(follo)n(wed)g(by)h(1-norm)e(Balanced-edge)g(\(SHEBM1N\))1033 -4458 y(6)83 b(Sorted)28 b(Hea)n(vy-Edge)f(Matching)h(follo)n(wed)g(by)h -FM(1)p FL(-norm)e(Balanced-edge)g(\(SHEBMIN\))1158 4567 -y(\(Def)o(ault\))1033 4693 y(7)83 b(1-norm)18 b(Balanced-edge)g(follo)n -(wed)h(by)h(Hea)n(vy-Edge)e(Matching)h(\(SBHEM1N\))1033 -4819 y(8)83 b FM(1)p FL(-norm)18 b(Balanced-edge)g(follo)n(wed)h(by)h -(Hea)n(vy-Edge)e(Matching)h(\(SBHEMIN\))1033 4945 y(Experiments)g(has)j -(sho)n(wn)e(that)h(for)g(simple)g(balancing)e(problems,)h(the)h -(schemes)g(that)g(gi)n(v)o(e)f(pri-)1033 5055 y(ority)15 -b(to)h(hea)n(vy)e(edges)h(\()p Fs(e)o(.g)o FL(.,)h(SHEM,)g(SHEBM1N,)f -(SHEBMIN\))g(perform)e(better)m(,)j(and)f(for)f(hard)1033 -5164 y(balancing)i(problems,)f(the)i(schemes)g(that)g(gi)n(v)o(e)g -(priority)e(to)i(balanced)f(edges)h(\()p Fs(e)o(.g)n -FL(.,)h(SBHEM1N,)1033 5274 y(SBHEMIN\))i(perform)e(better)-5 -b(.)581 5400 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used) -g(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1908 -5649 y(26)p eop -%%Page: 27 27 -27 26 bop 1033 83 a FL(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g -(bisection)1033 209 y(2)83 b(Relax)o(ed)19 b(Multile)n(v)o(el)h -(recursi)n(v)o(e)e(bisection)i(\(Def)o(ault\))581 335 -y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h -(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 462 -y(1)83 b(Random)19 b(boundary)e(re\002nement)i(\(Def)o(ault\))581 -588 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 -b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208 -731 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j -(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h -(by)e(the)i(partition.)208 873 y FC(part)220 b FL(This)18 -b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h -(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.) -23 b(The)581 983 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i -(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)0 1159 y FB(Note)208 1269 y FL(This)24 -b(function)f(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h -(a)h(lar)o(ge)f(number)e(of)j(partitions)e(\(greater)g(than)h(8\).)38 -b(If)24 b(a)h(small)208 1378 y(number)f(of)i(partitions)g(is)h -(desired,)g(the)g Fz(METIS)p 1683 1378 25 4 v 30 w(mCP)m(ar)s(tGr)o -(aphRecursiv)n(e)g FL(should)e(be)h(used)h(instead,)g(as)g(it)g -(produces)208 1488 y(some)n(what)19 b(better)h(partitions.)1908 -5649 y(27)p eop -%%Page: 28 28 -28 27 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(WP)n(ar)r(tGraphRecur)o -(sive)20 b FL(\(int)h(*n,)e(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5 -b(,)17 b(idxtype)i(*vwgt,)g(idxtype)g(*adjwgt,)g(int)i(*wgt\003ag,)1183 -193 y(int)g(*num\003ag,)d(int)i(*nparts,)f(\003oat)i(*tpwgts,)e(int)i -(*options,)d(int)j(*edgecut,)d(idxtype)h(*part\))0 452 -y FB(Description)208 561 y FL(It)29 b(is)h(used)f(to)g(partition)f(a)i -(graph)e(into)h Ft(k)34 b FL(parts)29 b(using)g(multile)n(v)o(el)f -(recursi)n(v)o(e)g(bisection.)51 b(The)29 b(underlying)d(algorithm)i -(is)208 671 y(similar)g(to)h(the)g(one)f(used)g(by)g -Fz(METIS)p 1392 671 V 31 w(P)m(ar)s(tGr)o(aphRecursiv)n(e)p -FL(,)i(b)n(ut)e(it)i(can)e(be)h(used)f(to)h(compute)e(a)i(partitioning) -d(with)208 780 y(prescribed)19 b(partition)h(weights.)27 -b(F)o(or)20 b(e)o(xample,)g(it)h(can)g(be)g(used)g(to)g(compute)e(a)j -(3-w)o(ay)e(partition)g(such)g(that)h(partition)f(1)h(has)208 -890 y(50\045)h(of)g(the)h(weight,)f(partition)g(2)h(has)f(20\045)h(of)f -(the)h(weight,)f(and)g(partition)g(3)h(has)f(30\045)h(of)f(the)h -(weight.)31 b(The)23 b(objecti)n(v)o(e)e(of)208 1000 -y(the)f(partitioning)e(is)j(to)f(minimize)g(the)g(edgecut)f(\(as)i -(described)d(in)j(Section)f(5.3\).)0 1176 y FB(P)n(arameter)o(s)208 -1295 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h -(graph.)208 1412 y FC(xadj,)e(adjncy)581 1521 y FL(The)h(adjacenc)o(y)e -(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.) -208 1638 y FC(vwgt,)f(adjwgt)581 1748 y FL(Information)f(about)h(the)h -(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h -(Section)g(5.1.)208 1890 y FC(wgt\003ag)113 b FL(Used)21 -b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 2033 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h -(are)g(NULL\))581 2159 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g -(only)g(\(vwgts)f(=)i(NULL\))581 2286 y(2)83 b(W)-7 b(eights)21 -b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581 -2412 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h -(edges.)208 2555 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g -(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f -(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 -2664 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:) -581 2807 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g -(starts)h(from)e(0)581 2933 y(1)83 b(F)o(ortran-style)18 -b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208 -3076 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h -(partition)e(the)h(graph.)208 3219 y FC(tpwgts)137 b -FL(This)17 b(is)g(an)f(array)f(containing)g Fs(nparts)h -FL(\003oating)f(point)h(numbers.)22 b(F)o(or)16 b(partition)e -Ft(i)9 b FL(,)17 b Fs(tpwgts[)o Ft(i)9 b Fs(])17 b FL(stores)g(the)f -(fraction)581 3328 y(of)g(the)g(total)g(weight)g(that)g(should)f(be)h -(assigned)f(to)i(it.)24 b(F)o(or)15 b(e)o(xample,)h(for)f(a)i(4-w)o(ay) -e(partition)g(the)h(v)o(ector)f Fs(tpwgts[])581 3438 -y(=)j FM(f)p Fs(0.2)e(0.2)g(0.4)g(0.2)p FM(g)g FL(will)i(result)f(in)g -(partitions)f(0,)h(1,)h(and)e(3)h(ha)n(ving)f(20\045)g(of)h(the)g -(weight)g(and)f(partition)g(2)h(ha)n(ving)581 3548 y(40\045)j(of)g(the) -g(weight.)25 b(Note)20 b(that)g(the)g(numbers)f(in)h -Fs(tpwgts)h FL(should)e(add)h(up)g(to)g(1.0.)208 3690 -y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers) -e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f -(phases)h(of)g(the)g(algorithm.)581 3800 y(If)j Fs(options[0]=0)e -FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 b(If)24 -b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h(elements)g -(of)581 3910 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -4052 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24 -b(Possible)d(v)n(alues)e(are:)1033 4179 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 4305 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 4431 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 4557 y(Experiments)f(has)h -(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.) -581 4683 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g -(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 -4810 y(1)83 b(Re)o(gion)19 b(Gro)n(wing)g(\(Def)o(ault\))581 -4936 y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h -(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 5062 -y(1)83 b(Early-Exit)18 b(Boundary)h(FM)h(re\002nement)f(\(Def)o(ault\)) -581 5188 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 -b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208 -5331 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j -(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h -(by)e(the)i(partition.)1908 5649 y(28)p eop -%%Page: 29 29 -29 28 bop 208 83 a FC(part)220 b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i -(size)g Fs(n)g FL(that)g(upon)e(successful)h(completion)f(stores)i(the) -g(partition)f(v)o(ector)f(of)h(the)h(graph.)23 b(The)581 -193 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h -(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)0 369 y FB(Note)208 478 y FL(This)d(function)f -(should)h(be)g(used)g(to)h(partition)f(a)g(graph)g(into)g(a)h(small)g -(number)e(of)h(partitions)g(\(less)h(than)f(8\).)23 b(If)17 -b(a)g(lar)o(ge)e(number)208 588 y(of)k(partitions)h(is)h(desired,)e -(the)h Fz(METIS)p 1369 588 25 4 v 31 w(WP)m(ar)s(tGr)o(aphKw)o(a)n(y)h -FL(should)e(be)h(used)g(instead,)g(as)g(it)h(is)h(signi\002cantly)d(f)o -(aster)-5 b(.)1908 5649 y(29)p eop -%%Page: 30 30 -30 29 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(WP)n(ar)r(tGraphKwa)n(y) -20 b FL(\(int)g(*n,)g(idxtype)e(*xadj,)h(idxtype)g(*adjnc)o(y)-5 -b(,)18 b(idxtype)h(*vwgt,)g(idxtype)g(*adjwgt,)g(int)h(*wgt\003ag,)1003 -193 y(int)g(*num\003ag,)f(int)h(*nparts,)f(\003oat)h(*tpwgts,)g(int)g -(*options,)f(int)h(*edgecut,)e(idxtype)h(*part\))0 444 -y FB(Description)208 554 y FL(It)29 b(is)h(used)f(to)g(partition)f(a)i -(graph)e(into)h Ft(k)34 b FL(parts)29 b(using)g(multile)n(v)o(el)f -(recursi)n(v)o(e)g(bisection.)51 b(The)29 b(underlying)d(algorithm)i -(is)208 663 y(similar)16 b(to)h(the)f(one)g(used)g(by)h -Fz(METIS)p 1320 663 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)p -FL(,)g(b)n(ut)g(it)g(can)f(be)g(used)h(to)f(compute)f(a)i(partitioning) -e(with)h(prescribed)208 773 y(partition)24 b(weights.)42 -b(F)o(or)25 b(e)o(xample,)h(it)g(can)g(be)g(used)f(to)h(compute)e(a)j -(3-w)o(ay)e(partition)f(such)i(that)g(partition)e(1)i(has)g(50\045)g -(of)208 883 y(the)j(weight,)h(partition)e(2)h(has)g(20\045)g(of)g(the)f -(weight,)j(and)d(partition)g(3)h(has)g(30\045)g(of)g(the)g(weight.)51 -b(The)28 b(objecti)n(v)o(e)g(of)h(the)208 992 y(partitioning)18 -b(is)j(to)f(minimize)g(the)g(edgecut)f(\(as)h(described)f(in)i(Section) -e(5.3\).)0 1167 y FB(P)n(arameter)o(s)208 1284 y FC(n)327 -b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 -1399 y FC(xadj,)e(adjncy)581 1509 y FL(The)h(adjacenc)o(y)e(structure)i -(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208 -1624 y FC(vwgt,)f(adjwgt)581 1734 y FL(Information)f(about)h(the)h -(weights)g(of)g(the)g(v)o(ertices)g(and)f(edges)h(as)h(described)e(in)h -(Section)g(5.1.)208 1875 y FC(wgt\003ag)113 b FL(Used)21 -b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 2016 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(adjwgt)h -(are)g(NULL\))581 2141 y(1)83 b(W)-7 b(eights)21 b(on)e(the)h(edges)g -(only)g(\(vwgts)f(=)i(NULL\))581 2267 y(2)83 b(W)-7 b(eights)21 -b(on)e(the)h(v)o(ertices)g(only)g(\(adjwgt)f(=)i(NULL\))581 -2392 y(3)83 b(W)-7 b(eights)21 b(both)e(on)h(v)o(ertices)f(and)h -(edges.)208 2533 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g -(which)g(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f -(structure)g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 -2643 y FL(can)20 b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:) -581 2784 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g -(starts)h(from)e(0)581 2909 y(1)83 b(F)o(ortran-style)18 -b(numbering)g(is)j(assumed)e(that)i(starts)g(from)e(1)208 -3051 y FC(nparts)142 b FL(The)20 b(number)e(of)i(parts)g(to)h -(partition)e(the)h(graph.)208 3192 y FC(tpwgts)137 b -FL(This)17 b(is)g(an)f(array)f(containing)g Fs(nparts)h -FL(\003oating)f(point)h(numbers.)22 b(F)o(or)16 b(partition)e -Ft(i)9 b FL(,)17 b Fs(tpwgts[)o Ft(i)9 b Fs(])17 b FL(stores)g(the)f -(fraction)581 3301 y(of)g(the)g(total)g(weight)g(that)g(should)f(be)h -(assigned)f(to)i(it.)24 b(F)o(or)15 b(e)o(xample,)h(for)f(a)i(4-w)o(ay) -e(partition)g(the)h(v)o(ector)f Fs(tpwgts[])581 3411 -y(=)j FM(f)p Fs(0.2)e(0.2)g(0.4)g(0.2)p FM(g)g FL(will)i(result)f(in)g -(partitions)f(0,)h(1,)h(and)e(3)h(ha)n(ving)f(20\045)g(of)h(the)g -(weight)g(and)f(partition)g(2)h(ha)n(ving)581 3520 y(40\045)j(of)g(the) -g(weight.)25 b(Note)20 b(that)g(the)g(numbers)f(in)h -Fs(tpwgts)h FL(should)e(add)h(up)g(to)g(1.0.)208 3662 -y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers) -e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f -(phases)h(of)g(the)g(algorithm.)581 3771 y(If)j Fs(options[0]=0)e -FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 b(If)24 -b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h(elements)g -(of)581 3881 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -4022 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24 -b(Possible)d(v)n(alues)e(are:)1033 4147 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 4273 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 4398 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 4523 y(Experiments)f(has)h -(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.) -581 4649 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g -(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 -4774 y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g -(\(Def)o(ault\))581 4900 y(options[3])108 b(Determines)20 -b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g -(are:)1033 5025 y(1)83 b(Random)19 b(boundary)e(re\002nement)1033 -5150 y(2)83 b(Greedy)19 b(boundary)e(re\002nement)1033 -5276 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h -(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158 -5385 y(domains)f(\(Def)o(ault\))1908 5649 y(30)p eop -%%Page: 31 31 -31 30 bop 581 83 a FL(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f -(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208 -226 y FC(edgecut)100 b FL(Upon)19 b(successful)h(completion,)e(this)j -(v)n(ariable)e(stores)i(the)f(number)e(of)i(edges)g(that)g(are)g(cut)h -(by)e(the)i(partition.)208 369 y FC(part)220 b FL(This)18 -b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g FL(that)g(upon)e(successful)h -(completion)f(stores)i(the)g(partition)f(v)o(ector)f(of)h(the)h(graph.) -23 b(The)581 478 y(numbering)18 b(of)i(this)g(v)o(ector)f(starts)i -(from)e(either)h(0)g(or)g(1,)g(depending)e(on)i(the)g(v)n(alue)g(of)f -Fs(num\003a)o(g)p FL(.)0 654 y FB(Note)208 764 y FL(This)24 -b(function)f(should)g(be)i(used)f(to)h(partition)e(a)i(graph)e(into)h -(a)h(lar)o(ge)f(number)e(of)j(partitions)e(\(greater)g(than)h(8\).)38 -b(If)24 b(a)h(small)208 873 y(number)j(of)i(partitions)f(is)i(desired,) -h(the)e Fz(METIS)p 1706 873 25 4 v 31 w(WP)m(ar)s(tGr)o(aphRecursiv)n -(e)g FL(should)f(be)h(used)g(instead,)i(as)f(it)g(produces)208 -983 y(some)n(what)19 b(better)h(partitions.)1908 5649 -y(31)p eop -%%Page: 32 32 -32 31 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(WP)n(ar)r(tGraphVKwa)n -(y)20 b FL(\(int)h(*n,)e(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5 -b(,)17 b(idxtype)i(*vwgt,)g(idxtype)g(*vsize,)h(int)g(*wgt\003ag,)1058 -193 y(int)h(*num\003ag,)d(int)i(*nparts,)f(\003oat)i(*tpwgts,)e(int)i -(*options,)d(int)j(*v)n(olume,)d(idxtype)h(*part\))0 -450 y FB(Description)208 560 y FL(It)29 b(is)h(used)f(to)g(partition)f -(a)i(graph)e(into)h Ft(k)34 b FL(parts)29 b(using)g(multile)n(v)o(el)f -(recursi)n(v)o(e)g(bisection.)51 b(The)29 b(underlying)d(algorithm)i -(is)208 669 y(similar)16 b(to)h(the)f(one)g(used)g(by)h -Fz(METIS)p 1320 669 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)p -FL(,)g(b)n(ut)g(it)g(can)f(be)g(used)h(to)f(compute)f(a)i(partitioning) -e(with)h(prescribed)208 779 y(partition)24 b(weights.)42 -b(F)o(or)25 b(e)o(xample,)h(it)g(can)g(be)g(used)f(to)h(compute)e(a)j -(3-w)o(ay)e(partition)f(such)i(that)g(partition)e(1)i(has)g(50\045)g -(of)208 888 y(the)j(weight,)h(partition)e(2)h(has)g(20\045)g(of)g(the)f -(weight,)j(and)d(partition)g(3)h(has)g(30\045)g(of)g(the)g(weight.)51 -b(The)28 b(objecti)n(v)o(e)g(of)h(the)208 998 y(partitioning)18 -b(is)j(to)f(minimize)g(the)g(total)g(communication)e(v)n(olume)h(\(as)h -(described)f(in)h(Section)g(5.3\).)0 1174 y FB(P)n(arameter)o(s)208 -1293 y FC(n)327 b FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h -(graph.)208 1409 y FC(xadj,)e(adjncy)581 1519 y FL(The)h(adjacenc)o(y)e -(structure)i(of)g(the)g(graph)f(as)i(described)d(in)j(Sections)f(5.1)f -(and)h(5.3.)208 1635 y FC(vwgt,)f(vsize)581 1745 y FL(Information)h -(about)j(the)g(weights)g(of)g(the)g(v)o(ertices)f(related)h(to)g(the)g -(computation)e(and)i(communication)d(as)k(de-)581 1854 -y(scribed)c(in)g(Section)g(5.1.)208 1997 y FC(wgt\003ag)113 -b FL(Used)21 b(to)f(indicate)f(if)i(the)f(graph)f(is)i(weighted.)j -Fs(wgt\003a)o(g)19 b FL(can)h(tak)o(e)h(the)f(follo)n(wing)e(v)n -(alues:)581 2139 y(0)83 b(No)20 b(weights)g(\(vwgts)g(and)f(vsize)i -(are)f(NULL\))581 2265 y(1)83 b(Communication)18 b(weights)i(only)f -(\(vwgts)h(=)g(NULL\))581 2391 y(2)83 b(Computation)18 -b(weights)i(only)f(\(vsize)h(=)h(NULL\))581 2517 y(3)83 -b(Both)20 b(communication)d(and)j(computation)e(weights.)208 -2660 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 2769 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -2912 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 3038 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 3180 y FC(nparts)142 -b FL(The)20 b(number)e(of)i(parts)g(to)h(partition)e(the)h(graph.)208 -3322 y FC(tpwgts)137 b FL(This)17 b(is)g(an)f(array)f(containing)g -Fs(nparts)h FL(\003oating)f(point)h(numbers.)22 b(F)o(or)16 -b(partition)e Ft(i)9 b FL(,)17 b Fs(tpwgts[)o Ft(i)9 -b Fs(])17 b FL(stores)g(the)f(fraction)581 3432 y(of)g(the)g(total)g -(weight)g(that)g(should)f(be)h(assigned)f(to)i(it.)24 -b(F)o(or)15 b(e)o(xample,)h(for)f(a)i(4-w)o(ay)e(partition)g(the)h(v)o -(ector)f Fs(tpwgts[])581 3542 y(=)j FM(f)p Fs(0.2)e(0.2)g(0.4)g(0.2)p -FM(g)g FL(will)i(result)f(in)g(partitions)f(0,)h(1,)h(and)e(3)h(ha)n -(ving)f(20\045)g(of)h(the)g(weight)g(and)f(partition)g(2)h(ha)n(ving) -581 3651 y(40\045)j(of)g(the)g(weight.)25 b(Note)20 b(that)g(the)g -(numbers)f(in)h Fs(tpwgts)h FL(should)e(add)h(up)g(to)g(1.0.)208 -3794 y FC(options)114 b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o -(gers)e(that)h(is)i(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n -(arious)f(phases)h(of)g(the)g(algorithm.)581 3903 y(If)j -Fs(options[0]=0)e FL(then)h(def)o(ault)g(v)n(alues)g(are)h(used.)34 -b(If)24 b Fs(options[0]=1)p FL(,)f(then)g(the)g(remaining)f(four)h -(elements)g(of)581 4013 y Fs(options)c FL(are)i(interpreted)d(as)j -(follo)n(ws:)581 4155 y(options[1])108 b(Determines)20 -b(the)g(matching)f(type.)24 b(Possible)d(v)n(alues)e(are:)1033 -4281 y(1)83 b(Random)19 b(Matching)g(\(RM\))1033 4407 -y(2)83 b(Hea)n(vy-Edge)18 b(Matching)h(\(HEM\))1033 4533 -y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f(Matching)h(\(SHEM\))h(\(Def)o -(ault\))1033 4659 y(Experiments)f(has)h(sho)n(wn)g(that)g(both)f(HEM)h -(and)g(SHEM)g(perform)f(quite)g(well.)581 4785 y(options[2])108 -b(Determines)20 b(the)g(algorithm)f(used)g(during)g(initial)i -(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 4911 -y(1)83 b(Multile)n(v)o(el)19 b(recursi)n(v)o(e)g(bisection)g(\(Def)o -(ault\))581 5037 y(options[3])108 b(Determines)20 b(the)g(algorithm)f -(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 -5163 y(1)83 b(Random)19 b(boundary)e(re\002nement)i(\(Def)o(ault\))1033 -5289 y(3)83 b(Random)19 b(boundary)e(re\002nement)i(that)h(also)h -(minimizes)f(the)g(connecti)n(vity)e(among)h(the)h(sub-)1158 -5399 y(domains)1908 5649 y(32)p eop -%%Page: 33 33 -33 32 bop 581 83 a FL(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f -(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208 -226 y FC(v)o(olume)115 b FL(Upon)27 b(successful)h(completion,)g(this)h -(v)n(ariable)e(stores)h(the)g(total)g(communication)e(v)n(olume)h -(required)f(by)i(the)581 335 y(partition.)208 478 y FC(part)220 -b FL(This)18 b(is)h(a)f(v)o(ector)e(of)i(size)g Fs(n)g -FL(that)g(upon)e(successful)h(completion)f(stores)i(the)g(partition)f -(v)o(ector)f(of)h(the)h(graph.)23 b(The)581 588 y(numbering)18 -b(of)i(this)g(v)o(ector)f(starts)i(from)e(either)h(0)g(or)g(1,)g -(depending)e(on)i(the)g(v)n(alue)g(of)f Fs(num\003a)o(g)p -FL(.)1908 5649 y(33)p eop -%%Page: 34 34 -34 33 bop 0 83 a Fr(5.5)100 b(Mesh)28 b(P)m(ar)r(titioning)g(Routines)0 -242 y FB(METIS)p 258 242 25 4 v 31 w(P)n(ar)r(tMeshNodal)20 -b FL(\(int)g(*ne,)f(int)i(*nn,)e(idxtype)g(*elmnts,)g(int)h(*etype,)f -(int)i(*num\003ag,)d(int)i(*nparts,)f(int)i(*edgecut,)908 -352 y(idxtype)e(*epart,)g(idxtype)f(*npart\))0 611 y -FB(Description)208 721 y FL(This)f(function)f(is)j(used)e(to)h -(partition)e(a)i(mesh)f(into)h Ft(k)23 b FL(equal-size)16 -b(parts.)24 b(It)18 b(pro)o(vides)e(the)h(functionality)f(of)h(the)h -Fp(partnmesh)208 830 y FL(program.)0 1006 y FB(P)n(arameter)o(s)208 -1126 y FC(ne)290 b FL(The)20 b(number)e(of)i(elements)g(in)h(the)f -(mesh.)208 1269 y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g -(the)g(mesh.)208 1411 y FC(elmnts)138 b FL(The)20 b(element)g(node)f -(array)g(storing)g(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.) -208 1554 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i -(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the) -g(follo)n(wing)f(v)n(alues:)581 1697 y(1)83 b(The)20 -b(elements)f(are)i(triangles.)581 1823 y(2)83 b(The)20 -b(elements)f(are)i(tetrahedra.)581 1949 y(3)83 b(The)20 -b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 2076 -y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208 -2218 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5 -b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581 -2328 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2471 y(0)83 -b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581 -2597 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i -(starts)g(from)e(1)208 2740 y FC(nparts)142 b FL(The)20 -b(number)e(of)i(parts)g(to)h(partition)e(the)h(mesh.)208 -2883 y FC(edgecut)100 b FL(Upon)20 b(successful)h(completion,)f(this)i -(v)n(ariable)e(stores)h(the)g(number)f(of)h(edges)g(that)g(are)g(cut)g -(by)g(the)g(partition)f(in)581 2992 y(the)g(nodal)g(graph.)208 -3135 y FC(epart)183 b FL(This)18 b(is)h(a)g(v)o(ector)d(of)i(size)h -Fs(ne)e FL(that)h(upon)f(successful)h(completion)e(stores)i(the)g -(partition)f(v)o(ector)g(for)g(the)h(elements)581 3245 -y(of)31 b(the)f(mesh.)57 b(The)30 b(numbering)e(of)j(this)g(v)o(ector)e -(starts)j(from)e(either)g(0)h(or)f(1,)k(depending)28 -b(on)i(the)h(v)n(alue)f(of)581 3354 y Fs(num\003a)o(g)p -FL(.)208 3497 y FC(npart)174 b FL(This)19 b(is)g(a)g(v)o(ector)e(of)h -(size)i Fs(nn)e FL(that)g(upon)f(successful)h(completion)f(stores)i -(the)f(partition)g(v)o(ector)f(for)h(the)g(nodes)g(of)581 -3606 y(the)i(mesh.)25 b(The)19 b(numbering)f(of)h(this)i(v)o(ector)d -(starts)j(from)e(either)g(0)h(or)g(1,)g(depending)d(on)j(the)g(v)n -(alue)f(of)h Fs(num\003a)o(g)p FL(.)0 3782 y FB(Note)208 -3892 y FL(This)g(function)f(con)m(v)o(erts)g(the)h(mesh)h(into)f(a)h -(nodal)e(graph)g(and)h(then)g(uses)i Fz(METIS)p 2642 -3892 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)f FL(to)f(compute)f(a)i -(parti-)208 4002 y(tioning)f(of)h(the)g(nodes.)28 b(This)22 -b(partitioning)d(of)i(nodes)g(is)h(then)f(used)g(to)h(compute)e(a)h -(partitioning)f(for)g(the)i(elements.)28 b(This)22 b(is)208 -4111 y(done)d(by)i(assigning)f(each)h(element)f(to)h(the)g(partition)f -(in)h(which)g(the)g(majority)f(of)g(its)i(nodes)e(belong)g(to)h -(\(subject)f(to)h(balance)208 4221 y(constraints\).)1908 -5649 y(34)p eop -%%Page: 35 35 -35 34 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(P)n(ar)r(tMeshDual)20 -b FL(\(int)g(*ne,)g(int)g(*nn,)f(idxtype)g(*elmnts,)g(int)i(*etype,)e -(int)h(*num\003ag,)e(int)j(*nparts,)e(int)h(*edgecut,)857 -193 y(idxtype)f(*epart,)g(idxtype)g(*npart\))0 452 y -FB(Description)208 561 y FL(This)e(function)f(is)j(used)e(to)h -(partition)e(a)i(mesh)f(into)h Ft(k)23 b FL(equal-size)16 -b(parts.)24 b(It)18 b(pro)o(vides)e(the)h(functionality)f(of)h(the)h -Fp(partdmesh)208 671 y FL(program.)0 847 y FB(P)n(arameter)o(s)208 -966 y FC(ne)290 b FL(The)20 b(number)e(of)i(elements)g(in)h(the)f -(mesh.)208 1109 y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g -(the)g(mesh.)208 1252 y FC(elmnts)138 b FL(The)20 b(element)g(node)f -(array)g(storing)g(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.) -208 1395 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i -(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the) -g(follo)n(wing)f(v)n(alues:)581 1538 y(1)83 b(The)20 -b(elements)f(are)i(triangles.)581 1664 y(2)83 b(The)20 -b(elements)f(are)i(tetrahedra.)581 1790 y(3)83 b(The)20 -b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 1916 -y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208 -2059 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5 -b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581 -2169 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2311 y(0)83 -b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581 -2438 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i -(starts)g(from)e(1)208 2580 y FC(nparts)142 b FL(The)20 -b(number)e(of)i(parts)g(to)h(partition)e(the)h(mesh.)208 -2723 y FC(edgecut)100 b FL(Upon)20 b(successful)h(completion,)f(this)i -(v)n(ariable)e(stores)h(the)g(number)f(of)h(edges)g(that)g(are)g(cut)g -(by)g(the)g(partition)f(in)581 2833 y(the)g(dual)g(graph.)208 -2976 y FC(epart)183 b FL(This)18 b(is)h(a)g(v)o(ector)d(of)i(size)h -Fs(ne)e FL(that)h(upon)f(successful)h(completion)e(stores)i(the)g -(partition)f(v)o(ector)g(for)g(the)h(elements)581 3085 -y(of)31 b(the)f(mesh.)57 b(The)30 b(numbering)e(of)j(this)g(v)o(ector)e -(starts)j(from)e(either)g(0)h(or)f(1,)k(depending)28 -b(on)i(the)h(v)n(alue)f(of)581 3195 y Fs(num\003a)o(g)p -FL(.)208 3337 y FC(npart)174 b FL(This)19 b(is)g(a)g(v)o(ector)e(of)h -(size)i Fs(nn)e FL(that)g(upon)f(successful)h(completion)f(stores)i -(the)f(partition)g(v)o(ector)f(for)h(the)g(nodes)g(of)581 -3447 y(the)i(mesh.)25 b(The)19 b(numbering)f(of)h(this)i(v)o(ector)d -(starts)j(from)e(either)g(0)h(or)g(1,)g(depending)d(on)j(the)g(v)n -(alue)f(of)h Fs(num\003a)o(g)p FL(.)0 3623 y FB(Note)208 -3733 y FL(This)j(function)e(con)m(v)o(erts)h(the)h(mesh)g(into)f(a)i -(dual)f(graph)e(and)i(then)g(uses)g Fz(METIS)p 2631 3733 -V 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)g FL(to)g(compute)f(a)h(parti-)208 -3842 y(tioning)c(of)h(the)g(elements.)25 b(This)20 b(partitioning)f(of) -h(elements)g(is)h(then)f(used)g(to)g(compute)f(a)i(partitioning)d(for)i -(the)g(nodes.)k(This)208 3952 y(is)d(done)f(by)g(assigning)g(each)g -(node)g(to)h(the)g(partition)e(in)i(which)f(the)h(majority)f(of)g(its)i -(incident)e(elements)g(belong)f(to)i(\(subject)208 4061 -y(to)f(balance)f(constraints\).)1908 5649 y(35)p eop -%%Page: 36 36 -36 35 bop 0 83 a Fr(5.6)100 b(Spar)o(se)29 b(Matrix)f(Reor)n(dering)f -(Routines)0 242 y FB(METIS)p 258 242 25 4 v 31 w(Edg)q(eND)20 -b FL(\(int)g(*n,)g(idxtype)e(*xadj,)h(idxtype)g(*adjnc)o(y)-5 -b(,)18 b(int)i(*num\003ag,)f(int)h(*options,)f(idxtype)f(*perm,)h -(idxtype)g(*iperm\))0 501 y FB(Description)208 611 y -FL(This)25 b(function)f(computes)h(\002ll)h(reducing)e(orderings)f(of)j -(sparse)f(matrices)h(using)f(the)g(multile)n(v)o(el)g(nested)g -(dissection)g(algo-)208 721 y(rithm.)f(It)c(pro)o(vides)f(the)h -(functionality)e(of)i(the)g Fp(oemetis)g FL(program.)0 -897 y FB(P)n(arameter)o(s)208 1016 y FC(n)327 b FL(The)20 -b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1133 -y FC(xadj,)e(adjncy)581 1242 y FL(The)h(adjacenc)o(y)e(structure)i(of)g -(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208 -1385 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 1495 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -1638 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 1764 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 1907 y FC(options)114 -b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i -(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g -(the)g(algorithm.)581 2016 y(If)j Fs(options[0]=0)e FL(then)h(def)o -(ault)g(v)n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p -FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581 -2126 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -2269 y(options[1])108 b(Determined)19 b(the)h(matching)f(type.)24 -b(Possible)d(v)n(alues)f(are:)1033 2395 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 2521 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 2647 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 2773 y(Experiments)f(has)h -(sho)n(wn)g(that)g(both)f(HEM)h(and)g(SHEM)g(perform)f(quite)g(well.) -581 2900 y(options[2])108 b(Determines)20 b(the)g(algorithm)f(used)g -(during)g(initial)i(partitioning.)h(Possible)f(v)n(alues)f(are:)1033 -3026 y(1)83 b(Re)o(gion)19 b(Gro)n(wing)g(\(Def)o(ault\))581 -3152 y(options[3])108 b(Determines)20 b(the)g(algorithm)f(used)g(for)h -(re\002nement.)k(Possible)c(v)n(alues)g(are:)1033 3278 -y(1)83 b(Early-Exit)18 b(Boundary)h(FM)h(re\002nement)f(\(Def)o(ault\)) -581 3404 y(options[4])108 b(Used)21 b(for)e(deb)n(ugging)f(purposes.)23 -b(Al)o(w)o(ays)e(set)g(it)g(to)f(0)h(\(Def)o(ault\).)208 -3521 y FC(perm,)f(iperm)581 3631 y FL(These)25 b(are)g(v)o(ectors,)f -(each)h(of)g(size)g Fs(n)p FL(.)39 b(Upon)24 b(successful)h -(completion,)f(the)o(y)g(store)g(the)h(\002ll-reducing)e(permu-)581 -3740 y(tation)j(and)g(in)m(v)o(erse-permutation.)39 b(Let)34 -b Ft(A)29 b FL(be)d(the)g(original)f(matrix)h(and)34 -b Ft(A)2868 3710 y Fe(0)2915 3740 y FL(be)27 b(the)f(permuted)e -(matrix.)43 b(The)581 3850 y(arrays)21 b Fs(perm)g FL(and)f -Fs(iperm)h FL(are)g(de\002ned)f(as)i(follo)n(ws.)27 b(Ro)n(w)21 -b(\(column\))d Ft(i)30 b FL(of)f Ft(A)2836 3820 y Fe(0)2878 -3850 y FL(is)22 b(the)f(perm)o FM(T)o Ft(i)9 b FM(U)20 -b FL(ro)n(w)h(\(column\))e(of)589 3959 y Ft(A)r FL(,)j(and)f(ro)n(w)g -(\(column\))d Ft(i)31 b FL(of)e Ft(A)24 b FL(is)e(the)g(iperm)n -FM(T)o Ft(i)9 b FM(U)21 b FL(ro)n(w)g(\(column\))f(of)29 -b Ft(A)2659 3929 y Fe(0)2680 3959 y FL(.)g(The)21 b(numbering)e(of)i -(this)h(v)o(ector)f(starts)581 4069 y(from)e(either)h(0)g(or)g(1,)g -(depending)e(on)i(the)g(v)n(alue)f(of)h Fs(num\003a)o(g)p -FL(.)0 4245 y FB(Note)208 4355 y FL(This)25 b(function)f(computes)g -(the)h(v)o(erte)o(x)f(separator)g(from)g(the)h(edge)g(separator)f -(using)h(a)g(minimum)f(co)o(v)o(er)g(algorithm.)38 b(This)208 -4464 y(function)21 b(should)i(be)g(used)h(only)f(in)g(ordering)f(lar)o -(ge)g(graphs)h(arising)g(in)h(3D)f(\002nite)h(element)f(applications.) -34 b(In)23 b(general)g(the)208 4574 y Fz(METIS)p 466 -4574 V 30 w(NodeND)e FL(routine)e(should)g(be)h(preferred,)e(as)j(it)g -(produces)d(better)i(orderings.)1908 5649 y(36)p eop -%%Page: 37 37 -37 36 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(NodeND)20 -b FL(\(int)g(*n,)f(idxtype)g(*xadj,)g(idxtype)g(*adjnc)o(y)-5 -b(,)18 b(int)i(*num\003ag,)e(int)j(*options,)d(idxtype)h(*perm,)g -(idxtype)g(*iperm\))0 342 y FB(Description)208 452 y -FL(This)25 b(function)f(computes)h(\002ll)h(reducing)e(orderings)f(of)j -(sparse)f(matrices)h(using)f(the)g(multile)n(v)o(el)g(nested)g -(dissection)g(algo-)208 561 y(rithm.)f(It)c(pro)o(vides)f(the)h -(functionality)e(of)i(the)g Fp(onmetis)g FL(program.)0 -737 y FB(P)n(arameter)o(s)208 857 y FC(n)327 b FL(The)20 -b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 973 -y FC(xadj,)e(adjncy)581 1083 y FL(The)h(adjacenc)o(y)e(structure)i(of)g -(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208 -1226 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 1335 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -1478 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 1604 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 1747 y FC(options)114 -b FL(This)22 b(is)g(an)f(array)f(of)h(8)h(inte)o(gers)e(that)h(is)i -(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g -(the)g(algorithm.)581 1857 y(If)g Fs(options[0]=0)e FL(then)h(def)o -(ault)g(v)n(alues)g(are)h(used.)26 b(If)21 b Fs(options[0]=1)p -FL(,)e(then)h(the)h(remaining)e(se)n(v)o(en)g(elements)i(of)581 -1966 y Fs(options)e FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -2109 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24 -b(Possible)d(v)n(alues)e(are:)1033 2235 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 2362 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 2488 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 2614 y(Experiments)14 -b(ha)n(v)o(e)h(sho)n(wn)g(that)h(all)h(three)e(matching)f(schemes)i -(perform)e(quite)h(well.)24 b(In)16 b(general)1033 2724 -y(SHEM)22 b(is)h(f)o(aster)e(and)g(RM)i(is)f(slo)n(wer)m(,)f(b)n(ut)h -(feel)g(free)f(to)g(e)o(xperiment)f(with)i(the)f(other)g(matching)1033 -2833 y(schemes.)581 2959 y(options[2])108 b(Determines)20 -b(the)g(algorithm)f(used)g(during)g(initial)i(partitioning.)h(Possible) -f(v)n(alues)f(are:)1033 3086 y(1)83 b(Edge-based)18 b(re)o(gion)g(gro)n -(wing)h(\(Def)o(ault\))1033 3212 y(2)83 b(Node-based)18 -b(re)o(gion)h(gro)n(wing)581 3338 y(options[3])108 b(Determines)20 -b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g -(are:)1033 3464 y(1)83 b(T)-7 b(w)o(o-sided)19 b(node)g(FM)i -(re\002nement)1033 3590 y(2)83 b(One-sided)19 b(node)g(FM)i -(re\002nement)d(\(Def)o(ault\))1033 3717 y(One-sided)i(FM)h -(re\002nement)f(is)i(f)o(aster)f(than)g(tw)o(o-sided,)f(b)n(ut)h(in)g -(some)f(cases)i(tw)o(o-sided)e(re\002ne-)1033 3826 y(ment)g(may)g -(produce)e(better)i(orderings.)j(Feel)d(free)g(to)h(e)o(xperiment)d -(with)i(this)h(option.)581 3952 y(options[4])108 b(Used)21 -b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0) -h(\(Def)o(ault\).)581 4079 y(options[5])108 b(Used)17 -b(to)f(select)h(whether)e(or)h(not)f(to)i(compress)e(the)h(graph)f(and) -g(to)i(order)d(connected)h(components)1033 4188 y(separately)-5 -b(.)24 b(The)c(possible)g(v)n(alues)f(and)h(their)g(meaning)f(are)h(as) -h(follo)n(ws.)1033 4314 y(0)83 b(Do)32 b(not)h(try)f(to)h(compress)f -(the)h(graph)e(and)h(do)g(not)h(order)e(each)h(connected)f(component) -1158 4424 y(separately)-5 b(.)1033 4550 y(1)83 b(T)m(ry)23 -b(to)i(compress)e(the)h(graph.)36 b(\(A)24 b(compressed)f(graph)f(is)j -(actually)f(formed)e(if)j(the)f(size)h(of)1158 4660 y(the)20 -b(graph)f(can)h(be)g(reduced)e(by)i(at)h(least)g(15\045\))e(\(Def)o -(ault\).)1033 4786 y(2)83 b(Order)28 b(each)h(connected)e(component)f -(of)j(the)g(graph)e(separately)-5 b(.)50 b(This)30 b(option)d(is)j -(partic-)1158 4895 y(ularly)25 b(useful)h(when)f(after)h(a)h(fe)n(w)f -(le)n(v)o(els)g(of)g(nested)f(dissection,)i(the)g(graph)d(breaks)i(up)f -(in)1158 5005 y(man)o(y)16 b(smaller)i(disconnected)e(subgraphs.)22 -b(This)c(is)g(true)g(for)f(certain)g(types)g(of)h(LP)g(matrices.)1033 -5131 y(3)83 b(T)m(ry)19 b(to)i(compress)e(the)h(graph)f(and)h(also)g -(order)f(each)h(connected)e(component)g(separately)-5 -b(.)1908 5649 y(37)p eop -%%Page: 38 38 -38 37 bop 581 83 a FL(options[6])108 b(Used)20 b(to)f(control)f -(whether)g(or)h(not)g(the)g(ordering)e(algorithm)h(should)g(remo)o(v)o -(e)f(an)o(y)i(v)o(ertices)f(with)1033 193 y(high)j(de)o(gree)e(\()p -Fs(i.e)p FL(.,)i(dense)g(columns\).)27 b(This)21 b(is)h(particularly)e -(helpful)g(for)g(certain)h(classes)h(of)f(LP)1033 302 -y(matrices,)k(in)f(which)g(there)f(a)i(fe)n(w)f(v)o(ertices)g(that)g -(are)g(connected)e(to)j(man)o(y)e(other)g(v)o(ertices.)36 -b(By)1033 412 y(remo)o(ving)20 b(these)j(v)o(ertices)e(prior)h(to)g -(ordering,)f(the)h(quality)g(and)f(the)i(amount)e(of)h(time)g(required) -1033 521 y(to)f(do)e(the)i(ordering)d(impro)o(v)o(es.)23 -b(The)c(possible)h(v)n(alues)g(are)g(as)h(follo)n(ws:)1033 -648 y(0)83 b(Do)20 b(not)g(remo)o(v)o(e)e(an)o(y)h(v)o(ertices)h(\(Def) -o(ault\))1035 774 y Ft(x)91 b FL(Where)34 b Ft(x)54 b -Fu(>)46 b FL(0,)36 b(instructs)d(the)g(algorithm)e(to)i(remo)o(v)o(e)e -(an)o(y)h(v)o(ertices)g(whose)g(de)o(gree)g(is)1158 883 -y(greater)25 b(than)h(0)p Fu(:)p FL(1)21 b FM(\003)k -Ft(x)31 b FM(\003)23 b Fu(.)p FL(a)n(v)o(erage)c(de)o(gree\))m(.)44 -b(F)o(or)26 b(e)o(xample)e(if)29 b Ft(x)41 b FM(D)34 -b FL(40,)27 b(and)f(the)g(a)n(v)o(erage)1158 993 y(de)o(gree)18 -b(is)i(5,)f(then)g(the)g(algorithm)e(will)j(remo)o(v)o(e)e(all)h(v)o -(ertices)g(with)h(de)o(gree)d(greater)h(than)h(20.)1158 -1103 y(The)f(v)o(ertices)g(that)g(are)g(remo)o(v)o(ed)e(are)i(ordered)f -(last)i(\()p Fs(i.e)o FL(.,)g(the)o(y)f(are)g(automatically)f(placed)g -(in)1158 1212 y(the)22 b(top-le)n(v)o(el)f(separator\).)31 -b(Good)22 b(v)n(alues)g(are)h(often)f(in)g(the)h(range)f(of)g(60)g(to)h -(200)f(\()p Fs(i.e)o FL(.,)i(6)e(to)1158 1322 y(20)e(times)g(more)g -(than)f(the)h(a)n(v)o(erage\).)581 1448 y(options[7])108 -b(Used)23 b(to)g(determine)e(ho)n(w)h(man)o(y)g(separators)g(to)h -(\002nd)f(at)h(each)g(step)g(of)f(nested)h(dissection.)32 -b(The)1033 1558 y(lar)o(ger)16 b(the)i(number)d(of)i(separators)g -(found)f(at)h(each)h(step,)g(the)f(higher)f(the)h(runtime)g(and)g -(better)g(the)1033 1667 y(quality)i(is)h(\(in)f(general\).)k(The)18 -b(def)o(ault)h(v)n(alue)f(is)i(1,)f(unless)h(the)f(graph)f(has)h(been)f -(compressed)g(by)1033 1777 y(more)g(than)h(a)g(f)o(actor)g(of)f(2,)h -(in)g(which)g(case)g(it)h(becomes)e(2.)25 b(Reasonable)18 -b(v)n(alues)h(are)f(in)i(the)f(range)1033 1886 y(of)h(1)g(to)h(5.)k(F)o -(or)20 b(most)g(problems,)e(a)j(v)n(alue)e(of)h(5)h(increases)f(the)g -(runtime)f(by)h(a)g(f)o(actor)g(of)g(3.)208 2003 y FC(perm,)g(iperm)581 -2113 y FL(These)25 b(are)g(v)o(ectors,)f(each)h(of)g(size)g -Fs(n)p FL(.)39 b(Upon)24 b(successful)h(completion,)f(the)o(y)g(store)g -(the)h(\002ll-reducing)e(permu-)581 2222 y(tation)j(and)g(in)m(v)o -(erse-permutation.)39 b(Let)34 b Ft(A)29 b FL(be)d(the)g(original)f -(matrix)h(and)34 b Ft(A)2868 2192 y Fe(0)2915 2222 y -FL(be)27 b(the)f(permuted)e(matrix.)43 b(The)581 2332 -y(arrays)21 b Fs(perm)g FL(and)f Fs(iperm)h FL(are)g(de\002ned)f(as)i -(follo)n(ws.)27 b(Ro)n(w)21 b(\(column\))d Ft(i)30 b -FL(of)f Ft(A)2836 2302 y Fe(0)2878 2332 y FL(is)22 b(the)f(perm)o -FM(T)o Ft(i)9 b FM(U)20 b FL(ro)n(w)h(\(column\))e(of)589 -2441 y Ft(A)r FL(,)j(and)f(ro)n(w)g(\(column\))d Ft(i)31 -b FL(of)e Ft(A)24 b FL(is)e(the)g(iperm)n FM(T)o Ft(i)9 -b FM(U)21 b FL(ro)n(w)g(\(column\))f(of)29 b Ft(A)2659 -2411 y Fe(0)2680 2441 y FL(.)g(The)21 b(numbering)e(of)i(this)h(v)o -(ector)f(starts)581 2551 y(from)e(either)h(0)g(or)g(1,)g(depending)e -(on)i(the)g(v)n(alue)f(of)h Fs(num\003a)o(g)p FL(.)0 -2727 y FB(Note)208 2837 y FL(This)25 b(function)g(computes)f(the)i(v)o -(erte)o(x)e(separator)h(directly)g(by)g(using)g(a)h(multile)n(v)o(el)f -(algorithm.)40 b(This)26 b(function)e(produces)208 2946 -y(high)19 b(quality)g(orderings)g(and)g(should)g(be)i(preferred)d(o)o -(v)o(er)g Fz(METIS)p 2192 2946 25 4 v 31 w(EdgeND)p FL(.)1908 -5649 y(38)p eop -%%Page: 39 39 -39 38 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(NodeWND)20 -b FL(\(int)g(*n,)g(idxtype)f(*xadj,)g(idxtype)f(*adjnc)o(y)-5 -b(,)18 b(idxtype)h(*vwgt,)g(int)h(*num\003ag,)f(int)h(*options,)710 -193 y(idxtype)f(*perm,)g(idxtype)f(*iperm\))0 452 y FB(Description)208 -561 y FL(This)25 b(function)f(computes)h(\002ll)h(reducing)e(orderings) -f(of)j(sparse)f(matrices)h(using)f(the)g(multile)n(v)o(el)g(nested)g -(dissection)g(algo-)208 671 y(rithm.)f(It)19 b(is)h(similar)f(to)g -Fz(METIS)p 1171 671 V 31 w(NodeWND)h FL(b)n(ut)f(it)g(assumes)h(that)f -(the)g(compression)e(has)i(been)f(already)g(performed)f(prior)208 -780 y(to)22 b(calling)f(this)i(routine.)29 b(It)22 b(is)h(particularly) -d(suited)i(for)f(ordering)f(v)o(ery)h(lar)o(ge)g(matrices)g(in)h(which) -g(the)g(compressed)e(matrix)208 890 y(is)h(kno)n(wn)d(a)j(priori.)0 -1066 y FB(P)n(arameter)o(s)208 1186 y FC(n)327 b FL(The)20 -b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 1302 -y FC(xadj,)e(adjncy)581 1412 y FL(The)h(adjacenc)o(y)e(structure)i(of)g -(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208 -1555 y FC(vwgt)201 b FL(The)20 b(weight)g(of)g(the)g(v)o(ertices.)208 -1697 y FC(num\003ag)82 b FL(Used)22 b(to)f(indicate)g(which)g -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(adjacenc)o(y)f(structure) -g(of)h(the)g(graph.)27 b Fs(num\003a)o(g)581 1807 y FL(can)20 -b(tak)o(e)g(the)h(follo)n(wing)d(tw)o(o)j(v)n(alues:)581 -1950 y(0)83 b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h -(from)e(0)581 2076 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j -(assumed)e(that)i(starts)g(from)e(1)208 2219 y FC(options)114 -b FL(This)22 b(is)g(an)f(array)f(of)h(5)h(inte)o(gers)e(that)h(is)i -(used)e(to)g(pass)h(parameters)e(for)h(the)g(v)n(arious)f(phases)h(of)g -(the)g(algorithm.)581 2328 y(If)j Fs(options[0]=0)e FL(then)h(def)o -(ault)g(v)n(alues)g(are)h(used.)34 b(If)24 b Fs(options[0]=1)p -FL(,)f(then)g(the)g(remaining)f(four)h(elements)g(of)581 -2438 y Fs(options)c FL(are)i(interpreted)d(as)j(follo)n(ws:)581 -2581 y(options[1])108 b(Determines)20 b(the)g(matching)f(type.)24 -b(Possible)d(v)n(alues)e(are:)1033 2707 y(1)83 b(Random)19 -b(Matching)g(\(RM\))1033 2833 y(2)83 b(Hea)n(vy-Edge)18 -b(Matching)h(\(HEM\))1033 2959 y(3)83 b(Sorted)19 b(Hea)n(vy-Edge)f -(Matching)h(\(SHEM\))h(\(Def)o(ault\))1033 3086 y(Experiments)14 -b(ha)n(v)o(e)h(sho)n(wn)g(that)h(all)h(three)e(matching)f(schemes)i -(perform)e(quite)h(well.)24 b(In)16 b(general)1033 3195 -y(SHEM)22 b(is)h(f)o(aster)e(and)g(RM)i(is)f(slo)n(wer)m(,)f(b)n(ut)h -(feel)g(free)f(to)g(e)o(xperiment)f(with)i(the)f(other)g(matching)1033 -3305 y(schemes.)581 3431 y(options[2])108 b(Determines)20 -b(the)g(algorithm)f(used)g(during)g(initial)i(partitioning.)h(Possible) -f(v)n(alues)f(are:)1033 3557 y(1)83 b(Edge-based)18 b(re)o(gion)g(gro)n -(wing)h(\(Def)o(ault\))1033 3683 y(2)83 b(Node-based)18 -b(re)o(gion)h(gro)n(wing)581 3810 y(options[3])108 b(Determines)20 -b(the)g(algorithm)f(used)g(for)h(re\002nement.)k(Possible)c(v)n(alues)g -(are:)1033 3936 y(1)83 b(T)-7 b(w)o(o-sided)19 b(node)g(FM)i -(re\002nement)1033 4062 y(2)83 b(One-sided)19 b(node)g(FM)i -(re\002nement)d(\(Def)o(ault\))1033 4188 y(One-sided)i(FM)h -(re\002nement)f(is)i(f)o(aster)f(than)g(tw)o(o-sided,)f(b)n(ut)h(in)g -(some)f(cases)i(tw)o(o-sided)e(re\002ne-)1033 4298 y(ment)g(may)g -(produce)e(better)i(orderings.)j(Feel)d(free)g(to)h(e)o(xperiment)d -(with)i(this)h(option.)581 4424 y(options[4])108 b(Used)21 -b(for)e(deb)n(ugging)f(purposes.)23 b(Al)o(w)o(ays)e(set)g(it)g(to)f(0) -h(\(Def)o(ault\).)208 4541 y FC(perm,)f(iperm)581 4650 -y FL(These)25 b(are)g(v)o(ectors,)f(each)h(of)g(size)g -Fs(n)p FL(.)39 b(Upon)24 b(successful)h(completion,)f(the)o(y)g(store)g -(the)h(\002ll-reducing)e(permu-)581 4760 y(tation)j(and)g(in)m(v)o -(erse-permutation.)39 b(Let)34 b Ft(A)29 b FL(be)d(the)g(original)f -(matrix)h(and)34 b Ft(A)2868 4730 y Fe(0)2915 4760 y -FL(be)27 b(the)f(permuted)e(matrix.)43 b(The)581 4869 -y(arrays)21 b Fs(perm)g FL(and)f Fs(iperm)h FL(are)g(de\002ned)f(as)i -(follo)n(ws.)27 b(Ro)n(w)21 b(\(column\))d Ft(i)30 b -FL(of)f Ft(A)2836 4839 y Fe(0)2878 4869 y FL(is)22 b(the)f(perm)o -FM(T)o Ft(i)9 b FM(U)20 b FL(ro)n(w)h(\(column\))e(of)589 -4979 y Ft(A)r FL(,)j(and)f(ro)n(w)g(\(column\))d Ft(i)31 -b FL(of)e Ft(A)24 b FL(is)e(the)g(iperm)n FM(T)o Ft(i)9 -b FM(U)21 b FL(ro)n(w)g(\(column\))f(of)29 b Ft(A)2659 -4949 y Fe(0)2680 4979 y FL(.)g(The)21 b(numbering)e(of)i(this)h(v)o -(ector)f(starts)581 5089 y(from)e(either)h(0)g(or)g(1,)g(depending)e -(on)i(the)g(v)n(alue)f(of)h Fs(num\003a)o(g)p FL(.)1908 -5649 y(39)p eop -%%Page: 40 40 -40 39 bop 0 83 a Fr(5.7)100 b(A)m(uxiliar)q(y)28 b(Routines)0 -242 y FB(METIS)p 258 242 25 4 v 31 w(MeshT)-7 b(oNodal)20 -b FL(\(int)g(*ne,)f(int)i(*nn,)e(idxtype)g(*elmnts,)g(int)i(*etype,)d -(int)j(*num\003ag,)d(idxtype)h(*nxadj,)f(idxtype)h(*nadjnc)o(y\))0 -501 y FB(Description)208 611 y FL(This)26 b(function)f(is)i(used)f(to)g -(con)m(v)o(ert)f(a)h(mesh)g(into)g(a)h(nodal)f(graph,)g(in)g(a)h -(format)e(suitable)h(for)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p -Fz(S)r(lib)p FL(.)46 b(It)27 b(pro)o(vides)e(the)208 -721 y(function)18 b(of)i(the)g Fp(mesh2nodal)f FL(program.)0 -897 y FB(P)n(arameter)o(s)208 1016 y FC(ne)290 b FL(The)20 -b(number)e(of)i(elements)g(in)h(the)f(mesh.)208 1159 -y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g(the)g(mesh.)208 -1302 y FC(elmnts)138 b FL(The)20 b(element)g(node)f(array)g(storing)g -(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.)208 -1445 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i -(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the) -g(follo)n(wing)f(v)n(alues:)581 1587 y(1)83 b(The)20 -b(elements)f(are)i(triangles.)581 1714 y(2)83 b(The)20 -b(elements)f(are)i(tetrahedra.)581 1840 y(3)83 b(The)20 -b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 1966 -y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208 -2109 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5 -b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581 -2218 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2361 y(0)83 -b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581 -2487 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i -(starts)g(from)e(1)208 2604 y FC(nxadj,)g(nadjncy)581 -2714 y FL(These)29 b(arrays)f(store)g(the)h(adjacenc)o(y)e(structure)h -(of)g(the)h(nodal)e(graph.)49 b(The)29 b(user)f(must)h(pro)o(vide)d -(arrays)i(that)581 2823 y(are)c(suf)n(\002ciently)g(lar)o(ge)f(to)i -(store)f(the)g(graph.)36 b(The)24 b(size)h(of)f(array)f -Fs(nxadj)h FL(is)h Fs(nn+1)e FL(where)h(the)g(size)h(of)f -Fs(nadjncy)581 2933 y FL(depends)i(on)g(the)h(type)f(of)h(the)g(mesh.) -44 b(F)o(or)27 b(triangular)n(-element)d(and)i(he)o(xahedra-element)d -(meshes,)28 b Fs(nadjncy)581 3042 y FL(should)19 b(be)g(at)h(least)h(6) -15 b FM(\003)h Fs(nn)o FL(,)k(for)f(quadrilateral-element)e(meshes,)i -Fs(nadjncy)f FL(should)g(be)i(at)g(least)g(4)c FM(\003)g -Fs(nn)o FL(,)k(and)f(for)581 3152 y(tetrahedra-element)e(meshes,)j -Fs(nadjncy)f FL(should)g(be)h(at)h(least)g(15)c FM(\003)i -Fs(nn)o FL(.)0 3328 y FB(Note)208 3438 y FL(The)k(nodal)h(graph)e(is)k -(de\002ned)d(as)i(the)f(graph)f(in)h(which)g(each)g(v)o(erte)o(x)e(of)i -(the)h(graph)d(corresponds)g(to)j(a)f(node)f(in)i(the)f(mesh,)208 -3547 y(and)19 b(tw)o(o)i(v)o(ertices)e(are)h(connected)f(by)h(an)g -(edge)f(if)i(the)f(corresponding)d(nodes)i(a)i(connected)d(by)i(an)g -(element.)1908 5649 y(40)p eop -%%Page: 41 41 -41 40 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(MeshT)-7 -b(oDual)20 b FL(\(int)g(*ne,)g(int)g(*nn,)f(idxtype)g(*elmnts,)g(int)i -(*etype,)e(int)h(*num\003ag,)e(idxtype)h(*dxadj,)g(idxtype)f(*dadjnc)o -(y\))0 342 y FB(Description)208 452 y FL(This)28 b(function)e(is)j -(used)f(to)h(con)m(v)o(ert)d(a)i(mesh)g(into)g(a)h(dual)f(graph,)g(in)g -(a)h(format)e(suitable)h(for)i Fz(M)l FG(E)-17 b Fz(T)g -FG(I)p Fz(S)r(lib)p FL(.)52 b(It)28 b(pro)o(vides)f(the)208 -561 y(function)18 b(of)i(the)g Fp(mesh2nodal)f FL(program.)0 -737 y FB(P)n(arameter)o(s)208 857 y FC(ne)290 b FL(The)20 -b(number)e(of)i(elements)g(in)h(the)f(mesh.)208 1000 -y FC(nn)281 b FL(The)20 b(number)e(of)i(nodes)g(in)g(the)g(mesh.)208 -1142 y FC(elmnts)138 b FL(The)20 b(element)g(node)f(array)g(storing)g -(the)i(mesh)f(as)h(described)d(in)j(Section)f(5.2.)208 -1285 y FC(etype)183 b FL(Indicates)20 b(the)g(type)g(of)f(the)i -(elements)f(in)g(the)g(mesh.)25 b Fs(etype)20 b FL(can)g(tak)o(e)g(the) -g(follo)n(wing)f(v)n(alues:)581 1428 y(1)83 b(The)20 -b(elements)f(are)i(triangles.)581 1554 y(2)83 b(The)20 -b(elements)f(are)i(tetrahedra.)581 1680 y(3)83 b(The)20 -b(elements)f(are)i(he)o(xahedra)c(\(bricks\).)581 1807 -y(4)83 b(The)20 b(elements)f(are)i(quadrilaterals.)208 -1949 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5 -b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581 -2059 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 2202 y(0)83 -b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581 -2328 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i -(starts)g(from)e(1)208 2445 y FC(dxadj,)g(dadjncy)581 -2554 y FL(These)31 b(arrays)g(store)g(the)g(adjacenc)o(y)e(structure)h -(of)h(the)g(dual)g(graph.)56 b(The)31 b(user)g(must)g(pro)o(vide)e -(arrays)h(that)581 2664 y(are)25 b(suf)n(\002ciently)e(lar)o(ge)h(to)g -(store)h(the)f(graph.)37 b(The)24 b(size)h(of)g(array)e -Fs(dxadj)h FL(is)h Fs(ne+1)f FL(where)g(the)h(size)g(of)f -Fs(dadjncy)581 2773 y FL(depends)e(on)g(the)h(type)f(of)h(the)g(mesh.) -33 b(F)o(or)22 b(triangular)n(-element)e(meshes,)j Fs(dadjncy)f -FL(should)f(be)i(at)h(least)f(3)d FM(\003)h Fs(ne)o FL(,)581 -2883 y(for)i(tetrahedra-element)d(and)j(quadrilateral-element)d -(meshes,)j Fs(dadjncy)f FL(should)g(be)i(at)f(least)h(4)d -FM(\003)g Fs(ne)o FL(,)j(and)f(for)581 2993 y(he)o(xahedra-element)16 -b(meshes,)k Fs(dadjncy)f FL(should)g(be)h(at)h(least)g(6)d -FM(\003)g Fs(ne)p FL(.)0 3169 y FB(Note)208 3278 y FL(The)h(dual)f -(graph)g(is)j(de\002ned)d(as)i(the)g(graph)e(in)h(which)g(each)g(v)o -(erte)o(x)f(of)h(the)g(graph)f(corresponds)f(to)j(an)f(element)g(in)h -(the)f(mesh,)208 3388 y(and)g(tw)o(o)i(v)o(ertices)e(are)h(connected)f -(by)h(an)g(edge)f(if)i(the)f(corresponding)d(elements)j(share)f(a)i(f)o -(ace.)1908 5649 y(41)p eop -%%Page: 42 42 -42 41 bop 0 83 a FB(METIS)p 258 83 25 4 v 31 w(EstimateMemor)q(y)21 -b FL(\(int)f(*n,)f(idxtype)g(*xadj,)g(int)h(*adjnc)o(y)-5 -b(,)18 b(int)i(*num\003ag,)f(int)h(*optype,)e(int)j(*nbytes\))0 -342 y FB(Description)208 452 y FL(This)d(function)e(is)j(used)e(to)h -(estimate)g(the)g(amount)f(of)g(memory)g(that)h(will)g(be)g(used)g(by)h -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r FL(.)20 b(Ev)o(en)d(though,)h -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)22 b FL(dynam-)208 -561 y(ically)f(allocates)g(the)g(amount)f(of)g(memory)g(that)h(it)h -(needs,)e(this)i(function)d(can)i(be)g(useful)g(in)g(determining)e(if)i -(the)g(amount)f(of)208 671 y(memory)e(in)i(the)h(system)f(is)h(suf)n -(\002cient)f(for)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r -FL(.)0 847 y FB(P)n(arameter)o(s)208 966 y FC(n)327 b -FL(The)20 b(number)e(of)i(v)o(ertices)g(in)g(the)h(graph.)208 -1083 y FC(xadj,)e(adjncy)581 1193 y FL(The)h(adjacenc)o(y)e(structure)i -(of)g(the)g(graph)f(as)i(described)d(in)j(Section)f(5.1.)208 -1335 y FC(num\003ag)82 b FL(Used)22 b(to)h(indicate)e(which)h -(numbering)d(scheme)j(is)h(used)f(for)g(the)g(element)f(node)g(array)-5 -b(.)30 b Fs(num\003a)o(g)20 b FL(can)i(tak)o(e)h(the)581 -1445 y(follo)n(wing)c(tw)o(o)h(v)n(alues:)581 1588 y(0)83 -b(C-style)20 b(numbering)e(is)j(assumed)f(that)g(starts)h(from)e(0)581 -1714 y(1)83 b(F)o(ortran-style)18 b(numbering)g(is)j(assumed)e(that)i -(starts)g(from)e(1)208 1857 y FC(optype)132 b FL(Indicates)15 -b(the)h(operation)d(for)i(which)g(the)h(memory)e(will)i(be)g -(estimated.)23 b Fs(optype)14 b FL(can)i(tak)o(e)f(the)h(follo)n(wing)e -(v)n(alues:)581 2000 y(1)83 b(Estimates)15 b(the)h(memory)d(needed)h -(for)h Fz(METIS)p 2076 2000 V 30 w(P)m(ar)s(tGr)o(aphRecursiv)n(e)g -FL(and)g Fz(METIS)p 3260 2000 V 30 w(WP)m(ar)s(tGr)o(aphRecursiv)n(e)p -FL(.)581 2126 y(2)83 b(Estimates)20 b(the)h(memory)d(needed)h(for)g -Fz(METIS)p 2100 2126 V 31 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)h -FL(and)g Fz(METIS)p 3127 2126 V 30 w(WP)m(ar)s(tGr)o(aphKw)o(a)n(y)p -FL(.)581 2252 y(3)83 b(Estimates)20 b(the)h(memory)d(needed)h(for)g -Fz(METIS)p 2100 2252 V 31 w(EdgeND)p FL(.)581 2378 y(4)83 -b(Estimates)25 b(the)g(memory)d(needed)i(for)g Fz(METIS)p -2123 2378 V 30 w(NodeND)p FL(,)i(b)n(ut)e(it)i(does)e(not)h(tak)o(e)f -(into)h(account)e(memory)706 2488 y(sa)n(v)o(ed)d(due)f(to)i -(compression.)208 2631 y FC(nbytes)142 b FL(Upon)19 b(return,)g -Fs(nbytes)h FL(stores)g(an)h(estimate)f(on)g(the)g(number)e(of)i(bytes) -g(that)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)24 b FL(requires.)1908 -5649 y(42)p eop -%%Page: 43 43 -43 42 bop 0 83 a Fr(5.8)100 b(C)28 b(and)g(For)r(tran)f(Suppor)r(t)0 -242 y FL(The)g(v)n(arious)g(routines)f(in)k Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)r(lib)31 b FL(can)c(be)h(called)f(from)g(either)g -(C)h(or)f(F)o(ortran)g(programs.)45 b(Using)27 b(C)i(with)h -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)30 b FL(is)f(quite)0 -352 y(straightforw)o(ard)24 b(\(as)30 b Fz(M)l FG(E)-17 -b Fz(T)g FG(I)p Fz(S)31 b FL(is)d(written)f(entirely)f(in)h(C\).)g(Ho)n -(we)n(v)o(er)m(,)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)31 -b FL(fully)26 b(supports)g(F)o(ortran)g(as)h(well.)46 -b(This)27 b(support)0 462 y(comes)20 b(in)g(three)g(forms.)104 -638 y(1.)41 b(All)20 b(the)h(scalar)f(ar)o(guments)e(in)i(the)h -(routines)e(are)h(passed)g(by)g(reference)e(to)j(f)o(acilitate)f(F)o -(ortran)f(programs.)104 814 y(2.)41 b(All)22 b(the)g(routines)f(tak)o -(e)h(a)h(parameter)d(called)i Fs(num\003a)o(g)e FL(indicating)h -(whether)g(or)h(not)f(the)h(numbering)e(of)h(the)h(graph)f(or)h(mesh) -208 923 y(starts)28 b(from)e(0)h(or)g(1.)46 b(In)27 b(C)h(programs)e -(numbering)e(usually)j(starts)h(from)e(0,)j(whereas)e(in)g(F)o(ortran)f -(programs)f(numbering)208 1033 y(starts)c(from)e(1.)104 -1209 y(3.)43 b Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)21 -b FL(incorporates)c(alternati)n(v)o(e)g(names)i(for)f(each)g(of)g(the)h -(routines)e(to)i(f)o(acilitate)g(linking)e(the)i(library)f(with)g(F)o -(ortran)g(pro-)208 1318 y(grams.)29 b(In)22 b(particular)m(,)f(for)g(e) -n(v)o(ery)g(function)h Fz(M)l FG(E)-17 b Fz(T)g FG(I)p -Fz(S)r(lib)25 b FL(pro)o(vides)c(three)g(additional)g(names,)h(one)f -(all)i(capital,)f(one)f(all)i(lo)n(wer)208 1428 y(case,)f(and)g(one)f -(all)i(lo)n(wer)e(case)h(with)h(`)p 1363 1428 25 4 v -29 w(')f(appended)e(to)i(it.)31 b(F)o(or)22 b(e)o(xample,)e(for)i -Fz(METIS)p 2801 1428 V 30 w(P)m(ar)s(tGr)o(aphKw)o(a)n(y)p -FL(,)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)r(lib)26 -b FL(pro-)208 1538 y(vides)c Fz(METIS)p 664 1538 V 30 -w(P)-10 b(AR)n(TGRAPHKW)l(A)i(Y)p FL(,)24 b Fz(metis)p -1672 1538 V 30 w(par)s(tg)o(r)o(aphkw)o(a)n(y)p FL(,)f(and)e -Fz(metis)p 2629 1538 V 31 w(par)s(tg)o(r)o(aphkw)o(a)n(y)p -3203 1538 V 29 w FL(.)31 b(These)22 b(e)o(xtra)g(names)208 -1647 y(allo)n(w)j(the)h(library)f(to)h(be)g(directly)f(link)o(ed)g -(into)g(F)o(ortran)g(programs)f(on)h(a)i(wide)e(range)g(of)h -(architectures)e(including)g(Cray)-5 b(,)208 1757 y(SGI,)20 -b(and)h(HP)-9 b(.)21 b(If)f(you)g(still)i(encounter)d(problems)g -(linking)h(with)h(the)g(library)f(let)h(us)g(kno)n(w)f(so)h(we)g(can)g -(include)f(appropriate)208 1866 y(support.)1908 5649 -y(43)p eop -%%Page: 44 44 -44 43 bop 0 85 a FD(6)116 b(System)31 b(Requirements)g(and)h(Contact)f -(Inf)n(ormation)0 261 y FL(The)24 b(distrib)n(ution)g(of)i -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)30 b FL(contains)24 -b(a)h(number)e(of)h(\002les,)j(that)e(total)g(to)g(o)o(v)o(er)e(22,000) -g(lines)i(of)f(code.)38 b(It)25 b(is)h(written)e(entirely)g(in)0 -370 y(ANSI)f(C,)h(and)e(is)i(portable)e(on)g(most)h(Unix)g(systems)g -(that)g(ha)n(v)o(e)f(an)h(ANSI)g(C)h(compiler)e(\(the)g(GNU)i(C)g -(compiler)d(will)j(do\).)32 b(It)23 b(has)0 480 y(been)17 -b(e)o(xtensi)n(v)o(ely)g(tested)h(on)g(AIX,)g(SunOS,)f(Solaris,)i -(IRIX,)f(Linux,)f(HP-UX,)h(BSD,)h(and)f(Unicos.)24 b(Instructions)16 -b(on)i(ho)n(w)g(to)g(b)n(uild)0 590 y(and)i(install)i -Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 b FL(can)20 b(be)g(found)e(in)j -(the)f(\002le)h Fp(INSTALL)e FL(of)h(the)g(distrib)n(ution.)100 -699 y(Ev)o(en)d(though,)i Fz(M)l FG(E)-17 b Fz(T)g FG(I)p -Fz(S)23 b FL(contains)18 b(no)h(kno)n(wn)e(b)n(ugs,)h(it)i(does)e(not)h -(mean)f(that)h(all)g(of)f(its)i(b)n(ugs)f(ha)n(v)o(e)f(been)g(found)f -(and)h(\002x)o(ed.)24 b(If)18 b(you)0 809 y(\002nd)24 -b(an)o(y)f(problems,)g(please)h(send)f(email)h(to)g Fs -(metis@cs.umn.edu)p FL(,)g(with)g(a)g(brief)f(description)g(of)g(the)h -(problem)e(you)h(ha)n(v)o(e)h(found.)0 918 y(Also,)c(an)o(y)g(future)f -(updates)g(to)j Fz(M)l FG(E)-17 b Fz(T)g FG(I)p Fz(S)25 -b FL(will)c(be)f(made)g(a)n(v)n(ailable)f(on)h(WWW)i(at)f -Fs(http://www)-6 b(.cs.umn.edu/\230metis)p FL(.)0 1164 -y FD(Ref)o(erences)37 1331 y FK([1])42 b(Stephen)26 b(T)-6 -b(.)26 b(Barnard)g(and)g(Horst)g(D.)f(Simon.)49 b(A)25 -b(f)o(ast)h(multile)n(v)o(el)g(implementation)g(of)g(recursi)n(v)o(e)g -(spectral)g(bisection)h(for)e(partitioning)166 1431 y(unstructured)d -(problems.)34 b(In)21 b FJ(Pr)m(oceedings)h(of)e(the)h(sixth)g(SIAM)g -(confer)m(ence)i(on)e(P)-6 b(ar)o(allel)20 b(Pr)m(ocessing)i(for)e -(Scienti\002c)i(Computing)p FK(,)g(pages)166 1532 y(711\226718,)f -(1993.)37 1649 y([2])42 b(A.)19 b(Geor)o(ge)h(and)h(J.)e(W)-7 -b(.-H.)18 b(Liu.)29 b FJ(Computer)21 b(Solution)f(of)g(Lar)m(g)o(e)h -(Spar)o(se)g(P)-6 b(ositive)19 b(De\002nite)h(Systems)p -FK(.)30 b(Prentice-Hall,)19 b(Engle)n(w)o(ood)i(Clif)n(fs,)166 -1749 y(NJ,)d(1981.)37 1866 y([3])42 b(Anshul)d(Gupta,)44 -b(Geor)o(ge)39 b(Karypis,)44 b(and)c(V)l(ipin)e(K)o(umar)l(.)91 -b(Highly)39 b(scalable)g(parallel)g(algorithms)g(for)g(sparse)g(matrix) -f(f)o(actoriza-)166 1967 y(tion.)64 b FJ(IEEE)30 b(T)l(r)o(ansactions)h -(on)g(P)-6 b(ar)o(allel)30 b(and)i(Distrib)o(uted)e(Systems)p -FK(,)k(8\(5\):502\226520,)i(May)31 b(1997.)66 b(A)-6 -b(v)n(ailable)31 b(on)g(WWW)e(at)i(URL)166 2067 y(http://www)-5 -b(.cs.umn.edu/\230karypis.)37 2184 y([4])42 b(Bruce)15 -b(Hendrickson)i(and)f(Robert)f(Leland.)k(The)c(chaco)h(user')l(s)f -(guide,)h(v)o(ersion)g(1.0.)i(T)-5 b(echnical)16 b(Report)f -(SAND93-2339,)h(Sandia)g(National)166 2285 y(Laboratories,)j(1993.)37 -2402 y([5])42 b(Bruce)26 b(Hendrickson)h(and)f(Robert)g(Leland.)48 -b(A)25 b(multile)n(v)o(el)g(algorithm)h(for)g(partitioning)g(graphs.)49 -b(T)-5 b(echnical)25 b(Report)h(SAND93-1301,)166 2502 -y(Sandia)19 b(National)g(Laboratories,)g(1993.)37 2619 -y([6])42 b(G.)30 b(Karypis)g(and)h(V)-10 b(.)30 b(K)o(umar)l(.)62 -b(Multile)n(v)o(el)31 b(algorithms)f(for)g(multi-constraint)g(graph)i -(partitioning.)63 b(T)-5 b(echnical)30 b(Report)g(TR)g(98-019,)166 -2720 y(Department)19 b(of)g(Computer)h(Science,)f(Uni)n(v)o(ersity)g -(of)g(Minnesota,)h(1998.)37 2837 y([7])42 b(G.)24 b(Karypis)h(and)g(V) --10 b(.)24 b(K)o(umar)l(.)44 b(Multile)n(v)o(el)25 b(k-w)o(ay)g -(partitioning)g(scheme)g(for)f(irre)o(gular)g(graphs.)46 -b FJ(J)n(ournal)26 b(of)e(P)-6 b(ar)o(allel)24 b(and)h(Distrib)o(uted) -166 2937 y(Computing)p FK(,)19 b(48\(1\):96\226129,)j(1998.)28 -b(Also)18 b(a)o(v)n(ailable)i(on)f(WWW)e(at)i(URL)f(http://www)-5 -b(.cs.umn.edu/\230karypis.)37 3055 y([8])42 b(G.)23 b(Karypis)h(and)g -(V)-10 b(.)23 b(K)o(umar)l(.)42 b(A)23 b(f)o(ast)h(and)g(highly)g -(quality)g(multile)n(v)o(el)f(scheme)i(for)e(partitioning)h(irre)o -(gular)f(graphs.)43 b FJ(SIAM)23 b(J)n(ournal)i(on)166 -3155 y(Scienti\002c)f(Computing)p FK(,)g(1998)g(\(to)f(appear\).)40 -b(Also)23 b(a)o(v)n(ailable)g(on)h(WWW)d(at)i(URL)f(http://www)-5 -b(.cs.umn.edu/\230karypis.)23 b(A)g(short)g(v)o(ersion)166 -3255 y(appears)d(in)f(Intl.)f(Conf.)h(on)g(P)o(arallel)f(Processing)h -(1995.)37 3372 y([9])42 b(Geor)o(ge)21 b(Karypis,)f(Rajat)g(Aggarw)o -(al,)h(V)l(ipin)f(K)o(umar)m(,)g(and)i(Shashi)e(Shekhar)l(.)32 -b(Multile)n(v)o(el)20 b(hyper)o(graph)i(partitioning:)27 -b(Application)21 b(in)f(vlsi)166 3473 y(domain.)28 b(In)19 -b FJ(Pr)m(oceedings)g(of)g(the)g(Design)h(and)f(A)o(utomation)g(Confer) -m(ence)p FK(,)h(1997.)0 3590 y([10])42 b(V)l(ipin)19 -b(K)o(umar)m(,)h(Ananth)g(Grama,)f(Anshul)i(Gupta,)e(and)i(Geor)o(ge)e -(Karypis.)30 b FJ(Intr)m(oduction)20 b(to)g(P)-6 b(ar)o(allel)19 -b(Computing:)25 b(Design)20 b(and)h(Analysis)166 3690 -y(of)e(Algorithms)p FK(.)27 b(Benjamin/Cummings)20 b(Publishing)f -(Compan)o(y)-5 b(,)20 b(Redw)o(ood)g(City)-5 b(,)19 b(CA,)f(1994.)1908 -5649 y FL(44)p eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF diff --git a/Metis/Makefile b/Metis/Makefile deleted file mode 100644 index d087657867..0000000000 --- a/Metis/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -# $Id: Makefile,v 1.2 2005-09-11 02:08:40 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshMetis.a -INCLUDE = -I. -CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} - -SRC = balance.c \ - fm.c \ - kwayfm.c \ - mcoarsen.c \ - minitpart2.c \ - mpmetis.c \ - pmetis.c \ - subdomains.c\ - bucketsort.c \ - fortran.c \ - kwayrefine.c\ - memory.c \ - minitpart.c \ - mrefine2.c\ - pqueue.c\ - timing.c\ - ccgraph.c \ - frename.c \ - kwayvolfm.c\ - mesh.c\ - mkmetis.c\ - mrefine.c \ - refine.c \ - util.c\ - coarsen.c \ - graph.c\ - kwayvolrefine.c \ - meshpart.c \ - mkwayfmh.c \ - mutil.c \ - separator.c\ - compress.c\ - initpart.c\ - match.c\ - mfm2.c \ - mkwayrefine.c\ - myqsort.c\ - sfm.c\ - debug.c \ - kmetis.c \ - mbalance2.c\ - mfm.c \ - mmatch.c \ - ometis.c \ - srefine.c\ - estmem.c \ - kvmetis.c\ - mbalance.c \ - mincover.c \ - mmd.c \ - parmetis.c \ - stat.c - -OBJ = ${SRC:.c=.o} - -.SUFFIXES: .o .c - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.c.o: - ${CC} ${CFLAGS} -c $< -o ${<:.c=.o} - -clean: - rm -f *.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE diff --git a/Metis/Makefile.in b/Metis/Makefile.in deleted file mode 100644 index d9a7f9cc67..0000000000 --- a/Metis/Makefile.in +++ /dev/null @@ -1,22 +0,0 @@ - -# Which compiler to use -CC = cc - -# What optimization level to use -OPTFLAGS = -O2 - -# What options to be used by the compiler -COPTIONS = - -# What options to be used by the loader -LDOPTIONS = - -# What archiving to use -AR = ar rv - -# What to use for indexing the archive -RANLIB = ranlib -#RANLIB = ar -ts -#RANLIB = - - diff --git a/Metis/Makefile~ b/Metis/Makefile~ deleted file mode 100644 index 3e96298675..0000000000 --- a/Metis/Makefile~ +++ /dev/null @@ -1,114 +0,0 @@ -# $Id: Makefile~,v 1.1 2005-09-21 15:03:47 remacle Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshANN.a -INCLUDE = -I../Common -I./include/ -CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} -DNO_PARALLEL_THREADS -UWIN32 - -SRC = src/ANN.cpp\ - src/bd_fix_rad_search.cpp\ -src/bd_pr_search.cpp\ -src/bd_search.cpp\ -src/bd_tree.cpp\ -src/brute.cpp\ -src/kd_dump.cpp\ -src/kd_fix_rad_search.cpp\ -src/kd_pr_search.cpp\ -src/kd_search.cpp\ -src/kd_split.cpp\ -src/kd_tree.cpp\ -src/kd_util.cpp\ -src/perf.cpp - -OBJ = ${SRC:.cpp=.o} - -.SUFFIXES: .o .cpp - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.cpp.o: - ${CXX} ${CFLAGS} -c $< -o ${<:.cpp=.o} - -clean: - rm -f src/*.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -# 1 "/Users/geuzaine/.gmsh/ANN//" -ANN.o: src/ANN.cpp include/ANN/ANNx.h include/ANN/ANN.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_fix_rad_search.o: src/bd_fix_rad_search.cpp src/bd_tree.h \ - include/ANN/ANNx.h include/ANN/ANN.h src/kd_tree.h \ - src/kd_fix_rad_search.h src/kd_util.h src/pr_queue_k.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_pr_search.o: src/bd_pr_search.cpp src/bd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_tree.h src/kd_pr_search.h src/kd_util.h \ - src/pr_queue.h include/ANN/ANNperf.h src/pr_queue_k.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_search.o: src/bd_search.cpp src/bd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_tree.h src/kd_search.h src/kd_util.h \ - src/pr_queue_k.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -bd_tree.o: src/bd_tree.cpp src/bd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_tree.h src/kd_util.h src/kd_split.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -brute.o: src/brute.cpp include/ANN/ANNx.h include/ANN/ANN.h \ - src/pr_queue_k.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_dump.o: src/kd_dump.cpp src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/bd_tree.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_fix_rad_search.o: src/kd_fix_rad_search.cpp src/kd_fix_rad_search.h \ - src/kd_tree.h include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h \ - src/pr_queue_k.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_pr_search.o: src/kd_pr_search.cpp src/kd_pr_search.h src/kd_tree.h \ - include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h src/pr_queue.h \ - include/ANN/ANNperf.h src/pr_queue_k.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_search.o: src/kd_search.cpp src/kd_search.h src/kd_tree.h \ - include/ANN/ANNx.h include/ANN/ANN.h src/kd_util.h src/pr_queue_k.h \ - include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_split.o: src/kd_split.cpp src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_util.h src/kd_split.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_tree.o: src/kd_tree.cpp src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h src/kd_split.h src/kd_util.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -kd_util.o: src/kd_util.cpp src/kd_util.h src/kd_tree.h include/ANN/ANNx.h \ - include/ANN/ANN.h include/ANN/ANNperf.h -# 1 "/Users/geuzaine/.gmsh/ANN//" -perf.o: src/perf.cpp include/ANN/ANN.h include/ANN/ANNperf.h diff --git a/Metis/balance.c b/Metis/balance.c deleted file mode 100644 index b5fc3d50ea..0000000000 --- a/Metis/balance.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * balance.c - * - * This file contains code that is used to forcefully balance either - * bisections or k-sections - * - * Started 7/29/97 - * George - * - * $Id: balance.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function is the entry point of the bisection balancing algorithms. -**************************************************************************/ -void Balance2Way(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - int i, j, nvtxs, from, imax, gain, mindiff; - idxtype *id, *ed; - - /* Return right away if the balance is OK */ - mindiff = abs(tpwgts[0]-graph->pwgts[0]); - if (mindiff < 3*(graph->pwgts[0]+graph->pwgts[1])/graph->nvtxs) - return; - if (graph->pwgts[0] > tpwgts[0] && graph->pwgts[0] < (int)(ubfactor*tpwgts[0])) - return; - if (graph->pwgts[1] > tpwgts[1] && graph->pwgts[1] < (int)(ubfactor*tpwgts[1])) - return; - - if (graph->nbnd > 0) - Bnd2WayBalance(ctrl, graph, tpwgts); - else - General2WayBalance(ctrl, graph, tpwgts); - -} - - - -/************************************************************************* -* This function balances two partitions by moving boundary nodes -* from the domain that is overweight to the one that is underweight. -**************************************************************************/ -void Bnd2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts) -{ - int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, tmp; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts; - idxtype *moved, *perm; - PQueueType parts; - int higain, oldgain, mincut, mindiff; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - pwgts = graph->pwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - - /* Determine from which domain you will be moving data */ - mindiff = abs(tpwgts[0]-pwgts[0]); - from = (pwgts[0] < tpwgts[0] ? 1 : 0); - to = (from+1)%2; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n", - pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]; - PQueueInit(ctrl, &parts, nvtxs, tmp); - - idxset(nvtxs, -1, moved); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert the boundary nodes of the proper partition whose size is OK in the priority queue */ - nbnd = graph->nbnd; - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = perm[ii]; - ASSERT(ed[bndind[i]] > 0 || id[bndind[i]] == 0); - ASSERT(bndptr[bndind[i]] != -1); - if (where[bndind[i]] == from && vwgt[bndind[i]] <= mindiff) - PQueueInsert(&parts, bndind[i], ed[bndind[i]]-id[bndind[i]]); - } - - mincut = graph->mincut; - for (nswaps=0; nswaps<nvtxs; nswaps++) { - if ((higain = PQueueGetMax(&parts)) == -1) - break; - ASSERT(bndptr[higain] != -1); - - if (pwgts[to]+vwgt[higain] > tpwgts[to]) - break; - - mincut -= (ed[higain]-id[higain]); - INC_DEC(pwgts[to], pwgts[from], vwgt[higain]); - - where[higain] = to; - moved[higain] = nswaps; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1])); - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update its boundary information and queue position */ - if (bndptr[k] != -1) { /* If k was a boundary vertex */ - if (ed[k] == 0) { /* Not a boundary vertex any more */ - BNDDelete(nbnd, bndind, bndptr, k); - if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff) /* Remove it if in the queues */ - PQueueDelete(&parts, k, oldgain); - } - else { /* If it has not been moved, update its position in the queue */ - if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff) - PQueueUpdate(&parts, k, oldgain, ed[k]-id[k]); - } - } - else { - if (ed[k] > 0) { /* It will now become a boundary vertex */ - BNDInsert(nbnd, bndind, bndptr, k); - if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff) - PQueueInsert(&parts, k, ed[k]-id[k]); - } - } - } - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - PQueueFree(ctrl, &parts); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function balances two partitions by moving the highest gain -* (including negative gain) vertices to the other domain. -* It is used only when tha unbalance is due to non contigous -* subdomains. That is, the are no boundary vertices. -* It moves vertices from the domain that is overweight to the one that -* is underweight. -**************************************************************************/ -void General2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts) -{ - int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, tmp; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts; - idxtype *moved, *perm; - PQueueType parts; - int higain, oldgain, mincut, mindiff; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - pwgts = graph->pwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - - /* Determine from which domain you will be moving data */ - mindiff = abs(tpwgts[0]-pwgts[0]); - from = (pwgts[0] < tpwgts[0] ? 1 : 0); - to = (from+1)%2; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n", - pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]; - PQueueInit(ctrl, &parts, nvtxs, tmp); - - idxset(nvtxs, -1, moved); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert the nodes of the proper partition whose size is OK in the priority queue */ - RandomPermute(nvtxs, perm, 1); - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - if (where[i] == from && vwgt[i] <= mindiff) - PQueueInsert(&parts, i, ed[i]-id[i]); - } - - mincut = graph->mincut; - nbnd = graph->nbnd; - for (nswaps=0; nswaps<nvtxs; nswaps++) { - if ((higain = PQueueGetMax(&parts)) == -1) - break; - - if (pwgts[to]+vwgt[higain] > tpwgts[to]) - break; - - mincut -= (ed[higain]-id[higain]); - INC_DEC(pwgts[to], pwgts[from], vwgt[higain]); - - where[higain] = to; - moved[higain] = nswaps; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1])); - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update the queue position */ - if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff) - PQueueUpdate(&parts, k, oldgain, ed[k]-id[k]); - - /* Update its boundary information */ - if (ed[k] == 0 && bndptr[k] != -1) - BNDDelete(nbnd, bndind, bndptr, k); - else if (ed[k] > 0 && bndptr[k] == -1) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - PQueueFree(ctrl, &parts); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} diff --git a/Metis/bucketsort.c b/Metis/bucketsort.c deleted file mode 100644 index 8f44b66bb9..0000000000 --- a/Metis/bucketsort.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * bucketsort.c - * - * This file contains code that implement a variety of counting sorting - * algorithms - * - * Started 7/25/97 - * George - * - * $Id: bucketsort.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - - -/************************************************************************* -* This function uses simple counting sort to return a permutation array -* corresponding to the sorted order. The keys are assumed to start from -* 0 and they are positive. This sorting is used during matching. -**************************************************************************/ -void BucketSortKeysInc(int n, int max, idxtype *keys, idxtype *tperm, idxtype *perm) -{ - int i, ii; - idxtype *counts; - - counts = idxsmalloc(max+2, 0, "BucketSortKeysInc: counts"); - - for (i=0; i<n; i++) - counts[keys[i]]++; - MAKECSR(i, max+1, counts); - - for (ii=0; ii<n; ii++) { - i = tperm[ii]; - perm[counts[keys[i]]++] = i; - } - - free(counts); -} - diff --git a/Metis/ccgraph.c b/Metis/ccgraph.c deleted file mode 100644 index b1def86912..0000000000 --- a/Metis/ccgraph.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * ccgraph.c - * - * This file contains the functions that create the coarse graph - * - * Started 8/11/97 - * George - * - * $Id: ccgraph.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - - -/************************************************************************* -* This function creates the coarser graph -**************************************************************************/ -void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm) -{ - int i, j, jj, k, kk, l, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, mask, dovsize; - idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj; - idxtype *cmap, *htable; - idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum; - float *nvwgt, *cnvwgt; - GraphType *cgraph; - - dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0); - - mask = HTLENGTH; - if (cnvtxs < 8*mask || graph->nedges/graph->nvtxs > 15) { - CreateCoarseGraphNoMask(ctrl, graph, cnvtxs, match, perm); - return; - } - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - vwgt = graph->vwgt; - vsize = graph->vsize; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - cmap = graph->cmap; - - /* Initialize the coarser graph */ - cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize); - cxadj = cgraph->xadj; - cvwgt = cgraph->vwgt; - cvsize = cgraph->vsize; - cnvwgt = cgraph->nvwgt; - cadjwgtsum = cgraph->adjwgtsum; - cadjncy = cgraph->adjncy; - cadjwgt = cgraph->adjwgt; - - - iend = xadj[nvtxs]; - auxadj = ctrl->wspace.auxcore; - memcpy(auxadj, adjncy, iend*sizeof(idxtype)); - for (i=0; i<iend; i++) - auxadj[i] = cmap[auxadj[i]]; - - htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1)); - - cxadj[0] = cnvtxs = cnedges = 0; - for (i=0; i<nvtxs; i++) { - v = perm[i]; - if (cmap[v] != cnvtxs) - continue; - - u = match[v]; - if (ncon == 1) - cvwgt[cnvtxs] = vwgt[v]; - else - scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon); - - if (dovsize) - cvsize[cnvtxs] = vsize[v]; - - cadjwgtsum[cnvtxs] = adjwgtsum[v]; - nedges = 0; - - istart = xadj[v]; - iend = xadj[v+1]; - for (j=istart; j<iend; j++) { - k = auxadj[j]; - kk = k&mask; - if ((m = htable[kk]) == -1) { - cadjncy[nedges] = k; - cadjwgt[nedges] = adjwgt[j]; - htable[kk] = nedges++; - } - else if (cadjncy[m] == k) { - cadjwgt[m] += adjwgt[j]; - } - else { - for (jj=0; jj<nedges; jj++) { - if (cadjncy[jj] == k) { - cadjwgt[jj] += adjwgt[j]; - break; - } - } - if (jj == nedges) { - cadjncy[nedges] = k; - cadjwgt[nedges++] = adjwgt[j]; - } - } - } - - if (v != u) { - if (ncon == 1) - cvwgt[cnvtxs] += vwgt[u]; - else - saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1); - - if (dovsize) - cvsize[cnvtxs] += vsize[u]; - - cadjwgtsum[cnvtxs] += adjwgtsum[u]; - - istart = xadj[u]; - iend = xadj[u+1]; - for (j=istart; j<iend; j++) { - k = auxadj[j]; - kk = k&mask; - if ((m = htable[kk]) == -1) { - cadjncy[nedges] = k; - cadjwgt[nedges] = adjwgt[j]; - htable[kk] = nedges++; - } - else if (cadjncy[m] == k) { - cadjwgt[m] += adjwgt[j]; - } - else { - for (jj=0; jj<nedges; jj++) { - if (cadjncy[jj] == k) { - cadjwgt[jj] += adjwgt[j]; - break; - } - } - if (jj == nedges) { - cadjncy[nedges] = k; - cadjwgt[nedges++] = adjwgt[j]; - } - } - } - - /* Remove the contracted adjacency weight */ - jj = htable[cnvtxs&mask]; - if (jj >= 0 && cadjncy[jj] != cnvtxs) { - for (jj=0; jj<nedges; jj++) { - if (cadjncy[jj] == cnvtxs) - break; - } - } - if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */ - cadjwgtsum[cnvtxs] -= cadjwgt[jj]; - cadjncy[jj] = cadjncy[--nedges]; - cadjwgt[jj] = cadjwgt[nedges]; - } - } - - ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v])); - - for (j=0; j<nedges; j++) - htable[cadjncy[j]&mask] = -1; /* Zero out the htable */ - htable[cnvtxs&mask] = -1; - - cnedges += nedges; - cxadj[++cnvtxs] = cnedges; - cadjncy += nedges; - cadjwgt += nedges; - } - - cgraph->nedges = cnedges; - - ReAdjustMemory(graph, cgraph, dovsize); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); - - idxwspacefree(ctrl, mask+1); - -} - - -/************************************************************************* -* This function creates the coarser graph -**************************************************************************/ -void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm) -{ - int i, j, k, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, dovsize; - idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj; - idxtype *cmap, *htable; - idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum; - float *nvwgt, *cnvwgt; - GraphType *cgraph; - - dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - vwgt = graph->vwgt; - vsize = graph->vsize; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - cmap = graph->cmap; - - - /* Initialize the coarser graph */ - cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize); - cxadj = cgraph->xadj; - cvwgt = cgraph->vwgt; - cvsize = cgraph->vsize; - cnvwgt = cgraph->nvwgt; - cadjwgtsum = cgraph->adjwgtsum; - cadjncy = cgraph->adjncy; - cadjwgt = cgraph->adjwgt; - - - htable = idxset(cnvtxs, -1, idxwspacemalloc(ctrl, cnvtxs)); - - iend = xadj[nvtxs]; - auxadj = ctrl->wspace.auxcore; - memcpy(auxadj, adjncy, iend*sizeof(idxtype)); - for (i=0; i<iend; i++) - auxadj[i] = cmap[auxadj[i]]; - - cxadj[0] = cnvtxs = cnedges = 0; - for (i=0; i<nvtxs; i++) { - v = perm[i]; - if (cmap[v] != cnvtxs) - continue; - - u = match[v]; - if (ncon == 1) - cvwgt[cnvtxs] = vwgt[v]; - else - scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon); - - if (dovsize) - cvsize[cnvtxs] = vsize[v]; - - cadjwgtsum[cnvtxs] = adjwgtsum[v]; - nedges = 0; - - istart = xadj[v]; - iend = xadj[v+1]; - for (j=istart; j<iend; j++) { - k = auxadj[j]; - if ((m = htable[k]) == -1) { - cadjncy[nedges] = k; - cadjwgt[nedges] = adjwgt[j]; - htable[k] = nedges++; - } - else { - cadjwgt[m] += adjwgt[j]; - } - } - - if (v != u) { - if (ncon == 1) - cvwgt[cnvtxs] += vwgt[u]; - else - saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1); - - if (dovsize) - cvsize[cnvtxs] += vsize[u]; - - cadjwgtsum[cnvtxs] += adjwgtsum[u]; - - istart = xadj[u]; - iend = xadj[u+1]; - for (j=istart; j<iend; j++) { - k = auxadj[j]; - if ((m = htable[k]) == -1) { - cadjncy[nedges] = k; - cadjwgt[nedges] = adjwgt[j]; - htable[k] = nedges++; - } - else { - cadjwgt[m] += adjwgt[j]; - } - } - - /* Remove the contracted adjacency weight */ - if ((j = htable[cnvtxs]) != -1) { - ASSERT(cadjncy[j] == cnvtxs); - cadjwgtsum[cnvtxs] -= cadjwgt[j]; - cadjncy[j] = cadjncy[--nedges]; - cadjwgt[j] = cadjwgt[nedges]; - htable[cnvtxs] = -1; - } - } - - ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d\n", cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt))); - - for (j=0; j<nedges; j++) - htable[cadjncy[j]] = -1; /* Zero out the htable */ - - cnedges += nedges; - cxadj[++cnvtxs] = cnedges; - cadjncy += nedges; - cadjwgt += nedges; - } - - cgraph->nedges = cnedges; - - ReAdjustMemory(graph, cgraph, dovsize); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); - - idxwspacefree(ctrl, cnvtxs); -} - - -/************************************************************************* -* This function creates the coarser graph -**************************************************************************/ -void CreateCoarseGraph_NVW(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm) -{ - int i, j, jj, k, kk, l, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, mask; - idxtype *xadj, *adjncy, *adjwgtsum, *auxadj; - idxtype *cmap, *htable; - idxtype *cxadj, *cvwgt, *cadjncy, *cadjwgt, *cadjwgtsum; - float *nvwgt, *cnvwgt; - GraphType *cgraph; - - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgtsum = graph->adjwgtsum; - cmap = graph->cmap; - - /* Initialize the coarser graph */ - cgraph = SetUpCoarseGraph(graph, cnvtxs, 0); - cxadj = cgraph->xadj; - cvwgt = cgraph->vwgt; - cnvwgt = cgraph->nvwgt; - cadjwgtsum = cgraph->adjwgtsum; - cadjncy = cgraph->adjncy; - cadjwgt = cgraph->adjwgt; - - - iend = xadj[nvtxs]; - auxadj = ctrl->wspace.auxcore; - memcpy(auxadj, adjncy, iend*sizeof(idxtype)); - for (i=0; i<iend; i++) - auxadj[i] = cmap[auxadj[i]]; - - mask = HTLENGTH; - htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1)); - - cxadj[0] = cnvtxs = cnedges = 0; - for (i=0; i<nvtxs; i++) { - v = perm[i]; - if (cmap[v] != cnvtxs) - continue; - - u = match[v]; - cvwgt[cnvtxs] = 1; - cadjwgtsum[cnvtxs] = adjwgtsum[v]; - nedges = 0; - - istart = xadj[v]; - iend = xadj[v+1]; - for (j=istart; j<iend; j++) { - k = auxadj[j]; - kk = k&mask; - if ((m = htable[kk]) == -1) { - cadjncy[nedges] = k; - cadjwgt[nedges] = 1; - htable[kk] = nedges++; - } - else if (cadjncy[m] == k) { - cadjwgt[m]++; - } - else { - for (jj=0; jj<nedges; jj++) { - if (cadjncy[jj] == k) { - cadjwgt[jj]++; - break; - } - } - if (jj == nedges) { - cadjncy[nedges] = k; - cadjwgt[nedges++] = 1; - } - } - } - - if (v != u) { - cvwgt[cnvtxs]++; - cadjwgtsum[cnvtxs] += adjwgtsum[u]; - - istart = xadj[u]; - iend = xadj[u+1]; - for (j=istart; j<iend; j++) { - k = auxadj[j]; - kk = k&mask; - if ((m = htable[kk]) == -1) { - cadjncy[nedges] = k; - cadjwgt[nedges] = 1; - htable[kk] = nedges++; - } - else if (cadjncy[m] == k) { - cadjwgt[m]++; - } - else { - for (jj=0; jj<nedges; jj++) { - if (cadjncy[jj] == k) { - cadjwgt[jj]++; - break; - } - } - if (jj == nedges) { - cadjncy[nedges] = k; - cadjwgt[nedges++] = 1; - } - } - } - - /* Remove the contracted adjacency weight */ - jj = htable[cnvtxs&mask]; - if (jj >= 0 && cadjncy[jj] != cnvtxs) { - for (jj=0; jj<nedges; jj++) { - if (cadjncy[jj] == cnvtxs) - break; - } - } - if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */ - cadjwgtsum[cnvtxs] -= cadjwgt[jj]; - cadjncy[jj] = cadjncy[--nedges]; - cadjwgt[jj] = cadjwgt[nedges]; - } - } - - ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v])); - - for (j=0; j<nedges; j++) - htable[cadjncy[j]&mask] = -1; /* Zero out the htable */ - htable[cnvtxs&mask] = -1; - - cnedges += nedges; - cxadj[++cnvtxs] = cnedges; - cadjncy += nedges; - cadjwgt += nedges; - } - - cgraph->nedges = cnedges; - - ReAdjustMemory(graph, cgraph, 0); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); - - idxwspacefree(ctrl, mask+1); - -} - - -/************************************************************************* -* Setup the various arrays for the coarse graph -**************************************************************************/ -GraphType *SetUpCoarseGraph(GraphType *graph, int cnvtxs, int dovsize) -{ - GraphType *cgraph; - - cgraph = CreateGraph(); - cgraph->nvtxs = cnvtxs; - cgraph->ncon = graph->ncon; - - cgraph->finer = graph; - graph->coarser = cgraph; - - - /* Allocate memory for the coarser graph */ - if (graph->ncon == 1) { - if (dovsize) { - cgraph->gdata = idxmalloc(5*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); - cgraph->xadj = cgraph->gdata; - cgraph->vwgt = cgraph->gdata + cnvtxs+1; - cgraph->vsize = cgraph->gdata + 2*cnvtxs+1; - cgraph->adjwgtsum = cgraph->gdata + 3*cnvtxs+1; - cgraph->cmap = cgraph->gdata + 4*cnvtxs+1; - cgraph->adjncy = cgraph->gdata + 5*cnvtxs+1; - cgraph->adjwgt = cgraph->gdata + 5*cnvtxs+1 + graph->nedges; - } - else { - cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); - cgraph->xadj = cgraph->gdata; - cgraph->vwgt = cgraph->gdata + cnvtxs+1; - cgraph->adjwgtsum = cgraph->gdata + 2*cnvtxs+1; - cgraph->cmap = cgraph->gdata + 3*cnvtxs+1; - cgraph->adjncy = cgraph->gdata + 4*cnvtxs+1; - cgraph->adjwgt = cgraph->gdata + 4*cnvtxs+1 + graph->nedges; - } - } - else { - if (dovsize) { - cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); - cgraph->xadj = cgraph->gdata; - cgraph->vsize = cgraph->gdata + cnvtxs+1; - cgraph->adjwgtsum = cgraph->gdata + 2*cnvtxs+1; - cgraph->cmap = cgraph->gdata + 3*cnvtxs+1; - cgraph->adjncy = cgraph->gdata + 4*cnvtxs+1; - cgraph->adjwgt = cgraph->gdata + 4*cnvtxs+1 + graph->nedges; - } - else { - cgraph->gdata = idxmalloc(3*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); - cgraph->xadj = cgraph->gdata; - cgraph->adjwgtsum = cgraph->gdata + cnvtxs+1; - cgraph->cmap = cgraph->gdata + 2*cnvtxs+1; - cgraph->adjncy = cgraph->gdata + 3*cnvtxs+1; - cgraph->adjwgt = cgraph->gdata + 3*cnvtxs+1 + graph->nedges; - } - - cgraph->nvwgt = fmalloc(graph->ncon*cnvtxs, "SetUpCoarseGraph: nvwgt"); - } - - return cgraph; -} - - -/************************************************************************* -* This function re-adjusts the amount of memory that was allocated if -* it will lead to significant savings -**************************************************************************/ -void ReAdjustMemory(GraphType *graph, GraphType *cgraph, int dovsize) -{ - - if (cgraph->nedges > 100000 && graph->nedges < 0.7*graph->nedges) { - idxcopy(cgraph->nedges, cgraph->adjwgt, cgraph->adjncy+cgraph->nedges); - - if (graph->ncon == 1) { - if (dovsize) { - cgraph->gdata = realloc(cgraph->gdata, (5*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); - - /* Do this, in case everything was copied into new space */ - cgraph->xadj = cgraph->gdata; - cgraph->vwgt = cgraph->gdata + cgraph->nvtxs+1; - cgraph->vsize = cgraph->gdata + 2*cgraph->nvtxs+1; - cgraph->adjwgtsum = cgraph->gdata + 3*cgraph->nvtxs+1; - cgraph->cmap = cgraph->gdata + 4*cgraph->nvtxs+1; - cgraph->adjncy = cgraph->gdata + 5*cgraph->nvtxs+1; - cgraph->adjwgt = cgraph->gdata + 5*cgraph->nvtxs+1 + cgraph->nedges; - } - else { - cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); - - /* Do this, in case everything was copied into new space */ - cgraph->xadj = cgraph->gdata; - cgraph->vwgt = cgraph->gdata + cgraph->nvtxs+1; - cgraph->adjwgtsum = cgraph->gdata + 2*cgraph->nvtxs+1; - cgraph->cmap = cgraph->gdata + 3*cgraph->nvtxs+1; - cgraph->adjncy = cgraph->gdata + 4*cgraph->nvtxs+1; - cgraph->adjwgt = cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges; - } - } - else { - if (dovsize) { - cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); - - /* Do this, in case everything was copied into new space */ - cgraph->xadj = cgraph->gdata; - cgraph->vsize = cgraph->gdata + cgraph->nvtxs+1; - cgraph->adjwgtsum = cgraph->gdata + 2*cgraph->nvtxs+1; - cgraph->cmap = cgraph->gdata + 3*cgraph->nvtxs+1; - cgraph->adjncy = cgraph->gdata + 4*cgraph->nvtxs+1; - cgraph->adjwgt = cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges; - } - else { - cgraph->gdata = realloc(cgraph->gdata, (3*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); - - /* Do this, in case everything was copied into new space */ - cgraph->xadj = cgraph->gdata; - cgraph->adjwgtsum = cgraph->gdata + cgraph->nvtxs+1; - cgraph->cmap = cgraph->gdata + 2*cgraph->nvtxs+1; - cgraph->adjncy = cgraph->gdata + 3*cgraph->nvtxs+1; - cgraph->adjwgt = cgraph->gdata + 3*cgraph->nvtxs+1 + cgraph->nedges; - } - } - } - -} diff --git a/Metis/coarsen.c b/Metis/coarsen.c deleted file mode 100644 index 904cb28522..0000000000 --- a/Metis/coarsen.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * coarsen.c - * - * This file contains the driving routines for the coarsening process - * - * Started 7/23/97 - * George - * - * $Id: coarsen.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function takes a graph and creates a sequence of coarser graphs -**************************************************************************/ -GraphType *Coarsen2Way(CtrlType *ctrl, GraphType *graph) -{ - int clevel; - GraphType *cgraph; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->CoarsenTmr)); - - cgraph = graph; - - /* The following is ahack to allow the multiple bisections to go through with correct - coarsening */ - if (ctrl->CType > 20) { - clevel = 1; - ctrl->CType -= 20; - } - else - clevel = 0; - - do { - IFSET(ctrl->dbglvl, DBG_COARSEN, printf("%6d %7d [%d] [%d %d]\n", - cgraph->nvtxs, cgraph->nedges, ctrl->CoarsenTo, ctrl->maxvwgt, - (cgraph->vwgt ? idxsum(cgraph->nvtxs, cgraph->vwgt) : cgraph->nvtxs))); - - if (cgraph->adjwgt) { - switch (ctrl->CType) { - case MATCH_RM: - Match_RM(ctrl, cgraph); - break; - case MATCH_HEM: - if (clevel < 1) - Match_RM(ctrl, cgraph); - else - Match_HEM(ctrl, cgraph); - break; - case MATCH_SHEM: - if (clevel < 1) - Match_RM(ctrl, cgraph); - else - Match_SHEM(ctrl, cgraph); - break; - case MATCH_SHEMKWAY: - Match_SHEM(ctrl, cgraph); - break; - default: - errexit("Unknown CType: %d\n", ctrl->CType); - } - } - else { - Match_RM_NVW(ctrl, cgraph); - } - - cgraph = cgraph->coarser; - clevel++; - - } while (cgraph->nvtxs > ctrl->CoarsenTo && cgraph->nvtxs < COARSEN_FRACTION2*cgraph->finer->nvtxs && cgraph->nedges > cgraph->nvtxs/2); - - IFSET(ctrl->dbglvl, DBG_COARSEN, printf("%6d %7d [%d] [%d %d]\n", - cgraph->nvtxs, cgraph->nedges, ctrl->CoarsenTo, ctrl->maxvwgt, - (cgraph->vwgt ? idxsum(cgraph->nvtxs, cgraph->vwgt) : cgraph->nvtxs))); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->CoarsenTmr)); - - return cgraph; -} - diff --git a/Metis/compress.c b/Metis/compress.c deleted file mode 100644 index 11ff2926c9..0000000000 --- a/Metis/compress.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * compress.c - * - * This file contains code for compressing nodes with identical adjacency - * structure and for prunning dense columns - * - * Started 9/17/97 - * George - * - * $Id: compress.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - -/************************************************************************* -* This function compresses a graph by merging identical vertices -* The compression should lead to at least 10% reduction. -**************************************************************************/ -void CompressGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *cptr, idxtype *cind) -{ - int i, ii, iii, j, jj, k, l, cnvtxs, cnedges; - idxtype *cxadj, *cadjncy, *cvwgt, *mark, *map; - KeyValueType *keys; - - mark = idxsmalloc(nvtxs, -1, "CompressGraph: mark"); - map = idxsmalloc(nvtxs, -1, "CompressGraph: map"); - keys = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "CompressGraph: keys"); - - /* Compute a key for each adjacency list */ - for (i=0; i<nvtxs; i++) { - k = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) - k += adjncy[j]; - keys[i].key = k+i; /* Add the diagonal entry as well */ - keys[i].val = i; - } - - ikeysort(nvtxs, keys); - - l = cptr[0] = 0; - for (cnvtxs=i=0; i<nvtxs; i++) { - ii = keys[i].val; - if (map[ii] == -1) { - mark[ii] = i; /* Add the diagonal entry */ - for (j=xadj[ii]; j<xadj[ii+1]; j++) - mark[adjncy[j]] = i; - - cind[l++] = ii; - map[ii] = cnvtxs; - - for (j=i+1; j<nvtxs; j++) { - iii = keys[j].val; - - if (keys[i].key != keys[j].key || xadj[ii+1]-xadj[ii] != xadj[iii+1]-xadj[iii]) - break; /* Break if keys or degrees are different */ - - if (map[iii] == -1) { /* Do a comparison if iii has not been mapped */ - for (jj=xadj[iii]; jj<xadj[iii+1]; jj++) { - if (mark[adjncy[jj]] != i) - break; - } - - if (jj == xadj[iii+1]) { /* Identical adjacency structure */ - map[iii] = cnvtxs; - cind[l++] = iii; - } - } - } - - cptr[++cnvtxs] = l; - } - } - - /* printf("Original: %6d, Compressed: %6d\n", nvtxs, cnvtxs); */ - - - InitGraph(graph); - - if (cnvtxs >= COMPRESSION_FRACTION*nvtxs) { - graph->nvtxs = nvtxs; - graph->nedges = xadj[nvtxs]; - graph->ncon = 1; - graph->xadj = xadj; - graph->adjncy = adjncy; - - graph->gdata = idxmalloc(3*nvtxs+graph->nedges, "CompressGraph: gdata"); - graph->vwgt = graph->gdata; - graph->adjwgtsum = graph->gdata+nvtxs; - graph->cmap = graph->gdata+2*nvtxs; - graph->adjwgt = graph->gdata+3*nvtxs; - - idxset(nvtxs, 1, graph->vwgt); - idxset(graph->nedges, 1, graph->adjwgt); - for (i=0; i<nvtxs; i++) - graph->adjwgtsum[i] = xadj[i+1]-xadj[i]; - - graph->label = idxmalloc(nvtxs, "CompressGraph: label"); - for (i=0; i<nvtxs; i++) - graph->label[i] = i; - } - else { /* Ok, form the compressed graph */ - cnedges = 0; - for (i=0; i<cnvtxs; i++) { - ii = cind[cptr[i]]; - cnedges += xadj[ii+1]-xadj[ii]; - } - - /* Allocate memory for the compressed graph*/ - graph->gdata = idxmalloc(4*cnvtxs+1 + 2*cnedges, "CompressGraph: gdata"); - cxadj = graph->xadj = graph->gdata; - cvwgt = graph->vwgt = graph->gdata + cnvtxs+1; - graph->adjwgtsum = graph->gdata + 2*cnvtxs+1; - graph->cmap = graph->gdata + 3*cnvtxs+1; - cadjncy = graph->adjncy = graph->gdata + 4*cnvtxs+1; - graph->adjwgt = graph->gdata + 4*cnvtxs+1 + cnedges; - - /* Now go and compress the graph */ - idxset(nvtxs, -1, mark); - l = cxadj[0] = 0; - for (i=0; i<cnvtxs; i++) { - cvwgt[i] = cptr[i+1]-cptr[i]; - mark[i] = i; /* Remove any dioganal entries in the compressed graph */ - for (j=cptr[i]; j<cptr[i+1]; j++) { - ii = cind[j]; - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { - k = map[adjncy[jj]]; - if (mark[k] != i) - cadjncy[l++] = k; - mark[k] = i; - } - } - cxadj[i+1] = l; - } - - graph->nvtxs = cnvtxs; - graph->nedges = l; - graph->ncon = 1; - - idxset(graph->nedges, 1, graph->adjwgt); - for (i=0; i<cnvtxs; i++) - graph->adjwgtsum[i] = cxadj[i+1]-cxadj[i]; - - graph->label = idxmalloc(cnvtxs, "CompressGraph: label"); - for (i=0; i<cnvtxs; i++) - graph->label[i] = i; - - } - - GKfree(&keys, &map, &mark, LTERM); -} - - - -/************************************************************************* -* This function prunes all the vertices in a graph with degree greater -* than factor*average -**************************************************************************/ -void PruneGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *iperm, float factor) -{ - int i, j, k, l, nlarge, pnvtxs, pnedges; - idxtype *pxadj, *padjncy, *padjwgt, *pvwgt; - idxtype *perm; - - perm = idxmalloc(nvtxs, "PruneGraph: perm"); - - factor = factor*xadj[nvtxs]/nvtxs; - - pnvtxs = pnedges = nlarge = 0; - for (i=0; i<nvtxs; i++) { - if (xadj[i+1]-xadj[i] < factor) { - perm[i] = pnvtxs; - iperm[pnvtxs++] = i; - pnedges += xadj[i+1]-xadj[i]; - } - else { - perm[i] = nvtxs - ++nlarge; - iperm[nvtxs-nlarge] = i; - } - } - - /* printf("Pruned %d vertices\n", nlarge); */ - - InitGraph(graph); - - if (nlarge == 0) { /* No prunning */ - graph->nvtxs = nvtxs; - graph->nedges = xadj[nvtxs]; - graph->ncon = 1; - graph->xadj = xadj; - graph->adjncy = adjncy; - - graph->gdata = idxmalloc(3*nvtxs+graph->nedges, "CompressGraph: gdata"); - graph->vwgt = graph->gdata; - graph->adjwgtsum = graph->gdata+nvtxs; - graph->cmap = graph->gdata+2*nvtxs; - graph->adjwgt = graph->gdata+3*nvtxs; - - idxset(nvtxs, 1, graph->vwgt); - idxset(graph->nedges, 1, graph->adjwgt); - for (i=0; i<nvtxs; i++) - graph->adjwgtsum[i] = xadj[i+1]-xadj[i]; - - graph->label = idxmalloc(nvtxs, "CompressGraph: label"); - for (i=0; i<nvtxs; i++) - graph->label[i] = i; - } - else { /* Prune the graph */ - /* Allocate memory for the compressed graph*/ - graph->gdata = idxmalloc(4*pnvtxs+1 + 2*pnedges, "PruneGraph: gdata"); - pxadj = graph->xadj = graph->gdata; - graph->vwgt = graph->gdata + pnvtxs+1; - graph->adjwgtsum = graph->gdata + 2*pnvtxs+1; - graph->cmap = graph->gdata + 3*pnvtxs+1; - padjncy = graph->adjncy = graph->gdata + 4*pnvtxs+1; - graph->adjwgt = graph->gdata + 4*pnvtxs+1 + pnedges; - - pxadj[0] = pnedges = l = 0; - for (i=0; i<nvtxs; i++) { - if (xadj[i+1]-xadj[i] < factor) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = perm[adjncy[j]]; - if (k < pnvtxs) - padjncy[pnedges++] = k; - } - pxadj[++l] = pnedges; - } - } - - graph->nvtxs = pnvtxs; - graph->nedges = pnedges; - graph->ncon = 1; - - idxset(pnvtxs, 1, graph->vwgt); - idxset(pnedges, 1, graph->adjwgt); - for (i=0; i<pnvtxs; i++) - graph->adjwgtsum[i] = pxadj[i+1]-pxadj[i]; - - graph->label = idxmalloc(pnvtxs, "CompressGraph: label"); - for (i=0; i<pnvtxs; i++) - graph->label[i] = i; - } - - free(perm); - -} - - - - - - - - - diff --git a/Metis/debug.c b/Metis/debug.c deleted file mode 100644 index 17f19e31f4..0000000000 --- a/Metis/debug.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * debug.c - * - * This file contains code that performs self debuging - * - * Started 7/24/97 - * George - * - * $Id: debug.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function computes the cut given the graph and a where vector -**************************************************************************/ -int ComputeCut(GraphType *graph, idxtype *where) -{ - int i, j, cut; - - if (graph->adjwgt == NULL) { - for (cut=0, i=0; i<graph->nvtxs; i++) { - for (j=graph->xadj[i]; j<graph->xadj[i+1]; j++) - if (where[i] != where[graph->adjncy[j]]) - cut++; - } - } - else { - for (cut=0, i=0; i<graph->nvtxs; i++) { - for (j=graph->xadj[i]; j<graph->xadj[i+1]; j++) - if (where[i] != where[graph->adjncy[j]]) - cut += graph->adjwgt[j]; - } - } - - return cut/2; -} - - -/************************************************************************* -* This function checks whether or not the boundary information is correct -**************************************************************************/ -int CheckBnd(GraphType *graph) -{ - int i, j, nvtxs, nbnd; - idxtype *xadj, *adjncy, *where, *bndptr, *bndind; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - - for (nbnd=0, i=0; i<nvtxs; i++) { - if (xadj[i+1]-xadj[i] == 0) - nbnd++; /* Islands are considered to be boundary vertices */ - - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (where[i] != where[adjncy[j]]) { - nbnd++; - ASSERT(bndptr[i] != -1); - ASSERT(bndind[bndptr[i]] == i); - break; - } - } - } - - ASSERTP(nbnd == graph->nbnd, ("%d %d\n", nbnd, graph->nbnd)); - - return 1; -} - - - -/************************************************************************* -* This function checks whether or not the boundary information is correct -**************************************************************************/ -int CheckBnd2(GraphType *graph) -{ - int i, j, nvtxs, nbnd, id, ed; - idxtype *xadj, *adjncy, *where, *bndptr, *bndind; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - - for (nbnd=0, i=0; i<nvtxs; i++) { - id = ed = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (where[i] != where[adjncy[j]]) - ed += graph->adjwgt[j]; - else - id += graph->adjwgt[j]; - } - if (ed - id >= 0 && xadj[i] < xadj[i+1]) { - nbnd++; - ASSERTP(bndptr[i] != -1, ("%d %d %d\n", i, id, ed)); - ASSERT(bndind[bndptr[i]] == i); - } - } - - ASSERTP(nbnd == graph->nbnd, ("%d %d\n", nbnd, graph->nbnd)); - - return 1; -} - -/************************************************************************* -* This function checks whether or not the boundary information is correct -**************************************************************************/ -int CheckNodeBnd(GraphType *graph, int onbnd) -{ - int i, j, nvtxs, nbnd; - idxtype *xadj, *adjncy, *where, *bndptr, *bndind; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - - for (nbnd=0, i=0; i<nvtxs; i++) { - if (where[i] == 2) - nbnd++; - } - - ASSERTP(nbnd == onbnd, ("%d %d\n", nbnd, onbnd)); - - for (i=0; i<nvtxs; i++) { - if (where[i] != 2) { - ASSERTP(bndptr[i] == -1, ("%d %d\n", i, bndptr[i])); - } - else { - ASSERTP(bndptr[i] != -1, ("%d %d\n", i, bndptr[i])); - } - } - - return 1; -} - - - -/************************************************************************* -* This function checks whether or not the rinfo of a vertex is consistent -**************************************************************************/ -int CheckRInfo(RInfoType *rinfo) -{ - int i, j; - - for (i=0; i<rinfo->ndegrees; i++) { - for (j=i+1; j<rinfo->ndegrees; j++) - ASSERTP(rinfo->edegrees[i].pid != rinfo->edegrees[j].pid, ("%d %d %d %d\n", i, j, rinfo->edegrees[i].pid, rinfo->edegrees[j].pid)); - } - - return 1; -} - - - -/************************************************************************* -* This function checks the correctness of the NodeFM data structures -**************************************************************************/ -int CheckNodePartitionParams(GraphType *graph) -{ - int i, j, k, l, nvtxs, me, other; - idxtype *xadj, *adjncy, *adjwgt, *vwgt, *where; - idxtype edegrees[2], pwgts[3]; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - - /*------------------------------------------------------------ - / Compute now the separator external degrees - /------------------------------------------------------------*/ - pwgts[0] = pwgts[1] = pwgts[2] = 0; - for (i=0; i<nvtxs; i++) { - me = where[i]; - pwgts[me] += vwgt[i]; - - if (me == 2) { /* If it is on the separator do some computations */ - edegrees[0] = edegrees[1] = 0; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - other = where[adjncy[j]]; - if (other != 2) - edegrees[other] += vwgt[adjncy[j]]; - } - if (edegrees[0] != graph->nrinfo[i].edegrees[0] || edegrees[1] != graph->nrinfo[i].edegrees[1]) { - printf("Something wrong with edegrees: %d %d %d %d %d\n", i, edegrees[0], edegrees[1], graph->nrinfo[i].edegrees[0], graph->nrinfo[i].edegrees[1]); - return 0; - } - } - } - - if (pwgts[0] != graph->pwgts[0] || pwgts[1] != graph->pwgts[1] || pwgts[2] != graph->pwgts[2]) - printf("Something wrong with part-weights: %d %d %d %d %d %d\n", pwgts[0], pwgts[1], pwgts[2], graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]); - - return 1; -} - - -/************************************************************************* -* This function checks if the separator is indeed a separator -**************************************************************************/ -int IsSeparable(GraphType *graph) -{ - int i, j, nvtxs, other; - idxtype *xadj, *adjncy, *where; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - - for (i=0; i<nvtxs; i++) { - if (where[i] == 2) - continue; - other = (where[i]+1)%2; - for (j=xadj[i]; j<xadj[i+1]; j++) { - ASSERTP(where[adjncy[j]] != other, ("%d %d %d %d %d %d\n", i, where[i], adjncy[j], where[adjncy[j]], xadj[i+1]-xadj[i], xadj[adjncy[j]+1]-xadj[adjncy[j]])); - } - } - - return 1; -} - - diff --git a/Metis/defs.h b/Metis/defs.h deleted file mode 100644 index 7696998e61..0000000000 --- a/Metis/defs.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * defs.h - * - * This file contains constant definitions - * - * Started 8/27/94 - * George - * - * $Id: defs.h,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#define METISTITLE " METIS 4.0.1 Copyright 1998, Regents of the University of Minnesota\n\n" -#define MAXLINE 1280000 - -#define LTERM (void **) 0 /* List terminator for GKfree() */ - -#define MAXNCON 16 /* The maximum number of constrains */ -#define MAXNOBJ 16 /* The maximum number of objectives */ - -#define PLUS_GAINSPAN 500 /* Parameters for FM buckets */ -#define NEG_GAINSPAN 500 - -#define HTLENGTH ((1<<11)-1) - -/* Meaning of various options[] parameters */ -#define OPTION_PTYPE 0 -#define OPTION_CTYPE 1 -#define OPTION_ITYPE 2 -#define OPTION_RTYPE 3 -#define OPTION_DBGLVL 4 -#define OPTION_OFLAGS 5 -#define OPTION_PFACTOR 6 -#define OPTION_NSEPS 7 - -#define OFLAG_COMPRESS 1 /* Try to compress the graph */ -#define OFLAG_CCMP 2 /* Find and order connected components */ - - -/* Default options for PMETIS */ -#define PMETIS_CTYPE MATCH_SHEM -#define PMETIS_ITYPE IPART_GGPKL -#define PMETIS_RTYPE RTYPE_FM -#define PMETIS_DBGLVL 0 - -/* Default options for KMETIS */ -#define KMETIS_CTYPE MATCH_SHEM -#define KMETIS_ITYPE IPART_PMETIS -#define KMETIS_RTYPE RTYPE_KWAYRANDOM_MCONN -#define KMETIS_DBGLVL 0 - -/* Default options for OEMETIS */ -#define OEMETIS_CTYPE MATCH_SHEM -#define OEMETIS_ITYPE IPART_GGPKL -#define OEMETIS_RTYPE RTYPE_FM -#define OEMETIS_DBGLVL 0 - -/* Default options for ONMETIS */ -#define ONMETIS_CTYPE MATCH_SHEM -#define ONMETIS_ITYPE IPART_GGPKL -#define ONMETIS_RTYPE RTYPE_SEP1SIDED -#define ONMETIS_DBGLVL 0 -#define ONMETIS_OFLAGS OFLAG_COMPRESS -#define ONMETIS_PFACTOR -1 -#define ONMETIS_NSEPS 1 - -/* Default options for McPMETIS */ -#define McPMETIS_CTYPE MATCH_SHEBM_ONENORM -#define McPMETIS_ITYPE IPART_RANDOM -#define McPMETIS_RTYPE RTYPE_FM -#define McPMETIS_DBGLVL 0 - -/* Default options for McKMETIS */ -#define McKMETIS_CTYPE MATCH_SHEBM_ONENORM -#define McKMETIS_ITYPE IPART_McHPMETIS -#define McKMETIS_RTYPE RTYPE_KWAYRANDOM -#define McKMETIS_DBGLVL 0 - -/* Default options for KVMETIS */ -#define KVMETIS_CTYPE MATCH_SHEM -#define KVMETIS_ITYPE IPART_PMETIS -#define KVMETIS_RTYPE RTYPE_KWAYRANDOM -#define KVMETIS_DBGLVL 0 - - -/* Operations supported by stand-alone code */ -#define OP_PMETIS 1 -#define OP_KMETIS 2 -#define OP_OEMETIS 3 -#define OP_ONMETIS 4 -#define OP_ONWMETIS 5 -#define OP_KVMETIS 6 - - -/* Matching Schemes */ -#define MATCH_RM 1 -#define MATCH_HEM 2 -#define MATCH_SHEM 3 -#define MATCH_SHEMKWAY 4 -#define MATCH_SHEBM_ONENORM 5 -#define MATCH_SHEBM_INFNORM 6 -#define MATCH_SBHEM_ONENORM 7 -#define MATCH_SBHEM_INFNORM 8 - -/* Initial partitioning schemes for PMETIS and ONMETIS */ -#define IPART_GGPKL 1 -#define IPART_GGPKLNODE 2 -#define IPART_RANDOM 2 - -/* Refinement schemes for PMETIS */ -#define RTYPE_FM 1 - -/* Initial partitioning schemes for KMETIS */ -#define IPART_PMETIS 1 - -/* Refinement schemes for KMETIS */ -#define RTYPE_KWAYRANDOM 1 -#define RTYPE_KWAYGREEDY 2 -#define RTYPE_KWAYRANDOM_MCONN 3 - -/* Refinement schemes for ONMETIS */ -#define RTYPE_SEP2SIDED 1 -#define RTYPE_SEP1SIDED 2 - -/* Initial Partitioning Schemes for McKMETIS */ -#define IPART_McPMETIS 1 /* Simple McPMETIS */ -#define IPART_McHPMETIS 2 /* horizontally relaxed McPMETIS */ - -#define UNMATCHED -1 - -#define HTABLE_EMPTY -1 - -#define NGR_PASSES 4 /* Number of greedy refinement passes */ -#define NLGR_PASSES 5 /* Number of GR refinement during IPartition */ - -#define LARGENIPARTS 8 /* Number of random initial partitions */ -#define SMALLNIPARTS 3 /* Number of random initial partitions */ - -#define COARSEN_FRACTION 0.75 /* Node reduction between succesive coarsening levels */ -#define COARSEN_FRACTION2 0.90 /* Node reduction between succesive coarsening levels */ -#define UNBALANCE_FRACTION 1.05 - -#define COMPRESSION_FRACTION 0.85 - -#define ORDER_UNBALANCE_FRACTION 1.10 - -#define MMDSWITCH 200 - -#define HORIZONTAL_IMBALANCE 1.05 - -/* Debug Levels */ -#define DBG_TIME 1 /* Perform timing analysis */ -#define DBG_OUTPUT 2 -#define DBG_COARSEN 4 /* Show the coarsening progress */ -#define DBG_REFINE 8 /* Show info on communication during folding */ -#define DBG_IPART 16 /* Show info on initial partition */ -#define DBG_MOVEINFO 32 /* Show info on communication during folding */ -#define DBG_KWAYPINFO 64 /* Show info on communication during folding */ -#define DBG_SEPINFO 128 /* Show info on communication during folding */ diff --git a/Metis/estmem.c b/Metis/estmem.c deleted file mode 100644 index 576d0b645f..0000000000 --- a/Metis/estmem.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * estmem.c - * - * This file contains code for estimating the amount of memory required by - * the various routines in METIS - * - * Started 11/4/97 - * George - * - * $Id: estmem.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function computes how much memory will be required by the various -* routines in METIS -**************************************************************************/ -void METIS_EstimateMemory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) -{ - int i, j, k, nedges, nlevels; - float vfraction, efraction, vmult, emult; - int coresize, gdata, rdata; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - nedges = xadj[*nvtxs]; - - InitRandom(-1); - EstimateCFraction(*nvtxs, xadj, adjncy, &vfraction, &efraction); - - /* Estimate the amount of memory for coresize */ - if (*optype == 2) - coresize = nedges; - else - coresize = 0; - coresize += nedges + 11*(*nvtxs) + 4*1024 + 2*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)); - coresize += 2*(*nvtxs); /* add some more fore other vectors */ - - gdata = nedges; /* Assume that the user does not pass weights */ - - nlevels = (int)(log(100.0/(*nvtxs))/log(vfraction) + .5); - vmult = 0.5 + (1.0 - pow(vfraction, nlevels))/(1.0 - vfraction); - emult = 1.0 + (1.0 - pow(efraction, nlevels+1))/(1.0 - efraction); - - gdata += vmult*4*(*nvtxs) + emult*2*nedges; - if ((vmult-1.0)*4*(*nvtxs) + (emult-1.0)*2*nedges < 5*(*nvtxs)) - rdata = 0; - else - rdata = 5*(*nvtxs); - - *nbytes = sizeof(idxtype)*(coresize+gdata+rdata+(*nvtxs)); - - if (*numflag == 1) - Change2FNumbering2(*nvtxs, xadj, adjncy); -} - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void EstimateCFraction(int nvtxs, idxtype *xadj, idxtype *adjncy, float *vfraction, float *efraction) -{ - int i, ii, j, cnvtxs, cnedges, maxidx; - idxtype *match, *cmap, *perm; - - cmap = idxmalloc(nvtxs, "cmap"); - match = idxsmalloc(nvtxs, UNMATCHED, "match"); - perm = idxmalloc(nvtxs, "perm"); - RandomPermute(nvtxs, perm, 1); - - cnvtxs = 0; - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - - /* Find a random matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (match[adjncy[j]] == UNMATCHED) { - maxidx = adjncy[j]; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - cnedges = ComputeCoarseGraphSize(nvtxs, xadj, adjncy, cnvtxs, cmap, match, perm); - - *vfraction = (1.0*cnvtxs)/(1.0*nvtxs); - *efraction = (1.0*cnedges)/(1.0*xadj[nvtxs]); - - GKfree(&cmap, &match, &perm, LTERM); -} - - - - -/************************************************************************* -* This function computes the size of the coarse graph -**************************************************************************/ -int ComputeCoarseGraphSize(int nvtxs, idxtype *xadj, idxtype *adjncy, int cnvtxs, idxtype *cmap, idxtype *match, idxtype *perm) -{ - int i, j, k, istart, iend, nedges, cnedges, v, u; - idxtype *htable; - - htable = idxsmalloc(cnvtxs, -1, "htable"); - - cnvtxs = cnedges = 0; - for (i=0; i<nvtxs; i++) { - v = perm[i]; - if (cmap[v] != cnvtxs) - continue; - - htable[cnvtxs] = cnvtxs; - - u = match[v]; - - istart = xadj[v]; - iend = xadj[v+1]; - for (j=istart; j<iend; j++) { - k = cmap[adjncy[j]]; - if (htable[k] != cnvtxs) { - htable[k] = cnvtxs; - cnedges++; - } - } - - if (v != u) { - istart = xadj[u]; - iend = xadj[u+1]; - for (j=istart; j<iend; j++) { - k = cmap[adjncy[j]]; - if (htable[k] != cnvtxs) { - htable[k] = cnvtxs; - cnedges++; - } - } - } - cnvtxs++; - } - - GKfree(&htable, LTERM); - - return cnedges; -} - - diff --git a/Metis/fm.c b/Metis/fm.c deleted file mode 100644 index 341d2b4f73..0000000000 --- a/Metis/fm.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * fm.c - * - * This file contains code that implements the edge-based FM refinement - * - * Started 7/23/97 - * George - * - * $Id: fm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs an edge-based FM refinement -**************************************************************************/ -void FM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, int *tpwgts, int npasses) -{ - int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, limit, tmp; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts; - idxtype *moved, *swaps, *perm; - PQueueType parts[2]; - int higain, oldgain, mincut, mindiff, origdiff, initcut, newcut, mincutorder, avgvwgt; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - pwgts = graph->pwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - - limit = amin(amax(0.01*nvtxs, 15), 100); - avgvwgt = amin((pwgts[0]+pwgts[1])/20, 2*(pwgts[0]+pwgts[1])/nvtxs); - - tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]; - PQueueInit(ctrl, &parts[0], nvtxs, tmp); - PQueueInit(ctrl, &parts[1], nvtxs, tmp); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d\n", - pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - origdiff = abs(tpwgts[0]-pwgts[0]); - idxset(nvtxs, -1, moved); - for (pass=0; pass<npasses; pass++) { /* Do a number of passes */ - PQueueReset(&parts[0]); - PQueueReset(&parts[1]); - - mincutorder = -1; - newcut = mincut = initcut = graph->mincut; - mindiff = abs(tpwgts[0]-pwgts[0]); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert boundary nodes in the priority queues */ - nbnd = graph->nbnd; - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = perm[ii]; - ASSERT(ed[bndind[i]] > 0 || id[bndind[i]] == 0); - ASSERT(bndptr[bndind[i]] != -1); - PQueueInsert(&parts[where[bndind[i]]], bndind[i], ed[bndind[i]]-id[bndind[i]]); - } - - for (nswaps=0; nswaps<nvtxs; nswaps++) { - from = (tpwgts[0]-pwgts[0] < tpwgts[1]-pwgts[1] ? 0 : 1); - to = (from+1)%2; - - if ((higain = PQueueGetMax(&parts[from])) == -1) - break; - ASSERT(bndptr[higain] != -1); - - newcut -= (ed[higain]-id[higain]); - INC_DEC(pwgts[to], pwgts[from], vwgt[higain]); - - if ((newcut < mincut && abs(tpwgts[0]-pwgts[0]) <= origdiff+avgvwgt) || - (newcut == mincut && abs(tpwgts[0]-pwgts[0]) < mindiff)) { - mincut = newcut; - mindiff = abs(tpwgts[0]-pwgts[0]); - mincutorder = nswaps; - } - else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */ - newcut += (ed[higain]-id[higain]); - INC_DEC(pwgts[from], pwgts[to], vwgt[higain]); - break; - } - - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], newcut, pwgts[0], pwgts[1])); - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update its boundary information and queue position */ - if (bndptr[k] != -1) { /* If k was a boundary vertex */ - if (ed[k] == 0) { /* Not a boundary vertex any more */ - BNDDelete(nbnd, bndind, bndptr, k); - if (moved[k] == -1) /* Remove it if in the queues */ - PQueueDelete(&parts[where[k]], k, oldgain); - } - else { /* If it has not been moved, update its position in the queue */ - if (moved[k] == -1) - PQueueUpdate(&parts[where[k]], k, oldgain, ed[k]-id[k]); - } - } - else { - if (ed[k] > 0) { /* It will now become a boundary vertex */ - BNDInsert(nbnd, bndind, bndptr, k); - if (moved[k] == -1) - PQueueInsert(&parts[where[k]], k, ed[k]-id[k]); - } - } - } - - } - - - /**************************************************************** - * Roll back computations - *****************************************************************/ - for (i=0; i<nswaps; i++) - moved[swaps[i]] = -1; /* reset moved array */ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - to = where[higain] = (where[higain]+1)%2; - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - else if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - INC_DEC(pwgts[to], pwgts[(to+1)%2], vwgt[higain]); - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - if (bndptr[k] != -1 && ed[k] == 0) - BNDDelete(nbnd, bndind, bndptr, k); - if (bndptr[k] == -1 && ed[k] > 0) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum cut: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (mincutorder == -1 || mincut == initcut) - break; - } - - PQueueFree(ctrl, &parts[0]); - PQueueFree(ctrl, &parts[1]); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - - diff --git a/Metis/fortran.c b/Metis/fortran.c deleted file mode 100644 index 7d84eae989..0000000000 --- a/Metis/fortran.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * fortran.c - * - * This file contains code for the fortran to C interface - * - * Started 8/19/97 - * George - * - * $Id: fortran.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function changes the numbering to start from 0 instead of 1 -**************************************************************************/ -void Change2CNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy) -{ - int i, nedges; - - for (i=0; i<=nvtxs; i++) - xadj[i]--; - - nedges = xadj[nvtxs]; - for (i=0; i<nedges; i++) - adjncy[i]--; -} - -/************************************************************************* -* This function changes the numbering to start from 1 instead of 0 -**************************************************************************/ -void Change2FNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vector) -{ - int i, nedges; - - for (i=0; i<nvtxs; i++) - vector[i]++; - - nedges = xadj[nvtxs]; - for (i=0; i<nedges; i++) - adjncy[i]++; - - for (i=0; i<=nvtxs; i++) - xadj[i]++; -} - -/************************************************************************* -* This function changes the numbering to start from 1 instead of 0 -**************************************************************************/ -void Change2FNumbering2(int nvtxs, idxtype *xadj, idxtype *adjncy) -{ - int i, nedges; - - nedges = xadj[nvtxs]; - for (i=0; i<nedges; i++) - adjncy[i]++; - - for (i=0; i<=nvtxs; i++) - xadj[i]++; -} - - - -/************************************************************************* -* This function changes the numbering to start from 1 instead of 0 -**************************************************************************/ -void Change2FNumberingOrder(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *v1, idxtype *v2) -{ - int i, nedges; - - for (i=0; i<nvtxs; i++) { - v1[i]++; - v2[i]++; - } - - nedges = xadj[nvtxs]; - for (i=0; i<nedges; i++) - adjncy[i]++; - - for (i=0; i<=nvtxs; i++) - xadj[i]++; - -} - - - -/************************************************************************* -* This function changes the numbering to start from 0 instead of 1 -**************************************************************************/ -void ChangeMesh2CNumbering(int n, idxtype *mesh) -{ - int i; - - for (i=0; i<n; i++) - mesh[i]--; - -} - - -/************************************************************************* -* This function changes the numbering to start from 1 instead of 0 -**************************************************************************/ -void ChangeMesh2FNumbering(int n, idxtype *mesh, int nvtxs, idxtype *xadj, idxtype *adjncy) -{ - int i, nedges; - - for (i=0; i<n; i++) - mesh[i]++; - - nedges = xadj[nvtxs]; - for (i=0; i<nedges; i++) - adjncy[i]++; - - for (i=0; i<=nvtxs; i++) - xadj[i]++; - -} - - -/************************************************************************* -* This function changes the numbering to start from 1 instead of 0 -**************************************************************************/ -void ChangeMesh2FNumbering2(int n, idxtype *mesh, int ne, int nn, idxtype *epart, idxtype *npart) -{ - int i, nedges; - - for (i=0; i<n; i++) - mesh[i]++; - - for (i=0; i<ne; i++) - epart[i]++; - - for (i=0; i<nn; i++) - npart[i]++; - -} - diff --git a/Metis/frename.c b/Metis/frename.c deleted file mode 100644 index 0ef94ab1b4..0000000000 --- a/Metis/frename.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * frename.c - * - * This file contains some renaming routines to deal with different Fortran compilers - * - * Started 9/15/97 - * George - * - * $Id: frename.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -void METIS_PARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_partgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_partgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_partgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} - - -void METIS_WPARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} -void metis_wpartgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} -void metis_wpartgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} -void metis_wpartgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} - - - -void METIS_PARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_partgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_partgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_partgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} - - - -void METIS_WPARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} -void metis_wpartgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} -void metis_wpartgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} -void metis_wpartgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); -} - - - -void METIS_EDGEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} -void metis_edgend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} -void metis_edgend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} -void metis_edgend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} - - - -void METIS_NODEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} -void metis_nodend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} -void metis_nodend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} -void metis_nodend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); -} - - - -void METIS_NODEWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); -} -void metis_nodewnd(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); -} -void metis_nodewnd_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); -} -void metis_nodewnd__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) -{ - METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); -} - - - -void METIS_PARTMESHNODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} -void metis_partmeshnodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} -void metis_partmeshnodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} -void metis_partmeshnodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} - - -void METIS_PARTMESHDUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} -void metis_partmeshdual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} -void metis_partmeshdual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} -void metis_partmeshdual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); -} - - -void METIS_MESHTONODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} -void metis_meshtonodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} -void metis_meshtonodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} -void metis_meshtonodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} - - -void METIS_MESHTODUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} -void metis_meshtodual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} -void metis_meshtodual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} -void metis_meshtodual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) -{ - METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); -} - - -void METIS_ESTIMATEMEMORY(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) -{ - METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); -} -void metis_estimatememory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) -{ - METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); -} -void metis_estimatememory_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) -{ - METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); -} -void metis_estimatememory__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) -{ - METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); -} - - - -void METIS_MCPARTGRAPHRECURSIVE(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_mcpartgraphrecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_mcpartgraphrecursive_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} -void metis_mcpartgraphrecursive__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); -} - - -void METIS_MCPARTGRAPHKWAY(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); -} -void metis_mcpartgraphkway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); -} -void metis_mcpartgraphkway_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); -} -void metis_mcpartgraphkway__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) -{ - METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); -} - - -void METIS_PARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) -{ - METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); -} -void metis_partgraphvkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) -{ - METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); -} -void metis_partgraphvkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) -{ - METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); -} -void metis_partgraphvkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) -{ - METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); -} - -void METIS_WPARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) -{ - METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); -} -void metis_wpartgraphvkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) -{ - METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); -} -void metis_wpartgraphvkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) -{ - METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); -} -void metis_wpartgraphvkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) -{ - METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); -} - - - diff --git a/Metis/graph.c b/Metis/graph.c deleted file mode 100644 index 5bb06c51de..0000000000 --- a/Metis/graph.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * graph.c - * - * This file contains functions that deal with setting up the graphs - * for METIS. - * - * Started 7/25/97 - * George - * - * $Id: graph.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function sets up the graph from the user input -**************************************************************************/ -void SetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, - idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int wgtflag) -{ - int i, j, k, sum, gsize; - float *nvwgt; - idxtype tvwgt[MAXNCON]; - - if (OpType == OP_KMETIS && ncon == 1 && (wgtflag&2) == 0 && (wgtflag&1) == 0) { - SetUpGraphKway(graph, nvtxs, xadj, adjncy); - return; - } - - InitGraph(graph); - - graph->nvtxs = nvtxs; - graph->nedges = xadj[nvtxs]; - graph->ncon = ncon; - graph->xadj = xadj; - graph->adjncy = adjncy; - - if (ncon == 1) { /* We are in the non mC mode */ - gsize = 0; - if ((wgtflag&2) == 0) - gsize += nvtxs; - if ((wgtflag&1) == 0) - gsize += graph->nedges; - - gsize += 2*nvtxs; - - graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); - - /* Create the vertex/edge weight vectors if they are not supplied */ - gsize = 0; - if ((wgtflag&2) == 0) { - vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata); - gsize += nvtxs; - } - else - graph->vwgt = vwgt; - - if ((wgtflag&1) == 0) { - adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize); - gsize += graph->nedges; - } - else - graph->adjwgt = adjwgt; - - - /* Compute the initial values of the adjwgtsum */ - graph->adjwgtsum = graph->gdata + gsize; - gsize += nvtxs; - - for (i=0; i<nvtxs; i++) { - sum = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) - sum += adjwgt[j]; - graph->adjwgtsum[i] = sum; - } - - graph->cmap = graph->gdata + gsize; - gsize += nvtxs; - - } - else { /* Set up the graph in MOC mode */ - gsize = 0; - if ((wgtflag&1) == 0) - gsize += graph->nedges; - - gsize += 2*nvtxs; - - graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); - gsize = 0; - - for (i=0; i<ncon; i++) - tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon); - - nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt"); - - for (i=0; i<nvtxs; i++) { - for (j=0; j<ncon; j++) - nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]); - } - - - /* Create the edge weight vectors if they are not supplied */ - if ((wgtflag&1) == 0) { - adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize); - gsize += graph->nedges; - } - else - graph->adjwgt = adjwgt; - - /* Compute the initial values of the adjwgtsum */ - graph->adjwgtsum = graph->gdata + gsize; - gsize += nvtxs; - - for (i=0; i<nvtxs; i++) { - sum = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) - sum += adjwgt[j]; - graph->adjwgtsum[i] = sum; - } - - graph->cmap = graph->gdata + gsize; - gsize += nvtxs; - - } - - if (OpType != OP_KMETIS && OpType != OP_KVMETIS) { - graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); - - for (i=0; i<nvtxs; i++) - graph->label[i] = i; - } - -} - - -/************************************************************************* -* This function sets up the graph from the user input -**************************************************************************/ -void SetUpGraphKway(GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy) -{ - int i; - - InitGraph(graph); - - graph->nvtxs = nvtxs; - graph->nedges = xadj[nvtxs]; - graph->ncon = 1; - graph->xadj = xadj; - graph->vwgt = NULL; - graph->adjncy = adjncy; - graph->adjwgt = NULL; - - graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata"); - graph->adjwgtsum = graph->gdata; - graph->cmap = graph->gdata + nvtxs; - - /* Compute the initial values of the adjwgtsum */ - for (i=0; i<nvtxs; i++) - graph->adjwgtsum[i] = xadj[i+1]-xadj[i]; - -} - - - -/************************************************************************* -* This function sets up the graph from the user input -**************************************************************************/ -void SetUpGraph2(GraphType *graph, int nvtxs, int ncon, idxtype *xadj, - idxtype *adjncy, float *nvwgt, idxtype *adjwgt) -{ - int i, j, sum; - - InitGraph(graph); - - graph->nvtxs = nvtxs; - graph->nedges = xadj[nvtxs]; - graph->ncon = ncon; - graph->xadj = xadj; - graph->adjncy = adjncy; - graph->adjwgt = adjwgt; - - graph->nvwgt = fmalloc(nvtxs*ncon, "SetUpGraph2: graph->nvwgt"); - scopy(nvtxs*ncon, nvwgt, graph->nvwgt); - - graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata"); - - /* Compute the initial values of the adjwgtsum */ - graph->adjwgtsum = graph->gdata; - for (i=0; i<nvtxs; i++) { - sum = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) - sum += adjwgt[j]; - graph->adjwgtsum[i] = sum; - } - - graph->cmap = graph->gdata+nvtxs; - - graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); - for (i=0; i<nvtxs; i++) - graph->label[i] = i; - -} - - -/************************************************************************* -* This function sets up the graph from the user input -**************************************************************************/ -void VolSetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, - idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int wgtflag) -{ - int i, j, k, sum, gsize; - idxtype *adjwgt; - float *nvwgt; - idxtype tvwgt[MAXNCON]; - - InitGraph(graph); - - graph->nvtxs = nvtxs; - graph->nedges = xadj[nvtxs]; - graph->ncon = ncon; - graph->xadj = xadj; - graph->adjncy = adjncy; - - if (ncon == 1) { /* We are in the non mC mode */ - gsize = graph->nedges; /* This is for the edge weights */ - if ((wgtflag&2) == 0) - gsize += nvtxs; /* vwgts */ - if ((wgtflag&1) == 0) - gsize += nvtxs; /* vsize */ - - gsize += 2*nvtxs; - - graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); - - /* Create the vertex/edge weight vectors if they are not supplied */ - gsize = 0; - if ((wgtflag&2) == 0) { - vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata); - gsize += nvtxs; - } - else - graph->vwgt = vwgt; - - if ((wgtflag&1) == 0) { - vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata); - gsize += nvtxs; - } - else - graph->vsize = vsize; - - /* Allocate memory for edge weights and initialize them to the sum of the vsize */ - adjwgt = graph->adjwgt = graph->gdata+gsize; - gsize += graph->nedges; - - for (i=0; i<nvtxs; i++) { - for (j=xadj[i]; j<xadj[i+1]; j++) - adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]]; - } - - - /* Compute the initial values of the adjwgtsum */ - graph->adjwgtsum = graph->gdata + gsize; - gsize += nvtxs; - - for (i=0; i<nvtxs; i++) { - sum = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) - sum += adjwgt[j]; - graph->adjwgtsum[i] = sum; - } - - graph->cmap = graph->gdata + gsize; - gsize += nvtxs; - - } - else { /* Set up the graph in MOC mode */ - gsize = graph->nedges; - if ((wgtflag&1) == 0) - gsize += nvtxs; - - gsize += 2*nvtxs; - - graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); - gsize = 0; - - /* Create the normalized vertex weights along each constrain */ - if ((wgtflag&2) == 0) - vwgt = idxsmalloc(nvtxs, 1, "SetUpGraph: vwgt"); - - for (i=0; i<ncon; i++) - tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon); - - nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt"); - - for (i=0; i<nvtxs; i++) { - for (j=0; j<ncon; j++) - nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]); - } - if ((wgtflag&2) == 0) - free(vwgt); - - - /* Create the vsize vector if it is not supplied */ - if ((wgtflag&1) == 0) { - vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata); - gsize += nvtxs; - } - else - graph->vsize = vsize; - - /* Allocate memory for edge weights and initialize them to the sum of the vsize */ - adjwgt = graph->adjwgt = graph->gdata+gsize; - gsize += graph->nedges; - - for (i=0; i<nvtxs; i++) { - for (j=xadj[i]; j<xadj[i+1]; j++) - adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]]; - } - - /* Compute the initial values of the adjwgtsum */ - graph->adjwgtsum = graph->gdata + gsize; - gsize += nvtxs; - - for (i=0; i<nvtxs; i++) { - sum = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) - sum += adjwgt[j]; - graph->adjwgtsum[i] = sum; - } - - graph->cmap = graph->gdata + gsize; - gsize += nvtxs; - - } - - if (OpType != OP_KVMETIS) { - graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); - - for (i=0; i<nvtxs; i++) - graph->label[i] = i; - } - -} - - -/************************************************************************* -* This function randomly permutes the adjacency lists of a graph -**************************************************************************/ -void RandomizeGraph(GraphType *graph) -{ - int i, j, k, l, tmp, nvtxs; - idxtype *xadj, *adjncy, *adjwgt; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - for (i=0; i<nvtxs; i++) { - l = xadj[i+1]-xadj[i]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = xadj[i] + RandomInRange(l); - SWAP(adjncy[j], adjncy[k], tmp); - SWAP(adjwgt[j], adjwgt[k], tmp); - } - } -} - - -/************************************************************************* -* This function checks whether or not partition pid is contigous -**************************************************************************/ -int IsConnectedSubdomain(CtrlType *ctrl, GraphType *graph, int pid, int report) -{ - int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; - idxtype *xadj, *adjncy, *where, *touched, *queue; - idxtype *cptr; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - - touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); - queue = idxmalloc(nvtxs, "IsConnected: queue"); - cptr = idxmalloc(nvtxs, "IsConnected: cptr"); - - nleft = 0; - for (i=0; i<nvtxs; i++) { - if (where[i] == pid) - nleft++; - } - - for (i=0; i<nvtxs; i++) { - if (where[i] == pid) - break; - } - - touched[i] = 1; - queue[0] = i; - first = 0; last = 1; - - cptr[0] = 0; /* This actually points to queue */ - ncmps = 0; - while (first != nleft) { - if (first == last) { /* Find another starting vertex */ - cptr[++ncmps] = first; - for (i=0; i<nvtxs; i++) { - if (where[i] == pid && !touched[i]) - break; - } - queue[last++] = i; - touched[i] = 1; - } - - i = queue[first++]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] == pid && !touched[k]) { - queue[last++] = k; - touched[k] = 1; - } - } - } - cptr[++ncmps] = first; - - if (ncmps > 1 && report) { - printf("The graph has %d connected components in partition %d:\t", ncmps, pid); - for (i=0; i<ncmps; i++) { - wgt = 0; - for (j=cptr[i]; j<cptr[i+1]; j++) - wgt += graph->vwgt[queue[j]]; - printf("[%5d %5d] ", cptr[i+1]-cptr[i], wgt); - /* - if (cptr[i+1]-cptr[i] == 1) - printf("[%d %d] ", queue[cptr[i]], xadj[queue[cptr[i]]+1]-xadj[queue[cptr[i]]]); - */ - } - printf("\n"); - } - - GKfree(&touched, &queue, &cptr, LTERM); - - return (ncmps == 1 ? 1 : 0); -} - - -/************************************************************************* -* This function checks whether a graph is contigous or not -**************************************************************************/ -int IsConnected(CtrlType *ctrl, GraphType *graph, int report) -{ - int i, j, k, nvtxs, first, last; - idxtype *xadj, *adjncy, *touched, *queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - - touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); - queue = idxmalloc(nvtxs, "IsConnected: queue"); - - touched[0] = 1; - queue[0] = 0; - first = 0; last = 1; - - while (first < last) { - i = queue[first++]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (!touched[k]) { - queue[last++] = k; - touched[k] = 1; - } - } - } - - if (first != nvtxs && report) - printf("The graph is not connected. It has %d disconnected vertices!\n", nvtxs-first); - - return (first == nvtxs ? 1 : 0); -} - - -/************************************************************************* -* This function checks whether or not partition pid is contigous -**************************************************************************/ -int IsConnected2(GraphType *graph, int report) -{ - int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; - idxtype *xadj, *adjncy, *where, *touched, *queue; - idxtype *cptr; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - - touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); - queue = idxmalloc(nvtxs, "IsConnected: queue"); - cptr = idxmalloc(nvtxs, "IsConnected: cptr"); - - nleft = nvtxs; - touched[0] = 1; - queue[0] = 0; - first = 0; last = 1; - - cptr[0] = 0; /* This actually points to queue */ - ncmps = 0; - while (first != nleft) { - if (first == last) { /* Find another starting vertex */ - cptr[++ncmps] = first; - for (i=0; i<nvtxs; i++) { - if (!touched[i]) - break; - } - queue[last++] = i; - touched[i] = 1; - } - - i = queue[first++]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (!touched[k]) { - queue[last++] = k; - touched[k] = 1; - } - } - } - cptr[++ncmps] = first; - - if (ncmps > 1 && report) { - printf("%d connected components:\t", ncmps); - for (i=0; i<ncmps; i++) { - if (cptr[i+1]-cptr[i] > 200) - printf("[%5d] ", cptr[i+1]-cptr[i]); - } - printf("\n"); - } - - GKfree(&touched, &queue, &cptr, LTERM); - - return (ncmps == 1 ? 1 : 0); -} - - -/************************************************************************* -* This function returns the number of connected components in cptr,cind -* The separator of the graph is used to split it and then find its components. -**************************************************************************/ -int FindComponents(CtrlType *ctrl, GraphType *graph, idxtype *cptr, idxtype *cind) -{ - int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; - idxtype *xadj, *adjncy, *where, *touched, *queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - where = graph->where; - - touched = idxsmalloc(nvtxs, 0, "IsConnected: queue"); - - for (i=0; i<graph->nbnd; i++) - touched[graph->bndind[i]] = 1; - - queue = cind; - - nleft = 0; - for (i=0; i<nvtxs; i++) { - if (where[i] != 2) - nleft++; - } - - for (i=0; i<nvtxs; i++) { - if (where[i] != 2) - break; - } - - touched[i] = 1; - queue[0] = i; - first = 0; last = 1; - - cptr[0] = 0; /* This actually points to queue */ - ncmps = 0; - while (first != nleft) { - if (first == last) { /* Find another starting vertex */ - cptr[++ncmps] = first; - for (i=0; i<nvtxs; i++) { - if (!touched[i]) - break; - } - queue[last++] = i; - touched[i] = 1; - } - - i = queue[first++]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (!touched[k]) { - queue[last++] = k; - touched[k] = 1; - } - } - } - cptr[++ncmps] = first; - - free(touched); - - return ncmps; -} - - - diff --git a/Metis/initpart.c b/Metis/initpart.c deleted file mode 100644 index 58b01056ee..0000000000 --- a/Metis/initpart.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * initpart.c - * - * This file contains code that performs the initial partition of the - * coarsest graph - * - * Started 7/23/97 - * George - * - * $Id: initpart.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function computes the initial bisection of the coarsest graph -**************************************************************************/ -void Init2WayPartition(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - int dbglvl; - - dbglvl = ctrl->dbglvl; - IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); - IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - - switch (ctrl->IType) { - case IPART_GGPKL: - GrowBisection(ctrl, graph, tpwgts, ubfactor); - break; - case 3: - RandomBisection(ctrl, graph, tpwgts, ubfactor); - break; - default: - errexit("Unknown initial partition type: %d\n", ctrl->IType); - } - - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut)); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - ctrl->dbglvl = dbglvl; - -/* - IsConnectedSubdomain(ctrl, graph, 0); - IsConnectedSubdomain(ctrl, graph, 1); -*/ -} - -/************************************************************************* -* This function computes the initial bisection of the coarsest graph -**************************************************************************/ -void InitSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) -{ - int dbglvl; - - dbglvl = ctrl->dbglvl; - IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); - IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - - GrowBisectionNode(ctrl, graph, ubfactor); - Compute2WayNodePartitionParams(ctrl, graph); - - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Sep: %d\n", graph->mincut)); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - - ctrl->dbglvl = dbglvl; - -} - - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void GrowBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where; - idxtype *queue, *touched, *gain, *bestwhere; - - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - Allocate2WayPartitionMemory(ctrl, graph); - where = graph->where; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - queue = idxmalloc(nvtxs, "BisectGraph: queue"); - touched = idxmalloc(nvtxs, "BisectGraph: touched"); - - ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt))); - - maxpwgt[0] = ubfactor*tpwgts[0]; - maxpwgt[1] = ubfactor*tpwgts[1]; - minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; - minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; - - nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = idxsum(nvtxs, graph->adjwgtsum)+1; /* The +1 is for the 0 edges case */ - for (; nbfs>0; nbfs--) { - idxset(nvtxs, 0, touched); - - pwgts[1] = tpwgts[0]+tpwgts[1]; - pwgts[0] = 0; - - idxset(nvtxs, 1, where); - - queue[0] = RandomInRange(nvtxs); - touched[queue[0]] = 1; - first = 0; last = 1; - nleft = nvtxs-1; - drain = 0; - - /* Start the BFS from queue to get a partition */ - for (;;) { - if (first == last) { /* Empty. Disconnected graph! */ - if (nleft == 0 || drain) - break; - - k = RandomInRange(nleft); - for (i=0; i<nvtxs; i++) { - if (touched[i] == 0) { - if (k == 0) - break; - else - k--; - } - } - - queue[0] = i; - touched[i] = 1; - first = 0; last = 1;; - nleft--; - } - - i = queue[first++]; - if (pwgts[0] > 0 && pwgts[1]-vwgt[i] < minpwgt[1]) { - drain = 1; - continue; - } - - where[i] = 0; - INC_DEC(pwgts[0], pwgts[1], vwgt[i]); - if (pwgts[1] <= maxpwgt[1]) - break; - - drain = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (touched[k] == 0) { - queue[last++] = k; - touched[k] = 1; - nleft--; - } - } - } - - /* Check to see if we hit any bad limiting cases */ - if (pwgts[1] == 0) { - i = RandomInRange(nvtxs); - where[i] = 1; - INC_DEC(pwgts[1], pwgts[0], vwgt[i]); - } - - /************************************************************* - * Do some partition refinement - **************************************************************/ - Compute2WayPartitionParams(ctrl, graph); - /*printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ - - Balance2Way(ctrl, graph, tpwgts, ubfactor); - /*printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/ - - FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); - /*printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/ - - if (bestcut > graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - if (bestcut == 0) - break; - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - GKfree(&bestwhere, &queue, &touched, LTERM); -} - - - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void GrowBisectionNode(CtrlType *ctrl, GraphType *graph, float ubfactor) -{ - int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], tpwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *bndind; - idxtype *queue, *touched, *gain, *bestwhere; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - queue = idxmalloc(nvtxs, "BisectGraph: queue"); - touched = idxmalloc(nvtxs, "BisectGraph: touched"); - - tpwgts[0] = idxsum(nvtxs, vwgt); - tpwgts[1] = tpwgts[0]/2; - tpwgts[0] -= tpwgts[1]; - - maxpwgt[0] = ubfactor*tpwgts[0]; - maxpwgt[1] = ubfactor*tpwgts[1]; - minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; - minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; - - /* Allocate memory for graph->rdata. Allocate sufficient memory for both edge and node */ - graph->rdata = idxmalloc(5*nvtxs+3, "GrowBisectionNode: graph->rdata"); - graph->pwgts = graph->rdata; - graph->where = graph->rdata + 3; - graph->bndptr = graph->rdata + nvtxs + 3; - graph->bndind = graph->rdata + 2*nvtxs + 3; - graph->nrinfo = (NRInfoType *)(graph->rdata + 3*nvtxs + 3); - graph->id = graph->rdata + 3*nvtxs + 3; - graph->ed = graph->rdata + 4*nvtxs + 3; - - where = graph->where; - bndind = graph->bndind; - - nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = tpwgts[0]+tpwgts[1]; - for (nbfs++; nbfs>0; nbfs--) { - idxset(nvtxs, 0, touched); - - pwgts[1] = tpwgts[0]+tpwgts[1]; - pwgts[0] = 0; - - idxset(nvtxs, 1, where); - - queue[0] = RandomInRange(nvtxs); - touched[queue[0]] = 1; - first = 0; last = 1; - nleft = nvtxs-1; - drain = 0; - - /* Start the BFS from queue to get a partition */ - if (nbfs >= 1) { - for (;;) { - if (first == last) { /* Empty. Disconnected graph! */ - if (nleft == 0 || drain) - break; - - k = RandomInRange(nleft); - for (i=0; i<nvtxs; i++) { - if (touched[i] == 0) { - if (k == 0) - break; - else - k--; - } - } - - queue[0] = i; - touched[i] = 1; - first = 0; last = 1;; - nleft--; - } - - i = queue[first++]; - if (pwgts[1]-vwgt[i] < minpwgt[1]) { - drain = 1; - continue; - } - - where[i] = 0; - INC_DEC(pwgts[0], pwgts[1], vwgt[i]); - if (pwgts[1] <= maxpwgt[1]) - break; - - drain = 0; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (touched[k] == 0) { - queue[last++] = k; - touched[k] = 1; - nleft--; - } - } - } - } - - /************************************************************* - * Do some partition refinement - **************************************************************/ - Compute2WayPartitionParams(ctrl, graph); - Balance2Way(ctrl, graph, tpwgts, ubfactor); - FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); - - /* Construct and refine the vertex separator */ - for (i=0; i<graph->nbnd; i++) - where[bndind[i]] = 2; - - Compute2WayNodePartitionParams(ctrl, graph); - FM_2WayNodeRefine(ctrl, graph, ubfactor, 6); - - /* printf("ISep: [%d %d %d] %d\n", graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */ - - if (bestcut > graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - Compute2WayNodePartitionParams(ctrl, graph); - - GKfree(&bestwhere, &queue, &touched, LTERM); -} - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void RandomBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - int i, ii, j, k, nvtxs, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where; - idxtype *perm, *bestwhere; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - Allocate2WayPartitionMemory(ctrl, graph); - where = graph->where; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - perm = idxmalloc(nvtxs, "BisectGraph: queue"); - - ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt))); - - maxpwgt[0] = ubfactor*tpwgts[0]; - maxpwgt[1] = ubfactor*tpwgts[1]; - minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; - minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; - - nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = idxsum(nvtxs, graph->adjwgtsum)+1; /* The +1 is for the 0 edges case */ - for (; nbfs>0; nbfs--) { - RandomPermute(nvtxs, perm, 1); - - idxset(nvtxs, 1, where); - pwgts[1] = tpwgts[0]+tpwgts[1]; - pwgts[0] = 0; - - - if (nbfs != 1) { - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - if (pwgts[0]+vwgt[i] < maxpwgt[0]) { - where[i] = 0; - pwgts[0] += vwgt[i]; - pwgts[1] -= vwgt[i]; - if (pwgts[0] > minpwgt[0]) - break; - } - } - } - - /************************************************************* - * Do some partition refinement - **************************************************************/ - Compute2WayPartitionParams(ctrl, graph); - /* printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ - - Balance2Way(ctrl, graph, tpwgts, ubfactor); - /* printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ - - FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); - /* printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ - - if (bestcut > graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - if (bestcut == 0) - break; - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - GKfree(&bestwhere, &perm, LTERM); -} - - - - diff --git a/Metis/kmetis.c b/Metis/kmetis.c deleted file mode 100644 index f684c1bbad..0000000000 --- a/Metis/kmetis.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * kmetis.c - * - * This file contains the top level routines for the multilevel k-way partitioning - * algorithm KMETIS. - * - * Started 7/28/97 - * George - * - * $Id: kmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point for KMETIS -**************************************************************************/ -void METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ - int i; - float *tpwgts; - - tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); - for (i=0; i<*nparts; i++) - tpwgts[i] = 1.0/(1.0*(*nparts)); - - METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, - tpwgts, options, edgecut, part); - - free(tpwgts); -} - - -/************************************************************************* -* This function is the entry point for KWMETIS -**************************************************************************/ -void METIS_WPartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_KMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = KMETIS_CTYPE; - ctrl.IType = KMETIS_ITYPE; - ctrl.RType = KMETIS_RTYPE; - ctrl.dbglvl = KMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_KMETIS; - ctrl.CoarsenTo = amax((*nvtxs)/(40*log2(*nparts)), 20*(*nparts)); - ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MlevelKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -int MlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor) -{ - int i, j, nvtxs, tvwgt, tpwgts2[2]; - GraphType *cgraph; - int wgtflag=3, numflag=0, options[10], edgecut; - - cgraph = Coarsen2Way(ctrl, graph); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - AllocateKWayPartitionMemory(ctrl, cgraph, nparts); - - options[0] = 1; - options[OPTION_CTYPE] = MATCH_SHEMKWAY; - options[OPTION_ITYPE] = IPART_GGPKL; - options[OPTION_RTYPE] = RTYPE_FM; - options[OPTION_DBGLVL] = 0; - - METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, - cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, - &edgecut, cgraph->where); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); - - IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); - - RefineKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor); - - idxcopy(graph->nvtxs, graph->where, part); - - GKfree(&graph->gdata, &graph->rdata, LTERM); - - return graph->mincut; - -} - diff --git a/Metis/kvmetis.c b/Metis/kvmetis.c deleted file mode 100644 index 6cb7f17b18..0000000000 --- a/Metis/kvmetis.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * kvmetis.c - * - * This file contains the top level routines for the multilevel k-way partitioning - * algorithm KMETIS. - * - * Started 7/28/97 - * George - * - * $Id: kvmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point for KMETIS -**************************************************************************/ -void METIS_PartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *vsize, int *wgtflag, int *numflag, int *nparts, - int *options, int *volume, idxtype *part) -{ - int i; - float *tpwgts; - - tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); - for (i=0; i<*nparts; i++) - tpwgts[i] = 1.0/(1.0*(*nparts)); - - METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, - tpwgts, options, volume, part); - - free(tpwgts); -} - - -/************************************************************************* -* This function is the entry point for KWMETIS -**************************************************************************/ -void METIS_WPartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *vsize, int *wgtflag, int *numflag, int *nparts, - float *tpwgts, int *options, int *volume, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - VolSetUpGraph(&graph, OP_KVMETIS, *nvtxs, 1, xadj, adjncy, vwgt, vsize, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = KVMETIS_CTYPE; - ctrl.IType = KVMETIS_ITYPE; - ctrl.RType = KVMETIS_RTYPE; - ctrl.dbglvl = KVMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_KVMETIS; - ctrl.CoarsenTo = amax((*nvtxs)/(40*log2(*nparts)), 20*(*nparts)); - ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *volume = MlevelVolKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -int MlevelVolKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, - float *tpwgts, float ubfactor) -{ - int i, j, nvtxs, tvwgt, tpwgts2[2]; - GraphType *cgraph; - int wgtflag=3, numflag=0, options[10], edgecut; - - cgraph = Coarsen2Way(ctrl, graph); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - AllocateVolKWayPartitionMemory(ctrl, cgraph, nparts); - - options[0] = 1; - options[OPTION_CTYPE] = MATCH_SHEMKWAY; - options[OPTION_ITYPE] = IPART_GGPKL; - options[OPTION_RTYPE] = RTYPE_FM; - options[OPTION_DBGLVL] = 0; - - METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, - cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, - &edgecut, cgraph->where); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); - - IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); - - RefineVolKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor); - - idxcopy(graph->nvtxs, graph->where, part); - - GKfree(&graph->gdata, &graph->rdata, LTERM); - - return graph->minvol; - -} - diff --git a/Metis/kwayfm.c b/Metis/kwayfm.c deleted file mode 100644 index 5b376e5db3..0000000000 --- a/Metis/kwayfm.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * kwayfm.c - * - * This file contains code that implements the multilevel k-way refinement - * - * Started 7/28/97 - * George - * - * $Id: kwayfm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Random_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees; - int from, me, to, oldcut, vwgt, gain; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts; - EDegreeType *myedegrees; - RInfoType *myrinfo; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (nmoves=iii=0; iii<graph->nbnd; iii++) { - ii = perm[iii]; - if (ii >= nbnd) - continue; - i = bndind[ii]; - - myrinfo = graph->rinfo+i; - - if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */ - from = where[i]; - vwgt = graph->vwgt[i]; - - if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - j = myrinfo->id; - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - gain = myedegrees[k].ed-j; /* j = myrinfo->id. Allow good nodes to move */ - if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) || - (myedegrees[j].ed == myedegrees[k].ed && - itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) - k = j; - } - - to = myedegrees[k].pid; - - j = 0; - if (myedegrees[k].ed-myrinfo->id > 0) - j = 1; - else if (myedegrees[k].ed-myrinfo->id == 0) { - if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) - j = 1; - } - if (j == 0) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - INC_DEC(pwgts[to], pwgts[from], vwgt); - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed-myrinfo->id < 0) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - - } - nmoves++; - } - } - - graph->nbnd = nbnd; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, ComputeVolume(graph, where))); - - if (graph->mincut == oldcut) - break; - } - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); -} - - - - - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Greedy_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain; - int from, me, to, oldcut, vwgt; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts; - EDegreeType *myedegrees; - RInfoType *myrinfo; - PQueueType queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxwspacemalloc(ctrl, nvtxs); - - PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - PQueueReset(&queue); - idxset(nvtxs, -1, moved); - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id); - moved[i] = 2; - } - - for (iii=0;;iii++) { - if ((i = PQueueGetMax(&queue)) == -1) - break; - moved[i] = 1; - - myrinfo = graph->rinfo+i; - from = where[i]; - vwgt = graph->vwgt[i]; - - if (pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - j = myrinfo->id; - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - gain = myedegrees[k].ed-j; /* j = myrinfo->id. Allow good nodes to move */ - if (pwgts[to]+vwgt <= maxwgt[to]+gain && gain >= 0) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) || - (myedegrees[j].ed == myedegrees[k].ed && - itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) - k = j; - } - - to = myedegrees[k].pid; - - j = 0; - if (myedegrees[k].ed-myrinfo->id > 0) - j = 1; - else if (myedegrees[k].ed-myrinfo->id == 0) { - if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) - j = 1; - } - if (j == 0) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - INC_DEC(pwgts[to], pwgts[from], vwgt); - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed < myrinfo->id) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - oldgain = (myrinfo->ed-myrinfo->id); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - /* Update the queue */ - if (me == to || me == from) { - gain = myrinfo->ed-myrinfo->id; - if (moved[ii] == 2) { - if (gain >= 0) - PQueueUpdate(&queue, ii, oldgain, gain); - else { - PQueueDelete(&queue, ii, oldgain); - moved[ii] = -1; - } - } - else if (moved[ii] == -1 && gain >= 0) { - PQueueInsert(&queue, ii, gain); - moved[ii] = 2; - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - - } - } - - graph->nbnd = nbnd; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Cut: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, graph->mincut)); - - if (graph->mincut == oldcut) - break; - } - - PQueueFree(ctrl, &queue); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Greedy_KWayEdgeBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves; - int from, me, to, oldcut, vwgt; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts; - EDegreeType *myedegrees; - RInfoType *myrinfo; - PQueueType queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxwspacemalloc(ctrl, nvtxs); - - PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - /* Check to see if things are out of balance, given the tolerance */ - for (i=0; i<nparts; i++) { - if (pwgts[i] > maxwgt[i]) - break; - } - if (i == nparts) /* Things are balanced. Return right away */ - break; - - PQueueReset(&queue); - idxset(nvtxs, -1, moved); - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id); - moved[i] = 2; - } - - nmoves = 0; - for (;;) { - if ((i = PQueueGetMax(&queue)) == -1) - break; - moved[i] = 1; - - myrinfo = graph->rinfo+i; - from = where[i]; - vwgt = graph->vwgt[i]; - - if (pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) - k = j; - } - - to = myedegrees[k].pid; - - if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->id < 0) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - INC_DEC(pwgts[to], pwgts[from], vwgt); - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed == 0) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - oldgain = (myrinfo->ed-myrinfo->id); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed > 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed == 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - /* Update the queue */ - if (me == to || me == from) { - gain = myrinfo->ed-myrinfo->id; - if (moved[ii] == 2) { - if (myrinfo->ed > 0) - PQueueUpdate(&queue, ii, oldgain, gain); - else { - PQueueDelete(&queue, ii, oldgain); - moved[ii] = -1; - } - } - else if (moved[ii] == -1 && myrinfo->ed > 0) { - PQueueInsert(&queue, ii, gain); - moved[ii] = 2; - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - } - nmoves++; - } - - graph->nbnd = nbnd; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut)); - } - - PQueueFree(ctrl, &queue); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - diff --git a/Metis/kwayrefine.c b/Metis/kwayrefine.c deleted file mode 100644 index 8a9ff04008..0000000000 --- a/Metis/kwayrefine.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * kwayrefine.c - * - * This file contains the driving routines for multilevel k-way refinement - * - * Started 7/28/97 - * George - * - * $Id: kwayrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of refinement -**************************************************************************/ -void RefineKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *tpwgts, float ubfactor) -{ - int i, nlevels, mustfree=0; - GraphType *ptr; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - /* Compute the parameters of the coarsest graph */ - ComputeKWayPartitionParams(ctrl, graph, nparts); - - /* Take care any non-contiguity */ - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr1)); - if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) { - EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25); - EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts); - EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25); - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr1)); - - /* Determine how many levels are there */ - for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); - - for (i=0; ;i++) { - /* PrintSubDomainGraph(graph, nparts, graph->where); */ - if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN && (i == nlevels/2 || i == nlevels/2+1)) - EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - - if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) { - ComputeKWayBalanceBoundary(ctrl, graph, nparts); - if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) - Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); - else - Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); - ComputeKWayBoundary(ctrl, graph, nparts); - } - - switch (ctrl->RType) { - case RTYPE_KWAYRANDOM: - Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); - break; - case RTYPE_KWAYGREEDY: - Greedy_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10); - break; - case RTYPE_KWAYRANDOM_MCONN: - Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); - break; - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - GKfree(&graph->gdata, LTERM); /* Deallocate the graph related arrays */ - - graph = graph->finer; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - if (graph->vwgt == NULL) { - graph->vwgt = idxsmalloc(graph->nvtxs, 1, "RefineKWay: graph->vwgt"); - graph->adjwgt = idxsmalloc(graph->nedges, 1, "RefineKWay: graph->adjwgt"); - mustfree = 1; - } - ProjectKWayPartition(ctrl, graph, nparts); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) { - ComputeKWayBalanceBoundary(ctrl, graph, nparts); - if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) { - Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); - Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); - } - else { - Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); - Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); - } - } - - /* Take care any trivial non-contiguity */ - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr2)); - EliminateComponents(ctrl, graph, nparts, tpwgts, ubfactor); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr2)); - - if (mustfree) - GKfree(&graph->vwgt, &graph->adjwgt, LTERM); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - -/************************************************************************* -* This function allocates memory for k-way edge refinement -**************************************************************************/ -void AllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int nvtxs, pad64; - - nvtxs = graph->nvtxs; - - pad64 = (3*nvtxs+nparts)%2; - - graph->rdata = idxmalloc(3*nvtxs+nparts+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata"); - graph->pwgts = graph->rdata; - graph->where = graph->rdata + nparts; - graph->bndptr = graph->rdata + nvtxs + nparts; - graph->bndind = graph->rdata + 2*nvtxs + nparts; - graph->rinfo = (RInfoType *)(graph->rdata + 3*nvtxs+nparts + pad64); - -/* - if (ctrl->wspace.edegrees != NULL) - free(ctrl->wspace.edegrees); - ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateKWayPartitionMemory: edegrees"); -*/ -} - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void ComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, j, k, l, nvtxs, nbnd, mincut, me, other; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr; - RInfoType *rinfo, *myrinfo; - EDegreeType *myedegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = idxset(nparts, 0, graph->pwgts); - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - rinfo = graph->rinfo; - - - /*------------------------------------------------------------ - / Compute now the id/ed degrees - /------------------------------------------------------------*/ - ctrl->wspace.cdegree = 0; - nbnd = mincut = 0; - for (i=0; i<nvtxs; i++) { - me = where[i]; - pwgts[me] += vwgt[i]; - - myrinfo = rinfo+i; - myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; - myrinfo->edegrees = NULL; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me != where[adjncy[j]]) - myrinfo->ed += adjwgt[j]; - } - myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed; - - if (myrinfo->ed > 0) - mincut += myrinfo->ed; - - if (myrinfo->ed-myrinfo->id >= 0) - BNDInsert(nbnd, bndind, bndptr, i); - - /* Time to compute the particular external degrees */ - if (myrinfo->ed > 0) { - myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - other = where[adjncy[j]]; - if (me != other) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == other) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = other; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - } - - ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]); - } - } - - graph->mincut = mincut/2; - graph->nbnd = nbnd; - -} - - - -/************************************************************************* -* This function projects a partition, and at the same time computes the -* parameters for refinement. -**************************************************************************/ -void ProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees; - idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; - idxtype *cmap, *where, *bndptr, *bndind; - idxtype *cwhere; - GraphType *cgraph; - RInfoType *crinfo, *rinfo, *myrinfo; - EDegreeType *myedegrees; - idxtype *htable; - - cgraph = graph->coarser; - cwhere = cgraph->where; - crinfo = cgraph->rinfo; - - nvtxs = graph->nvtxs; - cmap = graph->cmap; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - - AllocateKWayPartitionMemory(ctrl, graph, nparts); - where = graph->where; - rinfo = graph->rinfo; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - /* Go through and project partition and compute id/ed for the nodes */ - for (i=0; i<nvtxs; i++) { - k = cmap[i]; - where[i] = cwhere[k]; - cmap[i] = crinfo[k].ed; /* For optimization */ - } - - htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); - - ctrl->wspace.cdegree = 0; - for (nbnd=0, i=0; i<nvtxs; i++) { - me = where[i]; - - myrinfo = rinfo+i; - myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; - myrinfo->edegrees = NULL; - - myrinfo->id = adjwgtsum[i]; - - if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */ - istart = xadj[i]; - iend = xadj[i+1]; - - myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += iend-istart; - - ndegrees = 0; - for (j=istart; j<iend; j++) { - other = where[adjncy[j]]; - if (me != other) { - myrinfo->ed += adjwgt[j]; - if ((k = htable[other]) == -1) { - htable[other] = ndegrees; - myedegrees[ndegrees].pid = other; - myedegrees[ndegrees++].ed = adjwgt[j]; - } - else { - myedegrees[k].ed += adjwgt[j]; - } - } - } - myrinfo->id -= myrinfo->ed; - - /* Remove space for edegrees if it was interior */ - if (myrinfo->ed == 0) { - myrinfo->edegrees = NULL; - ctrl->wspace.cdegree -= iend-istart; - } - else { - if (myrinfo->ed-myrinfo->id >= 0) - BNDInsert(nbnd, bndind, bndptr, i); - - myrinfo->ndegrees = ndegrees; - - for (j=0; j<ndegrees; j++) - htable[myedegrees[j].pid] = -1; - } - } - } - - idxcopy(nparts, cgraph->pwgts, graph->pwgts); - graph->mincut = cgraph->mincut; - graph->nbnd = nbnd; - - FreeGraph(graph->coarser); - graph->coarser = NULL; - - idxwspacefree(ctrl, nparts); - - ASSERT(CheckBnd2(graph)); - -} - - - -/************************************************************************* -* This function checks if the partition weights are within the balance -* contraints -**************************************************************************/ -int IsBalanced(idxtype *pwgts, int nparts, float *tpwgts, float ubfactor) -{ - int i, j, tvwgt; - - tvwgt = idxsum(nparts, pwgts); - for (i=0; i<nparts; i++) { - if (pwgts[i] > tpwgts[i]*tvwgt*(ubfactor+0.005)) - return 0; - } - - return 1; -} - - -/************************************************************************* -* This function computes the boundary definition for balancing -**************************************************************************/ -void ComputeKWayBoundary(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, nvtxs, nbnd; - idxtype *bndind, *bndptr; - - nvtxs = graph->nvtxs; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - - /*------------------------------------------------------------ - / Compute the new boundary - /------------------------------------------------------------*/ - nbnd = 0; - for (i=0; i<nvtxs; i++) { - if (graph->rinfo[i].ed-graph->rinfo[i].id >= 0) - BNDInsert(nbnd, bndind, bndptr, i); - } - - graph->nbnd = nbnd; -} - -/************************************************************************* -* This function computes the boundary definition for balancing -**************************************************************************/ -void ComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, nvtxs, nbnd; - idxtype *bndind, *bndptr; - - nvtxs = graph->nvtxs; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - - /*------------------------------------------------------------ - / Compute the new boundary - /------------------------------------------------------------*/ - nbnd = 0; - for (i=0; i<nvtxs; i++) { - if (graph->rinfo[i].ed > 0) - BNDInsert(nbnd, bndind, bndptr, i); - } - - graph->nbnd = nbnd; -} - diff --git a/Metis/kwayvolfm.c b/Metis/kwayvolfm.c deleted file mode 100644 index 16ce80b29a..0000000000 --- a/Metis/kwayvolfm.c +++ /dev/null @@ -1,1778 +0,0 @@ -/* - * kwayvolfm.c - * - * This file contains code that implements the multilevel k-way refinement - * - * Started 7/8/98 - * George - * - * $Id: kwayvolfm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Random_KWayVolRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, - float ubfactor, int npasses, int ffactor) -{ - int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; - int from, me, to, oldcut, oldvol, vwgt; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; - VEDegreeType *myedegrees; - VRInfoType *myrinfo; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); - marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); - phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut, graph->minvol)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - oldcut = graph->mincut; - oldvol = graph->minvol; - - RandomPermute(graph->nbnd, perm, 1); - for (nmoves=iii=0; iii<graph->nbnd; iii++) { - ii = perm[iii]; - if (ii >= graph->nbnd) - continue; - i = bndind[ii]; - myrinfo = graph->vrinfo+i; - - if (myrinfo->gv >= 0) { /* Total volume gain is too high */ - from = where[i]; - vwgt = graph->vwgt[i]; - - if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*myedegrees[k].gv && xgain+myedegrees[k].gv >= 0) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (pwgts[to]+vwgt > maxwgt[to]) - continue; - if (myedegrees[j].gv > myedegrees[k].gv || - (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) || - (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed == myedegrees[k].ed && - itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) - k = j; - } - - to = myedegrees[k].pid; - - j = 0; - if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->id > 0) - j = 1; - else if (myedegrees[k].ed-myrinfo->id == 0) { - if ((iii&5) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) - j = 1; - } - if (j == 0) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - INC_DEC(pwgts[to], pwgts[from], vwgt); - graph->mincut -= myedegrees[k].ed-myrinfo->id; - graph->minvol -= (xgain+myedegrees[k].gv); - where[i] = to; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", - i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); - - KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); - - nmoves++; - - /* CheckVolKWayPartitionParams(ctrl, graph, nparts); */ - } - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, - graph->minvol)); - - if (graph->minvol == oldvol && graph->mincut == oldcut) - break; - } - - GKfree(&marker, &updind, &phtable, LTERM); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Random_KWayVolRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, - float ubfactor, int npasses, int ffactor) -{ - int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; - int from, me, to, oldcut, oldvol, vwgt, nadd, maxndoms; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; - idxtype *pmat, *pmatptr, *ndoms; - VEDegreeType *myedegrees; - VRInfoType *myrinfo; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); - marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); - phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); - - pmat = ctrl->wspace.pmat; - ndoms = idxwspacemalloc(ctrl, nparts); - - ComputeVolSubDomainGraph(graph, nparts, pmat, ndoms); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut, graph->minvol)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - maxndoms = ndoms[idxamax(nparts, ndoms)]; - - oldcut = graph->mincut; - oldvol = graph->minvol; - - RandomPermute(graph->nbnd, perm, 1); - for (nmoves=iii=0; iii<graph->nbnd; iii++) { - ii = perm[iii]; - if (ii >= graph->nbnd) - continue; - i = bndind[ii]; - myrinfo = graph->vrinfo+i; - - if (myrinfo->gv >= 0) { /* Total volume gain is too high */ - from = where[i]; - vwgt = graph->vwgt[i]; - - if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - /* Determine the valid domains */ - for (j=0; j<myndegrees; j++) { - to = myedegrees[j].pid; - phtable[to] = 1; - pmatptr = pmat + to*nparts; - for (nadd=0, k=0; k<myndegrees; k++) { - if (k == j) - continue; - - l = myedegrees[k].pid; - if (pmatptr[l] == 0) { - if (ndoms[l] > maxndoms-1) { - phtable[to] = 0; - nadd = maxndoms; - break; - } - nadd++; - } - } - if (ndoms[to]+nadd > maxndoms) - phtable[to] = 0; - if (nadd == 0) - phtable[to] = 2; - } - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (!phtable[to]) - continue; - if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*myedegrees[k].gv && xgain+myedegrees[k].gv >= 0) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (!phtable[to] || pwgts[to]+vwgt > maxwgt[to]) - continue; - if (myedegrees[j].gv > myedegrees[k].gv || - (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) || - (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed == myedegrees[k].ed && - itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) - k = j; - } - - to = myedegrees[k].pid; - - j = 0; - if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->id > 0) - j = 1; - else if (myedegrees[k].ed-myrinfo->id == 0) { - if ((iii&5) == 0 || phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) - j = 1; - } - - if (j == 0) - continue; - - for (j=0; j<myndegrees; j++) - phtable[myedegrees[j].pid] = -1; - - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - INC_DEC(pwgts[to], pwgts[from], vwgt); - graph->mincut -= myedegrees[k].ed-myrinfo->id; - graph->minvol -= (xgain+myedegrees[k].gv); - where[i] = to; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", - i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); - - /* Update pmat to reflect the move of 'i' */ - pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); - pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); - if (pmat[from*nparts+to] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[to*nparts+from] == 0) { - ndoms[to]--; - if (ndoms[to]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ - if (me != from && me != to) { - pmat[me*nparts+from] -= adjwgt[j]; - pmat[from*nparts+me] -= adjwgt[j]; - if (pmat[me*nparts+from] == 0) { - ndoms[me]--; - if (ndoms[me]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[from*nparts+me] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - if (pmat[me*nparts+to] == 0) { - ndoms[me]++; - if (ndoms[me] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms); - maxndoms = ndoms[me]; - } - } - if (pmat[to*nparts+me] == 0) { - ndoms[to]++; - if (ndoms[to] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms); - maxndoms = ndoms[to]; - } - } - pmat[me*nparts+to] += adjwgt[j]; - pmat[to*nparts+me] += adjwgt[j]; - } - } - - KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); - - nmoves++; - - /* CheckVolKWayPartitionParams(ctrl, graph, nparts); */ - } - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, - graph->minvol)); - - if (graph->minvol == oldvol && graph->mincut == oldcut) - break; - } - - GKfree(&marker, &updind, &phtable, LTERM); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); -} - - - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Greedy_KWayVolBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, - float ubfactor, int npasses) -{ - int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; - int from, me, to, vwgt, gain; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; - VEDegreeType *myedegrees; - VRInfoType *myrinfo; - PQueueType queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); - marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); - phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxwspacemalloc(ctrl, nvtxs); - - PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut, graph->minvol)); - - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - /* Check to see if things are out of balance, given the tolerance */ - for (i=0; i<nparts; i++) { - if (pwgts[i] > maxwgt[i]) - break; - } - if (i == nparts) /* Things are balanced. Return right away */ - break; - - PQueueReset(&queue); - idxset(nvtxs, -1, moved); - - RandomPermute(graph->nbnd, perm, 1); - for (ii=0; ii<graph->nbnd; ii++) { - i = bndind[perm[ii]]; - PQueueInsert(&queue, i, graph->vrinfo[i].gv); - moved[i] = 2; - } - - for (nmoves=0;;) { - if ((i = PQueueGetMax(&queue)) == -1) - break; - moved[i] = 1; - - myrinfo = graph->vrinfo+i; - from = where[i]; - vwgt = graph->vwgt[i]; - - if (pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (pwgts[to]+vwgt <= maxwgt[to] || - itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) - k = j; - } - - to = myedegrees[k].pid; - - if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && - (xgain+myedegrees[k].gv < 0 || - (xgain+myedegrees[k].gv == 0 && myedegrees[k].ed-myrinfo->id < 0)) - ) - continue; - - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - INC_DEC(pwgts[to], pwgts[from], vwgt); - graph->mincut -= myedegrees[k].ed-myrinfo->id; - graph->minvol -= (xgain+myedegrees[k].gv); - where[i] = to; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", - i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); - - KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); - - nmoves++; - - /*CheckVolKWayPartitionParams(ctrl, graph, nparts); */ - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, - graph->minvol)); - - } - - GKfree(&marker, &updind, &phtable, LTERM); - - PQueueFree(ctrl, &queue); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Greedy_KWayVolBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, - float ubfactor, int npasses) -{ - int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; - int from, me, to, vwgt, gain, maxndoms, nadd; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; - idxtype *pmat, *pmatptr, *ndoms; - VEDegreeType *myedegrees; - VRInfoType *myrinfo; - PQueueType queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - pwgts = graph->pwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); - marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); - phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); - - pmat = ctrl->wspace.pmat; - ndoms = idxwspacemalloc(ctrl, nparts); - - ComputeVolSubDomainGraph(graph, nparts, pmat, ndoms); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxwspacemalloc(ctrl, nvtxs); - - PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut, graph->minvol)); - - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - /* Check to see if things are out of balance, given the tolerance */ - for (i=0; i<nparts; i++) { - if (pwgts[i] > maxwgt[i]) - break; - } - if (i == nparts) /* Things are balanced. Return right away */ - break; - - PQueueReset(&queue); - idxset(nvtxs, -1, moved); - - RandomPermute(graph->nbnd, perm, 1); - for (ii=0; ii<graph->nbnd; ii++) { - i = bndind[perm[ii]]; - PQueueInsert(&queue, i, graph->vrinfo[i].gv); - moved[i] = 2; - } - - maxndoms = ndoms[idxamax(nparts, ndoms)]; - - for (nmoves=0;;) { - if ((i = PQueueGetMax(&queue)) == -1) - break; - moved[i] = 1; - - myrinfo = graph->vrinfo+i; - from = where[i]; - vwgt = graph->vwgt[i]; - - if (pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - /* Determine the valid domains */ - for (j=0; j<myndegrees; j++) { - to = myedegrees[j].pid; - phtable[to] = 1; - pmatptr = pmat + to*nparts; - for (nadd=0, k=0; k<myndegrees; k++) { - if (k == j) - continue; - - l = myedegrees[k].pid; - if (pmatptr[l] == 0) { - if (ndoms[l] > maxndoms-1) { - phtable[to] = 0; - nadd = maxndoms; - break; - } - nadd++; - } - } - if (ndoms[to]+nadd > maxndoms) - phtable[to] = 0; - } - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (!phtable[to]) - continue; - if (pwgts[to]+vwgt <= maxwgt[to] || - itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (!phtable[to]) - continue; - if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) - k = j; - } - - to = myedegrees[k].pid; - - for (j=0; j<myndegrees; j++) - phtable[myedegrees[j].pid] = -1; - - if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && - (xgain+myedegrees[k].gv < 0 || - (xgain+myedegrees[k].gv == 0 && myedegrees[k].ed-myrinfo->id < 0)) - ) - continue; - - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - INC_DEC(pwgts[to], pwgts[from], vwgt); - graph->mincut -= myedegrees[k].ed-myrinfo->id; - graph->minvol -= (xgain+myedegrees[k].gv); - where[i] = to; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", - i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); - - /* Update pmat to reflect the move of 'i' */ - pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); - pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); - if (pmat[from*nparts+to] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[to*nparts+from] == 0) { - ndoms[to]--; - if (ndoms[to]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ - if (me != from && me != to) { - pmat[me*nparts+from] -= adjwgt[j]; - pmat[from*nparts+me] -= adjwgt[j]; - if (pmat[me*nparts+from] == 0) { - ndoms[me]--; - if (ndoms[me]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[from*nparts+me] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - if (pmat[me*nparts+to] == 0) { - ndoms[me]++; - if (ndoms[me] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms); - maxndoms = ndoms[me]; - } - } - if (pmat[to*nparts+me] == 0) { - ndoms[to]++; - if (ndoms[to] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms); - maxndoms = ndoms[to]; - } - } - pmat[me*nparts+to] += adjwgt[j]; - pmat[to*nparts+me] += adjwgt[j]; - } - } - - KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); - - nmoves++; - - /*CheckVolKWayPartitionParams(ctrl, graph, nparts); */ - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, - graph->minvol)); - - } - - GKfree(&marker, &updind, &phtable, LTERM); - - PQueueFree(ctrl, &queue); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - - -/************************************************************************* -* This function updates the edge and volume gains as a result of moving -* v from 'from' to 'to'. -* The working arrays marker and phtable are assumed to be initialized to -* -1, and they left to -1 upon return -**************************************************************************/ -void KWayVolUpdate(CtrlType *ctrl, GraphType *graph, int v, int from, int to, - idxtype *marker, idxtype *phtable, idxtype *updind) -{ - int ii, iii, j, jj, k, kk, l, u, nupd, other, me, myidx; - idxtype *xadj, *vsize, *adjncy, *adjwgt, *where; - VEDegreeType *myedegrees, *oedegrees; - VRInfoType *myrinfo, *orinfo; - - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - vsize = graph->vsize; - where = graph->where; - - myrinfo = graph->vrinfo+v; - myedegrees = myrinfo->edegrees; - - - /*====================================================================== - * Remove the contributions on the gain made by 'v'. - *=====================================================================*/ - for (k=0; k<myrinfo->ndegrees; k++) - phtable[myedegrees[k].pid] = k; - phtable[from] = k; - - myidx = phtable[to]; /* Keep track of the index in myedegrees of the 'to' domain */ - - for (j=xadj[v]; j<xadj[v+1]; j++) { - ii = adjncy[j]; - other = where[ii]; - orinfo = graph->vrinfo+ii; - oedegrees = orinfo->edegrees; - - if (other == from) { - for (k=0; k<orinfo->ndegrees; k++) { - if (phtable[oedegrees[k].pid] == -1) - oedegrees[k].gv += vsize[v]; - } - } - else { - ASSERT(phtable[other] != -1); - - if (myedegrees[phtable[other]].ned > 1) { - for (k=0; k<orinfo->ndegrees; k++) { - if (phtable[oedegrees[k].pid] == -1) - oedegrees[k].gv += vsize[v]; - } - } - else { /* There is only one connection */ - for (k=0; k<orinfo->ndegrees; k++) { - if (phtable[oedegrees[k].pid] != -1) - oedegrees[k].gv -= vsize[v]; - } - } - } - } - - for (k=0; k<myrinfo->ndegrees; k++) - phtable[myedegrees[k].pid] = -1; - phtable[from] = -1; - - - /*====================================================================== - * Update the id/ed of vertex 'v' - *=====================================================================*/ - myrinfo->ed += myrinfo->id-myedegrees[myidx].ed; - SWAP(myrinfo->id, myedegrees[myidx].ed, j); - SWAP(myrinfo->nid, myedegrees[myidx].ned, j); - if (myedegrees[myidx].ed == 0) - myedegrees[myidx] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[myidx].pid = from; - - /*====================================================================== - * Update the degrees of adjacent vertices and their volume gains - *=====================================================================*/ - marker[v] = 1; - updind[0] = v; - nupd = 1; - for (j=xadj[v]; j<xadj[v+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - if (!marker[ii]) { /* The marking is done for boundary and max gv calculations */ - marker[ii] = 2; - updind[nupd++] = ii; - } - - myrinfo = graph->vrinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - myrinfo->nid--; - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - myrinfo->nid++; - } - - /* Remove the edgeweight from the 'pid == from' entry of the vertex */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ned == 1) { - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - marker[ii] = 1; /* You do a complete .gv calculation */ - - /* All vertices adjacent to 'ii' need to be updated */ - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { - u = adjncy[jj]; - other = where[u]; - orinfo = graph->vrinfo+u; - oedegrees = orinfo->edegrees; - - for (kk=0; kk<orinfo->ndegrees; kk++) { - if (oedegrees[kk].pid == from) { - oedegrees[kk].gv -= vsize[ii]; - break; - } - } - } - } - else { - myedegrees[k].ed -= adjwgt[j]; - myedegrees[k].ned--; - - /* Update the gv due to single 'ii' connection to 'from' */ - if (myedegrees[k].ned == 1) { - /* find the vertex 'u' that 'ii' was connected into 'from' */ - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { - u = adjncy[jj]; - other = where[u]; - orinfo = graph->vrinfo+u; - oedegrees = orinfo->edegrees; - - if (other == from) { - for (kk=0; kk<orinfo->ndegrees; kk++) - oedegrees[kk].gv += vsize[ii]; - break; - } - } - } - } - - break; - } - } - } - - /* Add the edgeweight to the 'pid == to' entry of the vertex */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - myedegrees[k].ned++; - - /* Update the gv due to non-single 'ii' connection to 'to' */ - if (myedegrees[k].ned == 2) { - /* find the vertex 'u' that 'ii' was connected into 'to' */ - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { - u = adjncy[jj]; - other = where[u]; - orinfo = graph->vrinfo+u; - oedegrees = orinfo->edegrees; - - if (u != v && other == to) { - for (kk=0; kk<orinfo->ndegrees; kk++) - oedegrees[kk].gv -= vsize[ii]; - break; - } - } - } - break; - } - } - - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees].ed = adjwgt[j]; - myedegrees[myrinfo->ndegrees++].ned = 1; - marker[ii] = 1; /* You do a complete .gv calculation */ - - /* All vertices adjacent to 'ii' need to be updated */ - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { - u = adjncy[jj]; - other = where[u]; - orinfo = graph->vrinfo+u; - oedegrees = orinfo->edegrees; - - for (kk=0; kk<orinfo->ndegrees; kk++) { - if (oedegrees[kk].pid == to) { - oedegrees[kk].gv += vsize[ii]; - if (!marker[u]) { /* Need to update boundary etc */ - marker[u] = 2; - updind[nupd++] = u; - } - break; - } - } - } - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - } - - /*====================================================================== - * Add the contributions on the volume gain due to 'v' - *=====================================================================*/ - myrinfo = graph->vrinfo+v; - myedegrees = myrinfo->edegrees; - for (k=0; k<myrinfo->ndegrees; k++) - phtable[myedegrees[k].pid] = k; - phtable[to] = k; - - for (j=xadj[v]; j<xadj[v+1]; j++) { - ii = adjncy[j]; - other = where[ii]; - orinfo = graph->vrinfo+ii; - oedegrees = orinfo->edegrees; - - if (other == to) { - for (k=0; k<orinfo->ndegrees; k++) { - if (phtable[oedegrees[k].pid] == -1) - oedegrees[k].gv -= vsize[v]; - } - } - else { - ASSERT(phtable[other] != -1); - - if (myedegrees[phtable[other]].ned > 1) { - for (k=0; k<orinfo->ndegrees; k++) { - if (phtable[oedegrees[k].pid] == -1) - oedegrees[k].gv -= vsize[v]; - } - } - else { /* There is only one connection */ - for (k=0; k<orinfo->ndegrees; k++) { - if (phtable[oedegrees[k].pid] != -1) - oedegrees[k].gv += vsize[v]; - } - } - } - } - for (k=0; k<myrinfo->ndegrees; k++) - phtable[myedegrees[k].pid] = -1; - phtable[to] = -1; - - - /*====================================================================== - * Recompute the volume information of the 'hard' nodes, and update the - * max volume gain for all the update vertices - *=====================================================================*/ - ComputeKWayVolume(graph, nupd, updind, marker, phtable); - - - /*====================================================================== - * Maintain a consistent boundary - *=====================================================================*/ - for (j=0; j<nupd; j++) { - k = updind[j]; - marker[k] = 0; - myrinfo = graph->vrinfo+k; - - if ((myrinfo->gv >= 0 || myrinfo->ed-myrinfo->id >= 0) && graph->bndptr[k] == -1) - BNDInsert(graph->nbnd, graph->bndind, graph->bndptr, k); - - if (myrinfo->gv < 0 && myrinfo->ed-myrinfo->id < 0 && graph->bndptr[k] != -1) - BNDDelete(graph->nbnd, graph->bndind, graph->bndptr, k); - } - -} - - - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void ComputeKWayVolume(GraphType *graph, int nupd, idxtype *updind, idxtype *marker, idxtype *phtable) -{ - int ii, iii, i, j, k, kk, l, nvtxs, me, other, pid; - idxtype *xadj, *vsize, *adjncy, *adjwgt, *where; - VRInfoType *rinfo, *myrinfo, *orinfo; - VEDegreeType *myedegrees, *oedegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vsize = graph->vsize; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - rinfo = graph->vrinfo; - - - /*------------------------------------------------------------ - / Compute now the iv/ev degrees - /------------------------------------------------------------*/ - for (iii=0; iii<nupd; iii++) { - i = updind[iii]; - me = where[i]; - - myrinfo = rinfo+i; - myedegrees = myrinfo->edegrees; - - if (marker[i] == 1) { /* Only complete gain updates go through */ - for (k=0; k<myrinfo->ndegrees; k++) - myedegrees[k].gv = 0; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - other = where[ii]; - orinfo = rinfo+ii; - oedegrees = orinfo->edegrees; - - for (kk=0; kk<orinfo->ndegrees; kk++) - phtable[oedegrees[kk].pid] = kk; - phtable[other] = 1; - - if (me == other) { - /* Find which domains 'i' is connected and 'ii' is not and update their gain */ - for (k=0; k<myrinfo->ndegrees; k++) { - if (phtable[myedegrees[k].pid] == -1) - myedegrees[k].gv -= vsize[ii]; - } - } - else { - ASSERT(phtable[me] != -1); - - /* I'm the only connection of 'ii' in 'me' */ - if (oedegrees[phtable[me]].ned == 1) { - /* Increase the gains for all the common domains between 'i' and 'ii' */ - for (k=0; k<myrinfo->ndegrees; k++) { - if (phtable[myedegrees[k].pid] != -1) - myedegrees[k].gv += vsize[ii]; - } - } - else { - /* Find which domains 'i' is connected and 'ii' is not and update their gain */ - for (k=0; k<myrinfo->ndegrees; k++) { - if (phtable[myedegrees[k].pid] == -1) - myedegrees[k].gv -= vsize[ii]; - } - } - } - - for (kk=0; kk<orinfo->ndegrees; kk++) - phtable[oedegrees[kk].pid] = -1; - phtable[other] = -1; - - } - } - - myrinfo->gv = -MAXIDX; - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].gv > myrinfo->gv) - myrinfo->gv = myedegrees[k].gv; - } - if (myrinfo->ed > 0 && myrinfo->id == 0) - myrinfo->gv += vsize[i]; - - } - -} - - - -/************************************************************************* -* This function computes the total volume -**************************************************************************/ -int ComputeVolume(GraphType *graph, idxtype *where) -{ - int i, j, k, me, nvtxs, nparts, totalv; - idxtype *xadj, *adjncy, *vsize, *marker; - - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vsize = (graph->vsize == NULL ? graph->vwgt : graph->vsize); - - nparts = where[idxamax(nvtxs, where)]+1; - marker = idxsmalloc(nparts, -1, "ComputeVolume: marker"); - - totalv = 0; - - for (i=0; i<nvtxs; i++) { - marker[where[i]] = i; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = where[adjncy[j]]; - if (marker[k] != i) { - marker[k] = i; - totalv += vsize[i]; - } - } - } - - free(marker); - - return totalv; -} - - - - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void CheckVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, ii, j, k, kk, l, nvtxs, nbnd, mincut, minvol, me, other, pid; - idxtype *xadj, *vsize, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr; - VRInfoType *rinfo, *myrinfo, *orinfo, tmprinfo; - VEDegreeType *myedegrees, *oedegrees, *tmpdegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vsize = graph->vsize; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - rinfo = graph->vrinfo; - - tmpdegrees = (VEDegreeType *)GKmalloc(nparts*sizeof(VEDegreeType), "CheckVolKWayPartitionParams: tmpdegrees"); - - /*------------------------------------------------------------ - / Compute now the iv/ev degrees - /------------------------------------------------------------*/ - for (i=0; i<nvtxs; i++) { - me = where[i]; - - myrinfo = rinfo+i; - myedegrees = myrinfo->edegrees; - - for (k=0; k<myrinfo->ndegrees; k++) - tmpdegrees[k] = myedegrees[k]; - - tmprinfo.ndegrees = myrinfo->ndegrees; - tmprinfo.id = myrinfo->id; - tmprinfo.ed = myrinfo->ed; - - myrinfo = &tmprinfo; - myedegrees = tmpdegrees; - - - for (k=0; k<myrinfo->ndegrees; k++) - myedegrees[k].gv = 0; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - other = where[ii]; - orinfo = rinfo+ii; - oedegrees = orinfo->edegrees; - - if (me == other) { - /* Find which domains 'i' is connected and 'ii' is not and update their gain */ - for (k=0; k<myrinfo->ndegrees; k++) { - pid = myedegrees[k].pid; - for (kk=0; kk<orinfo->ndegrees; kk++) { - if (oedegrees[kk].pid == pid) - break; - } - if (kk == orinfo->ndegrees) - myedegrees[k].gv -= vsize[ii]; - } - } - else { - /* Find the orinfo[me].ed and see if I'm the only connection */ - for (k=0; k<orinfo->ndegrees; k++) { - if (oedegrees[k].pid == me) - break; - } - - if (oedegrees[k].ned == 1) { /* I'm the only connection of 'ii' in 'me' */ - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == other) { - myedegrees[k].gv += vsize[ii]; - break; - } - } - - /* Increase the gains for all the common domains between 'i' and 'ii' */ - for (k=0; k<myrinfo->ndegrees; k++) { - if ((pid = myedegrees[k].pid) == other) - continue; - for (kk=0; kk<orinfo->ndegrees; kk++) { - if (oedegrees[kk].pid == pid) { - myedegrees[k].gv += vsize[ii]; - break; - } - } - } - - } - else { - /* Find which domains 'i' is connected and 'ii' is not and update their gain */ - for (k=0; k<myrinfo->ndegrees; k++) { - if ((pid = myedegrees[k].pid) == other) - continue; - for (kk=0; kk<orinfo->ndegrees; kk++) { - if (oedegrees[kk].pid == pid) - break; - } - if (kk == orinfo->ndegrees) - myedegrees[k].gv -= vsize[ii]; - } - } - } - } - - myrinfo = rinfo+i; - myedegrees = myrinfo->edegrees; - - for (k=0; k<myrinfo->ndegrees; k++) { - pid = myedegrees[k].pid; - for (kk=0; kk<tmprinfo.ndegrees; kk++) { - if (tmpdegrees[kk].pid == pid) { - if (tmpdegrees[kk].gv != myedegrees[k].gv) - printf("[%d %d %d %d]\n", i, pid, myedegrees[k].gv, tmpdegrees[kk].gv); - break; - } - } - } - - } - - free(tmpdegrees); - -} - - -/************************************************************************* -* This function computes the subdomain graph -**************************************************************************/ -void ComputeVolSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms) -{ - int i, j, k, me, nvtxs, ndegrees; - idxtype *xadj, *adjncy, *adjwgt, *where; - VRInfoType *rinfo; - VEDegreeType *edegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - rinfo = graph->vrinfo; - - idxset(nparts*nparts, 0, pmat); - - for (i=0; i<nvtxs; i++) { - if (rinfo[i].ed > 0) { - me = where[i]; - ndegrees = rinfo[i].ndegrees; - edegrees = rinfo[i].edegrees; - - k = me*nparts; - for (j=0; j<ndegrees; j++) - pmat[k+edegrees[j].pid] += edegrees[j].ed; - } - } - - for (i=0; i<nparts; i++) { - ndoms[i] = 0; - for (j=0; j<nparts; j++) { - if (pmat[i*nparts+j] > 0) - ndoms[i]++; - } - } -} - - - -/************************************************************************* -* This function computes the subdomain graph -**************************************************************************/ -void EliminateVolSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts) -{ - int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd; - int min, move, cpwgt, tvwgt; - idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind; - KeyValueType *cand, *cand2; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = idxset(nparts, 0, graph->pwgts); - - maxpwgt = idxwspacemalloc(ctrl, nparts); - ndoms = idxwspacemalloc(ctrl, nparts); - otherpmat = idxwspacemalloc(ctrl, nparts); - ind = idxwspacemalloc(ctrl, nvtxs); - pmat = idxset(nparts*nparts, 0, ctrl->wspace.pmat); - - cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); - cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); - - /* Compute the pmat matrix */ - for (i=0; i<nvtxs; i++) { - me = where[i]; - pwgts[me] += vwgt[i]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] != me) - pmat[me*nparts+where[k]] += adjwgt[j]; - } - } - - /* Compute the maximum allowed weight for each domain */ - tvwgt = idxsum(nparts, pwgts); - for (i=0; i<nparts; i++) - maxpwgt[i] = 1.25*tpwgts[i]*tvwgt; - - /* Determine the domain connectivity */ - for (i=0; i<nparts; i++) { - for (k=0, j=0; j<nparts; j++) { - if (pmat[i*nparts+j] > 0) - k++; - } - ndoms[i] = k; - } - - /* Get into the loop eliminating subdomain connections */ - for (;;) { - total = idxsum(nparts, ndoms); - avg = total/nparts; - max = ndoms[idxamax(nparts, ndoms)]; - - /* printf("Adjacent Subdomain Stats: Total: %3d, Max: %3d, Avg: %3d\n", total, max, avg); */ - - if (max < 1.5*avg) - break; - - me = idxamax(nparts, ndoms); - mypmat = pmat + me*nparts; - totalout = idxsum(nparts, mypmat); - - /*printf("Me: %d, TotalOut: %d,\n", me, totalout);*/ - - /* Sort the connections according to their cut */ - for (ncand2=0, i=0; i<nparts; i++) { - if (mypmat[i] > 0) { - cand2[ncand2].key = mypmat[i]; - cand2[ncand2++].val = i; - } - } - ikeysort(ncand2, cand2); - - move = 0; - for (min=0; min<ncand2; min++) { - if (cand2[min].key > totalout/(2*ndoms[me])) - break; - - other = cand2[min].val; - - /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/ - - idxset(nparts, 0, otherpmat); - - /* Go and find the vertices in 'other' that are connected in 'me' */ - for (nind=0, i=0; i<nvtxs; i++) { - if (where[i] == other) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (where[adjncy[j]] == me) { - ind[nind++] = i; - break; - } - } - } - } - - /* Go and construct the otherpmat to see where these nind vertices are connected to */ - for (cpwgt=0, ii=0; ii<nind; ii++) { - i = ind[ii]; - cpwgt += vwgt[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] != other) - otherpmat[where[k]] += adjwgt[j]; - } - } - - for (ncand=0, i=0; i<nparts; i++) { - if (otherpmat[i] > 0) { - cand[ncand].key = -otherpmat[i]; - cand[ncand++].val = i; - } - } - ikeysort(ncand, cand); - - /* - * Go through and the select the first domain that is common with 'me', and - * does not increase the ndoms[target] higher than my ndoms, subject to the - * maxpwgt constraint. Traversal is done from the mostly connected to the least. - */ - target = target2 = -1; - for (i=0; i<ncand; i++) { - k = cand[i].val; - - if (mypmat[k] > 0) { - if (pwgts[k] + cpwgt > maxpwgt[k]) /* Check if balance will go off */ - continue; - - for (j=0; j<nparts; j++) { - if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0) - break; - } - if (j == nparts) { /* No bad second level effects */ - for (nadd=0, j=0; j<nparts; j++) { - if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0) - nadd++; - } - - /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/ - if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) { - target2 = k; - } - if (nadd == 0) { - target = k; - break; - } - } - } - } - if (target == -1 && target2 != -1) - target = target2; - - if (target == -1) { - /* printf("\t\tCould not make the move\n");*/ - continue; - } - - /*printf("\t\tMoving to %d\n", target);*/ - - /* Update the partition weights */ - INC_DEC(pwgts[target], pwgts[other], cpwgt); - - /* Set all nind vertices to belong to 'target' */ - for (ii=0; ii<nind; ii++) { - i = ind[ii]; - where[i] = target; - - /* First remove any contribution that this vertex may have made */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] != other) { - if (pmat[nparts*other + where[k]] == 0) - printf("Something wrong\n"); - pmat[nparts*other + where[k]] -= adjwgt[j]; - if (pmat[nparts*other + where[k]] == 0) - ndoms[other]--; - - if (pmat[nparts*where[k] + other] == 0) - printf("Something wrong\n"); - pmat[nparts*where[k] + other] -= adjwgt[j]; - if (pmat[nparts*where[k] + other] == 0) - ndoms[where[k]]--; - } - } - - /* Next add the new contributions as a result of the move */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] != target) { - if (pmat[nparts*target + where[k]] == 0) - ndoms[target]++; - pmat[nparts*target + where[k]] += adjwgt[j]; - - if (pmat[nparts*where[k] + target] == 0) - ndoms[where[k]]++; - pmat[nparts*where[k] + target] += adjwgt[j]; - } - } - } - - move = 1; - break; - } - - if (move == 0) - break; - } - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - - GKfree(&cand, &cand2, LTERM); -} - - - -/************************************************************************* -* This function finds all the connected components induced by the -* partitioning vector in wgraph->where and tries to push them around to -* remove some of them -**************************************************************************/ -void EliminateVolComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor) -{ - int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, ncand, other, target, deltawgt; - idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt; - idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps; - KeyValueType *cand; - int recompute=0; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = idxset(nparts, 0, graph->pwgts); - - touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs)); - cptr = idxwspacemalloc(ctrl, nvtxs); - cind = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - todo = idxwspacemalloc(ctrl, nvtxs); - maxpwgt = idxwspacemalloc(ctrl, nparts); - cpvec = idxwspacemalloc(ctrl, nparts); - npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts)); - - for (i=0; i<nvtxs; i++) - perm[i] = todo[i] = i; - - /* Find the connected componends induced by the partition */ - ncmps = -1; - first = last = 0; - nleft = nvtxs; - while (nleft > 0) { - if (first == last) { /* Find another starting vertex */ - cptr[++ncmps] = first; - ASSERT(touched[todo[0]] == 0); - i = todo[0]; - cind[last++] = i; - touched[i] = 1; - me = where[i]; - npcmps[me]++; - } - - i = cind[first++]; - k = perm[i]; - j = todo[k] = todo[--nleft]; - perm[j] = k; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] == me && !touched[k]) { - cind[last++] = k; - touched[k] = 1; - } - } - } - cptr[++ncmps] = first; - - /* printf("I found %d components, for this %d-way partition\n", ncmps, nparts); */ - - if (ncmps > nparts) { /* There are more components than processors */ - cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); - - /* First determine the partition sizes and max allowed load imbalance */ - for (i=0; i<nvtxs; i++) - pwgts[where[i]] += vwgt[i]; - tvwgt = idxsum(nparts, pwgts); - for (i=0; i<nparts; i++) - maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt; - - deltawgt = tvwgt/(100*nparts); - deltawgt = 5; - - for (i=0; i<ncmps; i++) { - me = where[cind[cptr[i]]]; /* Get the domain of this component */ - if (npcmps[me] == 1) - continue; /* Skip it because it is contigous */ - - /*printf("Trying to move %d from %d\n", i, me); */ - - /* Determine the connectivity */ - idxset(nparts, 0, cpvec); - for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++) { - ii = cind[j]; - cwgt += vwgt[ii]; - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { - other = where[adjncy[jj]]; - if (me != other) - cpvec[other] += adjwgt[jj]; - } - } - - /*printf("\tCmp weight: %d\n", cwgt);*/ - - if (cwgt > .30*pwgts[me]) - continue; /* Skip the component if it is over 30% of the weight */ - - for (ncand=0, j=0; j<nparts; j++) { - if (cpvec[j] > 0) { - cand[ncand].key = -cpvec[j]; - cand[ncand++].val = j; - } - } - if (ncand == 0) - continue; - - ikeysort(ncand, cand); - - target = -1; - for (j=0; j<ncand; j++) { - k = cand[j].val; - if (cwgt < deltawgt || pwgts[k] + cwgt < maxpwgt[k]) { - target = k; - break; - } - } - - /*printf("\tMoving it to %d [%d]\n", target, cpvec[target]);*/ - - if (target != -1) { - /* Assign all the vertices of 'me' to 'target' and update data structures */ - pwgts[me] -= cwgt; - pwgts[target] += cwgt; - npcmps[me]--; - - for (j=cptr[i]; j<cptr[i+1]; j++) - where[cind[j]] = target; - - graph->mincut -= cpvec[target]; - recompute = 1; - } - } - - free(cand); - } - - if (recompute) { - int ttlv; - idxtype *marker; - - marker = idxset(nparts, -1, cpvec); - for (ttlv=0, i=0; i<nvtxs; i++) { - marker[where[i]] = i; - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (marker[where[adjncy[j]]] != i) { - ttlv += graph->vsize[i]; - marker[where[adjncy[j]]] = i; - } - } - } - graph->minvol = ttlv; - } - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - diff --git a/Metis/kwayvolrefine.c b/Metis/kwayvolrefine.c deleted file mode 100644 index 2c4e56ed0c..0000000000 --- a/Metis/kwayvolrefine.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * kwayvolrefine.c - * - * This file contains the driving routines for multilevel k-way refinement - * - * Started 7/28/97 - * George - * - * $Id: kwayvolrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of refinement -**************************************************************************/ -void RefineVolKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, - float *tpwgts, float ubfactor) -{ - int i, nlevels; - GraphType *ptr; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - /* Take care any non-contiguity */ - if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) { - ComputeVolKWayPartitionParams(ctrl, graph, nparts); - EliminateVolComponents(ctrl, graph, nparts, tpwgts, 1.25); - EliminateVolSubDomainEdges(ctrl, graph, nparts, tpwgts); - EliminateVolComponents(ctrl, graph, nparts, tpwgts, 1.25); - } - - - /* Determine how many levels are there */ - for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); - - /* Compute the parameters of the coarsest graph */ - ComputeVolKWayPartitionParams(ctrl, graph, nparts); - - for (i=0; ;i++) { - /*PrintSubDomainGraph(graph, nparts, graph->where);*/ - MALLOC_CHECK(NULL); - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - - if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) { - ComputeVolKWayBalanceBoundary(ctrl, graph, nparts); - switch (ctrl->RType) { - case RTYPE_KWAYRANDOM: - Greedy_KWayVolBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); - break; - case RTYPE_KWAYRANDOM_MCONN: - Greedy_KWayVolBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); - break; - } - ComputeVolKWayBoundary(ctrl, graph, nparts); - } - - switch (ctrl->RType) { - case RTYPE_KWAYRANDOM: - Random_KWayVolRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); - break; - case RTYPE_KWAYRANDOM_MCONN: - Random_KWayVolRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); - break; - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - GKfree(&graph->gdata, LTERM); /* Deallocate the graph related arrays */ - - graph = graph->finer; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - ProjectVolKWayPartition(ctrl, graph, nparts); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) { - ComputeVolKWayBalanceBoundary(ctrl, graph, nparts); - switch (ctrl->RType) { - case RTYPE_KWAYRANDOM: - Greedy_KWayVolBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); - Random_KWayVolRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); - break; - case RTYPE_KWAYRANDOM_MCONN: - Greedy_KWayVolBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); - Random_KWayVolRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); - break; - } - } - - EliminateVolComponents(ctrl, graph, nparts, tpwgts, ubfactor); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - - -/************************************************************************* -* This function allocates memory for k-way edge refinement -**************************************************************************/ -void AllocateVolKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int nvtxs, pad64; - - nvtxs = graph->nvtxs; - - pad64 = (3*nvtxs+nparts)%2; - - graph->rdata = idxmalloc(3*nvtxs+nparts+(sizeof(VRInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateVolKWayPartitionMemory: rdata"); - graph->pwgts = graph->rdata; - graph->where = graph->rdata + nparts; - graph->bndptr = graph->rdata + nvtxs + nparts; - graph->bndind = graph->rdata + 2*nvtxs + nparts; - graph->vrinfo = (VRInfoType *)(graph->rdata + 3*nvtxs+nparts + pad64); - -} - - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void ComputeVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, ii, j, k, kk, l, nvtxs, nbnd, mincut, minvol, me, other, pid; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where; - VRInfoType *rinfo, *myrinfo, *orinfo; - VEDegreeType *myedegrees, *oedegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = idxset(nparts, 0, graph->pwgts); - rinfo = graph->vrinfo; - - - /*------------------------------------------------------------ - / Compute now the id/ed degrees - /------------------------------------------------------------*/ - ctrl->wspace.cdegree = 0; - mincut = 0; - for (i=0; i<nvtxs; i++) { - me = where[i]; - pwgts[me] += vwgt[i]; - - myrinfo = rinfo+i; - myrinfo->id = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0; - myrinfo->edegrees = NULL; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me == where[adjncy[j]]) { - myrinfo->id += adjwgt[j]; - myrinfo->nid++; - } - } - myrinfo->ed = graph->adjwgtsum[i] - myrinfo->id; - - mincut += myrinfo->ed; - - /* Time to compute the particular external degrees */ - if (myrinfo->ed > 0) { - myedegrees = myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - other = where[adjncy[j]]; - if (me != other) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == other) { - myedegrees[k].ed += adjwgt[j]; - myedegrees[k].ned++; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].gv = 0; - myedegrees[myrinfo->ndegrees].pid = other; - myedegrees[myrinfo->ndegrees].ed = adjwgt[j]; - myedegrees[myrinfo->ndegrees++].ned = 1; - } - } - } - - ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]); - } - } - graph->mincut = mincut/2; - - - ComputeKWayVolGains(ctrl, graph, nparts); - -} - - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void ComputeKWayVolGains(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, ii, j, k, kk, l, nvtxs, me, other, pid, myndegrees; - idxtype *xadj, *vsize, *adjncy, *adjwgt, *where, *bndind, *bndptr, *ophtable; - VRInfoType *rinfo, *myrinfo, *orinfo; - VEDegreeType *myedegrees, *oedegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vsize = graph->vsize; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - rinfo = graph->vrinfo; - - ophtable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); - - /*------------------------------------------------------------ - / Compute now the iv/ev degrees - /------------------------------------------------------------*/ - graph->minvol = graph->nbnd = 0; - for (i=0; i<nvtxs; i++) { - myrinfo = rinfo+i; - myrinfo->gv = -MAXIDX; - - if (myrinfo->ndegrees > 0) { - me = where[i]; - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - graph->minvol += myndegrees*vsize[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - other = where[ii]; - orinfo = rinfo+ii; - oedegrees = orinfo->edegrees; - - for (k=0; k<orinfo->ndegrees; k++) - ophtable[oedegrees[k].pid] = k; - ophtable[other] = 1; /* this is to simplify coding */ - - if (me == other) { - /* Find which domains 'i' is connected and 'ii' is not and update their gain */ - for (k=0; k<myndegrees; k++) { - if (ophtable[myedegrees[k].pid] == -1) - myedegrees[k].gv -= vsize[ii]; - } - } - else { - ASSERT(ophtable[me] != -1); - - if (oedegrees[ophtable[me]].ned == 1) { /* I'm the only connection of 'ii' in 'me' */ - /* Increase the gains for all the common domains between 'i' and 'ii' */ - for (k=0; k<myndegrees; k++) { - if (ophtable[myedegrees[k].pid] != -1) - myedegrees[k].gv += vsize[ii]; - } - } - else { - /* Find which domains 'i' is connected and 'ii' is not and update their gain */ - for (k=0; k<myndegrees; k++) { - if (ophtable[myedegrees[k].pid] == -1) - myedegrees[k].gv -= vsize[ii]; - } - } - } - - for (kk=0; kk<orinfo->ndegrees; kk++) - ophtable[oedegrees[kk].pid] = -1; - ophtable[other] = -1; - } - - /* Compute the max vgain */ - for (k=0; k<myndegrees; k++) { - if (myedegrees[k].gv > myrinfo->gv) - myrinfo->gv = myedegrees[k].gv; - } - } - - if (myrinfo->ed > 0 && myrinfo->id == 0) - myrinfo->gv += vsize[i]; - - if (myrinfo->gv >= 0 || myrinfo->ed-myrinfo->id >= 0) - BNDInsert(graph->nbnd, bndind, bndptr, i); - } - - idxwspacefree(ctrl, nparts); - -} - - - -/************************************************************************* -* This function projects a partition, and at the same time computes the -* parameters for refinement. -**************************************************************************/ -void ProjectVolKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, j, k, nvtxs, me, other, istart, iend, ndegrees; - idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; - idxtype *cmap, *where; - idxtype *cwhere; - GraphType *cgraph; - VRInfoType *crinfo, *rinfo, *myrinfo; - VEDegreeType *myedegrees; - idxtype *htable; - - cgraph = graph->coarser; - cwhere = cgraph->where; - crinfo = cgraph->vrinfo; - - nvtxs = graph->nvtxs; - cmap = graph->cmap; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - - AllocateVolKWayPartitionMemory(ctrl, graph, nparts); - where = graph->where; - rinfo = graph->vrinfo; - - /* Go through and project partition and compute id/ed for the nodes */ - for (i=0; i<nvtxs; i++) { - k = cmap[i]; - where[i] = cwhere[k]; - cmap[i] = crinfo[k].ed; /* For optimization */ - } - - htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); - - ctrl->wspace.cdegree = 0; - for (i=0; i<nvtxs; i++) { - me = where[i]; - - myrinfo = rinfo+i; - myrinfo->id = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0; - myrinfo->edegrees = NULL; - - myrinfo->id = adjwgtsum[i]; - myrinfo->nid = xadj[i+1]-xadj[i]; - - if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */ - istart = xadj[i]; - iend = xadj[i+1]; - - myedegrees = myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += iend-istart; - - ndegrees = 0; - for (j=istart; j<iend; j++) { - other = where[adjncy[j]]; - if (me != other) { - myrinfo->ed += adjwgt[j]; - myrinfo->nid--; - if ((k = htable[other]) == -1) { - htable[other] = ndegrees; - myedegrees[ndegrees].gv = 0; - myedegrees[ndegrees].pid = other; - myedegrees[ndegrees].ed = adjwgt[j]; - myedegrees[ndegrees++].ned = 1; - } - else { - myedegrees[k].ed += adjwgt[j]; - myedegrees[k].ned++; - } - } - } - myrinfo->id -= myrinfo->ed; - - /* Remove space for edegrees if it was interior */ - if (myrinfo->ed == 0) { - myrinfo->edegrees = NULL; - ctrl->wspace.cdegree -= iend-istart; - } - else { - myrinfo->ndegrees = ndegrees; - - for (j=0; j<ndegrees; j++) - htable[myedegrees[j].pid] = -1; - } - } - } - - ComputeKWayVolGains(ctrl, graph, nparts); - - idxcopy(nparts, cgraph->pwgts, graph->pwgts); - graph->mincut = cgraph->mincut; - - FreeGraph(graph->coarser); - graph->coarser = NULL; - - idxwspacefree(ctrl, nparts); - -} - - - -/************************************************************************* -* This function computes the boundary definition for balancing -**************************************************************************/ -void ComputeVolKWayBoundary(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, nvtxs, nbnd; - idxtype *bndind, *bndptr; - - nvtxs = graph->nvtxs; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - - /*------------------------------------------------------------ - / Compute the new boundary - /------------------------------------------------------------*/ - nbnd = 0; - for (i=0; i<nvtxs; i++) { - if (graph->vrinfo[i].gv >=0 || graph->vrinfo[i].ed-graph->vrinfo[i].id >= 0) - BNDInsert(nbnd, bndind, bndptr, i); - } - - graph->nbnd = nbnd; -} - -/************************************************************************* -* This function computes the boundary definition for balancing -**************************************************************************/ -void ComputeVolKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, nvtxs, nbnd; - idxtype *bndind, *bndptr; - - nvtxs = graph->nvtxs; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - - /*------------------------------------------------------------ - / Compute the new boundary - /------------------------------------------------------------*/ - nbnd = 0; - for (i=0; i<nvtxs; i++) { - if (graph->vrinfo[i].ed > 0) - BNDInsert(nbnd, bndind, bndptr, i); - } - - graph->nbnd = nbnd; -} - diff --git a/Metis/macros.h b/Metis/macros.h deleted file mode 100644 index 16634f73b4..0000000000 --- a/Metis/macros.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * macros.h - * - * This file contains macros used in multilevel - * - * Started 9/25/94 - * George - * - * $Id: macros.h,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - - -/************************************************************************* -* The following macro returns a random number in the specified range -**************************************************************************/ -#ifdef __VC__ -#define RandomInRange(u) ((rand()>>3)%(u)) -#define RandomInRangeFast(u) ((rand()>>3)%(u)) -#else -#define RandomInRange(u) ((int)(drand48()*((double)(u)))) -#define RandomInRangeFast(u) ((rand()>>3)%(u)) -#endif - - - -#define amax(a, b) ((a) >= (b) ? (a) : (b)) -#define amin(a, b) ((a) >= (b) ? (b) : (a)) - -#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b))) -#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b))) -#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b))) - -#define SWAP(a, b, tmp) \ - do {(tmp) = (a); (a) = (b); (b) = (tmp);} while(0) - -#define INC_DEC(a, b, val) \ - do {(a) += (val); (b) -= (val);} while(0) - - -#define scopy(n, a, b) (float *)memcpy((void *)(b), (void *)(a), sizeof(float)*(n)) -#define idxcopy(n, a, b) (idxtype *)memcpy((void *)(b), (void *)(a), sizeof(idxtype)*(n)) - -#define HASHFCT(key, size) ((key)%(size)) - - -/************************************************************************* -* Timer macros -**************************************************************************/ -#define cleartimer(tmr) (tmr = 0.0) -#define starttimer(tmr) (tmr -= seconds()) -#define stoptimer(tmr) (tmr += seconds()) -#define gettimer(tmr) (tmr) - - -/************************************************************************* -* This macro is used to handle dbglvl -**************************************************************************/ -#define IFSET(a, flag, cmd) if ((a)&(flag)) (cmd); - -/************************************************************************* -* These macros are used for debuging memory leaks -**************************************************************************/ -#ifdef DMALLOC -#define imalloc(n, msg) (malloc(sizeof(int)*(n))) -#define fmalloc(n, msg) (malloc(sizeof(float)*(n))) -#define idxmalloc(n, msg) (malloc(sizeof(idxtype)*(n))) -#define ismalloc(n, val, msg) (iset((n), (val), malloc(sizeof(int)*(n)))) -#define idxsmalloc(n, val, msg) (idxset((n), (val), malloc(sizeof(idxtype)*(n)))) -#define GKmalloc(a, b) (malloc((a))) -#endif - -#ifdef DMALLOC -# define MALLOC_CHECK(ptr) \ - if (malloc_verify((ptr)) == DMALLOC_VERIFY_ERROR) { \ - printf("***MALLOC_CHECK failed on line %d of file %s: " #ptr "\n", \ - __LINE__, __FILE__); \ - abort(); \ - } -#else -# define MALLOC_CHECK(ptr) ; -#endif - - - -/************************************************************************* -* This macro converts a length array in a CSR one -**************************************************************************/ -#define MAKECSR(i, n, a) \ - do { \ - for (i=1; i<n; i++) a[i] += a[i-1]; \ - for (i=n; i>0; i--) a[i] = a[i-1]; \ - a[0] = 0; \ - } while(0) - - -/************************************************************************* -* These macros insert and remove nodes from the boundary list -**************************************************************************/ -#define BNDInsert(nbnd, bndind, bndptr, vtx) \ - do { \ - ASSERT(bndptr[vtx] == -1); \ - bndind[nbnd] = vtx; \ - bndptr[vtx] = nbnd++;\ - } while(0) - -#define BNDDelete(nbnd, bndind, bndptr, vtx) \ - do { \ - ASSERT(bndptr[vtx] != -1); \ - bndind[bndptr[vtx]] = bndind[--nbnd]; \ - bndptr[bndind[nbnd]] = bndptr[vtx]; \ - bndptr[vtx] = -1; \ - } while(0) - - - -/************************************************************************* -* These are debugging macros -**************************************************************************/ -#ifdef DEBUG -# define ASSERT(expr) \ - if (!(expr)) { \ - printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ - __LINE__, __FILE__); \ - abort(); \ - } -#else -# define ASSERT(expr) ; -#endif - -#ifdef DEBUG -# define ASSERTP(expr, msg) \ - if (!(expr)) { \ - printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ - __LINE__, __FILE__); \ - printf msg ; \ - abort(); \ - } -#else -# define ASSERTP(expr, msg) ; -#endif diff --git a/Metis/match.c b/Metis/match.c deleted file mode 100644 index c1434576a2..0000000000 --- a/Metis/match.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * match.c - * - * This file contains the code that computes matchings and creates the next - * level coarse graph. - * - * Started 7/23/97 - * George - * - * $Id: match.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void Match_RM(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, nvtxs, cnvtxs, maxidx; - idxtype *xadj, *vwgt, *adjncy, *adjwgt; - idxtype *match, *cmap, *perm; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - RandomPermute(nvtxs, perm, 1); - - cnvtxs = 0; - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - - /* Find a random matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (match[adjncy[j]] == UNMATCHED && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) { - maxidx = adjncy[j]; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void Match_RM_NVW(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, nvtxs, cnvtxs, maxidx; - idxtype *xadj, *adjncy; - idxtype *match, *cmap, *perm; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - RandomPermute(nvtxs, perm, 1); - - cnvtxs = 0; - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - - /* Find a random matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (match[adjncy[j]] == UNMATCHED) { - maxidx = adjncy[j]; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - CreateCoarseGraph_NVW(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void Match_HEM(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt; - idxtype *xadj, *vwgt, *adjncy, *adjwgt; - idxtype *match, *cmap, *perm; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - RandomPermute(nvtxs, perm, 1); - - cnvtxs = 0; - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - maxwgt = 0; - - /* Find a heavy-edge matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (match[k] == UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[k] <= ctrl->maxvwgt) { - maxwgt = adjwgt[j]; - maxidx = adjncy[j]; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void Match_SHEM(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt, avgdegree; - idxtype *xadj, *vwgt, *adjncy, *adjwgt; - idxtype *match, *cmap, *degrees, *perm, *tperm; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - tperm = idxwspacemalloc(ctrl, nvtxs); - degrees = idxwspacemalloc(ctrl, nvtxs); - - RandomPermute(nvtxs, tperm, 1); - avgdegree = 0.7*(xadj[nvtxs]/nvtxs); - for (i=0; i<nvtxs; i++) - degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]); - BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); - - cnvtxs = 0; - - /* Take care any islands. Islands are matched with non-islands due to coarsening */ - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - if (xadj[i] < xadj[i+1]) - break; - - maxidx = i; - for (j=nvtxs-1; j>ii; j--) { - k = perm[j]; - if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { - maxidx = k; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - /* Continue with normal matching */ - for (; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - maxwgt = 0; - - /* Find a heavy-edge matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (match[adjncy[j]] == UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) { - maxwgt = adjwgt[j]; - maxidx = adjncy[j]; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - idxwspacefree(ctrl, nvtxs); /* degrees */ - idxwspacefree(ctrl, nvtxs); /* tperm */ - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - diff --git a/Metis/mbalance.c b/Metis/mbalance.c deleted file mode 100644 index b97938e87e..0000000000 --- a/Metis/mbalance.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mbalance.c - * - * This file contains code that is used to forcefully balance either - * bisections or k-sections - * - * Started 7/29/97 - * George - * - * $Id: mbalance.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of the bisection balancing algorithms. -**************************************************************************/ -void MocBalance2Way(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor) -{ - - if (Compute2WayHLoadImbalance(graph->ncon, graph->npwgts, tpwgts) < lbfactor) - return; - - MocGeneral2WayBalance(ctrl, graph, tpwgts, lbfactor); - -} - - -/************************************************************************* -* This function performs an edge-based FM refinement -**************************************************************************/ -void MocGeneral2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor) -{ - int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; - idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; - idxtype *moved, *swaps, *perm, *qnum; - float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; - PQueueType parts[MAXNCON][2]; - int higain, oldgain, mincut, newcut, mincutorder; - int qsizes[MAXNCON][2]; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - npwgts = graph->npwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - qnum = idxwspacemalloc(ctrl, nvtxs); - - limit = amin(amax(0.01*nvtxs, 15), 100); - - /* Initialize the queues */ - for (i=0; i<ncon; i++) { - PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1); - PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1); - qsizes[i][0] = qsizes[i][1] = 0; - } - - for (i=0; i<nvtxs; i++) { - qnum[i] = samax(ncon, nvwgt+i*ncon); - qsizes[qnum[i]][where[i]]++; - } - -/* - printf("Weight Distribution: \t"); - for (i=0; i<ncon; i++) - printf(" [%d %d]", qsizes[i][0], qsizes[i][1]); - printf("\n"); -*/ - - for (from=0; from<2; from++) { - for (j=0; j<ncon; j++) { - if (qsizes[j][from] == 0) { - for (i=0; i<nvtxs; i++) { - if (where[i] != from) - continue; - - k = samax2(ncon, nvwgt+i*ncon); - if (k == j && qsizes[qnum[i]][from] > qsizes[j][from] && nvwgt[i*ncon+qnum[i]] < 1.3*nvwgt[i*ncon+j]) { - qsizes[qnum[i]][from]--; - qsizes[j][from]++; - qnum[i] = j; - } - } - } - } - } - -/* - printf("Weight Distribution (after):\t "); - for (i=0; i<ncon; i++) - printf(" [%d %d]", qsizes[i][0], qsizes[i][1]); - printf("\n"); -*/ - - - - for (i=0; i<ncon; i++) - mindiff[i] = fabs(tpwgts[0]-npwgts[i]); - minbal = origbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts); - newcut = mincut = graph->mincut; - mincutorder = -1; - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Parts: ["); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, origbal); - } - - idxset(nvtxs, -1, moved); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert all nodes in the priority queues */ - nbnd = graph->nbnd; - RandomPermute(nvtxs, perm, 1); - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); - } - - for (nswaps=0; nswaps<nvtxs; nswaps++) { - if (minbal < lbfactor) - break; - - SelectQueue(ncon, npwgts, tpwgts, &from, &cnum, parts); - to = (from+1)%2; - - if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1) - break; - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - newcut -= (ed[higain]-id[higain]); - newbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts); - - if (newbal < minbal || (newbal == minbal && - (newcut < mincut || (newcut == mincut && BetterBalance(ncon, npwgts, tpwgts, mindiff))))) { - mincut = newcut; - minbal = newbal; - mincutorder = nswaps; - for (i=0; i<ncon; i++) - mindiff[i] = fabs(tpwgts[0]-npwgts[i]); - } - else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */ - newcut += (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - break; - } - - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - if (ctrl->dbglvl&DBG_MOVEINFO) { - printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf(", %.3f LB: %.3f\n", minbal, newbal); - } - - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update the queue position */ - if (moved[k] == -1) - PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]); - - /* Update its boundary information */ - if (ed[k] == 0 && bndptr[k] != -1) - BNDDelete(nbnd, bndind, bndptr, k); - else if (ed[k] > 0 && bndptr[k] == -1) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - - - /**************************************************************** - * Roll back computations - *****************************************************************/ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - to = where[higain] = (where[higain]+1)%2; - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - else if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - if (bndptr[k] != -1 && ed[k] == 0) - BNDDelete(nbnd, bndind, bndptr, k); - if (bndptr[k] == -1 && ed[k] > 0) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("], LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts)); - } - - graph->mincut = mincut; - graph->nbnd = nbnd; - - - for (i=0; i<ncon; i++) { - PQueueFree(ctrl, &parts[i][0]); - PQueueFree(ctrl, &parts[i][1]); - } - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - diff --git a/Metis/mbalance2.c b/Metis/mbalance2.c deleted file mode 100644 index 717bcef352..0000000000 --- a/Metis/mbalance2.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mbalance2.c - * - * This file contains code that is used to forcefully balance either - * bisections or k-sections - * - * Started 7/29/97 - * George - * - * $Id: mbalance2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of the bisection balancing algorithms. -**************************************************************************/ -void MocBalance2Way2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int i; - float tvec[MAXNCON]; - - Compute2WayHLoadImbalanceVec(graph->ncon, graph->npwgts, tpwgts, tvec); - if (!AreAllBelow(graph->ncon, tvec, ubvec)) - MocGeneral2WayBalance2(ctrl, graph, tpwgts, ubvec); -} - - - -/************************************************************************* -* This function performs an edge-based FM refinement -**************************************************************************/ -void MocGeneral2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; - idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; - idxtype *moved, *swaps, *perm, *qnum; - float *nvwgt, *npwgts, origbal[MAXNCON], minbal[MAXNCON], newbal[MAXNCON]; - PQueueType parts[MAXNCON][2]; - int higain, oldgain, mincut, newcut, mincutorder; - float *maxwgt, *minwgt, tvec[MAXNCON]; - - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - npwgts = graph->npwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - qnum = idxwspacemalloc(ctrl, nvtxs); - - limit = amin(amax(0.01*nvtxs, 15), 100); - - /* Setup the weight intervals of the two subdomains */ - minwgt = fwspacemalloc(ctrl, 2*ncon); - maxwgt = fwspacemalloc(ctrl, 2*ncon); - - for (i=0; i<2; i++) { - for (j=0; j<ncon; j++) { - maxwgt[i*ncon+j] = tpwgts[i]*ubvec[j]; - minwgt[i*ncon+j] = tpwgts[i]*(1.0/ubvec[j]); - } - } - - - /* Initialize the queues */ - for (i=0; i<ncon; i++) { - PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1); - PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1); - } - for (i=0; i<nvtxs; i++) - qnum[i] = samax(ncon, nvwgt+i*ncon); - - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, origbal); - for (i=0; i<ncon; i++) - minbal[i] = origbal[i]; - - newcut = mincut = graph->mincut; - mincutorder = -1; - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Parts: ["); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: ", tpwgts[0], tpwgts[1], - graph->nvtxs, graph->nbnd, graph->mincut); - for (i=0; i<ncon; i++) - printf("%.3f ", origbal[i]); - printf("[B]\n"); - } - - idxset(nvtxs, -1, moved); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert all nodes in the priority queues */ - nbnd = graph->nbnd; - RandomPermute(nvtxs, perm, 1); - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); - } - - - for (nswaps=0; nswaps<nvtxs; nswaps++) { - if (AreAllBelow(ncon, minbal, ubvec)) - break; - - SelectQueue3(ncon, npwgts, tpwgts, &from, &cnum, parts, maxwgt); - to = (from+1)%2; - - if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1) - break; - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - newcut -= (ed[higain]-id[higain]); - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, newbal); - - if (IsBetter2wayBalance(ncon, newbal, minbal, ubvec) || - (IsBetter2wayBalance(ncon, newbal, origbal, ubvec) && newcut < mincut)) { - mincut = newcut; - for (i=0; i<ncon; i++) - minbal[i] = newbal[i]; - mincutorder = nswaps; - } - else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */ - newcut += (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - break; - } - - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - if (ctrl->dbglvl&DBG_MOVEINFO) { - printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); - for (i=0; i<ncon; i++) - printf("(%.3f, %.3f) ", npwgts[i], npwgts[ncon+i]); - - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec); - printf(", LB: "); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - if (mincutorder == nswaps) - printf(" *\n"); - else - printf("\n"); - } - - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update the queue position */ - if (moved[k] == -1) - PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]); - - /* Update its boundary information */ - if (ed[k] == 0 && bndptr[k] != -1) - BNDDelete(nbnd, bndind, bndptr, k); - else if (ed[k] > 0 && bndptr[k] == -1) - BNDInsert(nbnd, bndind, bndptr, k); - } - - } - - - - /**************************************************************** - * Roll back computations - *****************************************************************/ - for (i=0; i<nswaps; i++) - moved[swaps[i]] = -1; /* reset moved array */ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - to = where[higain] = (where[higain]+1)%2; - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - else if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - if (bndptr[k] != -1 && ed[k] == 0) - BNDDelete(nbnd, bndind, bndptr, k); - if (bndptr[k] == -1 && ed[k] > 0) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); - for (i=0; i<ncon; i++) - printf("(%.3f, %.3f) ", npwgts[i], npwgts[ncon+i]); - printf("], LB: "); - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - printf("\n"); - } - - graph->mincut = mincut; - graph->nbnd = nbnd; - - - for (i=0; i<ncon; i++) { - PQueueFree(ctrl, &parts[i][0]); - PQueueFree(ctrl, &parts[i][1]); - } - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - fwspacefree(ctrl, 2*ncon); - fwspacefree(ctrl, 2*ncon); - -} - - - - -/************************************************************************* -* This function selects the partition number and the queue from which -* we will move vertices out -**************************************************************************/ -void SelectQueue3(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, - PQueueType queues[MAXNCON][2], float *maxwgt) -{ - int i, j, maxgain=0; - float maxdiff=0.0, diff; - - *from = -1; - *cnum = -1; - - /* First determine the side and the queue, irrespective of the presence of nodes */ - for (j=0; j<2; j++) { - for (i=0; i<ncon; i++) { - diff = npwgts[j*ncon+i]-maxwgt[j*ncon+i]; - if (diff >= maxdiff) { - maxdiff = diff; - *from = j; - *cnum = i; - } - } - } - -/* DELETE -j = *from; -for (i=0; i<ncon; i++) - printf("[%5d %5d %.4f %.4f] ", i, PQueueGetSize(&queues[i][j]), npwgts[j*ncon+i], maxwgt[j*ncon+i]); -printf("***[%5d %5d]\n", *cnum, *from); -*/ - - /* If the desired queue is empty, select a node from that side anyway */ - if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][*from]) > 0) { - maxdiff = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]); - *cnum = i; - break; - } - } - - for (i++; i<ncon; i++) { - diff = npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]; - if (diff > maxdiff && PQueueGetSize(&queues[i][*from]) > 0) { - maxdiff = diff; - *cnum = i; - } - } - } - - /* If the constraints ar OK, select a high gain vertex */ - if (*from == -1) { - maxgain = -100000; - for (j=0; j<2; j++) { - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][j]) > 0 && PQueueGetKey(&queues[i][j]) > maxgain) { - maxgain = PQueueGetKey(&queues[i][0]); - *from = j; - *cnum = i; - } - } - } - - /* printf("(%2d %2d) %3d\n", *from, *cnum, maxgain); */ - } -} diff --git a/Metis/mcoarsen.c b/Metis/mcoarsen.c deleted file mode 100644 index 34bd5da46c..0000000000 --- a/Metis/mcoarsen.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * mcoarsen.c - * - * This file contains the driving routines for the coarsening process - * - * Started 7/23/97 - * George - * - * $Id: mcoarsen.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function takes a graph and creates a sequence of coarser graphs -**************************************************************************/ -GraphType *MCCoarsen2Way(CtrlType *ctrl, GraphType *graph) -{ - int i, clevel; - GraphType *cgraph; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->CoarsenTmr)); - - cgraph = graph; - - clevel = 0; - do { - if (ctrl->dbglvl&DBG_COARSEN) { - printf("%6d %7d %10d [%d] [%6.4f", cgraph->nvtxs, cgraph->nedges, - idxsum(cgraph->nvtxs, cgraph->adjwgtsum), ctrl->CoarsenTo, ctrl->nmaxvwgt); - for (i=0; i<graph->ncon; i++) - printf(" %5.3f", ssum_strd(cgraph->nvtxs, cgraph->nvwgt+i, cgraph->ncon)); - printf("]\n"); - } - - switch (ctrl->CType) { - case MATCH_RM: - MCMatch_RM(ctrl, cgraph); - break; - case MATCH_HEM: - if (clevel < 1) - MCMatch_RM(ctrl, cgraph); - else - MCMatch_HEM(ctrl, cgraph); - break; - case MATCH_SHEM: - if (clevel < 1) - MCMatch_RM(ctrl, cgraph); - else - MCMatch_SHEM(ctrl, cgraph); - break; - case MATCH_SHEMKWAY: - MCMatch_SHEM(ctrl, cgraph); - break; - case MATCH_SHEBM_ONENORM: - MCMatch_SHEBM(ctrl, cgraph, 1); - break; - case MATCH_SHEBM_INFNORM: - MCMatch_SHEBM(ctrl, cgraph, -1); - break; - case MATCH_SBHEM_ONENORM: - MCMatch_SBHEM(ctrl, cgraph, 1); - break; - case MATCH_SBHEM_INFNORM: - MCMatch_SBHEM(ctrl, cgraph, -1); - break; - default: - errexit("Unknown CType: %d\n", ctrl->CType); - } - - cgraph = cgraph->coarser; - clevel++; - - } while (cgraph->nvtxs > ctrl->CoarsenTo && cgraph->nvtxs < COARSEN_FRACTION2*cgraph->finer->nvtxs && cgraph->nedges > cgraph->nvtxs/2); - - if (ctrl->dbglvl&DBG_COARSEN) { - printf("%6d %7d %10d [%d] [%6.4f", cgraph->nvtxs, cgraph->nedges, - idxsum(cgraph->nvtxs, cgraph->adjwgtsum), ctrl->CoarsenTo, ctrl->nmaxvwgt); - for (i=0; i<graph->ncon; i++) - printf(" %5.3f", ssum_strd(cgraph->nvtxs, cgraph->nvwgt+i, cgraph->ncon)); - printf("]\n"); - } - - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->CoarsenTmr)); - - return cgraph; -} - diff --git a/Metis/memory.c b/Metis/memory.c deleted file mode 100644 index 2342de3d91..0000000000 --- a/Metis/memory.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * memory.c - * - * This file contains routines that deal with memory allocation - * - * Started 2/24/96 - * George - * - * $Id: memory.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function allocates memory for the workspace -**************************************************************************/ -void AllocateWorkSpace(CtrlType *ctrl, GraphType *graph, int nparts) -{ - ctrl->wspace.pmat = NULL; - - if (ctrl->optype == OP_KMETIS) { - ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateWorkSpace: edegrees"); - ctrl->wspace.vedegrees = NULL; - ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; - - ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); - - /* Memory requirements for different phases - Coarsening - Matching: 4*nvtxs vectors - Contraction: 2*nvtxs vectors (from the above 4), 1*nparts, 1*Nedges - Total = MAX(4*nvtxs, 2*nvtxs+nparts+nedges) - - Refinement - Random Refinement/Balance: 5*nparts + 1*nvtxs + 2*nedges - Greedy Refinement/Balance: 5*nparts + 2*nvtxs + 2*nedges + 1*PQueue(==Nvtxs) - Total = 5*nparts + 3*nvtxs + 2*nedges - - Total = 5*nparts + 3*nvtxs + 2*nedges - */ - ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ - 5*(nparts+1) + /* Partition weights etc */ - graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ - 20 /* padding for 64 bit machines */ - ; - } - else if (ctrl->optype == OP_KVMETIS) { - ctrl->wspace.edegrees = NULL; - ctrl->wspace.vedegrees = (VEDegreeType *)GKmalloc(graph->nedges*sizeof(VEDegreeType), "AllocateWorkSpace: vedegrees"); - ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.vedegrees; - - ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); - - /* Memory requirements for different phases are identical to KMETIS */ - ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ - 3*(nparts+1) + /* Partition weights etc */ - graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ - 20 /* padding for 64 bit machines */ - ; - } - else { - ctrl->wspace.edegrees = (EDegreeType *)idxmalloc(graph->nedges, "AllocateWorkSpace: edegrees"); - ctrl->wspace.vedegrees = NULL; - ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; - - ctrl->wspace.maxcore = 5*(graph->nvtxs+1) + /* Refinement vectors */ - 4*(nparts+1) + /* Partition weights etc */ - 2*graph->ncon*graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* 2-way refinement */ - 2*graph->ncon*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)) + /* 2-way refinement */ - 20 /* padding for 64 bit machines */ - ; - } - - ctrl->wspace.maxcore += HTLENGTH; - ctrl->wspace.core = idxmalloc(ctrl->wspace.maxcore, "AllocateWorkSpace: maxcore"); - ctrl->wspace.ccore = 0; -} - - -/************************************************************************* -* This function allocates memory for the workspace -**************************************************************************/ -void FreeWorkSpace(CtrlType *ctrl, GraphType *graph) -{ - GKfree(&ctrl->wspace.edegrees, &ctrl->wspace.vedegrees, &ctrl->wspace.core, &ctrl->wspace.pmat, LTERM); -} - -/************************************************************************* -* This function returns how may words are left in the workspace -**************************************************************************/ -int WspaceAvail(CtrlType *ctrl) -{ - return ctrl->wspace.maxcore - ctrl->wspace.ccore; -} - - -/************************************************************************* -* This function allocate space from the core -**************************************************************************/ -idxtype *idxwspacemalloc(CtrlType *ctrl, int n) -{ - n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ - - ctrl->wspace.ccore += n; - ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); - return ctrl->wspace.core + ctrl->wspace.ccore - n; -} - -/************************************************************************* -* This function frees space from the core -**************************************************************************/ -void idxwspacefree(CtrlType *ctrl, int n) -{ - n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ - - ctrl->wspace.ccore -= n; - ASSERT(ctrl->wspace.ccore >= 0); -} - - -/************************************************************************* -* This function allocate space from the core -**************************************************************************/ -float *fwspacemalloc(CtrlType *ctrl, int n) -{ - n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ - - ctrl->wspace.ccore += n; - ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); - return (float *) (ctrl->wspace.core + ctrl->wspace.ccore - n); -} - -/************************************************************************* -* This function frees space from the core -**************************************************************************/ -void fwspacefree(CtrlType *ctrl, int n) -{ - n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ - - ctrl->wspace.ccore -= n; - ASSERT(ctrl->wspace.ccore >= 0); -} - - - -/************************************************************************* -* This function creates a CoarseGraphType data structure and initializes -* the various fields -**************************************************************************/ -GraphType *CreateGraph(void) -{ - GraphType *graph; - - graph = (GraphType *)GKmalloc(sizeof(GraphType), "CreateCoarseGraph: graph"); - - InitGraph(graph); - - return graph; -} - - -/************************************************************************* -* This function creates a CoarseGraphType data structure and initializes -* the various fields -**************************************************************************/ -void InitGraph(GraphType *graph) -{ - graph->gdata = graph->rdata = NULL; - - graph->nvtxs = graph->nedges = -1; - graph->mincut = graph->minvol = -1; - - graph->xadj = graph->vwgt = graph->adjncy = graph->adjwgt = NULL; - graph->adjwgtsum = NULL; - graph->label = NULL; - graph->cmap = NULL; - - graph->where = graph->pwgts = NULL; - graph->id = graph->ed = NULL; - graph->bndptr = graph->bndind = NULL; - graph->rinfo = NULL; - graph->vrinfo = NULL; - graph->nrinfo = NULL; - - graph->ncon = -1; - graph->nvwgt = NULL; - graph->npwgts = NULL; - - graph->vsize = NULL; - - graph->coarser = graph->finer = NULL; - -} - -/************************************************************************* -* This function deallocates any memory stored in a graph -**************************************************************************/ -void FreeGraph(GraphType *graph) -{ - - GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, LTERM); - free(graph); -} - diff --git a/Metis/mesh.c b/Metis/mesh.c deleted file mode 100644 index 015f693fed..0000000000 --- a/Metis/mesh.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mesh.c - * - * This file contains routines for converting 3D and 4D finite element - * meshes into dual or nodal graphs - * - * Started 8/18/97 - * George - * - * $Id: mesh.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/***************************************************************************** -* This function creates a graph corresponding to the dual of a finite element -* mesh. At this point the supported elements are triangles, tetrahedrons, and -* bricks. -******************************************************************************/ -void METIS_MeshToDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, - idxtype *dxadj, idxtype *dadjncy) -{ - int esizes[] = {-1, 3, 4, 8, 4}; - - if (*numflag == 1) - ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts); - - GENDUALMETIS(*ne, *nn, *etype, elmnts, dxadj, dadjncy); - - if (*numflag == 1) - ChangeMesh2FNumbering((*ne)*esizes[*etype], elmnts, *ne, dxadj, dadjncy); -} - - -/***************************************************************************** -* This function creates a graph corresponding to the finite element mesh. -* At this point the supported elements are triangles, tetrahedrons. -******************************************************************************/ -void METIS_MeshToNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, - idxtype *dxadj, idxtype *dadjncy) -{ - int esizes[] = {-1, 3, 4, 8, 4}; - - if (*numflag == 1) - ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts); - - switch (*etype) { - case 1: - TRINODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); - break; - case 2: - TETNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); - break; - case 3: - HEXNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); - break; - case 4: - QUADNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); - break; - } - - if (*numflag == 1) - ChangeMesh2FNumbering((*ne)*esizes[*etype], elmnts, *nn, dxadj, dadjncy); -} - - - -/***************************************************************************** -* This function creates the dual of a finite element mesh -******************************************************************************/ -void GENDUALMETIS(int nelmnts, int nvtxs, int etype, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy) -{ - int i, j, jj, k, kk, kkk, l, m, n, nedges, mask; - idxtype *nptr, *nind; - idxtype *mark, ind[200], wgt[200]; - int esize, esizes[] = {-1, 3, 4, 8, 4}, - mgcnum, mgcnums[] = {-1, 2, 3, 4, 2}; - - mask = (1<<11)-1; - mark = idxsmalloc(mask+1, -1, "GENDUALMETIS: mark"); - - /* Get the element size and magic number for the particular element */ - esize = esizes[etype]; - mgcnum = mgcnums[etype]; - - /* Construct the node-element list first */ - nptr = idxsmalloc(nvtxs+1, 0, "GENDUALMETIS: nptr"); - for (j=esize*nelmnts, i=0; i<j; i++) - nptr[elmnts[i]]++; - MAKECSR(i, nvtxs, nptr); - - nind = idxmalloc(nptr[nvtxs], "GENDUALMETIS: nind"); - for (k=i=0; i<nelmnts; i++) { - for (j=0; j<esize; j++, k++) - nind[nptr[elmnts[k]]++] = i; - } - for (i=nvtxs; i>0; i--) - nptr[i] = nptr[i-1]; - nptr[0] = 0; - - for (i=0; i<nelmnts; i++) - dxadj[i] = esize*i; - - for (i=0; i<nelmnts; i++) { - for (m=j=0; j<esize; j++) { - n = elmnts[esize*i+j]; - for (k=nptr[n+1]-1; k>=nptr[n]; k--) { - if ((kk = nind[k]) <= i) - break; - - kkk = kk&mask; - if ((l = mark[kkk]) == -1) { - ind[m] = kk; - wgt[m] = 1; - mark[kkk] = m++; - } - else if (ind[l] == kk) { - wgt[l]++; - } - else { - for (jj=0; jj<m; jj++) { - if (ind[jj] == kk) { - wgt[jj]++; - break; - } - } - if (jj == m) { - ind[m] = kk; - wgt[m++] = 1; - } - } - } - } - for (j=0; j<m; j++) { - if (wgt[j] == mgcnum) { - k = ind[j]; - dadjncy[dxadj[i]++] = k; - dadjncy[dxadj[k]++] = i; - } - mark[ind[j]&mask] = -1; - } - } - - /* Go and consolidate the dxadj and dadjncy */ - for (j=i=0; i<nelmnts; i++) { - for (k=esize*i; k<dxadj[i]; k++, j++) - dadjncy[j] = dadjncy[k]; - dxadj[i] = j; - } - for (i=nelmnts; i>0; i--) - dxadj[i] = dxadj[i-1]; - dxadj[0] = 0; - - free(mark); - free(nptr); - free(nind); - -} - - - - -/***************************************************************************** -* This function creates the nodal graph of a finite element mesh -******************************************************************************/ -void TRINODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy) -{ - int i, j, jj, k, kk, kkk, l, m, n, nedges; - idxtype *nptr, *nind; - idxtype *mark; - - /* Construct the node-element list first */ - nptr = idxsmalloc(nvtxs+1, 0, "TRINODALMETIS: nptr"); - for (j=3*nelmnts, i=0; i<j; i++) - nptr[elmnts[i]]++; - MAKECSR(i, nvtxs, nptr); - - nind = idxmalloc(nptr[nvtxs], "TRINODALMETIS: nind"); - for (k=i=0; i<nelmnts; i++) { - for (j=0; j<3; j++, k++) - nind[nptr[elmnts[k]]++] = i; - } - for (i=nvtxs; i>0; i--) - nptr[i] = nptr[i-1]; - nptr[0] = 0; - - - mark = idxsmalloc(nvtxs, -1, "TRINODALMETIS: mark"); - - nedges = dxadj[0] = 0; - for (i=0; i<nvtxs; i++) { - mark[i] = i; - for (j=nptr[i]; j<nptr[i+1]; j++) { - for (jj=3*nind[j], k=0; k<3; k++, jj++) { - kk = elmnts[jj]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - } - } - dxadj[i+1] = nedges; - } - - free(mark); - free(nptr); - free(nind); - -} - - -/***************************************************************************** -* This function creates the nodal graph of a finite element mesh -******************************************************************************/ -void TETNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy) -{ - int i, j, jj, k, kk, kkk, l, m, n, nedges; - idxtype *nptr, *nind; - idxtype *mark; - - /* Construct the node-element list first */ - nptr = idxsmalloc(nvtxs+1, 0, "TETNODALMETIS: nptr"); - for (j=4*nelmnts, i=0; i<j; i++) - nptr[elmnts[i]]++; - MAKECSR(i, nvtxs, nptr); - - nind = idxmalloc(nptr[nvtxs], "TETNODALMETIS: nind"); - for (k=i=0; i<nelmnts; i++) { - for (j=0; j<4; j++, k++) - nind[nptr[elmnts[k]]++] = i; - } - for (i=nvtxs; i>0; i--) - nptr[i] = nptr[i-1]; - nptr[0] = 0; - - - mark = idxsmalloc(nvtxs, -1, "TETNODALMETIS: mark"); - - nedges = dxadj[0] = 0; - for (i=0; i<nvtxs; i++) { - mark[i] = i; - for (j=nptr[i]; j<nptr[i+1]; j++) { - for (jj=4*nind[j], k=0; k<4; k++, jj++) { - kk = elmnts[jj]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - } - } - dxadj[i+1] = nedges; - } - - free(mark); - free(nptr); - free(nind); - -} - - -/***************************************************************************** -* This function creates the nodal graph of a finite element mesh -******************************************************************************/ -void HEXNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy) -{ - int i, j, jj, k, kk, kkk, l, m, n, nedges; - idxtype *nptr, *nind; - idxtype *mark; - int table[8][3] = {1, 3, 4, - 0, 2, 5, - 1, 3, 6, - 0, 2, 7, - 0, 5, 7, - 1, 4, 6, - 2, 5, 7, - 3, 4, 6}; - - /* Construct the node-element list first */ - nptr = idxsmalloc(nvtxs+1, 0, "HEXNODALMETIS: nptr"); - for (j=8*nelmnts, i=0; i<j; i++) - nptr[elmnts[i]]++; - MAKECSR(i, nvtxs, nptr); - - nind = idxmalloc(nptr[nvtxs], "HEXNODALMETIS: nind"); - for (k=i=0; i<nelmnts; i++) { - for (j=0; j<8; j++, k++) - nind[nptr[elmnts[k]]++] = i; - } - for (i=nvtxs; i>0; i--) - nptr[i] = nptr[i-1]; - nptr[0] = 0; - - - mark = idxsmalloc(nvtxs, -1, "HEXNODALMETIS: mark"); - - nedges = dxadj[0] = 0; - for (i=0; i<nvtxs; i++) { - mark[i] = i; - for (j=nptr[i]; j<nptr[i+1]; j++) { - jj=8*nind[j]; - for (k=0; k<8; k++) { - if (elmnts[jj+k] == i) - break; - } - ASSERT(k != 8); - - /* You found the index, now go and put the 3 neighbors */ - kk = elmnts[jj+table[k][0]]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - kk = elmnts[jj+table[k][1]]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - kk = elmnts[jj+table[k][2]]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - } - dxadj[i+1] = nedges; - } - - free(mark); - free(nptr); - free(nind); - -} - - -/***************************************************************************** -* This function creates the nodal graph of a finite element mesh -******************************************************************************/ -void QUADNODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy) -{ - int i, j, jj, k, kk, kkk, l, m, n, nedges; - idxtype *nptr, *nind; - idxtype *mark; - int table[4][2] = {1, 3, - 0, 2, - 1, 3, - 0, 2}; - - /* Construct the node-element list first */ - nptr = idxsmalloc(nvtxs+1, 0, "QUADNODALMETIS: nptr"); - for (j=4*nelmnts, i=0; i<j; i++) - nptr[elmnts[i]]++; - MAKECSR(i, nvtxs, nptr); - - nind = idxmalloc(nptr[nvtxs], "QUADNODALMETIS: nind"); - for (k=i=0; i<nelmnts; i++) { - for (j=0; j<4; j++, k++) - nind[nptr[elmnts[k]]++] = i; - } - for (i=nvtxs; i>0; i--) - nptr[i] = nptr[i-1]; - nptr[0] = 0; - - - mark = idxsmalloc(nvtxs, -1, "QUADNODALMETIS: mark"); - - nedges = dxadj[0] = 0; - for (i=0; i<nvtxs; i++) { - mark[i] = i; - for (j=nptr[i]; j<nptr[i+1]; j++) { - jj=4*nind[j]; - for (k=0; k<4; k++) { - if (elmnts[jj+k] == i) - break; - } - ASSERT(k != 4); - - /* You found the index, now go and put the 2 neighbors */ - kk = elmnts[jj+table[k][0]]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - kk = elmnts[jj+table[k][1]]; - if (mark[kk] != i) { - mark[kk] = i; - dadjncy[nedges++] = kk; - } - } - dxadj[i+1] = nedges; - } - - free(mark); - free(nptr); - free(nind); - -} diff --git a/Metis/meshpart.c b/Metis/meshpart.c deleted file mode 100644 index e010fe3a80..0000000000 --- a/Metis/meshpart.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * meshpart.c - * - * This file contains routines for partitioning finite element meshes. - * - * Started 9/29/97 - * George - * - * $Id: meshpart.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function partitions a finite element mesh by partitioning its nodal -* graph using KMETIS and then assigning elements in a load balanced fashion. -**************************************************************************/ -void METIS_PartMeshNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, - int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - int i, j, k, me; - idxtype *xadj, *adjncy, *pwgts; - int options[10], pnumflag=0, wgtflag=0; - int nnbrs, nbrind[200], nbrwgt[200], maxpwgt; - int esize, esizes[] = {-1, 3, 4, 8, 4}; - - esize = esizes[*etype]; - - if (*numflag == 1) - ChangeMesh2CNumbering((*ne)*esize, elmnts); - - xadj = idxmalloc(*nn+1, "METIS_MESHPARTNODAL: xadj"); - adjncy = idxmalloc(20*(*nn), "METIS_MESHPARTNODAL: adjncy"); - - METIS_MeshToNodal(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy); - - adjncy = realloc(adjncy, xadj[*nn]*sizeof(idxtype)); - - options[0] = 0; - METIS_PartGraphKway(nn, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, npart); - - /* OK, now compute an element partition based on the nodal partition npart */ - idxset(*ne, -1, epart); - pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTNODAL: pwgts"); - for (i=0; i<*ne; i++) { - me = npart[elmnts[i*esize]]; - for (j=1; j<esize; j++) { - if (npart[elmnts[i*esize+j]] != me) - break; - } - if (j == esize) { - epart[i] = me; - pwgts[me]++; - } - } - - maxpwgt = 1.03*(*ne)/(*nparts); - for (i=0; i<*ne; i++) { - if (epart[i] == -1) { /* Assign the boundary element */ - nnbrs = 0; - for (j=0; j<esize; j++) { - me = npart[elmnts[i*esize+j]]; - for (k=0; k<nnbrs; k++) { - if (nbrind[k] == me) { - nbrwgt[k]++; - break; - } - } - if (k == nnbrs) { - nbrind[nnbrs] = me; - nbrwgt[nnbrs++] = 1; - } - } - /* Try to assign it first to the domain with most things in common */ - j = iamax(nnbrs, nbrwgt); - if (pwgts[nbrind[j]] < maxpwgt) { - epart[i] = nbrind[j]; - } - else { - /* If that fails, assign it to a light domain */ - for (j=0; j<nnbrs; j++) { - if (pwgts[nbrind[j]] < maxpwgt) { - epart[i] = nbrind[j]; - break; - } - } - if (j == nnbrs) - epart[i] = nbrind[iamax(nnbrs, nbrwgt)]; - } - pwgts[epart[i]]++; - } - } - - if (*numflag == 1) - ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart); - - GKfree(&xadj, &adjncy, &pwgts, LTERM); - -} - - -/************************************************************************* -* This function partitions a finite element mesh by partitioning its dual -* graph using KMETIS and then assigning nodes in a load balanced fashion. -**************************************************************************/ -void METIS_PartMeshDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, - int *nparts, int *edgecut, idxtype *epart, idxtype *npart) -{ - int i, j, k, me; - idxtype *xadj, *adjncy, *pwgts, *nptr, *nind; - int options[10], pnumflag=0, wgtflag=0; - int nnbrs, nbrind[200], nbrwgt[200], maxpwgt; - int esize, esizes[] = {-1, 3, 4, 8, 4}; - - esize = esizes[*etype]; - - if (*numflag == 1) - ChangeMesh2CNumbering((*ne)*esize, elmnts); - - xadj = idxmalloc(*ne+1, "METIS_MESHPARTNODAL: xadj"); - adjncy = idxmalloc(esize*(*ne), "METIS_MESHPARTNODAL: adjncy"); - - METIS_MeshToDual(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy); - - options[0] = 0; - METIS_PartGraphKway(ne, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, epart); - - /* Construct the node-element list */ - nptr = idxsmalloc(*nn+1, 0, "METIS_MESHPARTDUAL: nptr"); - for (j=esize*(*ne), i=0; i<j; i++) - nptr[elmnts[i]]++; - MAKECSR(i, *nn, nptr); - - nind = idxmalloc(nptr[*nn], "METIS_MESHPARTDUAL: nind"); - for (k=i=0; i<(*ne); i++) { - for (j=0; j<esize; j++, k++) - nind[nptr[elmnts[k]]++] = i; - } - for (i=(*nn); i>0; i--) - nptr[i] = nptr[i-1]; - nptr[0] = 0; - - - /* OK, now compute a nodal partition based on the element partition npart */ - idxset(*nn, -1, npart); - pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTDUAL: pwgts"); - for (i=0; i<*nn; i++) { - me = epart[nind[nptr[i]]]; - for (j=nptr[i]+1; j<nptr[i+1]; j++) { - if (epart[nind[j]] != me) - break; - } - if (j == nptr[i+1]) { - npart[i] = me; - pwgts[me]++; - } - } - - maxpwgt = 1.03*(*nn)/(*nparts); - for (i=0; i<*nn; i++) { - if (npart[i] == -1) { /* Assign the boundary element */ - nnbrs = 0; - for (j=nptr[i]; j<nptr[i+1]; j++) { - me = epart[nind[j]]; - for (k=0; k<nnbrs; k++) { - if (nbrind[k] == me) { - nbrwgt[k]++; - break; - } - } - if (k == nnbrs) { - nbrind[nnbrs] = me; - nbrwgt[nnbrs++] = 1; - } - } - /* Try to assign it first to the domain with most things in common */ - j = iamax(nnbrs, nbrwgt); - if (pwgts[nbrind[j]] < maxpwgt) { - npart[i] = nbrind[j]; - } - else { - /* If that fails, assign it to a light domain */ - npart[i] = nbrind[0]; - for (j=0; j<nnbrs; j++) { - if (pwgts[nbrind[j]] < maxpwgt) { - npart[i] = nbrind[j]; - break; - } - } - } - pwgts[npart[i]]++; - } - } - - if (*numflag == 1) - ChangeMesh2FNumbering2((*ne)*esize, elmnts, *ne, *nn, epart, npart); - - GKfree(&xadj, &adjncy, &pwgts, &nptr, &nind, LTERM); - -} diff --git a/Metis/metis.h b/Metis/metis.h deleted file mode 100644 index 13c0b9cd2a..0000000000 --- a/Metis/metis.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * metis.h - * - * This file includes all necessary header files - * - * Started 8/27/94 - * George - * - * $Id: metis.h,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - - -#include <stdio.h> -#ifdef __STDC__ -#include <stdlib.h> -#else -#include <malloc.h> -#endif -#include <strings.h> -#include <string.h> -#include <ctype.h> -#include <math.h> -#include <stdarg.h> -#include <time.h> - -#ifdef DMALLOC -#include <dmalloc.h> -#endif - -#include <defs.h> -#include <struct.h> -#include <macros.h> -#include <rename.h> -#include <proto.h> - diff --git a/Metis/mfm.c b/Metis/mfm.c deleted file mode 100644 index 820278f799..0000000000 --- a/Metis/mfm.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mfm.c - * - * This file contains code that implements the edge-based FM refinement - * - * Started 7/23/97 - * George - * - * $Id: mfm.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs an edge-based FM refinement -**************************************************************************/ -void MocFM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, float *tpwgts, int npasses) -{ - int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; - idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; - idxtype *moved, *swaps, *perm, *qnum; - float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; - PQueueType parts[MAXNCON][2]; - int higain, oldgain, mincut, initcut, newcut, mincutorder; - float rtpwgts[2]; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - npwgts = graph->npwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - qnum = idxwspacemalloc(ctrl, nvtxs); - - limit = amin(amax(0.01*nvtxs, 25), 150); - - /* Initialize the queues */ - for (i=0; i<ncon; i++) { - PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1); - PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1); - } - for (i=0; i<nvtxs; i++) - qnum[i] = samax(ncon, nvwgt+i*ncon); - - origbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts); - - rtpwgts[0] = origbal*tpwgts[0]; - rtpwgts[1] = origbal*tpwgts[1]; - - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Parts: ["); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, origbal); - } - - idxset(nvtxs, -1, moved); - for (pass=0; pass<npasses; pass++) { /* Do a number of passes */ - for (i=0; i<ncon; i++) { - PQueueReset(&parts[i][0]); - PQueueReset(&parts[i][1]); - } - - mincutorder = -1; - newcut = mincut = initcut = graph->mincut; - for (i=0; i<ncon; i++) - mindiff[i] = fabs(tpwgts[0]-npwgts[i]); - minbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert boundary nodes in the priority queues */ - nbnd = graph->nbnd; - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(ed[i] > 0 || id[i] == 0); - ASSERT(bndptr[i] != -1); - PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); - } - - for (nswaps=0; nswaps<nvtxs; nswaps++) { - SelectQueue(ncon, npwgts, rtpwgts, &from, &cnum, parts); - to = (from+1)%2; - - if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1) - break; - ASSERT(bndptr[higain] != -1); - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - - newcut -= (ed[higain]-id[higain]); - newbal = Compute2WayHLoadImbalance(ncon, npwgts, tpwgts); - - if ((newcut < mincut && newbal-origbal <= .00001) || - (newcut == mincut && (newbal < minbal || - (newbal == minbal && BetterBalance(ncon, npwgts, tpwgts, mindiff))))) { - mincut = newcut; - minbal = newbal; - mincutorder = nswaps; - for (i=0; i<ncon; i++) - mindiff[i] = fabs(tpwgts[0]-npwgts[i]); - } - else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */ - newcut += (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - break; - } - - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - if (ctrl->dbglvl&DBG_MOVEINFO) { - printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf(", %.3f LB: %.3f\n", minbal, newbal); - } - - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update its boundary information and queue position */ - if (bndptr[k] != -1) { /* If k was a boundary vertex */ - if (ed[k] == 0) { /* Not a boundary vertex any more */ - BNDDelete(nbnd, bndind, bndptr, k); - if (moved[k] == -1) /* Remove it if in the queues */ - PQueueDelete(&parts[qnum[k]][where[k]], k, oldgain); - } - else { /* If it has not been moved, update its position in the queue */ - if (moved[k] == -1) - PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]); - } - } - else { - if (ed[k] > 0) { /* It will now become a boundary vertex */ - BNDInsert(nbnd, bndind, bndptr, k); - if (moved[k] == -1) - PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]); - } - } - } - - } - - - /**************************************************************** - * Roll back computations - *****************************************************************/ - for (i=0; i<nswaps; i++) - moved[swaps[i]] = -1; /* reset moved array */ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - to = where[higain] = (where[higain]+1)%2; - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - else if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - if (bndptr[k] != -1 && ed[k] == 0) - BNDDelete(nbnd, bndind, bndptr, k); - if (bndptr[k] == -1 && ed[k] > 0) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("], LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts)); - } - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (mincutorder == -1 || mincut == initcut) - break; - } - - for (i=0; i<ncon; i++) { - PQueueFree(ctrl, &parts[i][0]); - PQueueFree(ctrl, &parts[i][1]); - } - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - - -/************************************************************************* -* This function selects the partition number and the queue from which -* we will move vertices out -**************************************************************************/ -void SelectQueue(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, PQueueType queues[MAXNCON][2]) -{ - int i, part, maxgain=0; - float max, maxdiff=0.0; - - *from = -1; - *cnum = -1; - - /* First determine the side and the queue, irrespective of the presence of nodes */ - for (part=0; part<2; part++) { - for (i=0; i<ncon; i++) { - if (npwgts[part*ncon+i]-tpwgts[part] >= maxdiff) { - maxdiff = npwgts[part*ncon+i]-tpwgts[part]; - *from = part; - *cnum = i; - } - } - } - - /* printf("Selected1 %d(%d) -> %d [%5f]\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from]), maxdiff); */ - - if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { - /* The desired queue is empty, select a node from that side anyway */ - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][*from]) > 0) { - max = npwgts[(*from)*ncon + i]; - *cnum = i; - break; - } - } - - for (i++; i<ncon; i++) { - if (npwgts[(*from)*ncon + i] > max && PQueueGetSize(&queues[i][*from]) > 0) { - max = npwgts[(*from)*ncon + i]; - *cnum = i; - } - } - } - - /* Check to see if you can focus on the cut */ - if (maxdiff <= 0.0 || *from == -1) { - maxgain = -100000; - - for (part=0; part<2; part++) { - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][part]) > 0 && PQueueGetKey(&queues[i][part]) > maxgain) { - maxgain = PQueueGetKey(&queues[i][part]); - *from = part; - *cnum = i; - } - } - } - } - - /* printf("Selected2 %d(%d) -> %d\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from])); */ -} - - - - - -/************************************************************************* -* This function checks if the balance achieved is better than the diff -* For now, it uses a 2-norm measure -**************************************************************************/ -int BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff) -{ - int i; - float ndiff[MAXNCON]; - - for (i=0; i<ncon; i++) - ndiff[i] = fabs(tpwgts[0]-npwgts[i]); - - return snorm2(ncon, ndiff) < snorm2(ncon, diff); -} - - - -/************************************************************************* -* This function computes the load imbalance over all the constrains -**************************************************************************/ -float Compute2WayHLoadImbalance(int ncon, float *npwgts, float *tpwgts) -{ - int i; - float max=0.0, temp; - - for (i=0; i<ncon; i++) { - /* temp = amax(npwgts[i]/tpwgts[0], npwgts[ncon+i]/tpwgts[1]); */ - temp = fabs(tpwgts[0]-npwgts[i])/tpwgts[0]; - max = (max < temp ? temp : max); - } - return 1.0+max; -} - - -/************************************************************************* -* This function computes the load imbalance over all the constrains -* For now assume that we just want balanced partitionings -**************************************************************************/ -void Compute2WayHLoadImbalanceVec(int ncon, float *npwgts, float *tpwgts, float *lbvec) -{ - int i; - - for (i=0; i<ncon; i++) - lbvec[i] = 1.0 + fabs(tpwgts[0]-npwgts[i])/tpwgts[0]; -} - diff --git a/Metis/mfm2.c b/Metis/mfm2.c deleted file mode 100644 index 0b2a4d5211..0000000000 --- a/Metis/mfm2.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mfm2.c - * - * This file contains code that implements the edge-based FM refinement - * - * Started 7/23/97 - * George - * - * $Id: mfm2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs an edge-based FM refinement -**************************************************************************/ -void MocFM_2WayEdgeRefine2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *orgubvec, - int npasses) -{ - int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; - idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; - idxtype *moved, *swaps, *perm, *qnum; - float *nvwgt, *npwgts, origdiff[MAXNCON], origbal[MAXNCON], minbal[MAXNCON]; - PQueueType parts[MAXNCON][2]; - int higain, oldgain, mincut, initcut, newcut, mincutorder; - float *maxwgt, *minwgt, ubvec[MAXNCON], tvec[MAXNCON]; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - npwgts = graph->npwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - qnum = idxwspacemalloc(ctrl, nvtxs); - - limit = amin(amax(0.01*nvtxs, 15), 100); - - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, origbal); - for (i=0; i<ncon; i++) { - origdiff[i] = fabs(tpwgts[0]-npwgts[i]); - ubvec[i] = amax(origbal[i], orgubvec[i]); - } - - /* Setup the weight intervals of the two subdomains */ - minwgt = fwspacemalloc(ctrl, 2*ncon); - maxwgt = fwspacemalloc(ctrl, 2*ncon); - - for (i=0; i<2; i++) { - for (j=0; j<ncon; j++) { - maxwgt[i*ncon+j] = tpwgts[i]*ubvec[j]; - minwgt[i*ncon+j] = tpwgts[i]*(1.0/ubvec[j]); - } - } - - /* Initialize the queues */ - for (i=0; i<ncon; i++) { - PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1); - PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1); - } - for (i=0; i<nvtxs; i++) - qnum[i] = samax(ncon, nvwgt+i*ncon); - - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Parts: ["); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: ", tpwgts[0], tpwgts[1], - graph->nvtxs, graph->nbnd, graph->mincut); - for (i=0; i<ncon; i++) - printf("%.3f ", origbal[i]); - printf("\n"); - } - - idxset(nvtxs, -1, moved); - for (pass=0; pass<npasses; pass++) { /* Do a number of passes */ - for (i=0; i<ncon; i++) { - PQueueReset(&parts[i][0]); - PQueueReset(&parts[i][1]); - } - - mincutorder = -1; - newcut = mincut = initcut = graph->mincut; - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, minbal); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - /* Insert boundary nodes in the priority queues */ - nbnd = graph->nbnd; - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(ed[i] > 0 || id[i] == 0); - ASSERT(bndptr[i] != -1); - PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); - } - - for (nswaps=0; nswaps<nvtxs; nswaps++) { - SelectQueue2(ncon, npwgts, tpwgts, &from, &cnum, parts, maxwgt); - to = (from+1)%2; - - if (from == -1 || (higain = PQueueGetMax(&parts[cnum][from])) == -1) - break; - ASSERT(bndptr[higain] != -1); - - newcut -= (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec); - if ((newcut < mincut && AreAllBelow(ncon, tvec, ubvec)) || - (newcut == mincut && IsBetter2wayBalance(ncon, tvec, minbal, ubvec))) { - mincut = newcut; - for (i=0; i<ncon; i++) - minbal[i] = tvec[i]; - mincutorder = nswaps; - } - else if (nswaps-mincutorder > limit) { /* We hit the limit, undo last move */ - newcut += (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - break; - } - - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - if (ctrl->dbglvl&DBG_MOVEINFO) { - printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - - printf(", LB: "); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - if (mincutorder == nswaps) - printf(" *\n"); - else - printf("\n"); - } - - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update its boundary information and queue position */ - if (bndptr[k] != -1) { /* If k was a boundary vertex */ - if (ed[k] == 0) { /* Not a boundary vertex any more */ - BNDDelete(nbnd, bndind, bndptr, k); - if (moved[k] == -1) /* Remove it if in the queues */ - PQueueDelete(&parts[qnum[k]][where[k]], k, oldgain); - } - else { /* If it has not been moved, update its position in the queue */ - if (moved[k] == -1) - PQueueUpdate(&parts[qnum[k]][where[k]], k, oldgain, ed[k]-id[k]); - } - } - else { - if (ed[k] > 0) { /* It will now become a boundary vertex */ - BNDInsert(nbnd, bndind, bndptr, k); - if (moved[k] == -1) - PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]); - } - } - } - - } - - - /**************************************************************** - * Roll back computations - *****************************************************************/ - for (i=0; i<nswaps; i++) - moved[swaps[i]] = -1; /* reset moved array */ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - to = where[higain] = (where[higain]+1)%2; - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - else if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - if (bndptr[k] != -1 && ed[k] == 0) - BNDDelete(nbnd, bndind, bndptr, k); - if (bndptr[k] == -1 && ed[k] > 0) - BNDInsert(nbnd, bndind, bndptr, k); - } - } - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("], LB: "); - Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, tvec); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - printf("\n"); - } - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (mincutorder == -1 || mincut == initcut) - break; - } - - for (i=0; i<ncon; i++) { - PQueueFree(ctrl, &parts[i][0]); - PQueueFree(ctrl, &parts[i][1]); - } - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - fwspacefree(ctrl, 2*ncon); - fwspacefree(ctrl, 2*ncon); - -} - - -/************************************************************************* -* This function selects the partition number and the queue from which -* we will move vertices out -**************************************************************************/ -void SelectQueue2(int ncon, float *npwgts, float *tpwgts, int *from, int *cnum, - PQueueType queues[MAXNCON][2], float *maxwgt) -{ - int i, j, maxgain=0; - float diff, max, maxdiff=0.0; - - *from = -1; - *cnum = -1; - - /* First determine the side and the queue, irrespective of the presence of nodes */ - for (j=0; j<2; j++) { - for (i=0; i<ncon; i++) { - diff = npwgts[j*ncon+i]-maxwgt[j*ncon+i]; - if (diff >= maxdiff) { - maxdiff = diff; - *from = j; - *cnum = i; - } - } - } - - if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { - /* The desired queue is empty, select a node from that side anyway */ - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][*from]) > 0) { - max = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]); - *cnum = i; - break; - } - } - - for (i++; i<ncon; i++) { - diff = npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]; - if (diff > max && PQueueGetSize(&queues[i][*from]) > 0) { - max = diff; - *cnum = i; - } - } - } - - /* Check to see if you can focus on the cut */ - if (maxdiff <= 0.0 || *from == -1) { - maxgain = -100000; - - for (j=0; j<2; j++) { - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][j]) > 0 && PQueueGetKey(&queues[i][j]) > maxgain) { - maxgain = PQueueGetKey(&queues[i][j]); - *from = j; - *cnum = i; - } - } - } - - /* printf("(%2d %2d) %3d\n", *from, *cnum, maxgain); */ - } -} - - -/************************************************************************* -* This function checks if the newbal is better than oldbal given the -* ubvector ubvec -**************************************************************************/ -int IsBetter2wayBalance(int ncon, float *newbal, float *oldbal, float *ubvec) -{ - int i, j; - float max1=0.0, max2=0.0, sum1=0.0, sum2=0.0, tmp; - - for (i=0; i<ncon; i++) { - tmp = (newbal[i]-1)/(ubvec[i]-1); - max1 = (max1 < tmp ? tmp : max1); - sum1 += tmp; - - tmp = (oldbal[i]-1)/(ubvec[i]-1); - max2 = (max2 < tmp ? tmp : max2); - sum2 += tmp; - } - - if (max1 < max2) - return 1; - else if (max1 > max2) - return 0; - else - return sum1 <= sum2; -} - - diff --git a/Metis/mincover.c b/Metis/mincover.c deleted file mode 100644 index 3ebd4091c7..0000000000 --- a/Metis/mincover.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mincover.c - * - * This file implements the minimum cover algorithm - * - * Started 8/1/97 - * George - * - * $Id: mincover.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - -/************************************************************************* -* Constants used by mincover algorithm -**************************************************************************/ -#define INCOL 10 -#define INROW 20 -#define VC 1 -#define SC 2 -#define HC 3 -#define VR 4 -#define SR 5 -#define HR 6 - - -/************************************************************************* -* This function returns the min-cover of a bipartite graph. -* The algorithm used is due to Hopcroft and Karp as modified by Duff etal -* adj: the adjacency list of the bipartite graph -* asize: the number of vertices in the first part of the bipartite graph -* bsize-asize: the number of vertices in the second part -* 0..(asize-1) > A vertices -* asize..bsize > B vertices -* -* Returns: -* cover : the actual cover (array) -* csize : the size of the cover -**************************************************************************/ -void MinCover(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *cover, int *csize) -{ - int i, j; - idxtype *mate, *queue, *flag, *level, *lst; - int fptr, rptr, lstptr; - int row, maxlevel, col; - - mate = idxsmalloc(bsize, -1, "MinCover: mate"); - flag = idxmalloc(bsize, "MinCover: flag"); - level = idxmalloc(bsize, "MinCover: level"); - queue = idxmalloc(bsize, "MinCover: queue"); - lst = idxmalloc(bsize, "MinCover: lst"); - - /* Get a cheap matching */ - for (i=0; i<asize; i++) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (mate[adjncy[j]] == -1) { - mate[i] = adjncy[j]; - mate[adjncy[j]] = i; - break; - } - } - } - - /* Get into the main loop */ - while (1) { - /* Initialization */ - fptr = rptr = 0; /* Empty Queue */ - lstptr = 0; /* Empty List */ - for (i=0; i<bsize; i++) { - level[i] = -1; - flag[i] = 0; - } - maxlevel = bsize; - - /* Insert free nodes into the queue */ - for (i=0; i<asize; i++) - if (mate[i] == -1) { - queue[rptr++] = i; - level[i] = 0; - } - - /* Perform the BFS */ - while (fptr != rptr) { - row = queue[fptr++]; - if (level[row] < maxlevel) { - flag[row] = 1; - for (j=xadj[row]; j<xadj[row+1]; j++) { - col = adjncy[j]; - if (!flag[col]) { /* If this column has not been accessed yet */ - flag[col] = 1; - if (mate[col] == -1) { /* Free column node was found */ - maxlevel = level[row]; - lst[lstptr++] = col; - } - else { /* This column node is matched */ - if (flag[mate[col]]) - printf("\nSomething wrong, flag[%d] is 1",mate[col]); - queue[rptr++] = mate[col]; - level[mate[col]] = level[row] + 1; - } - } - } - } - } - - if (lstptr == 0) - break; /* No free columns can be reached */ - - /* Perform restricted DFS from the free column nodes */ - for (i=0; i<lstptr; i++) - MinCover_Augment(xadj, adjncy, lst[i], mate, flag, level, maxlevel); - } - - MinCover_Decompose(xadj, adjncy, asize, bsize, mate, cover, csize); - - GKfree(&mate, &flag, &level, &queue, &lst, LTERM); - -} - - -/************************************************************************* -* This function perfoms a restricted DFS and augments matchings -**************************************************************************/ -int MinCover_Augment(idxtype *xadj, idxtype *adjncy, int col, idxtype *mate, idxtype *flag, idxtype *level, int maxlevel) -{ - int i; - int row = -1; - int status; - - flag[col] = 2; - for (i=xadj[col]; i<xadj[col+1]; i++) { - row = adjncy[i]; - - if (flag[row] == 1) { /* First time through this row node */ - if (level[row] == maxlevel) { /* (col, row) is an edge of the G^T */ - flag[row] = 2; /* Mark this node as being visited */ - if (maxlevel != 0) - status = MinCover_Augment(xadj, adjncy, mate[row], mate, flag, level, maxlevel-1); - else - status = 1; - - if (status) { - mate[col] = row; - mate[row] = col; - return 1; - } - } - } - } - - return 0; -} - - - -/************************************************************************* -* This function performs a coarse decomposition and determines the -* min-cover. -* REF: Pothen ACMTrans. on Amth Software -**************************************************************************/ -void MinCover_Decompose(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *mate, idxtype *cover, int *csize) -{ - int i, k; - idxtype *where; - int card[10]; - - where = idxmalloc(bsize, "MinCover_Decompose: where"); - for (i=0; i<10; i++) - card[i] = 0; - - for (i=0; i<asize; i++) - where[i] = SC; - for (; i<bsize; i++) - where[i] = SR; - - for (i=0; i<asize; i++) - if (mate[i] == -1) - MinCover_ColDFS(xadj, adjncy, i, mate, where, INCOL); - for (; i<bsize; i++) - if (mate[i] == -1) - MinCover_RowDFS(xadj, adjncy, i, mate, where, INROW); - - for (i=0; i<bsize; i++) - card[where[i]]++; - - k = 0; - if (abs(card[VC]+card[SC]-card[HR]) < abs(card[VC]-card[SR]-card[HR])) { /* S = VC+SC+HR */ - /* printf("%d %d ",vc+sc, hr); */ - for (i=0; i<bsize; i++) - if (where[i] == VC || where[i] == SC || where[i] == HR) - cover[k++] = i; - } - else { /* S = VC+SR+HR */ - /* printf("%d %d ",vc, hr+sr); */ - for (i=0; i<bsize; i++) - if (where[i] == VC || where[i] == SR || where[i] == HR) - cover[k++] = i; - } - - *csize = k; - free(where); - -} - - -/************************************************************************* -* This function perfoms a dfs starting from an unmatched col node -* forming alternate paths -**************************************************************************/ -void MinCover_ColDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag) -{ - int i; - - if (flag == INCOL) { - if (where[root] == HC) - return; - where[root] = HC; - for (i=xadj[root]; i<xadj[root+1]; i++) - MinCover_ColDFS(xadj, adjncy, adjncy[i], mate, where, INROW); - } - else { - if (where[root] == HR) - return; - where[root] = HR; - if (mate[root] != -1) - MinCover_ColDFS(xadj, adjncy, mate[root], mate, where, INCOL); - } - -} - -/************************************************************************* -* This function perfoms a dfs starting from an unmatched col node -* forming alternate paths -**************************************************************************/ -void MinCover_RowDFS(idxtype *xadj, idxtype *adjncy, int root, idxtype *mate, idxtype *where, int flag) -{ - int i; - - if (flag == INROW) { - if (where[root] == VR) - return; - where[root] = VR; - for (i=xadj[root]; i<xadj[root+1]; i++) - MinCover_RowDFS(xadj, adjncy, adjncy[i], mate, where, INCOL); - } - else { - if (where[root] == VC) - return; - where[root] = VC; - if (mate[root] != -1) - MinCover_RowDFS(xadj, adjncy, mate[root], mate, where, INROW); - } - -} - - - diff --git a/Metis/minitpart.c b/Metis/minitpart.c deleted file mode 100644 index 2f77d221a9..0000000000 --- a/Metis/minitpart.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * minitpart.c - * - * This file contains code that performs the initial partition of the - * coarsest graph - * - * Started 7/23/97 - * George - * - * $Id: minitpart.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function computes the initial bisection of the coarsest graph -**************************************************************************/ -void MocInit2WayPartition(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) -{ - int i, dbglvl; - - dbglvl = ctrl->dbglvl; - IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); - IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - - switch (ctrl->IType) { - case IPART_GGPKL: - MocGrowBisection(ctrl, graph, tpwgts, ubfactor); - break; - case IPART_RANDOM: - MocRandomBisection(ctrl, graph, tpwgts, ubfactor); - break; - default: - errexit("Unknown initial partition type: %d\n", ctrl->IType); - } - - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d [%d]\n", graph->mincut, graph->where[0])); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - ctrl->dbglvl = dbglvl; - -} - - - - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void MocGrowBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) -{ - int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs; - idxtype *bestwhere, *where; - - nvtxs = graph->nvtxs; - - MocAllocate2WayPartitionMemory(ctrl, graph); - where = graph->where; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = idxsum(graph->nedges, graph->adjwgt); - - for (; nbfs>0; nbfs--) { - idxset(nvtxs, 1, where); - where[RandomInRange(nvtxs)] = 0; - - MocCompute2WayPartitionParams(ctrl, graph); - - MocInit2WayBalance(ctrl, graph, tpwgts); - - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); - - MocBalance2Way(ctrl, graph, tpwgts, 1.02); - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); - - if (bestcut >= graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - if (bestcut == 0) - break; - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - GKfree(&bestwhere, LTERM); -} - - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void MocRandomBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) -{ - int i, ii, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs, qnum; - idxtype *bestwhere, *where, *perm; - int counts[MAXNCON]; - float *nvwgt; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - nvwgt = graph->nvwgt; - - MocAllocate2WayPartitionMemory(ctrl, graph); - where = graph->where; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = idxsum(graph->nedges, graph->adjwgt); - perm = idxmalloc(nvtxs, "BisectGraph: perm"); - - for (; nbfs>0; nbfs--) { - for (i=0; i<ncon; i++) - counts[i] = 0; - - RandomPermute(nvtxs, perm, 1); - - /* Partition by spliting the queues randomly */ - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - qnum = samax(ncon, nvwgt+i*ncon); - where[i] = counts[qnum]; - counts[qnum] = (counts[qnum]+1)%2; - } - - MocCompute2WayPartitionParams(ctrl, graph); - - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 6); - MocBalance2Way(ctrl, graph, tpwgts, 1.02); - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 6); - MocBalance2Way(ctrl, graph, tpwgts, 1.02); - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 6); - - /* - printf("Edgecut: %6d, NPwgts: [", graph->mincut); - for (i=0; i<graph->ncon; i++) - printf("(%.3f %.3f) ", graph->npwgts[i], graph->npwgts[graph->ncon+i]); - printf("]\n"); - */ - - if (bestcut >= graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - if (bestcut == 0) - break; - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - GKfree(&bestwhere, &perm, LTERM); -} - - - - -/************************************************************************* -* This function balances two partitions by moving the highest gain -* (including negative gain) vertices to the other domain. -* It is used only when tha unbalance is due to non contigous -* subdomains. That is, the are no boundary vertices. -* It moves vertices from the domain that is overweight to the one that -* is underweight. -**************************************************************************/ -void MocInit2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts) -{ - int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp; - idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; - idxtype *perm, *qnum; - float *nvwgt, *npwgts; - PQueueType parts[MAXNCON][2]; - int higain, oldgain, mincut; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - adjncy = graph->adjncy; - nvwgt = graph->nvwgt; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - npwgts = graph->npwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - perm = idxwspacemalloc(ctrl, nvtxs); - qnum = idxwspacemalloc(ctrl, nvtxs); - - /* This is called for initial partitioning so we know from where to pick nodes */ - from = 1; - to = (from+1)%2; - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Parts: ["); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], - graph->nvtxs, graph->nbnd, graph->mincut, - Compute2WayHLoadImbalance(ncon, npwgts, tpwgts)); - } - - for (i=0; i<ncon; i++) { - PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1); - PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1); - } - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - ASSERT(CheckGraph(graph)); - - /* Compute the queues in which each vertex will be assigned to */ - for (i=0; i<nvtxs; i++) - qnum[i] = samax(ncon, nvwgt+i*ncon); - - /* Insert the nodes of the proper partition in the appropriate priority queue */ - RandomPermute(nvtxs, perm, 1); - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - if (where[i] == from) { - if (ed[i] > 0) - PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]); - else - PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]); - } - } - - - mincut = graph->mincut; - nbnd = graph->nbnd; - for (nswaps=0; nswaps<nvtxs; nswaps++) { - if (AreAnyVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, tpwgts[from])) - break; - - if ((cnum = SelectQueueOneWay(ncon, npwgts, tpwgts, from, parts)) == -1) - break; - - if ((higain = PQueueGetMax(&parts[cnum][0])) == -1) - higain = PQueueGetMax(&parts[cnum][1]); - - mincut -= (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - - where[higain] = to; - - if (ctrl->dbglvl&DBG_MOVEINFO) { - printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf(", LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts)); - if (ed[higain] == 0 && id[higain] > 0) - printf("\t Pulled from the interior!\n"); - } - - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update the queue position */ - if (where[k] == from) { - if (ed[k] > 0 && bndptr[k] == -1) { /* It moves in boundary */ - PQueueDelete(&parts[qnum[k]][1], k, oldgain); - PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]); - } - else { /* It must be in the boundary already */ - if (bndptr[k] == -1) - printf("What you thought was wrong!\n"); - PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]); - } - } - - /* Update its boundary information */ - if (ed[k] == 0 && bndptr[k] != -1) - BNDDelete(nbnd, bndind, bndptr, k); - else if (ed[k] > 0 && bndptr[k] == -1) - BNDInsert(nbnd, bndind, bndptr, k); - } - - ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut)); - - } - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf(", LB: %.3f\n", Compute2WayHLoadImbalance(ncon, npwgts, tpwgts)); - } - - graph->mincut = mincut; - graph->nbnd = nbnd; - - for (i=0; i<ncon; i++) { - PQueueFree(ctrl, &parts[i][0]); - PQueueFree(ctrl, &parts[i][1]); - } - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - - -/************************************************************************* -* This function selects the partition number and the queue from which -* we will move vertices out -**************************************************************************/ -int SelectQueueOneWay(int ncon, float *npwgts, float *tpwgts, int from, PQueueType queues[MAXNCON][2]) -{ - int i, cnum=-1; - float max=0.0; - - for (i=0; i<ncon; i++) { - if (npwgts[from*ncon+i]-tpwgts[from] >= max && - PQueueGetSize(&queues[i][0]) + PQueueGetSize(&queues[i][1]) > 0) { - max = npwgts[from*ncon+i]-tpwgts[0]; - cnum = i; - } - } - - return cnum; -} - - diff --git a/Metis/minitpart2.c b/Metis/minitpart2.c deleted file mode 100644 index efda6fbdf2..0000000000 --- a/Metis/minitpart2.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * minitpart2.c - * - * This file contains code that performs the initial partition of the - * coarsest graph - * - * Started 7/23/97 - * George - * - * $Id: minitpart2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function computes the initial bisection of the coarsest graph -**************************************************************************/ -void MocInit2WayPartition2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int dbglvl; - - dbglvl = ctrl->dbglvl; - IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); - IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - - switch (ctrl->IType) { - case IPART_GGPKL: - case IPART_RANDOM: - MocGrowBisection2(ctrl, graph, tpwgts, ubvec); - break; - case 3: - MocGrowBisectionNew2(ctrl, graph, tpwgts, ubvec); - break; - default: - errexit("Unknown initial partition type: %d\n", ctrl->IType); - } - - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut)); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - ctrl->dbglvl = dbglvl; - -} - - - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void MocGrowBisection2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs; - idxtype *bestwhere, *where; - - nvtxs = graph->nvtxs; - - MocAllocate2WayPartitionMemory(ctrl, graph); - where = graph->where; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = idxsum(graph->nedges, graph->adjwgt); - - for (; nbfs>0; nbfs--) { - idxset(nvtxs, 1, where); - where[RandomInRange(nvtxs)] = 0; - - MocCompute2WayPartitionParams(ctrl, graph); - - MocBalance2Way2(ctrl, graph, tpwgts, ubvec); - - MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); - - MocBalance2Way2(ctrl, graph, tpwgts, ubvec); - MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); - - if (bestcut > graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - if (bestcut == 0) - break; - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - GKfree(&bestwhere, LTERM); -} - - - - - - -/************************************************************************* -* This function takes a graph and produces a bisection by using a region -* growing algorithm. The resulting partition is returned in -* graph->where -**************************************************************************/ -void MocGrowBisectionNew2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs; - idxtype *bestwhere, *where; - - nvtxs = graph->nvtxs; - - MocAllocate2WayPartitionMemory(ctrl, graph); - where = graph->where; - - bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); - nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); - bestcut = idxsum(graph->nedges, graph->adjwgt); - - for (; nbfs>0; nbfs--) { - idxset(nvtxs, 1, where); - where[RandomInRange(nvtxs)] = 0; - - MocCompute2WayPartitionParams(ctrl, graph); - - MocInit2WayBalance2(ctrl, graph, tpwgts, ubvec); - - MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); - - if (bestcut > graph->mincut) { - bestcut = graph->mincut; - idxcopy(nvtxs, where, bestwhere); - if (bestcut == 0) - break; - } - } - - graph->mincut = bestcut; - idxcopy(nvtxs, bestwhere, where); - - GKfree(&bestwhere, LTERM); -} - - - -/************************************************************************* -* This function balances two partitions by moving the highest gain -* (including negative gain) vertices to the other domain. -* It is used only when tha unbalance is due to non contigous -* subdomains. That is, the are no boundary vertices. -* It moves vertices from the domain that is overweight to the one that -* is underweight. -**************************************************************************/ -void MocInit2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp, imin; - idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; - idxtype *moved, *perm, *qnum; - float *nvwgt, *npwgts, minwgt; - PQueueType parts[MAXNCON][2]; - int higain, oldgain, mincut; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - adjncy = graph->adjncy; - nvwgt = graph->nvwgt; - adjwgt = graph->adjwgt; - where = graph->where; - id = graph->id; - ed = graph->ed; - npwgts = graph->npwgts; - bndptr = graph->bndptr; - bndind = graph->bndind; - - moved = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - qnum = idxwspacemalloc(ctrl, nvtxs); - - /* This is called for initial partitioning so we know from where to pick nodes */ - from = 1; - to = (from+1)%2; - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Parts: ["); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf("] T[%.3f %.3f], Nv-Nb[%5d, %5d]. ICut: %6d, LB: %.3f [B]\n", tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut, ComputeLoadImbalance(ncon, 2, npwgts, tpwgts)); - } - - for (i=0; i<ncon; i++) { - PQueueInit(ctrl, &parts[i][0], nvtxs, PLUS_GAINSPAN+1); - PQueueInit(ctrl, &parts[i][1], nvtxs, PLUS_GAINSPAN+1); - } - - idxset(nvtxs, -1, moved); - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - ASSERT(CheckGraph(graph)); - - /* Compute the queues in which each vertex will be assigned to */ - for (i=0; i<nvtxs; i++) - qnum[i] = samax(ncon, nvwgt+i*ncon); - - /* Insert the nodes of the proper partition in the appropriate priority queue */ - RandomPermute(nvtxs, perm, 1); - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - if (where[i] == from) { - if (ed[i] > 0) - PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]); - else - PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]); - } - } - -/* - for (i=0; i<ncon; i++) - printf("Queue #%d has %d %d\n", i, parts[i][0].nnodes, parts[i][1].nnodes); -*/ - - /* Determine the termination criterion */ - imin = 0; - for (i=1; i<ncon; i++) - imin = (ubvec[i] < ubvec[imin] ? i : imin); - minwgt = .5/ubvec[imin]; - - mincut = graph->mincut; - nbnd = graph->nbnd; - for (nswaps=0; nswaps<nvtxs; nswaps++) { - /* Exit as soon as the minimum weight crossed over */ - if (npwgts[to*ncon+imin] > minwgt) - break; - - if ((cnum = SelectQueueOneWay2(ncon, npwgts+to*ncon, parts, ubvec)) == -1) - break; - - if ((higain = PQueueGetMax(&parts[cnum][0])) == -1) - higain = PQueueGetMax(&parts[cnum][1]); - - mincut -= (ed[higain]-id[higain]); - saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); - - where[higain] = to; - moved[higain] = nswaps; - - if (ctrl->dbglvl&DBG_MOVEINFO) { - printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf(", LB: %.3f\n", ComputeLoadImbalance(ncon, 2, npwgts, tpwgts)); - if (ed[higain] == 0 && id[higain] > 0) - printf("\t Pulled from the interior!\n"); - } - - - /************************************************************** - * Update the id[i]/ed[i] values of the affected nodes - ***************************************************************/ - SWAP(id[higain], ed[higain], tmp); - if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) - BNDDelete(nbnd, bndind, bndptr, higain); - if (ed[higain] > 0 && bndptr[higain] == -1) - BNDInsert(nbnd, bndind, bndptr, higain); - - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - oldgain = ed[k]-id[k]; - - kwgt = (to == where[k] ? adjwgt[j] : -adjwgt[j]); - INC_DEC(id[k], ed[k], kwgt); - - /* Update the queue position */ - if (moved[k] == -1 && where[k] == from) { - if (ed[k] > 0 && bndptr[k] == -1) { /* It moves in boundary */ - PQueueDelete(&parts[qnum[k]][1], k, oldgain); - PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]); - } - else { /* It must be in the boundary already */ - if (bndptr[k] == -1) - printf("What you thought was wrong!\n"); - PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]); - } - } - - /* Update its boundary information */ - if (ed[k] == 0 && bndptr[k] != -1) - BNDDelete(nbnd, bndind, bndptr, k); - else if (ed[k] > 0 && bndptr[k] == -1) - BNDInsert(nbnd, bndind, bndptr, k); - } - - ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut)); - - } - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd); - for (l=0; l<ncon; l++) - printf("(%.3f, %.3f) ", npwgts[l], npwgts[ncon+l]); - printf(", LB: %.3f\n", ComputeLoadImbalance(ncon, 2, npwgts, tpwgts)); - } - - graph->mincut = mincut; - graph->nbnd = nbnd; - - for (i=0; i<ncon; i++) { - PQueueFree(ctrl, &parts[i][0]); - PQueueFree(ctrl, &parts[i][1]); - } - - ASSERT(ComputeCut(graph, where) == graph->mincut); - ASSERT(CheckBnd(graph)); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function selects the partition number and the queue from which -* we will move vertices out -**************************************************************************/ -int SelectQueueOneWay2(int ncon, float *pto, PQueueType queues[MAXNCON][2], float *ubvec) -{ - int i, cnum=-1, imax, maxgain; - float max=0.0; - float twgt[MAXNCON]; - - for (i=0; i<ncon; i++) { - if (max < pto[i]) { - imax = i; - max = pto[i]; - } - } - for (i=0; i<ncon; i++) - twgt[i] = (max/(ubvec[imax]*ubvec[i]))/pto[i]; - twgt[imax] = 0.0; - - max = 0.0; - for (i=0; i<ncon; i++) { - if (max < twgt[i] && (PQueueGetSize(&queues[i][0]) > 0 || PQueueGetSize(&queues[i][1]) > 0)) { - max = twgt[i]; - cnum = i; - } - } - if (max > 1) - return cnum; - - /* optimize of cut */ - maxgain = -10000000; - for (i=0; i<ncon; i++) { - if (PQueueGetSize(&queues[i][0]) > 0 && PQueueGetKey(&queues[i][0]) > maxgain) { - maxgain = PQueueGetKey(&queues[i][0]); - cnum = i; - } - } - - return cnum; - -} - diff --git a/Metis/mkmetis.c b/Metis/mkmetis.c deleted file mode 100644 index ed270e1c1a..0000000000 --- a/Metis/mkmetis.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mkmetis.c - * - * This file contains the top level routines for the multilevel k-way partitioning - * algorithm KMETIS. - * - * Started 7/28/97 - * George - * - * $Id: mkmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - - -/************************************************************************* -* This function is the entry point for KWMETIS -**************************************************************************/ -void METIS_mCPartGraphKway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, - idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, - int *nparts, float *rubvec, int *options, int *edgecut, - idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_KMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = McKMETIS_CTYPE; - ctrl.IType = McKMETIS_ITYPE; - ctrl.RType = McKMETIS_RTYPE; - ctrl.dbglvl = McKMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_KMETIS; - ctrl.CoarsenTo = amax((*nvtxs)/(20*log2(*nparts)), 30*(*nparts)); - - ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MCMlevelKWayPartitioning(&ctrl, &graph, *nparts, part, rubvec); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -int MCMlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, - float *rubvec) -{ - int i, j, nvtxs; - GraphType *cgraph; - int options[10], edgecut; - - cgraph = MCCoarsen2Way(ctrl, graph); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); - MocAllocateKWayPartitionMemory(ctrl, cgraph, nparts); - - options[0] = 1; - options[OPTION_CTYPE] = MATCH_SBHEM_INFNORM; - options[OPTION_ITYPE] = IPART_RANDOM; - options[OPTION_RTYPE] = RTYPE_FM; - options[OPTION_DBGLVL] = 0; - - /* Determine what you will use as the initial partitioner, based on tolerances */ - for (i=0; i<graph->ncon; i++) { - if (rubvec[i] > 1.2) - break; - } - if (i == graph->ncon) - METIS_mCPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon, - cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts, - options, &edgecut, cgraph->where); - else - METIS_mCHPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon, - cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts, - rubvec, options, &edgecut, cgraph->where); - - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); - IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); - - IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); - - MocRefineKWayHorizontal(ctrl, graph, cgraph, nparts, rubvec); - - idxcopy(graph->nvtxs, graph->where, part); - - GKfree(&graph->nvwgt, &graph->npwgts, &graph->gdata, &graph->rdata, LTERM); - - return graph->mincut; - -} - diff --git a/Metis/mkwayfmh.c b/Metis/mkwayfmh.c deleted file mode 100644 index 0d06ed0e38..0000000000 --- a/Metis/mkwayfmh.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * mkwayfmh.c - * - * This file contains code that implements the multilevel k-way refinement - * - * Started 7/28/97 - * George - * - * $Id: mkwayfmh.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void MCRandom_KWayEdgeRefineHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, - float *orgubvec, int npasses) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nmoves, nbnd, myndegrees, same; - int from, me, to, oldcut, gain; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *perm, *bndptr, *bndind; - EDegreeType *myedegrees; - RInfoType *myrinfo; - float *npwgts, *nvwgt, *minwgt, *maxwgt, maxlb, minlb, ubvec[MAXNCON], tvec[MAXNCON]; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - npwgts = graph->npwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = fwspacemalloc(ctrl, nparts*ncon); - maxwgt = fwspacemalloc(ctrl, nparts*ncon); - - /* See if the orgubvec consists of identical constraints */ - maxlb = minlb = orgubvec[0]; - for (i=1; i<ncon; i++) { - minlb = (orgubvec[i] < minlb ? orgubvec[i] : minlb); - maxlb = (orgubvec[i] > maxlb ? orgubvec[i] : maxlb); - } - same = (fabs(maxlb-minlb) < .01 ? 1 : 0); - - - /* Let's not get very optimistic. Let Balancing do the work */ - ComputeHKWayLoadImbalance(ncon, nparts, npwgts, ubvec); - for (i=0; i<ncon; i++) - ubvec[i] = amax(ubvec[i], orgubvec[i]); - - if (!same) { - for (i=0; i<nparts; i++) { - for (j=0; j<ncon; j++) { - maxwgt[i*ncon+j] = ubvec[j]/nparts; - minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts); - } - } - } - else { - maxlb = ubvec[0]; - for (i=1; i<ncon; i++) - maxlb = (ubvec[i] > maxlb ? ubvec[i] : maxlb); - - for (i=0; i<nparts; i++) { - for (j=0; j<ncon; j++) { - maxwgt[i*ncon+j] = maxlb/nparts; - minwgt[i*ncon+j] = 1.0/(maxlb*nparts); - } - } - } - - - perm = idxwspacemalloc(ctrl, nvtxs); - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ", - npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], - graph->nvtxs, graph->nbnd, graph->mincut); - ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - printf("\n"); - } - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (nmoves=iii=0; iii<graph->nbnd; iii++) { - ii = perm[iii]; - if (ii >= nbnd) - continue; - i = bndind[ii]; - - myrinfo = graph->rinfo+i; - - if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */ - from = where[i]; - nvwgt = graph->nvwgt+i*ncon; - - if (myrinfo->id > 0 && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon)) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - gain = myedegrees[k].ed - myrinfo->id; - if (gain >= 0 && - (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) || - IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if ((myedegrees[j].ed > myedegrees[k].ed && - (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) || - IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) || - (myedegrees[j].ed == myedegrees[k].ed && - IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec))) - k = j; - } - - to = myedegrees[k].pid; - - if (myedegrees[k].ed-myrinfo->id == 0 - && !IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec) - && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, npwgts+from*ncon, maxwgt+from*ncon)) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update where, weight, and ID/ED information of the vertex you moved */ - saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1); - where[i] = to; - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed-myrinfo->id < 0) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - - } - nmoves++; - } - } - - graph->nbnd = nbnd; - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ", - npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], - nbnd, nmoves, graph->mincut); - ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - printf("\n"); - } - - if (graph->mincut == oldcut) - break; - } - - fwspacefree(ctrl, ncon*nparts); - fwspacefree(ctrl, ncon*nparts); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, - float *ubvec, int npasses) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nbnd, myndegrees, oldgain, gain, nmoves; - int from, me, to, oldcut; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *perm, *bndptr, *bndind, *moved; - EDegreeType *myedegrees; - RInfoType *myrinfo; - PQueueType queue; - float *npwgts, *nvwgt, *minwgt, *maxwgt, tvec[MAXNCON]; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - - where = graph->where; - npwgts = graph->npwgts; - - /* Setup the weight intervals of the various subdomains */ - minwgt = fwspacemalloc(ctrl, ncon*nparts); - maxwgt = fwspacemalloc(ctrl, ncon*nparts); - - for (i=0; i<nparts; i++) { - for (j=0; j<ncon; j++) { - maxwgt[i*ncon+j] = ubvec[j]/nparts; - minwgt[i*ncon+j] = 1.0/(ubvec[j]*nparts); - } - } - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxwspacemalloc(ctrl, nvtxs); - - PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); - - if (ctrl->dbglvl&DBG_REFINE) { - printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ", - npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], - graph->nvtxs, graph->nbnd, graph->mincut); - ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - printf("[B]\n"); - } - - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - /* Check to see if things are out of balance, given the tolerance */ - if (MocIsHBalanced(ncon, nparts, npwgts, ubvec)) - break; - - PQueueReset(&queue); - idxset(nvtxs, -1, moved); - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id); - moved[i] = 2; - } - - nmoves = 0; - for (;;) { - if ((i = PQueueGetMax(&queue)) == -1) - break; - moved[i] = 1; - - myrinfo = graph->rinfo+i; - from = where[i]; - nvwgt = graph->nvwgt+i*ncon; - - if (AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon)) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec)) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec)) - k = j; - } - - to = myedegrees[k].pid; - - j = 0; - if (!AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon)) - j++; - if (myedegrees[k].ed-myrinfo->id >= 0) - j++; - if (!AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) && - AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon)) - j++; - if (j == 0) - continue; - -/* DELETE - if (myedegrees[k].ed-myrinfo->id < 0 && - AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon) && - AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) && - AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon)) - continue; -*/ - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update where, weight, and ID/ED information of the vertex you moved */ - saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1); - saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1); - where[i] = to; - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed == 0) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - oldgain = (myrinfo->ed-myrinfo->id); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed > 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed == 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - - /* Update the queue */ - if (me == to || me == from) { - gain = myrinfo->ed-myrinfo->id; - if (moved[ii] == 2) { - if (myrinfo->ed > 0) - PQueueUpdate(&queue, ii, oldgain, gain); - else { - PQueueDelete(&queue, ii, oldgain); - moved[ii] = -1; - } - } - else if (moved[ii] == -1 && myrinfo->ed > 0) { - PQueueInsert(&queue, ii, gain); - moved[ii] = 2; - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - } - nmoves++; - } - - graph->nbnd = nbnd; - - if (ctrl->dbglvl&DBG_REFINE) { - printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ", - npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], - nbnd, nmoves, graph->mincut); - ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); - for (i=0; i<ncon; i++) - printf("%.3f ", tvec[i]); - printf("\n"); - } - - if (nmoves == 0) - break; - } - - PQueueFree(ctrl, &queue); - - fwspacefree(ctrl, ncon*nparts); - fwspacefree(ctrl, ncon*nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - - - - - -/************************************************************************* -* This function checks if the vertex weights of two vertices are below -* a given set of values -**************************************************************************/ -int AreAllHVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit) -{ - int i; - - for (i=0; i<ncon; i++) - if (alpha*vwgt1[i] + beta*vwgt2[i] > limit[i]) - return 0; - - return 1; -} - - - -/************************************************************************* -* This function checks if the vertex weights of two vertices are above -* a given set of values -**************************************************************************/ -int AreAllHVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit) -{ - int i; - - for (i=0; i<ncon; i++) - if (alpha*vwgt1[i] + beta*vwgt2[i] < limit[i]) - return 0; - - return 1; -} - - -/************************************************************************* -* This function computes the load imbalance over all the constrains -* For now assume that we just want balanced partitionings -**************************************************************************/ -void ComputeHKWayLoadImbalance(int ncon, int nparts, float *npwgts, float *lbvec) -{ - int i, j; - float max; - - for (i=0; i<ncon; i++) { - max = 0.0; - for (j=0; j<nparts; j++) { - if (npwgts[j*ncon+i] > max) - max = npwgts[j*ncon+i]; - } - - lbvec[i] = max*nparts; - } -} - - -/************************************************************************* -* This function determines if a partitioning is horizontally balanced -**************************************************************************/ -int MocIsHBalanced(int ncon, int nparts, float *npwgts, float *ubvec) -{ - int i, j; - float max; - - for (i=0; i<ncon; i++) { - max = 0.0; - for (j=0; j<nparts; j++) { - if (npwgts[j*ncon+i] > max) - max = npwgts[j*ncon+i]; - } - - if (ubvec[i] < max*nparts) - return 0; - } - - return 1; -} - - - - - -/************************************************************************* -* This function checks if the pairwise balance of the between the two -* partitions will improve by moving the vertex v from pfrom to pto, -* subject to the target partition weights of tfrom, and tto respectively -**************************************************************************/ -int IsHBalanceBetterFT(int ncon, int nparts, float *pfrom, float *pto, float *vwgt, float *ubvec) -{ - int i, j, k; - float blb1=0.0, alb1=0.0, sblb=0.0, salb=0.0; - float blb2=0.0, alb2=0.0; - float temp; - - for (i=0; i<ncon; i++) { - temp = amax(pfrom[i], pto[i])*nparts/ubvec[i]; - if (blb1 < temp) { - blb2 = blb1; - blb1 = temp; - } - else if (blb2 < temp) - blb2 = temp; - sblb += temp; - - temp = amax(pfrom[i]-vwgt[i], pto[i]+vwgt[i])*nparts/ubvec[i]; - if (alb1 < temp) { - alb2 = alb1; - alb1 = temp; - } - else if (alb2 < temp) - alb2 = temp; - salb += temp; - } - - if (alb1 < blb1) - return 1; - if (blb1 < alb1) - return 0; - if (alb2 < blb2) - return 1; - if (blb2 < alb2) - return 0; - - return salb < sblb; - -} - - - - -/************************************************************************* -* This function checks if it will be better to move a vertex to pt2 than -* to pt1 subject to their target weights of tt1 and tt2, respectively -* This routine takes into account the weight of the vertex in question -**************************************************************************/ -int IsHBalanceBetterTT(int ncon, int nparts, float *pt1, float *pt2, float *vwgt, float *ubvec) -{ - int i; - float m11=0.0, m12=0.0, m21=0.0, m22=0.0, sm1=0.0, sm2=0.0, temp; - - for (i=0; i<ncon; i++) { - temp = (pt1[i]+vwgt[i])*nparts/ubvec[i]; - if (m11 < temp) { - m12 = m11; - m11 = temp; - } - else if (m12 < temp) - m12 = temp; - sm1 += temp; - - temp = (pt2[i]+vwgt[i])*nparts/ubvec[i]; - if (m21 < temp) { - m22 = m21; - m21 = temp; - } - else if (m22 < temp) - m22 = temp; - sm2 += temp; - } - - if (m21 < m11) - return 1; - if (m21 > m11) - return 0; - if (m22 < m12) - return 1; - if (m22 > m12) - return 0; - - return sm2 < sm1; -} - diff --git a/Metis/mkwayrefine.c b/Metis/mkwayrefine.c deleted file mode 100644 index 0984ad707d..0000000000 --- a/Metis/mkwayrefine.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mkwayrefine.c - * - * This file contains the driving routines for multilevel k-way refinement - * - * Started 7/28/97 - * George - * - * $Id: mkwayrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of refinement -**************************************************************************/ -void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, - float *ubvec) -{ - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - /* Compute the parameters of the coarsest graph */ - MocComputeKWayPartitionParams(ctrl, graph, nparts); - - for (;;) { - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - - if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) { - MocComputeKWayBalanceBoundary(ctrl, graph, nparts); - MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); - ComputeKWayBoundary(ctrl, graph, nparts); - } - - MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - graph = graph->finer; - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - MocProjectKWayPartition(ctrl, graph, nparts); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) { - MocComputeKWayBalanceBoundary(ctrl, graph, nparts); - MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); - ComputeKWayBoundary(ctrl, graph, nparts); - MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - - - -/************************************************************************* -* This function allocates memory for k-way edge refinement -**************************************************************************/ -void MocAllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int nvtxs, ncon, pad64; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - - pad64 = (3*nvtxs)%2; - - graph->rdata = idxmalloc(3*nvtxs+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata"); - graph->where = graph->rdata; - graph->bndptr = graph->rdata + nvtxs; - graph->bndind = graph->rdata + 2*nvtxs; - graph->rinfo = (RInfoType *)(graph->rdata + 3*nvtxs + pad64); - - graph->npwgts = fmalloc(ncon*nparts, "MocAllocateKWayPartitionMemory: npwgts"); -} - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, j, k, l, nvtxs, ncon, nbnd, mincut, me, other; - idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr; - RInfoType *rinfo, *myrinfo; - EDegreeType *myedegrees; - float *nvwgt, *npwgts; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - npwgts = sset(ncon*nparts, 0.0, graph->npwgts); - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - rinfo = graph->rinfo; - - - /*------------------------------------------------------------ - / Compute now the id/ed degrees - /------------------------------------------------------------*/ - ctrl->wspace.cdegree = 0; - nbnd = mincut = 0; - for (i=0; i<nvtxs; i++) { - me = where[i]; - saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); - - myrinfo = rinfo+i; - myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; - myrinfo->edegrees = NULL; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me != where[adjncy[j]]) - myrinfo->ed += adjwgt[j]; - } - myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed; - - if (myrinfo->ed > 0) - mincut += myrinfo->ed; - - if (myrinfo->ed-myrinfo->id >= 0) - BNDInsert(nbnd, bndind, bndptr, i); - - /* Time to compute the particular external degrees */ - if (myrinfo->ed > 0) { - myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - other = where[adjncy[j]]; - if (me != other) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == other) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = other; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - } - - ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]); - } - } - - graph->mincut = mincut/2; - graph->nbnd = nbnd; - -} - - - -/************************************************************************* -* This function projects a partition, and at the same time computes the -* parameters for refinement. -**************************************************************************/ -void MocProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees; - idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; - idxtype *cmap, *where, *bndptr, *bndind; - idxtype *cwhere; - GraphType *cgraph; - RInfoType *crinfo, *rinfo, *myrinfo; - EDegreeType *myedegrees; - idxtype *htable; - - cgraph = graph->coarser; - cwhere = cgraph->where; - crinfo = cgraph->rinfo; - - nvtxs = graph->nvtxs; - cmap = graph->cmap; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - - MocAllocateKWayPartitionMemory(ctrl, graph, nparts); - where = graph->where; - rinfo = graph->rinfo; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - /* Go through and project partition and compute id/ed for the nodes */ - for (i=0; i<nvtxs; i++) { - k = cmap[i]; - where[i] = cwhere[k]; - cmap[i] = crinfo[k].ed; /* For optimization */ - } - - htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); - - ctrl->wspace.cdegree = 0; - for (nbnd=0, i=0; i<nvtxs; i++) { - me = where[i]; - - myrinfo = rinfo+i; - myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; - myrinfo->edegrees = NULL; - - myrinfo->id = adjwgtsum[i]; - - if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */ - istart = xadj[i]; - iend = xadj[i+1]; - - myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += iend-istart; - - ndegrees = 0; - for (j=istart; j<iend; j++) { - other = where[adjncy[j]]; - if (me != other) { - myrinfo->ed += adjwgt[j]; - if ((k = htable[other]) == -1) { - htable[other] = ndegrees; - myedegrees[ndegrees].pid = other; - myedegrees[ndegrees++].ed = adjwgt[j]; - } - else { - myedegrees[k].ed += adjwgt[j]; - } - } - } - myrinfo->id -= myrinfo->ed; - - /* Remove space for edegrees if it was interior */ - if (myrinfo->ed == 0) { - myrinfo->edegrees = NULL; - ctrl->wspace.cdegree -= iend-istart; - } - else { - if (myrinfo->ed-myrinfo->id >= 0) - BNDInsert(nbnd, bndind, bndptr, i); - - myrinfo->ndegrees = ndegrees; - - for (j=0; j<ndegrees; j++) - htable[myedegrees[j].pid] = -1; - } - } - } - - scopy(graph->ncon*nparts, cgraph->npwgts, graph->npwgts); - graph->mincut = cgraph->mincut; - graph->nbnd = nbnd; - - FreeGraph(graph->coarser); - graph->coarser = NULL; - - idxwspacefree(ctrl, nparts); - - ASSERT(CheckBnd2(graph)); - -} - - - -/************************************************************************* -* This function computes the boundary definition for balancing -**************************************************************************/ -void MocComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts) -{ - int i, nvtxs, nbnd; - idxtype *bndind, *bndptr; - - nvtxs = graph->nvtxs; - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - - /* Compute the new boundary */ - nbnd = 0; - for (i=0; i<nvtxs; i++) { - if (graph->rinfo[i].ed > 0) - BNDInsert(nbnd, bndind, bndptr, i); - } - - graph->nbnd = nbnd; -} - diff --git a/Metis/mmatch.c b/Metis/mmatch.c deleted file mode 100644 index 45259570d4..0000000000 --- a/Metis/mmatch.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mmatch.c - * - * This file contains the code that computes matchings and creates the next - * level coarse graph. - * - * Started 7/23/97 - * George - * - * $Id: mmatch.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void MCMatch_RM(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, k, nvtxs, ncon, cnvtxs, maxidx; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *match, *cmap, *perm; - float *nvwgt; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - RandomPermute(nvtxs, perm, 1); - - cnvtxs = 0; - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - - /* Find a random matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (match[k] == UNMATCHED && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) { - maxidx = k; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void MCMatch_HEM(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, k, l, nvtxs, cnvtxs, ncon, maxidx, maxwgt; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *match, *cmap, *perm; - float *nvwgt; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - RandomPermute(nvtxs, perm, 1); - - cnvtxs = 0; - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - maxwgt = 0; - - /* Find a heavy-edge matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (match[k] == UNMATCHED && maxwgt <= adjwgt[j] && - AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) { - maxwgt = adjwgt[j]; - maxidx = adjncy[j]; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void MCMatch_SHEM(CtrlType *ctrl, GraphType *graph) -{ - int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *match, *cmap, *degrees, *perm, *tperm; - float *nvwgt; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - tperm = idxwspacemalloc(ctrl, nvtxs); - degrees = idxwspacemalloc(ctrl, nvtxs); - - RandomPermute(nvtxs, tperm, 1); - avgdegree = 0.7*(xadj[nvtxs]/nvtxs); - for (i=0; i<nvtxs; i++) - degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]); - BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); - - cnvtxs = 0; - - /* Take care any islands. Islands are matched with non-islands due to coarsening */ - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - if (xadj[i] < xadj[i+1]) - break; - - maxidx = i; - for (j=nvtxs-1; j>ii; j--) { - k = perm[j]; - if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { - maxidx = k; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - /* Continue with normal matching */ - for (; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - maxwgt = 0; - - /* Find a heavy-edge matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (match[k] == UNMATCHED && maxwgt <= adjwgt[j] && - AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) { - maxwgt = adjwgt[j]; - maxidx = adjncy[j]; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - idxwspacefree(ctrl, nvtxs); /* degrees */ - idxwspacefree(ctrl, nvtxs); /* tperm */ - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void MCMatch_SHEBM(CtrlType *ctrl, GraphType *graph, int norm) -{ - int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *match, *cmap, *degrees, *perm, *tperm; - float *nvwgt; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - tperm = idxwspacemalloc(ctrl, nvtxs); - degrees = idxwspacemalloc(ctrl, nvtxs); - - RandomPermute(nvtxs, tperm, 1); - avgdegree = 0.7*(xadj[nvtxs]/nvtxs); - for (i=0; i<nvtxs; i++) - degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]); - BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); - - cnvtxs = 0; - - /* Take care any islands. Islands are matched with non-islands due to coarsening */ - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - if (xadj[i] < xadj[i+1]) - break; - - maxidx = i; - for (j=nvtxs-1; j>ii; j--) { - k = perm[j]; - if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { - maxidx = k; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - /* Continue with normal matching */ - for (; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - maxwgt = -1; - - /* Find a heavy-edge matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - - if (match[k] == UNMATCHED && - AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt) && - (maxwgt < adjwgt[j] || - (maxwgt == adjwgt[j] && - BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon) >= 0 - ) - ) - ) { - maxwgt = adjwgt[j]; - maxidx = k; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - idxwspacefree(ctrl, nvtxs); /* degrees */ - idxwspacefree(ctrl, nvtxs); /* tperm */ - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function finds a matching using the HEM heuristic -**************************************************************************/ -void MCMatch_SBHEM(CtrlType *ctrl, GraphType *graph, int norm) -{ - int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *match, *cmap, *degrees, *perm, *tperm; - float *nvwgt, vbal; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - cmap = graph->cmap; - match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); - - perm = idxwspacemalloc(ctrl, nvtxs); - tperm = idxwspacemalloc(ctrl, nvtxs); - degrees = idxwspacemalloc(ctrl, nvtxs); - - RandomPermute(nvtxs, tperm, 1); - avgdegree = 0.7*(xadj[nvtxs]/nvtxs); - for (i=0; i<nvtxs; i++) - degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]); - BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); - - cnvtxs = 0; - - /* Take care any islands. Islands are matched with non-islands due to coarsening */ - for (ii=0; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - if (xadj[i] < xadj[i+1]) - break; - - maxidx = i; - for (j=nvtxs-1; j>ii; j--) { - k = perm[j]; - if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { - maxidx = k; - break; - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - /* Continue with normal matching */ - for (; ii<nvtxs; ii++) { - i = perm[ii]; - - if (match[i] == UNMATCHED) { /* Unmatched */ - maxidx = i; - maxwgt = -1; - vbal = 0.0; - - /* Find a heavy-edge matching, subject to maxvwgt constraints */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (match[k] == UNMATCHED && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) { - if (maxidx != i) - vbal = BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon); - - if (vbal > 0 || (vbal > -.01 && maxwgt < adjwgt[j])) { - maxwgt = adjwgt[j]; - maxidx = k; - } - } - } - - cmap[i] = cmap[maxidx] = cnvtxs++; - match[i] = maxidx; - match[maxidx] = i; - } - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); - - idxwspacefree(ctrl, nvtxs); /* degrees */ - idxwspacefree(ctrl, nvtxs); /* tperm */ - - CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - - - -/************************************************************************* -* This function checks if v+u2 provides a better balance in the weight -* vector that v+u1 -**************************************************************************/ -float BetterVBalance(int ncon, int norm, float *vwgt, float *u1wgt, float *u2wgt) -{ - int i; - float sum1, sum2, max1, max2, min1, min2, diff1, diff2; - - if (norm == -1) { - max1 = min1 = vwgt[0]+u1wgt[0]; - max2 = min2 = vwgt[0]+u2wgt[0]; - sum1 = vwgt[0]+u1wgt[0]; - sum2 = vwgt[0]+u2wgt[0]; - - for (i=1; i<ncon; i++) { - if (max1 < vwgt[i]+u1wgt[i]) - max1 = vwgt[i]+u1wgt[i]; - if (min1 > vwgt[i]+u1wgt[i]) - min1 = vwgt[i]+u1wgt[i]; - - if (max2 < vwgt[i]+u2wgt[i]) - max2 = vwgt[i]+u2wgt[i]; - if (min2 > vwgt[i]+u2wgt[i]) - min2 = vwgt[i]+u2wgt[i]; - - sum1 += vwgt[i]+u1wgt[i]; - sum2 += vwgt[i]+u2wgt[i]; - } - - if (sum1 == 0.0) - return 1; - else if (sum2 == 0.0) - return -1; - else - return ((max1-min1)/sum1) - ((max2-min2)/sum2); - } - else if (norm == 1) { - sum1 = sum2 = 0.0; - for (i=0; i<ncon; i++) { - sum1 += vwgt[i]+u1wgt[i]; - sum2 += vwgt[i]+u2wgt[i]; - } - sum1 = sum1/(1.0*ncon); - sum2 = sum2/(1.0*ncon); - - diff1 = diff2 = 0.0; - for (i=0; i<ncon; i++) { - diff1 += fabs(sum1 - (vwgt[i]+u1wgt[i])); - diff2 += fabs(sum2 - (vwgt[i]+u2wgt[i])); - } - - return diff1 - diff2; - } - else { - errexit("Unknown norm: %d\n", norm); - } - return 0.0; -} - - -/************************************************************************* -* This function checks if the vertex weights of two vertices are below -* a given set of values -**************************************************************************/ -int AreAllVwgtsBelowFast(int ncon, float *vwgt1, float *vwgt2, float limit) -{ - int i; - - for (i=0; i<ncon; i++) - if (vwgt1[i] + vwgt2[i] > limit) - return 0; - - return 1; -} - diff --git a/Metis/mmd.c b/Metis/mmd.c deleted file mode 100644 index bf3d16d786..0000000000 --- a/Metis/mmd.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * mmd.c - * - * ************************************************************** - * The following C function was developed from a FORTRAN subroutine - * in SPARSPAK written by Eleanor Chu, Alan George, Joseph Liu - * and Esmond Ng. - * - * The FORTRAN-to-C transformation and modifications such as dynamic - * memory allocation and deallocation were performed by Chunguang - * Sun. - * ************************************************************** - * - * Taken from SMMS, George 12/13/94 - * - * The meaning of invperm, and perm vectors is different from that - * in genqmd_ of SparsPak - * - * $Id: mmd.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* genmmd -- multiple minimum external degree -* purpose -- this routine implements the minimum degree -* algorithm. it makes use of the implicit representation -* of elimination graphs by quotient graphs, and the notion -* of indistinguishable nodes. It also implements the modifications -* by multiple elimination and minimum external degree. -* Caution -- the adjacency vector adjncy will be destroyed. -* Input parameters -- -* neqns -- number of equations. -* (xadj, adjncy) -- the adjacency structure. -* delta -- tolerance value for multiple elimination. -* maxint -- maximum machine representable (short) integer -* (any smaller estimate will do) for marking nodes. -* Output parameters -- -* perm -- the minimum degree ordering. -* invp -- the inverse of perm. -* *ncsub -- an upper bound on the number of nonzero subscripts -* for the compressed storage scheme. -* Working parameters -- -* head -- vector for head of degree lists. -* invp -- used temporarily for degree forward link. -* perm -- used temporarily for degree backward link. -* qsize -- vector for size of supernodes. -* list -- vector for temporary linked lists. -* marker -- a temporary marker vector. -* Subroutines used -- mmdelm, mmdint, mmdnum, mmdupd. -**************************************************************************/ -void genmmd(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *invp, idxtype *perm, - int delta, idxtype *head, idxtype *qsize, idxtype *list, idxtype *marker, - int maxint, int *ncsub) -{ - int ehead, i, mdeg, mdlmt, mdeg_node, nextmd, num, tag; - - if (neqns <= 0) - return; - - /* Adjust from C to Fortran */ - xadj--; adjncy--; invp--; perm--; head--; qsize--; list--; marker--; - - /* initialization for the minimum degree algorithm. */ - *ncsub = 0; - mmdint(neqns, xadj, adjncy, head, invp, perm, qsize, list, marker); - - /* 'num' counts the number of ordered nodes plus 1. */ - num = 1; - - /* eliminate all isolated nodes. */ - nextmd = head[1]; - while (nextmd > 0) { - mdeg_node = nextmd; - nextmd = invp[mdeg_node]; - marker[mdeg_node] = maxint; - invp[mdeg_node] = -num; - num = num + 1; - } - - /* search for node of the minimum degree. 'mdeg' is the current */ - /* minimum degree; 'tag' is used to facilitate marking nodes. */ - if (num > neqns) - goto n1000; - tag = 1; - head[1] = 0; - mdeg = 2; - - /* infinite loop here ! */ - while (1) { - while (head[mdeg] <= 0) - mdeg++; - - /* use value of 'delta' to set up 'mdlmt', which governs */ - /* when a degree update is to be performed. */ - mdlmt = mdeg + delta; - ehead = 0; - -n500: - mdeg_node = head[mdeg]; - while (mdeg_node <= 0) { - mdeg++; - - if (mdeg > mdlmt) - goto n900; - mdeg_node = head[mdeg]; - }; - - /* remove 'mdeg_node' from the degree structure. */ - nextmd = invp[mdeg_node]; - head[mdeg] = nextmd; - if (nextmd > 0) - perm[nextmd] = -mdeg; - invp[mdeg_node] = -num; - *ncsub += mdeg + qsize[mdeg_node] - 2; - if ((num+qsize[mdeg_node]) > neqns) - goto n1000; - - /* eliminate 'mdeg_node' and perform quotient graph */ - /* transformation. reset 'tag' value if necessary. */ - tag++; - if (tag >= maxint) { - tag = 1; - for (i = 1; i <= neqns; i++) - if (marker[i] < maxint) - marker[i] = 0; - }; - - mmdelm(mdeg_node, xadj, adjncy, head, invp, perm, qsize, list, marker, maxint, tag); - - num += qsize[mdeg_node]; - list[mdeg_node] = ehead; - ehead = mdeg_node; - if (delta >= 0) - goto n500; - - n900: - /* update degrees of the nodes involved in the */ - /* minimum degree nodes elimination. */ - if (num > neqns) - goto n1000; - mmdupd( ehead, neqns, xadj, adjncy, delta, &mdeg, head, invp, perm, qsize, list, marker, maxint, &tag); - }; /* end of -- while ( 1 ) -- */ - -n1000: - mmdnum( neqns, perm, invp, qsize ); - - /* Adjust from Fortran back to C*/ - xadj++; adjncy++; invp++; perm++; head++; qsize++; list++; marker++; -} - - -/************************************************************************** -* mmdelm ...... multiple minimum degree elimination -* Purpose -- This routine eliminates the node mdeg_node of minimum degree -* from the adjacency structure, which is stored in the quotient -* graph format. It also transforms the quotient graph representation -* of the elimination graph. -* Input parameters -- -* mdeg_node -- node of minimum degree. -* maxint -- estimate of maximum representable (short) integer. -* tag -- tag value. -* Updated parameters -- -* (xadj, adjncy) -- updated adjacency structure. -* (head, forward, backward) -- degree doubly linked structure. -* qsize -- size of supernode. -* marker -- marker vector. -* list -- temporary linked list of eliminated nabors. -***************************************************************************/ -void mmdelm(int mdeg_node, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward, - idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker, int maxint,int tag) -{ - int element, i, istop, istart, j, - jstop, jstart, link, - nabor, node, npv, nqnbrs, nxnode, - pvnode, rlmt, rloc, rnode, xqnbr; - - /* find the reachable set of 'mdeg_node' and */ - /* place it in the data structure. */ - marker[mdeg_node] = tag; - istart = xadj[mdeg_node]; - istop = xadj[mdeg_node+1] - 1; - - /* 'element' points to the beginning of the list of */ - /* eliminated nabors of 'mdeg_node', and 'rloc' gives the */ - /* storage location for the next reachable node. */ - element = 0; - rloc = istart; - rlmt = istop; - for ( i = istart; i <= istop; i++ ) { - nabor = adjncy[i]; - if ( nabor == 0 ) break; - if ( marker[nabor] < tag ) { - marker[nabor] = tag; - if ( forward[nabor] < 0 ) { - list[nabor] = element; - element = nabor; - } else { - adjncy[rloc] = nabor; - rloc++; - }; - }; /* end of -- if -- */ - }; /* end of -- for -- */ - - /* merge with reachable nodes from generalized elements. */ - while ( element > 0 ) { - adjncy[rlmt] = -element; - link = element; - -n400: - jstart = xadj[link]; - jstop = xadj[link+1] - 1; - for ( j = jstart; j <= jstop; j++ ) { - node = adjncy[j]; - link = -node; - if ( node < 0 ) goto n400; - if ( node == 0 ) break; - if ((marker[node]<tag)&&(forward[node]>=0)) { - marker[node] = tag; - /*use storage from eliminated nodes if necessary.*/ - while ( rloc >= rlmt ) { - link = -adjncy[rlmt]; - rloc = xadj[link]; - rlmt = xadj[link+1] - 1; - }; - adjncy[rloc] = node; - rloc++; - }; - }; /* end of -- for ( j = jstart; -- */ - element = list[element]; - }; /* end of -- while ( element > 0 ) -- */ - if ( rloc <= rlmt ) adjncy[rloc] = 0; - /* for each node in the reachable set, do the following. */ - link = mdeg_node; - -n1100: - istart = xadj[link]; - istop = xadj[link+1] - 1; - for ( i = istart; i <= istop; i++ ) { - rnode = adjncy[i]; - link = -rnode; - if ( rnode < 0 ) goto n1100; - if ( rnode == 0 ) return; - - /* 'rnode' is in the degree list structure. */ - pvnode = backward[rnode]; - if (( pvnode != 0 ) && ( pvnode != (-maxint) )) { - /* then remove 'rnode' from the structure. */ - nxnode = forward[rnode]; - if ( nxnode > 0 ) backward[nxnode] = pvnode; - if ( pvnode > 0 ) forward[pvnode] = nxnode; - npv = -pvnode; - if ( pvnode < 0 ) head[npv] = nxnode; - }; - - /* purge inactive quotient nabors of 'rnode'. */ - jstart = xadj[rnode]; - jstop = xadj[rnode+1] - 1; - xqnbr = jstart; - for ( j = jstart; j <= jstop; j++ ) { - nabor = adjncy[j]; - if ( nabor == 0 ) break; - if ( marker[nabor] < tag ) { - adjncy[xqnbr] = nabor; - xqnbr++; - }; - }; - - /* no active nabor after the purging. */ - nqnbrs = xqnbr - jstart; - if ( nqnbrs <= 0 ) { - /* merge 'rnode' with 'mdeg_node'. */ - qsize[mdeg_node] += qsize[rnode]; - qsize[rnode] = 0; - marker[rnode] = maxint; - forward[rnode] = -mdeg_node; - backward[rnode] = -maxint; - } else { - /* flag 'rnode' for degree update, and */ - /* add 'mdeg_node' as a nabor of 'rnode'. */ - forward[rnode] = nqnbrs + 1; - backward[rnode] = 0; - adjncy[xqnbr] = mdeg_node; - xqnbr++; - if ( xqnbr <= jstop ) adjncy[xqnbr] = 0; - }; - }; /* end of -- for ( i = istart; -- */ - return; - } - -/*************************************************************************** -* mmdint ---- mult minimum degree initialization -* purpose -- this routine performs initialization for the -* multiple elimination version of the minimum degree algorithm. -* input parameters -- -* neqns -- number of equations. -* (xadj, adjncy) -- adjacency structure. -* output parameters -- -* (head, dfrow, backward) -- degree doubly linked structure. -* qsize -- size of supernode ( initialized to one). -* list -- linked list. -* marker -- marker vector. -****************************************************************************/ -int mmdint(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward, - idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker) -{ - int fnode, ndeg, node; - - for ( node = 1; node <= neqns; node++ ) { - head[node] = 0; - qsize[node] = 1; - marker[node] = 0; - list[node] = 0; - }; - - /* initialize the degree doubly linked lists. */ - for ( node = 1; node <= neqns; node++ ) { - ndeg = xadj[node+1] - xadj[node]/* + 1*/; /* george */ - if (ndeg == 0) - ndeg = 1; - fnode = head[ndeg]; - forward[node] = fnode; - head[ndeg] = node; - if ( fnode > 0 ) backward[fnode] = node; - backward[node] = -ndeg; - }; - return 0; -} - -/**************************************************************************** -* mmdnum --- multi minimum degree numbering -* purpose -- this routine performs the final step in producing -* the permutation and inverse permutation vectors in the -* multiple elimination version of the minimum degree -* ordering algorithm. -* input parameters -- -* neqns -- number of equations. -* qsize -- size of supernodes at elimination. -* updated parameters -- -* invp -- inverse permutation vector. on input, -* if qsize[node] = 0, then node has been merged -* into the node -invp[node]; otherwise, -* -invp[node] is its inverse labelling. -* output parameters -- -* perm -- the permutation vector. -****************************************************************************/ -void mmdnum(int neqns, idxtype *perm, idxtype *invp, idxtype *qsize) -{ - int father, nextf, node, nqsize, num, root; - - for ( node = 1; node <= neqns; node++ ) { - nqsize = qsize[node]; - if ( nqsize <= 0 ) perm[node] = invp[node]; - if ( nqsize > 0 ) perm[node] = -invp[node]; - }; - - /* for each node which has been merged, do the following. */ - for ( node = 1; node <= neqns; node++ ) { - if ( perm[node] <= 0 ) { - - /* trace the merged tree until one which has not */ - /* been merged, call it root. */ - father = node; - while ( perm[father] <= 0 ) - father = - perm[father]; - - /* number node after root. */ - root = father; - num = perm[root] + 1; - invp[node] = -num; - perm[root] = num; - - /* shorten the merged tree. */ - father = node; - nextf = - perm[father]; - while ( nextf > 0 ) { - perm[father] = -root; - father = nextf; - nextf = -perm[father]; - }; - }; /* end of -- if ( perm[node] <= 0 ) -- */ - }; /* end of -- for ( node = 1; -- */ - - /* ready to compute perm. */ - for ( node = 1; node <= neqns; node++ ) { - num = -invp[node]; - invp[node] = num; - perm[num] = node; - }; - return; -} - -/**************************************************************************** -* mmdupd ---- multiple minimum degree update -* purpose -- this routine updates the degrees of nodes after a -* multiple elimination step. -* input parameters -- -* ehead -- the beginning of the list of eliminated nodes -* (i.e., newly formed elements). -* neqns -- number of equations. -* (xadj, adjncy) -- adjacency structure. -* delta -- tolerance value for multiple elimination. -* maxint -- maximum machine representable (short) integer. -* updated parameters -- -* mdeg -- new minimum degree after degree update. -* (head, forward, backward) -- degree doubly linked structure. -* qsize -- size of supernode. -* list -- marker vector for degree update. -* *tag -- tag value. -****************************************************************************/ -void mmdupd(int ehead, int neqns, idxtype *xadj, idxtype *adjncy, int delta, int *mdeg, - idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list, - idxtype *marker, int maxint,int *tag) -{ - int deg, deg0, element, enode, fnode, i, iq2, istop, - istart, j, jstop, jstart, link, mdeg0, mtag, nabor, - node, q2head, qxhead; - - mdeg0 = *mdeg + delta; - element = ehead; - -n100: - if ( element <= 0 ) return; - - /* for each of the newly formed element, do the following. */ - /* reset tag value if necessary. */ - mtag = *tag + mdeg0; - if ( mtag >= maxint ) { - *tag = 1; - for ( i = 1; i <= neqns; i++ ) - if ( marker[i] < maxint ) marker[i] = 0; - mtag = *tag + mdeg0; - }; - - /* create two linked lists from nodes associated with 'element': */ - /* one with two nabors (q2head) in the adjacency structure, and the*/ - /* other with more than two nabors (qxhead). also compute 'deg0',*/ - /* number of nodes in this element. */ - q2head = 0; - qxhead = 0; - deg0 = 0; - link =element; - -n400: - istart = xadj[link]; - istop = xadj[link+1] - 1; - for ( i = istart; i <= istop; i++ ) { - enode = adjncy[i]; - link = -enode; - if ( enode < 0 ) goto n400; - if ( enode == 0 ) break; - if ( qsize[enode] != 0 ) { - deg0 += qsize[enode]; - marker[enode] = mtag; - - /*'enode' requires a degree update*/ - if ( backward[enode] == 0 ) { - /* place either in qxhead or q2head list. */ - if ( forward[enode] != 2 ) { - list[enode] = qxhead; - qxhead = enode; - } else { - list[enode] = q2head; - q2head = enode; - }; - }; - }; /* enf of -- if ( qsize[enode] != 0 ) -- */ - }; /* end of -- for ( i = istart; -- */ - - /* for each node in q2 list, do the following. */ - enode = q2head; - iq2 = 1; - -n900: - if ( enode <= 0 ) goto n1500; - if ( backward[enode] != 0 ) goto n2200; - (*tag)++; - deg = deg0; - - /* identify the other adjacent element nabor. */ - istart = xadj[enode]; - nabor = adjncy[istart]; - if ( nabor == element ) nabor = adjncy[istart+1]; - link = nabor; - if ( forward[nabor] >= 0 ) { - /* nabor is uneliminated, increase degree count. */ - deg += qsize[nabor]; - goto n2100; - }; - - /* the nabor is eliminated. for each node in the 2nd element */ - /* do the following. */ -n1000: - istart = xadj[link]; - istop = xadj[link+1] - 1; - for ( i = istart; i <= istop; i++ ) { - node = adjncy[i]; - link = -node; - if ( node != enode ) { - if ( node < 0 ) goto n1000; - if ( node == 0 ) goto n2100; - if ( qsize[node] != 0 ) { - if ( marker[node] < *tag ) { - /* 'node' is not yet considered. */ - marker[node] = *tag; - deg += qsize[node]; - } else { - if ( backward[node] == 0 ) { - if ( forward[node] == 2 ) { - /* 'node' is indistinguishable from 'enode'.*/ - /* merge them into a new supernode. */ - qsize[enode] += qsize[node]; - qsize[node] = 0; - marker[node] = maxint; - forward[node] = -enode; - backward[node] = -maxint; - } else { - /* 'node' is outmacthed by 'enode' */ - if (backward[node]==0) backward[node] = -maxint; - }; - }; /* end of -- if ( backward[node] == 0 ) -- */ - }; /* end of -- if ( marker[node] < *tag ) -- */ - }; /* end of -- if ( qsize[node] != 0 ) -- */ - }; /* end of -- if ( node != enode ) -- */ - }; /* end of -- for ( i = istart; -- */ - goto n2100; - -n1500: - /* for each 'enode' in the 'qx' list, do the following. */ - enode = qxhead; - iq2 = 0; - -n1600: if ( enode <= 0 ) goto n2300; - if ( backward[enode] != 0 ) goto n2200; - (*tag)++; - deg = deg0; - - /*for each unmarked nabor of 'enode', do the following.*/ - istart = xadj[enode]; - istop = xadj[enode+1] - 1; - for ( i = istart; i <= istop; i++ ) { - nabor = adjncy[i]; - if ( nabor == 0 ) break; - if ( marker[nabor] < *tag ) { - marker[nabor] = *tag; - link = nabor; - if ( forward[nabor] >= 0 ) - /*if uneliminated, include it in deg count.*/ - deg += qsize[nabor]; - else { -n1700: - /* if eliminated, include unmarked nodes in this*/ - /* element into the degree count. */ - jstart = xadj[link]; - jstop = xadj[link+1] - 1; - for ( j = jstart; j <= jstop; j++ ) { - node = adjncy[j]; - link = -node; - if ( node < 0 ) goto n1700; - if ( node == 0 ) break; - if ( marker[node] < *tag ) { - marker[node] = *tag; - deg += qsize[node]; - }; - }; /* end of -- for ( j = jstart; -- */ - }; /* end of -- if ( forward[nabor] >= 0 ) -- */ - }; /* end of -- if ( marker[nabor] < *tag ) -- */ - }; /* end of -- for ( i = istart; -- */ - -n2100: - /* update external degree of 'enode' in degree structure, */ - /* and '*mdeg' if necessary. */ - deg = deg - qsize[enode] + 1; - fnode = head[deg]; - forward[enode] = fnode; - backward[enode] = -deg; - if ( fnode > 0 ) backward[fnode] = enode; - head[deg] = enode; - if ( deg < *mdeg ) *mdeg = deg; - -n2200: - /* get next enode in current element. */ - enode = list[enode]; - if ( iq2 == 1 ) goto n900; - goto n1600; - -n2300: - /* get next element in the list. */ - *tag = mtag; - element = list[element]; - goto n100; - } diff --git a/Metis/mpmetis.c b/Metis/mpmetis.c deleted file mode 100644 index e8795cafdc..0000000000 --- a/Metis/mpmetis.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mpmetis.c - * - * This file contains the top level routines for the multilevel recursive - * bisection algorithm PMETIS. - * - * Started 7/24/97 - * George - * - * $Id: mpmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - - -/************************************************************************* -* This function is the entry point for PWMETIS that accepts exact weights -* for the target partitions -**************************************************************************/ -void METIS_mCPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, - idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = McPMETIS_CTYPE; - ctrl.IType = McPMETIS_ITYPE; - ctrl.RType = McPMETIS_RTYPE; - ctrl.dbglvl = McPMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_PMETIS; - ctrl.CoarsenTo = 100; - - ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MCMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, 1.000, 0); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - - -/************************************************************************* -* This function is the entry point for PWMETIS that accepts exact weights -* for the target partitions -**************************************************************************/ -void METIS_mCHPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, - idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - float *ubvec, int *options, int *edgecut, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - float *myubvec; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = PMETIS_CTYPE; - ctrl.IType = PMETIS_ITYPE; - ctrl.RType = PMETIS_RTYPE; - ctrl.dbglvl = PMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_PMETIS; - ctrl.CoarsenTo = 100; - - ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); - - myubvec = fmalloc(*ncon, "PWMETIS: mytpwgts"); - scopy(*ncon, ubvec, myubvec); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MCHMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, myubvec, 0); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - GKfree(&myubvec, LTERM); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - - -/************************************************************************* -* This function is the entry point for PWMETIS that accepts exact weights -* for the target partitions -**************************************************************************/ -void METIS_mCPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, - float *nvwgt, idxtype *adjwgt, int *nparts, int *options, int *edgecut, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = PMETIS_CTYPE; - ctrl.IType = PMETIS_ITYPE; - ctrl.RType = PMETIS_RTYPE; - ctrl.dbglvl = PMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_PMETIS; - ctrl.CoarsenTo = 100; - - ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MCMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, 1.000, 0); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - -} - - -/************************************************************************* -* This function is the entry point for PWMETIS that accepts exact weights -* for the target partitions -**************************************************************************/ -void METIS_mCHPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, - float *nvwgt, idxtype *adjwgt, int *nparts, float *ubvec, int *options, int *edgecut, - idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - float *myubvec; - - SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = PMETIS_CTYPE; - ctrl.IType = PMETIS_ITYPE; - ctrl.RType = PMETIS_RTYPE; - ctrl.dbglvl = PMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_PMETIS; - ctrl.CoarsenTo = 100; - - ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); - - myubvec = fmalloc(*ncon, "PWMETIS: mytpwgts"); - scopy(*ncon, ubvec, myubvec); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MCHMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, myubvec, 0); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - GKfree(&myubvec, LTERM); - -} - - - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -int MCMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, - float ubfactor, int fpart) -{ - int i, j, nvtxs, ncon, cut; - idxtype *label, *where; - GraphType lgraph, rgraph; - float tpwgts[2]; - - nvtxs = graph->nvtxs; - if (nvtxs == 0) { - printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); - return 0; - } - - /* Determine the weights of the partitions */ - tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts); - tpwgts[1] = 1.0 - tpwgts[0]; - - MCMlevelEdgeBisection(ctrl, graph, tpwgts, ubfactor); - cut = graph->mincut; - - label = graph->label; - where = graph->where; - for (i=0; i<nvtxs; i++) - part[label[i]] = where[i] + fpart; - - if (nparts > 2) - SplitGraphPart(ctrl, graph, &lgraph, &rgraph); - - /* Free the memory of the top level graph */ - GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, &graph->label, LTERM); - - - /* Do the recursive call */ - if (nparts > 3) { - cut += MCMlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, ubfactor, fpart); - cut += MCMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, ubfactor, fpart+nparts/2); - } - else if (nparts == 3) { - cut += MCMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, ubfactor, fpart+nparts/2); - GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); - } - - return cut; - -} - - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -int MCHMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, - float *ubvec, int fpart) -{ - int i, j, nvtxs, ncon, cut; - idxtype *label, *where; - GraphType lgraph, rgraph; - float tpwgts[2], *npwgts, *lubvec, *rubvec; - - lubvec = rubvec = NULL; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - if (nvtxs == 0) { - printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); - return 0; - } - - /* Determine the weights of the partitions */ - tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts); - tpwgts[1] = 1.0 - tpwgts[0]; - - /* For now, relax at the coarsest level only */ - if (nparts == 2) - MCHMlevelEdgeBisection(ctrl, graph, tpwgts, ubvec); - else - MCMlevelEdgeBisection(ctrl, graph, tpwgts, 1.000); - cut = graph->mincut; - - label = graph->label; - where = graph->where; - for (i=0; i<nvtxs; i++) - part[label[i]] = where[i] + fpart; - - if (nparts > 2) { - /* Adjust the ubvecs before the split */ - npwgts = graph->npwgts; - lubvec = fmalloc(ncon, "MCHMlevelRecursiveBisection"); - rubvec = fmalloc(ncon, "MCHMlevelRecursiveBisection"); - - for (i=0; i<ncon; i++) { - lubvec[i] = ubvec[i]*tpwgts[0]/npwgts[i]; - lubvec[i] = amax(lubvec[i], 1.01); - - rubvec[i] = ubvec[i]*tpwgts[1]/npwgts[ncon+i]; - rubvec[i] = amax(rubvec[i], 1.01); - } - - SplitGraphPart(ctrl, graph, &lgraph, &rgraph); - } - - /* Free the memory of the top level graph */ - GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, &graph->label, LTERM); - - - /* Do the recursive call */ - if (nparts > 3) { - cut += MCHMlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, lubvec, fpart); - cut += MCHMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, rubvec, fpart+nparts/2); - } - else if (nparts == 3) { - cut += MCHMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, rubvec, fpart+nparts/2); - GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); - } - - GKfree(&lubvec, &rubvec, LTERM); - - return cut; - -} - - - - -/************************************************************************* -* This function performs multilevel bisection -**************************************************************************/ -void MCMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) -{ - GraphType *cgraph; - - cgraph = MCCoarsen2Way(ctrl, graph); - - MocInit2WayPartition(ctrl, cgraph, tpwgts, ubfactor); - - MocRefine2Way(ctrl, graph, cgraph, tpwgts, ubfactor); - -} - - - -/************************************************************************* -* This function performs multilevel bisection -**************************************************************************/ -void MCHMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) -{ - int i; - GraphType *cgraph; - -/* - for (i=0; i<graph->ncon; i++) - printf("%.4f ", ubvec[i]); - printf("\n"); -*/ - - cgraph = MCCoarsen2Way(ctrl, graph); - - MocInit2WayPartition2(ctrl, cgraph, tpwgts, ubvec); - - MocRefine2Way2(ctrl, graph, cgraph, tpwgts, ubvec); - -} - - diff --git a/Metis/mrefine.c b/Metis/mrefine.c deleted file mode 100644 index 1012311581..0000000000 --- a/Metis/mrefine.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * refine.c - * - * This file contains the driving routines for multilevel refinement - * - * Started 7/24/97 - * George - * - * $Id: mrefine.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of refinement -**************************************************************************/ -void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor) -{ - int i; - float tubvec[MAXNCON]; - - for (i=0; i<graph->ncon; i++) - tubvec[i] = 1.0; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - /* Compute the parameters of the coarsest graph */ - MocCompute2WayPartitionParams(ctrl, graph); - - for (;;) { - ASSERT(CheckBnd(graph)); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - switch (ctrl->RType) { - case RTYPE_FM: - MocBalance2Way(ctrl, graph, tpwgts, 1.03); - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); - break; - case 2: - MocBalance2Way(ctrl, graph, tpwgts, 1.03); - MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8); - break; - default: - errexit("Unknown refinement type: %d\n", ctrl->RType); - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - graph = graph->finer; - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - MocProject2WayPartition(ctrl, graph); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - MocBalance2Way(ctrl, graph, tpwgts, 1.01); - MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - -/************************************************************************* -* This function allocates memory for 2-way edge refinement -**************************************************************************/ -void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph) -{ - int nvtxs, ncon; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - - graph->rdata = idxmalloc(5*nvtxs, "Allocate2WayPartitionMemory: rdata"); - graph->where = graph->rdata; - graph->id = graph->rdata + nvtxs; - graph->ed = graph->rdata + 2*nvtxs; - graph->bndptr = graph->rdata + 3*nvtxs; - graph->bndind = graph->rdata + 4*nvtxs; - - graph->npwgts = fmalloc(2*ncon, "npwgts"); -} - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) -{ - int i, j, k, l, nvtxs, ncon, nbnd, mincut; - idxtype *xadj, *adjncy, *adjwgt; - float *nvwgt, *npwgts; - idxtype *id, *ed, *where; - idxtype *bndptr, *bndind; - int me, other; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - npwgts = sset(2*ncon, 0.0, graph->npwgts); - id = idxset(nvtxs, 0, graph->id); - ed = idxset(nvtxs, 0, graph->ed); - bndptr = idxset(nvtxs, -1, graph->bndptr); - bndind = graph->bndind; - - - /*------------------------------------------------------------ - / Compute now the id/ed degrees - /------------------------------------------------------------*/ - nbnd = mincut = 0; - for (i=0; i<nvtxs; i++) { - ASSERT(where[i] >= 0 && where[i] <= 1); - me = where[i]; - saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); - - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me == where[adjncy[j]]) - id[i] += adjwgt[j]; - else - ed[i] += adjwgt[j]; - } - - if (ed[i] > 0 || xadj[i] == xadj[i+1]) { - mincut += ed[i]; - bndptr[i] = nbnd; - bndind[nbnd++] = i; - } - } - - graph->mincut = mincut/2; - graph->nbnd = nbnd; - -} - - - -/************************************************************************* -* This function projects a partition, and at the same time computes the -* parameters for refinement. -**************************************************************************/ -void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph) -{ - int i, j, k, nvtxs, nbnd, me; - idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; - idxtype *cmap, *where, *id, *ed, *bndptr, *bndind; - idxtype *cwhere, *cid, *ced, *cbndptr; - GraphType *cgraph; - - cgraph = graph->coarser; - cwhere = cgraph->where; - cid = cgraph->id; - ced = cgraph->ed; - cbndptr = cgraph->bndptr; - - nvtxs = graph->nvtxs; - cmap = graph->cmap; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - - MocAllocate2WayPartitionMemory(ctrl, graph); - - where = graph->where; - id = idxset(nvtxs, 0, graph->id); - ed = idxset(nvtxs, 0, graph->ed); - bndptr = idxset(nvtxs, -1, graph->bndptr); - bndind = graph->bndind; - - - /* Go through and project partition and compute id/ed for the nodes */ - for (i=0; i<nvtxs; i++) { - k = cmap[i]; - where[i] = cwhere[k]; - cmap[i] = cbndptr[k]; - } - - for (nbnd=0, i=0; i<nvtxs; i++) { - me = where[i]; - - id[i] = adjwgtsum[i]; - - if (xadj[i] == xadj[i+1]) { - bndptr[i] = nbnd; - bndind[nbnd++] = i; - } - else { - if (cmap[i] != -1) { /* If it is an interface node. Note that cmap[i] = cbndptr[cmap[i]] */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me != where[adjncy[j]]) - ed[i] += adjwgt[j]; - } - id[i] -= ed[i]; - - if (ed[i] > 0 || xadj[i] == xadj[i+1]) { - bndptr[i] = nbnd; - bndind[nbnd++] = i; - } - } - } - } - - graph->mincut = cgraph->mincut; - graph->nbnd = nbnd; - scopy(2*graph->ncon, cgraph->npwgts, graph->npwgts); - - FreeGraph(graph->coarser); - graph->coarser = NULL; - -} - diff --git a/Metis/mrefine2.c b/Metis/mrefine2.c deleted file mode 100644 index 636c9a5337..0000000000 --- a/Metis/mrefine2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * mrefine2.c - * - * This file contains the driving routines for multilevel refinement - * - * Started 7/24/97 - * George - * - * $Id: mrefine2.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of refinement -**************************************************************************/ -void MocRefine2Way2(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, - float *ubvec) -{ - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - /* Compute the parameters of the coarsest graph */ - MocCompute2WayPartitionParams(ctrl, graph); - - for (;;) { - ASSERT(CheckBnd(graph)); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - switch (ctrl->RType) { - case RTYPE_FM: - MocBalance2Way2(ctrl, graph, tpwgts, ubvec); - MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 8); - break; - default: - errexit("Unknown refinement type: %d\n", ctrl->RType); - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - graph = graph->finer; - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - MocProject2WayPartition(ctrl, graph); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - diff --git a/Metis/mutil.c b/Metis/mutil.c deleted file mode 100644 index 08871df652..0000000000 --- a/Metis/mutil.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * mutil.c - * - * This file contains various utility functions for the MOC portion of the - * code - * - * Started 2/15/98 - * George - * - * $Id: mutil.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function checks if the vertex weights of two vertices are below -* a given set of values -**************************************************************************/ -int AreAllVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit) -{ - int i; - - for (i=0; i<ncon; i++) - if (alpha*vwgt1[i] + beta*vwgt2[i] > limit) - return 0; - - return 1; -} - - -/************************************************************************* -* This function checks if the vertex weights of two vertices are below -* a given set of values -**************************************************************************/ -int AreAnyVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit) -{ - int i; - - for (i=0; i<ncon; i++) - if (alpha*vwgt1[i] + beta*vwgt2[i] < limit) - return 1; - - return 0; -} - - - -/************************************************************************* -* This function checks if the vertex weights of two vertices are above -* a given set of values -**************************************************************************/ -int AreAllVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit) -{ - int i; - - for (i=0; i<ncon; i++) - if (alpha*vwgt1[i] + beta*vwgt2[i] < limit) - return 0; - - return 1; -} - - -/************************************************************************* -* This function computes the load imbalance over all the constrains -* For now assume that we just want balanced partitionings -**************************************************************************/ -float ComputeLoadImbalance(int ncon, int nparts, float *npwgts, float *tpwgts) -{ - int i, j; - float max, lb=0.0; - - for (i=0; i<ncon; i++) { - max = 0.0; - for (j=0; j<nparts; j++) { - if (npwgts[j*ncon+i] > max) - max = npwgts[j*ncon+i]; - } - if (max*nparts > lb) - lb = max*nparts; - } - - return lb; -} - -/************************************************************************* -* This function checks if the vertex weights of two vertices are below -* a given set of values -**************************************************************************/ -int AreAllBelow(int ncon, float *v1, float *v2) -{ - int i; - - for (i=0; i<ncon; i++) - if (v1[i] > v2[i]) - return 0; - - return 1; -} diff --git a/Metis/myqsort.c b/Metis/myqsort.c deleted file mode 100644 index 07267ae34a..0000000000 --- a/Metis/myqsort.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * myqsort.c - * - * This file contains a fast idxtype increasing qsort algorithm. - * Addopted from TeX - * - * Started 10/18/96 - * George - * - * $Id: myqsort.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - */ - -#include <metis.h> /* only for type declarations */ - -#define THRESH 1 /* threshold for insertion */ -#define MTHRESH 6 /* threshold for median */ - - - - -static void siqst(idxtype *, idxtype *); -static void iiqst(int *, int *); -static void keyiqst(KeyValueType *, KeyValueType *); -static void keyvaliqst(KeyValueType *, KeyValueType *); - - -/************************************************************************* -* Entry point of idxtype increasing sort -**************************************************************************/ -void iidxsort(int n, idxtype *base) -{ - register idxtype *i; - register idxtype *j; - register idxtype *lo; - register idxtype *hi; - register idxtype *min; - register idxtype c; - idxtype *max; - - if (n <= 1) - return; - - max = base + n; - - if (n >= THRESH) { - siqst(base, max); - hi = base + THRESH; - } - else - hi = max; - - for (j = lo = base; lo++ < hi;) { - if (*j > *lo) - j = lo; - } - if (j != base) { /* swap j into place */ - c = *base; - *base = *j; - *j = c; - } - - for (min = base; (hi = min += 1) < max;) { - while (*(--hi) > *min); - if ((hi += 1) != min) { - for (lo = min + 1; --lo >= min;) { - c = *lo; - for (i = j = lo; (j -= 1) >= hi; i = j) - *i = *j; - *i = c; - } - } - } -} - -static void siqst(idxtype *base, idxtype *max) -{ - register idxtype *i; - register idxtype *j; - register idxtype *jj; - register idxtype *mid; - register int ii; - register idxtype c; - idxtype *tmp; - int lo; - int hi; - - lo = max - base; /* number of elements as idxtype */ - do { - mid = base + ((unsigned) lo>>1); - if (lo >= MTHRESH) { - j = (*base > *mid ? base : mid); - tmp = max - 1; - if (*j > *tmp) { - j = (j == base ? mid : base); /* switch to first loser */ - if (*j < *tmp) - j = tmp; - } - - if (j != mid) { /* SWAP */ - c = *mid; - *mid = *j; - *j = c; - } - } - - /* Semi-standard quicksort partitioning/swapping */ - for (i = base, j = max - 1;;) { - while (i < mid && *i <= *mid) - i++; - while (j > mid) { - if (*mid <= *j) { - j--; - continue; - } - tmp = i + 1; /* value of i after swap */ - if (i == mid) /* j <-> mid, new mid is j */ - mid = jj = j; - else /* i <-> j */ - jj = j--; - goto swap; - } - - if (i == mid) - break; - else { /* i <-> mid, new mid is i */ - jj = mid; - tmp = mid = i; /* value of i after swap */ - j--; - } -swap: - c = *i; - *i = *jj; - *jj = c; - i = tmp; - } - - i = (j = mid) + 1; - if ((lo = j - base) <= (hi = max - i)) { - if (lo >= THRESH) - siqst(base, j); - base = i; - lo = hi; - } - else { - if (hi >= THRESH) - siqst(i, max); - max = j; - } - } while (lo >= THRESH); -} - - - - - -/************************************************************************* -* Entry point of int increasing sort -**************************************************************************/ -void iintsort(int n, int *base) -{ - register int *i; - register int *j; - register int *lo; - register int *hi; - register int *min; - register int c; - int *max; - - if (n <= 1) - return; - - max = base + n; - - if (n >= THRESH) { - iiqst(base, max); - hi = base + THRESH; - } - else - hi = max; - - for (j = lo = base; lo++ < hi;) { - if (*j > *lo) - j = lo; - } - if (j != base) { /* swap j into place */ - c = *base; - *base = *j; - *j = c; - } - - for (min = base; (hi = min += 1) < max;) { - while (*(--hi) > *min); - if ((hi += 1) != min) { - for (lo = min + 1; --lo >= min;) { - c = *lo; - for (i = j = lo; (j -= 1) >= hi; i = j) - *i = *j; - *i = c; - } - } - } -} - - -static void iiqst(int *base, int *max) -{ - register int *i; - register int *j; - register int *jj; - register int *mid; - register int ii; - register int c; - int *tmp; - int lo; - int hi; - - lo = max - base; /* number of elements as ints */ - do { - mid = base + ((unsigned) lo>>1); - if (lo >= MTHRESH) { - j = (*base > *mid ? base : mid); - tmp = max - 1; - if (*j > *tmp) { - j = (j == base ? mid : base); /* switch to first loser */ - if (*j < *tmp) - j = tmp; - } - - if (j != mid) { /* SWAP */ - c = *mid; - *mid = *j; - *j = c; - } - } - - /* Semi-standard quicksort partitioning/swapping */ - for (i = base, j = max - 1;;) { - while (i < mid && *i <= *mid) - i++; - while (j > mid) { - if (*mid <= *j) { - j--; - continue; - } - tmp = i + 1; /* value of i after swap */ - if (i == mid) /* j <-> mid, new mid is j */ - mid = jj = j; - else /* i <-> j */ - jj = j--; - goto swap; - } - - if (i == mid) - break; - else { /* i <-> mid, new mid is i */ - jj = mid; - tmp = mid = i; /* value of i after swap */ - j--; - } -swap: - c = *i; - *i = *jj; - *jj = c; - i = tmp; - } - - i = (j = mid) + 1; - if ((lo = j - base) <= (hi = max - i)) { - if (lo >= THRESH) - iiqst(base, j); - base = i; - lo = hi; - } - else { - if (hi >= THRESH) - iiqst(i, max); - max = j; - } - } while (lo >= THRESH); -} - - - - - -/************************************************************************* -* Entry point of KeyVal increasing sort, ONLY key part -**************************************************************************/ -void ikeysort(int n, KeyValueType *base) -{ - register KeyValueType *i; - register KeyValueType *j; - register KeyValueType *lo; - register KeyValueType *hi; - register KeyValueType *min; - register KeyValueType c; - KeyValueType *max; - - if (n <= 1) - return; - - max = base + n; - - if (n >= THRESH) { - keyiqst(base, max); - hi = base + THRESH; - } - else - hi = max; - - for (j = lo = base; lo++ < hi;) { - if (j->key > lo->key) - j = lo; - } - if (j != base) { /* swap j into place */ - c = *base; - *base = *j; - *j = c; - } - - for (min = base; (hi = min += 1) < max;) { - while ((--hi)->key > min->key); - if ((hi += 1) != min) { - for (lo = min + 1; --lo >= min;) { - c = *lo; - for (i = j = lo; (j -= 1) >= hi; i = j) - *i = *j; - *i = c; - } - } - } - - /* Sanity check */ - { - int i; - for (i=0; i<n-1; i++) - if (base[i].key > base[i+1].key) - printf("Something went wrong!\n"); - } -} - - -static void keyiqst(KeyValueType *base, KeyValueType *max) -{ - register KeyValueType *i; - register KeyValueType *j; - register KeyValueType *jj; - register KeyValueType *mid; - register KeyValueType c; - KeyValueType *tmp; - int lo; - int hi; - - lo = (max - base)>>1; /* number of elements as KeyValueType */ - do { - mid = base + ((unsigned) lo>>1); - if (lo >= MTHRESH) { - j = (base->key > mid->key ? base : mid); - tmp = max - 1; - if (j->key > tmp->key) { - j = (j == base ? mid : base); /* switch to first loser */ - if (j->key < tmp->key) - j = tmp; - } - - if (j != mid) { /* SWAP */ - c = *mid; - *mid = *j; - *j = c; - } - } - - /* Semi-standard quicksort partitioning/swapping */ - for (i = base, j = max - 1;;) { - while (i < mid && i->key <= mid->key) - i++; - while (j > mid) { - if (mid->key <= j->key) { - j--; - continue; - } - tmp = i + 1; /* value of i after swap */ - if (i == mid) /* j <-> mid, new mid is j */ - mid = jj = j; - else /* i <-> j */ - jj = j--; - goto swap; - } - - if (i == mid) - break; - else { /* i <-> mid, new mid is i */ - jj = mid; - tmp = mid = i; /* value of i after swap */ - j--; - } -swap: - c = *i; - *i = *jj; - *jj = c; - i = tmp; - } - - i = (j = mid) + 1; - if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) { - if (lo >= THRESH) - keyiqst(base, j); - base = i; - lo = hi; - } - else { - if (hi >= THRESH) - keyiqst(i, max); - max = j; - } - } while (lo >= THRESH); -} - - - - -/************************************************************************* -* Entry point of KeyVal increasing sort, BOTH key and val part -**************************************************************************/ -void ikeyvalsort(int n, KeyValueType *base) -{ - register KeyValueType *i; - register KeyValueType *j; - register KeyValueType *lo; - register KeyValueType *hi; - register KeyValueType *min; - register KeyValueType c; - KeyValueType *max; - - if (n <= 1) - return; - - max = base + n; - - if (n >= THRESH) { - keyvaliqst(base, max); - hi = base + THRESH; - } - else - hi = max; - - for (j = lo = base; lo++ < hi;) { - if ((j->key > lo->key) || (j->key == lo->key && j->val > lo->val)) - j = lo; - } - if (j != base) { /* swap j into place */ - c = *base; - *base = *j; - *j = c; - } - - for (min = base; (hi = min += 1) < max;) { - while ((--hi)->key > min->key || (hi->key == min->key && hi->val > min->val)); - if ((hi += 1) != min) { - for (lo = min + 1; --lo >= min;) { - c = *lo; - for (i = j = lo; (j -= 1) >= hi; i = j) - *i = *j; - *i = c; - } - } - } -} - - -static void keyvaliqst(KeyValueType *base, KeyValueType *max) -{ - register KeyValueType *i; - register KeyValueType *j; - register KeyValueType *jj; - register KeyValueType *mid; - register KeyValueType c; - KeyValueType *tmp; - int lo; - int hi; - - lo = (max - base)>>1; /* number of elements as KeyValueType */ - do { - mid = base + ((unsigned) lo>>1); - if (lo >= MTHRESH) { - j = (base->key > mid->key || (base->key == mid->key && base->val > mid->val) ? base : mid); - tmp = max - 1; - if (j->key > tmp->key || (j->key == tmp->key && j->val > tmp->val)) { - j = (j == base ? mid : base); /* switch to first loser */ - if (j->key < tmp->key || (j->key == tmp->key && j->val < tmp->val)) - j = tmp; - } - - if (j != mid) { /* SWAP */ - c = *mid; - *mid = *j; - *j = c; - } - } - - /* Semi-standard quicksort partitioning/swapping */ - for (i = base, j = max - 1;;) { - while (i < mid && (i->key < mid->key || (i->key == mid->key && i->val <= mid->val))) - i++; - while (j > mid) { - if (mid->key < j->key || (mid->key == j->key && mid->val <= j->val)) { - j--; - continue; - } - tmp = i + 1; /* value of i after swap */ - if (i == mid) /* j <-> mid, new mid is j */ - mid = jj = j; - else /* i <-> j */ - jj = j--; - goto swap; - } - - if (i == mid) - break; - else { /* i <-> mid, new mid is i */ - jj = mid; - tmp = mid = i; /* value of i after swap */ - j--; - } -swap: - c = *i; - *i = *jj; - *jj = c; - i = tmp; - } - - i = (j = mid) + 1; - if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) { - if (lo >= THRESH) - keyvaliqst(base, j); - base = i; - lo = hi; - } - else { - if (hi >= THRESH) - keyvaliqst(i, max); - max = j; - } - } while (lo >= THRESH); -} diff --git a/Metis/ometis.c b/Metis/ometis.c deleted file mode 100644 index 9ed53b4105..0000000000 --- a/Metis/ometis.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * ometis.c - * - * This file contains the top level routines for the multilevel recursive - * bisection algorithm PMETIS. - * - * Started 7/24/97 - * George - * - * $Id: ometis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point for OEMETIS -**************************************************************************/ -void METIS_EdgeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, - idxtype *perm, idxtype *iperm) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_OEMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = OEMETIS_CTYPE; - ctrl.IType = OEMETIS_ITYPE; - ctrl.RType = OEMETIS_RTYPE; - ctrl.dbglvl = OEMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.oflags = 0; - ctrl.pfactor = -1; - ctrl.nseps = 1; - - ctrl.optype = OP_OEMETIS; - ctrl.CoarsenTo = 20; - ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, 2); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - for (i=0; i<*nvtxs; i++) - perm[iperm[i]] = i; - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm); -} - - -/************************************************************************* -* This function is the entry point for ONCMETIS -**************************************************************************/ -void METIS_NodeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, - idxtype *perm, idxtype *iperm) -{ - int i, ii, j, l, wflag, nflag; - GraphType graph; - CtrlType ctrl; - idxtype *cptr, *cind, *piperm; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = ONMETIS_CTYPE; - ctrl.IType = ONMETIS_ITYPE; - ctrl.RType = ONMETIS_RTYPE; - ctrl.dbglvl = ONMETIS_DBGLVL; - ctrl.oflags = ONMETIS_OFLAGS; - ctrl.pfactor = ONMETIS_PFACTOR; - ctrl.nseps = ONMETIS_NSEPS; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - ctrl.oflags = options[OPTION_OFLAGS]; - ctrl.pfactor = options[OPTION_PFACTOR]; - ctrl.nseps = options[OPTION_NSEPS]; - } - if (ctrl.nseps < 1) - ctrl.nseps = 1; - - ctrl.optype = OP_ONMETIS; - ctrl.CoarsenTo = 100; - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - InitRandom(-1); - - if (ctrl.pfactor > 0) { - /*============================================================ - * Prune the dense columns - ==============================================================*/ - piperm = idxmalloc(*nvtxs, "ONMETIS: piperm"); - - PruneGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, piperm, (float)(0.1*ctrl.pfactor)); - } - else if (ctrl.oflags&OFLAG_COMPRESS) { - /*============================================================ - * Compress the graph - ==============================================================*/ - cptr = idxmalloc(*nvtxs+1, "ONMETIS: cptr"); - cind = idxmalloc(*nvtxs, "ONMETIS: cind"); - - CompressGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, cptr, cind); - - if (graph.nvtxs >= COMPRESSION_FRACTION*(*nvtxs)) { - ctrl.oflags--; /* We actually performed no compression */ - GKfree(&cptr, &cind, LTERM); - } - else if (2*graph.nvtxs < *nvtxs && ctrl.nseps == 1) - ctrl.nseps = 2; - } - else { - SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0); - } - - - /*============================================================= - * Do the nested dissection ordering - --=============================================================*/ - ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo); - AllocateWorkSpace(&ctrl, &graph, 2); - - if (ctrl.oflags&OFLAG_CCMP) - MlevelNestedDissectionCC(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs); - else - MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs); - - FreeWorkSpace(&ctrl, &graph); - - if (ctrl.pfactor > 0) { /* Order any prunned vertices */ - if (graph.nvtxs < *nvtxs) { - idxcopy(graph.nvtxs, iperm, perm); /* Use perm as an auxiliary array */ - for (i=0; i<graph.nvtxs; i++) - iperm[piperm[i]] = perm[i]; - for (i=graph.nvtxs; i<*nvtxs; i++) - iperm[piperm[i]] = i; - } - - GKfree(&piperm, LTERM); - } - else if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */ - if (graph.nvtxs < COMPRESSION_FRACTION*(*nvtxs)) { - /* construct perm from iperm */ - for (i=0; i<graph.nvtxs; i++) - perm[iperm[i]] = i; - for (l=ii=0; ii<graph.nvtxs; ii++) { - i = perm[ii]; - for (j=cptr[i]; j<cptr[i+1]; j++) - iperm[cind[j]] = l++; - } - } - - GKfree(&cptr, &cind, LTERM); - } - - - for (i=0; i<*nvtxs; i++) - perm[iperm[i]] = i; - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - if (*numflag == 1) - Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm); - -} - - -/************************************************************************* -* This function is the entry point for ONWMETIS. It requires weights on the -* vertices. It is for the case that the matrix has been pre-compressed. -**************************************************************************/ -void METIS_NodeWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, - int *options, idxtype *perm, idxtype *iperm) -{ - int i, j, tvwgt; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, NULL, 2); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = ONMETIS_CTYPE; - ctrl.IType = ONMETIS_ITYPE; - ctrl.RType = ONMETIS_RTYPE; - ctrl.dbglvl = ONMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - - ctrl.oflags = OFLAG_COMPRESS; - ctrl.pfactor = 0; - ctrl.nseps = 2; - ctrl.optype = OP_ONMETIS; - ctrl.CoarsenTo = 100; - ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo); - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, 2); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - for (i=0; i<*nvtxs; i++) - perm[iperm[i]] = i; - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm); -} - - - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -void MlevelNestedDissection(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx) -{ - int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2]; - idxtype *label, *bndind; - GraphType lgraph, rgraph; - - nvtxs = graph->nvtxs; - - /* Determine the weights of the partitions */ - tvwgt = idxsum(nvtxs, graph->vwgt); - tpwgts2[0] = tvwgt/2; - tpwgts2[1] = tvwgt-tpwgts2[0]; - - switch (ctrl->optype) { - case OP_OEMETIS: - MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr)); - ConstructMinCoverSeparator(ctrl, graph, ubfactor); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr)); - - break; - case OP_ONMETIS: - MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); - - IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); - - break; - } - - /* Order the nodes in the separator */ - nbnd = graph->nbnd; - bndind = graph->bndind; - label = graph->label; - for (i=0; i<nbnd; i++) - order[label[bndind[i]]] = --lastvtx; - - SplitGraphOrder(ctrl, graph, &lgraph, &rgraph); - - /* Free the memory of the top level graph */ - GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); - - if (rgraph.nvtxs > MMDSWITCH) - MlevelNestedDissection(ctrl, &rgraph, order, ubfactor, lastvtx); - else { - MMDOrder(ctrl, &rgraph, order, lastvtx); - GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM); - } - if (lgraph.nvtxs > MMDSWITCH) - MlevelNestedDissection(ctrl, &lgraph, order, ubfactor, lastvtx-rgraph.nvtxs); - else { - MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); - GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM); - } -} - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -void MlevelNestedDissectionCC(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx) -{ - int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2], nsgraphs, ncmps, rnvtxs; - idxtype *label, *bndind; - idxtype *cptr, *cind; - GraphType *sgraphs; - - nvtxs = graph->nvtxs; - - /* Determine the weights of the partitions */ - tvwgt = idxsum(nvtxs, graph->vwgt); - tpwgts2[0] = tvwgt/2; - tpwgts2[1] = tvwgt-tpwgts2[0]; - - MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); - IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); - - /* Order the nodes in the separator */ - nbnd = graph->nbnd; - bndind = graph->bndind; - label = graph->label; - for (i=0; i<nbnd; i++) - order[label[bndind[i]]] = --lastvtx; - - cptr = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cptr"); - cind = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cind"); - ncmps = FindComponents(ctrl, graph, cptr, cind); - -/* - if (ncmps > 2) - printf("[%5d] has %3d components\n", nvtxs, ncmps); -*/ - - sgraphs = (GraphType *)GKmalloc(ncmps*sizeof(GraphType), "MlevelNestedDissectionCC: sgraphs"); - - nsgraphs = SplitGraphOrderCC(ctrl, graph, sgraphs, ncmps, cptr, cind); - - GKfree(&cptr, &cind, LTERM); - - /* Free the memory of the top level graph */ - GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); - - /* Go and process the subgraphs */ - for (rnvtxs=i=0; i<nsgraphs; i++) { - if (sgraphs[i].adjwgt == NULL) { - MMDOrder(ctrl, sgraphs+i, order, lastvtx-rnvtxs); - GKfree(&sgraphs[i].gdata, &sgraphs[i].label, LTERM); - } - else { - MlevelNestedDissectionCC(ctrl, sgraphs+i, order, ubfactor, lastvtx-rnvtxs); - } - rnvtxs += sgraphs[i].nvtxs; - } - - free(sgraphs); -} - - - -/************************************************************************* -* This function performs multilevel bisection. It performs multiple -* bisections and selects the best. -**************************************************************************/ -void MlevelNodeBisectionMultiple(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - int i, nvtxs, cnvtxs, mincut, tmp; - GraphType *cgraph; - idxtype *bestwhere; - - if (ctrl->nseps == 1 || graph->nvtxs < (ctrl->oflags&OFLAG_COMPRESS ? 1000 : 2000)) { - MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor); - return; - } - - nvtxs = graph->nvtxs; - - if (ctrl->oflags&OFLAG_COMPRESS) { /* Multiple separators at the original graph */ - bestwhere = idxmalloc(nvtxs, "MlevelNodeBisection2: bestwhere"); - mincut = nvtxs; - - for (i=ctrl->nseps; i>0; i--) { - MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor); - - /* printf("%5d ", cgraph->mincut); */ - - if (graph->mincut < mincut) { - mincut = graph->mincut; - idxcopy(nvtxs, graph->where, bestwhere); - } - - GKfree(&graph->rdata, LTERM); - - if (mincut == 0) - break; - } - /* printf("[%5d]\n", mincut); */ - - Allocate2WayNodePartitionMemory(ctrl, graph); - idxcopy(nvtxs, bestwhere, graph->where); - free(bestwhere); - - Compute2WayNodePartitionParams(ctrl, graph); - } - else { /* Coarsen it a bit */ - ctrl->CoarsenTo = nvtxs-1; - - cgraph = Coarsen2Way(ctrl, graph); - - cnvtxs = cgraph->nvtxs; - - bestwhere = idxmalloc(cnvtxs, "MlevelNodeBisection2: bestwhere"); - mincut = nvtxs; - - for (i=ctrl->nseps; i>0; i--) { - ctrl->CType += 20; /* This is a hack. Look at coarsen.c */ - MlevelNodeBisection(ctrl, cgraph, tpwgts, ubfactor); - - /* printf("%5d ", cgraph->mincut); */ - - if (cgraph->mincut < mincut) { - mincut = cgraph->mincut; - idxcopy(cnvtxs, cgraph->where, bestwhere); - } - - GKfree(&cgraph->rdata, LTERM); - - if (mincut == 0) - break; - } - /* printf("[%5d]\n", mincut); */ - - Allocate2WayNodePartitionMemory(ctrl, cgraph); - idxcopy(cnvtxs, bestwhere, cgraph->where); - free(bestwhere); - - Compute2WayNodePartitionParams(ctrl, cgraph); - - Refine2WayNode(ctrl, graph, cgraph, ubfactor); - } - -} - -/************************************************************************* -* This function performs multilevel bisection -**************************************************************************/ -void MlevelNodeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - GraphType *cgraph; - - ctrl->CoarsenTo = graph->nvtxs/8; - if (ctrl->CoarsenTo > 100) - ctrl->CoarsenTo = 100; - else if (ctrl->CoarsenTo < 40) - ctrl->CoarsenTo = 40; - ctrl->maxvwgt = 1.5*((tpwgts[0]+tpwgts[1])/ctrl->CoarsenTo); - - cgraph = Coarsen2Way(ctrl, graph); - - switch (ctrl->IType) { - case IPART_GGPKL: - Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr)); - - Compute2WayPartitionParams(ctrl, cgraph); - ConstructSeparator(ctrl, cgraph, ubfactor); - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr)); - break; - case IPART_GGPKLNODE: - InitSeparator(ctrl, cgraph, ubfactor); - break; - } - - Refine2WayNode(ctrl, graph, cgraph, ubfactor); - -} - - - - -/************************************************************************* -* This function takes a graph and a bisection and splits it into two graphs. -* This function relies on the fact that adjwgt is all equal to 1. -**************************************************************************/ -void SplitGraphOrder(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph) -{ - int i, ii, j, k, l, istart, iend, mypart, nvtxs, snvtxs[3], snedges[3]; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind; - idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2]; - idxtype *rename; - idxtype *auxadjncy, *auxadjwgt; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr)); - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - label = graph->label; - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - ASSERT(bndptr != NULL); - - rename = idxwspacemalloc(ctrl, nvtxs); - - snvtxs[0] = snvtxs[1] = snvtxs[2] = snedges[0] = snedges[1] = snedges[2] = 0; - for (i=0; i<nvtxs; i++) { - k = where[i]; - rename[i] = snvtxs[k]++; - snedges[k] += xadj[i+1]-xadj[i]; - } - - SetUpSplitGraph(graph, lgraph, snvtxs[0], snedges[0]); - sxadj[0] = lgraph->xadj; - svwgt[0] = lgraph->vwgt; - sadjwgtsum[0] = lgraph->adjwgtsum; - sadjncy[0] = lgraph->adjncy; - sadjwgt[0] = lgraph->adjwgt; - slabel[0] = lgraph->label; - - SetUpSplitGraph(graph, rgraph, snvtxs[1], snedges[1]); - sxadj[1] = rgraph->xadj; - svwgt[1] = rgraph->vwgt; - sadjwgtsum[1] = rgraph->adjwgtsum; - sadjncy[1] = rgraph->adjncy; - sadjwgt[1] = rgraph->adjwgt; - slabel[1] = rgraph->label; - - /* Go and use bndptr to also mark the boundary nodes in the two partitions */ - for (ii=0; ii<graph->nbnd; ii++) { - i = bndind[ii]; - for (j=xadj[i]; j<xadj[i+1]; j++) - bndptr[adjncy[j]] = 1; - } - - snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0; - sxadj[0][0] = sxadj[1][0] = 0; - for (i=0; i<nvtxs; i++) { - if ((mypart = where[i]) == 2) - continue; - - istart = xadj[i]; - iend = xadj[i+1]; - if (bndptr[i] == -1) { /* This is an interior vertex */ - auxadjncy = sadjncy[mypart] + snedges[mypart] - istart; - for(j=istart; j<iend; j++) - auxadjncy[j] = adjncy[j]; - snedges[mypart] += iend-istart; - } - else { - auxadjncy = sadjncy[mypart]; - l = snedges[mypart]; - for (j=istart; j<iend; j++) { - k = adjncy[j]; - if (where[k] == mypart) - auxadjncy[l++] = k; - } - snedges[mypart] = l; - } - - svwgt[mypart][snvtxs[mypart]] = vwgt[i]; - sadjwgtsum[mypart][snvtxs[mypart]] = snedges[mypart]-sxadj[mypart][snvtxs[mypart]]; - slabel[mypart][snvtxs[mypart]] = label[i]; - sxadj[mypart][++snvtxs[mypart]] = snedges[mypart]; - } - - for (mypart=0; mypart<2; mypart++) { - iend = snedges[mypart]; - idxset(iend, 1, sadjwgt[mypart]); - - auxadjncy = sadjncy[mypart]; - for (i=0; i<iend; i++) - auxadjncy[i] = rename[auxadjncy[i]]; - } - - lgraph->nvtxs = snvtxs[0]; - lgraph->nedges = snedges[0]; - rgraph->nvtxs = snvtxs[1]; - rgraph->nedges = snedges[1]; - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr)); - - idxwspacefree(ctrl, nvtxs); - -} - -/************************************************************************* -* This function uses MMD to order the graph. The vertices are numbered -* from lastvtx downwards -**************************************************************************/ -void MMDOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx) -{ - int i, j, k, nvtxs, nofsub, firstvtx; - idxtype *xadj, *adjncy, *label; - idxtype *perm, *iperm, *head, *qsize, *list, *marker; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - - /* Relabel the vertices so that it starts from 1 */ - k = xadj[nvtxs]; - for (i=0; i<k; i++) - adjncy[i]++; - for (i=0; i<nvtxs+1; i++) - xadj[i]++; - - perm = idxmalloc(6*(nvtxs+5), "MMDOrder: perm"); - iperm = perm + nvtxs + 5; - head = iperm + nvtxs + 5; - qsize = head + nvtxs + 5; - list = qsize + nvtxs + 5; - marker = list + nvtxs + 5; - - genmmd(nvtxs, xadj, adjncy, iperm, perm, 1, head, qsize, list, marker, MAXIDX, &nofsub); - - label = graph->label; - firstvtx = lastvtx-nvtxs; - for (i=0; i<nvtxs; i++) - order[label[i]] = firstvtx+iperm[i]-1; - - free(perm); - - /* Relabel the vertices so that it starts from 0 */ - for (i=0; i<nvtxs+1; i++) - xadj[i]--; - k = xadj[nvtxs]; - for (i=0; i<k; i++) - adjncy[i]--; -} - - -/************************************************************************* -* This function takes a graph and a bisection and splits it into two graphs. -* It relies on the fact that adjwgt is all set to 1. -**************************************************************************/ -int SplitGraphOrderCC(CtrlType *ctrl, GraphType *graph, GraphType *sgraphs, int ncmps, idxtype *cptr, idxtype *cind) -{ - int i, ii, iii, j, k, l, istart, iend, mypart, nvtxs, snvtxs, snedges; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind; - idxtype *sxadj, *svwgt, *sadjncy, *sadjwgt, *sadjwgtsum, *slabel; - idxtype *rename; - idxtype *auxadjncy, *auxadjwgt; - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr)); - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - label = graph->label; - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - ASSERT(bndptr != NULL); - - /* Go and use bndptr to also mark the boundary nodes in the two partitions */ - for (ii=0; ii<graph->nbnd; ii++) { - i = bndind[ii]; - for (j=xadj[i]; j<xadj[i+1]; j++) - bndptr[adjncy[j]] = 1; - } - - rename = idxwspacemalloc(ctrl, nvtxs); - - /* Go and split the graph a component at a time */ - for (iii=0; iii<ncmps; iii++) { - RandomPermute(cptr[iii+1]-cptr[iii], cind+cptr[iii], 0); - snvtxs = snedges = 0; - for (j=cptr[iii]; j<cptr[iii+1]; j++) { - i = cind[j]; - rename[i] = snvtxs++; - snedges += xadj[i+1]-xadj[i]; - } - - SetUpSplitGraph(graph, sgraphs+iii, snvtxs, snedges); - sxadj = sgraphs[iii].xadj; - svwgt = sgraphs[iii].vwgt; - sadjwgtsum = sgraphs[iii].adjwgtsum; - sadjncy = sgraphs[iii].adjncy; - sadjwgt = sgraphs[iii].adjwgt; - slabel = sgraphs[iii].label; - - snvtxs = snedges = sxadj[0] = 0; - for (ii=cptr[iii]; ii<cptr[iii+1]; ii++) { - i = cind[ii]; - - istart = xadj[i]; - iend = xadj[i+1]; - if (bndptr[i] == -1) { /* This is an interior vertex */ - auxadjncy = sadjncy + snedges - istart; - auxadjwgt = sadjwgt + snedges - istart; - for(j=istart; j<iend; j++) - auxadjncy[j] = adjncy[j]; - snedges += iend-istart; - } - else { - l = snedges; - for (j=istart; j<iend; j++) { - k = adjncy[j]; - if (where[k] != 2) - sadjncy[l++] = k; - } - snedges = l; - } - - svwgt[snvtxs] = vwgt[i]; - sadjwgtsum[snvtxs] = snedges-sxadj[snvtxs]; - slabel[snvtxs] = label[i]; - sxadj[++snvtxs] = snedges; - } - - idxset(snedges, 1, sadjwgt); - for (i=0; i<snedges; i++) - sadjncy[i] = rename[sadjncy[i]]; - - sgraphs[iii].nvtxs = snvtxs; - sgraphs[iii].nedges = snedges; - sgraphs[iii].ncon = 1; - - if (snvtxs < MMDSWITCH) - sgraphs[iii].adjwgt = NULL; /* A marker to call MMD on the driver */ - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr)); - - idxwspacefree(ctrl, nvtxs); - - return ncmps; - -} - - - - - diff --git a/Metis/parmetis.c b/Metis/parmetis.c deleted file mode 100644 index b20396a551..0000000000 --- a/Metis/parmetis.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * parmetis.c - * - * This file contains top level routines that are used by ParMETIS - * - * Started 10/14/97 - * George - * - * $Id: parmetis.c,v 1.1 2005-09-07 14:36:45 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point for KMETIS with seed specification -* in options[7] -**************************************************************************/ -void METIS_PartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ - int i; - float *tpwgts; - - tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); - for (i=0; i<*nparts; i++) - tpwgts[i] = 1.0/(1.0*(*nparts)); - - METIS_WPartGraphKway2(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, - tpwgts, options, edgecut, part); - - free(tpwgts); -} - - -/************************************************************************* -* This function is the entry point for KWMETIS with seed specification -* in options[7] -**************************************************************************/ -void METIS_WPartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_KMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = KMETIS_CTYPE; - ctrl.IType = KMETIS_ITYPE; - ctrl.RType = KMETIS_RTYPE; - ctrl.dbglvl = KMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_KMETIS; - ctrl.CoarsenTo = 20*(*nparts); - ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo); - - InitRandom(options[7]); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MlevelKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - -/************************************************************************* -* This function is the entry point for the node ND code for ParMETIS -**************************************************************************/ -void METIS_NodeNDP(int nvtxs, idxtype *xadj, idxtype *adjncy, int npes, - int *options, idxtype *perm, idxtype *iperm, idxtype *sizes) -{ - int i, ii, j, l, wflag, nflag; - GraphType graph; - CtrlType ctrl; - idxtype *cptr, *cind; - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = ONMETIS_CTYPE; - ctrl.IType = ONMETIS_ITYPE; - ctrl.RType = ONMETIS_RTYPE; - ctrl.dbglvl = ONMETIS_DBGLVL; - ctrl.oflags = ONMETIS_OFLAGS; - ctrl.pfactor = ONMETIS_PFACTOR; - ctrl.nseps = ONMETIS_NSEPS; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - ctrl.oflags = options[OPTION_OFLAGS]; - ctrl.pfactor = options[OPTION_PFACTOR]; - ctrl.nseps = options[OPTION_NSEPS]; - } - if (ctrl.nseps < 1) - ctrl.nseps = 1; - - ctrl.optype = OP_ONMETIS; - ctrl.CoarsenTo = 100; - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - InitRandom(-1); - - if (ctrl.oflags&OFLAG_COMPRESS) { - /*============================================================ - * Compress the graph - ==============================================================*/ - cptr = idxmalloc(nvtxs+1, "ONMETIS: cptr"); - cind = idxmalloc(nvtxs, "ONMETIS: cind"); - - CompressGraph(&ctrl, &graph, nvtxs, xadj, adjncy, cptr, cind); - - if (graph.nvtxs >= COMPRESSION_FRACTION*(nvtxs)) { - ctrl.oflags--; /* We actually performed no compression */ - GKfree(&cptr, &cind, LTERM); - } - else if (2*graph.nvtxs < nvtxs && ctrl.nseps == 1) - ctrl.nseps = 2; - } - else { - SetUpGraph(&graph, OP_ONMETIS, nvtxs, 1, xadj, adjncy, NULL, NULL, 0); - } - - - /*============================================================= - * Do the nested dissection ordering - --=============================================================*/ - ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo); - AllocateWorkSpace(&ctrl, &graph, 2); - - idxset(2*npes-1, 0, sizes); - MlevelNestedDissectionP(&ctrl, &graph, iperm, graph.nvtxs, npes, 0, sizes); - - FreeWorkSpace(&ctrl, &graph); - - if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */ - if (graph.nvtxs < COMPRESSION_FRACTION*(nvtxs)) { - /* construct perm from iperm */ - for (i=0; i<graph.nvtxs; i++) - perm[iperm[i]] = i; - for (l=ii=0; ii<graph.nvtxs; ii++) { - i = perm[ii]; - for (j=cptr[i]; j<cptr[i+1]; j++) - iperm[cind[j]] = l++; - } - } - - GKfree(&cptr, &cind, LTERM); - } - - - for (i=0; i<nvtxs; i++) - perm[iperm[i]] = i; - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - -} - - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -void MlevelNestedDissectionP(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx, - int npes, int cpos, idxtype *sizes) -{ - int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2]; - idxtype *label, *bndind; - GraphType lgraph, rgraph; - float ubfactor; - - nvtxs = graph->nvtxs; - - if (nvtxs == 0) { - GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); - return; - } - - /* Determine the weights of the partitions */ - tvwgt = idxsum(nvtxs, graph->vwgt); - tpwgts2[0] = tvwgt/2; - tpwgts2[1] = tvwgt-tpwgts2[0]; - - if (cpos >= npes-1) - ubfactor = ORDER_UNBALANCE_FRACTION; - else - ubfactor = 1.05; - - - MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); - - IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); - - if (cpos < npes-1) { - sizes[2*npes-2-cpos] = graph->pwgts[2]; - sizes[2*npes-2-(2*cpos+1)] = graph->pwgts[1]; - sizes[2*npes-2-(2*cpos+2)] = graph->pwgts[0]; - } - - /* Order the nodes in the separator */ - nbnd = graph->nbnd; - bndind = graph->bndind; - label = graph->label; - for (i=0; i<nbnd; i++) - order[label[bndind[i]]] = --lastvtx; - - SplitGraphOrder(ctrl, graph, &lgraph, &rgraph); - - /* Free the memory of the top level graph */ - GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); - - if (rgraph.nvtxs > MMDSWITCH || 2*cpos+1 < npes-1) - MlevelNestedDissectionP(ctrl, &rgraph, order, lastvtx, npes, 2*cpos+1, sizes); - else { - MMDOrder(ctrl, &rgraph, order, lastvtx); - GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM); - } - if (lgraph.nvtxs > MMDSWITCH || 2*cpos+2 < npes-1) - MlevelNestedDissectionP(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs, npes, 2*cpos+2, sizes); - else { - MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); - GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM); - } -} - - - - -/************************************************************************* -* This function is the entry point for ONWMETIS. It requires weights on the -* vertices. It is for the case that the matrix has been pre-compressed. -**************************************************************************/ -void METIS_NodeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *options, int *sepsize, idxtype *part) -{ - int i, j, tvwgt, tpwgts[2]; - GraphType graph; - CtrlType ctrl; - - SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3); - tvwgt = idxsum(*nvtxs, graph.vwgt); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = ONMETIS_CTYPE; - ctrl.IType = ONMETIS_ITYPE; - ctrl.RType = ONMETIS_RTYPE; - ctrl.dbglvl = ONMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - - ctrl.oflags = 0; - ctrl.pfactor = 0; - ctrl.nseps = 1; - ctrl.optype = OP_ONMETIS; - ctrl.CoarsenTo = amin(100, *nvtxs-1); - ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; - - InitRandom(options[7]); - - AllocateWorkSpace(&ctrl, &graph, 2); - - /*============================================================ - * Perform the bisection - *============================================================*/ - tpwgts[0] = tvwgt/2; - tpwgts[1] = tvwgt-tpwgts[0]; - - MlevelNodeBisectionMultiple(&ctrl, &graph, tpwgts, 1.05); - - *sepsize = graph.pwgts[2]; - idxcopy(*nvtxs, graph.where, part); - - GKfree(&graph.gdata, &graph.rdata, &graph.label, LTERM); - - - FreeWorkSpace(&ctrl, &graph); - -} - - - -/************************************************************************* -* This function is the entry point for ONWMETIS. It requires weights on the -* vertices. It is for the case that the matrix has been pre-compressed. -**************************************************************************/ -void METIS_EdgeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *options, int *sepsize, idxtype *part) -{ - int i, j, tvwgt, tpwgts[2]; - GraphType graph; - CtrlType ctrl; - - SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3); - tvwgt = idxsum(*nvtxs, graph.vwgt); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = ONMETIS_CTYPE; - ctrl.IType = ONMETIS_ITYPE; - ctrl.RType = ONMETIS_RTYPE; - ctrl.dbglvl = ONMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - - ctrl.oflags = 0; - ctrl.pfactor = 0; - ctrl.nseps = 1; - ctrl.optype = OP_OEMETIS; - ctrl.CoarsenTo = amin(100, *nvtxs-1); - ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; - - InitRandom(options[7]); - - AllocateWorkSpace(&ctrl, &graph, 2); - - /*============================================================ - * Perform the bisection - *============================================================*/ - tpwgts[0] = tvwgt/2; - tpwgts[1] = tvwgt-tpwgts[0]; - - MlevelEdgeBisection(&ctrl, &graph, tpwgts, 1.05); - ConstructMinCoverSeparator(&ctrl, &graph, 1.05); - - *sepsize = graph.pwgts[2]; - idxcopy(*nvtxs, graph.where, part); - - GKfree(&graph.gdata, &graph.rdata, &graph.label, LTERM); - - - FreeWorkSpace(&ctrl, &graph); - -} diff --git a/Metis/pmetis.c b/Metis/pmetis.c deleted file mode 100644 index 9e17cdfe73..0000000000 --- a/Metis/pmetis.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * pmetis.c - * - * This file contains the top level routines for the multilevel recursive - * bisection algorithm PMETIS. - * - * Started 7/24/97 - * George - * - * $Id: pmetis.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point for PMETIS -**************************************************************************/ -void METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ - int i; - float *tpwgts; - - tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); - for (i=0; i<*nparts; i++) - tpwgts[i] = 1.0/(1.0*(*nparts)); - - METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, - tpwgts, options, edgecut, part); - - free(tpwgts); -} - - - -/************************************************************************* -* This function is the entry point for PWMETIS that accepts exact weights -* for the target partitions -**************************************************************************/ -void METIS_WPartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - float *tpwgts, int *options, int *edgecut, idxtype *part) -{ - int i, j; - GraphType graph; - CtrlType ctrl; - float *mytpwgts; - - if (*numflag == 1) - Change2CNumbering(*nvtxs, xadj, adjncy); - - SetUpGraph(&graph, OP_PMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag); - - if (options[0] == 0) { /* Use the default parameters */ - ctrl.CType = PMETIS_CTYPE; - ctrl.IType = PMETIS_ITYPE; - ctrl.RType = PMETIS_RTYPE; - ctrl.dbglvl = PMETIS_DBGLVL; - } - else { - ctrl.CType = options[OPTION_CTYPE]; - ctrl.IType = options[OPTION_ITYPE]; - ctrl.RType = options[OPTION_RTYPE]; - ctrl.dbglvl = options[OPTION_DBGLVL]; - } - ctrl.optype = OP_PMETIS; - ctrl.CoarsenTo = 20; - ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo); - - mytpwgts = fmalloc(*nparts, "PWMETIS: mytpwgts"); - for (i=0; i<*nparts; i++) - mytpwgts[i] = tpwgts[i]; - - InitRandom(-1); - - AllocateWorkSpace(&ctrl, &graph, *nparts); - - IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); - IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); - - *edgecut = MlevelRecursiveBisection(&ctrl, &graph, *nparts, part, mytpwgts, 1.000, 0); - - IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); - IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); - - FreeWorkSpace(&ctrl, &graph); - free(mytpwgts); - - if (*numflag == 1) - Change2FNumbering(*nvtxs, xadj, adjncy, part); -} - - - -/************************************************************************* -* This function takes a graph and produces a bisection of it -**************************************************************************/ -int MlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor, int fpart) -{ - int i, j, nvtxs, cut, tvwgt, tpwgts2[2]; - idxtype *label, *where; - GraphType lgraph, rgraph; - float wsum; - - nvtxs = graph->nvtxs; - if (nvtxs == 0) { - printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); - return 0; - } - - /* Determine the weights of the partitions */ - tvwgt = idxsum(nvtxs, graph->vwgt); - tpwgts2[0] = tvwgt*ssum(nparts/2, tpwgts); - tpwgts2[1] = tvwgt-tpwgts2[0]; - - MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); - cut = graph->mincut; - - /* printf("%5d %5d %5d [%5d %f]\n", tpwgts2[0], tpwgts2[1], cut, tvwgt, ssum(nparts/2, tpwgts));*/ - - label = graph->label; - where = graph->where; - for (i=0; i<nvtxs; i++) - part[label[i]] = where[i] + fpart; - - if (nparts > 2) { - SplitGraphPart(ctrl, graph, &lgraph, &rgraph); - /* printf("%d %d\n", lgraph.nvtxs, rgraph.nvtxs); */ - } - - - /* Free the memory of the top level graph */ - GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); - - /* Scale the fractions in the tpwgts according to the true weight */ - wsum = ssum(nparts/2, tpwgts); - sscale(nparts/2, 1.0/wsum, tpwgts); - sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2); - /* - for (i=0; i<nparts; i++) - printf("%5.3f ", tpwgts[i]); - printf("[%5.3f]\n", wsum); - */ - - /* Do the recursive call */ - if (nparts > 3) { - cut += MlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, tpwgts, ubfactor, fpart); - cut += MlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, tpwgts+nparts/2, ubfactor, fpart+nparts/2); - } - else if (nparts == 3) { - cut += MlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, tpwgts+nparts/2, ubfactor, fpart+nparts/2); - GKfree(&lgraph.gdata, &lgraph.label, LTERM); - } - - return cut; - -} - - -/************************************************************************* -* This function performs multilevel bisection -**************************************************************************/ -void MlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) -{ - GraphType *cgraph; - - cgraph = Coarsen2Way(ctrl, graph); - - Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor); - - Refine2Way(ctrl, graph, cgraph, tpwgts, ubfactor); - -/* - IsConnectedSubdomain(ctrl, graph, 0); - IsConnectedSubdomain(ctrl, graph, 1); -*/ -} - - - - -/************************************************************************* -* This function takes a graph and a bisection and splits it into two graphs. -**************************************************************************/ -void SplitGraphPart(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph) -{ - int i, j, k, kk, l, istart, iend, mypart, nvtxs, ncon, snvtxs[2], snedges[2], sum; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr; - idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2]; - idxtype *rename; - idxtype *auxadjncy, *auxadjwgt; - float *nvwgt, *snvwgt[2], *npwgts; - - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr)); - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - vwgt = graph->vwgt; - nvwgt = graph->nvwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - label = graph->label; - where = graph->where; - bndptr = graph->bndptr; - npwgts = graph->npwgts; - - ASSERT(bndptr != NULL); - - rename = idxwspacemalloc(ctrl, nvtxs); - - snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0; - for (i=0; i<nvtxs; i++) { - k = where[i]; - rename[i] = snvtxs[k]++; - snedges[k] += xadj[i+1]-xadj[i]; - } - - SetUpSplitGraph(graph, lgraph, snvtxs[0], snedges[0]); - sxadj[0] = lgraph->xadj; - svwgt[0] = lgraph->vwgt; - snvwgt[0] = lgraph->nvwgt; - sadjwgtsum[0] = lgraph->adjwgtsum; - sadjncy[0] = lgraph->adjncy; - sadjwgt[0] = lgraph->adjwgt; - slabel[0] = lgraph->label; - - SetUpSplitGraph(graph, rgraph, snvtxs[1], snedges[1]); - sxadj[1] = rgraph->xadj; - svwgt[1] = rgraph->vwgt; - snvwgt[1] = rgraph->nvwgt; - sadjwgtsum[1] = rgraph->adjwgtsum; - sadjncy[1] = rgraph->adjncy; - sadjwgt[1] = rgraph->adjwgt; - slabel[1] = rgraph->label; - - snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0; - sxadj[0][0] = sxadj[1][0] = 0; - for (i=0; i<nvtxs; i++) { - mypart = where[i]; - sum = adjwgtsum[i]; - - istart = xadj[i]; - iend = xadj[i+1]; - if (bndptr[i] == -1) { /* This is an interior vertex */ - auxadjncy = sadjncy[mypart] + snedges[mypart] - istart; - auxadjwgt = sadjwgt[mypart] + snedges[mypart] - istart; - for(j=istart; j<iend; j++) { - auxadjncy[j] = adjncy[j]; - auxadjwgt[j] = adjwgt[j]; - } - snedges[mypart] += iend-istart; - } - else { - auxadjncy = sadjncy[mypart]; - auxadjwgt = sadjwgt[mypart]; - l = snedges[mypart]; - for (j=istart; j<iend; j++) { - k = adjncy[j]; - if (where[k] == mypart) { - auxadjncy[l] = k; - auxadjwgt[l++] = adjwgt[j]; - } - else { - sum -= adjwgt[j]; - } - } - snedges[mypart] = l; - } - - if (ncon == 1) - svwgt[mypart][snvtxs[mypart]] = vwgt[i]; - else { - for (kk=0; kk<ncon; kk++) - snvwgt[mypart][snvtxs[mypart]*ncon+kk] = nvwgt[i*ncon+kk]/npwgts[mypart*ncon+kk]; - } - - sadjwgtsum[mypart][snvtxs[mypart]] = sum; - slabel[mypart][snvtxs[mypart]] = label[i]; - sxadj[mypart][++snvtxs[mypart]] = snedges[mypart]; - } - - for (mypart=0; mypart<2; mypart++) { - iend = sxadj[mypart][snvtxs[mypart]]; - auxadjncy = sadjncy[mypart]; - for (i=0; i<iend; i++) - auxadjncy[i] = rename[auxadjncy[i]]; - } - - lgraph->nedges = snedges[0]; - rgraph->nedges = snedges[1]; - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr)); - - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* Setup the various arrays for the splitted graph -**************************************************************************/ -void SetUpSplitGraph(GraphType *graph, GraphType *sgraph, int snvtxs, int snedges) -{ - InitGraph(sgraph); - sgraph->nvtxs = snvtxs; - sgraph->nedges = snedges; - sgraph->ncon = graph->ncon; - - /* Allocate memory for the splitted graph */ - if (graph->ncon == 1) { - sgraph->gdata = idxmalloc(4*snvtxs+1 + 2*snedges, "SetUpSplitGraph: gdata"); - - sgraph->xadj = sgraph->gdata; - sgraph->vwgt = sgraph->gdata + snvtxs+1; - sgraph->adjwgtsum = sgraph->gdata + 2*snvtxs+1; - sgraph->cmap = sgraph->gdata + 3*snvtxs+1; - sgraph->adjncy = sgraph->gdata + 4*snvtxs+1; - sgraph->adjwgt = sgraph->gdata + 4*snvtxs+1 + snedges; - } - else { - sgraph->gdata = idxmalloc(3*snvtxs+1 + 2*snedges, "SetUpSplitGraph: gdata"); - - sgraph->xadj = sgraph->gdata; - sgraph->adjwgtsum = sgraph->gdata + snvtxs+1; - sgraph->cmap = sgraph->gdata + 2*snvtxs+1; - sgraph->adjncy = sgraph->gdata + 3*snvtxs+1; - sgraph->adjwgt = sgraph->gdata + 3*snvtxs+1 + snedges; - - sgraph->nvwgt = fmalloc(graph->ncon*snvtxs, "SetUpSplitGraph: nvwgt"); - } - - sgraph->label = idxmalloc(snvtxs, "SetUpSplitGraph: sgraph->label"); -} - diff --git a/Metis/pqueue.c b/Metis/pqueue.c deleted file mode 100644 index c5b8c8b3b5..0000000000 --- a/Metis/pqueue.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * pqueue.c - * - * This file contains functions for manipulating the bucket list - * representation of the gains associated with each vertex in a graph. - * These functions are used by the refinement algorithms - * - * Started 9/2/94 - * George - * - * $Id: pqueue.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function initializes the data structures of the priority queue -**************************************************************************/ -void PQueueInit(CtrlType *ctrl, PQueueType *queue, int maxnodes, int maxgain) -{ - int i, j, ncore; - - queue->nnodes = 0; - queue->maxnodes = maxnodes; - - queue->buckets = NULL; - queue->nodes = NULL; - queue->heap = NULL; - queue->locator = NULL; - - if (maxgain > PLUS_GAINSPAN || maxnodes < 500) - queue->type = 2; - else - queue->type = 1; - - if (queue->type == 1) { - queue->pgainspan = amin(PLUS_GAINSPAN, maxgain); - queue->ngainspan = amin(NEG_GAINSPAN, maxgain); - - j = queue->ngainspan+queue->pgainspan+1; - - ncore = 2 + (sizeof(ListNodeType)/sizeof(idxtype))*maxnodes + (sizeof(ListNodeType *)/sizeof(idxtype))*j; - - if (WspaceAvail(ctrl) > ncore) { - queue->nodes = (ListNodeType *)idxwspacemalloc(ctrl, (sizeof(ListNodeType)/sizeof(idxtype))*maxnodes); - queue->buckets = (ListNodeType **)idxwspacemalloc(ctrl, (sizeof(ListNodeType *)/sizeof(idxtype))*j); - queue->mustfree = 0; - } - else { /* Not enough memory in the wspace, allocate it */ - queue->nodes = (ListNodeType *)idxmalloc((sizeof(ListNodeType)/sizeof(idxtype))*maxnodes, "PQueueInit: queue->nodes"); - queue->buckets = (ListNodeType **)idxmalloc((sizeof(ListNodeType *)/sizeof(idxtype))*j, "PQueueInit: queue->buckets"); - queue->mustfree = 1; - } - - for (i=0; i<maxnodes; i++) - queue->nodes[i].id = i; - - for (i=0; i<j; i++) - queue->buckets[i] = NULL; - - queue->buckets += queue->ngainspan; /* Advance buckets by the ngainspan proper indexing */ - queue->maxgain = -queue->ngainspan; - } - else { - queue->heap = (KeyValueType *)idxwspacemalloc(ctrl, (sizeof(KeyValueType)/sizeof(idxtype))*maxnodes); - queue->locator = idxwspacemalloc(ctrl, maxnodes); - idxset(maxnodes, -1, queue->locator); - } - -} - - -/************************************************************************* -* This function resets the buckets -**************************************************************************/ -void PQueueReset(PQueueType *queue) -{ - int i, j; - queue->nnodes = 0; - - if (queue->type == 1) { - queue->maxgain = -queue->ngainspan; - - j = queue->ngainspan+queue->pgainspan+1; - queue->buckets -= queue->ngainspan; - for (i=0; i<j; i++) - queue->buckets[i] = NULL; - queue->buckets += queue->ngainspan; - } - else { - idxset(queue->maxnodes, -1, queue->locator); - } - -} - - -/************************************************************************* -* This function frees the buckets -**************************************************************************/ -void PQueueFree(CtrlType *ctrl, PQueueType *queue) -{ - - if (queue->type == 1) { - if (queue->mustfree) { - queue->buckets -= queue->ngainspan; - GKfree(&queue->nodes, &queue->buckets, LTERM); - } - else { - idxwspacefree(ctrl, sizeof(ListNodeType *)*(queue->ngainspan+queue->pgainspan+1)/sizeof(idxtype)); - idxwspacefree(ctrl, sizeof(ListNodeType)*queue->maxnodes/sizeof(idxtype)); - } - } - else { - idxwspacefree(ctrl, sizeof(KeyValueType)*queue->maxnodes/sizeof(idxtype)); - idxwspacefree(ctrl, queue->maxnodes); - } - - queue->maxnodes = 0; -} - - -/************************************************************************* -* This function returns the number of nodes in the queue -**************************************************************************/ -int PQueueGetSize(PQueueType *queue) -{ - return queue->nnodes; -} - - -/************************************************************************* -* This function adds a node of certain gain into a partition -**************************************************************************/ -int PQueueInsert(PQueueType *queue, int node, int gain) -{ - int i, j, k; - idxtype *locator; - ListNodeType *newnode; - KeyValueType *heap; - - if (queue->type == 1) { - ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan); - - /* Allocate and add the node */ - queue->nnodes++; - newnode = queue->nodes + node; - - /* Attach this node in the doubly-linked list */ - newnode->next = queue->buckets[gain]; - newnode->prev = NULL; - if (newnode->next != NULL) - newnode->next->prev = newnode; - queue->buckets[gain] = newnode; - - if (queue->maxgain < gain) - queue->maxgain = gain; - } - else { - ASSERT(CheckHeap(queue)); - - heap = queue->heap; - locator = queue->locator; - - ASSERT(locator[node] == -1); - - i = queue->nnodes++; - while (i > 0) { - j = (i-1)/2; - if (heap[j].key < gain) { - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - ASSERT(i >= 0); - heap[i].key = gain; - heap[i].val = node; - locator[node] = i; - - ASSERT(CheckHeap(queue)); - } - - return 0; -} - - -/************************************************************************* -* This function deletes a node from a partition and reinserts it with -* an updated gain -**************************************************************************/ -int PQueueDelete(PQueueType *queue, int node, int gain) -{ - int i, j, newgain, oldgain; - idxtype *locator; - ListNodeType *newnode, **buckets; - KeyValueType *heap; - - if (queue->type == 1) { - ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan); - ASSERT(queue->nnodes > 0); - - buckets = queue->buckets; - queue->nnodes--; - newnode = queue->nodes+node; - - /* Remove newnode from the doubly-linked list */ - if (newnode->prev != NULL) - newnode->prev->next = newnode->next; - else - buckets[gain] = newnode->next; - if (newnode->next != NULL) - newnode->next->prev = newnode->prev; - - if (buckets[gain] == NULL && gain == queue->maxgain) { - if (queue->nnodes == 0) - queue->maxgain = -queue->ngainspan; - else - for (; buckets[queue->maxgain]==NULL; queue->maxgain--); - } - } - else { /* Heap Priority Queue */ - heap = queue->heap; - locator = queue->locator; - - ASSERT(locator[node] != -1); - ASSERT(heap[locator[node]].val == node); - - ASSERT(CheckHeap(queue)); - - i = locator[node]; - locator[node] = -1; - - if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) { - node = heap[queue->nnodes].val; - newgain = heap[queue->nnodes].key; - oldgain = heap[i].key; - - if (oldgain < newgain) { /* Filter-up */ - while (i > 0) { - j = (i-1)>>1; - if (heap[j].key < newgain) { - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - } - else { /* Filter down */ - while ((j=2*i+1) < queue->nnodes) { - if (heap[j].key > newgain) { - if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) - j = j+1; - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { - j = j+1; - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - } - - heap[i].key = newgain; - heap[i].val = node; - locator[node] = i; - } - - ASSERT(CheckHeap(queue)); - } - - return 0; -} - - - -/************************************************************************* -* This function deletes a node from a partition and reinserts it with -* an updated gain -**************************************************************************/ -int PQueueUpdate(PQueueType *queue, int node, int oldgain, int newgain) -{ - int i, j; - idxtype *locator; - ListNodeType *newnode; - KeyValueType *heap; - - if (oldgain == newgain) - return 0; - - if (queue->type == 1) { - /* First delete the node and then insert it */ - PQueueDelete(queue, node, oldgain); - return PQueueInsert(queue, node, newgain); - } - else { /* Heap Priority Queue */ - heap = queue->heap; - locator = queue->locator; - - ASSERT(locator[node] != -1); - ASSERT(heap[locator[node]].val == node); - ASSERT(heap[locator[node]].key == oldgain); - ASSERT(CheckHeap(queue)); - - i = locator[node]; - - if (oldgain < newgain) { /* Filter-up */ - while (i > 0) { - j = (i-1)>>1; - if (heap[j].key < newgain) { - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - } - else { /* Filter down */ - while ((j=2*i+1) < queue->nnodes) { - if (heap[j].key > newgain) { - if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) - j = j+1; - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { - j = j+1; - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - } - - heap[i].key = newgain; - heap[i].val = node; - locator[node] = i; - - ASSERT(CheckHeap(queue)); - } - - return 0; -} - - - -/************************************************************************* -* This function deletes a node from a partition and reinserts it with -* an updated gain -**************************************************************************/ -void PQueueUpdateUp(PQueueType *queue, int node, int oldgain, int newgain) -{ - int i, j; - idxtype *locator; - ListNodeType *newnode, **buckets; - KeyValueType *heap; - - if (oldgain == newgain) - return; - - if (queue->type == 1) { - ASSERT(oldgain >= -queue->ngainspan && oldgain <= queue->pgainspan); - ASSERT(newgain >= -queue->ngainspan && newgain <= queue->pgainspan); - ASSERT(queue->nnodes > 0); - - buckets = queue->buckets; - newnode = queue->nodes+node; - - /* First delete the node */ - if (newnode->prev != NULL) - newnode->prev->next = newnode->next; - else - buckets[oldgain] = newnode->next; - if (newnode->next != NULL) - newnode->next->prev = newnode->prev; - - /* Attach this node in the doubly-linked list */ - newnode->next = buckets[newgain]; - newnode->prev = NULL; - if (newnode->next != NULL) - newnode->next->prev = newnode; - buckets[newgain] = newnode; - - if (queue->maxgain < newgain) - queue->maxgain = newgain; - } - else { /* Heap Priority Queue */ - heap = queue->heap; - locator = queue->locator; - - ASSERT(locator[node] != -1); - ASSERT(heap[locator[node]].val == node); - ASSERT(heap[locator[node]].key == oldgain); - ASSERT(CheckHeap(queue)); - - - /* Here we are just filtering up since the newgain is greater than the oldgain */ - i = locator[node]; - while (i > 0) { - j = (i-1)>>1; - if (heap[j].key < newgain) { - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - - heap[i].key = newgain; - heap[i].val = node; - locator[node] = i; - - ASSERT(CheckHeap(queue)); - } - -} - - -/************************************************************************* -* This function returns the vertex with the largest gain from a partition -* and removes the node from the bucket list -**************************************************************************/ -int PQueueGetMax(PQueueType *queue) -{ - int vtx, i, j, gain, node; - idxtype *locator; - ListNodeType *tptr; - KeyValueType *heap; - - if (queue->nnodes == 0) - return -1; - - queue->nnodes--; - - if (queue->type == 1) { - tptr = queue->buckets[queue->maxgain]; - queue->buckets[queue->maxgain] = tptr->next; - if (tptr->next != NULL) { - tptr->next->prev = NULL; - } - else { - if (queue->nnodes == 0) { - queue->maxgain = -queue->ngainspan; - } - else - for (; queue->buckets[queue->maxgain]==NULL; queue->maxgain--); - } - - return tptr->id; - } - else { - heap = queue->heap; - locator = queue->locator; - - vtx = heap[0].val; - locator[vtx] = -1; - - if ((i = queue->nnodes) > 0) { - gain = heap[i].key; - node = heap[i].val; - i = 0; - while ((j=2*i+1) < queue->nnodes) { - if (heap[j].key > gain) { - if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) - j = j+1; - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else if (j+1 < queue->nnodes && heap[j+1].key > gain) { - j = j+1; - heap[i] = heap[j]; - locator[heap[i].val] = i; - i = j; - } - else - break; - } - - heap[i].key = gain; - heap[i].val = node; - locator[node] = i; - } - - ASSERT(CheckHeap(queue)); - return vtx; - } -} - - -/************************************************************************* -* This function returns the vertex with the largest gain from a partition -**************************************************************************/ -int PQueueSeeMax(PQueueType *queue) -{ - int vtx; - - if (queue->nnodes == 0) - return -1; - - if (queue->type == 1) - vtx = queue->buckets[queue->maxgain]->id; - else - vtx = queue->heap[0].val; - - return vtx; -} - - -/************************************************************************* -* This function returns the vertex with the largest gain from a partition -**************************************************************************/ -int PQueueGetKey(PQueueType *queue) -{ - int key; - - if (queue->nnodes == 0) - return -1; - - if (queue->type == 1) - key = queue->maxgain; - else - key = queue->heap[0].key; - - return key; -} - - - - -/************************************************************************* -* This functions checks the consistency of the heap -**************************************************************************/ -int CheckHeap(PQueueType *queue) -{ - int i, j, nnodes; - idxtype *locator; - KeyValueType *heap; - - heap = queue->heap; - locator = queue->locator; - nnodes = queue->nnodes; - - if (nnodes == 0) - return 1; - - ASSERT(locator[heap[0].val] == 0); - for (i=1; i<nnodes; i++) { - ASSERTP(locator[heap[i].val] == i, ("%d %d %d %d\n", nnodes, i, heap[i].val, locator[heap[i].val])); - ASSERTP(heap[i].key <= heap[(i-1)/2].key, ("%d %d %d %d %d\n", i, (i-1)/2, nnodes, heap[i].key, heap[(i-1)/2].key)); - } - for (i=1; i<nnodes; i++) - ASSERT(heap[i].key <= heap[0].key); - - for (j=i=0; i<queue->maxnodes; i++) { - if (locator[i] != -1) - j++; - } - ASSERTP(j == nnodes, ("%d %d\n", j, nnodes)); - - return 1; -} diff --git a/Metis/proto.h b/Metis/proto.h deleted file mode 100644 index a82e7c9fa5..0000000000 --- a/Metis/proto.h +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * proto.h - * - * This file contains header files - * - * Started 10/19/95 - * George - * - * $Id: proto.h,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -/* balance.c */ -void Balance2Way(CtrlType *, GraphType *, int *, float); -void Bnd2WayBalance(CtrlType *, GraphType *, int *); -void General2WayBalance(CtrlType *, GraphType *, int *); - -/* bucketsort.c */ -void BucketSortKeysInc(int, int, idxtype *, idxtype *, idxtype *); - -/* ccgraph.c */ -void CreateCoarseGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *); -void CreateCoarseGraphNoMask(CtrlType *, GraphType *, int, idxtype *, idxtype *); -void CreateCoarseGraph_NVW(CtrlType *, GraphType *, int, idxtype *, idxtype *); -GraphType *SetUpCoarseGraph(GraphType *, int, int); -void ReAdjustMemory(GraphType *, GraphType *, int); - -/* coarsen.c */ -GraphType *Coarsen2Way(CtrlType *, GraphType *); - -/* compress.c */ -void CompressGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, idxtype *); -void PruneGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, float); - -/* debug.c */ -int ComputeCut(GraphType *, idxtype *); -int CheckBnd(GraphType *); -int CheckBnd2(GraphType *); -int CheckNodeBnd(GraphType *, int); -int CheckRInfo(RInfoType *); -int CheckNodePartitionParams(GraphType *); -int IsSeparable(GraphType *); - -/* estmem.c */ -void METIS_EstimateMemory(int *, idxtype *, idxtype *, int *, int *, int *); -void EstimateCFraction(int, idxtype *, idxtype *, float *, float *); -int ComputeCoarseGraphSize(int, idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *); - -/* fm.c */ -void FM_2WayEdgeRefine(CtrlType *, GraphType *, int *, int); - -/* fortran.c */ -void Change2CNumbering(int, idxtype *, idxtype *); -void Change2FNumbering(int, idxtype *, idxtype *, idxtype *); -void Change2FNumbering2(int, idxtype *, idxtype *); -void Change2FNumberingOrder(int, idxtype *, idxtype *, idxtype *, idxtype *); -void ChangeMesh2CNumbering(int, idxtype *); -void ChangeMesh2FNumbering(int, idxtype *, int, idxtype *, idxtype *); -void ChangeMesh2FNumbering2(int, idxtype *, int, int, idxtype *, idxtype *); - -/* frename.c */ -void METIS_PARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void METIS_PARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void METIS_EDGEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_edgend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_edgend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_edgend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_NODEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_nodend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_nodend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_nodend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_NODEWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_nodewnd(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_nodewnd_(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_nodewnd__(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_PARTMESHNODAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void metis_partmeshnodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void metis_partmeshnodal_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void metis_partmeshnodal__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void METIS_PARTMESHDUAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void metis_partmeshdual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void metis_partmeshdual_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void metis_partmeshdual__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void METIS_MESHTONODAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_meshtonodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_meshtonodal_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_meshtonodal__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_MESHTODUAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_meshtodual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_meshtodual_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void metis_meshtodual__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_ESTIMATEMEMORY(int *, idxtype *, idxtype *, int *, int *, int *); -void metis_estimatememory(int *, idxtype *, idxtype *, int *, int *, int *); -void metis_estimatememory_(int *, idxtype *, idxtype *, int *, int *, int *); -void metis_estimatememory__(int *, idxtype *, idxtype *, int *, int *, int *); -void METIS_MCPARTGRAPHRECURSIVE(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_mcpartgraphrecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_mcpartgraphrecursive_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_mcpartgraphrecursive__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_MCPARTGRAPHKWAY(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_mcpartgraphkway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_mcpartgraphkway_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_mcpartgraphkway__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void METIS_PARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void metis_partgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void metis_wpartgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); - -/* graph.c */ -void SetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int); -void SetUpGraphKway(GraphType *, int, idxtype *, idxtype *); -void SetUpGraph2(GraphType *, int, int, idxtype *, idxtype *, float *, idxtype *); -void VolSetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int); -void RandomizeGraph(GraphType *); -int IsConnectedSubdomain(CtrlType *, GraphType *, int, int); -int IsConnected(CtrlType *, GraphType *, int); -int IsConnected2(GraphType *, int); -int FindComponents(CtrlType *, GraphType *, idxtype *, idxtype *); - -/* initpart.c */ -void Init2WayPartition(CtrlType *, GraphType *, int *, float); -void InitSeparator(CtrlType *, GraphType *, float); -void GrowBisection(CtrlType *, GraphType *, int *, float); -void GrowBisectionNode(CtrlType *, GraphType *, float); -void RandomBisection(CtrlType *, GraphType *, int *, float); - -/* kmetis.c */ -void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -int MlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float); - -/* kvmetis.c */ -void METIS_PartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -int MlevelVolKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float); - -/* kwayfm.c */ -void Random_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int, int); -void Greedy_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int); -void Greedy_KWayEdgeBalance(CtrlType *, GraphType *, int, float *, float, int); - -/* kwayrefine.c */ -void RefineKWay(CtrlType *, GraphType *, GraphType *, int, float *, float); -void AllocateKWayPartitionMemory(CtrlType *, GraphType *, int); -void ComputeKWayPartitionParams(CtrlType *, GraphType *, int); -void ProjectKWayPartition(CtrlType *, GraphType *, int); -int IsBalanced(idxtype *, int, float *, float); -void ComputeKWayBoundary(CtrlType *, GraphType *, int); -void ComputeKWayBalanceBoundary(CtrlType *, GraphType *, int); - -/* kwayvolfm.c */ -void Random_KWayVolRefine(CtrlType *, GraphType *, int, float *, float, int, int); -void Random_KWayVolRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int); -void Greedy_KWayVolBalance(CtrlType *, GraphType *, int, float *, float, int); -void Greedy_KWayVolBalanceMConn(CtrlType *, GraphType *, int, float *, float, int); -void KWayVolUpdate(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *, idxtype *); -void ComputeKWayVolume(GraphType *, int, idxtype *, idxtype *, idxtype *); -int ComputeVolume(GraphType *, idxtype *); -void CheckVolKWayPartitionParams(CtrlType *, GraphType *, int); -void ComputeVolSubDomainGraph(GraphType *, int, idxtype *, idxtype *); -void EliminateVolSubDomainEdges(CtrlType *, GraphType *, int, float *); -void EliminateVolComponents(CtrlType *, GraphType *, int, float *, float); - -/* kwayvolrefine.c */ -void RefineVolKWay(CtrlType *, GraphType *, GraphType *, int, float *, float); -void AllocateVolKWayPartitionMemory(CtrlType *, GraphType *, int); -void ComputeVolKWayPartitionParams(CtrlType *, GraphType *, int); -void ComputeKWayVolGains(CtrlType *, GraphType *, int); -void ProjectVolKWayPartition(CtrlType *, GraphType *, int); -void ComputeVolKWayBoundary(CtrlType *, GraphType *, int); -void ComputeVolKWayBalanceBoundary(CtrlType *, GraphType *, int); - -/* match.c */ -void Match_RM(CtrlType *, GraphType *); -void Match_RM_NVW(CtrlType *, GraphType *); -void Match_HEM(CtrlType *, GraphType *); -void Match_SHEM(CtrlType *, GraphType *); - -/* mbalance.c */ -void MocBalance2Way(CtrlType *, GraphType *, float *, float); -void MocGeneral2WayBalance(CtrlType *, GraphType *, float *, float); - -/* mbalance2.c */ -void MocBalance2Way2(CtrlType *, GraphType *, float *, float *); -void MocGeneral2WayBalance2(CtrlType *, GraphType *, float *, float *); -void SelectQueue3(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *); - -/* mcoarsen.c */ -GraphType *MCCoarsen2Way(CtrlType *, GraphType *); - -/* memory.c */ -void AllocateWorkSpace(CtrlType *, GraphType *, int); -void FreeWorkSpace(CtrlType *, GraphType *); -int WspaceAvail(CtrlType *); -idxtype *idxwspacemalloc(CtrlType *, int); -void idxwspacefree(CtrlType *, int); -float *fwspacemalloc(CtrlType *, int); -void fwspacefree(CtrlType *, int); -GraphType *CreateGraph(void); -void InitGraph(GraphType *); -void FreeGraph(GraphType *); - -/* mesh.c */ -void METIS_MeshToDual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_MeshToNodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); -void GENDUALMETIS(int, int, int, idxtype *, idxtype *, idxtype *adjncy); -void TRINODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); -void TETNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); -void HEXNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); -void QUADNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); - -/* meshpart.c */ -void METIS_PartMeshNodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); -void METIS_PartMeshDual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); - -/* mfm.c */ -void MocFM_2WayEdgeRefine(CtrlType *, GraphType *, float *, int); -void SelectQueue(int, float *, float *, int *, int *, PQueueType [MAXNCON][2]); -int BetterBalance(int, float *, float *, float *); -float Compute2WayHLoadImbalance(int, float *, float *); -void Compute2WayHLoadImbalanceVec(int, float *, float *, float *); - -/* mfm2.c */ -void MocFM_2WayEdgeRefine2(CtrlType *, GraphType *, float *, float *, int); -void SelectQueue2(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *); -int IsBetter2wayBalance(int, float *, float *, float *); - -/* mincover.o */ -void MinCover(idxtype *, idxtype *, int, int, idxtype *, int *); -int MinCover_Augment(idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *, int); -void MinCover_Decompose(idxtype *, idxtype *, int, int, idxtype *, idxtype *, int *); -void MinCover_ColDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int); -void MinCover_RowDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int); - -/* minitpart.c */ -void MocInit2WayPartition(CtrlType *, GraphType *, float *, float); -void MocGrowBisection(CtrlType *, GraphType *, float *, float); -void MocRandomBisection(CtrlType *, GraphType *, float *, float); -void MocInit2WayBalance(CtrlType *, GraphType *, float *); -int SelectQueueoneWay(int, float *, float *, int, PQueueType [MAXNCON][2]); - -/* minitpart2.c */ -void MocInit2WayPartition2(CtrlType *, GraphType *, float *, float *); -void MocGrowBisection2(CtrlType *, GraphType *, float *, float *); -void MocGrowBisectionNew2(CtrlType *, GraphType *, float *, float *); -void MocInit2WayBalance2(CtrlType *, GraphType *, float *, float *); -int SelectQueueOneWay2(int, float *, PQueueType [MAXNCON][2], float *); - -/* mkmetis.c */ -void METIS_mCPartGraphKway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -int MCMlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *); - -/* mkwayfmh.c */ -void MCRandom_KWayEdgeRefineHorizontal(CtrlType *, GraphType *, int, float *, int); -void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *, GraphType *, int, float *, int); -int AreAllHVwgtsBelow(int, float, float *, float, float *, float *); -int AreAllHVwgtsAbove(int, float, float *, float, float *, float *); -void ComputeHKWayLoadImbalance(int, int, float *, float *); -int MocIsHBalanced(int, int, float *, float *); -int IsHBalanceBetterFT(int, int, float *, float *, float *, float *); -int IsHBalanceBetterTT(int, int, float *, float *, float *, float *); - -/* mkwayrefine.c */ -void MocRefineKWayHorizontal(CtrlType *, GraphType *, GraphType *, int, float *); -void MocAllocateKWayPartitionMemory(CtrlType *, GraphType *, int); -void MocComputeKWayPartitionParams(CtrlType *, GraphType *, int); -void MocProjectKWayPartition(CtrlType *, GraphType *, int); -void MocComputeKWayBalanceBoundary(CtrlType *, GraphType *, int); - -/* mmatch.c */ -void MCMatch_RM(CtrlType *, GraphType *); -void MCMatch_HEM(CtrlType *, GraphType *); -void MCMatch_SHEM(CtrlType *, GraphType *); -void MCMatch_SHEBM(CtrlType *, GraphType *, int); -void MCMatch_SBHEM(CtrlType *, GraphType *, int); -float BetterVBalance(int, int, float *, float *, float *); -int AreAllVwgtsBelowFast(int, float *, float *, float); - -/* mmd.c */ -void genmmd(int, idxtype *, idxtype *, idxtype *, idxtype *, int , idxtype *, idxtype *, idxtype *, idxtype *, int, int *); -void mmdelm(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int); -int mmdint(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *); -void mmdnum(int, idxtype *, idxtype *, idxtype *); -void mmdupd(int, int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int *tag); - -/* mpmetis.c */ -void METIS_mCPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_mCHPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void METIS_mCPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, int *, int *, idxtype *); -void METIS_mCHPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, float *, int *, int *, idxtype *); -int MCMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float, int); -int MCHMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, int); -void MCMlevelEdgeBisection(CtrlType *, GraphType *, float *, float); -void MCHMlevelEdgeBisection(CtrlType *, GraphType *, float *, float *); - -/* mrefine.c */ -void MocRefine2Way(CtrlType *, GraphType *, GraphType *, float *, float); -void MocAllocate2WayPartitionMemory(CtrlType *, GraphType *); -void MocCompute2WayPartitionParams(CtrlType *, GraphType *); -void MocProject2WayPartition(CtrlType *, GraphType *); - -/* mrefine2.c */ -void MocRefine2Way2(CtrlType *, GraphType *, GraphType *, float *, float *); - -/* mutil.c */ -int AreAllVwgtsBelow(int, float, float *, float, float *, float); -int AreAnyVwgtsBelow(int, float, float *, float, float *, float); -int AreAllVwgtsAbove(int, float, float *, float, float *, float); -float ComputeLoadImbalance(int, int, float *, float *); -int AreAllBelow(int, float *, float *); - -/* myqsort.c */ -void iidxsort(int, idxtype *); -void iintsort(int, int *); -void ikeysort(int, KeyValueType *); -void ikeyvalsort(int, KeyValueType *); - -/* ometis.c */ -void METIS_EdgeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void METIS_NodeWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); -void MlevelNestedDissection(CtrlType *, GraphType *, idxtype *, float, int); -void MlevelNestedDissectionCC(CtrlType *, GraphType *, idxtype *, float, int); -void MlevelNodeBisectionMultiple(CtrlType *, GraphType *, int *, float); -void MlevelNodeBisection(CtrlType *, GraphType *, int *, float); -void SplitGraphOrder(CtrlType *, GraphType *, GraphType *, GraphType *); -void MMDOrder(CtrlType *, GraphType *, idxtype *, int); -int SplitGraphOrderCC(CtrlType *, GraphType *, GraphType *, int, idxtype *, idxtype *); - -/* parmetis.c */ -void METIS_PartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -void METIS_NodeNDP(int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *); -void MlevelNestedDissectionP(CtrlType *, GraphType *, idxtype *, int, int, int, idxtype *); -void METIS_NodeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); -void METIS_EdgeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); - -/* pmetis.c */ -void METIS_PartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); -void METIS_WPartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); -int MlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, float, int); -void MlevelEdgeBisection(CtrlType *, GraphType *, int *, float); -void SplitGraphPart(CtrlType *, GraphType *, GraphType *, GraphType *); -void SetUpSplitGraph(GraphType *, GraphType *, int, int); - -/* pqueue.c */ -void PQueueInit(CtrlType *ctrl, PQueueType *, int, int); -void PQueueReset(PQueueType *); -void PQueueFree(CtrlType *ctrl, PQueueType *); -int PQueueGetSize(PQueueType *); -int PQueueInsert(PQueueType *, int, int); -int PQueueDelete(PQueueType *, int, int); -int PQueueUpdate(PQueueType *, int, int, int); -void PQueueUpdateUp(PQueueType *, int, int, int); -int PQueueGetMax(PQueueType *); -int PQueueSeeMax(PQueueType *); -int PQueueGetKey(PQueueType *); -int CheckHeap(PQueueType *); - -/* refine.c */ -void Refine2Way(CtrlType *, GraphType *, GraphType *, int *, float ubfactor); -void Allocate2WayPartitionMemory(CtrlType *, GraphType *); -void Compute2WayPartitionParams(CtrlType *, GraphType *); -void Project2WayPartition(CtrlType *, GraphType *); - -/* separator.c */ -void ConstructSeparator(CtrlType *, GraphType *, float); -void ConstructMinCoverSeparator0(CtrlType *, GraphType *, float); -void ConstructMinCoverSeparator(CtrlType *, GraphType *, float); - -/* sfm.c */ -void FM_2WayNodeRefine(CtrlType *, GraphType *, float, int); -void FM_2WayNodeRefineEqWgt(CtrlType *, GraphType *, int); -void FM_2WayNodeRefine_OneSided(CtrlType *, GraphType *, float, int); -void FM_2WayNodeBalance(CtrlType *, GraphType *, float); -int ComputeMaxNodeGain(int, idxtype *, idxtype *, idxtype *); - -/* srefine.c */ -void Refine2WayNode(CtrlType *, GraphType *, GraphType *, float); -void Allocate2WayNodePartitionMemory(CtrlType *, GraphType *); -void Compute2WayNodePartitionParams(CtrlType *, GraphType *); -void Project2WayNodePartition(CtrlType *, GraphType *); - -/* stat.c */ -void ComputePartitionInfo(GraphType *, int, idxtype *); -void ComputePartitionInfoBipartite(GraphType *, int, idxtype *); -void ComputePartitionBalance(GraphType *, int, idxtype *, float *); -float ComputeElementBalance(int, int, idxtype *); - -/* subdomains.c */ -void Random_KWayEdgeRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int); -void Greedy_KWayEdgeBalanceMConn(CtrlType *, GraphType *, int, float *, float, int); -void PrintSubDomainGraph(GraphType *, int, idxtype *); -void ComputeSubDomainGraph(GraphType *, int, idxtype *, idxtype *); -void EliminateSubDomainEdges(CtrlType *, GraphType *, int, float *); -void MoveGroupMConn(CtrlType *, GraphType *, idxtype *, idxtype *, int, int, int, idxtype *); -void EliminateComponents(CtrlType *, GraphType *, int, float *, float); -void MoveGroup(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *); - -/* timing.c */ -void InitTimers(CtrlType *); -void PrintTimers(CtrlType *); -double seconds(void); - -/* util.c */ -void errexit(char *,...); -#ifndef DMALLOC -int *imalloc(int, char *); -idxtype *idxmalloc(int, char *); -float *fmalloc(int, char *); -int *ismalloc(int, int, char *); -idxtype *idxsmalloc(int, idxtype, char *); -void *GKmalloc(int, char *); -#endif -/*void GKfree(void **,...); */ -int *iset(int n, int val, int *x); -idxtype *idxset(int n, idxtype val, idxtype *x); -float *sset(int n, float val, float *x); -int iamax(int, int *); -int idxamax(int, idxtype *); -int idxamax_strd(int, idxtype *, int); -int samax(int, float *); -int samax2(int, float *); -int idxamin(int, idxtype *); -int samin(int, float *); -int idxsum(int, idxtype *); -int idxsum_strd(int, idxtype *, int); -void idxadd(int, idxtype *, idxtype *); -int charsum(int, char *); -int isum(int, int *); -float ssum(int, float *); -float ssum_strd(int n, float *x, int); -void sscale(int n, float, float *x); -float snorm2(int, float *); -float sdot(int n, float *, float *); -void saxpy(int, float, float *, int, float *, int); -void RandomPermute(int, idxtype *, int); -double drand48(); -void srand48(long); -int ispow2(int); -void InitRandom(int); -//int log2(int); - - - - - - - - - - -/*************************************************************** -* Programs Directory -****************************************************************/ - -/* io.c */ -void ReadGraph(GraphType *, char *, int *); -void WritePartition(char *, idxtype *, int, int); -void WriteMeshPartition(char *, int, int, idxtype *, int, idxtype *); -void WritePermutation(char *, idxtype *, int); -int CheckGraph(GraphType *); -idxtype *ReadMesh(char *, int *, int *, int *); -void WriteGraph(char *, int, idxtype *, idxtype *); - -/* smbfactor.c */ -void ComputeFillIn(GraphType *, idxtype *); -idxtype ComputeFillIn2(GraphType *, idxtype *); -int smbfct(int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int *, idxtype *, idxtype *, int *); - - -/*************************************************************** -* Test Directory -****************************************************************/ -void Test_PartGraph(int, idxtype *, idxtype *); -int VerifyPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *); -int VerifyWPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); -void Test_PartGraphV(int, idxtype *, idxtype *); -int VerifyPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *); -int VerifyWPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); -void Test_PartGraphmC(int, idxtype *, idxtype *); -int VerifyPartmC(int, int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); -void Test_ND(int, idxtype *, idxtype *); -int VerifyND(int, idxtype *, idxtype *); - diff --git a/Metis/refine.c b/Metis/refine.c deleted file mode 100644 index 314ec21aaf..0000000000 --- a/Metis/refine.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * refine.c - * - * This file contains the driving routines for multilevel refinement - * - * Started 7/24/97 - * George - * - * $Id: refine.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of refinement -**************************************************************************/ -void Refine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int *tpwgts, float ubfactor) -{ - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - /* Compute the parameters of the coarsest graph */ - Compute2WayPartitionParams(ctrl, graph); - - for (;;) { - ASSERT(CheckBnd(graph)); - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - switch (ctrl->RType) { - case 1: - Balance2Way(ctrl, graph, tpwgts, ubfactor); - FM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); - break; - default: - errexit("Unknown refinement type: %d\n", ctrl->RType); - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - graph = graph->finer; - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - Project2WayPartition(ctrl, graph); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - -/************************************************************************* -* This function allocates memory for 2-way edge refinement -**************************************************************************/ -void Allocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph) -{ - int nvtxs; - - nvtxs = graph->nvtxs; - - graph->rdata = idxmalloc(5*nvtxs+2, "Allocate2WayPartitionMemory: rdata"); - graph->pwgts = graph->rdata; - graph->where = graph->rdata + 2; - graph->id = graph->rdata + nvtxs + 2; - graph->ed = graph->rdata + 2*nvtxs + 2; - graph->bndptr = graph->rdata + 3*nvtxs + 2; - graph->bndind = graph->rdata + 4*nvtxs + 2; -} - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void Compute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) -{ - int i, j, k, l, nvtxs, nbnd, mincut; - idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts; - idxtype *id, *ed, *where; - idxtype *bndptr, *bndind; - int me, other; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = idxset(2, 0, graph->pwgts); - id = idxset(nvtxs, 0, graph->id); - ed = idxset(nvtxs, 0, graph->ed); - bndptr = idxset(nvtxs, -1, graph->bndptr); - bndind = graph->bndind; - - - /*------------------------------------------------------------ - / Compute now the id/ed degrees - /------------------------------------------------------------*/ - nbnd = mincut = 0; - for (i=0; i<nvtxs; i++) { - ASSERT(where[i] >= 0 && where[i] <= 1); - me = where[i]; - pwgts[me] += vwgt[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me == where[adjncy[j]]) - id[i] += adjwgt[j]; - else - ed[i] += adjwgt[j]; - } - - if (ed[i] > 0 || xadj[i] == xadj[i+1]) { - mincut += ed[i]; - bndptr[i] = nbnd; - bndind[nbnd++] = i; - } - } - - graph->mincut = mincut/2; - graph->nbnd = nbnd; - - ASSERT(pwgts[0]+pwgts[1] == idxsum(nvtxs, vwgt)); -} - - - -/************************************************************************* -* This function projects a partition, and at the same time computes the -* parameters for refinement. -**************************************************************************/ -void Project2WayPartition(CtrlType *ctrl, GraphType *graph) -{ - int i, j, k, nvtxs, nbnd, me; - idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; - idxtype *cmap, *where, *id, *ed, *bndptr, *bndind; - idxtype *cwhere, *cid, *ced, *cbndptr; - GraphType *cgraph; - - cgraph = graph->coarser; - cwhere = cgraph->where; - cid = cgraph->id; - ced = cgraph->ed; - cbndptr = cgraph->bndptr; - - nvtxs = graph->nvtxs; - cmap = graph->cmap; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - adjwgtsum = graph->adjwgtsum; - - Allocate2WayPartitionMemory(ctrl, graph); - - where = graph->where; - id = idxset(nvtxs, 0, graph->id); - ed = idxset(nvtxs, 0, graph->ed); - bndptr = idxset(nvtxs, -1, graph->bndptr); - bndind = graph->bndind; - - - /* Go through and project partition and compute id/ed for the nodes */ - for (i=0; i<nvtxs; i++) { - k = cmap[i]; - where[i] = cwhere[k]; - cmap[i] = cbndptr[k]; - } - - for (nbnd=0, i=0; i<nvtxs; i++) { - me = where[i]; - - id[i] = adjwgtsum[i]; - - if (xadj[i] == xadj[i+1]) { - bndptr[i] = nbnd; - bndind[nbnd++] = i; - } - else { - if (cmap[i] != -1) { /* If it is an interface node. Note that cmap[i] = cbndptr[cmap[i]] */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (me != where[adjncy[j]]) - ed[i] += adjwgt[j]; - } - id[i] -= ed[i]; - - if (ed[i] > 0 || xadj[i] == xadj[i+1]) { - bndptr[i] = nbnd; - bndind[nbnd++] = i; - } - } - } - } - - graph->mincut = cgraph->mincut; - graph->nbnd = nbnd; - idxcopy(2, cgraph->pwgts, graph->pwgts); - - FreeGraph(graph->coarser); - graph->coarser = NULL; - -} - diff --git a/Metis/rename.h b/Metis/rename.h deleted file mode 100644 index 74534511a4..0000000000 --- a/Metis/rename.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * rename.h - * - * This file contains header files - * - * Started 10/2/97 - * George - * - * $Id: rename.h,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -/* balance.c */ -#define Balance2Way __Balance2Way -#define Bnd2WayBalance __Bnd2WayBalance -#define General2WayBalance __General2WayBalance - - -/* bucketsort.c */ -#define BucketSortKeysInc __BucketSortKeysInc - - -/* ccgraph.c */ -#define CreateCoarseGraph __CreateCoarseGraph -#define CreateCoarseGraphNoMask __CreateCoarseGraphNoMask -#define CreateCoarseGraph_NVW __CreateCoarseGraph_NVW -#define SetUpCoarseGraph __SetUpCoarseGraph -#define ReAdjustMemory __ReAdjustMemory - - -/* coarsen.c */ -#define Coarsen2Way __Coarsen2Way - - -/* compress.c */ -#define CompressGraph __CompressGraph -#define PruneGraph __PruneGraph - - -/* debug.c */ -#define ComputeCut __ComputeCut -#define CheckBnd __CheckBnd -#define CheckBnd2 __CheckBnd2 -#define CheckNodeBnd __CheckNodeBnd -#define CheckRInfo __CheckRInfo -#define CheckNodePartitionParams __CheckNodePartitionParams -#define IsSeparable __IsSeparable - - -/* estmem.c */ -#define EstimateCFraction __EstimateCFraction -#define ComputeCoarseGraphSize __ComputeCoarseGraphSize - - -/* fm.c */ -#define FM_2WayEdgeRefine __FM_2WayEdgeRefine - - -/* fortran.c */ -#define Change2CNumbering __Change2CNumbering -#define Change2FNumbering __Change2FNumbering -#define Change2FNumbering2 __Change2FNumbering2 -#define Change2FNumberingOrder __Change2FNumberingOrder -#define ChangeMesh2CNumbering __ChangeMesh2CNumbering -#define ChangeMesh2FNumbering __ChangeMesh2FNumbering -#define ChangeMesh2FNumbering2 __ChangeMesh2FNumbering2 - - -/* graph.c */ -#define SetUpGraph __SetUpGraph -#define SetUpGraphKway __SetUpGraphKway -#define SetUpGraph2 __SetUpGraph2 -#define VolSetUpGraph __VolSetUpGraph -#define RandomizeGraph __RandomizeGraph -#define IsConnectedSubdomain __IsConnectedSubdomain -#define IsConnected __IsConnected -#define IsConnected2 __IsConnected2 -#define FindComponents __FindComponents - - -/* initpart.c */ -#define Init2WayPartition __Init2WayPartition -#define InitSeparator __InitSeparator -#define GrowBisection __GrowBisection -#define GrowBisectionNode __GrowBisectionNode -#define RandomBisection __RandomBisection - - -/* kmetis.c */ -#define MlevelKWayPartitioning __MlevelKWayPartitioning - - -/* kvmetis.c */ -#define MlevelVolKWayPartitioning __MlevelVolKWayPartitioning - - -/* kwayfm.c */ -#define Random_KWayEdgeRefine __Random_KWayEdgeRefine -#define Greedy_KWayEdgeRefine __Greedy_KWayEdgeRefine -#define Greedy_KWayEdgeBalance __Greedy_KWayEdgeBalance - - -/* kwayrefine.c */ -#define RefineKWay __RefineKWay -#define AllocateKWayPartitionMemory __AllocateKWayPartitionMemory -#define ComputeKWayPartitionParams __ComputeKWayPartitionParams -#define ProjectKWayPartition __ProjectKWayPartition -#define IsBalanced __IsBalanced -#define ComputeKWayBoundary __ComputeKWayBoundary -#define ComputeKWayBalanceBoundary __ComputeKWayBalanceBoundary - - -/* kwayvolfm.c */ -#define Random_KWayVolRefine __Random_KWayVolRefine -#define Random_KWayVolRefineMConn __Random_KWayVolRefineMConn -#define Greedy_KWayVolBalance __Greedy_KWayVolBalance -#define Greedy_KWayVolBalanceMConn __Greedy_KWayVolBalanceMConn -#define KWayVolUpdate __KWayVolUpdate -#define ComputeKWayVolume __ComputeKWayVolume -#define ComputeVolume __ComputeVolume -#define CheckVolKWayPartitionParams __CheckVolKWayPartitionParams -#define ComputeVolSubDomainGraph __ComputeVolSubDomainGraph -#define EliminateVolSubDomainEdges __EliminateVolSubDomainEdges - - -/* kwayvolrefine.c */ -#define RefineVolKWay __RefineVolKWay -#define AllocateVolKWayPartitionMemory __AllocateVolKWayPartitionMemory -#define ComputeVolKWayPartitionParams __ComputeVolKWayPartitionParams -#define ComputeKWayVolGains __ComputeKWayVolGains -#define ProjectVolKWayPartition __ProjectVolKWayPartition -#define ComputeVolKWayBoundary __ComputeVolKWayBoundary -#define ComputeVolKWayBalanceBoundary __ComputeVolKWayBalanceBoundary - - -/* match.c */ -#define Match_RM __Match_RM -#define Match_RM_NVW __Match_RM_NVW -#define Match_HEM __Match_HEM -#define Match_SHEM __Match_SHEM - - -/* mbalance.c */ -#define MocBalance2Way __MocBalance2Way -#define MocGeneral2WayBalance __MocGeneral2WayBalance - - -/* mbalance2.c */ -#define MocBalance2Way2 __MocBalance2Way2 -#define MocGeneral2WayBalance2 __MocGeneral2WayBalance2 -#define SelectQueue3 __SelectQueue3 - - -/* mcoarsen.c */ -#define MCCoarsen2Way __MCCoarsen2Way - - -/* memory.c */ -#define AllocateWorkSpace __AllocateWorkSpace -#define FreeWorkSpace __FreeWorkSpace -#define WspaceAvail __WspaceAvail -#define idxwspacemalloc __idxwspacemalloc -#define idxwspacefree __idxwspacefree -#define fwspacemalloc __fwspacemalloc -#define CreateGraph __CreateGraph -#define InitGraph __InitGraph -#define FreeGraph __FreeGraph - - -/* mesh.c */ -#define TRIDUALMETIS __TRIDUALMETIS -#define TETDUALMETIS __TETDUALMETIS -#define HEXDUALMETIS __HEXDUALMETIS -#define TRINODALMETIS __TRINODALMETIS -#define TETNODALMETIS __TETNODALMETIS -#define HEXNODALMETIS __HEXNODALMETIS - - -/* mfm.c */ -#define MocFM_2WayEdgeRefine __MocFM_2WayEdgeRefine -#define SelectQueue __SelectQueue -#define BetterBalance __BetterBalance -#define Compute2WayHLoadImbalance __Compute2WayHLoadImbalance -#define Compute2WayHLoadImbalanceVec __Compute2WayHLoadImbalanceVec - - -/* mfm2.c */ -#define MocFM_2WayEdgeRefine2 __MocFM_2WayEdgeRefine2 -#define SelectQueue2 __SelectQueue2 -#define IsBetter2wayBalance __IsBetter2wayBalance - - -/* mincover.c */ -#define MinCover __MinCover -#define MinCover_Augment __MinCover_Augment -#define MinCover_Decompose __MinCover_Decompose -#define MinCover_ColDFS __MinCover_ColDFS -#define MinCover_RowDFS __MinCover_RowDFS - - -/* minitpart.c */ -#define MocInit2WayPartition __MocInit2WayPartition -#define MocGrowBisection __MocGrowBisection -#define MocRandomBisection __MocRandomBisection -#define MocInit2WayBalance __MocInit2WayBalance -#define SelectQueueoneWay __SelectQueueoneWay - - -/* minitpart2.c */ -#define MocInit2WayPartition2 __MocInit2WayPartition2 -#define MocGrowBisection2 __MocGrowBisection2 -#define MocGrowBisectionNew2 __MocGrowBisectionNew2 -#define MocInit2WayBalance2 __MocInit2WayBalance2 -#define SelectQueueOneWay2 __SelectQueueOneWay2 - - -/* mkmetis.c */ -#define MCMlevelKWayPartitioning __MCMlevelKWayPartitioning - - -/* mkwayfmh.c */ -#define MCRandom_KWayEdgeRefineHorizontal __MCRandom_KWayEdgeRefineHorizontal -#define MCGreedy_KWayEdgeBalanceHorizontal __MCGreedy_KWayEdgeBalanceHorizontal -#define AreAllHVwgtsBelow __AreAllHVwgtsBelow -#define AreAllHVwgtsAbove __AreAllHVwgtsAbove -#define ComputeHKWayLoadImbalance __ComputeHKWayLoadImbalance -#define MocIsHBalanced __MocIsHBalanced -#define IsHBalanceBetterFT __IsHBalanceBetterFT -#define IsHBalanceBetterTT __IsHBalanceBetterTT - - -/* mkwayrefine.c */ -#define MocRefineKWayHorizontal __MocRefineKWayHorizontal -#define MocAllocateKWayPartitionMemory __MocAllocateKWayPartitionMemory -#define MocComputeKWayPartitionParams __MocComputeKWayPartitionParams -#define MocProjectKWayPartition __MocProjectKWayPartition -#define MocComputeKWayBalanceBoundary __MocComputeKWayBalanceBoundary - - -/* mmatch.c */ -#define MCMatch_RM __MCMatch_RM -#define MCMatch_HEM __MCMatch_HEM -#define MCMatch_SHEM __MCMatch_SHEM -#define MCMatch_SHEBM __MCMatch_SHEBM -#define MCMatch_SBHEM __MCMatch_SBHEM -#define BetterVBalance __BetterVBalance -#define AreAllVwgtsBelowFast __AreAllVwgtsBelowFast - - -/* mmd.c */ -#define genmmd __genmmd -#define mmdelm __mmdelm -#define mmdint __mmdint -#define mmdnum __mmdnum -#define mmdupd __mmdupd - - -/* mpmetis.c */ -#define MCMlevelRecursiveBisection __MCMlevelRecursiveBisection -#define MCHMlevelRecursiveBisection __MCHMlevelRecursiveBisection -#define MCMlevelEdgeBisection __MCMlevelEdgeBisection -#define MCHMlevelEdgeBisection __MCHMlevelEdgeBisection - - -/* mrefine.c */ -#define MocRefine2Way __MocRefine2Way -#define MocAllocate2WayPartitionMemory __MocAllocate2WayPartitionMemory -#define MocCompute2WayPartitionParams __MocCompute2WayPartitionParams -#define MocProject2WayPartition __MocProject2WayPartition - - -/* mrefine2.c */ -#define MocRefine2Way2 __MocRefine2Way2 - - -/* mutil.c */ -#define AreAllVwgtsBelow __AreAllVwgtsBelow -#define AreAnyVwgtsBelow __AreAnyVwgtsBelow -#define AreAllVwgtsAbove __AreAllVwgtsAbove -#define ComputeLoadImbalance __ComputeLoadImbalance -#define AreAllBelow __AreAllBelow - - -/* myqsort.c */ -#define iidxsort __iidxsort -#define iintsort __iintsort -#define ikeysort __ikeysort -#define ikeyvalsort __ikeyvalsort - - -/* ometis.c */ -#define MlevelNestedDissection __MlevelNestedDissection -#define MlevelNestedDissectionCC __MlevelNestedDissectionCC -#define MlevelNodeBisectionMultiple __MlevelNodeBisectionMultiple -#define MlevelNodeBisection __MlevelNodeBisection -#define SplitGraphOrder __SplitGraphOrder -#define MMDOrder __MMDOrder -#define SplitGraphOrderCC __SplitGraphOrderCC - - -/* parmetis.c */ -#define MlevelNestedDissectionP __MlevelNestedDissectionP - - -/* pmetis.c */ -#define MlevelRecursiveBisection __MlevelRecursiveBisection -#define MlevelEdgeBisection __MlevelEdgeBisection -#define SplitGraphPart __SplitGraphPart -#define SetUpSplitGraph __SetUpSplitGraph - - -/* pqueue.c */ -#define PQueueInit __PQueueInit -#define PQueueReset __PQueueReset -#define PQueueFree __PQueueFree -#define PQueueInsert __PQueueInsert -#define PQueueDelete __PQueueDelete -#define PQueueUpdate __PQueueUpdate -#define PQueueUpdateUp __PQueueUpdateUp -#define PQueueGetMax __PQueueGetMax -#define PQueueSeeMax __PQueueSeeMax -#define CheckHeap __CheckHeap - - -/* refine.c */ -#define Refine2Way __Refine2Way -#define Allocate2WayPartitionMemory __Allocate2WayPartitionMemory -#define Compute2WayPartitionParams __Compute2WayPartitionParams -#define Project2WayPartition __Project2WayPartition - - -/* separator.c */ -#define ConstructSeparator __ConstructSeparator -#define ConstructMinCoverSeparator0 __ConstructMinCoverSeparator0 -#define ConstructMinCoverSeparator __ConstructMinCoverSeparator - - -/* sfm.c */ -#define FM_2WayNodeRefine __FM_2WayNodeRefine -#define FM_2WayNodeRefineEqWgt __FM_2WayNodeRefineEqWgt -#define FM_2WayNodeRefine_OneSided __FM_2WayNodeRefine_OneSided -#define FM_2WayNodeBalance __FM_2WayNodeBalance -#define ComputeMaxNodeGain __ComputeMaxNodeGain - - -/* srefine.c */ -#define Refine2WayNode __Refine2WayNode -#define Allocate2WayNodePartitionMemory __Allocate2WayNodePartitionMemory -#define Compute2WayNodePartitionParams __Compute2WayNodePartitionParams -#define Project2WayNodePartition __Project2WayNodePartition - - -/* stat.c */ -#define ComputePartitionInfo __ComputePartitionInfo -#define ComputePartitionBalance __ComputePartitionBalance -#define ComputeElementBalance __ComputeElementBalance - - -/* subdomains.c */ -#define Random_KWayEdgeRefineMConn __Random_KWayEdgeRefineMConn -#define Greedy_KWayEdgeBalanceMConn __Greedy_KWayEdgeBalanceMConn -#define PrintSubDomainGraph __PrintSubDomainGraph -#define ComputeSubDomainGraph __ComputeSubDomainGraph -#define EliminateSubDomainEdges __EliminateSubDomainEdges -#define MoveGroupMConn __MoveGroupMConn -#define EliminateComponents __EliminateComponents -#define MoveGroup __MoveGroup - - -/* timing.c */ -#define InitTimers __InitTimers -#define PrintTimers __PrintTimers -#define seconds __seconds - - -/* util.c */ -#define errexit __errexit -#define GKfree __GKfree -#ifndef DMALLOC -#define imalloc __imalloc -#define idxmalloc __idxmalloc -#define fmalloc __fmalloc -#define ismalloc __ismalloc -#define idxsmalloc __idxsmalloc -#define GKmalloc __GKmalloc -#endif -#define iset __iset -#define idxset __idxset -#define sset __sset -#define iamax __iamax -#define idxamax __idxamax -#define idxamax_strd __idxamax_strd -#define samax __samax -#define samax2 __samax2 -#define idxamin __idxamin -#define samin __samin -#define idxsum __idxsum -#define idxsum_strd __idxsum_strd -#define idxadd __idxadd -#define charsum __charsum -#define isum __isum -#define ssum __ssum -#define ssum_strd __ssum_strd -#define sscale __sscale -#define snorm2 __snorm2 -#define sdot __sdot -#define saxpy __saxpy -#define RandomPermute __RandomPermute -#define ispow2 __ispow2 -#define InitRandom __InitRandom -#define log2 __log2 - - - - - diff --git a/Metis/separator.c b/Metis/separator.c deleted file mode 100644 index cbabeacb7f..0000000000 --- a/Metis/separator.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * separator.c - * - * This file contains code for separator extraction - * - * Started 8/1/97 - * George - * - * $Id: separator.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - -/************************************************************************* -* This function takes a bisection and constructs a minimum weight vertex -* separator out of it. It uses the node-based separator refinement for it. -**************************************************************************/ -void ConstructSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) -{ - int i, j, k, nvtxs, nbnd; - idxtype *xadj, *where, *bndind; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - nbnd = graph->nbnd; - bndind = graph->bndind; - - where = idxcopy(nvtxs, graph->where, idxwspacemalloc(ctrl, nvtxs)); - - /* Put the nodes in the boundary into the separator */ - for (i=0; i<nbnd; i++) { - j = bndind[i]; - if (xadj[j+1]-xadj[j] > 0) /* Ignore islands */ - where[j] = 2; - } - - GKfree(&graph->rdata, LTERM); - Allocate2WayNodePartitionMemory(ctrl, graph); - idxcopy(nvtxs, where, graph->where); - idxwspacefree(ctrl, nvtxs); - - ASSERT(IsSeparable(graph)); - - Compute2WayNodePartitionParams(ctrl, graph); - - ASSERT(CheckNodePartitionParams(graph)); - - FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); - - ASSERT(IsSeparable(graph)); -} - - - -/************************************************************************* -* This function takes a bisection and constructs a minimum weight vertex -* separator out of it. It uses an unweighted minimum-cover algorithm -* followed by node-based separator refinement. -**************************************************************************/ -void ConstructMinCoverSeparator0(CtrlType *ctrl, GraphType *graph, float ubfactor) -{ - int i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize; - idxtype *xadj, *adjncy, *bxadj, *badjncy; - idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover; - - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - - nbnd = graph->nbnd; - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - - vmap = idxwspacemalloc(ctrl, nvtxs); - ivmap = idxwspacemalloc(ctrl, nbnd); - cover = idxwspacemalloc(ctrl, nbnd); - - if (nbnd > 0) { - /* Go through the boundary and determine the sizes of the bipartite graph */ - bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0; - for (i=0; i<nbnd; i++) { - j = bndind[i]; - k = where[j]; - if (xadj[j+1]-xadj[j] > 0) { - bnvtxs[k]++; - bnedges[k] += xadj[j+1]-xadj[j]; - } - } - - bnvtxs[2] = bnvtxs[0]+bnvtxs[1]; - bnvtxs[1] = bnvtxs[0]; - bnvtxs[0] = 0; - - bxadj = idxmalloc(bnvtxs[2]+1, "ConstructMinCoverSeparator: bxadj"); - badjncy = idxmalloc(bnedges[0]+bnedges[1]+1, "ConstructMinCoverSeparator: badjncy"); - - /* Construct the ivmap and vmap */ - ASSERT(idxset(nvtxs, -1, vmap) == vmap); - for (i=0; i<nbnd; i++) { - j = bndind[i]; - k = where[j]; - if (xadj[j+1]-xadj[j] > 0) { - vmap[j] = bnvtxs[k]; - ivmap[bnvtxs[k]++] = j; - } - } - - /* OK, go through and put the vertices of each part starting from 0 */ - bnvtxs[1] = bnvtxs[0]; - bnvtxs[0] = 0; - bxadj[0] = l = 0; - for (k=0; k<2; k++) { - for (ii=0; ii<nbnd; ii++) { - i = bndind[ii]; - if (where[i] == k && xadj[i] < xadj[i+1]) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - jj = adjncy[j]; - if (where[jj] != k) { - ASSERT(bndptr[jj] != -1); - ASSERTP(vmap[jj] != -1, ("%d %d %d\n", jj, vmap[jj], graph->bndptr[jj])); - badjncy[l++] = vmap[jj]; - } - } - bxadj[++bnvtxs[k]] = l; - } - } - } - - ASSERT(l <= bnedges[0]+bnedges[1]); - - MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize); - - IFSET(ctrl->dbglvl, DBG_SEPINFO, - printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize)); - - for (i=0; i<csize; i++) { - j = ivmap[cover[i]]; - where[j] = 2; - } - - GKfree(&bxadj, &badjncy, LTERM); - - for (i=0; i<nbnd; i++) - bndptr[bndind[i]] = -1; - for (nbnd=i=0; i<nvtxs; i++) { - if (where[i] == 2) { - bndind[nbnd] = i; - bndptr[i] = nbnd++; - } - } - } - else { - IFSET(ctrl->dbglvl, DBG_SEPINFO, - printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, 0, 0, 0)); - } - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, graph->nbnd); - idxwspacefree(ctrl, graph->nbnd); - graph->nbnd = nbnd; - - - ASSERT(IsSeparable(graph)); -} - - - -/************************************************************************* -* This function takes a bisection and constructs a minimum weight vertex -* separator out of it. It uses an unweighted minimum-cover algorithm -* followed by node-based separator refinement. -**************************************************************************/ -void ConstructMinCoverSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) -{ - int i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize; - idxtype *xadj, *adjncy, *bxadj, *badjncy; - idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover; - - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - - nbnd = graph->nbnd; - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - - vmap = idxwspacemalloc(ctrl, nvtxs); - ivmap = idxwspacemalloc(ctrl, nbnd); - cover = idxwspacemalloc(ctrl, nbnd); - - if (nbnd > 0) { - /* Go through the boundary and determine the sizes of the bipartite graph */ - bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0; - for (i=0; i<nbnd; i++) { - j = bndind[i]; - k = where[j]; - if (xadj[j+1]-xadj[j] > 0) { - bnvtxs[k]++; - bnedges[k] += xadj[j+1]-xadj[j]; - } - } - - bnvtxs[2] = bnvtxs[0]+bnvtxs[1]; - bnvtxs[1] = bnvtxs[0]; - bnvtxs[0] = 0; - - bxadj = idxmalloc(bnvtxs[2]+1, "ConstructMinCoverSeparator: bxadj"); - badjncy = idxmalloc(bnedges[0]+bnedges[1]+1, "ConstructMinCoverSeparator: badjncy"); - - /* Construct the ivmap and vmap */ - ASSERT(idxset(nvtxs, -1, vmap) == vmap); - for (i=0; i<nbnd; i++) { - j = bndind[i]; - k = where[j]; - if (xadj[j+1]-xadj[j] > 0) { - vmap[j] = bnvtxs[k]; - ivmap[bnvtxs[k]++] = j; - } - } - - /* OK, go through and put the vertices of each part starting from 0 */ - bnvtxs[1] = bnvtxs[0]; - bnvtxs[0] = 0; - bxadj[0] = l = 0; - for (k=0; k<2; k++) { - for (ii=0; ii<nbnd; ii++) { - i = bndind[ii]; - if (where[i] == k && xadj[i] < xadj[i+1]) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - jj = adjncy[j]; - if (where[jj] != k) { - ASSERT(bndptr[jj] != -1); - ASSERTP(vmap[jj] != -1, ("%d %d %d\n", jj, vmap[jj], graph->bndptr[jj])); - badjncy[l++] = vmap[jj]; - } - } - bxadj[++bnvtxs[k]] = l; - } - } - } - - ASSERT(l <= bnedges[0]+bnedges[1]); - - MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize); - - IFSET(ctrl->dbglvl, DBG_SEPINFO, - printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize)); - - for (i=0; i<csize; i++) { - j = ivmap[cover[i]]; - where[j] = 2; - } - - GKfree(&bxadj, &badjncy, LTERM); - } - else { - IFSET(ctrl->dbglvl, DBG_SEPINFO, - printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, 0, 0, 0)); - } - - /* Prepare to refine the vertex separator */ - idxcopy(nvtxs, graph->where, vmap); - GKfree(&graph->rdata, LTERM); - - Allocate2WayNodePartitionMemory(ctrl, graph); - idxcopy(nvtxs, vmap, graph->where); - idxwspacefree(ctrl, nvtxs+2*graph->nbnd); - - Compute2WayNodePartitionParams(ctrl, graph); - - ASSERT(CheckNodePartitionParams(graph)); - - FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 6); - - ASSERT(IsSeparable(graph)); -} - diff --git a/Metis/sfm.c b/Metis/sfm.c deleted file mode 100644 index 28f1acb874..0000000000 --- a/Metis/sfm.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * sfm.c - * - * This file contains code that implementes an FM-based separator refinement - * - * Started 8/1/97 - * George - * - * $Id: sfm.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs a node-based FM refinement -**************************************************************************/ -void FM_2WayNodeRefine(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses) -{ - int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; - idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; - idxtype *mptr, *mind, *moved, *swaps, *perm; - PQueueType parts[2]; - NRInfoType *rinfo; - int higain, oldgain, mincut, initcut, mincutorder; - int pass, to, other, limit; - int badmaxpwgt, mindiff, newdiff; - int u[2], g[2]; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - pwgts = graph->pwgts; - rinfo = graph->nrinfo; - - - i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt); - PQueueInit(ctrl, &parts[0], nvtxs, i); - PQueueInit(ctrl, &parts[1], nvtxs, i); - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - mptr = idxwspacemalloc(ctrl, nvtxs+1); - mind = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2); - - for (pass=0; pass<npasses; pass++) { - idxset(nvtxs, -1, moved); - PQueueReset(&parts[0]); - PQueueReset(&parts[1]); - - mincutorder = -1; - initcut = mincut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(where[i] == 2); - PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]); - PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]); - } - - ASSERT(CheckNodeBnd(graph, nbnd)); - ASSERT(CheckNodePartitionParams(graph)); - - limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); - - /****************************************************** - * Get into the FM loop - *******************************************************/ - mptr[0] = nmind = 0; - mindiff = abs(pwgts[0]-pwgts[1]); - to = (pwgts[0] < pwgts[1] ? 0 : 1); - for (nswaps=0; nswaps<nvtxs; nswaps++) { - u[0] = PQueueSeeMax(&parts[0]); - u[1] = PQueueSeeMax(&parts[1]); - if (u[0] != -1 && u[1] != -1) { - g[0] = vwgt[u[0]]-rinfo[u[0]].edegrees[1]; - g[1] = vwgt[u[1]]-rinfo[u[1]].edegrees[0]; - - to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); - /* to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : (pwgts[0] < pwgts[1] ? 0 : 1))); */ - - if (pwgts[to]+vwgt[u[to]] > badmaxpwgt) - to = (to+1)%2; - } - else if (u[0] == -1 && u[1] == -1) { - break; - } - else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) { - to = 0; - } - else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) { - to = 1; - } - else - break; - - other = (to+1)%2; - - higain = PQueueGetMax(&parts[to]); - if (moved[higain] == -1) /* Delete if it was in the separator originally */ - PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]); - - ASSERT(bndptr[higain] != -1); - - pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); - - newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); - if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { - mincut = pwgts[2]; - mincutorder = nswaps; - mindiff = newdiff; - } - else { - if (nswaps - mincutorder > limit) { - pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); - break; /* No further improvement, break out */ - } - } - - BNDDelete(nbnd, bndind, bndptr, higain); - pwgts[to] += vwgt[higain]; - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - - /********************************************************** - * Update the degrees of the affected nodes - ***********************************************************/ - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */ - oldgain = vwgt[k]-rinfo[k].edegrees[to]; - rinfo[k].edegrees[to] += vwgt[higain]; - if (moved[k] == -1 || moved[k] == -(2+other)) - PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]); - } - else if (where[k] == other) { /* This vertex is pulled into the separator */ - ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k])); - BNDInsert(nbnd, bndind, bndptr, k); - - mind[nmind++] = k; /* Keep track for rollback */ - where[k] = 2; - pwgts[other] -= vwgt[k]; - - edegrees = rinfo[k].edegrees; - edegrees[0] = edegrees[1] = 0; - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] != 2) - edegrees[where[kk]] += vwgt[kk]; - else { - oldgain = vwgt[kk]-rinfo[kk].edegrees[other]; - rinfo[kk].edegrees[other] -= vwgt[k]; - if (moved[kk] == -1 || moved[kk] == -(2+to)) - PQueueUpdate(&parts[to], kk, oldgain, oldgain+vwgt[k]); - } - } - - /* Insert the new vertex into the priority queue. Only one side! */ - if (moved[k] == -1) { - PQueueInsert(&parts[to], k, vwgt[k]-edegrees[other]); - moved[k] = -(2+to); - } - } - } - mptr[nswaps+1] = nmind; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2])); - - } - - - /**************************************************************** - * Roll back computation - *****************************************************************/ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - ASSERT(CheckNodePartitionParams(graph)); - - to = where[higain]; - other = (to+1)%2; - INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); - where[higain] = 2; - BNDInsert(nbnd, bndind, bndptr, higain); - - edegrees = rinfo[higain].edegrees; - edegrees[0] = edegrees[1] = 0; - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) - rinfo[k].edegrees[to] -= vwgt[higain]; - else - edegrees[where[k]] += vwgt[k]; - } - - /* Push nodes out of the separator */ - for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) { - k = mind[j]; - ASSERT(where[k] == 2); - where[k] = other; - INC_DEC(pwgts[other], pwgts[2], vwgt[k]); - BNDDelete(nbnd, bndind, bndptr, k); - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] == 2) - rinfo[kk].edegrees[other] += vwgt[k]; - } - } - } - - ASSERT(mincut == pwgts[2]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (mincutorder == -1 || mincut >= initcut) - break; - } - - PQueueFree(ctrl, &parts[0]); - PQueueFree(ctrl, &parts[1]); - - idxwspacefree(ctrl, nvtxs+1); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function performs a node-based FM refinement -**************************************************************************/ -void FM_2WayNodeRefine2(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses) -{ - int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; - idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; - idxtype *mptr, *mind, *moved, *swaps, *perm; - PQueueType parts[2]; - NRInfoType *rinfo; - int higain, oldgain, mincut, initcut, mincutorder; - int pass, to, other, limit; - int badmaxpwgt, mindiff, newdiff; - int u[2], g[2]; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - pwgts = graph->pwgts; - rinfo = graph->nrinfo; - - - i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt); - PQueueInit(ctrl, &parts[0], nvtxs, i); - PQueueInit(ctrl, &parts[1], nvtxs, i); - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - mptr = idxwspacemalloc(ctrl, nvtxs+1); - mind = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2); - - for (pass=0; pass<npasses; pass++) { - idxset(nvtxs, -1, moved); - PQueueReset(&parts[0]); - PQueueReset(&parts[1]); - - mincutorder = -1; - initcut = mincut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(where[i] == 2); - PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]); - PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]); - } - - ASSERT(CheckNodeBnd(graph, nbnd)); - ASSERT(CheckNodePartitionParams(graph)); - - limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); - - /****************************************************** - * Get into the FM loop - *******************************************************/ - mptr[0] = nmind = 0; - mindiff = abs(pwgts[0]-pwgts[1]); - to = (pwgts[0] < pwgts[1] ? 0 : 1); - for (nswaps=0; nswaps<nvtxs; nswaps++) { - badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2]/2)/2); - - u[0] = PQueueSeeMax(&parts[0]); - u[1] = PQueueSeeMax(&parts[1]); - if (u[0] != -1 && u[1] != -1) { - g[0] = vwgt[u[0]]-rinfo[u[0]].edegrees[1]; - g[1] = vwgt[u[1]]-rinfo[u[1]].edegrees[0]; - - to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); - /* to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : (pwgts[0] < pwgts[1] ? 0 : 1))); */ - - if (pwgts[to]+vwgt[u[to]] > badmaxpwgt) - to = (to+1)%2; - } - else if (u[0] == -1 && u[1] == -1) { - break; - } - else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) { - to = 0; - } - else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) { - to = 1; - } - else - break; - - other = (to+1)%2; - - higain = PQueueGetMax(&parts[to]); - if (moved[higain] == -1) /* Delete if it was in the separator originally */ - PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]); - - ASSERT(bndptr[higain] != -1); - - pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); - - newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); - if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { - mincut = pwgts[2]; - mincutorder = nswaps; - mindiff = newdiff; - } - else { - if (nswaps - mincutorder > limit) { - pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); - break; /* No further improvement, break out */ - } - } - - BNDDelete(nbnd, bndind, bndptr, higain); - pwgts[to] += vwgt[higain]; - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - - /********************************************************** - * Update the degrees of the affected nodes - ***********************************************************/ - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */ - oldgain = vwgt[k]-rinfo[k].edegrees[to]; - rinfo[k].edegrees[to] += vwgt[higain]; - if (moved[k] == -1 || moved[k] == -(2+other)) - PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]); - } - else if (where[k] == other) { /* This vertex is pulled into the separator */ - ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k])); - BNDInsert(nbnd, bndind, bndptr, k); - - mind[nmind++] = k; /* Keep track for rollback */ - where[k] = 2; - pwgts[other] -= vwgt[k]; - - edegrees = rinfo[k].edegrees; - edegrees[0] = edegrees[1] = 0; - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] != 2) - edegrees[where[kk]] += vwgt[kk]; - else { - oldgain = vwgt[kk]-rinfo[kk].edegrees[other]; - rinfo[kk].edegrees[other] -= vwgt[k]; - if (moved[kk] == -1 || moved[kk] == -(2+to)) - PQueueUpdate(&parts[to], kk, oldgain, oldgain+vwgt[k]); - } - } - - /* Insert the new vertex into the priority queue. Only one side! */ - if (moved[k] == -1) { - PQueueInsert(&parts[to], k, vwgt[k]-edegrees[other]); - moved[k] = -(2+to); - } - } - } - mptr[nswaps+1] = nmind; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2])); - - } - - - /**************************************************************** - * Roll back computation - *****************************************************************/ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - ASSERT(CheckNodePartitionParams(graph)); - - to = where[higain]; - other = (to+1)%2; - INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); - where[higain] = 2; - BNDInsert(nbnd, bndind, bndptr, higain); - - edegrees = rinfo[higain].edegrees; - edegrees[0] = edegrees[1] = 0; - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) - rinfo[k].edegrees[to] -= vwgt[higain]; - else - edegrees[where[k]] += vwgt[k]; - } - - /* Push nodes out of the separator */ - for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) { - k = mind[j]; - ASSERT(where[k] == 2); - where[k] = other; - INC_DEC(pwgts[other], pwgts[2], vwgt[k]); - BNDDelete(nbnd, bndind, bndptr, k); - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] == 2) - rinfo[kk].edegrees[other] += vwgt[k]; - } - } - } - - ASSERT(mincut == pwgts[2]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (mincutorder == -1 || mincut >= initcut) - break; - } - - PQueueFree(ctrl, &parts[0]); - PQueueFree(ctrl, &parts[1]); - - idxwspacefree(ctrl, nvtxs+1); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function performs a node-based FM refinement -**************************************************************************/ -void FM_2WayNodeRefineEqWgt(CtrlType *ctrl, GraphType *graph, int npasses) -{ - int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; - idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; - idxtype *mptr, *mind, *moved, *swaps, *perm; - PQueueType parts[2]; - NRInfoType *rinfo; - int higain, oldgain, mincut, initcut, mincutorder; - int pass, to, other, limit; - int mindiff, newdiff; - int u[2], g[2]; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - pwgts = graph->pwgts; - rinfo = graph->nrinfo; - - - i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt); - PQueueInit(ctrl, &parts[0], nvtxs, i); - PQueueInit(ctrl, &parts[1], nvtxs, i); - - moved = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - mptr = idxwspacemalloc(ctrl, nvtxs+1); - mind = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - for (pass=0; pass<npasses; pass++) { - idxset(nvtxs, -1, moved); - PQueueReset(&parts[0]); - PQueueReset(&parts[1]); - - mincutorder = -1; - initcut = mincut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(where[i] == 2); - PQueueInsert(&parts[0], i, vwgt[i]-rinfo[i].edegrees[1]); - PQueueInsert(&parts[1], i, vwgt[i]-rinfo[i].edegrees[0]); - } - - ASSERT(CheckNodeBnd(graph, nbnd)); - ASSERT(CheckNodePartitionParams(graph)); - - limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); - - /****************************************************** - * Get into the FM loop - *******************************************************/ - mptr[0] = nmind = 0; - mindiff = abs(pwgts[0]-pwgts[1]); - to = (pwgts[0] < pwgts[1] ? 0 : 1); - for (nswaps=0; nswaps<nvtxs; nswaps++) { - to = (pwgts[0] < pwgts[1] ? 0 : 1); - - if (pwgts[0] == pwgts[1]) { - u[0] = PQueueSeeMax(&parts[0]); - u[1] = PQueueSeeMax(&parts[1]); - if (u[0] != -1 && u[1] != -1) { - g[0] = vwgt[u[0]]-rinfo[u[0]].edegrees[1]; - g[1] = vwgt[u[1]]-rinfo[u[1]].edegrees[0]; - - to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); - } - } - other = (to+1)%2; - - if ((higain = PQueueGetMax(&parts[to])) == -1) - break; - - if (moved[higain] == -1) /* Delete if it was in the separator originally */ - PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]); - - ASSERT(bndptr[higain] != -1); - - pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); - - newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); - if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { - mincut = pwgts[2]; - mincutorder = nswaps; - mindiff = newdiff; - } - else { - if (nswaps - mincutorder > limit) { - pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); - break; /* No further improvement, break out */ - } - } - - BNDDelete(nbnd, bndind, bndptr, higain); - pwgts[to] += vwgt[higain]; - where[higain] = to; - moved[higain] = nswaps; - swaps[nswaps] = higain; - - - /********************************************************** - * Update the degrees of the affected nodes - ***********************************************************/ - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */ - oldgain = vwgt[k]-rinfo[k].edegrees[to]; - rinfo[k].edegrees[to] += vwgt[higain]; - if (moved[k] == -1 || moved[k] == -(2+other)) - PQueueUpdate(&parts[other], k, oldgain, oldgain-vwgt[higain]); - } - else if (where[k] == other) { /* This vertex is pulled into the separator */ - ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k])); - BNDInsert(nbnd, bndind, bndptr, k); - - mind[nmind++] = k; /* Keep track for rollback */ - where[k] = 2; - pwgts[other] -= vwgt[k]; - - edegrees = rinfo[k].edegrees; - edegrees[0] = edegrees[1] = 0; - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] != 2) - edegrees[where[kk]] += vwgt[kk]; - else { - oldgain = vwgt[kk]-rinfo[kk].edegrees[other]; - rinfo[kk].edegrees[other] -= vwgt[k]; - if (moved[kk] == -1 || moved[kk] == -(2+to)) - PQueueUpdate(&parts[to], kk, oldgain, oldgain+vwgt[k]); - } - } - - /* Insert the new vertex into the priority queue. Only one side! */ - if (moved[k] == -1) { - PQueueInsert(&parts[to], k, vwgt[k]-edegrees[other]); - moved[k] = -(2+to); - } - } - } - mptr[nswaps+1] = nmind; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2])); - - } - - - /**************************************************************** - * Roll back computation - *****************************************************************/ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - ASSERT(CheckNodePartitionParams(graph)); - - to = where[higain]; - other = (to+1)%2; - INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); - where[higain] = 2; - BNDInsert(nbnd, bndind, bndptr, higain); - - edegrees = rinfo[higain].edegrees; - edegrees[0] = edegrees[1] = 0; - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) - rinfo[k].edegrees[to] -= vwgt[higain]; - else - edegrees[where[k]] += vwgt[k]; - } - - /* Push nodes out of the separator */ - for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) { - k = mind[j]; - ASSERT(where[k] == 2); - where[k] = other; - INC_DEC(pwgts[other], pwgts[2], vwgt[k]); - BNDDelete(nbnd, bndind, bndptr, k); - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] == 2) - rinfo[kk].edegrees[other] += vwgt[k]; - } - } - } - - ASSERT(mincut == pwgts[2]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (mincutorder == -1 || mincut >= initcut) - break; - } - - PQueueFree(ctrl, &parts[0]); - PQueueFree(ctrl, &parts[1]); - - idxwspacefree(ctrl, nvtxs+1); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function performs a node-based FM refinement. This is the -* one-way version -**************************************************************************/ -void FM_2WayNodeRefine_OneSided(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses) -{ - int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; - idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; - idxtype *mptr, *mind, *swaps, *perm; - PQueueType parts; - NRInfoType *rinfo; - int higain, oldgain, mincut, initcut, mincutorder; - int pass, to, other, limit; - int badmaxpwgt, mindiff, newdiff; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - pwgts = graph->pwgts; - rinfo = graph->nrinfo; - - PQueueInit(ctrl, &parts, nvtxs, ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt)); - - perm = idxwspacemalloc(ctrl, nvtxs); - swaps = idxwspacemalloc(ctrl, nvtxs); - mptr = idxwspacemalloc(ctrl, nvtxs); - mind = idxwspacemalloc(ctrl, nvtxs+1); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions-N1: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2); - - to = (pwgts[0] < pwgts[1] ? 1 : 0); - for (pass=0; pass<npasses; pass++) { - other = to; - to = (to+1)%2; - - PQueueReset(&parts); - - mincutorder = -1; - initcut = mincut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(where[i] == 2); - PQueueInsert(&parts, i, vwgt[i]-rinfo[i].edegrees[other]); - } - - ASSERT(CheckNodeBnd(graph, nbnd)); - ASSERT(CheckNodePartitionParams(graph)); - - limit = (ctrl->oflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); - - /****************************************************** - * Get into the FM loop - *******************************************************/ - mptr[0] = nmind = 0; - mindiff = abs(pwgts[0]-pwgts[1]); - for (nswaps=0; nswaps<nvtxs; nswaps++) { - - if ((higain = PQueueGetMax(&parts)) == -1) - break; - - ASSERT(bndptr[higain] != -1); - - if (pwgts[to]+vwgt[higain] > badmaxpwgt) - break; /* No point going any further. Balance will be bad */ - - pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); - - newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); - if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { - mincut = pwgts[2]; - mincutorder = nswaps; - mindiff = newdiff; - } - else { - if (nswaps - mincutorder > limit) { - pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); - break; /* No further improvement, break out */ - } - } - - BNDDelete(nbnd, bndind, bndptr, higain); - pwgts[to] += vwgt[higain]; - where[higain] = to; - swaps[nswaps] = higain; - - - /********************************************************** - * Update the degrees of the affected nodes - ***********************************************************/ - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */ - rinfo[k].edegrees[to] += vwgt[higain]; - } - else if (where[k] == other) { /* This vertex is pulled into the separator */ - ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k])); - BNDInsert(nbnd, bndind, bndptr, k); - - mind[nmind++] = k; /* Keep track for rollback */ - where[k] = 2; - pwgts[other] -= vwgt[k]; - - edegrees = rinfo[k].edegrees; - edegrees[0] = edegrees[1] = 0; - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] != 2) - edegrees[where[kk]] += vwgt[kk]; - else { - oldgain = vwgt[kk]-rinfo[kk].edegrees[other]; - rinfo[kk].edegrees[other] -= vwgt[k]; - - /* Since the moves are one-sided this vertex has not been moved yet */ - PQueueUpdateUp(&parts, kk, oldgain, oldgain+vwgt[k]); - } - } - - /* Insert the new vertex into the priority queue. Safe due to one-sided moves */ - PQueueInsert(&parts, k, vwgt[k]-edegrees[other]); - } - } - mptr[nswaps+1] = nmind; - - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d to %3d, Gain: %5d [%5d] \t[%5d %5d %5d] [%3d %2d]\n", - higain, to, (vwgt[higain]-rinfo[higain].edegrees[other]), vwgt[higain], pwgts[0], pwgts[1], pwgts[2], nswaps, limit)); - - } - - - /**************************************************************** - * Roll back computation - *****************************************************************/ - for (nswaps--; nswaps>mincutorder; nswaps--) { - higain = swaps[nswaps]; - - ASSERT(CheckNodePartitionParams(graph)); - ASSERT(where[higain] == to); - - INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); - where[higain] = 2; - BNDInsert(nbnd, bndind, bndptr, higain); - - edegrees = rinfo[higain].edegrees; - edegrees[0] = edegrees[1] = 0; - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) - rinfo[k].edegrees[to] -= vwgt[higain]; - else - edegrees[where[k]] += vwgt[k]; - } - - /* Push nodes out of the separator */ - for (j=mptr[nswaps]; j<mptr[nswaps+1]; j++) { - k = mind[j]; - ASSERT(where[k] == 2); - where[k] = other; - INC_DEC(pwgts[other], pwgts[2], vwgt[k]); - BNDDelete(nbnd, bndind, bndptr, k); - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] == 2) - rinfo[kk].edegrees[other] += vwgt[k]; - } - } - } - - ASSERT(mincut == pwgts[2]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = mincut; - graph->nbnd = nbnd; - - if (pass%2 == 1 && (mincutorder == -1 || mincut >= initcut)) - break; - } - - PQueueFree(ctrl, &parts); - - idxwspacefree(ctrl, nvtxs+1); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function performs a node-based FM refinement -**************************************************************************/ -void FM_2WayNodeBalance(CtrlType *ctrl, GraphType *graph, float ubfactor) -{ - int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps; - idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; - idxtype *perm, *moved; - PQueueType parts; - NRInfoType *rinfo; - int higain, oldgain; - int pass, to, other; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - where = graph->where; - pwgts = graph->pwgts; - rinfo = graph->nrinfo; - - if (abs(pwgts[0]-pwgts[1]) < (int)((ubfactor-1.0)*(pwgts[0]+pwgts[1]))) - return; - if (abs(pwgts[0]-pwgts[1]) < 3*idxsum(nvtxs, vwgt)/nvtxs) - return; - - to = (pwgts[0] < pwgts[1] ? 0 : 1); - other = (to+1)%2; - - PQueueInit(ctrl, &parts, nvtxs, ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt)); - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxset(nvtxs, -1, idxwspacemalloc(ctrl, nvtxs)); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d [B]\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); - - nbnd = graph->nbnd; - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - ASSERT(where[i] == 2); - PQueueInsert(&parts, i, vwgt[i]-rinfo[i].edegrees[other]); - } - - ASSERT(CheckNodeBnd(graph, nbnd)); - ASSERT(CheckNodePartitionParams(graph)); - - /****************************************************** - * Get into the FM loop - *******************************************************/ - for (nswaps=0; nswaps<nvtxs; nswaps++) { - if ((higain = PQueueGetMax(&parts)) == -1) - break; - - moved[higain] = 1; - - if (pwgts[other] - rinfo[higain].edegrees[other] < (pwgts[0]+pwgts[1])/2) - continue; -#ifdef XXX - if (pwgts[other] - rinfo[higain].edegrees[other] < pwgts[to]+vwgt[higain]) - break; -#endif - - ASSERT(bndptr[higain] != -1); - - pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); - - BNDDelete(nbnd, bndind, bndptr, higain); - pwgts[to] += vwgt[higain]; - where[higain] = to; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, - printf("Moved %6d to %3d, Gain: %3d, \t[%5d %5d %5d]\n", higain, to, vwgt[higain]-rinfo[higain].edegrees[other], pwgts[0], pwgts[1], pwgts[2])); - - - /********************************************************** - * Update the degrees of the affected nodes - ***********************************************************/ - for (j=xadj[higain]; j<xadj[higain+1]; j++) { - k = adjncy[j]; - if (where[k] == 2) { /* For the in-separator vertices modify their edegree[to] */ - rinfo[k].edegrees[to] += vwgt[higain]; - } - else if (where[k] == other) { /* This vertex is pulled into the separator */ - ASSERTP(bndptr[k] == -1, ("%d %d %d\n", k, bndptr[k], where[k])); - BNDInsert(nbnd, bndind, bndptr, k); - - where[k] = 2; - pwgts[other] -= vwgt[k]; - - edegrees = rinfo[k].edegrees; - edegrees[0] = edegrees[1] = 0; - for (jj=xadj[k]; jj<xadj[k+1]; jj++) { - kk = adjncy[jj]; - if (where[kk] != 2) - edegrees[where[kk]] += vwgt[kk]; - else { - ASSERT(bndptr[kk] != -1); - oldgain = vwgt[kk]-rinfo[kk].edegrees[other]; - rinfo[kk].edegrees[other] -= vwgt[k]; - - if (moved[kk] == -1) - PQueueUpdateUp(&parts, kk, oldgain, oldgain+vwgt[k]); - } - } - - /* Insert the new vertex into the priority queue */ - PQueueInsert(&parts, k, vwgt[k]-edegrees[other]); - } - } - - if (pwgts[to] > pwgts[other]) - break; - } - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\tBalanced sep: %6d at %4d, PWGTS: [%6d %6d], NBND: %6d\n", pwgts[2], nswaps, pwgts[0], pwgts[1], nbnd)); - - graph->mincut = pwgts[2]; - graph->nbnd = nbnd; - - - PQueueFree(ctrl, &parts); - - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); -} - - -/************************************************************************* -* This function computes the maximum possible gain for a vertex -**************************************************************************/ -int ComputeMaxNodeGain(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt) -{ - int i, j, k, max; - - max = 0; - for (j=xadj[0]; j<xadj[1]; j++) - max += vwgt[adjncy[j]]; - - for (i=1; i<nvtxs; i++) { - for (k=0, j=xadj[i]; j<xadj[i+1]; j++) - k += vwgt[adjncy[j]]; - if (max < k) - max = k; - } - - return max; -} - - diff --git a/Metis/srefine.c b/Metis/srefine.c deleted file mode 100644 index a0cf88d101..0000000000 --- a/Metis/srefine.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * srefine.c - * - * This file contains code for the separator refinement algortihms - * - * Started 8/1/97 - * George - * - * $Id: srefine.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function is the entry point of the separator refinement -**************************************************************************/ -void Refine2WayNode(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float ubfactor) -{ - - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); - - for (;;) { - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); - if (ctrl->RType != 15) - FM_2WayNodeBalance(ctrl, graph, ubfactor); - - switch (ctrl->RType) { - case 1: - FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); - break; - case 2: - FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); - break; - case 3: - FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); - FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); - break; - case 4: - FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); - FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); - break; - case 5: - FM_2WayNodeRefineEqWgt(ctrl, graph, 8); - break; - } - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); - - if (graph == orggraph) - break; - - graph = graph->finer; - IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); - Project2WayNodePartition(ctrl, graph); - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); - } - - IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); -} - - -/************************************************************************* -* This function allocates memory for 2-way edge refinement -**************************************************************************/ -void Allocate2WayNodePartitionMemory(CtrlType *ctrl, GraphType *graph) -{ - int nvtxs, pad64; - - nvtxs = graph->nvtxs; - - pad64 = (3*nvtxs+3)%2; - - graph->rdata = idxmalloc(3*nvtxs+3+(sizeof(NRInfoType)/sizeof(idxtype))*nvtxs+pad64, "Allocate2WayPartitionMemory: rdata"); - graph->pwgts = graph->rdata; - graph->where = graph->rdata + 3; - graph->bndptr = graph->rdata + nvtxs + 3; - graph->bndind = graph->rdata + 2*nvtxs + 3; - graph->nrinfo = (NRInfoType *)(graph->rdata + 3*nvtxs + 3 + pad64); -} - - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void Compute2WayNodePartitionParams(CtrlType *ctrl, GraphType *graph) -{ - int i, j, k, l, nvtxs, nbnd; - idxtype *xadj, *adjncy, *adjwgt, *vwgt; - idxtype *where, *pwgts, *bndind, *bndptr, *edegrees; - NRInfoType *rinfo; - int me, other; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - vwgt = graph->vwgt; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - rinfo = graph->nrinfo; - pwgts = idxset(3, 0, graph->pwgts); - bndind = graph->bndind; - bndptr = idxset(nvtxs, -1, graph->bndptr); - - - /*------------------------------------------------------------ - / Compute now the separator external degrees - /------------------------------------------------------------*/ - nbnd = 0; - for (i=0; i<nvtxs; i++) { - me = where[i]; - pwgts[me] += vwgt[i]; - - ASSERT(me >=0 && me <= 2); - - if (me == 2) { /* If it is on the separator do some computations */ - BNDInsert(nbnd, bndind, bndptr, i); - - edegrees = rinfo[i].edegrees; - edegrees[0] = edegrees[1] = 0; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - other = where[adjncy[j]]; - if (other != 2) - edegrees[other] += vwgt[adjncy[j]]; - } - } - } - - ASSERT(CheckNodeBnd(graph, nbnd)); - - graph->mincut = pwgts[2]; - graph->nbnd = nbnd; -} - - -/************************************************************************* -* This function computes the initial id/ed -**************************************************************************/ -void Project2WayNodePartition(CtrlType *ctrl, GraphType *graph) -{ - int i, j, nvtxs; - idxtype *cmap, *where, *cwhere; - GraphType *cgraph; - - cgraph = graph->coarser; - cwhere = cgraph->where; - - nvtxs = graph->nvtxs; - cmap = graph->cmap; - - Allocate2WayNodePartitionMemory(ctrl, graph); - where = graph->where; - - /* Project the partition */ - for (i=0; i<nvtxs; i++) { - where[i] = cwhere[cmap[i]]; - ASSERTP(where[i] >= 0 && where[i] <= 2, ("%d %d %d %d\n", i, cmap[i], where[i], cwhere[cmap[i]])); - } - - FreeGraph(graph->coarser); - graph->coarser = NULL; - - Compute2WayNodePartitionParams(ctrl, graph); -} diff --git a/Metis/stat.c b/Metis/stat.c deleted file mode 100644 index 74d22e9989..0000000000 --- a/Metis/stat.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * stat.c - * - * This file computes various statistics - * - * Started 7/25/97 - * George - * - * $Id: stat.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function computes cuts and balance information -**************************************************************************/ -void ComputePartitionInfo(GraphType *graph, int nparts, idxtype *where) -{ - int i, j, k, nvtxs, ncon, mustfree=0; - idxtype *xadj, *adjncy, *vwgt, *adjwgt, *kpwgts, *tmpptr; - idxtype *padjncy, *padjwgt, *padjcut; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - adjwgt = graph->adjwgt; - - if (vwgt == NULL) { - vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt"); - mustfree = 1; - } - if (adjwgt == NULL) { - adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt"); - mustfree += 2; - } - - printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where)); - - /* Compute balance information */ - kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts"); - - for (i=0; i<nvtxs; i++) { - for (j=0; j<ncon; j++) - kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j]; - } - - if (ncon == 1) { - printf("\tBalance: %5.3f out of %5.3f\n", - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), - 1.0*nparts*vwgt[idxamax(nvtxs, vwgt)]/(1.0*idxsum(nparts, kpwgts))); - } - else { - printf("\tBalance:"); - for (j=0; j<ncon; j++) - printf(" (%5.3f out of %5.3f)", - 1.0*nparts*kpwgts[ncon*idxamax_strd(nparts, kpwgts+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)), - 1.0*nparts*vwgt[ncon*idxamax_strd(nvtxs, vwgt+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon))); - printf("\n"); - } - - - /* Compute p-adjncy information */ - padjncy = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjncy"); - padjwgt = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt"); - padjcut = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt"); - - idxset(nparts, 0, kpwgts); - for (i=0; i<nvtxs; i++) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (where[i] != where[adjncy[j]]) { - padjncy[where[i]*nparts+where[adjncy[j]]] = 1; - padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j]; - if (kpwgts[where[adjncy[j]]] == 0) { - padjwgt[where[i]*nparts+where[adjncy[j]]]++; - kpwgts[where[adjncy[j]]] = 1; - } - } - } - for (j=xadj[i]; j<xadj[i+1]; j++) - kpwgts[where[adjncy[j]]] = 0; - } - - for (i=0; i<nparts; i++) - kpwgts[i] = idxsum(nparts, padjncy+i*nparts); - printf("Min/Max/Avg/Bal # of adjacent subdomains: %5d %5d %5.2f %7.3f\n", - kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], - 1.0*idxsum(nparts, kpwgts)/(1.0*nparts), - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts))); - - for (i=0; i<nparts; i++) - kpwgts[i] = idxsum(nparts, padjcut+i*nparts); - printf("Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n", - kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts))); - - for (i=0; i<nparts; i++) - kpwgts[i] = idxsum(nparts, padjwgt+i*nparts); - printf("Min/Max/Avg/Bal/Frac # of interface nodes: %5d %5d %5d %7.3f %7.3f\n", - kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), 1.0*idxsum(nparts, kpwgts)/(1.0*nvtxs)); - - tmpptr = graph->where; - graph->where = where; - for (i=0; i<nparts; i++) - IsConnectedSubdomain(NULL, graph, i, 1); - graph->where = tmpptr; - - if (mustfree == 1 || mustfree == 3) { - free(vwgt); - graph->vwgt = NULL; - } - if (mustfree == 2 || mustfree == 3) { - free(adjwgt); - graph->adjwgt = NULL; - } - - GKfree(&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM); -} - - -/************************************************************************* -* This function computes cuts and balance information -**************************************************************************/ -void ComputePartitionInfoBipartite(GraphType *graph, int nparts, idxtype *where) -{ - int i, j, k, nvtxs, ncon, mustfree=0; - idxtype *xadj, *adjncy, *vwgt, *vsize, *adjwgt, *kpwgts, *tmpptr; - idxtype *padjncy, *padjwgt, *padjcut; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - vsize = graph->vsize; - adjwgt = graph->adjwgt; - - if (vwgt == NULL) { - vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt"); - mustfree = 1; - } - if (adjwgt == NULL) { - adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt"); - mustfree += 2; - } - - printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where)); - - /* Compute balance information */ - kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts"); - - for (i=0; i<nvtxs; i++) { - for (j=0; j<ncon; j++) - kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j]; - } - - if (ncon == 1) { - printf("\tBalance: %5.3f out of %5.3f\n", - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), - 1.0*nparts*vwgt[idxamax(nvtxs, vwgt)]/(1.0*idxsum(nparts, kpwgts))); - } - else { - printf("\tBalance:"); - for (j=0; j<ncon; j++) - printf(" (%5.3f out of %5.3f)", - 1.0*nparts*kpwgts[ncon*idxamax_strd(nparts, kpwgts+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)), - 1.0*nparts*vwgt[ncon*idxamax_strd(nvtxs, vwgt+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon))); - printf("\n"); - } - - - /* Compute p-adjncy information */ - padjncy = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjncy"); - padjwgt = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt"); - padjcut = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt"); - - idxset(nparts, 0, kpwgts); - for (i=0; i<nvtxs; i++) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (where[i] != where[adjncy[j]]) { - padjncy[where[i]*nparts+where[adjncy[j]]] = 1; - padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j]; - if (kpwgts[where[adjncy[j]]] == 0) { - padjwgt[where[i]*nparts+where[adjncy[j]]] += vsize[i]; - kpwgts[where[adjncy[j]]] = 1; - } - } - } - for (j=xadj[i]; j<xadj[i+1]; j++) - kpwgts[where[adjncy[j]]] = 0; - } - - for (i=0; i<nparts; i++) - kpwgts[i] = idxsum(nparts, padjncy+i*nparts); - printf("Min/Max/Avg/Bal # of adjacent subdomains: %5d %5d %5d %7.3f\n", - kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts))); - - for (i=0; i<nparts; i++) - kpwgts[i] = idxsum(nparts, padjcut+i*nparts); - printf("Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n", - kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts))); - - for (i=0; i<nparts; i++) - kpwgts[i] = idxsum(nparts, padjwgt+i*nparts); - printf("Min/Max/Avg/Bal/Frac # of interface nodes: %5d %5d %5d %7.3f %7.3f\n", - kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, - 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), 1.0*idxsum(nparts, kpwgts)/(1.0*nvtxs)); - - - if (mustfree == 1 || mustfree == 3) { - free(vwgt); - graph->vwgt = NULL; - } - if (mustfree == 2 || mustfree == 3) { - free(adjwgt); - graph->adjwgt = NULL; - } - - GKfree(&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM); -} - - - -/************************************************************************* -* This function computes the balance of the partitioning -**************************************************************************/ -void ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec) -{ - int i, j, nvtxs, ncon; - idxtype *kpwgts, *vwgt; - float balance; - - nvtxs = graph->nvtxs; - ncon = graph->ncon; - vwgt = graph->vwgt; - - kpwgts = idxsmalloc(nparts, 0, "ComputePartitionInfo: kpwgts"); - - if (vwgt == NULL) { - for (i=0; i<nvtxs; i++) - kpwgts[where[i]]++; - ubvec[0] = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*nvtxs); - } - else { - for (j=0; j<ncon; j++) { - idxset(nparts, 0, kpwgts); - for (i=0; i<graph->nvtxs; i++) - kpwgts[where[i]] += vwgt[i*ncon+j]; - - ubvec[j] = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)); - } - } - - free(kpwgts); - -} - - -/************************************************************************* -* This function computes the balance of the element partitioning -**************************************************************************/ -float ComputeElementBalance(int ne, int nparts, idxtype *where) -{ - int i; - idxtype *kpwgts; - float balance; - - kpwgts = idxsmalloc(nparts, 0, "ComputeElementBalance: kpwgts"); - - for (i=0; i<ne; i++) - kpwgts[where[i]]++; - - balance = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)); - - free(kpwgts); - - return balance; - -} diff --git a/Metis/struct.h b/Metis/struct.h deleted file mode 100644 index e5ba553e9a..0000000000 --- a/Metis/struct.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * struct.h - * - * This file contains data structures for ILU routines. - * - * Started 9/26/95 - * George - * - * $Id: struct.h,v 1.1 2005-09-07 14:36:46 remacle Exp $ - */ - -/* Undefine the following #define in order to use short int as the idxtype */ -#define IDXTYPE_INT - -/* Indexes are as long as integers for now */ -#ifdef IDXTYPE_INT -typedef int idxtype; -#else -typedef short idxtype; -#endif - -#define MAXIDX (1<<8*sizeof(idxtype)-2) - - -/************************************************************************* -* The following data structure stores key-value pair -**************************************************************************/ -struct KeyValueType { - idxtype key; - idxtype val; -}; - -typedef struct KeyValueType KeyValueType; - - -/************************************************************************* -* The following data structure will hold a node of a doubly-linked list. -**************************************************************************/ -struct ListNodeType { - int id; /* The id value of the node */ - struct ListNodeType *prev, *next; /* It's a doubly-linked list */ -}; - -typedef struct ListNodeType ListNodeType; - - - -/************************************************************************* -* The following data structure is used to store the buckets for the -* refinment algorithms -**************************************************************************/ -struct PQueueType { - int type; /* The type of the representation used */ - int nnodes; - int maxnodes; - int mustfree; - - /* Linear array version of the data structures */ - int pgainspan, ngainspan; /* plus and negative gain span */ - int maxgain; - ListNodeType *nodes; - ListNodeType **buckets; - - /* Heap version of the data structure */ - KeyValueType *heap; - idxtype *locator; -}; - -typedef struct PQueueType PQueueType; - - -/************************************************************************* -* The following data structure stores an edge -**************************************************************************/ -struct edegreedef { - idxtype pid; - idxtype ed; -}; -typedef struct edegreedef EDegreeType; - - -/************************************************************************* -* The following data structure stores an edge for vol -**************************************************************************/ -struct vedegreedef { - idxtype pid; - idxtype ed, ned; - idxtype gv; -}; -typedef struct vedegreedef VEDegreeType; - - -/************************************************************************* -* This data structure holds various working space data -**************************************************************************/ -struct workspacedef { - idxtype *core; /* Where pairs, indices, and degrees are coming from */ - int maxcore, ccore; - - EDegreeType *edegrees; - VEDegreeType *vedegrees; - int cdegree; - - idxtype *auxcore; /* This points to the memory of the edegrees */ - - idxtype *pmat; /* An array of k^2 used for eliminating domain - connectivity in k-way refinement */ -}; - -typedef struct workspacedef WorkSpaceType; - - -/************************************************************************* -* The following data structure holds information on degrees for k-way -* partition -**************************************************************************/ -struct rinfodef { - int id, ed; /* ID/ED of nodes */ - int ndegrees; /* The number of different ext-degrees */ - EDegreeType *edegrees; /* List of edges */ -}; - -typedef struct rinfodef RInfoType; - - -/************************************************************************* -* The following data structure holds information on degrees for k-way -* vol-based partition -**************************************************************************/ -struct vrinfodef { - int id, ed, nid; /* ID/ED of nodes */ - int gv; /* IV/EV of nodes */ - int ndegrees; /* The number of different ext-degrees */ - VEDegreeType *edegrees; /* List of edges */ -}; - -typedef struct vrinfodef VRInfoType; - - -/************************************************************************* -* The following data structure holds information on degrees for k-way -* partition -**************************************************************************/ -struct nrinfodef { - idxtype edegrees[2]; -}; - -typedef struct nrinfodef NRInfoType; - - -/************************************************************************* -* This data structure holds the input graph -**************************************************************************/ -struct graphdef { - idxtype *gdata, *rdata; /* Memory pools for graph and refinement data. - This is where memory is allocated and used - the rest of the fields in this structure */ - - int nvtxs, nedges; /* The # of vertices and edges in the graph */ - idxtype *xadj; /* Pointers to the locally stored vertices */ - idxtype *vwgt; /* Vertex weights */ - idxtype *vsize; /* Vertex sizes for min-volume formulation */ - idxtype *adjncy; /* Array that stores the adjacency lists of nvtxs */ - idxtype *adjwgt; /* Array that stores the weights of the adjacency lists */ - - idxtype *adjwgtsum; /* The sum of the adjacency weight of each vertex */ - - idxtype *label; - - idxtype *cmap; - - /* Partition parameters */ - int mincut, minvol; - idxtype *where, *pwgts; - int nbnd; - idxtype *bndptr, *bndind; - - /* Bisection refinement parameters */ - idxtype *id, *ed; - - /* K-way refinement parameters */ - RInfoType *rinfo; - - /* K-way volume refinement parameters */ - VRInfoType *vrinfo; - - /* Node refinement information */ - NRInfoType *nrinfo; - - - /* Additional info needed by the MOC routines */ - int ncon; /* The # of constrains */ - float *nvwgt; /* Normalized vertex weights */ - float *npwgts; /* The normalized partition weights */ - - struct graphdef *coarser, *finer; -}; - -typedef struct graphdef GraphType; - - - -/************************************************************************* -* The following data type implements a timer -**************************************************************************/ -typedef double timer; - - -/************************************************************************* -* The following structure stores information used by Metis -**************************************************************************/ -struct controldef { - int CoarsenTo; /* The # of vertices in the coarsest graph */ - int dbglvl; /* Controls the debuging output of the program */ - int CType; /* The type of coarsening */ - int IType; /* The type of initial partitioning */ - int RType; /* The type of refinement */ - int maxvwgt; /* The maximum allowed weight for a vertex */ - float nmaxvwgt; /* The maximum allowed weight for a vertex for each constrain */ - int optype; /* Type of operation */ - int pfactor; /* .1*prunning factor */ - int nseps; /* The number of separators to be found during multiple bisections */ - int oflags; - - WorkSpaceType wspace; /* Work Space Informations */ - - /* Various Timers */ - timer TotalTmr, InitPartTmr, MatchTmr, ContractTmr, CoarsenTmr, UncoarsenTmr, - SepTmr, RefTmr, ProjectTmr, SplitTmr, AuxTmr1, AuxTmr2, AuxTmr3, AuxTmr4, AuxTmr5, AuxTmr6; - -}; - -typedef struct controldef CtrlType; - - -/************************************************************************* -* The following data structure stores max-partition weight info for -* Vertical MOC k-way refinement -**************************************************************************/ -struct vpwgtdef { - float max[2][MAXNCON]; - int imax[2][MAXNCON]; -}; - -typedef struct vpwgtdef VPInfoType; - - - - diff --git a/Metis/subdomains.c b/Metis/subdomains.c deleted file mode 100644 index ec6ef674da..0000000000 --- a/Metis/subdomains.c +++ /dev/null @@ -1,1295 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * subdomains.c - * - * This file contains functions that deal with prunning the number of - * adjacent subdomains in KMETIS - * - * Started 7/15/98 - * George - * - * $Id: subdomains.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Random_KWayEdgeRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees; - int from, me, to, oldcut, vwgt, gain; - int maxndoms, nadd; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts; - idxtype *phtable, *pmat, *pmatptr, *ndoms; - EDegreeType *myedegrees; - RInfoType *myrinfo; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndptr = graph->bndptr; - bndind = graph->bndind; - - where = graph->where; - pwgts = graph->pwgts; - - pmat = ctrl->wspace.pmat; - phtable = idxwspacemalloc(ctrl, nparts); - ndoms = idxwspacemalloc(ctrl, nparts); - - ComputeSubDomainGraph(graph, nparts, pmat, ndoms); - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - maxndoms = ndoms[idxamax(nparts, ndoms)]; - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (nmoves=iii=0; iii<graph->nbnd; iii++) { - ii = perm[iii]; - if (ii >= nbnd) - continue; - i = bndind[ii]; - - myrinfo = graph->rinfo+i; - - if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */ - from = where[i]; - vwgt = graph->vwgt[i]; - - if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - /* Determine the valid domains */ - for (j=0; j<myndegrees; j++) { - to = myedegrees[j].pid; - phtable[to] = 1; - pmatptr = pmat + to*nparts; - for (nadd=0, k=0; k<myndegrees; k++) { - if (k == j) - continue; - - l = myedegrees[k].pid; - if (pmatptr[l] == 0) { - if (ndoms[l] > maxndoms-1) { - phtable[to] = 0; - nadd = maxndoms; - break; - } - nadd++; - } - } - if (ndoms[to]+nadd > maxndoms) - phtable[to] = 0; - if (nadd == 0) - phtable[to] = 2; - } - - /* Find the first valid move */ - j = myrinfo->id; - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (!phtable[to]) - continue; - gain = myedegrees[k].ed-j; /* j = myrinfo->id. Allow good nodes to move */ - if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (!phtable[to]) - continue; - if ((myedegrees[j].ed > myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) || - (myedegrees[j].ed == myedegrees[k].ed && - itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) - k = j; - } - - to = myedegrees[k].pid; - - j = 0; - if (myedegrees[k].ed-myrinfo->id > 0) - j = 1; - else if (myedegrees[k].ed-myrinfo->id == 0) { - if (/*(iii&7) == 0 ||*/ phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) - j = 1; - } - if (j == 0) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update pmat to reflect the move of 'i' */ - pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); - pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); - if (pmat[from*nparts+to] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[to*nparts+from] == 0) { - ndoms[to]--; - if (ndoms[to]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - INC_DEC(pwgts[to], pwgts[from], vwgt); - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed-myrinfo->id < 0) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ - if (me != from && me != to) { - pmat[me*nparts+from] -= adjwgt[j]; - pmat[from*nparts+me] -= adjwgt[j]; - if (pmat[me*nparts+from] == 0) { - ndoms[me]--; - if (ndoms[me]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[from*nparts+me] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - if (pmat[me*nparts+to] == 0) { - ndoms[me]++; - if (ndoms[me] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms); - maxndoms = ndoms[me]; - } - } - if (pmat[to*nparts+me] == 0) { - ndoms[to]++; - if (ndoms[to] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms); - maxndoms = ndoms[to]; - } - } - pmat[me*nparts+to] += adjwgt[j]; - pmat[to*nparts+me] += adjwgt[j]; - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - - } - nmoves++; - } - } - - graph->nbnd = nbnd; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %5d, Vol: %5d, %d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, - graph->mincut, ComputeVolume(graph, where), idxsum(nparts, ndoms))); - - if (graph->mincut == oldcut) - break; - } - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); -} - - - -/************************************************************************* -* This function performs k-way refinement -**************************************************************************/ -void Greedy_KWayEdgeBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses) -{ - int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves; - int from, me, to, oldcut, vwgt, maxndoms, nadd; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts; - idxtype *phtable, *pmat, *pmatptr, *ndoms; - EDegreeType *myedegrees; - RInfoType *myrinfo; - PQueueType queue; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - bndind = graph->bndind; - bndptr = graph->bndptr; - - where = graph->where; - pwgts = graph->pwgts; - - pmat = ctrl->wspace.pmat; - phtable = idxwspacemalloc(ctrl, nparts); - ndoms = idxwspacemalloc(ctrl, nparts); - - ComputeSubDomainGraph(graph, nparts, pmat, ndoms); - - - /* Setup the weight intervals of the various subdomains */ - minwgt = idxwspacemalloc(ctrl, nparts); - maxwgt = idxwspacemalloc(ctrl, nparts); - itpwgts = idxwspacemalloc(ctrl, nparts); - tvwgt = idxsum(nparts, pwgts); - ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); - - for (i=0; i<nparts; i++) { - itpwgts[i] = tpwgts[i]*tvwgt; - maxwgt[i] = tpwgts[i]*tvwgt*ubfactor; - minwgt[i] = tpwgts[i]*tvwgt*(1.0/ubfactor); - } - - perm = idxwspacemalloc(ctrl, nvtxs); - moved = idxwspacemalloc(ctrl, nvtxs); - - PQueueInit(ctrl, &queue, nvtxs, graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, - graph->mincut)); - - for (pass=0; pass<npasses; pass++) { - ASSERT(ComputeCut(graph, where) == graph->mincut); - - /* Check to see if things are out of balance, given the tolerance */ - for (i=0; i<nparts; i++) { - if (pwgts[i] > maxwgt[i]) - break; - } - if (i == nparts) /* Things are balanced. Return right away */ - break; - - PQueueReset(&queue); - idxset(nvtxs, -1, moved); - - oldcut = graph->mincut; - nbnd = graph->nbnd; - - RandomPermute(nbnd, perm, 1); - for (ii=0; ii<nbnd; ii++) { - i = bndind[perm[ii]]; - PQueueInsert(&queue, i, graph->rinfo[i].ed - graph->rinfo[i].id); - moved[i] = 2; - } - - maxndoms = ndoms[idxamax(nparts, ndoms)]; - - for (nmoves=0;;) { - if ((i = PQueueGetMax(&queue)) == -1) - break; - moved[i] = 1; - - myrinfo = graph->rinfo+i; - from = where[i]; - vwgt = graph->vwgt[i]; - - if (pwgts[from]-vwgt < minwgt[from]) - continue; /* This cannot be moved! */ - - myedegrees = myrinfo->edegrees; - myndegrees = myrinfo->ndegrees; - - /* Determine the valid domains */ - for (j=0; j<myndegrees; j++) { - to = myedegrees[j].pid; - phtable[to] = 1; - pmatptr = pmat + to*nparts; - for (nadd=0, k=0; k<myndegrees; k++) { - if (k == j) - continue; - - l = myedegrees[k].pid; - if (pmatptr[l] == 0) { - if (ndoms[l] > maxndoms-1) { - phtable[to] = 0; - nadd = maxndoms; - break; - } - nadd++; - } - } - if (ndoms[to]+nadd > maxndoms) - phtable[to] = 0; - } - - for (k=0; k<myndegrees; k++) { - to = myedegrees[k].pid; - if (!phtable[to]) - continue; - if (pwgts[to]+vwgt <= maxwgt[to] || itpwgts[from]*(pwgts[to]+vwgt) <= itpwgts[to]*pwgts[from]) - break; - } - if (k == myndegrees) - continue; /* break out if you did not find a candidate */ - - for (j=k+1; j<myndegrees; j++) { - to = myedegrees[j].pid; - if (!phtable[to]) - continue; - if (itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid]) - k = j; - } - - to = myedegrees[k].pid; - - if (pwgts[from] < maxwgt[from] && pwgts[to] > minwgt[to] && myedegrees[k].ed-myrinfo->id < 0) - continue; - - /*===================================================================== - * If we got here, we can now move the vertex from 'from' to 'to' - *======================================================================*/ - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); - - /* Update pmat to reflect the move of 'i' */ - pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); - pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); - if (pmat[from*nparts+to] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[to*nparts+from] == 0) { - ndoms[to]--; - if (ndoms[to]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - INC_DEC(pwgts[to], pwgts[from], vwgt); - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed == 0) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - oldgain = (myrinfo->ed-myrinfo->id); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed > 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed == 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ - if (me != from && me != to) { - pmat[me*nparts+from] -= adjwgt[j]; - pmat[from*nparts+me] -= adjwgt[j]; - if (pmat[me*nparts+from] == 0) { - ndoms[me]--; - if (ndoms[me]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - if (pmat[from*nparts+me] == 0) { - ndoms[from]--; - if (ndoms[from]+1 == maxndoms) - maxndoms = ndoms[idxamax(nparts, ndoms)]; - } - - if (pmat[me*nparts+to] == 0) { - ndoms[me]++; - if (ndoms[me] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms); - maxndoms = ndoms[me]; - } - } - if (pmat[to*nparts+me] == 0) { - ndoms[to]++; - if (ndoms[to] > maxndoms) { - printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms); - maxndoms = ndoms[to]; - } - } - pmat[me*nparts+to] += adjwgt[j]; - pmat[to*nparts+me] += adjwgt[j]; - } - - /* Update the queue */ - if (me == to || me == from) { - gain = myrinfo->ed-myrinfo->id; - if (moved[ii] == 2) { - if (myrinfo->ed > 0) - PQueueUpdate(&queue, ii, oldgain, gain); - else { - PQueueDelete(&queue, ii, oldgain); - moved[ii] = -1; - } - } - else if (moved[ii] == -1 && myrinfo->ed > 0) { - PQueueInsert(&queue, ii, gain); - moved[ii] = 2; - } - } - - ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); - ASSERT(CheckRInfo(myrinfo)); - } - nmoves++; - } - - graph->nbnd = nbnd; - - IFSET(ctrl->dbglvl, DBG_REFINE, - printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, %d\n", - pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], - 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut,idxsum(nparts, ndoms))); - } - - PQueueFree(ctrl, &queue); - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - - - - -/************************************************************************* -* This function computes the subdomain graph -**************************************************************************/ -void PrintSubDomainGraph(GraphType *graph, int nparts, idxtype *where) -{ - int i, j, k, me, nvtxs, total, max; - idxtype *xadj, *adjncy, *adjwgt, *pmat; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - pmat = idxsmalloc(nparts*nparts, 0, "ComputeSubDomainGraph: pmat"); - - for (i=0; i<nvtxs; i++) { - me = where[i]; - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] != me) - pmat[me*nparts+where[k]] += adjwgt[j]; - } - } - - /* printf("Subdomain Info\n"); */ - total = max = 0; - for (i=0; i<nparts; i++) { - for (k=0, j=0; j<nparts; j++) { - if (pmat[i*nparts+j] > 0) - k++; - } - total += k; - - if (k > max) - max = k; -/* - printf("%2d -> %2d ", i, k); - for (j=0; j<nparts; j++) { - if (pmat[i*nparts+j] > 0) - printf("[%2d %4d] ", j, pmat[i*nparts+j]); - } - printf("\n"); -*/ - } - printf("Total adjacent subdomains: %d, Max: %d\n", total, max); - - free(pmat); -} - - - -/************************************************************************* -* This function computes the subdomain graph -**************************************************************************/ -void ComputeSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms) -{ - int i, j, k, me, nvtxs, ndegrees; - idxtype *xadj, *adjncy, *adjwgt, *where; - RInfoType *rinfo; - EDegreeType *edegrees; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - where = graph->where; - rinfo = graph->rinfo; - - idxset(nparts*nparts, 0, pmat); - - for (i=0; i<nvtxs; i++) { - if (rinfo[i].ed > 0) { - me = where[i]; - ndegrees = rinfo[i].ndegrees; - edegrees = rinfo[i].edegrees; - - k = me*nparts; - for (j=0; j<ndegrees; j++) - pmat[k+edegrees[j].pid] += edegrees[j].ed; - } - } - - for (i=0; i<nparts; i++) { - ndoms[i] = 0; - for (j=0; j<nparts; j++) { - if (pmat[i*nparts+j] > 0) - ndoms[i]++; - } - } - -} - - - - - -/************************************************************************* -* This function computes the subdomain graph -**************************************************************************/ -void EliminateSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts) -{ - int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd; - int min, move, cpwgt, tvwgt; - idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind; - KeyValueType *cand, *cand2; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = graph->pwgts; /* We assume that this is properly initialized */ - - maxpwgt = idxwspacemalloc(ctrl, nparts); - ndoms = idxwspacemalloc(ctrl, nparts); - otherpmat = idxwspacemalloc(ctrl, nparts); - ind = idxwspacemalloc(ctrl, nvtxs); - pmat = ctrl->wspace.pmat; - - cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); - cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); - - /* Compute the pmat matrix and ndoms */ - ComputeSubDomainGraph(graph, nparts, pmat, ndoms); - - - /* Compute the maximum allowed weight for each domain */ - tvwgt = idxsum(nparts, pwgts); - for (i=0; i<nparts; i++) - maxpwgt[i] = 1.25*tpwgts[i]*tvwgt; - - - /* Get into the loop eliminating subdomain connections */ - for (;;) { - total = idxsum(nparts, ndoms); - avg = total/nparts; - max = ndoms[idxamax(nparts, ndoms)]; - - /* printf("Adjacent Subdomain Stats: Total: %3d, Max: %3d, Avg: %3d [%5d]\n", total, max, avg, idxsum(nparts*nparts, pmat)); */ - - if (max < 1.4*avg) - break; - - me = idxamax(nparts, ndoms); - mypmat = pmat + me*nparts; - totalout = idxsum(nparts, mypmat); - - /*printf("Me: %d, TotalOut: %d,\n", me, totalout);*/ - - /* Sort the connections according to their cut */ - for (ncand2=0, i=0; i<nparts; i++) { - if (mypmat[i] > 0) { - cand2[ncand2].key = mypmat[i]; - cand2[ncand2++].val = i; - } - } - ikeysort(ncand2, cand2); - - move = 0; - for (min=0; min<ncand2; min++) { - if (cand2[min].key > totalout/(2*ndoms[me])) - break; - - other = cand2[min].val; - - /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/ - - idxset(nparts, 0, otherpmat); - - /* Go and find the vertices in 'other' that are connected in 'me' */ - for (nind=0, i=0; i<nvtxs; i++) { - if (where[i] == other) { - for (j=xadj[i]; j<xadj[i+1]; j++) { - if (where[adjncy[j]] == me) { - ind[nind++] = i; - break; - } - } - } - } - - /* Go and construct the otherpmat to see where these nind vertices are connected to */ - for (cpwgt=0, ii=0; ii<nind; ii++) { - i = ind[ii]; - cpwgt += vwgt[i]; - - for (j=xadj[i]; j<xadj[i+1]; j++) - otherpmat[where[adjncy[j]]] += adjwgt[j]; - } - otherpmat[other] = 0; - - for (ncand=0, i=0; i<nparts; i++) { - if (otherpmat[i] > 0) { - cand[ncand].key = -otherpmat[i]; - cand[ncand++].val = i; - } - } - ikeysort(ncand, cand); - - /* - * Go through and the select the first domain that is common with 'me', and - * does not increase the ndoms[target] higher than my ndoms, subject to the - * maxpwgt constraint. Traversal is done from the mostly connected to the least. - */ - target = target2 = -1; - for (i=0; i<ncand; i++) { - k = cand[i].val; - - if (mypmat[k] > 0) { - if (pwgts[k] + cpwgt > maxpwgt[k]) /* Check if balance will go off */ - continue; - - for (j=0; j<nparts; j++) { - if (otherpmat[j] > 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0) - break; - } - if (j == nparts) { /* No bad second level effects */ - for (nadd=0, j=0; j<nparts; j++) { - if (otherpmat[j] > 0 && pmat[nparts*k+j] == 0) - nadd++; - } - - /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/ - if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) { - target2 = k; - } - if (nadd == 0) { - target = k; - break; - } - } - } - } - if (target == -1 && target2 != -1) - target = target2; - - if (target == -1) { - /* printf("\t\tCould not make the move\n");*/ - continue; - } - - /*printf("\t\tMoving to %d\n", target);*/ - - /* Update the partition weights */ - INC_DEC(pwgts[target], pwgts[other], cpwgt); - - MoveGroupMConn(ctrl, graph, ndoms, pmat, nparts, target, nind, ind); - - move = 1; - break; - } - - if (move == 0) - break; - } - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - - GKfree(&cand, &cand2, LTERM); -} - - -/************************************************************************* -* This function moves a collection of vertices and updates their rinfo -**************************************************************************/ -void MoveGroupMConn(CtrlType *ctrl, GraphType *graph, idxtype *ndoms, idxtype *pmat, - int nparts, int to, int nind, idxtype *ind) -{ - int i, ii, iii, j, jj, k, l, nvtxs, nbnd, myndegrees; - int from, me; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *bndptr, *bndind; - EDegreeType *myedegrees; - RInfoType *myrinfo; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - - nbnd = graph->nbnd; - - for (iii=0; iii<nind; iii++) { - i = ind[iii]; - from = where[i]; - - myrinfo = graph->rinfo+i; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; - myrinfo->ndegrees = 0; - } - myedegrees = myrinfo->edegrees; - - /* find the location of 'to' in myrinfo or create it if it is not there */ - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) - break; - } - if (k == myrinfo->ndegrees) { - myedegrees[k].pid = to; - myedegrees[k].ed = 0; - myrinfo->ndegrees++; - } - - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - /* Update pmat to reflect the move of 'i' */ - pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); - pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); - if (pmat[from*nparts+to] == 0) - ndoms[from]--; - if (pmat[to*nparts+from] == 0) - ndoms[to]--; - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[i] != -1) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ - if (me != from && me != to) { - pmat[me*nparts+from] -= adjwgt[j]; - pmat[from*nparts+me] -= adjwgt[j]; - if (pmat[me*nparts+from] == 0) - ndoms[me]--; - if (pmat[from*nparts+me] == 0) - ndoms[from]--; - - if (pmat[me*nparts+to] == 0) - ndoms[me]++; - if (pmat[to*nparts+me] == 0) - ndoms[to]++; - - pmat[me*nparts+to] += adjwgt[j]; - pmat[to*nparts+me] += adjwgt[j]; - } - - ASSERT(CheckRInfo(myrinfo)); - } - - ASSERT(CheckRInfo(graph->rinfo+i)); - } - - graph->nbnd = nbnd; - -} - - - - -/************************************************************************* -* This function finds all the connected components induced by the -* partitioning vector in wgraph->where and tries to push them around to -* remove some of them -**************************************************************************/ -void EliminateComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor) -{ - int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, other, target, deltawgt; - idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt; - idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - vwgt = graph->vwgt; - adjwgt = graph->adjwgt; - - where = graph->where; - pwgts = graph->pwgts; - - touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs)); - cptr = idxwspacemalloc(ctrl, nvtxs); - cind = idxwspacemalloc(ctrl, nvtxs); - perm = idxwspacemalloc(ctrl, nvtxs); - todo = idxwspacemalloc(ctrl, nvtxs); - maxpwgt = idxwspacemalloc(ctrl, nparts); - cpvec = idxwspacemalloc(ctrl, nparts); - npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts)); - - for (i=0; i<nvtxs; i++) - perm[i] = todo[i] = i; - - /* Find the connected componends induced by the partition */ - ncmps = -1; - first = last = 0; - nleft = nvtxs; - while (nleft > 0) { - if (first == last) { /* Find another starting vertex */ - cptr[++ncmps] = first; - ASSERT(touched[todo[0]] == 0); - i = todo[0]; - cind[last++] = i; - touched[i] = 1; - me = where[i]; - npcmps[me]++; - } - - i = cind[first++]; - k = perm[i]; - j = todo[k] = todo[--nleft]; - perm[j] = k; - - for (j=xadj[i]; j<xadj[i+1]; j++) { - k = adjncy[j]; - if (where[k] == me && !touched[k]) { - cind[last++] = k; - touched[k] = 1; - } - } - } - cptr[++ncmps] = first; - - /* printf("I found %d components, for this %d-way partition\n", ncmps, nparts); */ - - if (ncmps > nparts) { /* There are more components than processors */ - /* First determine the max allowed load imbalance */ - tvwgt = idxsum(nparts, pwgts); - for (i=0; i<nparts; i++) - maxpwgt[i] = ubfactor*tpwgts[i]*tvwgt; - - deltawgt = 5; - - for (i=0; i<ncmps; i++) { - me = where[cind[cptr[i]]]; /* Get the domain of this component */ - if (npcmps[me] == 1) - continue; /* Skip it because it is contigous */ - - /*printf("Trying to move %d from %d\n", i, me); */ - - /* Determine the weight of the block to be moved and abort if too high */ - for (cwgt=0, j=cptr[i]; j<cptr[i+1]; j++) - cwgt += vwgt[cind[j]]; - - if (cwgt > .30*pwgts[me]) - continue; /* Skip the component if it is over 30% of the weight */ - - /* Determine the connectivity */ - idxset(nparts, 0, cpvec); - for (j=cptr[i]; j<cptr[i+1]; j++) { - ii = cind[j]; - for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) - cpvec[where[adjncy[jj]]] += adjwgt[jj]; - } - cpvec[me] = 0; - - target = -1; - for (j=0; j<nparts; j++) { - if (cpvec[j] > 0 && (cwgt < deltawgt || pwgts[j] + cwgt < maxpwgt[j])) { - if (target == -1 || cpvec[target] < cpvec[j]) - target = j; - } - } - - /* printf("\tMoving it to %d [%d]\n", target, cpvec[target]);*/ - - if (target != -1) { - /* Assign all the vertices of 'me' to 'target' and update data structures */ - INC_DEC(pwgts[target], pwgts[me], cwgt); - npcmps[me]--; - - MoveGroup(ctrl, graph, nparts, target, i, cptr, cind); - } - } - - } - - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nparts); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - idxwspacefree(ctrl, nvtxs); - -} - - -/************************************************************************* -* This function moves a collection of vertices and updates their rinfo -**************************************************************************/ -void MoveGroup(CtrlType *ctrl, GraphType *graph, int nparts, int to, int gid, idxtype *ptr, idxtype *ind) -{ - int i, ii, iii, j, jj, k, l, nvtxs, nbnd, myndegrees; - int from, me; - idxtype *xadj, *adjncy, *adjwgt; - idxtype *where, *bndptr, *bndind; - EDegreeType *myedegrees; - RInfoType *myrinfo; - - nvtxs = graph->nvtxs; - xadj = graph->xadj; - adjncy = graph->adjncy; - adjwgt = graph->adjwgt; - - where = graph->where; - bndptr = graph->bndptr; - bndind = graph->bndind; - - nbnd = graph->nbnd; - - for (iii=ptr[gid]; iii<ptr[gid+1]; iii++) { - i = ind[iii]; - from = where[i]; - - myrinfo = graph->rinfo+i; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; - myrinfo->ndegrees = 0; - } - myedegrees = myrinfo->edegrees; - - /* find the location of 'to' in myrinfo or create it if it is not there */ - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) - break; - } - if (k == myrinfo->ndegrees) { - myedegrees[k].pid = to; - myedegrees[k].ed = 0; - myrinfo->ndegrees++; - } - - graph->mincut -= myedegrees[k].ed-myrinfo->id; - - - /* Update where, weight, and ID/ED information of the vertex you moved */ - where[i] = to; - myrinfo->ed += myrinfo->id-myedegrees[k].ed; - SWAP(myrinfo->id, myedegrees[k].ed, j); - if (myedegrees[k].ed == 0) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].pid = from; - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[i] != -1) - BNDDelete(nbnd, bndind, bndptr, i); - - /* Update the degrees of adjacent vertices */ - for (j=xadj[i]; j<xadj[i+1]; j++) { - ii = adjncy[j]; - me = where[ii]; - - myrinfo = graph->rinfo+ii; - if (myrinfo->edegrees == NULL) { - myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; - ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; - } - myedegrees = myrinfo->edegrees; - - ASSERT(CheckRInfo(myrinfo)); - - if (me == from) { - INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) - BNDInsert(nbnd, bndind, bndptr, ii); - } - else if (me == to) { - INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); - - if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) - BNDDelete(nbnd, bndind, bndptr, ii); - } - - /* Remove contribution from the .ed of 'from' */ - if (me != from) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == from) { - if (myedegrees[k].ed == adjwgt[j]) - myedegrees[k] = myedegrees[--myrinfo->ndegrees]; - else - myedegrees[k].ed -= adjwgt[j]; - break; - } - } - } - - /* Add contribution to the .ed of 'to' */ - if (me != to) { - for (k=0; k<myrinfo->ndegrees; k++) { - if (myedegrees[k].pid == to) { - myedegrees[k].ed += adjwgt[j]; - break; - } - } - if (k == myrinfo->ndegrees) { - myedegrees[myrinfo->ndegrees].pid = to; - myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; - } - } - - ASSERT(CheckRInfo(myrinfo)); - } - - ASSERT(CheckRInfo(graph->rinfo+i)); - } - - graph->nbnd = nbnd; - -} - diff --git a/Metis/timing.c b/Metis/timing.c deleted file mode 100644 index 5495f92732..0000000000 --- a/Metis/timing.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * timing.c - * - * This file contains routines that deal with timing Metis - * - * Started 7/24/97 - * George - * - * $Id: timing.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - * - */ - -#include <metis.h> - - -/************************************************************************* -* This function clears the timers -**************************************************************************/ -void InitTimers(CtrlType *ctrl) -{ - cleartimer(ctrl->TotalTmr); - cleartimer(ctrl->InitPartTmr); - cleartimer(ctrl->MatchTmr); - cleartimer(ctrl->ContractTmr); - cleartimer(ctrl->CoarsenTmr); - cleartimer(ctrl->UncoarsenTmr); - cleartimer(ctrl->RefTmr); - cleartimer(ctrl->ProjectTmr); - cleartimer(ctrl->SplitTmr); - cleartimer(ctrl->SepTmr); - cleartimer(ctrl->AuxTmr1); - cleartimer(ctrl->AuxTmr2); - cleartimer(ctrl->AuxTmr3); - cleartimer(ctrl->AuxTmr4); - cleartimer(ctrl->AuxTmr5); - cleartimer(ctrl->AuxTmr6); -} - - - -/************************************************************************* -* This function prints the various timers -**************************************************************************/ -void PrintTimers(CtrlType *ctrl) -{ - printf("\nTiming Information -------------------------------------------------"); - printf("\n Multilevel: \t\t %7.3f", gettimer(ctrl->TotalTmr)); - printf("\n Coarsening: \t\t %7.3f", gettimer(ctrl->CoarsenTmr)); - printf("\n Matching: \t\t\t %7.3f", gettimer(ctrl->MatchTmr)); - printf("\n Contract: \t\t\t %7.3f", gettimer(ctrl->ContractTmr)); - printf("\n Initial Partition: \t %7.3f", gettimer(ctrl->InitPartTmr)); - printf("\n Construct Separator: \t %7.3f", gettimer(ctrl->SepTmr)); - printf("\n Uncoarsening: \t\t %7.3f", gettimer(ctrl->UncoarsenTmr)); - printf("\n Refinement: \t\t\t %7.3f", gettimer(ctrl->RefTmr)); - printf("\n Projection: \t\t\t %7.3f", gettimer(ctrl->ProjectTmr)); - printf("\n Splitting: \t\t %7.3f", gettimer(ctrl->SplitTmr)); - printf("\n AUX1: \t\t %7.3f", gettimer(ctrl->AuxTmr1)); - printf("\n AUX2: \t\t %7.3f", gettimer(ctrl->AuxTmr2)); - printf("\n AUX3: \t\t %7.3f", gettimer(ctrl->AuxTmr3)); - printf("\n********************************************************************\n"); -} - - -/************************************************************************* -* This function returns the seconds -**************************************************************************/ -double seconds(void) -{ - return((double) clock()/CLOCKS_PER_SEC); -} - - diff --git a/Metis/util.c b/Metis/util.c deleted file mode 100644 index 36eef2f938..0000000000 --- a/Metis/util.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright 1997, Regents of the University of Minnesota - * - * util.c - * - * This function contains various utility routines - * - * Started 9/28/95 - * George - * - * $Id: util.c,v 1.1 2005-09-07 14:36:46 remacle Exp $ - */ - -#include <metis.h> - - -/************************************************************************* -* This function prints an error message and exits -**************************************************************************/ -void errexit(char *f_str,...) -{ - va_list argp; - char out1[256], out2[256]; - - va_start(argp, f_str); - vsprintf(out1, f_str, argp); - va_end(argp); - - sprintf(out2, "Error! %s", out1); - - fprintf(stdout, out2); - fflush(stdout); - - abort(); -} - - - -#ifndef DMALLOC -/************************************************************************* -* The following function allocates an array of integers -**************************************************************************/ -int *imalloc(int n, char *msg) -{ - if (n == 0) - return NULL; - - return (int *)GKmalloc(sizeof(int)*n, msg); -} - - -/************************************************************************* -* The following function allocates an array of integers -**************************************************************************/ -idxtype *idxmalloc(int n, char *msg) -{ - if (n == 0) - return NULL; - - return (idxtype *)GKmalloc(sizeof(idxtype)*n, msg); -} - - -/************************************************************************* -* The following function allocates an array of float -**************************************************************************/ -float *fmalloc(int n, char *msg) -{ - if (n == 0) - return NULL; - - return (float *)GKmalloc(sizeof(float)*n, msg); -} - - -/************************************************************************* -* The follwoing function allocates an array of integers -**************************************************************************/ -int *ismalloc(int n, int ival, char *msg) -{ - if (n == 0) - return NULL; - - return iset(n, ival, (int *)GKmalloc(sizeof(int)*n, msg)); -} - - - -/************************************************************************* -* The follwoing function allocates an array of integers -**************************************************************************/ -idxtype *idxsmalloc(int n, idxtype ival, char *msg) -{ - if (n == 0) - return NULL; - - return idxset(n, ival, (idxtype *)GKmalloc(sizeof(idxtype)*n, msg)); -} - - -/************************************************************************* -* This function is my wrapper around malloc -**************************************************************************/ -void *GKmalloc(int nbytes, char *msg) -{ - void *ptr; - - if (nbytes == 0) - return NULL; - - ptr = (void *)malloc(nbytes); - if (ptr == NULL) - errexit("***Memory allocation failed for %s. Requested size: %d bytes", msg, nbytes); - - return ptr; -} -#endif - -/************************************************************************* -* This function is my wrapper around free, allows multiple pointers -**************************************************************************/ -void GKfree(void **ptr1,...) -{ - va_list plist; - void **ptr; - - if (*ptr1 != NULL) - free(*ptr1); - *ptr1 = NULL; - - va_start(plist, ptr1); - - /* while ((int)(ptr = va_arg(plist, void **)) != -1) { */ - while ((ptr = va_arg(plist, void **)) != LTERM) { - if (*ptr != NULL) - free(*ptr); - *ptr = NULL; - } - - va_end(plist); -} - - -/************************************************************************* -* These functions set the values of a vector -**************************************************************************/ -int *iset(int n, int val, int *x) -{ - int i; - - for (i=0; i<n; i++) - x[i] = val; - - return x; -} - - -/************************************************************************* -* These functions set the values of a vector -**************************************************************************/ -idxtype *idxset(int n, idxtype val, idxtype *x) -{ - int i; - - for (i=0; i<n; i++) - x[i] = val; - - return x; -} - - -/************************************************************************* -* These functions set the values of a vector -**************************************************************************/ -float *sset(int n, float val, float *x) -{ - int i; - - for (i=0; i<n; i++) - x[i] = val; - - return x; -} - - - -/************************************************************************* -* These functions return the index of the maximum element in a vector -**************************************************************************/ -int iamax(int n, int *x) -{ - int i, max=0; - - for (i=1; i<n; i++) - max = (x[i] > x[max] ? i : max); - - return max; -} - - -/************************************************************************* -* These functions return the index of the maximum element in a vector -**************************************************************************/ -int idxamax(int n, idxtype *x) -{ - int i, max=0; - - for (i=1; i<n; i++) - max = (x[i] > x[max] ? i : max); - - return max; -} - -/************************************************************************* -* These functions return the index of the maximum element in a vector -**************************************************************************/ -int idxamax_strd(int n, idxtype *x, int incx) -{ - int i, max=0; - - n *= incx; - for (i=incx; i<n; i+=incx) - max = (x[i] > x[max] ? i : max); - - return max/incx; -} - - - -/************************************************************************* -* These functions return the index of the maximum element in a vector -**************************************************************************/ -int samax(int n, float *x) -{ - int i, max=0; - - for (i=1; i<n; i++) - max = (x[i] > x[max] ? i : max); - - return max; -} - -/************************************************************************* -* These functions return the index of the almost maximum element in a vector -**************************************************************************/ -int samax2(int n, float *x) -{ - int i, max1, max2; - - if (x[0] > x[1]) { - max1 = 0; - max2 = 1; - } - else { - max1 = 1; - max2 = 0; - } - - for (i=2; i<n; i++) { - if (x[i] > x[max1]) { - max2 = max1; - max1 = i; - } - else if (x[i] > x[max2]) - max2 = i; - } - - return max2; -} - - -/************************************************************************* -* These functions return the index of the minimum element in a vector -**************************************************************************/ -int idxamin(int n, idxtype *x) -{ - int i, min=0; - - for (i=1; i<n; i++) - min = (x[i] < x[min] ? i : min); - - return min; -} - - -/************************************************************************* -* These functions return the index of the minimum element in a vector -**************************************************************************/ -int samin(int n, float *x) -{ - int i, min=0; - - for (i=1; i<n; i++) - min = (x[i] < x[min] ? i : min); - - return min; -} - - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -int idxsum(int n, idxtype *x) -{ - int i, sum = 0; - - for (i=0; i<n; i++) - sum += x[i]; - - return sum; -} - - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -int idxsum_strd(int n, idxtype *x, int incx) -{ - int i, sum = 0; - - for (i=0; i<n; i++, x+=incx) { - sum += *x; - } - - return sum; -} - - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -void idxadd(int n, idxtype *x, idxtype *y) -{ - for (n--; n>=0; n--) - y[n] += x[n]; -} - - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -int charsum(int n, char *x) -{ - int i, sum = 0; - - for (i=0; i<n; i++) - sum += x[i]; - - return sum; -} - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -int isum(int n, int *x) -{ - int i, sum = 0; - - for (i=0; i<n; i++) - sum += x[i]; - - return sum; -} - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -float ssum(int n, float *x) -{ - int i; - float sum = 0.0; - - for (i=0; i<n; i++) - sum += x[i]; - - return sum; -} - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -float ssum_strd(int n, float *x, int incx) -{ - int i; - float sum = 0.0; - - for (i=0; i<n; i++, x+=incx) - sum += *x; - - return sum; -} - -/************************************************************************* -* This function sums the entries in an array -**************************************************************************/ -void sscale(int n, float alpha, float *x) -{ - int i; - - for (i=0; i<n; i++) - x[i] *= alpha; -} - - -/************************************************************************* -* This function computes a 2-norm -**************************************************************************/ -float snorm2(int n, float *v) -{ - int i; - float partial = 0; - - for (i = 0; i<n; i++) - partial += v[i] * v[i]; - - return sqrt(partial); -} - - - -/************************************************************************* -* This function computes a 2-norm -**************************************************************************/ -float sdot(int n, float *x, float *y) -{ - int i; - float partial = 0; - - for (i = 0; i<n; i++) - partial += x[i] * y[i]; - - return partial; -} - - -/************************************************************************* -* This function computes a 2-norm -**************************************************************************/ -void saxpy(int n, float alpha, float *x, int incx, float *y, int incy) -{ - int i; - - for (i=0; i<n; i++, x+=incx, y+=incy) - *y += alpha*(*x); -} - - - - -/************************************************************************* -* This file randomly permutes the contents of an array. -* flag == 0, don't initialize perm -* flag == 1, set p[i] = i -**************************************************************************/ -void RandomPermute(int n, idxtype *p, int flag) -{ - int i, u, v; - idxtype tmp; - - if (flag == 1) { - for (i=0; i<n; i++) - p[i] = i; - } - - if (n <= 4) - return; - - for (i=0; i<n; i+=16) { - u = RandomInRangeFast(n-4); - v = RandomInRangeFast(n-4); - SWAP(p[v], p[u], tmp); - SWAP(p[v+1], p[u+1], tmp); - SWAP(p[v+2], p[u+2], tmp); - SWAP(p[v+3], p[u+3], tmp); - } -} - - - -/************************************************************************* -* This function returns true if the a is a power of 2 -**************************************************************************/ -int ispow2(int a) -{ - for (; a%2 != 1; a = a>>1); - return (a > 1 ? 0 : 1); -} - - -/************************************************************************* -* This function initializes the random number generator -**************************************************************************/ -void InitRandom(int seed) -{ - if (seed == -1) { -#ifndef __VC__ - srand48(7654321L); -#endif - srand(4321); - } - else { -#ifndef __VC__ - srand48(seed); -#endif - srand(seed); - } -} - -/************************************************************************* -* This function returns the log2(x) -**************************************************************************/ -int log2(int a) -{ - int i; - - for (i=1; a > 1; i++, a = a>>1); - return i-1; -} - diff --git a/NR/Makefile b/NR/Makefile deleted file mode 100644 index 2d00d3fab0..0000000000 --- a/NR/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# $Id: Makefile,v 1.5 2005-01-01 19:35:31 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshNR.a -INCLUDE = -I../Common -I../DataStr -I../Numeric -# don't optimize this library: there are some problems with gcc... -OPTIM = -O0 -CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} - -SRC = brent.cpp\ - dpythag.cpp\ - dsvdcmp.cpp\ - fdjac.cpp\ - fmin.cpp\ - lnsrch.cpp\ - lubksb.cpp\ - ludcmp.cpp\ - mnbrak.cpp\ - newt.cpp\ - nrutil.cpp - -OBJ = ${SRC:.cpp=.o} - -.SUFFIXES: .o .cpp - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.cpp.o: - ${CXX} ${CFLAGS} -c $< - -clean: - rm -f *.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -brent.o: brent.cpp nrutil.h ../Numeric/Numeric.h -dpythag.o: dpythag.cpp nrutil.h ../Numeric/Numeric.h -dsvdcmp.o: dsvdcmp.cpp nrutil.h ../Numeric/Numeric.h -fdjac.o: fdjac.cpp nrutil.h ../Numeric/Numeric.h -fmin.o: fmin.cpp nrutil.h ../Numeric/Numeric.h -lnsrch.o: lnsrch.cpp nrutil.h ../Numeric/Numeric.h -lubksb.o: lubksb.cpp -ludcmp.o: ludcmp.cpp nrutil.h ../Numeric/Numeric.h -mnbrak.o: mnbrak.cpp nrutil.h ../Numeric/Numeric.h -newt.o: newt.cpp nrutil.h ../Numeric/Numeric.h -nrutil.o: nrutil.cpp ../Common/Gmsh.h ../Common/Message.h \ - ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \ - ../DataStr/avl.h ../DataStr/Tools.h diff --git a/NR/brent.cpp b/NR/brent.cpp deleted file mode 100644 index 8dc82e8813..0000000000 --- a/NR/brent.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define ITMAX 100 -#define CGOLD 0.3819660 -#define ZEPS 1.0e-10 -#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d); - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -double brent(double ax, double bx, double cx, double (*f)(double), double tol, - double *xmin) -{ - int iter; - double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; - double e=0.0; - - a=(ax < cx ? ax : cx); - b=(ax > cx ? ax : cx); - x=w=v=bx; - fw=fv=fx=(*f)(x); - for (iter=1;iter<=ITMAX;iter++) { - xm=0.5*(a+b); - tol2=2.0*(tol1=tol*fabs(x)+ZEPS); - if (fabs(x-xm) <= (tol2-0.5*(b-a))) { - *xmin=x; - return fx; - } - if (fabs(e) > tol1) { - r=(x-w)*(fx-fv); - q=(x-v)*(fx-fw); - p=(x-v)*q-(x-w)*r; - q=2.0*(q-r); - if (q > 0.0) p = -p; - q=fabs(q); - etemp=e; - e=d; - if (fabs(p) >= fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) - d=CGOLD*(e=(x >= xm ? a-x : b-x)); - else { - d=p/q; - u=x+d; - if (u-a < tol2 || b-u < tol2) - d=SIGN(tol1,xm-x); - } - } else { - d=CGOLD*(e=(x >= xm ? a-x : b-x)); - } - u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); - fu=(*f)(u); - if (fu <= fx) { - if (u >= x) a=x; else b=x; - SHFT(v,w,x,u) - SHFT(fv,fw,fx,fu) - } else { - if (u < x) a=u; else b=u; - if (fu <= fw || w == x) { - v=w; - w=u; - fv=fw; - fw=fu; - } else if (fu <= fv || v == x || v == w) { - v=u; - fv=fu; - } - } - } - nrerror("Too many iterations in brent"); - *xmin=x; - return fx; -} -#undef ITMAX -#undef CGOLD -#undef ZEPS -#undef SHFT -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/dpythag.cpp b/NR/dpythag.cpp deleted file mode 100644 index 4585295c43..0000000000 --- a/NR/dpythag.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" - -double dpythag(double a, double b) -{ - double absa,absb; - absa=fabs(a); - absb=fabs(b); - if (absa > absb) return absa*sqrt(1.0+DSQR(absb/absa)); - else return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+DSQR(absa/absb))); -} -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/dsvdcmp.cpp b/NR/dsvdcmp.cpp deleted file mode 100644 index 81317ec7db..0000000000 --- a/NR/dsvdcmp.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" - -void dsvdcmp(double **a, int m, int n, double w[], double **v) -{ - double dpythag(double a, double b); - int flag,i,its,j,jj,k,l,nm; - double anorm,c,f,g,h,s,scale,x,y,z,*rv1; - - rv1=dvector(1,n); - g=scale=anorm=0.0; - for (i=1;i<=n;i++) { - l=i+1; - rv1[i]=scale*g; - g=s=scale=0.0; - if (i <= m) { - for (k=i;k<=m;k++) scale += fabs(a[k][i]); - if (scale) { - for (k=i;k<=m;k++) { - a[k][i] /= scale; - s += a[k][i]*a[k][i]; - } - f=a[i][i]; - g = -SIGN(sqrt(s),f); - h=f*g-s; - a[i][i]=f-g; - for (j=l;j<=n;j++) { - for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j]; - f=s/h; - for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; - } - for (k=i;k<=m;k++) a[k][i] *= scale; - } - } - w[i]=scale *g; - g=s=scale=0.0; - if (i <= m && i != n) { - for (k=l;k<=n;k++) scale += fabs(a[i][k]); - if (scale) { - for (k=l;k<=n;k++) { - a[i][k] /= scale; - s += a[i][k]*a[i][k]; - } - f=a[i][l]; - g = -SIGN(sqrt(s),f); - h=f*g-s; - a[i][l]=f-g; - for (k=l;k<=n;k++) rv1[k]=a[i][k]/h; - for (j=l;j<=m;j++) { - for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k]; - for (k=l;k<=n;k++) a[j][k] += s*rv1[k]; - } - for (k=l;k<=n;k++) a[i][k] *= scale; - } - } - anorm=DMAX(anorm,(fabs(w[i])+fabs(rv1[i]))); - } - for (i=n;i>=1;i--) { - if (i < n) { - if (g) { - for (j=l;j<=n;j++) v[j][i]=(a[i][j]/a[i][l])/g; - for (j=l;j<=n;j++) { - for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j]; - for (k=l;k<=n;k++) v[k][j] += s*v[k][i]; - } - } - for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0; - } - v[i][i]=1.0; - g=rv1[i]; - l=i; - } - for (i=IMIN(m,n);i>=1;i--) { - l=i+1; - g=w[i]; - for (j=l;j<=n;j++) a[i][j]=0.0; - if (g) { - g=1.0/g; - for (j=l;j<=n;j++) { - for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j]; - f=(s/a[i][i])*g; - for (k=i;k<=m;k++) a[k][j] += f*a[k][i]; - } - for (j=i;j<=m;j++) a[j][i] *= g; - } else for (j=i;j<=m;j++) a[j][i]=0.0; - ++a[i][i]; - } - for (k=n;k>=1;k--) { - for (its=1;its<=30;its++) { - flag=1; - for (l=k;l>=1;l--) { - nm=l-1; - if ((double)(fabs(rv1[l])+anorm) == anorm) { - flag=0; - break; - } - if ((double)(fabs(w[nm])+anorm) == anorm) break; - } - if (flag) { - c=0.0; - s=1.0; - for (i=l;i<=k;i++) { - f=s*rv1[i]; - rv1[i]=c*rv1[i]; - if ((double)(fabs(f)+anorm) == anorm) break; - g=w[i]; - h=dpythag(f,g); - w[i]=h; - h=1.0/h; - c=g*h; - s = -f*h; - for (j=1;j<=m;j++) { - y=a[j][nm]; - z=a[j][i]; - a[j][nm]=y*c+z*s; - a[j][i]=z*c-y*s; - } - } - } - z=w[k]; - if (l == k) { - if (z < 0.0) { - w[k] = -z; - for (j=1;j<=n;j++) v[j][k] = -v[j][k]; - } - break; - } - if (its == 30) nrerror("no convergence in 30 dsvdcmp iterations"); - x=w[l]; - nm=k-1; - y=w[nm]; - g=rv1[nm]; - h=rv1[k]; - f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y); - g=dpythag(f,1.0); - f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x; - c=s=1.0; - for (j=l;j<=nm;j++) { - i=j+1; - g=rv1[i]; - y=w[i]; - h=s*g; - g=c*g; - z=dpythag(f,h); - rv1[j]=z; - c=f/z; - s=h/z; - f=x*c+g*s; - g = g*c-x*s; - h=y*s; - y *= c; - for (jj=1;jj<=n;jj++) { - x=v[jj][j]; - z=v[jj][i]; - v[jj][j]=x*c+z*s; - v[jj][i]=z*c-x*s; - } - z=dpythag(f,h); - w[j]=z; - if (z) { - z=1.0/z; - c=f*z; - s=h*z; - } - f=c*g+s*y; - x=c*y-s*g; - for (jj=1;jj<=m;jj++) { - y=a[jj][j]; - z=a[jj][i]; - a[jj][j]=y*c+z*s; - a[jj][i]=z*c-y*s; - } - } - rv1[l]=0.0; - rv1[k]=f; - w[k]=x; - } - } - free_dvector(rv1,1,n); -} -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/fdjac.cpp b/NR/fdjac.cpp deleted file mode 100644 index 7767ff1bc4..0000000000 --- a/NR/fdjac.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define EPS 1.0e-4 - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void fdjac(int n, double x[], double fvec[], double **df, - void (*vecfunc)(int, double [], double [])) -{ - int i,j; - double h,temp,*f; - - f=dvector(1,n); - for (j=1;j<=n;j++) { - temp=x[j]; - h=EPS*fabs(temp); - if (h == 0.0) h=EPS; - x[j]=temp+h; - h=x[j]-temp; - (*vecfunc)(n,x,f); - x[j]=temp; - for (i=1;i<=n;i++) df[i][j]=(f[i]-fvec[i])/h; - } - free_dvector(f,1,n); -} -#undef EPS -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/fmin.cpp b/NR/fmin.cpp deleted file mode 100644 index f461aa7a05..0000000000 --- a/NR/fmin.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#define NRANSI -#include "nrutil.h" - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -extern int nn; -extern double *fvec; -extern void (*nrfuncv)(int n, double v[], double f[]); - -double fmin(double x[]) -{ - int i; - double sum; - - (*nrfuncv)(nn,x,fvec); - for (sum=0.0,i=1;i<=nn;i++) sum += SQR(fvec[i]); - return 0.5*sum; -} -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/lnsrch.cpp b/NR/lnsrch.cpp deleted file mode 100644 index e4a5346a5f..0000000000 --- a/NR/lnsrch.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define ALF 1.0e-4 -#define TOLX 1.0e-7 - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void lnsrch(int n, double xold[], double fold, double g[], double p[], double x[], - double *f, double stpmax, int *check, double (*func)(double [])) -{ - int i; - double a,alam,alam2,alamin,b,disc,f2,fold2,rhs1,rhs2,slope,sum,temp, - test,tmplam; - - *check=0; - for (sum=0.0,i=1;i<=n;i++) sum += p[i]*p[i]; - sum=sqrt(sum); - if (sum > stpmax) - for (i=1;i<=n;i++) p[i] *= stpmax/sum; - for (slope=0.0,i=1;i<=n;i++) - slope += g[i]*p[i]; - test=0.0; - for (i=1;i<=n;i++) { - temp=fabs(p[i])/FMAX(fabs(xold[i]),1.0); - if (temp > test) test=temp; - } - alamin=TOLX/test; - alam=1.0; - for (;;) { - for (i=1;i<=n;i++) x[i]=xold[i]+alam*p[i]; - *f=(*func)(x); - if (alam < alamin) { - for (i=1;i<=n;i++) x[i]=xold[i]; - *check=1; - return; - } else if (*f <= fold+ALF*alam*slope) return; - else { - if (alam == 1.0) - tmplam = -slope/(2.0*(*f-fold-slope)); - else { - rhs1 = *f-fold-alam*slope; - rhs2=f2-fold2-alam2*slope; - a=(rhs1/(alam*alam)-rhs2/(alam2*alam2))/(alam-alam2); - b=(-alam2*rhs1/(alam*alam)+alam*rhs2/(alam2*alam2))/(alam-alam2); - if (a == 0.0) tmplam = -slope/(2.0*b); - else { - disc=b*b-3.0*a*slope; - if (disc<0.0) nrerror("Roundoff problem in lnsrch."); - else tmplam=(-b+sqrt(disc))/(3.0*a); - } - if (tmplam>0.5*alam) - tmplam=0.5*alam; - } - } - alam2=alam; - f2 = *f; - fold2=fold; - alam=FMAX(tmplam,0.1*alam); - } -} -#undef ALF -#undef TOLX -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/lubksb.cpp b/NR/lubksb.cpp deleted file mode 100644 index 202c826e2f..0000000000 --- a/NR/lubksb.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void lubksb(double **a, int n, int *indx, double b[]) -{ - int i,ii=0,ip,j; - double sum; - - for (i=1;i<=n;i++) { - ip=indx[i]; - sum=b[ip]; - b[ip]=b[i]; - if (ii) - for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j]; - else if (sum) ii=i; - b[i]=sum; - } - for (i=n;i>=1;i--) { - sum=b[i]; - for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j]; - b[i]=sum/a[i][i]; - } -} -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/ludcmp.cpp b/NR/ludcmp.cpp deleted file mode 100644 index 8f4e0c17fc..0000000000 --- a/NR/ludcmp.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define TINY 1.0e-20; - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void ludcmp(double **a, int n, int *indx, double *d) -{ - int i,imax,j,k; - double big,dum,sum,temp; - double *vv; - - vv=dvector(1,n); - *d=1.0; - for (i=1;i<=n;i++) { - big=0.0; - for (j=1;j<=n;j++) - if ((temp=fabs(a[i][j])) > big) big=temp; - if (big == 0.0) nrerror("Singular matrix in routine ludcmp"); - vv[i]=1.0/big; - } - for (j=1;j<=n;j++) { - for (i=1;i<j;i++) { - sum=a[i][j]; - for (k=1;k<i;k++) sum -= a[i][k]*a[k][j]; - a[i][j]=sum; - } - big=0.0; - for (i=j;i<=n;i++) { - sum=a[i][j]; - for (k=1;k<j;k++) - sum -= a[i][k]*a[k][j]; - a[i][j]=sum; - if ( (dum=vv[i]*fabs(sum)) >= big) { - big=dum; - imax=i; - } - } - if (j != imax) { - for (k=1;k<=n;k++) { - dum=a[imax][k]; - a[imax][k]=a[j][k]; - a[j][k]=dum; - } - *d = -(*d); - vv[imax]=vv[j]; - } - indx[j]=imax; - if (a[j][j] == 0.0) a[j][j]=TINY; - if (j != n) { - dum=1.0/(a[j][j]); - for (i=j+1;i<=n;i++) a[i][j] *= dum; - } - } - free_dvector(vv,1,n); -} -#undef TINY -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/mnbrak.cpp b/NR/mnbrak.cpp deleted file mode 100644 index 9aedccc886..0000000000 --- a/NR/mnbrak.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define GOLD 1.618034 -#define GLIMIT 100.0 -#define TINY 1.0e-20 -#define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d); - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -void mnbrak(double *ax, double *bx, double *cx, double *fa, double *fb, double *fc, - double (*func)(double)) -{ - double ulim,u,r,q,fu,dum; - - *fa=(*func)(*ax); - *fb=(*func)(*bx); - if (*fb > *fa) { - SHFT(dum,*ax,*bx,dum) - SHFT(dum,*fb,*fa,dum) - } - *cx=(*bx)+GOLD*(*bx-*ax); - *fc=(*func)(*cx); - while (*fb > *fc) { - r=(*bx-*ax)*(*fb-*fc); - q=(*bx-*cx)*(*fb-*fa); - u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ - (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r)); - ulim=(*bx)+GLIMIT*(*cx-*bx); - if ((*bx-u)*(u-*cx) > 0.0) { - fu=(*func)(u); - if (fu < *fc) { - *ax=(*bx); - *bx=u; - *fa=(*fb); - *fb=fu; - return; - } else if (fu > *fb) { - *cx=u; - *fc=fu; - return; - } - u=(*cx)+GOLD*(*cx-*bx); - fu=(*func)(u); - } else if ((*cx-u)*(u-ulim) > 0.0) { - fu=(*func)(u); - if (fu < *fc) { - SHFT(*bx,*cx,u,*cx+GOLD*(*cx-*bx)) - SHFT(*fb,*fc,fu,(*func)(u)) - } - } else if ((u-ulim)*(ulim-*cx) >= 0.0) { - u=ulim; - fu=(*func)(u); - } else { - u=(*cx)+GOLD*(*cx-*bx); - fu=(*func)(u); - } - SHFT(*ax,*bx,*cx,u) - SHFT(*fa,*fb,*fc,fu) - } -} -#undef GOLD -#undef GLIMIT -#undef TINY -#undef SHFT -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/newt.cpp b/NR/newt.cpp deleted file mode 100644 index b09482177e..0000000000 --- a/NR/newt.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include <math.h> -#define NRANSI -#include "nrutil.h" -#define MAXITS 200 -#define TOLF 1.0e-4 -#define TOLMIN 1.0e-6 -#define TOLX 1.0e-7 -#define STPMX 100.0 - -/* This file has been modified for inclusion in Gmsh (float->double) */ - -int nn; -double *fvec; -void (*nrfuncv)(int n, double v[], double f[]); -#define FREERETURN {free_dvector(fvec,1,n);free_dvector(xold,1,n);\ - free_dvector(p,1,n);free_dvector(g,1,n);free_dmatrix(fjac,1,n,1,n);\ - free_ivector(indx,1,n);return;} - -void newt(double x[], int n, int *check, - void (*vecfunc)(int, double [], double [])) -{ - void fdjac(int n, double x[], double fvec[], double **df, - void (*vecfunc)(int, double [], double [])); - double fmin(double x[]); - void lnsrch(int n, double xold[], double fold, double g[], double p[], double x[], - double *f, double stpmax, int *check, double (*func)(double [])); - void lubksb(double **a, int n, int *indx, double b[]); - void ludcmp(double **a, int n, int *indx, double *d); - int i,its,j,*indx; - double d,den,f,fold,stpmax,sum,temp,test,**fjac,*g,*p,*xold; - - indx=ivector(1,n); - fjac=dmatrix(1,n,1,n); - g=dvector(1,n); - p=dvector(1,n); - xold=dvector(1,n); - fvec=dvector(1,n); - nn=n; - nrfuncv=vecfunc; - f=fmin(x); - test=0.0; - for (i=1;i<=n;i++) - if (fabs(fvec[i]) > test) test=fabs(fvec[i]); - if (test<0.01*TOLF) FREERETURN - for (sum=0.0,i=1;i<=n;i++) sum += SQR(x[i]); - stpmax=STPMX*FMAX(sqrt(sum),(double)n); - for (its=1;its<=MAXITS;its++) { - fdjac(n,x,fvec,fjac,vecfunc); - for (i=1;i<=n;i++) { - for (sum=0.0,j=1;j<=n;j++) sum += fjac[j][i]*fvec[j]; - g[i]=sum; - } - for (i=1;i<=n;i++) xold[i]=x[i]; - fold=f; - for (i=1;i<=n;i++) p[i] = -fvec[i]; - ludcmp(fjac,n,indx,&d); - lubksb(fjac,n,indx,p); - lnsrch(n,xold,fold,g,p,x,&f,stpmax,check,fmin); - test=0.0; - for (i=1;i<=n;i++) - if (fabs(fvec[i]) > test) test=fabs(fvec[i]); - if (test < TOLF) { - *check=0; - FREERETURN - } - if (*check) { - test=0.0; - den=FMAX(f,0.5*n); - for (i=1;i<=n;i++) { - temp=fabs(g[i])*FMAX(fabs(x[i]),1.0)/den; - if (temp > test) test=temp; - } - *check=(test < TOLMIN ? 1 : 0); - FREERETURN - } - test=0.0; - for (i=1;i<=n;i++) { - temp=(fabs(x[i]-xold[i]))/FMAX(fabs(x[i]),1.0); - if (temp > test) test=temp; - } - if (test < TOLX) FREERETURN - } - nrerror("MAXITS exceeded in newt"); -} -#undef MAXITS -#undef TOLF -#undef TOLMIN -#undef TOLX -#undef STPMX -#undef FREERETURN -#undef NRANSI -/* (C) Copr. 1986-92 Numerical Recipes Software J!0. */ diff --git a/NR/nrutil.cpp b/NR/nrutil.cpp deleted file mode 100644 index 8aeaf3a79e..0000000000 --- a/NR/nrutil.cpp +++ /dev/null @@ -1,620 +0,0 @@ -#define NRANSI -#if defined(__STDC__) || defined(ANSI) || defined(NRANSI) /* ANSI */ - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#define NR_END 1 -#define FREE_ARG char* - -#include "Gmsh.h" - -void nrerror(char error_text[]) -/* Numerical Recipes standard error handler */ -{ - Msg(GERROR, "%s", error_text); - /* - fprintf(stderr,"Numerical Recipes run-time error...\n"); - fprintf(stderr,"%s\n",error_text); - fprintf(stderr,"...now exiting to system...\n"); - exit(1); - */ -} - -float *vector(long nl, long nh) -/* allocate a float vector with subscript range v[nl..nh] */ -{ - float *v; - - v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); - if (!v) nrerror("allocation failure in vector()"); - return v-nl+NR_END; -} - -int *ivector(long nl, long nh) -/* allocate an int vector with subscript range v[nl..nh] */ -{ - int *v; - - v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int))); - if (!v) nrerror("allocation failure in ivector()"); - return v-nl+NR_END; -} - -unsigned char *cvector(long nl, long nh) -/* allocate an unsigned char vector with subscript range v[nl..nh] */ -{ - unsigned char *v; - - v=(unsigned char *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(unsigned char))); - if (!v) nrerror("allocation failure in cvector()"); - return v-nl+NR_END; -} - -unsigned long *lvector(long nl, long nh) -/* allocate an unsigned long vector with subscript range v[nl..nh] */ -{ - unsigned long *v; - - v=(unsigned long *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(long))); - if (!v) nrerror("allocation failure in lvector()"); - return v-nl+NR_END; -} - -double *dvector(long nl, long nh) -/* allocate a double vector with subscript range v[nl..nh] */ -{ - double *v; - - v=(double *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(double))); - if (!v) nrerror("allocation failure in dvector()"); - return v-nl+NR_END; -} - -float **matrix(long nrl, long nrh, long ncl, long nch) -/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - float **m; - - /* allocate pointers to rows */ - m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - /* allocate rows and set pointers to them */ - m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -double **dmatrix(long nrl, long nrh, long ncl, long nch) -/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - double **m; - - /* allocate pointers to rows */ - m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - /* allocate rows and set pointers to them */ - m[nrl]=(double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -int **imatrix(long nrl, long nrh, long ncl, long nch) -/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - int **m; - - /* allocate pointers to rows */ - m=(int **) malloc((size_t)((nrow+NR_END)*sizeof(int*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - - /* allocate rows and set pointers to them */ - m[nrl]=(int *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(int))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch, - long newrl, long newcl) -/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */ -{ - long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl; - float **m; - - /* allocate array of pointers to rows */ - m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure in submatrix()"); - m += NR_END; - m -= newrl; - - /* set pointers to rows */ - for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch) -/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix -declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1 -and ncol=nch-ncl+1. The routine should be called with the address -&a[0][0] as the first argument. */ -{ - long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1; - float **m; - - /* allocate pointers to rows */ - m=(float **) malloc((size_t) ((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure in convert_matrix()"); - m += NR_END; - m -= nrl; - - /* set pointers to rows */ - m[nrl]=a-ncl; - for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol; - /* return pointer to array of pointers to rows */ - return m; -} - -float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh) -/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */ -{ - long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1; - float ***t; - - /* allocate pointers to pointers to rows */ - t=(float ***) malloc((size_t)((nrow+NR_END)*sizeof(float**))); - if (!t) nrerror("allocation failure 1 in f3tensor()"); - t += NR_END; - t -= nrl; - - /* allocate pointers to rows and set pointers to them */ - t[nrl]=(float **) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float*))); - if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()"); - t[nrl] += NR_END; - t[nrl] -= ncl; - - /* allocate rows and set pointers to them */ - t[nrl][ncl]=(float *) malloc((size_t)((nrow*ncol*ndep+NR_END)*sizeof(float))); - if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()"); - t[nrl][ncl] += NR_END; - t[nrl][ncl] -= ndl; - - for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep; - for(i=nrl+1;i<=nrh;i++) { - t[i]=t[i-1]+ncol; - t[i][ncl]=t[i-1][ncl]+ncol*ndep; - for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep; - } - - /* return pointer to array of pointers to rows */ - return t; -} - -void free_vector(float *v, long nl, long nh) -/* free a float vector allocated with vector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_ivector(int *v, long nl, long nh) -/* free an int vector allocated with ivector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_cvector(unsigned char *v, long nl, long nh) -/* free an unsigned char vector allocated with cvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_lvector(unsigned long *v, long nl, long nh) -/* free an unsigned long vector allocated with lvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_dvector(double *v, long nl, long nh) -/* free a double vector allocated with dvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_matrix(float **m, long nrl, long nrh, long ncl, long nch) -/* free a float matrix allocated by matrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch) -/* free a double matrix allocated by dmatrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch) -/* free an int matrix allocated by imatrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch) -/* free a submatrix allocated by submatrix() */ -{ - free((FREE_ARG) (b+nrl-NR_END)); -} - -void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch) -/* free a matrix allocated by convert_matrix() */ -{ - free((FREE_ARG) (b+nrl-NR_END)); -} - -void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch, - long ndl, long ndh) -/* free a float f3tensor allocated by f3tensor() */ -{ - free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END)); - free((FREE_ARG) (t[nrl]+ncl-NR_END)); - free((FREE_ARG) (t+nrl-NR_END)); -} - -#else /* ANSI */ -/* traditional - K&R */ - -#include <stdio.h> -#define NR_END 1 -#define FREE_ARG char* - -void nrerror(error_text) -char error_text[]; -/* Numerical Recipes standard error handler */ -{ - void exit(); - - fprintf(stderr,"Numerical Recipes run-time error...\n"); - fprintf(stderr,"%s\n",error_text); - fprintf(stderr,"...now exiting to system...\n"); - exit(1); -} - -float *vector(nl,nh) -long nh,nl; -/* allocate a float vector with subscript range v[nl..nh] */ -{ - float *v; - - v=(float *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(float))); - if (!v) nrerror("allocation failure in vector()"); - return v-nl+NR_END; -} - -int *ivector(nl,nh) -long nh,nl; -/* allocate an int vector with subscript range v[nl..nh] */ -{ - int *v; - - v=(int *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(int))); - if (!v) nrerror("allocation failure in ivector()"); - return v-nl+NR_END; -} - -unsigned char *cvector(nl,nh) -long nh,nl; -/* allocate an unsigned char vector with subscript range v[nl..nh] */ -{ - unsigned char *v; - - v=(unsigned char *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(unsigned char))); - if (!v) nrerror("allocation failure in cvector()"); - return v-nl+NR_END; -} - -unsigned long *lvector(nl,nh) -long nh,nl; -/* allocate an unsigned long vector with subscript range v[nl..nh] */ -{ - unsigned long *v; - - v=(unsigned long *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(long))); - if (!v) nrerror("allocation failure in lvector()"); - return v-nl+NR_END; -} - -double *dvector(nl,nh) -long nh,nl; -/* allocate a double vector with subscript range v[nl..nh] */ -{ - double *v; - - v=(double *)malloc((unsigned int) ((nh-nl+1+NR_END)*sizeof(double))); - if (!v) nrerror("allocation failure in dvector()"); - return v-nl+NR_END; -} - -float **matrix(nrl,nrh,ncl,nch) -long nch,ncl,nrh,nrl; -/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - float **m; - - /* allocate pointers to rows */ - m=(float **) malloc((unsigned int)((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - /* allocate rows and set pointers to them */ - m[nrl]=(float *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(float))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -double **dmatrix(nrl,nrh,ncl,nch) -long nch,ncl,nrh,nrl; -/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - double **m; - - /* allocate pointers to rows */ - m=(double **) malloc((unsigned int)((nrow+NR_END)*sizeof(double*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - /* allocate rows and set pointers to them */ - m[nrl]=(double *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(double))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -int **imatrix(nrl,nrh,ncl,nch) -long nch,ncl,nrh,nrl; -/* allocate a int matrix with subscript range m[nrl..nrh][ncl..nch] */ -{ - long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; - int **m; - - /* allocate pointers to rows */ - m=(int **) malloc((unsigned int)((nrow+NR_END)*sizeof(int*))); - if (!m) nrerror("allocation failure 1 in matrix()"); - m += NR_END; - m -= nrl; - - - /* allocate rows and set pointers to them */ - m[nrl]=(int *) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(int))); - if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); - m[nrl] += NR_END; - m[nrl] -= ncl; - - for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -float **submatrix(a,oldrl,oldrh,oldcl,oldch,newrl,newcl) -float **a; -long newcl,newrl,oldch,oldcl,oldrh,oldrl; -/* point a submatrix [newrl..][newcl..] to a[oldrl..oldrh][oldcl..oldch] */ -{ - long i,j,nrow=oldrh-oldrl+1,ncol=oldcl-newcl; - float **m; - - /* allocate array of pointers to rows */ - m=(float **) malloc((unsigned int) ((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure in submatrix()"); - m += NR_END; - m -= newrl; - - /* set pointers to rows */ - for(i=oldrl,j=newrl;i<=oldrh;i++,j++) m[j]=a[i]+ncol; - - /* return pointer to array of pointers to rows */ - return m; -} - -float **convert_matrix(a,nrl,nrh,ncl,nch) -float *a; -long nch,ncl,nrh,nrl; -/* allocate a float matrix m[nrl..nrh][ncl..nch] that points to the matrix -declared in the standard C manner as a[nrow][ncol], where nrow=nrh-nrl+1 -and ncol=nch-ncl+1. The routine should be called with the address -&a[0][0] as the first argument. */ -{ - long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1; - float **m; - - /* allocate pointers to rows */ - m=(float **) malloc((unsigned int) ((nrow+NR_END)*sizeof(float*))); - if (!m) nrerror("allocation failure in convert_matrix()"); - m += NR_END; - m -= nrl; - - /* set pointers to rows */ - m[nrl]=a-ncl; - for(i=1,j=nrl+1;i<nrow;i++,j++) m[j]=m[j-1]+ncol; - /* return pointer to array of pointers to rows */ - return m; -} - -float ***f3tensor(nrl,nrh,ncl,nch,ndl,ndh) -long nch,ncl,ndh,ndl,nrh,nrl; -/* allocate a float 3tensor with range t[nrl..nrh][ncl..nch][ndl..ndh] */ -{ - long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1; - float ***t; - - /* allocate pointers to pointers to rows */ - t=(float ***) malloc((unsigned int)((nrow+NR_END)*sizeof(float**))); - if (!t) nrerror("allocation failure 1 in f3tensor()"); - t += NR_END; - t -= nrl; - - /* allocate pointers to rows and set pointers to them */ - t[nrl]=(float **) malloc((unsigned int)((nrow*ncol+NR_END)*sizeof(float*))); - if (!t[nrl]) nrerror("allocation failure 2 in f3tensor()"); - t[nrl] += NR_END; - t[nrl] -= ncl; - - /* allocate rows and set pointers to them */ - t[nrl][ncl]=(float *) malloc((unsigned int)((nrow*ncol*ndep+NR_END)*sizeof(float))); - if (!t[nrl][ncl]) nrerror("allocation failure 3 in f3tensor()"); - t[nrl][ncl] += NR_END; - t[nrl][ncl] -= ndl; - - for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep; - for(i=nrl+1;i<=nrh;i++) { - t[i]=t[i-1]+ncol; - t[i][ncl]=t[i-1][ncl]+ncol*ndep; - for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep; - } - - /* return pointer to array of pointers to rows */ - return t; -} - -void free_vector(v,nl,nh) -float *v; -long nh,nl; -/* free a float vector allocated with vector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_ivector(v,nl,nh) -int *v; -long nh,nl; -/* free an int vector allocated with ivector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_cvector(v,nl,nh) -long nh,nl; -unsigned char *v; -/* free an unsigned char vector allocated with cvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_lvector(v,nl,nh) -long nh,nl; -unsigned long *v; -/* free an unsigned long vector allocated with lvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_dvector(v,nl,nh) -double *v; -long nh,nl; -/* free a double vector allocated with dvector() */ -{ - free((FREE_ARG) (v+nl-NR_END)); -} - -void free_matrix(m,nrl,nrh,ncl,nch) -float **m; -long nch,ncl,nrh,nrl; -/* free a float matrix allocated by matrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_dmatrix(m,nrl,nrh,ncl,nch) -double **m; -long nch,ncl,nrh,nrl; -/* free a double matrix allocated by dmatrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_imatrix(m,nrl,nrh,ncl,nch) -int **m; -long nch,ncl,nrh,nrl; -/* free an int matrix allocated by imatrix() */ -{ - free((FREE_ARG) (m[nrl]+ncl-NR_END)); - free((FREE_ARG) (m+nrl-NR_END)); -} - -void free_submatrix(b,nrl,nrh,ncl,nch) -float **b; -long nch,ncl,nrh,nrl; -/* free a submatrix allocated by submatrix() */ -{ - free((FREE_ARG) (b+nrl-NR_END)); -} - -void free_convert_matrix(b,nrl,nrh,ncl,nch) -float **b; -long nch,ncl,nrh,nrl; -/* free a matrix allocated by convert_matrix() */ -{ - free((FREE_ARG) (b+nrl-NR_END)); -} - -void free_f3tensor(t,nrl,nrh,ncl,nch,ndl,ndh) -float ***t; -long nch,ncl,ndh,ndl,nrh,nrl; -/* free a float f3tensor allocated by f3tensor() */ -{ - free((FREE_ARG) (t[nrl][ncl]+ndl-NR_END)); - free((FREE_ARG) (t[nrl]+ncl-NR_END)); - free((FREE_ARG) (t+nrl-NR_END)); -} - -#endif /* ANSI */ diff --git a/NR/nrutil.h b/NR/nrutil.h deleted file mode 100644 index 436193de5e..0000000000 --- a/NR/nrutil.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _NR_UTILS_H_ -#define _NR_UTILS_H_ - -/* This file has been modified for inclusion in Gmsh */ - -/* Gmsh: */ -#include "Gmsh.h" -#include "Numeric.h" - -/* Gmsh: -static float sqrarg; -#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg) - -static double dsqrarg; -#define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg) - -static double dmaxarg1,dmaxarg2; -#define DMAX(a,b) (dmaxarg1=(a),dmaxarg2=(b),(dmaxarg1) > (dmaxarg2) ?\ - (dmaxarg1) : (dmaxarg2)) - -static double dminarg1,dminarg2; -#define DMIN(a,b) (dminarg1=(a),dminarg2=(b),(dminarg1) < (dminarg2) ?\ - (dminarg1) : (dminarg2)) - -static float maxarg1,maxarg2; -#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\ - (maxarg1) : (maxarg2)) - -static float minarg1,minarg2; -#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\ - (minarg1) : (minarg2)) - -static long lmaxarg1,lmaxarg2; -#define LMAX(a,b) (lmaxarg1=(a),lmaxarg2=(b),(lmaxarg1) > (lmaxarg2) ?\ - (lmaxarg1) : (lmaxarg2)) - -static long lminarg1,lminarg2; -#define LMIN(a,b) (lminarg1=(a),lminarg2=(b),(lminarg1) < (lminarg2) ?\ - (lminarg1) : (lminarg2)) - -static int imaxarg1,imaxarg2; -#define IMAX(a,b) (imaxarg1=(a),imaxarg2=(b),(imaxarg1) > (imaxarg2) ?\ - (imaxarg1) : (imaxarg2)) - -static int iminarg1,iminarg2; -#define IMIN(a,b) (iminarg1=(a),iminarg2=(b),(iminarg1) < (iminarg2) ?\ - (iminarg1) : (iminarg2)) - -#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a)) -*/ - -#if defined(__STDC__) || defined(ANSI) || defined(NRANSI) /* ANSI */ - -void nrerror(char error_text[]); -float *vector(long nl, long nh); -int *ivector(long nl, long nh); -unsigned char *cvector(long nl, long nh); -unsigned long *lvector(long nl, long nh); -double *dvector(long nl, long nh); -float **matrix(long nrl, long nrh, long ncl, long nch); -double **dmatrix(long nrl, long nrh, long ncl, long nch); -int **imatrix(long nrl, long nrh, long ncl, long nch); -float **submatrix(float **a, long oldrl, long oldrh, long oldcl, long oldch, - long newrl, long newcl); -float **convert_matrix(float *a, long nrl, long nrh, long ncl, long nch); -float ***f3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh); -void free_vector(float *v, long nl, long nh); -void free_ivector(int *v, long nl, long nh); -void free_cvector(unsigned char *v, long nl, long nh); -void free_lvector(unsigned long *v, long nl, long nh); -void free_dvector(double *v, long nl, long nh); -void free_matrix(float **m, long nrl, long nrh, long ncl, long nch); -void free_dmatrix(double **m, long nrl, long nrh, long ncl, long nch); -void free_imatrix(int **m, long nrl, long nrh, long ncl, long nch); -void free_submatrix(float **b, long nrl, long nrh, long ncl, long nch); -void free_convert_matrix(float **b, long nrl, long nrh, long ncl, long nch); -void free_f3tensor(float ***t, long nrl, long nrh, long ncl, long nch, - long ndl, long ndh); - -#else /* ANSI */ -/* traditional - K&R */ - -void nrerror(); -float *vector(); -float **matrix(); -float **submatrix(); -float **convert_matrix(); -float ***f3tensor(); -double *dvector(); -double **dmatrix(); -int *ivector(); -int **imatrix(); -unsigned char *cvector(); -unsigned long *lvector(); -void free_vector(); -void free_dvector(); -void free_ivector(); -void free_cvector(); -void free_lvector(); -void free_matrix(); -void free_submatrix(); -void free_convert_matrix(); -void free_dmatrix(); -void free_imatrix(); -void free_f3tensor(); - -#endif /* ANSI */ - -#endif /* _NR_UTILS_H_ */ diff --git a/Netgen/COPYING.LIB b/Netgen/COPYING.LIB deleted file mode 100644 index b1e3f5a263..0000000000 --- a/Netgen/COPYING.LIB +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/Netgen/Makefile b/Netgen/Makefile deleted file mode 100644 index 3e6d384973..0000000000 --- a/Netgen/Makefile +++ /dev/null @@ -1,4412 +0,0 @@ -# $Id: Makefile,v 1.13 2005-07-15 10:31:06 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshNetgen.a -INCLUDE = -I../Common -Ilibsrc/include -Ilibsrc/interface -CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} -DNO_PARALLEL_THREADS -UWIN32 - -SRC = libsrc/opti/linopt.cpp \ - libsrc/opti/bfgs.cpp \ - libsrc/opti/linsearch.cpp \ - libsrc/meshing/global.cpp \ - libsrc/meshing/bisect.cpp \ - libsrc/meshing/meshtool.cpp \ - libsrc/meshing/refine.cpp \ - libsrc/meshing/ruler3.cpp \ - libsrc/meshing/improve3.cpp \ - libsrc/meshing/smoothing3.cpp \ - libsrc/meshing/adfront3.cpp \ - libsrc/meshing/tetrarls.cpp \ - libsrc/meshing/prism2rls.cpp \ - libsrc/meshing/pyramidrls.cpp \ - libsrc/meshing/pyramid2rls.cpp \ - libsrc/meshing/netrule3.cpp \ - libsrc/meshing/ruler2.cpp \ - libsrc/meshing/meshclass.cpp \ - libsrc/meshing/improve2.cpp \ - libsrc/meshing/smoothing2.cpp \ - libsrc/meshing/adfront2.cpp \ - libsrc/meshing/netrule2.cpp \ - libsrc/meshing/triarls.cpp \ - libsrc/meshing/geomsearch.cpp \ - libsrc/meshing/secondorder.cpp \ - libsrc/meshing/meshtype.cpp \ - libsrc/meshing/parser3.cpp \ - libsrc/meshing/meshing2.cpp \ - libsrc/meshing/quadrls.cpp \ - libsrc/meshing/specials.cpp \ - libsrc/meshing/parser2.cpp \ - libsrc/meshing/meshing3.cpp \ - libsrc/meshing/meshfunc.cpp \ - libsrc/meshing/localh.cpp \ - libsrc/meshing/improve2gen.cpp \ - libsrc/meshing/delaunay.cpp \ - libsrc/meshing/boundarylayer.cpp \ - libsrc/meshing/msghandler.cpp \ - libsrc/meshing/meshfunc2d.cpp \ - libsrc/meshing/topology.cpp \ - libsrc/meshing/clusters.cpp \ - libsrc/meshing/curvedelems.cpp \ - libsrc/meshing/curvedelems2.cpp \ - libsrc/meshing/hprefinement.cpp \ - libsrc/interface/nglib.cpp \ - libsrc/gprim/geomtest3d.cpp \ - libsrc/gprim/geom2d.cpp \ - libsrc/gprim/geom3d.cpp \ - libsrc/gprim/adtree.cpp \ - libsrc/gprim/transform3d.cpp \ - libsrc/gprim/geomfuncs.cpp \ - libsrc/linalg/polynomial.cpp \ - libsrc/linalg/densemat.cpp \ - libsrc/linalg/vector.cpp \ - libsrc/csg/algprim.cpp \ - libsrc/csg/brick.cpp \ - libsrc/csg/manifold.cpp \ - libsrc/csg/bspline2d.cpp \ - libsrc/csg/meshsurf.cpp \ - libsrc/csg/csgeom.cpp \ - libsrc/csg/polyhedra.cpp \ - libsrc/csg/curve2d.cpp \ - libsrc/csg/singularref.cpp \ - libsrc/csg/edgeflw.cpp \ - libsrc/csg/solid.cpp \ - libsrc/csg/explicitcurve2d.cpp \ - libsrc/csg/specpoin.cpp \ - libsrc/csg/gencyl.cpp \ - libsrc/csg/revolution.cpp \ - libsrc/csg/genmesh.cpp \ - libsrc/csg/spline3d.cpp \ - libsrc/csg/surface.cpp \ - libsrc/csg/identify.cpp \ - libsrc/csg/triapprox.cpp \ - libsrc/geom2d/geom2dmesh.cpp \ - libsrc/geom2d/spline2d.cpp \ - libsrc/geom2d/splinegeometry2.cpp \ - libsrc/geom2d/genmesh2d.cpp \ - libsrc/stlgeom/meshstlsurface.cpp \ - libsrc/stlgeom/stlline.cpp \ - libsrc/stlgeom/stltopology.cpp \ - libsrc/stlgeom/stltool.cpp \ - libsrc/stlgeom/stlgeom.cpp \ - libsrc/stlgeom/stlgeomchart.cpp \ - libsrc/stlgeom/stlgeommesh.cpp \ - libsrc/general/moveablemem.cpp \ - libsrc/general/ngexception.cpp \ - libsrc/general/table.cpp \ - libsrc/general/optmem.cpp \ - libsrc/general/spbita2d.cpp \ - libsrc/general/hashtabl.cpp \ - libsrc/general/sort.cpp \ - libsrc/general/flags.cpp \ - libsrc/general/seti.cpp \ - libsrc/general/bitarray.cpp \ - libsrc/general/array.cpp \ - libsrc/general/symbolta.cpp \ - libsrc/general/mystring.cpp \ - nglib_addon.cpp - -OBJ = ${SRC:.cpp=.o} - -.SUFFIXES: .o .cpp - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.cpp.o: - ${CXX} ${CFLAGS} -c $< -o ${<:.cpp=.o} - -clean: - rm -f libsrc/*/*.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -# 1 "/Users/geuzaine/.gmsh/Netgen//" -linopt.o: libsrc/opti/linopt.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -bfgs.o: libsrc/opti/bfgs.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -linsearch.o: libsrc/opti/linsearch.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -global.o: libsrc/meshing/global.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -bisect.o: libsrc/meshing/bisect.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshtool.o: libsrc/meshing/meshtool.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/meshing.hpp libsrc/include/../meshing/meshing.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/geometry2d.hpp libsrc/include/../geom2d/geometry2d.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/include/../geom2d/spline2d.hpp \ - libsrc/include/../geom2d/splinegeometry2.hpp \ - libsrc/include/../geom2d/geom2dmesh.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -refine.o: libsrc/meshing/refine.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -ruler3.o: libsrc/meshing/ruler3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -improve3.o: libsrc/meshing/improve3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/include/../opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -smoothing3.o: libsrc/meshing/smoothing3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/include/../opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -adfront3.o: libsrc/meshing/adfront3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -tetrarls.o: libsrc/meshing/tetrarls.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -prism2rls.o: libsrc/meshing/prism2rls.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -pyramidrls.o: libsrc/meshing/pyramidrls.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -pyramid2rls.o: libsrc/meshing/pyramid2rls.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -netrule3.o: libsrc/meshing/netrule3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -ruler2.o: libsrc/meshing/ruler2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshclass.o: libsrc/meshing/meshclass.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -improve2.o: libsrc/meshing/improve2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/include/../opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -smoothing2.o: libsrc/meshing/smoothing2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/include/../opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -adfront2.o: libsrc/meshing/adfront2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -netrule2.o: libsrc/meshing/netrule2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -triarls.o: libsrc/meshing/triarls.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -geomsearch.o: libsrc/meshing/geomsearch.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -secondorder.o: libsrc/meshing/secondorder.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshtype.o: libsrc/meshing/meshtype.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -parser3.o: libsrc/meshing/parser3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshing2.o: libsrc/meshing/meshing2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -quadrls.o: libsrc/meshing/quadrls.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -specials.o: libsrc/meshing/specials.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -parser2.o: libsrc/meshing/parser2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshing3.o: libsrc/meshing/meshing3.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshfunc.o: libsrc/meshing/meshfunc.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -localh.o: libsrc/meshing/localh.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -improve2gen.o: libsrc/meshing/improve2gen.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/include/../opti/opti.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -delaunay.o: libsrc/meshing/delaunay.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -boundarylayer.o: libsrc/meshing/boundarylayer.cpp \ - libsrc/include/mystdlib.h libsrc/meshing/meshing.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -msghandler.o: libsrc/meshing/msghandler.cpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mystdlib.h \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshfunc2d.o: libsrc/meshing/meshfunc2d.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -topology.o: libsrc/meshing/topology.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -clusters.o: libsrc/meshing/clusters.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -curvedelems.o: libsrc/meshing/curvedelems.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -curvedelems2.o: libsrc/meshing/curvedelems2.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -hprefinement.o: libsrc/meshing/hprefinement.cpp libsrc/include/mystdlib.h \ - libsrc/meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp libsrc/meshing/msghandler.hpp \ - libsrc/meshing/meshtype.hpp libsrc/meshing/localh.hpp \ - libsrc/meshing/meshclass.hpp libsrc/meshing/global.hpp \ - libsrc/meshing/meshtool.hpp libsrc/meshing/ruler2.hpp \ - libsrc/meshing/adfront2.hpp libsrc/meshing/meshing2.hpp \ - libsrc/meshing/improve2.hpp libsrc/meshing/geomsearch.hpp \ - libsrc/meshing/adfront3.hpp libsrc/meshing/ruler3.hpp \ - libsrc/meshing/meshing3.hpp libsrc/meshing/improve3.hpp \ - libsrc/meshing/findip.hpp libsrc/meshing/topology.hpp \ - libsrc/meshing/curvedelems.hpp libsrc/meshing/bisect.hpp \ - libsrc/meshing/clusters.hpp libsrc/meshing/meshfunc.hpp \ - libsrc/meshing/hprefinement.hpp libsrc/meshing/boundarylayer.hpp \ - libsrc/meshing/specials.hpp libsrc/meshing/hpref_trig.hpp \ - libsrc/meshing/hpref_quad.hpp libsrc/meshing/hpref_tet.hpp \ - libsrc/meshing/hpref_prism.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -nglib.o: libsrc/interface/nglib.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/stlgeom.hpp libsrc/include/../stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../stlgeom/stltopology.hpp \ - libsrc/include/../stlgeom/stltool.hpp \ - libsrc/include/../stlgeom/stlline.hpp \ - libsrc/include/../stlgeom/meshstlsurface.hpp \ - libsrc/include/geometry2d.hpp libsrc/include/../geom2d/geometry2d.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/include/../geom2d/spline2d.hpp \ - libsrc/include/../geom2d/splinegeometry2.hpp \ - libsrc/include/../geom2d/geom2dmesh.hpp libsrc/interface/nglib.h -# 1 "/Users/geuzaine/.gmsh/Netgen//" -geomtest3d.o: libsrc/gprim/geomtest3d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -geom2d.o: libsrc/gprim/geom2d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -geom3d.o: libsrc/gprim/geom3d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -adtree.o: libsrc/gprim/adtree.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -transform3d.o: libsrc/gprim/transform3d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -geomfuncs.o: libsrc/gprim/geomfuncs.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -polynomial.o: libsrc/linalg/polynomial.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -densemat.o: libsrc/linalg/densemat.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -vector.o: libsrc/linalg/vector.cpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -algprim.o: libsrc/csg/algprim.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -brick.o: libsrc/csg/brick.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -manifold.o: libsrc/csg/manifold.cpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mystdlib.h \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -bspline2d.o: libsrc/csg/bspline2d.cpp libsrc/include/mystdlib.h \ - libsrc/include/csg.hpp libsrc/include/../csg/csg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshsurf.o: libsrc/csg/meshsurf.cpp libsrc/include/mystdlib.h \ - libsrc/include/csg.hpp libsrc/include/../csg/csg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -csgeom.o: libsrc/csg/csgeom.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -polyhedra.o: libsrc/csg/polyhedra.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -curve2d.o: libsrc/csg/curve2d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -singularref.o: libsrc/csg/singularref.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -edgeflw.o: libsrc/csg/edgeflw.cpp libsrc/include/mystdlib.h \ - libsrc/include/meshing.hpp libsrc/include/../meshing/meshing.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -solid.o: libsrc/csg/solid.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -explicitcurve2d.o: libsrc/csg/explicitcurve2d.cpp \ - libsrc/include/mystdlib.h libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -specpoin.o: libsrc/csg/specpoin.cpp libsrc/include/mystdlib.h \ - libsrc/include/meshing.hpp libsrc/include/../meshing/meshing.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -gencyl.o: libsrc/csg/gencyl.cpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mystdlib.h \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -revolution.o: libsrc/csg/revolution.cpp libsrc/include/mystdlib.h \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -genmesh.o: libsrc/csg/genmesh.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -spline3d.o: libsrc/csg/spline3d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -surface.o: libsrc/csg/surface.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/../linalg/linalg.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -identify.o: libsrc/csg/identify.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -triapprox.o: libsrc/csg/triapprox.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -geom2dmesh.o: libsrc/geom2d/geom2dmesh.cpp libsrc/include/mystdlib.h \ - libsrc/include/csg.hpp libsrc/include/../csg/csg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/geometry2d.hpp libsrc/include/../geom2d/geometry2d.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/include/../geom2d/spline2d.hpp \ - libsrc/include/../geom2d/splinegeometry2.hpp \ - libsrc/include/../geom2d/geom2dmesh.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -spline2d.o: libsrc/geom2d/spline2d.cpp libsrc/include/mystdlib.h \ - libsrc/include/csg.hpp libsrc/include/../csg/csg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/geom2d/spline2d.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -splinegeometry2.o: libsrc/geom2d/splinegeometry2.cpp \ - libsrc/include/mystdlib.h libsrc/include/csg.hpp \ - libsrc/include/../csg/csg.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/geom2d/spline2d.hpp \ - libsrc/geom2d/splinegeometry2.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -genmesh2d.o: libsrc/geom2d/genmesh2d.cpp libsrc/include/mystdlib.h \ - libsrc/include/csg.hpp libsrc/include/../csg/csg.hpp \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/linalg.hpp libsrc/include/../linalg/linalg.hpp \ - libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp \ - libsrc/include/../csg/surface.hpp libsrc/include/../csg/solid.hpp \ - libsrc/include/../csg/identify.hpp \ - libsrc/include/../csg/singularref.hpp libsrc/include/../csg/csgeom.hpp \ - libsrc/include/../csg/triapprox.hpp libsrc/include/../csg/algprim.hpp \ - libsrc/include/../csg/brick.hpp libsrc/include/../csg/spline3d.hpp \ - libsrc/include/../csg/manifold.hpp libsrc/include/../csg/curve2d.hpp \ - libsrc/include/../csg/explicitcurve2d.hpp \ - libsrc/include/../csg/gencyl.hpp libsrc/include/../csg/polyhedra.hpp \ - libsrc/include/../csg/extrusion.hpp \ - libsrc/include/../csg/revolution.hpp libsrc/include/../csg/specpoin.hpp \ - libsrc/include/../csg/edgeflw.hpp libsrc/include/../csg/meshsurf.hpp \ - libsrc/include/geometry2d.hpp libsrc/include/../geom2d/geometry2d.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/include/../geom2d/spline2d.hpp \ - libsrc/include/../geom2d/splinegeometry2.hpp \ - libsrc/include/../geom2d/geom2dmesh.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -meshstlsurface.o: libsrc/stlgeom/meshstlsurface.cpp \ - libsrc/include/mystdlib.h libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mydefs.hpp \ - libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -stlline.o: libsrc/stlgeom/stlline.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -stltopology.o: libsrc/stlgeom/stltopology.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -stltool.o: libsrc/stlgeom/stltool.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -stlgeom.o: libsrc/stlgeom/stlgeom.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -stlgeomchart.o: libsrc/stlgeom/stlgeomchart.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -stlgeommesh.o: libsrc/stlgeom/stlgeommesh.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/stlgeom/stlgeom.hpp \ - libsrc/include/../gprim/gprim.hpp libsrc/stlgeom/stltopology.hpp \ - libsrc/stlgeom/stltool.hpp libsrc/stlgeom/stlline.hpp \ - libsrc/stlgeom/meshstlsurface.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -moveablemem.o: libsrc/general/moveablemem.cpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mystdlib.h \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -ngexception.o: libsrc/general/ngexception.cpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mystdlib.h \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -table.o: libsrc/general/table.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -optmem.o: libsrc/general/optmem.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -spbita2d.o: libsrc/general/spbita2d.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -hashtabl.o: libsrc/general/hashtabl.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -sort.o: libsrc/general/sort.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -flags.o: libsrc/general/flags.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -seti.o: libsrc/general/seti.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -bitarray.o: libsrc/general/bitarray.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -array.o: libsrc/general/array.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -symbolta.o: libsrc/general/symbolta.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -mystring.o: libsrc/general/mystring.cpp libsrc/include/mystdlib.h \ - libsrc/include/myadt.hpp libsrc/include/../general/myadt.hpp \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp -# 1 "/Users/geuzaine/.gmsh/Netgen//" -nglib_addon.o: nglib_addon.cpp libsrc/include/meshing.hpp \ - libsrc/include/../meshing/meshing.hpp libsrc/include/myadt.hpp \ - libsrc/include/../general/myadt.hpp libsrc/include/mystdlib.h \ - libsrc/include/mydefs.hpp libsrc/include/../general/ngexception.hpp \ - libsrc/include/../general/parthreads.hpp \ - libsrc/include/../general/moveablemem.hpp \ - libsrc/include/../general/dynamicmem.hpp \ - libsrc/include/../general/template.hpp \ - libsrc/include/../general/array.hpp libsrc/include/../general/table.hpp \ - libsrc/include/../general/hashtabl.hpp \ - libsrc/include/../general/symbolta.hpp \ - libsrc/include/../general/bitarray.hpp \ - libsrc/include/../general/flags.hpp \ - libsrc/include/../general/spbita2d.hpp \ - libsrc/include/../general/seti.hpp libsrc/include/../general/optmem.hpp \ - libsrc/include/../general/autoptr.hpp \ - libsrc/include/../general/sort.hpp libsrc/include/../general/stack.hpp \ - libsrc/include/../general/mystring.hpp libsrc/include/gprim.hpp \ - libsrc/include/../gprim/gprim.hpp \ - libsrc/include/../gprim/geomobjects.hpp \ - libsrc/include/../gprim/geomops.hpp \ - libsrc/include/../gprim/geomfuncs.hpp \ - libsrc/include/../gprim/geom2d.hpp libsrc/include/../gprim/geom3d.hpp \ - libsrc/include/../gprim/geomtest3d.hpp \ - libsrc/include/../gprim/transform3d.hpp \ - libsrc/include/../gprim/adtree.hpp libsrc/include/linalg.hpp \ - libsrc/include/../linalg/linalg.hpp libsrc/include/../linalg/vector.hpp \ - libsrc/include/../linalg/densemat.hpp \ - libsrc/include/../linalg/polynomial.hpp libsrc/include/opti.hpp \ - libsrc/include/../opti/opti.hpp \ - libsrc/include/../meshing/msghandler.hpp \ - libsrc/include/../meshing/meshtype.hpp \ - libsrc/include/../meshing/localh.hpp \ - libsrc/include/../meshing/meshclass.hpp \ - libsrc/include/../meshing/global.hpp \ - libsrc/include/../meshing/meshtool.hpp \ - libsrc/include/../meshing/ruler2.hpp \ - libsrc/include/../meshing/adfront2.hpp \ - libsrc/include/../meshing/meshing2.hpp \ - libsrc/include/../meshing/improve2.hpp \ - libsrc/include/../meshing/geomsearch.hpp \ - libsrc/include/../meshing/adfront3.hpp \ - libsrc/include/../meshing/ruler3.hpp \ - libsrc/include/../meshing/meshing3.hpp \ - libsrc/include/../meshing/improve3.hpp \ - libsrc/include/../meshing/findip.hpp \ - libsrc/include/../meshing/topology.hpp \ - libsrc/include/../meshing/curvedelems.hpp \ - libsrc/include/../meshing/bisect.hpp \ - libsrc/include/../meshing/clusters.hpp \ - libsrc/include/../meshing/meshfunc.hpp \ - libsrc/include/../meshing/hprefinement.hpp \ - libsrc/include/../meshing/boundarylayer.hpp \ - libsrc/include/../meshing/specials.hpp libsrc/interface/nglib.h \ - ../Common/Message.h diff --git a/Netgen/README b/Netgen/README deleted file mode 100644 index 08e5573ac2..0000000000 --- a/Netgen/README +++ /dev/null @@ -1,72 +0,0 @@ - -This directory may contain a slightly modified version of Joachim -Sch\"oberl's NETGEN mesh generator: - -- only the libsrc directory was kept from the original distribution - -- the file meshing/improve2.cpp was slightly modified to fix build - problems on machines without TCL/TK - -- the file meshing/meshtype.hpp was slightly modified so that it - compiles with ISO-C++ complient compilers - -**IMPORTANT NOTICE** - -NETGEN requires the boundary mesh to be oriented with exterior -pointing normals. You HAVE TO define your geometry so that this -criterion is fulfilled (i.e., correctly orient the geometry surfaces -and the surface loops). - -************************************************************** - -From NETGEN's documentation: - -What is NETGEN -============== - -NETGEN is an automatic mesh generation tool for two and three -dimensions. Netgen is open source under the conditions of the LGPL. -It comes as stand alone programme with graphical user interface, or as -C++ library to be linked into an other application. Netgen is -available for Unix/Linux and Windows 98/NT. Netgen generates -triangular or quadrilateral meshes in 2D, and tetrahedral meshes in -3D. The input for 2D is described by spline curves, and the input for -3D problems is either defined by constructive solid geometries (CSG) -or by the standard STL file format. NETGEN contains modules for mesh -optimization and hierarchical mesh refinement. Curved elements are -supported of arbitrary order. - -The history of NETGEN -===================== - -The NETGEN project was started 1994 in the master's programme of -Joachim Sch\"oberl, under supervision of Prof. Ulrich Langer, at the -Department of Computational Mathematics and Optimization, University -Linz, Austria. Its further development was supported by the Austrian -science Fund ``Fonds zur F\"orderung der wissenschaftlichen -Forschung'' (http://www.fwf.ac.at) under projects P 10643-TEC and SFB -1306. The current home of Netgen is the Start project ``hp-FEM'' -(http://www.hpfem.jku.at) granted by the FWF. - -Special thanks go to -- Robert Gaisbauer: High order curved elements -- Hannes Gerstmayr: Meshing of STL geometry - -How to receive NETGEN -===================== - -NETGEN is available from the WEB at http://www.hpfem.jku.at/netgen -You find there source code releases for Linux/Unix/Windows, as well -as compiled versions for Windows. You can use CVS access to receive -the most up to date version. - -************************************************************** - -From NETGEN's README.install file: - -Latest information is available from: -http://www.sfb013.uni-linz.ac.at/~joachim/netgen - -People might have asked similar questions on -https://www.sfb013.uni-linz.ac.at/mailman/listinfo/netgen -(please note the s in https) diff --git a/Netgen/VERSION b/Netgen/VERSION deleted file mode 100644 index f56504b6db..0000000000 --- a/Netgen/VERSION +++ /dev/null @@ -1 +0,0 @@ -NG Version 4.4 \ No newline at end of file diff --git a/Netgen/libsrc/Makefile b/Netgen/libsrc/Makefile deleted file mode 100644 index 4bf820bc2a..0000000000 --- a/Netgen/libsrc/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# -# -appl = NETGEN -.default all: -# -# -all: - @ (cd linalg; $(MAKE) -f Makefile) - @ (cd general; $(MAKE) -f Makefile) - @ (cd gprim; $(MAKE) -f Makefile) - @ (cd csg; $(MAKE) -f Makefile) - @ (cd geom2d; $(MAKE) -f Makefile) - @ (cd stlgeom; $(MAKE) -f Makefile) - @ (cd occ; $(MAKE) -f Makefile) - @ (cd meshing; $(MAKE) -f Makefile) - @ (cd opti; $(MAKE) -f Makefile) - @ (cd visualization; $(MAKE) -f Makefile) - @ (cd interface; $(MAKE) -f Makefile) -# -# @ (cd step; $(MAKE) -f Makefile) -# @ (cd stepgeom; $(MAKE) -f Makefile) -# @ (cd graphics; $(MAKE) -f Makefile) - -tar: - tar cvf ../../libsrc.tar Makefile - tar rf ../../libsrc.tar linalg/Makefile linalg/*.hh linalg/*.cc - tar rf ../../libsrc.tar general/Makefile general/*.hh general/*.cc - tar rf ../../libsrc.tar gprim/Makefile gprim/*.hh gprim/*.cc - tar rf ../../libsrc.tar csg/Makefile csg/*.hh csg/*.cc - tar rf ../../libsrc.tar stlgeom/Makefile stlgeom/*.hh stlgeom/*.cc - tar rf ../../libsrc.tar occ/Makefile occ/*.h* occ/*.c* - tar rf ../../libsrc.tar meshing/Makefile meshing/*.hh meshing/*.cc meshing/*.h - tar rf ../../libsrc.tar opti/Makefile opti/*.hh opti/*.cc - tar rf ../../libsrc.tar step/Makefile step/*.h step/*.cc - tar rf ../../libsrc.tar stepgeom/Makefile stepgeom/*.hh stepgeom/*.cc - tar tf ../../libsrc.tar include/*.h include/*.hh - gzip -9 ../../libsrc.tar - diff --git a/Netgen/libsrc/csg/Makefile b/Netgen/libsrc/csg/Makefile deleted file mode 100644 index e8c51dc218..0000000000 --- a/Netgen/libsrc/csg/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# Makefile for geometric library -# -src = csgparser.cpp algprim.cpp curve2d.cpp brick.cpp \ - solid.cpp spline3d.cpp surface.cpp bspline2d.cpp \ - explicitcurve2d.cpp gencyl.cpp csgeom.cpp polyhedra.cpp extrusion.cpp revolution.cpp \ - manifold.cpp curve2d.cpp triapprox.cpp identify.cpp \ - singularref.cpp \ - edgeflw.cpp specpoin.cpp meshsurf.cpp genmesh.cpp -# -# lex.yy.cpp geometry.cpp -# -lib = csg -libpath = libsrc/csg -# -# -include ../makefile.inc -# -# geometry.cpp : geometry.yy -# bison -d -o geometry.c geometry.yy -# mv -f geometry.c geometry.cpp -# -# lex.yy.cpp : geometry.yy geometry.ll -# flex -+ -d -I geometry.ll -# mv lex.yy.cc lex.yy.cpp - diff --git a/Netgen/libsrc/csg/algprim.cpp b/Netgen/libsrc/csg/algprim.cpp deleted file mode 100644 index 1123706b1e..0000000000 --- a/Netgen/libsrc/csg/algprim.cpp +++ /dev/null @@ -1,1389 +0,0 @@ -#include <mystdlib.h> - - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - -double -QuadraticSurface :: CalcFunctionValue (const Point<3> & p) const -{ - return p(0) * (cxx * p(0) + cxy * p(1) + cxz * p(2) + cx) + - p(1) * (cyy * p(1) + cyz * p(2) + cy) + - p(2) * (czz * p(2) + cz) + c1; -} - -void -QuadraticSurface :: CalcGradient (const Point<3> & p, Vec<3> & grad) const -{ - grad(0) = 2 * cxx * p(0) + cxy * p(1) + cxz * p(2) + cx; - grad(1) = 2 * cyy * p(1) + cxy * p(0) + cyz * p(2) + cy; - grad(2) = 2 * czz * p(2) + cxz * p(0) + cyz * p(1) + cz; -} - -void -QuadraticSurface :: CalcHesse (const Point<3> & /* p */, Mat<3> & hesse) const -{ - hesse(0,0) = 2 * cxx; - hesse(1,1) = 2 * cyy; - hesse(2,2) = 2 * czz; - hesse(0,1) = hesse(1,0) = cxy; - hesse(0,2) = hesse(2,0) = cxz; - hesse(1,2) = hesse(2,1) = cyz; -} - - -void QuadraticSurface :: Read (istream & ist) -{ - ist >> cxx >> cyy >> czz >> cxy >> cxz >> cyz >> cx >> cy >> cz >> c1; -} - -void QuadraticSurface :: Print (ostream & ost) const -{ - ost << cxx << " " << cyy << " " << czz << " " - << cxy << " " << cxz << " " << cyz << " " - << cx << " " << cy << " " << cz << " " - << c1 << endl; -} - - -void QuadraticSurface :: PrintCoeff (ostream & ost) const -{ - ost << " cxx = " << cxx - << " cyy = " << cyy - << " czz = " << czz - << " cxy = " << cxy - << " cxz = " << cxz - << " cyz = " << cyz - << " cx = " << cx - << " cy = " << cy - << " cz = " << cz - << " c1 = " << c1 << endl; -} - - - -Point<3> QuadraticSurface :: GetSurfacePoint () const -{ - MyError ("GetSurfacePoint called for QuadraticSurface"); - return Point<3> (0, 0, 0); -} - - -Plane :: Plane (const Point<3> & ap, Vec<3> an) -{ - p = ap; - n = an; - n.Normalize(); - - cxx = cyy = czz = cxy = cxz = cyz = 0; - cx = n(0); cy = n(1); cz = n(2); - c1 = - (cx * p(0) + cy * p(1) + cz * p(2)); -} - -Primitive * Plane :: Copy () const -{ - return new Plane (p, n); -} - -void Plane :: Transform (Transformation<3> & trans) -{ - Point<3> hp; - Vec<3> hn; - trans.Transform (p, hp); - trans.Transform (n, hn); - p = hp; - n = hn; - - cxx = cyy = czz = cxy = cxz = cyz = 0; - cx = n(0); cy = n(1); cz = n(2); - c1 = - (cx * p(0) + cy * p(1) + cz * p(2)); -} - - - -void Plane :: GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const -{ - classname = "plane"; - coeffs.SetSize (6); - coeffs.Elem(1) = p(0); - coeffs.Elem(2) = p(1); - coeffs.Elem(3) = p(2); - coeffs.Elem(4) = n(0); - coeffs.Elem(5) = n(1); - coeffs.Elem(6) = n(2); -} - -void Plane :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - p(0) = coeffs.Elem(1); - p(1) = coeffs.Elem(2); - p(2) = coeffs.Elem(3); - n(0) = coeffs.Elem(4); - n(1) = coeffs.Elem(5); - n(2) = coeffs.Elem(6); - - n.Normalize(); - - cxx = cyy = czz = cxy = cxz = cyz = 0; - cx = n(0); cy = n(1); cz = n(2); - c1 = - (cx * p(0) + cy * p(1) + cz * p(2)); -} - -Primitive * Plane :: CreateDefault () -{ - return new Plane (Point<3> (0,0,0), Vec<3> (0,0,1)); -} - - -int Plane :: IsIdentic (const Surface & s2, int & inv, double eps) const -{ - if (fabs (s2.CalcFunctionValue(p)) > eps) return 0; - Vec<3> hv1, hv2; - hv1 = n.GetNormal (); - hv2 = Cross (n, hv1); - - Point<3> hp = p + hv1; - if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0; - hp = p + hv2; - if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0; - - Vec<3> n1, n2; - n1 = GetNormalVector (p); - n2 = s2.GetNormalVector (p); - inv = (n1 * n2 < 0); - return 1; -} - - - -void Plane :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) -{ - Surface::DefineTangentialPlane (ap1, ap2); -} - - -void Plane :: ToPlane (const Point<3> & p3d, - Point<2> & pplane, - double h, int & zone) const -{ - Vec<3> p1p; - - p1p = p3d - p1; - p1p /= h; - pplane(0) = p1p * ex; - pplane(1) = p1p * ey; - zone = 0; -} - -void Plane :: FromPlane (const Point<2> & pplane, Point<3> & p3d, double h) const -{ - /* - Vec<3> p1p; - Point<2> pplane2 = pplane; - - pplane2 *= h; - p1p = pplane2(0) * ex + pplane2(1) * ey; - p3d = p1 + p1p; - */ - p3d = p1 + (h * pplane(0)) * ex + (h * pplane(1)) * ey; -} - - -void Plane :: Project (Point<3> & p3d) const -{ - double val = Plane::CalcFunctionValue (p3d); - p3d -= val * n; -} - -INSOLID_TYPE Plane :: BoxInSolid (const BoxSphere<3> & box) const -{ - int i; - double val; - Point<3> p; - - val = Plane::CalcFunctionValue (box.Center()); - if (val > box.Diam() / 2) return IS_OUTSIDE; - if (val < -box.Diam() / 2) return IS_INSIDE; - - if (val > 0) - { - /* - double modify = - ((box.MaxX()-box.MinX()) * fabs (cx) + - (box.MaxY()-box.MinY()) * fabs (cy) + - (box.MaxZ()-box.MinZ()) * fabs (cz)) / 2; - */ - Vec<3> vdiag = box.PMax() - box.PMin(); - double modify = (vdiag(0) * fabs (cx) + - vdiag(1) * fabs (cy) + - vdiag(2) * fabs (cz) ) / 2; - - if (val - modify < 0) - return DOES_INTERSECT; - return IS_OUTSIDE; - - // only outside or intersect possible - for (i = 0; i < 8; i++) - { - p = box.GetPointNr (i); - val = Plane::CalcFunctionValue (p); - if (val < 0) - return DOES_INTERSECT; - } - return IS_OUTSIDE; - } - else - { - /* - double modify = - ((box.MaxX()-box.MinX()) * fabs (cx) + - (box.MaxY()-box.MinY()) * fabs (cy) + - (box.MaxZ()-box.MinZ()) * fabs (cz)) / 2; - */ - Vec<3> vdiag = box.PMax() - box.PMin(); - double modify = (vdiag(0) * fabs (cx) + - vdiag(1) * fabs (cy) + - vdiag(2) * fabs (cz) ) / 2; - if (val + modify > 0) - return DOES_INTERSECT; - return IS_INSIDE; - - - // only inside or intersect possible - for (i = 0; i < 8; i++) - { - p = box.GetPointNr (i); - val = Plane::CalcFunctionValue (p); - if (val > 0) - return DOES_INTERSECT; - } - return IS_INSIDE; - } - - - - /* - for (i = 1; i <= 8; i++) - { - box.GetPointNr (i, p); - val = CalcFunctionValue (p); - if (val > 0) inside = 0; - if (val < 0) outside = 0; - } - - if (inside) return IS_INSIDE; - if (outside) return IS_OUTSIDE; - return DOES_INTERSECT; - */ -} - - - -// double Plane :: CalcFunctionValue (const Point<3> & p3d) const -// { -// return cx * p3d(0) + cy * p3d(1) + cz * p3d(2) + c1; -// } - -void Plane :: CalcGradient (const Point<3> & /* p */, Vec<3> & grad) const -{ - grad(0) = cx; - grad(1) = cy; - grad(2) = cz; -} - -void Plane :: CalcHesse (const Point<3> & /* p */, Mat<3> & hesse) const -{ - hesse = 0; -} - -double Plane :: HesseNorm () const -{ - return 0; -} - - -Point<3> Plane :: GetSurfacePoint () const -{ - return p; -} - - -void Plane :: GetTriangleApproximation -(TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const -{ - // find triangle, such that - // boundingbox /cap plane is contained in it - - Point<3> c = boundingbox.Center(); - double r = boundingbox.Diam(); - - Project (c); - Vec<3> t1 = n.GetNormal(); - Vec<3> t2 = Cross (n, t1); - - t1.Normalize(); - t2.Normalize(); - - tas.AddPoint (c + (-0.5 * r) * t2 + (sqrt(0.75) * r) * t1); - tas.AddPoint (c + (-0.5 * r) * t2 + (-sqrt(0.75) * r) * t1); - tas.AddPoint (c + r * t2); - - tas.AddTriangle (TATriangle (0, 0, 1, 2)); -} - - - - -Sphere :: Sphere (const Point<3> & ac, double ar) -{ - c = ac; - r = ar; - - cxx = cyy = czz = 0.5 / r; - cxy = cxz = cyz = 0; - cx = - c(0) / r; - cy = - c(1) / r; - cz = - c(2) / r; - c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2; -} - -void Sphere :: GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const -{ - classname = "sphere"; - coeffs.SetSize (4); - coeffs.Elem(1) = c(0); - coeffs.Elem(2) = c(1); - coeffs.Elem(3) = c(2); - coeffs.Elem(4) = r; -} - -void Sphere :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - c(0) = coeffs.Elem(1); - c(1) = coeffs.Elem(2); - c(2) = coeffs.Elem(3); - r = coeffs.Elem(4); - - cxx = cyy = czz = 0.5 / r; - cxy = cxz = cyz = 0; - cx = - c(0) / r; - cy = - c(1) / r; - cz = - c(2) / r; - c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2; -} - -Primitive * Sphere :: CreateDefault () -{ - return new Sphere (Point<3> (0,0,0), 1); -} - - - -Primitive * Sphere :: Copy () const -{ - return new Sphere (c, r); -} - -void Sphere :: Transform (Transformation<3> & trans) -{ - Point<3> hp; - trans.Transform (c, hp); - c = hp; - - cxx = cyy = czz = 0.5 / r; - cxy = cxz = cyz = 0; - cx = - c(0) / r; - cy = - c(1) / r; - cz = - c(2) / r; - c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2; -} - - - - -int Sphere :: IsIdentic (const Surface & s2, int & inv, double eps) const -{ - const Sphere * sp2 = dynamic_cast<const Sphere*> (&s2); - - if (!sp2) return 0; - - if (Dist (sp2->c, c) > eps) return 0; - if (fabs (sp2->r - r) > eps) return 0; - - inv = 0; - - return 1; -} - - -void Sphere :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) -{ - Surface::DefineTangentialPlane (ap1, ap2); - - ez = p1 - c; - ez /= ez.Length(); - - ex = p2 - p1; - ex -= (ex * ez) * ez; - ex /= ex.Length(); - - ey = Cross (ez, ex); -} - - -void Sphere :: ToPlane (const Point<3> & p, Point<2> & pplane, double h, int & zone) const -{ - Vec<3> p1p; - - p1p = p - p1; - - /* - if (p1p * ez < -r) - { - zone = -1; - pplane = Point<2> (1E8, 1E8); - } - else - { - zone = 0; - p1p /= h; - pplane(0) = p1p * ex; - pplane(1) = p1p * ey; - } - */ - - Point<3> p1top = c + (c - p1); - - Vec<3> p1topp = p - p1top; - Vec<3> p1topp1 = p1 - p1top; - Vec<3> lam; - // SolveLinearSystem (ex, ey, p1topp, p1topp1, lam); - - Mat<3> m; - for (int i = 0; i < 3; i++) - { - m(i, 0) = ex(i); - m(i, 1) = ey(i); - m(i, 2) = p1topp(i); - } - m.Solve (p1topp1, lam); - - pplane(0) = -lam(0) / h; - pplane(1) = -lam(1) / h; - - if (lam(2) > 2) - zone = -1; - else - zone = 0; -} - -void Sphere :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const -{ - /* - // Vec<3> p1p; - double z; - Point<2> pplane2 (pplane); - - pplane2(0) *= h; - pplane2(1) *= h; - z = -r + sqrt (sqr (r) - sqr (pplane2(0)) - sqr (pplane2(1))); - // p = p1; - p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0) + z * ez(0); - p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1) + z * ez(1); - p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2) + z * ez(2); - */ - - Point<2> pplane2 (pplane); - - pplane2(0) *= h; - pplane2(1) *= h; - - p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0); - p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1); - p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2); - Project (p); -} - - -void Sphere :: Project (Point<3> & p) const -{ - Vec<3> v; - v = p - c; - v *= (r / v.Length()); - p = c + v; -} - - -INSOLID_TYPE Sphere :: BoxInSolid (const BoxSphere<3> & box) const -{ - double dist; - dist = Dist (box.Center(), c); - - if (dist - box.Diam()/2 > r) return IS_OUTSIDE; - if (dist + box.Diam()/2 < r) return IS_INSIDE; - return DOES_INTERSECT; -} - -double Sphere :: HesseNorm () const -{ - return 2 / r; -} - - -Point<3> Sphere :: GetSurfacePoint () const -{ - return c + Vec<3> (r, 0, 0); -} - - -void Sphere :: GetTriangleApproximation -(TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const -{ - int i, j; - double lg, bg; - int n = int(facets) + 1; - - for (j = 0; j <= n; j++) - for (i = 0; i <= n; i++) - { - lg = 2 * M_PI * double (i) / n; - bg = M_PI * (double(j) / n - 0.5); - - Point<3> p(c(0) + r * cos(bg) * sin (lg), - c(1) + r * cos(bg) * cos (lg), - c(2) + r * sin(bg)); - tas.AddPoint (p); - } - - for (j = 0; j < n; j++) - for (i = 0; i < n; i++) - { - int pi = i + (n+1) * j; - tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); - tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); - } -} - - - - - -Ellipsoid :: -Ellipsoid (const Point<3> & aa, - const Vec<3> & av1, const Vec<3> & av2, const Vec<3> & av3) -{ - a = aa; - v1 = av1; - v2 = av2; - v3 = av3; - - CalcData(); -} - - -void Ellipsoid :: CalcData () -{ - // f = (x-a, vl)^2 / |vl|^2 + (x-a, vs)^2 / |vs|^2 -1 - // f = sum_{i=1}^3 (x-a,v_i)^2 / |vi|^4 - 1 = sum (x-a,hv_i)^2 - - Vec<3> hv1, hv2, hv3; - double lv1 = v1.Length2 (); - if (lv1 < 1e-32) lv1 = 1; - double lv2 = v2.Length2 (); - if (lv2 < 1e-32) lv2 = 1; - double lv3 = v3.Length2 (); - if (lv3 < 1e-32) lv3 = 1; - - rmin = sqrt (min3 (lv1, lv2, lv3)); - - hv1 = (1.0 / lv1) * v1; - hv2 = (1.0 / lv2) * v2; - hv3 = (1.0 / lv3) * v3; - - cxx = hv1(0) * hv1(0) + hv2(0) * hv2(0) + hv3(0) * hv3(0); - cyy = hv1(1) * hv1(1) + hv2(1) * hv2(1) + hv3(1) * hv3(1); - czz = hv1(2) * hv1(2) + hv2(2) * hv2(2) + hv3(2) * hv3(2); - - cxy = 2 * (hv1(0) * hv1(1) + hv2(0) * hv2(1) + hv3(0) * hv3(1)); - cxz = 2 * (hv1(0) * hv1(2) + hv2(0) * hv2(2) + hv3(0) * hv3(2)); - cyz = 2 * (hv1(1) * hv1(2) + hv2(1) * hv2(2) + hv3(1) * hv3(2)); - - Vec<3> va (a); - c1 = sqr(va * hv1) + sqr(va * hv2) + sqr(va * hv3) - 1; - - Vec<3> v = -2 * (va * hv1) * hv1 - 2 * (va * hv2) * hv2 - 2 * (va * hv3) * hv3; - cx = v(0); - cy = v(1); - cz = v(2); -} - - -INSOLID_TYPE Ellipsoid :: BoxInSolid (const BoxSphere<3> & box) const -{ - // double grad = 2.0 / rmin; - // double grad = 3*(box.Center()-a).Length() / (rmin*rmin*rmin); - - double ggrad = 1.0 / (rmin*rmin); - Vec<3> g; - double val = CalcFunctionValue (box.Center()); - CalcGradient (box.Center(), g); - double grad = g.Length(); - - double r = box.Diam() / 2; - double maxval = grad * r + ggrad * r * r; - - // (*testout) << "box = " << box << ", val = " << val << ", maxval = " << maxval << endl; - - if (val > maxval) return IS_OUTSIDE; - if (val < -maxval) return IS_INSIDE; - return DOES_INTERSECT; -} - - -double Ellipsoid :: HesseNorm () const -{ - return 1.0/ (rmin * rmin); -} - -Point<3> Ellipsoid :: GetSurfacePoint () const -{ - return a + v1; -} - - - -void Ellipsoid :: GetTriangleApproximation -(TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const -{ - int i, j; - double lg, bg; - int n = int(facets) + 1; - - for (j = 0; j <= n; j++) - for (i = 0; i <= n; i++) - { - lg = 2 * M_PI * double (i) / n; - bg = M_PI * (double(j) / n - 0.5); - - - Point<3> p(a + - sin (bg) * v1 + - cos (bg) * sin (lg) * v2 + - cos (bg) * cos (lg) * v3); - - tas.AddPoint (p); - } - - for (j = 0; j < n; j++) - for (i = 0; i < n; i++) - { - int pi = i + (n+1) * j; - tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); - tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); - } -} - - - - - - - - - - - - - - - - - - - - -Cylinder :: Cylinder (const Point<3> & aa, const Point<3> & ab, double ar) -{ - a = aa; - b = ab; - vab = (b - a); - vab /= vab.Length(); - r = ar; - - // ( <x,x> - 2 <x,a> + <a,a> - // - <x,vab>^2 + 2 <x,vab> <a, vab> - <a, vab>^2 - // - r^2) / (2r) = 0 - - double hv; - cxx = cyy = czz = 0.5 / r; - cxy = cxz = cyz = 0; - cx = - a(0) / r; - cy = - a(1) / r; - cz = - a(2) / r; - c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r); - hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2); - cxx -= vab(0) * vab(0) / (2 * r); - cyy -= vab(1) * vab(1) / (2 * r); - czz -= vab(2) * vab(2) / (2 * r); - cxy -= vab(0) * vab(1) / r; - cxz -= vab(0) * vab(2) / r; - cyz -= vab(1) * vab(2) / r; - cx += vab(0) * hv / r; - cy += vab(1) * hv / r; - cz += vab(2) * hv / r; - c1 -= hv * hv / (2 * r); - c1 -= r / 2; - // PrintCoeff (); -} - - - -void Cylinder :: GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const -{ - classname = "cylinder"; - coeffs.SetSize (7); - coeffs.Elem(1) = a(0); - coeffs.Elem(2) = a(1); - coeffs.Elem(3) = a(2); - coeffs.Elem(4) = b(0); - coeffs.Elem(5) = b(1); - coeffs.Elem(6) = b(2); - coeffs.Elem(7) = r; -} - -void Cylinder :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - a(0) = coeffs.Elem(1); - a(1) = coeffs.Elem(2); - a(2) = coeffs.Elem(3); - b(0) = coeffs.Elem(4); - b(1) = coeffs.Elem(5); - b(2) = coeffs.Elem(6); - r = coeffs.Elem(7); - - - vab = (b - a); - vab /= vab.Length(); - - - double hv; - cxx = cyy = czz = 0.5 / r; - cxy = cxz = cyz = 0; - cx = - a(0) / r; - cy = - a(1) / r; - cz = - a(2) / r; - c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r); - hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2); - cxx -= vab(0) * vab(0) / (2 * r); - cyy -= vab(1) * vab(1) / (2 * r); - czz -= vab(2) * vab(2) / (2 * r); - cxy -= vab(0) * vab(1) / r; - cxz -= vab(0) * vab(2) / r; - cyz -= vab(1) * vab(2) / r; - cx += vab(0) * hv / r; - cy += vab(1) * hv / r; - cz += vab(2) * hv / r; - c1 -= hv * hv / (2 * r); - c1 -= r / 2; -} - -Primitive * Cylinder :: CreateDefault () -{ - return new Cylinder (Point<3> (0,0,0), Point<3> (1,0,0), 1); -} - - - - -Primitive * Cylinder :: Copy () const -{ - return new Cylinder (a, b, r); -} - - -int Cylinder :: IsIdentic (const Surface & s2, int & inv, double eps) const -{ - const Cylinder * cyl2 = dynamic_cast<const Cylinder*> (&s2); - - if (!cyl2) return 0; - - if (fabs (cyl2->r - r) > eps) return 0; - - Vec<3> v1 = b - a; - Vec<3> v2 = cyl2->a - a; - - if ( fabs (v1 * v2) < (1-eps) * v1.Length() * v2.Length()) return 0; - v2 = cyl2->b - a; - if ( fabs (v1 * v2) < (1-eps) * v1.Length() * v2.Length()) return 0; - - inv = 0; - return 1; -} - - - -void Cylinder :: Transform (Transformation<3> & trans) -{ - Point<3> hp; - trans.Transform (a, hp); - a = hp; - trans.Transform (b, hp); - b = hp; - - vab = (b - a); - vab /= vab.Length(); - - // ( <x,x> - 2 <x,a> + <a,a> - // - <x,vab>^2 + 2 <x,vab> <a, vab> - <a, vab>^2 - // - r^2) / (2r) = 0 - - double hv; - cxx = cyy = czz = 0.5 / r; - cxy = cxz = cyz = 0; - cx = - a(0) / r; - cy = - a(1) / r; - cz = - a(2) / r; - c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r); - hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2); - cxx -= vab(0) * vab(0) / (2 * r); - cyy -= vab(1) * vab(1) / (2 * r); - czz -= vab(2) * vab(2) / (2 * r); - cxy -= vab(0) * vab(1) / r; - cxz -= vab(0) * vab(2) / r; - cyz -= vab(1) * vab(2) / r; - cx += vab(0) * hv / r; - cy += vab(1) * hv / r; - cz += vab(2) * hv / r; - c1 -= hv * hv / (2 * r); - c1 -= r / 2; - // PrintCoeff (); -} - - - - - - - - - -void Cylinder :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) -{ - Surface::DefineTangentialPlane (ap1, ap2); - - ez = Center (p1, p2) - a; - ez -= (ez * vab) * vab; - ez /= ez.Length(); - - ex = p2 - p1; - ex -= (ex * ez) * ez; - ex /= ex.Length(); - - ey = Cross (ez, ex); -} - - -void Cylinder :: ToPlane (const Point<3> & p, - Point<2> & pplane, - double h, int & zone) const -{ - Point<3> cp1p2 = Center (p1, p2); - Project (cp1p2); - - Point<3> ccp1p2 = a + ( (cp1p2 - a) * vab ) * vab; - - Vec<3> er = cp1p2 - ccp1p2; - er.Normalize(); - Vec<3> ephi = Cross (vab, er); - - double co, si; - Point<2> p1p, p2p, pp; - - co = er * (p1 - ccp1p2); - si = ephi * (p1 - ccp1p2); - p1p(0) = r * atan2 (si, co); - p1p(1) = vab * (p1 - ccp1p2); - - co = er * (p2 - ccp1p2); - si = ephi * (p2 - ccp1p2); - p2p(0) = r * atan2 (si, co); - p2p(1) = vab * (p2 - ccp1p2); - - co = er * (p - ccp1p2); - si = ephi * (p - ccp1p2); - - double phi = atan2 (si, co); - pp(0) = r * phi; - pp(1) = vab * (p - ccp1p2); - - zone = 0; - if (phi > 1.57) zone = 1; - if (phi < -1.57) zone = 2; - - - - Vec<2> e2x = p2p - p1p; - e2x /= e2x.Length(); - - Vec<2> e2y (-e2x(1), e2x(0)); - - Vec<2> p1pp = pp - p1p; - - - pplane(0) = (p1pp * e2x) / h; - pplane(1) = (p1pp * e2y) / h; - - /* - (*testout) << "p1 = " << p1 << ", p2 = " << p2 << endl; - (*testout) << "p = " << p << ", pp = " << pp << ", pplane = " << pplane << endl; - */ - - /* - Vec<3> p1p; - - p1p = p - p1; - - if (p1p * ez < -1 * r) - { - zone = -1; - pplane(0) = 1e8; - pplane(1) = 1e8; - } - else - { - zone = 0; - p1p /= h; - pplane(0) = p1p * ex; - pplane(1) = p1p * ey; - } - */ -} - -void Cylinder :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const -{ - Point<2> pplane2 (pplane); - - pplane2(0) *= h; - pplane2(1) *= h; - - p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0); - p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1); - p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2); - Project (p); -} - - -void Cylinder :: Project (Point<3> & p) const -{ - Vec<3> v; - Point<3> c; - - c = a + ((p - a) * vab) * vab; - v = p - c; - v *= (r / v.Length()); - p = c + v; -} -/* -int Cylinder :: RootInBox (const BoxSphere<3> & box) const - { - double dist; - dist = sqrt (2 * CalcFunctionValue(box.Center()) * r + r * r); - if (fabs (dist - r) > box.Diam()/2) return 0; - return 2; - } -*/ - -INSOLID_TYPE Cylinder :: BoxInSolid (const BoxSphere<3> & box) const -{ - double dist; - // dist = sqrt (2 * CalcFunctionValue(box.Center()) * r + r * r); - - dist = (2 * CalcFunctionValue(box.Center()) * r + r * r); - if (dist <= 0) dist = 0; - else dist = sqrt (dist + 1e-16); - - if (dist - box.Diam()/2 > r) return IS_OUTSIDE; - if (dist + box.Diam()/2 < r) return IS_INSIDE; - return DOES_INTERSECT; -} - - -double Cylinder :: HesseNorm () const -{ - return 2 / r; -} - -Point<3> Cylinder :: GetSurfacePoint () const -{ - Vec<3> vr; - if (fabs (vab(0)) > fabs(vab(2))) - vr = Vec<3> (vab(1), -vab(0), 0); - else - vr = Vec<3> (0, -vab(2), vab(1)); - - vr *= (r / vr.Length()); - return a + vr; -} - -void Cylinder :: GetTriangleApproximation -(TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const -{ - int i, j; - double lg, bg; - int n = int(facets) + 1; - - Vec<3> lvab = b - a; - Vec<3> n1 = lvab.GetNormal(); - Vec<3> n2 = Cross (lvab, n1); - - n1.Normalize(); - n2.Normalize(); - - - for (j = 0; j <= n; j++) - for (i = 0; i <= n; i++) - { - lg = 2 * M_PI * double (i) / n; - bg = double(j) / n; - - Point<3> p = a + (bg * lvab) - + ((r * cos(lg)) * n1) - + ((r * sin(lg)) * n2); - - tas.AddPoint (p); - } - - for (j = 0; j < n; j++) - for (i = 0; i < n; i++) - { - int pi = i + (n+1) * j; - tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); - tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); - } -} - - - - - - - - - -EllipticCylinder :: -EllipticCylinder (const Point<3> & aa, - const Vec<3> & avl, const Vec<3> & avs) -{ - a = aa; - vl = avl; - vs = avs; - - CalcData(); - Print (cout); -} - - -void EllipticCylinder :: CalcData () -{ - // f = (x-a, vl)^2 / |vl|^2 + (x-a, vs)^2 / |vs|^2 -1 - - Vec<3> hvl, hvs; - double lvl = vl.Length2 (); - if (lvl < 1e-32) lvl = 1; - double lvs = vs.Length2 (); - if (lvs < 1e-32) lvs = 1; - - hvl = (1.0 / lvl) * vl; - hvs = (1.0 / lvs) * vs; - - cxx = hvl(0) * hvl(0) + hvs(0) * hvs(0); - cyy = hvl(1) * hvl(1) + hvs(1) * hvs(1); - czz = hvl(2) * hvl(2) + hvs(2) * hvs(2); - - cxy = 2 * (hvl(0) * hvl(1) + hvs(0) * hvs(1)); - cxz = 2 * (hvl(0) * hvl(2) + hvs(0) * hvs(2)); - cyz = 2 * (hvl(1) * hvl(2) + hvs(1) * hvs(2)); - - Vec<3> va (a); - c1 = va * hvl + va * hvs - 1; - - Vec<3> v = -2 * (va * hvl) * hvl - 2 * (va * hvs) * hvs; - cx = v(0); - cy = v(1); - cz = v(2); -} - - -INSOLID_TYPE EllipticCylinder :: BoxInSolid (const BoxSphere<3> & box) const -{ - double grad = 2.0 / vs.Length (); - double ggrad = 1.0 / vs.Length2 (); - - double val = CalcFunctionValue (box.Center()); - double r = box.Diam() / 2; - double maxval = grad * r + ggrad * r * r; - - // (*testout) << "box = " << box << ", val = " << val << ", maxval = " << maxval << endl; - - if (val > maxval) return IS_OUTSIDE; - if (val < -maxval) return IS_INSIDE; - return DOES_INTERSECT; -} - - -double EllipticCylinder :: HesseNorm () const -{ - return 1.0/vs.Length2 (); -} - -Point<3> EllipticCylinder :: GetSurfacePoint () const -{ - return a + vl; -} - - - -void EllipticCylinder :: GetTriangleApproximation -(TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const -{ - int i, j; - double lg, bg; - int n = int(facets) + 1; - - Vec<3> axis = Cross (vl, vs); - - for (j = 0; j <= n; j++) - for (i = 0; i <= n; i++) - { - lg = 2 * M_PI * double (i) / n; - bg = double(j) / n; - - Point<3> p = a + (bg * axis) - + cos(lg) * vl + sin(lg) * vs; - - tas.AddPoint (p); - } - - for (j = 0; j < n; j++) - for (i = 0; i < n; i++) - { - int pi = i + (n+1) * j; - tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); - tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); - } -} - - - - - - - - - - -Cone :: Cone (const Point<3> & aa, const Point<3> & ab, - double ara, double arb) -{ - a = aa; - b = ab; - ra = ara; - rb = arb; - - CalcData(); - Print (cout); -} - - -Primitive * Cone :: CreateDefault () -{ - return new Cone (Point<3> (0,0,0), Point<3> (1,0,0), 0.5, 0.2); -} - - - - -void Cone :: GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const -{ - classname = "cone"; - coeffs.SetSize (8); - coeffs.Elem(1) = a(0); - coeffs.Elem(2) = a(1); - coeffs.Elem(3) = a(2); - coeffs.Elem(4) = b(0); - coeffs.Elem(5) = b(1); - coeffs.Elem(6) = b(2); - coeffs.Elem(7) = ra; - coeffs.Elem(8) = rb; -} - -void Cone :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - a(0) = coeffs.Elem(1); - a(1) = coeffs.Elem(2); - a(2) = coeffs.Elem(3); - b(0) = coeffs.Elem(4); - b(1) = coeffs.Elem(5); - b(2) = coeffs.Elem(6); - ra = coeffs.Elem(7); - rb = coeffs.Elem(8); - - CalcData(); -} - -void Cone :: CalcData () -{ - - minr = (ra < rb) ? ra : rb; - - vab = b - a; - vabl = vab.Length(); - - Vec<3> va (a); - - // - // f = r(P)^2 - R(z(P))^2 - // - // z(P) = t0vec * P + t0 = (P-a, b-a)/(b-a,b-a) - // R(z(P)) = t1vec * P + t1 = rb * z + ra * (1-z) - // r(P)^2 =||P-a||^2 - ||a-b||^2 z^2k - - - t0vec = vab; - t0vec /= (vabl * vabl); - t0 = -(va * vab) / (vabl * vabl); - - t1vec = t0vec; - t1vec *= (rb - ra); - t1 = ra + (rb - ra) * t0; - - cxx = cyy = czz = 1; - cxy = cxz = cyz = 0; - - cxx = 1 - (vab*vab) * t0vec(0) * t0vec(0) - t1vec(0) * t1vec(0); - cyy = 1 - (vab*vab) * t0vec(1) * t0vec(1) - t1vec(1) * t1vec(1); - czz = 1 - (vab*vab) * t0vec(2) * t0vec(2) - t1vec(2) * t1vec(2); - - cxy = -2 * (vab * vab) * t0vec(0) * t0vec(1) - 2 * t1vec(0) * t1vec(1); - cxz = -2 * (vab * vab) * t0vec(0) * t0vec(2) - 2 * t1vec(0) * t1vec(2); - cyz = -2 * (vab * vab) * t0vec(1) * t0vec(2) - 2 * t1vec(1) * t1vec(2); - - cx = -2 * a(0) - 2 * (vab * vab) * t0 * t0vec(0) - 2 * t1 * t1vec(0); - cy = -2 * a(1) - 2 * (vab * vab) * t0 * t0vec(1) - 2 * t1 * t1vec(1); - cz = -2 * a(2) - 2 * (vab * vab) * t0 * t0vec(2) - 2 * t1 * t1vec(2); - - c1 = va.Length2() - (vab * vab) * t0 * t0 - t1 * t1; - - // (*testout) << "t0vec = " << t0vec << " t0 = " << t0 << endl; - // (*testout) << "t1vec = " << t1vec << " t1 = " << t1 << endl; - // PrintCoeff (*testout); -} - - -INSOLID_TYPE Cone :: BoxInSolid (const BoxSphere<3> & box) const -{ - double rp, dist; - - Vec<3> cv(box.Center()); - - rp = cv * t1vec + t1; - dist = sqrt (CalcFunctionValue(box.Center()) + rp * rp) - rp; - - if (dist - box.Diam() > 0) return IS_OUTSIDE; - if (dist + box.Diam() < 0) return IS_INSIDE; - return DOES_INTERSECT; -} - - -double Cone :: HesseNorm () const -{ - return 2 / minr; -} - - -double Cone :: LocH (const Point<3> & p, double x, - double c, double hmax) const -{ - double bloch = Surface::LocH (p, x, c, hmax); - Vec<3> g; - CalcGradient (p, g); - - double lam = Abs(g); - double meancurv = - -( 2 * g(0)*g(1)*cxy - 2 * czz * (g(0)*g(0)+g(1)*g(1)) - +2 * g(1)*g(2)*cyz - 2 * cxx * (g(1)*g(1)+g(2)*g(2)) - +2 * g(0)*g(2)*cxz - 2 * cyy * (g(0)*g(0)+g(2)*g(2))) / (3*lam*lam*lam); - - // cout << "type = " << typeid(*this).name() << ", baseh = " << bloch << ", meancurv = " << meancurv << endl; - // return bloch; - - meancurv = fabs (meancurv); - if (meancurv < 1e-20) meancurv = 1e-20; - - // cout << "c = " << c << ", safety = " << mparam.curvaturesafety << endl; - double hcurv = 1.0/(3*meancurv*mparam.curvaturesafety); - - return min2 (hmax, hcurv); -} - - -Point<3> Cone :: GetSurfacePoint () const -{ - Vec<3> vr = vab.GetNormal (); - - vr *= (ra / vr.Length()); - return a + vr; -} - - - - - -void Cone :: GetTriangleApproximation -(TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const -{ - int i, j; - double lg, bg; - int n = int(facets) + 1; - - Vec<3> lvab = b - a; - Vec<3> n1 = lvab.GetNormal(); - Vec<3> n2 = Cross (lvab, n1); - - n1.Normalize(); - n2.Normalize(); - - - for (j = 0; j <= n; j++) - for (i = 0; i <= n; i++) - { - lg = 2 * M_PI * double (i) / n; - bg = double(j) / n; - - Point<3> p = a + (bg * lvab) - + (( (ra+(rb-ra)*bg) * cos(lg)) * n1) - + (( (ra+(rb-ra)*bg) * sin(lg)) * n2); - - tas.AddPoint (p); - } - - for (j = 0; j < n; j++) - for (i = 0; i < n; i++) - { - int pi = i + (n+1) * j; - tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); - tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); - } -} -} diff --git a/Netgen/libsrc/csg/algprim.hpp b/Netgen/libsrc/csg/algprim.hpp deleted file mode 100644 index aeb829f9c1..0000000000 --- a/Netgen/libsrc/csg/algprim.hpp +++ /dev/null @@ -1,338 +0,0 @@ -#ifndef FILE_ALGPRIM -#define FILE_ALGPRIM - - -/**************************************************************************/ -/* File: algprim.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 1. Dez. 95 */ -/**************************************************************************/ - -/* - -Quadric Surfaces (Plane, Sphere, Cylinder) - -*/ - - -/** - A quadric surface. - surface defined by - cxx x^2 + cyy y^2 + czz z^2 + cxy x y + cxz x z + cyz y z + - cx x + cy y + cz z + c1 = 0. - **/ -class QuadraticSurface : public OneSurfacePrimitive -{ -protected: - double cxx, cyy, czz, cxy, cxz, cyz, cx, cy, cz, c1; - -public: - - virtual double CalcFunctionValue (const Point<3> & point) const; - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; - virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; - /* - virtual int RootInBox (const Box<3> & box) - const { return 0; } - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) - const { return DOES_INTERSECT; } -*/ - virtual double HesseNorm () const { return cxx + cyy + czz; } - - virtual Point<3> GetSurfacePoint () const; - - - virtual void Print (ostream & ist) const; - virtual void Read (istream & ist); - void PrintCoeff (ostream & ost) const; -}; - - -/// A Plane (i.e., the plane and everything behind it). -class Plane : public QuadraticSurface -{ - /// a point in the plane - Point<3> p; - /// outward normal vector - Vec<3> n; -public: - /// - Plane (const Point<3> & ap, Vec<3> an); - - virtual void GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - static Primitive * CreateDefault (); - - virtual Primitive * Copy () const; - virtual void Transform (Transformation<3> & trans); - - - virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; - - /// - virtual void DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2); - /// - virtual void ToPlane (const Point<3> & p3d, - Point<2> & pplane, double h, - int & zone) const; - /// - virtual void FromPlane (const Point<2> & pplane, - Point<3> & p3d, - double h) const; - /// - virtual void Project (Point<3> & p) const; - - /// - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - - /// - inline virtual double CalcFunctionValue (const Point<3> & p3d) const - {return cx * p3d(0) + cy * p3d(1) + cz * p3d(2) + c1;} - /// - virtual void CalcGradient (const Point<3> & point, - Vec<3> & grad) const; - /// - virtual void CalcHesse (const Point<3> & point, - Mat<3> & hesse) const; - /// - virtual double HesseNorm () const; - /// - virtual Point<3> GetSurfacePoint () const; - /// - virtual void GetTriangleApproximation - (TriangleApproximation & tas, - const Box<3> & boundingbox, double facets) const; - -}; - -// typedef Plane Plane; - - -/// -class Sphere : public QuadraticSurface -{ - /// - Point<3> c; - /// - double r; -public: - /// - Sphere (const Point<3> & ac, double ar); - - virtual void GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - static Primitive * CreateDefault (); - - virtual Primitive * Copy () const; - virtual void Transform (Transformation<3> & trans); - - - virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; - - /// - virtual void DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2); - /// - virtual void ToPlane (const Point<3> & p3d, - Point<2> & pplane, double h, - int & zone) const; - /// - virtual void FromPlane (const Point<2> & pplane, - Point<3> & p, double h) const; - /// - virtual void Project (Point<3> & p) const; - - /// - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - /// - virtual double HesseNorm () const; - /// - virtual Point<3> GetSurfacePoint () const; - /// - const Point<3> & Center () const { return c; } - /// - double Radius () const { return r; } - - /// - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & bbox, - double facets) const; -}; - - -/// -class Cylinder : public QuadraticSurface -{ - /// - Point<3> a, b; - /// - double r; - /// - Vec<3> vab; - -public: - Cylinder (const Point<3> & aa, const Point<3> & ab, double ar); - - virtual void GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - static Primitive * CreateDefault (); - - virtual Primitive * Copy () const; - virtual void Transform (Transformation<3> & trans); - - /// - virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; - /// - virtual void DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2); - /// - virtual void ToPlane (const Point<3> & p, - Point<2> & pplane, - double h, - int & zone) const; - /// - virtual void FromPlane (const Point<2> & pplane, - Point<3> & p, - double h) const; - /// - virtual void Project (Point<3> & p) const; - - /// - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - /// - virtual double HesseNorm () const; - /// - virtual Point<3> GetSurfacePoint () const; - /// - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & bbox, - double facets) const; -}; - - - - - -/// -class EllipticCylinder : public QuadraticSurface -{ -private: - /// - Point<3> a; - /// - Vec<3> vl, vs; - /// - Vec<3> vab, t0vec, t1vec; - /// - double vabl, t0, t1; -public: - /// - EllipticCylinder (const Point<3> & aa, - const Vec<3> & avl, const Vec<3> & avs); - - /* - static Primitive * CreateDefault (); - virtual void GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - */ - /// - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - /// - virtual double HesseNorm () const; - /// - virtual Point<3> GetSurfacePoint () const; - - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & bbox, - double facets) const; - -private: - void CalcData(); -}; - - - - - - -/// -class Ellipsoid : public QuadraticSurface -{ -private: - /// - Point<3> a; - /// - Vec<3> v1, v2, v3; - /// - double rmin; -public: - /// - Ellipsoid (const Point<3> & aa, - const Vec<3> & av1, - const Vec<3> & av2, - const Vec<3> & av3); - /// - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - /// - virtual double HesseNorm () const; - /// - virtual Point<3> GetSurfacePoint () const; - - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & bbox, - double facets) const; - -private: - void CalcData(); -}; - - - - - - - - -/// -class Cone : public QuadraticSurface -{ - /// - Point<3> a, b; - /// - double ra, rb, minr; - /// - Vec<3> vab, t0vec, t1vec; - /// - double vabl, t0, t1; -public: - /// - Cone (const Point<3> & aa, const Point<3> & ab, double ara, double arb); - /// - static Primitive * CreateDefault (); - virtual void GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - - /// - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - /// - virtual double HesseNorm () const; - - virtual double LocH (const Point<3> & p, double x, - double c, double hmax) const; - - /// - virtual Point<3> GetSurfacePoint () const; - - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & bbox, - double facets) const; - -private: - void CalcData(); -}; - - -#endif diff --git a/Netgen/libsrc/csg/brick.cpp b/Netgen/libsrc/csg/brick.cpp deleted file mode 100644 index f408e922f4..0000000000 --- a/Netgen/libsrc/csg/brick.cpp +++ /dev/null @@ -1,409 +0,0 @@ -#include <mystdlib.h> - -#include <linalg.hpp> -#include <csg.hpp> - -namespace netgen -{ - -Parallelogram3d :: Parallelogram3d (Point<3> ap1, Point<3> ap2, Point<3> ap3) -{ - p1 = ap1; - p2 = ap2; - p3 = ap3; - - CalcData(); -} - -Parallelogram3d ::~Parallelogram3d () -{ - ; -} - -void Parallelogram3d :: SetPoints (Point<3> ap1, - Point<3> ap2, - Point<3> ap3) -{ - p1 = ap1; - p2 = ap2; - p3 = ap3; - - CalcData(); -} - -void Parallelogram3d :: CalcData() -{ - v12 = p2 - p1; - v13 = p3 - p1; - p4 = p2 + v13; - - n = Cross (v12, v13); - n.Normalize(); -} - -int Parallelogram3d :: -IsIdentic (const Surface & s2, int & inv, double eps) const -{ - int id = - (fabs (s2.CalcFunctionValue (p1)) <= eps) && - (fabs (s2.CalcFunctionValue (p2)) <= eps) && - (fabs (s2.CalcFunctionValue (p3)) <= eps); - - if (id) - { - Vec<3> n2; - n2 = s2.GetNormalVector(p1); - inv = (n * n2) < 0; - } - return id; -} - - -double Parallelogram3d :: CalcFunctionValue (const Point<3> & point) const -{ - return n * (point - p1); -} - -void Parallelogram3d :: CalcGradient (const Point<3> & point, - Vec<3> & grad) const -{ - grad = n; -} - -void Parallelogram3d :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const -{ - hesse = 0; -} - -double Parallelogram3d :: HesseNorm () const -{ - return 0; -} - -Point<3> Parallelogram3d :: GetSurfacePoint () const -{ - return p1; -} - -void Parallelogram3d :: Print (ostream & str) const -{ - str << "Parallelogram3d " << p1 << " - " << p2 << " - " << p3 << endl; -} - - -void Parallelogram3d :: -GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & bbox, - double facets) const -{ - tas.AddPoint (p1); - tas.AddPoint (p2); - tas.AddPoint (p3); - tas.AddPoint (p4); - tas.AddTriangle (TATriangle (0, 0, 1, 2)); - tas.AddTriangle (TATriangle (0, 2, 1, 3)); -} - - - - - - - - - - -Brick :: Brick (Point<3> ap1, Point<3> ap2, - Point<3> ap3, Point<3> ap4) -{ - faces.SetSize (6); - surfaceids.SetSize (6); - surfaceactive.SetSize(6); - - p1 = ap1; p2 = ap2; - p3 = ap3; p4 = ap4; - - for (int i = 0; i < 6; i++) - { - faces[i] = new Plane (Point<3>(0,0,0), Vec<3> (0,0,1)); - surfaceactive[i] = 1; - } - - CalcData(); -} - -Brick :: ~Brick () -{ - for (int i = 0; i < 6; i++) - delete faces[i]; -} - -Primitive * Brick :: CreateDefault () -{ - return new Brick (Point<3> (0,0,0), - Point<3> (1,0,0), - Point<3> (0,1,0), - Point<3> (0,0,1)); -} - - -INSOLID_TYPE Brick :: BoxInSolid (const BoxSphere<3> & box) const -{ - /* - int i; - double maxval; - for (i = 1; i <= 6; i++) - { - double val = faces.Get(i)->CalcFunctionValue (box.Center()); - if (i == 1 || val > maxval) - maxval = val; - } - - if (maxval > box.Diam()) return IS_OUTSIDE; - if (maxval < -box.Diam()) return IS_INSIDE; - return DOES_INTERSECT; - */ - - bool inside = 1; - bool outside = 0; - - for (int i = 0; i < 6; i++) - { - bool outsidei = 1; - for (int j = 0; j < 8; j++) - { - Point<3> p = box.GetPointNr (j); - double val = faces[i]->CalcFunctionValue (p); - - if (val > 0) inside = 0; - if (val < 0) outsidei = 0; - } - if (outsidei) outside = 1; - } - - if (outside) return IS_OUTSIDE; - if (inside) return IS_INSIDE; - return DOES_INTERSECT; -} - -INSOLID_TYPE Brick :: PointInSolid (const Point<3> & p, - double eps) const -{ - double maxval = faces[0] -> CalcFunctionValue (p); - for (int i = 1; i < 6; i++) - { - double val = faces[i] -> CalcFunctionValue (p); - if (val > maxval) maxval = val; - } - - if (maxval > eps) return IS_OUTSIDE; - if (maxval < -eps) return IS_INSIDE; - return DOES_INTERSECT; -} - -INSOLID_TYPE Brick :: VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const -{ - INSOLID_TYPE is = IS_INSIDE; - Vec<3> grad; - double scal; - - for (int i = 0; i < faces.Size(); i++) - { - if (faces[i] -> PointOnSurface (p, eps)) - { - GetSurface(i).CalcGradient (p, grad); - scal = v * grad; - - if (scal >= eps) - is = IS_OUTSIDE; - if (scal >= -eps && is == IS_INSIDE) - is = DOES_INTERSECT; - } - } - return is; - /* - Point<3> p2 = p + 1e-2 * v; - return PointInSolid (p2, eps); - */ -} - - -void Brick :: -GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const -{ - classname = "brick"; - coeffs.SetSize(12); - coeffs.Elem(1) = p1(0); - coeffs.Elem(2) = p1(1); - coeffs.Elem(3) = p1(2); - - coeffs.Elem(4) = p2(0); - coeffs.Elem(5) = p2(1); - coeffs.Elem(6) = p2(2); - - coeffs.Elem(7) = p3(0); - coeffs.Elem(8) = p3(1); - coeffs.Elem(9) = p3(2); - - coeffs.Elem(10) = p4(0); - coeffs.Elem(11) = p4(1); - coeffs.Elem(12) = p4(2); -} - -void Brick :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - p1(0) = coeffs.Elem(1); - p1(1) = coeffs.Elem(2); - p1(2) = coeffs.Elem(3); - - p2(0) = coeffs.Elem(4); - p2(1) = coeffs.Elem(5); - p2(2) = coeffs.Elem(6); - - p3(0) = coeffs.Elem(7); - p3(1) = coeffs.Elem(8); - p3(2) = coeffs.Elem(9); - - p4(0) = coeffs.Elem(10); - p4(1) = coeffs.Elem(11); - p4(2) = coeffs.Elem(12); - - CalcData(); -} - - - -void Brick :: CalcData() -{ - v12 = p2 - p1; - v13 = p3 - p1; - v14 = p4 - p1; - - Point<3> pi[8]; - int i1, i2, i3; - int i, j; - - i = 0; - for (i3 = 0; i3 <= 1; i3++) - for (i2 = 0; i2 <= 1; i2++) - for (i1 = 0; i1 <= 1; i1++) - { - pi[i] = p1 + i1 * v12 + i2 * v13 + i3 * v14; - i++; - } - - static int lface[6][4] = - { { 1, 3, 2, 4 }, - { 5, 6, 7, 8 }, - { 1, 2, 5, 6 }, - { 3, 7, 4, 8 }, - { 1, 5, 3, 7 }, - { 2, 4, 6, 8 } }; - - ARRAY<double> data(6); - for (i = 0; i < 6; i++) - { - const Point<3> p1 = pi[lface[i][0]-1]; - const Point<3> p2 = pi[lface[i][1]-1]; - const Point<3> p3 = pi[lface[i][2]-1]; - - Vec<3> n = Cross ((p2-p1), (p3-p1)); - n.Normalize(); - - for (j = 0; j < 3; j++) - { - data[j] = p1(j); - data[j+3] = n(j); - } - faces[i] -> SetPrimitiveData (data); - /* - { - faces.Elem(i+1) -> SetPoints - (pi[lface[i][0]-1], - pi[lface[i][1]-1], - pi[lface[i][2]-1]); - } - */ - } -} - - -void Brick :: Reduce (const BoxSphere<3> & box) -{ - double val; - Point<3> p; - for (int i = 0; i < 6; i++) - { - bool hasout = 0; - bool hasin = 0; - for (int j = 0; j < 8; j++) - { - p = box.GetPointNr (j); - val = faces[i]->CalcFunctionValue (p); - if (val > 0) hasout = 1; - else if (val < 0) hasin = 1; - } - surfaceactive[i] = hasout && hasin; - } -} - -void Brick :: UnReduce () -{ - for (int i = 0; i < 6; i++) - surfaceactive[i] = 1; -} - - - -OrthoBrick :: OrthoBrick (const Point<3> & ap1, const Point<3> & ap2) - : Brick (ap1, - Point<3> (ap2(0), ap1(1), ap1(2)), - Point<3> (ap1(0), ap2(1), ap1(2)), - Point<3> (ap1(0), ap1(1), ap2(2))) -{ - pmin = ap1; - pmax = ap2; -} - -INSOLID_TYPE OrthoBrick :: BoxInSolid (const BoxSphere<3> & box) const -{ - if (pmin(0) > box.PMax()(0) || - pmin(1) > box.PMax()(1) || - pmin(2) > box.PMax()(2) || - pmax(0) < box.PMin()(0) || - pmax(1) < box.PMin()(1) || - pmax(2) < box.PMin()(2)) - return IS_OUTSIDE; - - if (pmin(0) < box.PMin()(0) && - pmin(1) < box.PMin()(1) && - pmin(2) < box.PMin()(2) && - pmax(0) > box.PMax()(0) && - pmax(1) > box.PMax()(1) && - pmax(2) > box.PMax()(2)) - return IS_INSIDE; - - return DOES_INTERSECT; -} - - -void OrthoBrick :: Reduce (const BoxSphere<3> & box) -{ - surfaceactive.Elem(1) = - (box.PMin()(2) < pmin(2)) && (pmin(2) < box.PMax()(2)); - surfaceactive.Elem(2) = - (box.PMin()(2) < pmax(2)) && (pmax(2) < box.PMax()(2)); - - surfaceactive.Elem(3) = - (box.PMin()(1) < pmin(1)) && (pmin(1) < box.PMax()(1)); - surfaceactive.Elem(4) = - (box.PMin()(1) < pmax(1)) && (pmax(1) < box.PMax()(1)); - - surfaceactive.Elem(5) = - (box.PMin()(0) < pmin(0)) && (pmin(0) < box.PMax()(0)); - surfaceactive.Elem(6) = - (box.PMin()(0) < pmax(0)) && (pmax(0) < box.PMax()(0)); -} -} diff --git a/Netgen/libsrc/csg/brick.hpp b/Netgen/libsrc/csg/brick.hpp deleted file mode 100644 index 11106b66d3..0000000000 --- a/Netgen/libsrc/csg/brick.hpp +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef FILE_BRICK -#define FILE_BRICK - - -/**************************************************************************/ -/* File: brick.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 11. Mar. 98 */ -/**************************************************************************/ - -/* - - brick geometry, has several surfaces - -*/ - - - -class Parallelogram3d : public Surface -{ - Point<3> p1, p2, p3, p4; - Vec<3> v12, v13; - Vec<3> n; - -public: - Parallelogram3d (Point<3> ap1, Point<3> ap2, Point<3> ap3); - virtual ~Parallelogram3d (); - void SetPoints (Point<3> ap1, Point<3> ap2, Point<3> ap3); - - virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; - - virtual double CalcFunctionValue (const Point<3> & point) const; - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; - virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; - virtual double HesseNorm () const; - - virtual Point<3> GetSurfacePoint () const; - virtual void Print (ostream & str) const; - - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & boundingbox, - double facets) const; - -protected: - void CalcData(); -}; - - -class Brick : public Primitive -{ - Point<3> p1, p2, p3, p4; - Vec<3> v12, v13, v14; - ARRAY<OneSurfacePrimitive*> faces; - -public: - Brick (Point<3> ap1, Point<3> ap2, Point<3> ap3, Point<3> ap4); - virtual ~Brick (); - static Primitive * CreateDefault (); - - - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const; - - virtual int GetNSurfaces() const - { return 6; } - virtual Surface & GetSurface (int i) - { return *faces[i]; } - virtual const Surface & GetSurface (int i) const - { return *faces[i]; } - - - virtual void GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - - virtual void Reduce (const BoxSphere<3> & box); - virtual void UnReduce (); - -protected: - void CalcData(); -}; - - -class OrthoBrick : public Brick -{ -protected: - Point<3> pmin, pmax; -public: - OrthoBrick (const Point<3> & ap1, const Point<3> & ap2); - - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - virtual void Reduce (const BoxSphere<3> & box); -}; - -#endif diff --git a/Netgen/libsrc/csg/bspline2d.cpp b/Netgen/libsrc/csg/bspline2d.cpp deleted file mode 100644 index 93b5e89621..0000000000 --- a/Netgen/libsrc/csg/bspline2d.cpp +++ /dev/null @@ -1,242 +0,0 @@ -#include <mystdlib.h> - -#include <csg.hpp> - -namespace netgen -{ - -BSplineCurve2d :: BSplineCurve2d () -{ - redlevel = 0; -} - - -void BSplineCurve2d :: AddPoint (const Point<2> & apoint) -{ - points.Append (apoint); - intervallused.Append (0); -} - -bool BSplineCurve2d :: Inside (const Point<2> & p, double & dist) const -{ - Point<2> hp = p; - double t = ProjectParam (p); - hp = Eval(t); - Vec<2> v = EvalPrime (t); - - Vec<2> n (v(0), -v(1)); - - cout << "p = " << p << ", hp = " << hp << endl; - dist = Dist (p, hp); - double scal = (hp-p) * n; - cout << "scal = " << scal << endl; - - return scal >= 0; -} - -double BSplineCurve2d :: ProjectParam (const Point<2> & p) const -{ - double t, dt, mindist, mint = 0.0; - int n1; - - mindist = 1e10; - dt = 0.2; - for (n1 = 1; n1 <= points.Size(); n1++) - if (intervallused.Get(n1) == 0) - for (t = n1; t <= n1+1; t += dt) - if (Dist (Eval(t), p) < mindist) - { - mint = t; - mindist = Dist (Eval(t), p); - } - - if (mindist > 1e9) - { - for (t = 0; t <= points.Size(); t += dt) - if (Dist (Eval(t), p) < mindist) - { - mint = t; - mindist = Dist (Eval(t), p); - } - } - - while (Dist (Eval (mint-dt), p) < mindist) - { - mindist = Dist (Eval (mint-dt), p); - mint -= dt; - } - while (Dist (Eval (mint+dt), p) < mindist) - { - mindist = Dist (Eval (mint+dt), p); - mint += dt; - } - - - return NumericalProjectParam (p, mint-dt, mint+dt); -} - - -// t \in (n1, n2) - -Point<2> BSplineCurve2d :: Eval (double t) const -{ - int n, n1, n2, n3, n4; - double loct, b1, b2, b3, b4; - Point<2> hp; - - static int cnt = 0; - cnt++; - if (cnt % 100000 == 0) (*mycout) << "cnt = " << cnt << endl; - - n = int(t); - loct = t - n; - - b1 = 0.25 * (1 - loct) * (1 - loct); - b4 = 0.25 * loct * loct; - b2 = 0.5 - b4; - b3 = 0.5 - b1; - - n1 = (n + 10 * points.Size() -1) % points.Size() + 1; - n2 = n1+1; - if (n2 > points.Size()) n2 = 1; - n3 = n2+1; - if (n3 > points.Size()) n3 = 1; - n4 = n3+1; - if (n4 > points.Size()) n4 = 1; - - // (*mycout) << "t = " << t << " n = " << n << " loct = " << loct - // << " n1 = " << n1 << endl; - - - hp(0) = b1 * points.Get(n1)(0) + b2 * points.Get(n2)(0) + - b3 * points.Get(n3)(0) + b4 * points.Get(n4)(0); - hp(1) = b1 * points.Get(n1)(1) + b2 * points.Get(n2)(1) + - b3 * points.Get(n3)(1) + b4 * points.Get(n4)(1); - return hp; -} - -Vec<2> BSplineCurve2d :: EvalPrime (double t) const -{ - int n, n1, n2, n3, n4; - double loct, db1, db2, db3, db4; - Vec<2> hv; - - n = int(t); - loct = t - n; - - db1 = 0.5 * (loct - 1); - db4 = 0.5 * loct; - db2 = -db4; - db3 = -db1; - - n1 = (n + 10 * points.Size() -1) % points.Size() + 1; - n2 = n1+1; - if (n2 > points.Size()) n2 = 1; - n3 = n2+1; - if (n3 > points.Size()) n3 = 1; - n4 = n3+1; - if (n4 > points.Size()) n4 = 1; - - hv(0) = db1 * points.Get(n1)(0) + db2 * points.Get(n2)(0) + - db3 * points.Get(n3)(0) + db4 * points.Get(n4)(0); - hv(1) = db1 * points.Get(n1)(1) + db2 * points.Get(n2)(1) + - db3 * points.Get(n3)(1) + db4 * points.Get(n4)(1); - return hv; -} - -Vec<2> BSplineCurve2d :: EvalPrimePrime (double t) const -{ - int n, n1, n2, n3, n4; - double ddb1, ddb2, ddb3, ddb4; - Vec<2> hv; - - n = int(t); - // double loct = t - n; - - ddb1 = 0.5; - ddb4 = 0.5; - ddb2 = -0.5; - ddb3 = -0.5; - - n1 = (n + 10 * points.Size() -1) % points.Size() + 1; - n2 = n1+1; - if (n2 > points.Size()) n2 = 1; - n3 = n2+1; - if (n3 > points.Size()) n3 = 1; - n4 = n3+1; - if (n4 > points.Size()) n4 = 1; - - hv(0) = ddb1 * points.Get(n1)(0) + ddb2 * points.Get(n2)(0) + - ddb3 * points.Get(n3)(0) + ddb4 * points.Get(n4)(0); - hv(1) = ddb1 * points.Get(n1)(1) + ddb2 * points.Get(n2)(1) + - ddb3 * points.Get(n3)(1) + ddb4 * points.Get(n4)(1); - return hv; -} - - -int BSplineCurve2d :: SectionUsed (double t) const -{ - int n1 = int(t); - n1 = (n1 + 10 * points.Size() - 1) % points.Size() + 1; - return (intervallused.Get(n1) == 0); -} - -void BSplineCurve2d :: Reduce (const Point<2> & p, double rad) -{ - int n1, n; - int j; - double minx, miny, maxx, maxy; - - // (*testout) << "Reduce: " << p << "," << rad << endl; - - redlevel++; - - for (n1 = 1; n1 <= points.Size(); n1++) - { - if (intervallused.Get(n1) != 0) continue; - - minx = maxx = points.Get(n1)(0); - miny = maxy = points.Get(n1)(1); - - n = n1; - for (j = 1; j <= 3; j++) - { - n++; - if (n > points.Size()) n = 1; - if (points.Get(n)(0) < minx) minx = points.Get(n)(0); - if (points.Get(n)(1) < miny) miny = points.Get(n)(1); - if (points.Get(n)(0) > maxx) maxx = points.Get(n)(0); - if (points.Get(n)(1) > maxy) maxy = points.Get(n)(1); - } - - if (minx > p(0) + rad || maxx < p(0) - rad || - miny > p(1) + rad || maxy < p(1) - rad) - { - intervallused.Elem(n1) = redlevel; - // (*testout) << 0; - } - else - { - // (*testout) << 1; - intervallused.Elem(n1) = 0; - } - } - // (*testout) << endl; -} - -void BSplineCurve2d :: UnReduce () -{ - int i; - for (i = 1; i <= intervallused.Size(); i++) - if (intervallused.Get(i) == redlevel) - intervallused.Set (i, 0); - redlevel--; -} - -void BSplineCurve2d :: Print (ostream & ost) const -{ - ost << "SplineCurve: " << points.Size() << " points." << endl; - for (int i = 1; i <= points.Size(); i++) - ost << "P" << i << " = " << points.Get(i) << endl; -} -} diff --git a/Netgen/libsrc/csg/csg.hpp b/Netgen/libsrc/csg/csg.hpp deleted file mode 100644 index e150860232..0000000000 --- a/Netgen/libsrc/csg/csg.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef FILE_CSG -#define FILE_CSG - -/* *************************************************************************/ -/* File: geoml.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 21. Jun. 98 */ -/* *************************************************************************/ - -#include <myadt.hpp> -#include <gprim.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "surface.hpp" -#include "solid.hpp" -#include "identify.hpp" -#include "singularref.hpp" -#include "csgeom.hpp" - -#ifndef SMALLLIB -#define _INCLUDE_MORE -#endif -#ifdef LINUX -#define _INCLUDE_MORE -#endif - -#ifdef _INCLUDE_MORE -#include "triapprox.hpp" - -#include "algprim.hpp" -#include "brick.hpp" -#include "spline3d.hpp" -#include "manifold.hpp" -#include "curve2d.hpp" -#include "explicitcurve2d.hpp" -#include "gencyl.hpp" -#include "polyhedra.hpp" -#include "extrusion.hpp" -#include "revolution.hpp" -#include "specpoin.hpp" -#include "edgeflw.hpp" -#include "meshsurf.hpp" -#endif -} - -#endif diff --git a/Netgen/libsrc/csg/csgeom.cpp b/Netgen/libsrc/csg/csgeom.cpp deleted file mode 100644 index f7c25ee9c6..0000000000 --- a/Netgen/libsrc/csg/csgeom.cpp +++ /dev/null @@ -1,1020 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - - int CSGeometry :: changeval = 0; - - - - TopLevelObject :: - TopLevelObject (Solid * asolid, - Surface * asurface) - { - solid = asolid; - surface = asurface; - - SetRGB (0, 0, 1); - SetTransparent (0); - SetVisible (1); - SetLayer (1); - - if (!surface) - maxh = solid->GetMaxH(); - else - maxh = surface->GetMaxH(); - - SetBCProp (-1); - } - - void TopLevelObject :: GetData (ostream & ost) - { - ost << red << " " << green << " " << blue << " " - << transp << " " << visible << " "; - } - - void TopLevelObject :: SetData (istream & ist) - { - ist >> red >> green >> blue >> transp >> visible; - } - - - - Box<3> CSGeometry::default_boundingbox (Point<3> (-1000, -1000, -1000), - Point<3> ( 1000, 1000, 1000)); - - - CSGeometry :: CSGeometry () - : boundingbox (default_boundingbox), - identicsurfaces (100), filename("") - { - ; - } - - CSGeometry :: CSGeometry (const string & afilename) - : boundingbox (default_boundingbox), - identicsurfaces (100), filename(afilename) - { - changeval++; - } - - CSGeometry :: ~CSGeometry () - { - Clean(); - } - - - void CSGeometry :: Clean () - { - for (int i = 0; i < solids.Size(); i++) - delete solids[i]->S1(); - for (int i = 0; i < solids.Size(); i++) - delete solids[i]; - solids.DeleteAll (); - - /* - for (int i = 0; i < surfaces.Size(); i++) - delete surfaces[i]; - surfaces.DeleteAll (); - */ - - for (int i = 0; i < toplevelobjects.Size(); i++) - delete toplevelobjects[i]; - toplevelobjects.DeleteAll (); - for (int i = 0; i < triapprox.Size(); i++) - delete triapprox[i]; - triapprox.DeleteAll(); - - changeval++; - } - - - - - - class WritePrimitivesIt : public SolidIterator - { - ostream & ost; - public: - WritePrimitivesIt (ostream & aost) : ost(aost) { ; } - virtual ~WritePrimitivesIt () { ; } - - virtual void Do (Solid * sol); - }; - - void WritePrimitivesIt :: Do (Solid * sol) - { - Primitive * prim = sol->GetPrimitive(); - if (prim) - { - char * classname; - ARRAY<double> coeffs; - - prim -> GetPrimitiveData (classname, coeffs); - - if (sol->Name()) - ost << "primitive " - << sol->Name() << " " - << classname << " " << coeffs.Size(); - for (int i = 0; i < coeffs.Size(); i++) - ost << " " << coeffs[i]; - ost << endl; - } - } - - - void CSGeometry :: Save (ostream & ost) - { - ost << "boundingbox " - << boundingbox.PMin()(0) << " " - << boundingbox.PMin()(1) << " " - << boundingbox.PMin()(2) << " " - << boundingbox.PMax()(0) << " " - << boundingbox.PMax()(1) << " " - << boundingbox.PMax()(2) << endl; - - - WritePrimitivesIt wpi(ost); - IterateAllSolids (wpi, 1); - - for (int i = 0; i < solids.Size(); i++) - { - if (!solids[i]->GetPrimitive()) - { - ost << "solid " << solids.GetName(i) << " "; - solids[i] -> GetSolidData (ost); - ost << endl; - } - } - - for (int i = 0; i < GetNTopLevelObjects(); i++) - { - TopLevelObject * tlo = GetTopLevelObject (i); - ost << "toplevel "; - if (tlo -> GetSurface()) - ost << "surface " << tlo->GetSolid()->Name() << " " - << tlo->GetSurface()->Name() << " "; - else - ost << "solid " << tlo->GetSolid()->Name() << " "; - tlo->GetData(ost); - ost << endl; - } - - for (int i = 0; i < identifications.Size(); i++) - { - ost << "identify "; - identifications[i] -> GetData (ost); - ost << endl; - } - - ost << "end" << endl; - } - - - void CSGeometry :: Load (istream & ist) - { - // CSGeometry * geo = new CSGeometry; - - char key[100], name[100], classname[100], sname[100]; - int ncoeff, i, j; - ARRAY<double> coeff; - - while (ist.good()) - { - ist >> key; - if (strcmp (key, "boundingbox") == 0) - { - Point<3> pmin, pmax; - ist >> pmin(0) >> pmin(1) >> pmin(2); - ist >> pmax(0) >> pmax(1) >> pmax(2); - SetBoundingBox (Box<3> (pmin, pmax)); - } - if (strcmp (key, "primitive") == 0) - { - ist >> name >> classname >> ncoeff; - coeff.SetSize (ncoeff); - for (i = 0; i < ncoeff; i++) - ist >> coeff[i]; - - Primitive * nprim = Primitive::CreatePrimitive (classname); - nprim -> SetPrimitiveData (coeff); - Solid * nsol = new Solid (nprim); - - for (j = 0; j < nprim->GetNSurfaces(); j++) - { - sprintf (sname, "%s,%d", name, j); - AddSurface (sname, &nprim->GetSurface(j)); - nprim -> SetSurfaceId (j, GetNSurf()); - } - SetSolid (name, nsol); - } - else if (strcmp (key, "solid") == 0) - { - ist >> name; - Solid * nsol = Solid::CreateSolid (ist, solids); - - cout << " I have found solid " << name << " = "; - nsol -> GetSolidData (cout); - cout << endl; - - SetSolid (name, nsol); - } - else if (strcmp (key, "toplevel") == 0) - { - char type[20], solname[50], surfname[50]; - const Solid * sol = NULL; - const Surface * surf = NULL; - int nr; - - ist >> type; - if (strcmp (type, "solid") == 0) - { - ist >> solname; - sol = GetSolid (solname); - } - if (strcmp (type, "surface") == 0) - { - ist >> solname >> surfname; - sol = GetSolid (solname); - surf = GetSurface (surfname); - } - nr = SetTopLevelObject ((Solid*)sol, (Surface*)surf); - GetTopLevelObject (nr) -> SetData (ist); - } - else if (strcmp (key, "identify") == 0) - { - char type[10], surfname1[50], surfname2[50]; - const Surface * surf1; - const Surface * surf2; - - - ist >> type >> surfname1 >> surfname2; - surf1 = GetSurface(surfname1); - surf2 = GetSurface(surfname2); - - AddIdentification (new PeriodicIdentification - (GetNIdentifications(), - *this, surf1, surf2)); - } - else if (strcmp (key, "end") == 0) - break; - } - - changeval++; - } - - - - - - void CSGeometry :: AddSurface (Surface * surf) - { - static int cntsurfs = 0; - cntsurfs++; - char name[15]; - sprintf (name, "nnsurf%d", cntsurfs); - AddSurface (name, surf); - } - - void CSGeometry :: AddSurface (char * name, Surface * surf) - { - surfaces.Set (name, surf); - surf->SetName (name); - changeval++; - } - - void CSGeometry :: AddSurfaces (Primitive * prim) - { - for (int i = 0; i < prim->GetNSurfaces(); i++) - { - AddSurface (&prim->GetSurface(i)); - prim->SetSurfaceId (i, GetNSurf()-1); - } - } - - const Surface * CSGeometry :: GetSurface (const char * name) const - { - if (surfaces.Used(name)) - return surfaces.Get(name); - else - return NULL; - } - - /* - const Surface * CSGeometry :: GetSurface (int i) const - { - if (i >= 0 && i < surfaces.Size()) - return surfaces[i]; - else - throw NgException ("CSGeometry::GetSurface out of range"); - } - */ - - - - - void CSGeometry :: SetSolid (const char * name, Solid * sol) - { - Solid * oldsol = NULL; - - if (solids.Used (name)) - oldsol = solids.Get(name); - - solids.Set (name, sol); - sol->SetName (name); - - if (oldsol) - { - if (oldsol->op != Solid::ROOT || - sol->op != Solid::ROOT) - { - cerr << "Setsolid: old or new no root" << endl; - } - oldsol -> s1 = sol -> s1; - } - changeval++; - } - - const Solid * CSGeometry :: GetSolid (const char * name) const - { - if (solids.Used(name)) - return solids.Get(name); - else - return NULL; - } - - - - const Solid * CSGeometry :: GetSolid (const string & name) const - { - if (solids.Used(name.c_str())) - return solids.Get(name.c_str()); - else - return NULL; - } - - - - - - - - - class RemoveDummyIterator : public SolidIterator - { - public: - - RemoveDummyIterator() { ; } - virtual ~RemoveDummyIterator() { ; } - virtual void Do(Solid * sol); - }; - - void RemoveDummyIterator :: Do(Solid * sol) - { - if ( (sol->op == Solid::SUB || sol->op == Solid::SECTION || - sol->op == Solid::UNION) - && sol->s1->op == Solid::DUMMY) - sol->s1 = sol->s1->s1; - if ( (sol->op == Solid::SECTION || sol->op == Solid::UNION) - && sol->s2->op == Solid::DUMMY) - sol->s2 = sol->s2->s1; - } - - - - - - - int CSGeometry :: SetTopLevelObject (Solid * sol, Surface * surf) - { - return toplevelobjects.Append (new TopLevelObject (sol, surf)) - 1; - } - - TopLevelObject * CSGeometry :: - GetTopLevelObject (const Solid * sol, const Surface * surf) - { - for (int i = 0; i < toplevelobjects.Size(); i++) - { - if (toplevelobjects[i]->GetSolid() == sol && - toplevelobjects[i]->GetSurface() == surf) - return (toplevelobjects[i]); - } - return NULL; - } - - void CSGeometry :: RemoveTopLevelObject (Solid * sol, Surface * surf) - { - for (int i = 0; i < toplevelobjects.Size(); i++) - { - if (toplevelobjects[i]->GetSolid() == sol && - toplevelobjects[i]->GetSurface() == surf) - { - delete toplevelobjects[i]; - toplevelobjects.DeleteElement (i+1); - changeval++; - break; - } - } - } - - void CSGeometry :: AddIdentification (Identification * ident) - { - identifications.Append (ident); - } - - void CSGeometry :: SetFlags (const char * solidname, const Flags & flags) - { - Solid * solid = solids.Elem(solidname); - ARRAY<int> surfind; - - int i; - double maxh = flags.GetNumFlag ("maxh", -1); - if (maxh > 0 && solid) - { - solid->GetSurfaceIndices (surfind); - - for (i = 0; i < surfind.Size(); i++) - { - if (surfaces[surfind[i]]->GetMaxH() > maxh) - surfaces[surfind[i]] -> SetMaxH (maxh); - } - - solid->SetMaxH (maxh); - } - - if (flags.NumFlagDefined ("bc")) - { - solid->GetSurfaceIndices (surfind); - int bc = int (flags.GetNumFlag("bc", -1)); - for (i = 0; i < surfind.Size(); i++) - { - if (surfaces[surfind[i]]->GetBCProperty() == -1) - surfaces[surfind[i]]->SetBCProperty(bc); - } - } - } - - void CSGeometry :: FindIdenticSurfaces (double eps) - { - int inv; - int nsurf = GetNSurf(); - - isidenticto.SetSize(nsurf); - for (int i = 0; i < nsurf; i++) - isidenticto[i] = i; - - for (int i = 0; i < nsurf; i++) - for (int j = i+1; j < nsurf; j++) - if (GetSurface(j) -> IsIdentic (*GetSurface(i), inv, eps)) - { - INDEX_2 i2(i, j); - identicsurfaces.Set (i2, inv); - isidenticto[j] = isidenticto[i]; - // (*testout) << "surfaces " << i2 << " are identic" << endl; - } - - /* - (*testout) << "identicmap:" << endl; - for (int i = 0; i < isidenticto.Size(); i++) - (*testout) << i << " -> " << isidenticto[i] << endl; - - for (int i = 0; i < nsurf; i++) - GetSurface(i)->Print (*testout); - */ - } - - - void CSGeometry :: - GetIndependentSurfaceIndices (const Solid * sol, - const BoxSphere<3> & box, - ARRAY<int> & locsurf) const - { - ReducePrimitiveIterator rpi(box); - UnReducePrimitiveIterator urpi; - - ((Solid*)sol) -> IterateSolid (rpi); - sol -> GetSurfaceIndices (locsurf); - ((Solid*)sol) -> IterateSolid (urpi); - - for (int i = 0; i < locsurf.Size(); i++) - locsurf[i] = isidenticto[locsurf[i]]; - - for (int i = locsurf.Size()-1; i >= 0; i--) - { - bool indep = 1; - for (int j = 0; j < i; j++) - if (locsurf[i] == locsurf[j]) - { - indep = 0; - break; - } - - if (!indep) locsurf.Delete(i); - } - - - /* - // delete identified - for (int i = locsurf.Size()-1; i >= 0; i--) - { - bool indep = 1; - for (int j = 0; j < i; j++) - { - if (identicsurfaces.Used (INDEX_2::Sort (locsurf[i], locsurf[j])) != - (isidenticto[locsurf[i]] == isidenticto[locsurf[j]])) - { - cerr << "different result" << endl; - exit(1); - } - - if (isidenticto[locsurf[i]] == isidenticto[locsurf[j]]) - { - indep = 0; - break; - } - } - if (!indep) - locsurf.Delete(i); - } - - for (int i = 0; i < locsurf.Size(); i++) - locsurf[i] = isidenticto[locsurf[i]]; - */ - } - - - void CSGeometry :: - GetIndependentSurfaceIndices (const Solid * sol, - const Point<3> & p, Vec<3> & v, - ARRAY<int> & locsurf) const - { - Point<3> p2 = p + 1e-2 * v; - BoxSphere<3> box (p2, p2); - box.Increase (1e-3); - box.CalcDiamCenter(); - GetIndependentSurfaceIndices (sol, box, locsurf); - } - - - void CSGeometry :: - CalcTriangleApproximation(const Box<3> & boundingbox, - double detail, double facets) - { - PrintMessage (1, "Calc Triangle Approximation"); - - // FindIdenticSurfaces (1e-6); - - int ntlo = GetNTopLevelObjects(); - - for (int i = 0; i < triapprox.Size(); i++) - delete triapprox[i]; - triapprox.SetSize (ntlo); - - ARRAY<int> surfind; - - for (int i = 0; i < ntlo; i++) - { - Solid * sol; - Surface * surf; - GetTopLevelObject (i, sol, surf); - - sol -> CalcSurfaceInverse (); - - TriangleApproximation * tams = new TriangleApproximation(); - triapprox[i] = tams; - - // sol -> GetSurfaceIndices (surfind); - for (int j = 0; j < GetNSurf(); j++) - // for (int jj = 0; jj < surfind.Size(); jj++) - { - // int j = surfind[jj]; - - PrintMessageCR (3, "Surface ", j, "/", GetNSurf()); - // PrintMessageCR (3, "Surface ", j, "/", surfind.Size()); - - if (surf && surf != GetSurface(j)) - continue; - - TriangleApproximation tas; - GetSurface (j) -> GetTriangleApproximation (tas, boundingbox, facets); - - int oldnp = tams -> GetNP(); - - if (!tas.GetNP()) - continue; - - for (int k = 0; k < tas.GetNP(); k++) - { - tams -> AddPoint (tas.GetPoint(k)); - Vec<3> n = GetSurface(j) -> GetNormalVector (tas.GetPoint(k)); - n.Normalize(); - if (GetSurface(j)->Inverse()) n *= -1; - tams -> AddNormal (n); - } - - - BoxSphere<3> surfbox; - - if (tas.GetNP()) - surfbox.Set (tas.GetPoint(0)); - for (int k = 1; k < tas.GetNP(); k++) - surfbox.Add (tas.GetPoint(k)); - surfbox.Increase (1e-6); - surfbox.CalcDiamCenter(); - - Solid * surflocsol = sol -> GetReducedSolid (surfbox); - if (!surflocsol) - continue; - - for (int k = 0; k < tas.GetNT(); k++) - { - const TATriangle & tri = tas.GetTriangle (k); - - // check triangle - BoxSphere<3> box; - box.Set (tas.GetPoint (tri[0])); - box.Add (tas.GetPoint (tri[1])); - box.Add (tas.GetPoint (tri[2])); - box.Increase (1e-6); - box.CalcDiamCenter(); - - - Solid * locsol = surflocsol -> GetReducedSolid (box); - - if (locsol) - { - TATriangle tria(j, - tri[0] + oldnp, - tri[1] + oldnp, - tri[2] + oldnp); - - RefineTriangleApprox (locsol, j, box, detail, - tria, *tams); - delete locsol; - } - } - } - - tams->RemoveUnusedPoints (); - PrintMessage (2, "Object ", i, " has ", tams->GetNT(), " triangles"); - } - - Change(); - } - - - - void CSGeometry :: - RefineTriangleApprox (Solid * locsol, - int surfind, - const BoxSphere<3> & box, - double detail, - const TATriangle & tria, - TriangleApproximation & tams) - { - int pinds[6]; - ArrayMem<int,500> surfused(GetNSurf()); - - ReducePrimitiveIterator rpi(box); - UnReducePrimitiveIterator urpi; - - - locsol -> IterateSolid (rpi); - // locsol -> GetSurfaceIndices (lsurfi); - - - IndexSet iset(GetNSurf()); - locsol -> GetSurfaceIndices (iset); - const ARRAY<int> & lsurfi = iset.Array(); - - locsol -> IterateSolid (urpi); - - - int surfii = -1; - for (int i = 0; i < lsurfi.Size(); i++) - if (lsurfi[i] == surfind) - { - surfii = i; - break; - } - - if (surfii == -1) - return; - - - int cntindep = 0; - - for (int i = 0; i < lsurfi.Size(); i++) - { - int linkto = isidenticto[lsurfi[i]]; - surfused[linkto] = 0; - } - - for (int i = 0; i < lsurfi.Size(); i++) - { - int linkto = isidenticto[lsurfi[i]]; - if (!surfused[linkto]) - { - surfused[linkto] = 1; - cntindep++; - } - } - - int inverse = surfaces[surfind]->Inverse(); - - if (cntindep == 1) - { - tams.AddTriangle (tria); - return; - } - - if (cntindep == 2) - { - // just 2 surfaces: - // if smooth, project inner points to edge and finish - - int otherind = -1; - - for (int i = 0; i < lsurfi.Size(); i++) - { - INDEX_2 i2 (lsurfi[i], surfind); - i2.Sort(); - - if (i != surfii && !identicsurfaces.Used(i2)) - otherind = lsurfi[i]; - } - - double kappa = GetSurface(otherind)-> MaxCurvature (); - - if (kappa * box.Diam() < 0.1) - { - int pnums[6]; - static int between[3][3] = - { { 1, 2, 3 }, - { 0, 2, 4 }, - { 0, 1, 5 } }; - int onsurface[3]; - - for (int j = 0; j < 3; j++) - { - int pi = tria[j]; - pnums[j] = pi; - onsurface[j] = - !locsol->IsStrictIn (tams.GetPoint (pi), 1e-6) && - locsol->IsIn (tams.GetPoint (pi), 1e-6); - } - - for (int j = 0; j < 3; j++) - { - int lpi1 = between[j][0]; - int lpi2 = between[j][1]; - int lpin = between[j][2]; - if (onsurface[lpi1] == onsurface[lpi2]) - pnums[lpin] = -1; - else - { - const Point<3> & p1 = tams.GetPoint (pnums[lpi1]); - const Point<3> & p2 = tams.GetPoint (pnums[lpi2]); - double f1 = GetSurface(otherind)->CalcFunctionValue (p1); - double f2 = GetSurface(otherind)->CalcFunctionValue (p2); - - Point<3> pn; - if ( fabs (f1-f2) > 1e-20 ) - { - double l2 = -f1/(f2-f1); - double l1 = f2/(f2-f1); - pn = Point<3>(l1 * p1(0) + l2 * p2(0), - l1 * p1(1) + l2 * p2(1), - l1 * p1(2) + l2 * p2(2)); - } - else - pn = p1; - - pnums[lpin] = tams.AddPoint (pn); - - GetSurface (surfind)->Project (pn); - - Vec<3> n; - n = GetSurface (surfind)->GetNormalVector (pn); - if (inverse) n *= -1; - tams.AddNormal(n); - } - } - - int vcase = 0; - if (onsurface[0]) vcase++; - if (onsurface[1]) vcase+=2; - if (onsurface[2]) vcase+=4; - - static int trias[8][6] = - { { 0, 0, 0, 0, 0, 0 }, - { 1, 6, 5, 0, 0, 0 }, - { 2, 4, 6, 0, 0, 0 }, - { 1, 2, 4, 1, 4, 5 }, - { 3, 5, 4, 0, 0, 0 }, - { 1, 6, 4, 1, 4, 3 }, - { 2, 3, 6, 3, 5, 6 }, - { 1, 2, 3, 0, 0, 0 } }; - static int ntrias[4] = - { 0, 1, 2, 1 }; - - int nvis = 0; - for (int j = 0; j < 3; j++) - if (onsurface[j]) - nvis++; - - for (int j = 0; j < ntrias[nvis]; j++) - { - TATriangle ntria(tria.SurfaceIndex(), - pnums[trias[vcase][3*j]-1], - pnums[trias[vcase][3*j+1]-1], - pnums[trias[vcase][3*j+2]-1]); - tams.AddTriangle (ntria); - } - - /* saturn changes: - - int pvis[3]; - for (j = 0; j < 3; j++) - pvis[j] = !locsol->IsStrictIn (tams.GetPoint (j+1), 1e-6) && - locsol->IsIn (tams.GetPoint (j+1), 1e-6); - - int newpi[3]; - for (j = 0; j < 3; j++) - { - int pi1 = j; - int pi2 = (j+1) % 3; - int pic = j; - - if (pvis[pi1] != pvis[pi2]) - { - Point<3> hp = Center (tams.GetPoint (tria.PNum (pi1+1)), - tams.GetPoint (tria.PNum (pi2+1))); - - newpi[j] = tams.AddPoint (hp); - Vec<3> n = tams.GetNormal (pi1); - tams.AddNormal (n); - } - else - newpi[j] = 0; - } - - int nvis = 0; - for (j = 0; j <= nvis; j++) - if (pvis[j]) nvis++; - - int si = tria.SurfaceIndex(); - switch (nvis) - { - case 0: - break; - case 1: - { - int visj; - for (j = 0; j < 3; j++) - if (pvis[j]) visj = j; - int pivis = tria.PNum (visj+1); - int pic1 = newpi[(visj+1)%3]; - int pic2 = newpi[(visj+2)%3]; - - cout << pivis << "," << pic1 << "," << pic2 << endl; - - tams.AddTriangle (TATriangle (si, pivis, pic1,pic2)); - break; - } - case 2: - { - int nvisj; - for (j = 0; j < 3; j++) - if (!pvis[j]) nvisj = j; - - int pivis1 = tria.PNum ((nvisj+1)%3+1); - int pivis2 = tria.PNum ((nvisj+2)%3+1); - int pic1 = newpi[nvisj]; - int pic2 = newpi[(nvisj+2)%3]; - - tams.AddTriangle (TATriangle (si, pivis1, pic1,pic2)); - tams.AddTriangle (TATriangle (si, pivis1, pic1,pivis2)); - break; - } - case 3: - { - tams.AddTriangle (tria); - break; - } - } - - */ - return; - } - } - - // bisection - if (box.Diam() < detail) - return; - - for (int i = 0; i < 3; i++) - pinds[i] = tria[i]; - - static int between[3][3] = - { { 0, 1, 5 }, - { 0, 2, 4 }, - { 1, 2, 3 } }; - - for (int i = 0; i < 3; i++) - { - // int pi1 = tria[between[i][0]]; - - Point<3> newp = Center (tams.GetPoint (tria[between[i][0]]), - tams.GetPoint (tria[between[i][1]])); - Vec<3> n; - - GetSurface(surfind)->Project (newp); - n = GetSurface(surfind)->GetNormalVector (newp); - - pinds[between[i][2]] = tams.AddPoint (newp); - if (inverse) n *= -1; - tams.AddNormal (n); - } - - static int trias[4][4] = - { { 0, 5, 4 }, - { 5, 1, 3 }, - { 4, 3, 2 }, - { 3, 4, 5 } }; - - for (int i = 0; i < 4; i++) - { - TATriangle ntri(surfind, - pinds[trias[i][0]], - pinds[trias[i][1]], - pinds[trias[i][2]]); - - // check triangle - BoxSphere<3> nbox; - nbox.Set (tams.GetPoint (ntri[0])); - nbox.Add (tams.GetPoint (ntri[1])); - nbox.Add (tams.GetPoint (ntri[2])); - nbox.Increase (1e-6); - nbox.CalcDiamCenter(); - - Solid * nsol = locsol -> GetReducedSolid (nbox); - - if (nsol) - { - RefineTriangleApprox (nsol, surfind, nbox, - detail, ntri, tams); - - delete nsol; - } - } - } - - - - - class ClearVisitedIt : public SolidIterator - { - public: - ClearVisitedIt () { ; } - virtual ~ClearVisitedIt () { ; } - - virtual void Do (Solid * sol) - { - sol -> visited = 0; - } - }; - - - void CSGeometry :: - IterateAllSolids (SolidIterator & it, int only_once) - { - if (only_once) - { - ClearVisitedIt clit; - for (int i = 0; i < solids.Size(); i++) - solids[i] -> IterateSolid (clit, 0); - } - - for (int i = 0; i < solids.Size(); i++) - solids[i] -> IterateSolid (it, only_once); - } - - - double CSGeometry :: MaxSize () const - { - double maxs, mins; - maxs = max3 (boundingbox.PMax()(0), - boundingbox.PMax()(1), - boundingbox.PMax()(2)); - mins = min3 (boundingbox.PMin()(0), - boundingbox.PMin()(1), - boundingbox.PMin()(2)); - return max2 (maxs, -mins) * 1.1; - } -} diff --git a/Netgen/libsrc/csg/csgeom.hpp b/Netgen/libsrc/csg/csgeom.hpp deleted file mode 100644 index 6e29a8163b..0000000000 --- a/Netgen/libsrc/csg/csgeom.hpp +++ /dev/null @@ -1,257 +0,0 @@ -#ifndef FILE_CSGEOM -#define FILE_CSGEOM - -/**************************************************************************/ -/* File: csgeom.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 27. Nov. 97 */ -/**************************************************************************/ - -/** - Constructive Solid Geometry -*/ - - -class TriangleApproximation; -class TATriangle; - - -/** - A top level object is an entity to be meshed. - I can be either a solid, or one surface patch of a solid. - */ -class TopLevelObject -{ - Solid * solid; - Surface * surface; - - double red, blue, green; - bool visible, transp; - double maxh; - string material; - int layer; - int bc; // for surface patches, only -public: - TopLevelObject (Solid * asolid, - Surface * asurface = NULL); - - const Solid * GetSolid() const { return solid; } - Solid * GetSolid() { return solid; } - - const Surface * GetSurface () const { return surface; } - Surface * GetSurface () { return surface; } - - void GetData (ostream & ost); - void SetData (istream & ist); - - void SetMaxH (double amaxh) { maxh = amaxh; } - double GetMaxH () const { return maxh; } - - void SetRGB (double ared, double agreen, double ablue) - { - red = ared; - green = agreen; - blue = ablue; - } - - double GetRed () const { return red; } - double GetGreen () const { return green; } - double GetBlue () const { return blue; } - - void SetTransparent (bool atransp) - { transp = atransp; } - bool GetTransparent () const { return transp; } - - void SetVisible (bool avisible) - { visible = avisible; } - bool GetVisible () const { return visible; } - - const string GetMaterial () const { return material; } - void SetMaterial (const string & mat) { material = mat; } - - int GetLayer () const { return layer; } - void SetLayer (int alayer) { layer = alayer; } - - void SetBCProp (int abc) { bc = abc; } - int GetBCProp () const { return bc; } -}; - - -/** - CSGeometry has the whole geometric information - */ -class CSGeometry -{ -private: - /// all surfaces - SYMBOLTABLE<Surface*> surfaces; - - /// all named solids - SYMBOLTABLE<Solid*> solids; - - /// all top level objects: solids and surfaces - ARRAY<TopLevelObject*> toplevelobjects; - - /// additional points specified by user - ARRAY<Point<3> > userpoints; - - /// triangular approximation of top level objects - ARRAY<TriangleApproximation*> triapprox; - - /// increment, if geometry is changed - static int changeval; - - /// bounding box of geometry - Box<3> boundingbox; - - /// bounding box, if not set by input file - static Box<3> default_boundingbox; - - /// identic surfaces are stored by pair of indizes, val = inverse - INDEX_2_HASHTABLE<int> identicsurfaces; - ARRAY<int> isidenticto; - - /// identification of boundaries (periodic, thin domains, ...) - - - - /// filename of inputfile - string filename; - -public: - CSGeometry (); - CSGeometry (const string & afilename); - ~CSGeometry (); - - void Clean (); - - void Save (ostream & ost); - void Load (istream & ist); - - int GetChangeVal() { return changeval; } - void Change() { changeval++; } - - void AddSurface (Surface * surf); - void AddSurface (char * name, Surface * surf); - void AddSurfaces (Primitive * prim); - - int GetNSurf () const { return surfaces.Size(); } - const Surface * GetSurface (const char * name) const; - const Surface * GetSurface (int i) const - { return surfaces[i]; } - - void SetSolid (const char * name, Solid * sol); - const Solid * GetSolid (const char * name) const; - const Solid * GetSolid (const string & name) const; - int GetNSolids () const { return solids.Size(); } - const Solid * GetSolid (int i) { return solids[i]; } - const SYMBOLTABLE<Solid*> & GetSolids () const { return solids; } - - - void SetFlags (const char * solidname, const Flags & flags); - - - int GetNTopLevelObjects () const - { return toplevelobjects.Size(); } - int SetTopLevelObject (Solid * sol, Surface * surf = NULL); - void GetTopLevelObject (int nr, Solid *& sol, Surface *& surf) - { - sol = toplevelobjects[nr]->GetSolid(); - surf = toplevelobjects[nr]->GetSurface(); - } - void GetTopLevelObject (int nr, const Solid *& sol, const Surface *& surf) const - { - sol = toplevelobjects[nr]->GetSolid(); - surf = toplevelobjects[nr]->GetSurface(); - } - - TopLevelObject * GetTopLevelObject (const Solid * sol, const Surface * surf = NULL); - TopLevelObject * GetTopLevelObject (int nr) - { return toplevelobjects[nr]; } - const TopLevelObject * GetTopLevelObject (int nr) const - { return toplevelobjects[nr]; } - void RemoveTopLevelObject (Solid * sol, Surface * surf = NULL); - - - void AddUserPoint (const Point<3> & p) - { userpoints.Append (p); } - int GetNUserPoints () const - { return userpoints.Size(); } - const Point<3> & GetUserPoint (int nr) const - { return userpoints[nr]; } - - - // quick implementations: - ARRAY<SingularFace*> singfaces; - ARRAY<SingularEdge*> singedges; - ARRAY<SingularPoint*> singpoints; - ARRAY<Identification*> identifications; - - int GetNIdentifications () { return identifications.Size(); } - void AddIdentification (Identification * ident); - - - /// - void CalcTriangleApproximation(const Box<3> & boundingbox, - double detail, double facets); - - /// - void FindIdenticSurfaces (double eps); - /// - void GetIndependentSurfaceIndices (const Solid * sol, - const BoxSphere<3> & box, - ARRAY<int> & locsurf) const; - /// - void GetIndependentSurfaceIndices (const Solid * sol, - const Point<3> & p, Vec<3> & v, - ARRAY<int> & locsurf) const; - /// - int GetSurfaceClassRepresentant (int si) const - { return isidenticto[si]; } - - /// - const TriangleApproximation * GetTriApprox (int msnr) - { - if (msnr < triapprox.Size()) - return triapprox[msnr]; - return 0; - } - - - void IterateAllSolids (SolidIterator & it, int only_once = 0); - - void RefineTriangleApprox (Solid * locsol, - int surfind, - const BoxSphere<3> & box, - double detail, - const TATriangle & tria, - TriangleApproximation & tams); - - const Box<3> & BoundingBox () const { return boundingbox; } - - void SetBoundingBox (const Box<3> & abox) - { - boundingbox = abox; - } - - - static void SetDefaultBoundingBox (const Box<3> & abox) - { - default_boundingbox = abox; - } - - double MaxSize () const; - - - - class BCModification { - public: - int si; - int tlonr; - int bcnr; - }; - ARRAY<BCModification> bcmodifications; - -}; -#endif - diff --git a/Netgen/libsrc/csg/csgparser.cpp b/Netgen/libsrc/csg/csgparser.cpp deleted file mode 100644 index b6d4878399..0000000000 --- a/Netgen/libsrc/csg/csgparser.cpp +++ /dev/null @@ -1,1156 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - using namespace netgen; - - - enum TOKEN_TYPE - { - TOK_MINUS = '-', TOK_LP = '(', OK_RP = ')', TOK_LSP = '[', TOK_RSP = ']', - TOK_EQU = '=', TOK_COMMA = ',', TOK_SEMICOLON = ';', - TOK_NUM = 100, TOK_STRING, TOK_NAMED_SOLID, TOK_PRIMITIVE, - TOK_OR, TOK_AND, TOK_NOT, - TOK_SINGULAR, TOK_EDGE, TOK_POINT, TOK_FACE, TOK_IDENTIFY, TOK_CLOSESURFACES, - TOK_CLOSEEDGES, TOK_PERIODIC, - TOK_SOLID, TOK_RECO, TOK_TLO, TOK_BOUNDINGBOX, TOK_BOUNDARYCONDITION, - TOK_END }; - - struct kwstruct - { - TOKEN_TYPE kw; - char * name; - }; - - static kwstruct defkw[] = - { - { TOK_RECO, "algebraic3d" }, - { TOK_SOLID, "solid" }, - { TOK_TLO, "tlo" }, - { TOK_BOUNDINGBOX, "boundingbox" }, - { TOK_OR, "or" }, - { TOK_AND, "and" }, - { TOK_NOT, "not" }, - { TOK_SINGULAR, "singular" }, - { TOK_EDGE, "edge" }, - { TOK_FACE, "face" }, - { TOK_POINT, "point" }, - { TOK_IDENTIFY, "identify" }, - { TOK_CLOSESURFACES, "closesurfaces" }, - { TOK_CLOSEEDGES, "closeedges" }, - { TOK_PERIODIC, "periodic" }, - { TOK_BOUNDARYCONDITION, "boundarycondition" }, - { TOKEN_TYPE(0) } - }; - - enum PRIMITIVE_TYPE - { - TOK_SPHERE = 1, TOK_CYLINDER, TOK_PLANE, TOK_ELLIPTICCYLINDER, - TOK_ELLIPSOID, TOK_CONE, - TOK_ORTHOBRICK, TOK_POLYHEDRON, - - TOK_TUBE, TOK_GENCYL, TOK_EXTRUSION, TOK_REVOLUTION, // currently, out of order - - TOK_TRANSLATE, TOK_MULTITRANSLATE, TOK_ROTATE, TOK_MULTIROTATE - }; - - struct primstruct - { - PRIMITIVE_TYPE kw; - char * name; - }; - - static primstruct defprim[] = - { - { TOK_PLANE, "plane" }, - { TOK_SPHERE, "sphere" }, - { TOK_CYLINDER, "cylinder" }, - { TOK_CONE, "cone" }, - { TOK_ELLIPTICCYLINDER, "ellipticcylinder" }, - { TOK_ELLIPSOID, "ellipsoid" }, - { TOK_ORTHOBRICK, "orthobrick" }, - { TOK_POLYHEDRON, "polyhedron" }, - - { TOK_TUBE, "tube" }, - { TOK_GENCYL, "gencyl" }, - { TOK_EXTRUSION, "extrusion" }, - { TOK_REVOLUTION, "revolution" }, - - { TOK_TRANSLATE, "translate" }, - { TOK_MULTITRANSLATE, "multitranslate" }, - { TOK_ROTATE, "rotate" }, - { TOK_MULTIROTATE, "multirotate" }, - { PRIMITIVE_TYPE(0) } - }; - - static CSGeometry * geom; - - - - class CSGScanner - { - TOKEN_TYPE token; - PRIMITIVE_TYPE prim_token; - double num_value; - string string_value; - - int linenum; - istream * scanin; - - public: - - CSGScanner (istream & ascanin); - - TOKEN_TYPE GetToken() const - { return token; } - - double GetNumValue() const - { return num_value; } - - const string & GetStringValue() const - { return string_value; } - - char GetCharValue() const - { return string_value[0]; } - - PRIMITIVE_TYPE GetPrimitiveToken() const - { return prim_token; } - - void ReadNext(); - - /* - CSGScanner & Parse (char ch); - CSGScanner & Parse (int & i); - CSGScanner & Parse (double & d); - CSGScanner & Parse (Point<3> & p); - CSGScanner & Parse (Vec<3> & p); - */ - void Error (const string & err); - }; - - - CSGScanner :: CSGScanner (istream & ascanin) - { - scanin = &ascanin; - token = TOK_END; - num_value = 0; - linenum = 1; - } - - - void CSGScanner :: ReadNext () - { - char ch; - - - // scan whitespaces - do - { - scanin->get(ch); - - if (ch == '\n') - linenum++; - - // end of file reached - if (scanin->eof()) - { - token = TOK_END; - return; - } - - // skip comment line - if (ch == '#') - { - while (ch != '\n') - { - scanin->get(ch); - if (scanin->eof()) - { - token = TOK_END; - return; - } - } - linenum++; - } - } - while (isspace(ch)); - - switch (ch) - { - case '(': case ')': - case '[': case ']': - case '-': - case '=': case ',': case ';': - { - token = TOKEN_TYPE (ch); - break; - } - - default: - { - if (isdigit (ch) || ch == '.') - { - scanin->putback (ch); - (*scanin) >> num_value; - token = TOK_NUM; - return; - } - - if (isalpha (ch)) - { - string_value = string (1, ch); - scanin->get(ch); - while (isalnum(ch) || ch == '_') - { - string_value += ch; - scanin->get(ch); - } - scanin->putback (ch); - } - - int nr = 0; - while (defkw[nr].kw) - { - if (string_value == defkw[nr].name) - { - token = defkw[nr].kw; - return; - } - nr++; - } - - nr = 0; - while (defprim[nr].kw) - { - if (string_value == defprim[nr].name) - { - token = TOK_PRIMITIVE; - prim_token = defprim[nr].kw; - return; - } - nr++; - } - - token = TOK_STRING; - } - } - } - - void CSGScanner :: Error (const string & err) - { - stringstream errstr; - errstr << "Parsing error in line " << linenum << ": " << endl << err << endl; - throw string(errstr.str()); - } - - - /* - Solid = Term { OR Term } - Term = Primary { AND Primary } - Primary = PRIM | IDENT | ( Solid ) | NOT Primary - */ - - void ParseChar (CSGScanner & scan, char ch) - { - if (scan.GetToken() != TOKEN_TYPE(ch)) - scan.Error (string ("token '") + string(1, ch) + string("' expected")); - scan.ReadNext(); - } - - double ParseNumber(CSGScanner & scan) - { - if (scan.GetToken() == '-') - { - scan.ReadNext(); - return -ParseNumber (scan); - } - if (scan.GetToken() != TOK_NUM) scan.Error ("number expected"); - double val = scan.GetNumValue(); - scan.ReadNext(); - return val; - } - - Vec<3> ParseVector (CSGScanner & scan) - { - Vec<3> v; - v(0) = ParseNumber (scan); - ParseChar (scan, ','); - v(1) = ParseNumber (scan); - ParseChar (scan, ','); - v(2) = ParseNumber (scan); - return v; - } - - - CSGScanner & operator>> (CSGScanner & scan, char ch) - { - if (scan.GetToken() != TOKEN_TYPE(ch)) - scan.Error (string ("token '") + string(1, ch) + string("' expected")); - scan.ReadNext(); - return scan; - } - - CSGScanner & operator>> (CSGScanner & scan, double & d) - { - d = ParseNumber (scan); - return scan; - } - - CSGScanner & operator>> (CSGScanner & scan, int & i) - { - i = int (ParseNumber (scan)); - return scan; - } - - CSGScanner & operator>> (CSGScanner & scan, Point<3> & p) - { - scan >> p(0) >> ',' >> p(1) >> ',' >> p(2); - return scan; - } - - CSGScanner & operator>> (CSGScanner & scan, Vec<3> & v) - { - scan >> v(0) >> ',' >> v(1) >> ',' >> v(2); - return scan; - } - - - Solid * ParseSolid (CSGScanner & scan); - Solid * ParseTerm (CSGScanner & scan); - Solid * ParsePrimary (CSGScanner & scan); - - - Solid * ParsePrimary (CSGScanner & scan) - { - if (scan.GetToken() == TOK_PRIMITIVE) - { - switch (scan.GetPrimitiveToken()) - { - case TOK_PLANE: - { - Point<3> p; - Vec<3> v; - - scan.ReadNext(); - scan >> '(' >> p >> ';' >> v >> ')'; - - OneSurfacePrimitive * surf = new Plane ( p, v ); - geom->AddSurfaces (surf); - return new Solid (surf); - } - - case TOK_CYLINDER: - { - Point<3> pa, pb; - double r; - - scan.ReadNext(); - scan >> '(' >> pa >> ';' >> pb >> ';' >> r >> ')'; - - OneSurfacePrimitive * surf = new Cylinder ( pa, pb, r ); - geom->AddSurfaces (surf); - return new Solid (surf); - } - - case TOK_ELLIPTICCYLINDER: - { - Point<3> pa; - Vec<3> vl, vs; - - scan.ReadNext(); - scan >> '(' >> pa >> ';' >> vl >> ';' >> vs >> ')'; - - OneSurfacePrimitive * surf = new EllipticCylinder ( pa, vl, vs); - geom->AddSurfaces (surf); - return new Solid (surf); - } - - - case TOK_ELLIPSOID: - { - Point<3> pa; - Vec<3> v1, v2, v3; - - scan.ReadNext(); - scan >> '(' >> pa >> ';' >> v1 >> ';' >> v2 >> ';' >> v3 >> ')'; - - OneSurfacePrimitive * surf = new Ellipsoid ( pa, v1, v2, v3); - geom->AddSurfaces (surf); - return new Solid (surf); - } - - - case TOK_CONE: - { - Point<3> pa, pb; - double ra, rb; - - scan.ReadNext(); - scan >> '(' >> pa >> ';' >> ra >> ';' >> pb >> ';' >> rb >> ')'; - - OneSurfacePrimitive * surf = new Cone ( pa, pb, ra, rb ); - geom->AddSurfaces (surf); - return new Solid (surf); - } - - - - case TOK_SPHERE: - { - Point<3> p; - double r; - - scan.ReadNext(); - scan >> '(' >> p >> ';' >> r >> ')'; - - OneSurfacePrimitive * surf = new Sphere ( p, r ); - geom->AddSurfaces (surf); - return new Solid (surf); - } - - case TOK_ORTHOBRICK: - { - Point<3> pa, pb; - - scan.ReadNext(); - scan >> '(' >> pa >> ';' >> pb >> ')'; - - Primitive * nprim = new OrthoBrick (pa, pb); - geom->AddSurfaces (nprim); - return new Solid (nprim); - } - - case TOK_POLYHEDRON: - { - // Added by Dalibor Lukas, October 15, 2003 - - Point<3> p; - int pi1, pi2, pi3, pi4; - - scan.ReadNext(); - ParseChar (scan, '('); - - Polyhedra * polyhedron = new Polyhedra; - - // scanning the points - while (1) - { - p = Point<3> (ParseVector (scan)); - ParseChar (scan, ';'); - - polyhedron->AddPoint(p); - - if (scan.GetToken() == ';') - { - scan.ReadNext(); - break; - } - } - - // scanning the faces - while (1) - { - pi1 = (int) (ParseNumber (scan)); - ParseChar (scan, ','); - pi2 = (int) (ParseNumber (scan)); - ParseChar (scan, ','); - pi3 = (int) (ParseNumber (scan)); - - polyhedron->AddFace(pi1-1,pi2-1,pi3-1); - - if (scan.GetToken() == TOK_COMMA) - { - ParseChar (scan, ','); - pi4 = (int) (ParseNumber (scan)); - polyhedron->AddFace(pi1-1,pi3-1,pi4-1); - } - - if (scan.GetToken() == ')') - { - scan.ReadNext(); - break; - } - scan.ReadNext(); - } - - geom->AddSurfaces (polyhedron); - return new Solid (polyhedron); - } - - - case TOK_EXTRUSION: // not functional - { - Point<3> p0; - Vec<3> ex, ey; - ARRAY<Point<2> > points; - - scan.ReadNext(); - - ParseChar (scan, '('); - p0(0) = ParseNumber (scan); - ParseChar (scan, ','); - p0(1) = ParseNumber (scan); - ParseChar (scan, ','); - p0(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - ex(0) = ParseNumber (scan); - ParseChar (scan, ','); - ex(1) = ParseNumber (scan); - ParseChar (scan, ','); - ex(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - ey(0) = ParseNumber (scan); - ParseChar (scan, ','); - ey(1) = ParseNumber (scan); - ParseChar (scan, ','); - ey(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - cout << "p0 = " << p0 << endl; - - // int npseg = 0; - // int nseg = 0; - while (1) - { - Point<2> p1, p2, p3; - - p1(0) = ParseNumber(scan); - ParseChar (scan, ','); - p1(1) = ParseNumber(scan); - points.Append (p1); - if (scan.GetToken() == ')') - { - scan.ReadNext(); - break; - } - scan.ReadNext(); - } - - - /* - while (1) - { - Point<2> p1, p2, p3; - - p3 = p2; - p2 = p1; - p1(0) = ParseNumber(scan); - ParseChar (scan, ','); - p1(1) = ParseNumber(scan); - npseg++; - - cout << "p1 = " << p1 << endl; - - if (scan.GetToken() == ';' || scan.GetToken() == ')') - { - if (npseg == 2) - { - p3 = p2; - p2 = Center (p1, p3); - } - if (nseg == 0) - points.Append (p3); - points.Append (p2); - points.Append (p1); - npseg = 1; - nseg++; - - cout << "p1, = " << p1 << ", p2 = " << p2 << ", p3 = " << p3 << endl; - } - - if (scan.GetToken() == ')') - { - scan.ReadNext(); - break; - } - if (scan.GetToken() == ';' || scan.GetToken() == ',') - { - scan.ReadNext(); - } - } - */ - cout << "p0 = " << p0 << endl; - cout << ", ex = " << ex << ", ey = " << ey << endl; - cout << "points = " << points << endl; - - Extrusion * extrusion = new Extrusion (p0, ex, ey, points); - - geom->AddSurfaces (extrusion); - return new Solid (extrusion); - - /* - // cout << "define cylinder, pa = " << pa << "; pb = " << pb - // << ", rad = " << r << endl; - OneSurfacePrimitive * surf = new Cylinder ( pa, pb, r ); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - */ - } - - - - - - case TOK_TRANSLATE: - { - Vec<3> v; - scan.ReadNext(); - - ParseChar (scan, '('); - v = ParseVector (scan); - ParseChar (scan, ';'); - - Solid * sol1 = ParseSolid (scan); - - ParseChar (scan, ')'); - - Solid * nsol = sol1 -> Copy(*geom); - Transformation<3> trans(v); - nsol -> Transform (trans); - return nsol; - } - - - case TOK_MULTITRANSLATE: - { - Vec<3> v; - int n; - - scan.ReadNext(); - - scan >> '(' >> v >> ';' >> n >> ';'; - - Solid * sol1 = ParseSolid (scan); - - scan >> ')'; - - Solid * hsol = sol1; - for (int i = 1; i <= n; i++) - { - Solid * nsol = sol1 -> Copy(*geom); - Transformation<3> trans(double(i) * v); - - nsol -> Transform (trans); - hsol = new Solid (Solid::UNION, hsol, nsol); - } - return hsol; - } - - - case TOK_MULTIROTATE: - { - Point<3> c; - Vec<3> v; - int n; - - scan.ReadNext(); - - scan >> '(' >> c >> ';' >> v >> ';' >> n >> ';'; - Solid * sol1 = ParseSolid (scan); - scan >> ')'; - - Transformation<3> trans(c, v(0), v(1), v(2)); - Transformation<3> multi(Vec<3>(0,0,0)); - Transformation<3> ht; - - Solid * hsol = sol1; - for (int i = 1; i <= n; i++) - { - Solid * nsol = sol1 -> Copy(*geom); - - nsol -> Transform (multi); - hsol = new Solid (Solid::UNION, hsol, nsol); - - ht=multi; - multi.Combine (trans, ht); - } - return hsol; - } - - - default: - { - scan.Error (string ("unknown primary ") + scan.GetStringValue()); - } - - } - } - - else if (scan.GetToken() == TOK_STRING && - geom->GetSolid(scan.GetStringValue())) - - { - Solid * sol = const_cast<Solid*> (geom->GetSolid(scan.GetStringValue())); - scan.ReadNext(); - return sol; - } - - else if (scan.GetToken() == TOK_NOT) - - { - scan.ReadNext(); - Solid * sol1 = ParsePrimary (scan); - return new Solid (Solid::SUB, sol1); - } - - else if (scan.GetToken() == '(') - - { - scan.ReadNext(); - Solid * sol1 = ParseSolid (scan); - scan.ReadNext(); - return sol1; - } - - scan.Error (string ("not a primary, name = ")+ - scan.GetStringValue()); - return 0; - } - - - - Solid * ParseTerm (CSGScanner & scan) - { - Solid * sol = ParsePrimary(scan); - while (scan.GetToken() == TOK_AND) - { - scan.ReadNext(); - Solid * sol2 = ParsePrimary(scan); - sol = new Solid (Solid::SECTION, sol, sol2); - } - return sol; - } - - - Solid * ParseSolid (CSGScanner & scan) - { - Solid * sol = ParseTerm(scan); - while (scan.GetToken() == TOK_OR) - { - scan.ReadNext(); - Solid * sol2 = ParseTerm(scan); - sol = new Solid (Solid::UNION, sol, sol2); - } - return sol; - } - - - - void ParseFlags (CSGScanner & scan, Flags & flags) - { - while (scan.GetToken() == '-') - { - scan.ReadNext(); - string name = scan.GetStringValue(); - scan.ReadNext(); - if (scan.GetToken() == '=') - { - scan.ReadNext(); - if (scan.GetToken() == TOK_STRING) - { - flags.SetFlag (name.c_str(), scan.GetStringValue().c_str()); - scan.ReadNext(); - } - else if (scan.GetToken() == '[') - { - scan.ReadNext(); - ARRAY<double> vals; - vals.Append (ParseNumber(scan)); - while (scan.GetToken() == ',') - { - scan.ReadNext(); - vals.Append (ParseNumber(scan)); - } - ParseChar (scan, ']'); - flags.SetFlag (name.c_str(), vals); - } - else if (scan.GetToken() == TOK_NUM) - { - flags.SetFlag (name.c_str(), scan.GetNumValue()); - scan.ReadNext(); - } - } - else - { - flags.SetFlag (name.c_str()); - } - } - } - - - /* - Main parsing function for CSG geometry - */ - CSGeometry * ParseCSG (istream & istr) - { - CSGScanner scan(istr); - - geom = new CSGeometry; - - scan.ReadNext(); - if (scan.GetToken() != TOK_RECO) // keyword 'algebraic3d' - return 0; - - scan.ReadNext(); - - try - { - while (1) - { - if (scan.GetToken() == TOK_END) break; - - if (scan.GetToken() == TOK_SOLID) - { - scan.ReadNext(); - if (scan.GetToken() != TOK_STRING) - scan.Error ("name identifier expected"); - string solidname = scan.GetStringValue(); - - scan.ReadNext(); - - ParseChar (scan, '='); - Solid * solid = ParseSolid (scan); - - Flags flags; - ParseFlags (scan, flags); - - geom->SetSolid (solidname.c_str(), new Solid (Solid::ROOT, solid)); - geom->SetFlags (solidname.c_str(), flags); - - ParseChar (scan, ';'); - - PrintMessage (4, "define solid ", solidname); - } - - else if (scan.GetToken() == TOK_TLO) - - { // a TopLevelObject definition - - scan.ReadNext(); - - string name = scan.GetStringValue(); - scan.ReadNext(); - - if (scan.GetToken() != TOK_STRING) - - { // a solid TLO - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - if (!geom->GetSolid (name)) - scan.Error ("Top-Level-Object "+name+" not defined"); - - int tlonr = - geom->SetTopLevelObject ((Solid*)geom->GetSolid(name)); - TopLevelObject * tlo = geom->GetTopLevelObject (tlonr); - - if (flags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = - flags.GetNumListFlag ("col"); - tlo->SetRGB (col[0], col[1], col[2]); - } - - if (flags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - - tlo->SetMaterial (flags.GetStringFlag ("material", "")); - tlo->SetLayer (int(flags.GetNumFlag ("layer", 1))); - if (flags.NumFlagDefined ("maxh")) - tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10)); - } - - else - - { // a surface TLO - - string surfname = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - ARRAY<int> si; - geom->GetSolid(surfname)->GetSurfaceIndices(si); - int tlonr = - geom->SetTopLevelObject ((Solid*)geom->GetSolid(name), - (Surface*)geom->GetSurface(si.Get(1))); - TopLevelObject * tlo = geom->GetTopLevelObject (tlonr); - if (flags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = flags.GetNumListFlag ("col"); - tlo->SetRGB (col.Get(1), col.Get(2), col.Get(3)); - } - if (flags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - - if (flags.NumFlagDefined ("maxh")) - tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10)); - tlo->SetLayer (int(flags.GetNumFlag ("layer", 1))); - tlo->SetBCProp (int(flags.GetNumFlag ("bc", -1))); - } - } - - else if (scan.GetToken() == TOK_IDENTIFY) - - { - - scan.ReadNext(); - switch (scan.GetToken()) - { - case TOK_CLOSESURFACES: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - - ARRAY<int> si1, si2; - geom->GetSolid(name1)->GetSurfaceIndices(si1); - geom->GetSolid(name2)->GetSurfaceIndices(si2); - - const TopLevelObject * domain = - geom->GetTopLevelObject (geom->GetSolid(flags.GetStringFlag ("tlo",""))); - - geom->AddIdentification - (new CloseSurfaceIdentification - (geom->GetNIdentifications()+1, *geom, - geom->GetSurface (si1[0]), geom->GetSurface (si2[0]), - domain, - flags)); - - break; - } - - case TOK_PERIODIC: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - ParseChar (scan, ';'); - - - ARRAY<int> si1, si2; - geom->GetSolid(name1)->GetSurfaceIndices(si1); - geom->GetSolid(name2)->GetSurfaceIndices(si2); - - geom->AddIdentification - (new PeriodicIdentification - (geom->GetNIdentifications()+1, - *geom, - geom->GetSurface (si1.Get(1)), - geom->GetSurface (si2.Get(1)))); - break; - } - - default: - scan.Error ("keyword 'closesurfaces' or 'periodic' expected"); - } - - } - - else if (scan.GetToken() == TOK_SINGULAR) - - { - - scan.ReadNext(); - switch (scan.GetToken()) - { - case TOK_FACE: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); // tlo - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - const Solid * sol = geom->GetSolid(name2); - - for (int i = 0; i < geom->GetNTopLevelObjects(); i++) - if (name1 == geom->GetTopLevelObject (i)->GetSolid()->Name()) - geom->singfaces.Append (new SingularFace (i+1, sol)); - - break; - } - - case TOK_EDGE: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - const Solid * s1 = geom->GetSolid(name1); - const Solid * s2 = geom->GetSolid(name2); - geom->singedges.Append (new SingularEdge (1, s1, s2)); - break; - } - - case TOK_POINT: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - string name2 = scan.GetStringValue(); - scan.ReadNext(); - string name3 = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - const Solid * s1 = geom->GetSolid(name1); - const Solid * s2 = geom->GetSolid(name2); - const Solid * s3 = geom->GetSolid(name3); - geom->singpoints.Append (new SingularPoint (1, s1, s2, s3)); - break; - } - default: - scan.Error ("keyword 'face' or 'edge' or 'point' expected"); - } - } - - - else if (scan.GetToken() == TOK_POINT) - { - Point<3> p; - - scan.ReadNext(); - ParseChar (scan, '('); - p = Point<3> (ParseVector (scan)); - ParseChar (scan, ')'); - ParseChar (scan, ';'); - - geom->AddUserPoint (p); - } - - else if (scan.GetToken() == TOK_BOUNDINGBOX) - { - Point<3> p1, p2; - - scan.ReadNext(); - ParseChar (scan, '('); - p1 = Point<3> (ParseVector (scan)); - ParseChar (scan, ';'); - p2 = Point<3> (ParseVector (scan)); - ParseChar (scan, ')'); - ParseChar (scan, ';'); - - geom->SetBoundingBox (Box<3> (p1, p2)); - } - - else if (scan.GetToken() == TOK_BOUNDARYCONDITION) - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - int num = int (ParseNumber (scan)); - ParseChar (scan, ';'); - - - CSGeometry::BCModification bcm; - ARRAY<int> si; - - geom->GetSolid(name1)->GetSurfaceIndices(si); - - bcm.tlonr = -1; - int i; - for (i = 0; i < geom->GetNTopLevelObjects(); i++) - if (string (geom->GetTopLevelObject(i)->GetSolid()->Name()) - == name2) - { - bcm.tlonr = i; - break; - } - - bcm.bcnr = num; - for (i = 0; i < si.Size(); i++) - { - bcm.si = si[i]; - geom->bcmodifications.Append (bcm); - } - } - - else - { - cout << "read unidentified token " << scan.GetToken() - << " string = " << scan.GetStringValue() << endl; - scan.ReadNext(); - } - } - } - catch (string errstr) - { - cout << "caught error " << errstr << endl; - throw NgException (errstr); - } - - - return geom; - /* - do - { - scan.ReadNext(); - if (scan.GetToken() == TOK_STRING) - cout << "found string " << scan.GetStringValue() << endl; - else - cout << "token = " << int(scan.GetToken()) << endl; - } - while (scan.GetToken() != TOK_END); - */ - } - - -}; - diff --git a/Netgen/libsrc/csg/csgparser_dalibor.cpp b/Netgen/libsrc/csg/csgparser_dalibor.cpp deleted file mode 100644 index 7f640864a3..0000000000 --- a/Netgen/libsrc/csg/csgparser_dalibor.cpp +++ /dev/null @@ -1,1111 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - using namespace netgen; - - - enum TOKEN_TYPE - { - TOK_MINUS = '-', TOK_LP = '(', OK_RP = ')', TOK_LSP = '[', TOK_RSP = ']', - TOK_EQU = '=', TOK_COMMA = ',', TOK_SEMICOLON = ';', - TOK_NUM = 100, TOK_STRING, TOK_NAMED_SOLID, TOK_PRIMITIVE, - TOK_OR, TOK_AND, TOK_NOT, - TOK_TRANSLATE, TOK_MULTITRANSLATE, TOK_ROTATE, TOK_MULTIROTATE, - TOK_SINGULAR, TOK_EDGE, TOK_POINT, TOK_IDENTIFY, TOK_CLOSESURFACES, - TOK_CLOSEEDGES, TOK_PERIODIC, - TOK_SOLID, TOK_RECO, TOK_TLO, TOK_BOUNDINGBOX, TOK_BOUNDARYCONDITION, - TOK_END }; - - struct kwstruct - { - TOKEN_TYPE kw; - char * name; - }; - - static kwstruct defkw[] = - { - { TOK_RECO, "algebraic3d" }, - { TOK_SOLID, "solid" }, - { TOK_TLO, "tlo" }, - { TOK_BOUNDINGBOX, "boundingbox" }, - { TOK_OR, "or" }, - { TOK_AND, "and" }, - { TOK_NOT, "not" }, - { TOK_TRANSLATE, "translate" }, - { TOK_MULTITRANSLATE, "multitranslate" }, - { TOK_ROTATE, "rotate" }, - { TOK_MULTIROTATE, "multirotate" }, - { TOK_SINGULAR, "singular" }, - { TOK_EDGE, "edge" }, - { TOK_POINT, "point" }, - { TOK_IDENTIFY, "identify" }, - { TOK_CLOSESURFACES, "closesurfaces" }, - { TOK_CLOSEEDGES, "closeedges" }, - { TOK_PERIODIC, "periodic" }, - { TOK_BOUNDARYCONDITION, "boundarycondition" }, - { TOKEN_TYPE(0) } - }; - - enum PRIMITIVE_TYPE - { TOK_SPHERE = 1, TOK_CYLINDER, TOK_PLANE, TOK_ELLIPTICCYLINDER, - TOK_ELLIPSOID, - TOK_CONE, TOK_TUBE, - TOK_GENCYL, TOK_ORTHOBRICK, TOK_POLYHEDRON, TOK_EXTRUSION, TOK_REVOLUTION }; - - struct primstruct - { - PRIMITIVE_TYPE kw; - char * name; - }; - - static primstruct defprim[] = - { - { TOK_PLANE, "plane" }, - { TOK_SPHERE, "sphere" }, - { TOK_CYLINDER, "cylinder" }, - { TOK_CONE, "cone" }, - { TOK_ELLIPTICCYLINDER, "ellipticcylinder" }, - { TOK_ELLIPSOID, "ellipsoid" }, - { TOK_TUBE, "tube" }, - { TOK_GENCYL, "gencyl" }, - { TOK_ORTHOBRICK, "orthobrick" }, - { TOK_POLYHEDRON, "polyhedron" }, - { TOK_EXTRUSION, "extrusion" }, - { TOK_REVOLUTION, "revolution" }, - { PRIMITIVE_TYPE(0) } - }; - - - - static CSGeometry * geom; - - /* -%token <solidtype> TOK_SPHERE TOK_CYLINDER TOK_CONE TOK_PLAIN TOK_TUBE TOK_GENCYL TOK_ORTHOBRICK TOK_POLYHEDRON TOK_REVOLUTION -%left <solidtype> TOK_OR TOK_AND TOK_NOT -%token <solidtype> TOK_TRANSLATE TOK_MULTITRANSLATE TOK_ROTATE TOK_MULTIROTATE -%type <solidtype> solid solidprimitive -%type <void> splinesegmentlist splinesegment readbspline bsplinepointlist -%type <chptr> anyident -%token TOK_SINGULAR TOK_EDGE TOK_POINT -%token TOK_IDENTIFY TOK_CLOSESURFACES TOK_CLOSEEDGES TOK_PERIODIC -%token TOK_BOUNDARYCONDITION -%type <void> polyhedronpoints polyhedronfaces polyhedronpoint polyhedronface -%type <void> revolutionpoints revolutionpoint - */ - - - - class CSGScanner - { - TOKEN_TYPE token; - PRIMITIVE_TYPE prim_token; - double num_value; - string string_value; - - int linenum; - istream * scanin; - - public: - - CSGScanner (istream & ascanin); - - TOKEN_TYPE GetToken() const - { return token; } - - double GetNumValue() const - { return num_value; } - - const string & GetStringValue() const - { return string_value; } - - PRIMITIVE_TYPE GetPrimitiveToken() const - { return prim_token; } - - void ReadNext(); - void Error (const string & err); - }; - - - CSGScanner :: CSGScanner (istream & ascanin) - { - int i; - - scanin = &ascanin; - token = TOK_END; - num_value = 0; - linenum = 1; - } - - - void CSGScanner :: ReadNext () - { - char ch; - - - // whitespaces ueberspringen - do - { - scanin->get(ch); - - if (ch == '\n') - linenum++; - - // end of file reached - if (scanin->eof()) - { - token = TOK_END; - return; - } - - // skip comment line - if (ch == '#') - { - while (ch != '\n') - { - scanin->get(ch); - if (scanin->eof()) - { - token = TOK_END; - return; - } - } - linenum++; - } - } - while (isspace(ch)); - - switch (ch) - { - case '(': case ')': - case '[': case ']': - case '-': - case '=': case ',': case ';': - { - token = TOKEN_TYPE (ch); - break; - } - - default: - { - if (isdigit (ch) || ch == '.') - { - scanin->putback (ch); - (*scanin) >> num_value; - token = TOK_NUM; - return; - } - - if (isalpha (ch)) - { - string_value = string (1, ch); - scanin->get(ch); - while (isalnum(ch)) - { - string_value += ch; - scanin->get(ch); - } - scanin->putback (ch); - } - /* - (*scanin).putback (ch); - (*scanin) >> string_value; - */ - int nr = 0; - while (defkw[nr].kw) - { - if (string_value == defkw[nr].name) - { - token = defkw[nr].kw; - return; - } - nr++; - } - - nr = 0; - while (defprim[nr].kw) - { - if (string_value == defprim[nr].name) - { - token = TOK_PRIMITIVE; - prim_token = defprim[nr].kw; - return; - } - nr++; - } - - token = TOK_STRING; - } - } - } - - void CSGScanner :: Error (const string & err) - { - stringstream errstr; - errstr << "Parsing error in line " << linenum << ": " << endl << err << endl; - throw string(errstr.str()); - } - - - /* - Solid = Term { OR Term } - Term = Primary { AND Primary } - Primary = PRIM | IDENT | ( Solid ) | NOT Primary - */ - - void ParseChar (CSGScanner & scan, char ch) - { - char str[2]; - str[0] = ch; - str[1] = 0; - if (scan.GetToken() != TOKEN_TYPE(ch)) - scan.Error (string ("token '") + string(str) + string("' expected")); - scan.ReadNext(); - } - - double ParseNumber(CSGScanner & scan) - { - if (scan.GetToken() == '-') - { - scan.ReadNext(); - return -ParseNumber (scan); - } - if (scan.GetToken() != TOK_NUM) scan.Error ("number expected"); - double val = scan.GetNumValue(); - scan.ReadNext(); - return val; - } - - - Solid * ParseSolid (CSGScanner & scan); - Solid * ParseTerm (CSGScanner & scan); - Solid * ParsePrimary (CSGScanner & scan); - - - Solid * ParsePrimary (CSGScanner & scan) - { - if (scan.GetToken() == TOK_PRIMITIVE) - { - // cout << "prim token = " << int (scan.GetPrimitiveToken()) << endl; - switch (scan.GetPrimitiveToken()) - { - case TOK_PLANE: - { - Point<3> p; - Vec<3> v; - - scan.ReadNext(); - - ParseChar (scan, '('); - p(0) = ParseNumber (scan); - ParseChar (scan, ','); - p(1) = ParseNumber (scan); - ParseChar (scan, ','); - p(2) = ParseNumber (scan); - ParseChar (scan, ';'); - v(0) = ParseNumber (scan); - ParseChar (scan, ','); - v(1) = ParseNumber (scan); - ParseChar (scan, ','); - v(2) = ParseNumber (scan); - ParseChar (scan, ')'); - - // cout << "define plane, p = " << p << "; v = " << v << endl; - OneSurfacePrimitive * surf = new Plane ( p, v ); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - } - case TOK_CYLINDER: - { - Point<3> pa, pb; - double r; - - scan.ReadNext(); - - ParseChar (scan, '('); - pa(0) = ParseNumber (scan); - ParseChar (scan, ','); - pa(1) = ParseNumber (scan); - ParseChar (scan, ','); - pa(2) = ParseNumber (scan); - ParseChar (scan, ';'); - pb(0) = ParseNumber (scan); - ParseChar (scan, ','); - pb(1) = ParseNumber (scan); - ParseChar (scan, ','); - pb(2) = ParseNumber (scan); - ParseChar (scan, ';'); - r = ParseNumber (scan); - ParseChar (scan, ')'); - - OneSurfacePrimitive * surf = new Cylinder ( pa, pb, r ); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - } - - case TOK_ELLIPTICCYLINDER: - { - Point<3> pa; - Vec<3> vl, vs; - - scan.ReadNext(); - - ParseChar (scan, '('); - pa(0) = ParseNumber (scan); - ParseChar (scan, ','); - pa(1) = ParseNumber (scan); - ParseChar (scan, ','); - pa(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - vl(0) = ParseNumber (scan); - ParseChar (scan, ','); - vl(1) = ParseNumber (scan); - ParseChar (scan, ','); - vl(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - vs(0) = ParseNumber (scan); - ParseChar (scan, ','); - vs(1) = ParseNumber (scan); - ParseChar (scan, ','); - vs(2) = ParseNumber (scan); - ParseChar (scan, ')'); - - OneSurfacePrimitive * surf = new EllipticCylinder ( pa, vl, vs); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - } - - - case TOK_ELLIPSOID: - { - Point<3> pa; - Vec<3> v1, v2, v3; - - scan.ReadNext(); - - ParseChar (scan, '('); - pa(0) = ParseNumber (scan); - ParseChar (scan, ','); - pa(1) = ParseNumber (scan); - ParseChar (scan, ','); - pa(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - v1(0) = ParseNumber (scan); - ParseChar (scan, ','); - v1(1) = ParseNumber (scan); - ParseChar (scan, ','); - v1(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - v2(0) = ParseNumber (scan); - ParseChar (scan, ','); - v2(1) = ParseNumber (scan); - ParseChar (scan, ','); - v2(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - v3(0) = ParseNumber (scan); - ParseChar (scan, ','); - v3(1) = ParseNumber (scan); - ParseChar (scan, ','); - v3(2) = ParseNumber (scan); - ParseChar (scan, ')'); - - OneSurfacePrimitive * surf = new Ellipsoid ( pa, v1, v2, v3); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - } - - - case TOK_CONE: - { - Point<3> pa, pb; - double ra, rb; - - scan.ReadNext(); - - ParseChar (scan, '('); - pa(0) = ParseNumber (scan); - ParseChar (scan, ','); - pa(1) = ParseNumber (scan); - ParseChar (scan, ','); - pa(2) = ParseNumber (scan); - ParseChar (scan, ';'); - ra = ParseNumber (scan); - ParseChar (scan, ';'); - pb(0) = ParseNumber (scan); - ParseChar (scan, ','); - pb(1) = ParseNumber (scan); - ParseChar (scan, ','); - pb(2) = ParseNumber (scan); - ParseChar (scan, ';'); - rb = ParseNumber (scan); - ParseChar (scan, ')'); - - OneSurfacePrimitive * surf = new Cone ( pa, pb, ra, rb); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - } - - - - - case TOK_SPHERE: - { - Point<3> p; - double r; - - scan.ReadNext(); - - ParseChar (scan, '('); - p(0) = ParseNumber (scan); - ParseChar (scan, ','); - p(1) = ParseNumber (scan); - ParseChar (scan, ','); - p(2) = ParseNumber (scan); - ParseChar (scan, ';'); - r = ParseNumber (scan); - ParseChar (scan, ')'); - - // cout << "define sphere, c = " << p << ", rad = " << r << endl; - OneSurfacePrimitive * surf = new Sphere ( p, r ); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - } - - case TOK_ORTHOBRICK: - { - Point<3> pa, pb; - - scan.ReadNext(); - - ParseChar (scan, '('); - pa(0) = ParseNumber (scan); - ParseChar (scan, ','); - pa(1) = ParseNumber (scan); - ParseChar (scan, ','); - pa(2) = ParseNumber (scan); - ParseChar (scan, ';'); - pb(0) = ParseNumber (scan); - ParseChar (scan, ','); - pb(1) = ParseNumber (scan); - ParseChar (scan, ','); - pb(2) = ParseNumber (scan); - ParseChar (scan, ')'); - - // cout << "define orthobrick, p1 = " << pa << "; p2 = " << pb << endl; - - Primitive * nprim = new OrthoBrick (pa, pb); - - for (int j = 0; j < nprim->GetNSurfaces(); j++) - { - geom->AddSurface (&nprim->GetSurface(j)); - nprim->SetSurfaceId (j, geom->GetNSurf()-1); - } - return new Solid (nprim); - } - - - case TOK_EXTRUSION: - { - Point<3> p0; - Vec<3> ex, ey; - ARRAY<Point<2> > points; - - scan.ReadNext(); - - ParseChar (scan, '('); - p0(0) = ParseNumber (scan); - ParseChar (scan, ','); - p0(1) = ParseNumber (scan); - ParseChar (scan, ','); - p0(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - ex(0) = ParseNumber (scan); - ParseChar (scan, ','); - ex(1) = ParseNumber (scan); - ParseChar (scan, ','); - ex(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - ey(0) = ParseNumber (scan); - ParseChar (scan, ','); - ey(1) = ParseNumber (scan); - ParseChar (scan, ','); - ey(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - cout << "p0 = " << p0 << endl; - - int npseg = 0; - int nseg = 0; - while (1) - { - Point<2> p1, p2, p3; - - p1(0) = ParseNumber(scan); - ParseChar (scan, ','); - p1(1) = ParseNumber(scan); - points.Append (p1); - if (scan.GetToken() == ')') - { - scan.ReadNext(); - break; - } - scan.ReadNext(); - } - - - /* - while (1) - { - Point<2> p1, p2, p3; - - p3 = p2; - p2 = p1; - p1(0) = ParseNumber(scan); - ParseChar (scan, ','); - p1(1) = ParseNumber(scan); - npseg++; - - cout << "p1 = " << p1 << endl; - - if (scan.GetToken() == ';' || scan.GetToken() == ')') - { - if (npseg == 2) - { - p3 = p2; - p2 = Center (p1, p3); - } - if (nseg == 0) - points.Append (p3); - points.Append (p2); - points.Append (p1); - npseg = 1; - nseg++; - - cout << "p1, = " << p1 << ", p2 = " << p2 << ", p3 = " << p3 << endl; - } - - if (scan.GetToken() == ')') - { - scan.ReadNext(); - break; - } - if (scan.GetToken() == ';' || scan.GetToken() == ',') - { - scan.ReadNext(); - } - } - */ - cout << "p0 = " << p0 << endl; - cout << ", ex = " << ex << ", ey = " << ey << endl; - cout << "points = " << points << endl; - - Extrusion * extrusion = new Extrusion (p0, ex, ey, points); - - for (int i = 0; i < extrusion->GetNSurfaces(); i++) - { - geom->AddSurface (&extrusion->GetSurface(i)); - extrusion->SetSurfaceId(i, geom->GetNSurf()-1); - } - return new Solid (extrusion); - - /* - // cout << "define cylinder, pa = " << pa << "; pb = " << pb - // << ", rad = " << r << endl; - OneSurfacePrimitive * surf = new Cylinder ( pa, pb, r ); - - geom->AddSurface (surf); - surf->SetSurfaceId (0, geom->GetNSurf()-1); - - return new Solid (surf); - */ - } - - -// Added by Dalibor Lukas, October 15, 2003 - case TOK_POLYHEDRON: - { - Point<3> p; - int pi1, pi2, pi3, pi4; - - scan.ReadNext(); - ParseChar (scan, '('); - - Polyhedra * polyhedron = new Polyhedra; - - // scanning the points - while (1) - { - p(0) = ParseNumber (scan); - ParseChar (scan, ','); - p(1) = ParseNumber (scan); - ParseChar (scan, ','); - p(2) = ParseNumber (scan); - ParseChar (scan, ';'); - - cout << "point = " << p << endl; - - polyhedron->AddPoint(p); - - if (scan.GetToken() == ';') - { - scan.ReadNext(); - break; - } - } - - // scanning the faces - while (1) - { - pi1 = (int) (ParseNumber (scan)); - ParseChar (scan, ','); - pi2 = (int) (ParseNumber (scan)); - ParseChar (scan, ','); - pi3 = (int) (ParseNumber (scan)); - ParseChar (scan, ','); - pi4 = (int) (ParseNumber (scan)); - - cout << "face = (" << pi1 << ", " << pi2 << ", " << pi3 - << ", " << pi4 << ")" << endl; - - polyhedron->AddFace(pi1-1,pi2-1,pi3-1); - polyhedron->AddFace(pi1-1,pi3-1,pi4-1); - - if (scan.GetToken() == ')') - { - scan.ReadNext(); - break; - } - scan.ReadNext(); - } - - int j; - for (j = 0; j < polyhedron->GetNSurfaces(); j++) - { - geom->AddSurface (&polyhedron->GetSurface(j)); - polyhedron->SetSurfaceId (j, geom->GetNSurf()-1); - } - - return new Solid (polyhedron); - } -// DL - - - } - cout << "unknown primary " << scan.GetStringValue() << endl; - } - - else if (scan.GetToken() == TOK_STRING && - geom->GetSolid(scan.GetStringValue())) - - { - Solid * sol = const_cast<Solid*> (geom->GetSolid(scan.GetStringValue())); - scan.ReadNext(); - return sol; - } - - else if (scan.GetToken() == TOK_NOT) - - { - scan.ReadNext(); - Solid * sol1 = ParsePrimary (scan); - return new Solid (Solid::SUB, sol1); - } - - else if (scan.GetToken() == '(') - - { - scan.ReadNext(); - Solid * sol1 = ParseSolid (scan); - scan.ReadNext(); - return sol1; - } - - scan.Error (string ("not a primary, name = ")+ - scan.GetStringValue()); - return 0; - } - - - Solid * ParseTerm (CSGScanner & scan) - { - Solid * sol = ParsePrimary(scan); - while (scan.GetToken() == TOK_AND) - { - scan.ReadNext(); - Solid * sol2 = ParsePrimary(scan); - sol = new Solid (Solid::SECTION, sol, sol2); - } - return sol; - } - - Solid * ParseSolid (CSGScanner & scan) - { - Solid * sol = ParseTerm(scan); - while (scan.GetToken() == TOK_OR) - { - scan.ReadNext(); - Solid * sol2 = ParseTerm(scan); - sol = new Solid (Solid::UNION, sol, sol2); - } - return sol; - } - - - - void ParseFlags (CSGScanner & scan, Flags & flags) - { - while (scan.GetToken() == '-') - { - scan.ReadNext(); - string name = scan.GetStringValue(); - scan.ReadNext(); - if (scan.GetToken() == '=') - { - scan.ReadNext(); - if (scan.GetToken() == TOK_STRING) - { - flags.SetFlag (name.c_str(), scan.GetStringValue().c_str()); - scan.ReadNext(); - } - else if (scan.GetToken() == '[') - { - scan.ReadNext(); - ARRAY<double> vals; - vals.Append (ParseNumber(scan)); - while (scan.GetToken() == ',') - { - scan.ReadNext(); - vals.Append (ParseNumber(scan)); - } - ParseChar (scan, ']'); - flags.SetFlag (name.c_str(), vals); - } - else if (scan.GetToken() == TOK_NUM) - { - flags.SetFlag (name.c_str(), scan.GetNumValue()); - scan.ReadNext(); - } - } - else - { - flags.SetFlag (name.c_str()); - } - } - } - - - /* - Main parsing function for CSG geometry - */ - CSGeometry * ParseCSG (istream & istr) - { - CSGScanner scan(istr); - - geom = new CSGeometry; - - scan.ReadNext(); - if (scan.GetToken() != TOK_RECO) // keyword 'algebraic3d' - return 0; - scan.ReadNext(); - - try - { - while (1) - { - if (scan.GetToken() == TOK_END) break; - - if (scan.GetToken() == TOK_SOLID) - { - scan.ReadNext(); - if (scan.GetToken() != TOK_STRING) - scan.Error ("name identifier expected"); - string solidname = scan.GetStringValue(); - - scan.ReadNext(); - - ParseChar (scan, '='); - Solid * solid = ParseSolid (scan); - - Flags flags; - ParseFlags (scan, flags); - - geom->SetSolid (solidname.c_str(), new Solid (Solid::ROOT, solid)); - geom->SetFlags (solidname.c_str(), flags); - - ParseChar (scan, ';'); - - PrintMessage (4, "define solid ", solidname); - } - - else if (scan.GetToken() == TOK_TLO) - - { // a TopLevelObject definition - - scan.ReadNext(); - - string name = scan.GetStringValue(); - scan.ReadNext(); - - if (scan.GetToken() != TOK_STRING) - - { // a solid TLO - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - int tlonr = - geom->SetTopLevelObject ((Solid*)geom->GetSolid(name)); - TopLevelObject * tlo = geom->GetTopLevelObject (tlonr); - if (flags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = - flags.GetNumListFlag ("col"); - tlo->SetRGB (col[0], col[1], col[2]); - } - - if (flags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - - tlo->SetMaterial (flags.GetStringFlag ("material", "")); - tlo->SetLayer (int(flags.GetNumFlag ("layer", 1))); - if (flags.NumFlagDefined ("maxh")) - tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10)); - } - - else - - { // a surface TLO - - string surfname = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - ARRAY<int> si; - geom->GetSolid(surfname)->GetSurfaceIndices(si); - int tlonr = - geom->SetTopLevelObject ((Solid*)geom->GetSolid(name), - (Surface*)geom->GetSurface(si.Get(1))); - TopLevelObject * tlo = geom->GetTopLevelObject (tlonr); - if (flags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = flags.GetNumListFlag ("col"); - tlo->SetRGB (col.Get(1), col.Get(2), col.Get(3)); - } - if (flags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - - if (flags.NumFlagDefined ("maxh")) - tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10)); - tlo->SetLayer (int(flags.GetNumFlag ("layer", 1))); - tlo->SetBCProp (int(flags.GetNumFlag ("bc", -1))); - } - } - - else if (scan.GetToken() == TOK_IDENTIFY) - - { - - scan.ReadNext(); - switch (scan.GetToken()) - { - case TOK_CLOSESURFACES: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - Flags flags; - ParseFlags (scan, flags); - - ParseChar (scan, ';'); - - - ARRAY<int> si1, si2; - geom->GetSolid(name1)->GetSurfaceIndices(si1); - geom->GetSolid(name2)->GetSurfaceIndices(si2); - - geom->AddIdentification - (new CloseSurfaceIdentification - (geom->GetNIdentifications()+1, *geom, - geom->GetSurface (si1[0]), geom->GetSurface (si2[0]), - flags)); - break; - } - - case TOK_PERIODIC: - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - ParseChar (scan, ';'); - - - ARRAY<int> si1, si2; - geom->GetSolid(name1)->GetSurfaceIndices(si1); - geom->GetSolid(name2)->GetSurfaceIndices(si2); - - geom->AddIdentification - (new PeriodicIdentification - (geom->GetNIdentifications()+1, - *geom, - geom->GetSurface (si1.Get(1)), - geom->GetSurface (si2.Get(1)))); - break; - } - } - - } - - else if (scan.GetToken() == TOK_POINT) - { - Point<3> p; - - scan.ReadNext(); - ParseChar (scan, '('); - p(0) = ParseNumber (scan); - ParseChar (scan, ','); - p(1) = ParseNumber (scan); - ParseChar (scan, ','); - p(2) = ParseNumber (scan); - ParseChar (scan, ')'); - ParseChar (scan, ';'); - - geom->AddUserPoint (p); - } - - else if (scan.GetToken() == TOK_BOUNDINGBOX) - { - Point<3> p1, p2; - - scan.ReadNext(); - ParseChar (scan, '('); - p1(0) = ParseNumber (scan); - ParseChar (scan, ','); - p1(1) = ParseNumber (scan); - ParseChar (scan, ','); - p1(2) = ParseNumber (scan); - ParseChar (scan, ';'); - p2(0) = ParseNumber (scan); - ParseChar (scan, ','); - p2(1) = ParseNumber (scan); - ParseChar (scan, ','); - p2(2) = ParseNumber (scan); - ParseChar (scan, ')'); - ParseChar (scan, ';'); - - geom->SetBoundingBox (Box<3> (p1, p2)); - } - - else if (scan.GetToken() == TOK_BOUNDARYCONDITION) - { - scan.ReadNext(); - - string name1 = scan.GetStringValue(); - scan.ReadNext(); - - string name2 = scan.GetStringValue(); - scan.ReadNext(); - - int num = int (ParseNumber (scan)); - ParseChar (scan, ';'); - - - CSGeometry::BCModification bcm; - ARRAY<int> si; - - geom->GetSolid(name1)->GetSurfaceIndices(si); - - bcm.tlonr = -1; - int i; - for (i = 0; i < geom->GetNTopLevelObjects(); i++) - if (string (geom->GetTopLevelObject(i)->GetSolid()->Name()) - == name2) - { - bcm.tlonr = i; - break; - } - - bcm.bcnr = num; - for (i = 0; i < si.Size(); i++) - { - bcm.si = si[i]; - geom->bcmodifications.Append (bcm); - } - } - - else - { - cout << "read unidentified token " << scan.GetToken() - << " string = " << scan.GetStringValue() << endl; - scan.ReadNext(); - } - } - } - catch (string errstr) - { - cout << "caught error " << errstr << endl; - } - - - return geom; - /* - do - { - scan.ReadNext(); - if (scan.GetToken() == TOK_STRING) - cout << "found string " << scan.GetStringValue() << endl; - else - cout << "token = " << int(scan.GetToken()) << endl; - } - while (scan.GetToken() != TOK_END); - */ - } - - -}; - diff --git a/Netgen/libsrc/csg/csgscanner.cpp b/Netgen/libsrc/csg/csgscanner.cpp deleted file mode 100644 index 50e2213ea6..0000000000 --- a/Netgen/libsrc/csg/csgscanner.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - using namespace netgen; - - - enum TOKEN_TYPE - { - LP = '(', RP = ')', EQU = '=', COMMA = ',', SEMICOLON = ';', - TOK_NUM, TOK_STRING, TOK_NAMED_SOLID, TOK_PRIMITIVE, - TOK_OR, TOK_AND, TOK_NOT, - TOK_SOLID, TOK_RECO, TOK_TLO, TOK_BOUNDINGBOX, - TOK_END }; - - struct kwstruct - { - TOKEN_TYPE kw; - string name; - }; - - static kwstruct defkw[] = - { - { TOK_OR, "or" }, - { TOK_AND, "and" }, - { TOKEN_TYPE(0) } - }; - - enum PRIMITIVE_TYPE { TOK_SPHERE, TOK_CYLINDER, TOK_PLANE }; - - /* -%token <solidtype> TOK_SPHERE TOK_CYLINDER TOK_CONE TOK_PLAIN TOK_TUBE TOK_GENCYL TOK_ORTHOBRICK TOK_POLYHEDRON TOK_REVOLUTION -%left <solidtype> TOK_OR TOK_AND TOK_NOT -%token <solidtype> TOK_TRANSLATE TOK_MULTITRANSLATE TOK_ROTATE TOK_MULTIROTATE -%type <solidtype> solid solidprimitive -%type <void> splinesegmentlist splinesegment readbspline bsplinepointlist -%type <chptr> anyident -%token TOK_SINGULAR TOK_EDGE TOK_POINT -%token TOK_IDENTIFY TOK_CLOSESURFACES TOK_CLOSEEDGES TOK_PERIODIC -%token TOK_BOUNDARYCONDITION -%type <void> polyhedronpoints polyhedronfaces polyhedronpoint polyhedronface -%type <void> revolutionpoints revolutionpoint - */ - - - - class CSGScanner - { - TOKEN_TYPE token; - double num_value; - string string_value; - - int linenum; - istream * scanin; - - public: - - CSGScanner (istream & ascanin); - - TOKEN_TYPE GetToken() const - { return token; } - - double GetNumValue() const - { return num_value; } - - const string & GetStringValue() const - { return string_value; } - - void ReadNext(); - - void Error (const string & err); - }; - - - CSGScanner :: CSGScanner (istream & ascanin) - { - int i; - - scanin = &ascanin; - token = TOK_END; - num_value = 0; - linenum = 1; - } - - - void CSGScanner :: ReadNext () - { - char ch; - - - // whitespaces ueberspringen - do - { - scanin->get(ch); - - if (ch == '\n') - linenum++; - - // end of file reached - if (scanin->eof()) - { - token = TOK_END; - return; - } - - // skip comment line - if (ch == '#') - { - while (ch != '\n') - { - scanin->get(ch); - if (scanin->eof()) - { - token = TOK_END; - return; - } - } - linenum++; - } - } - while (isspace(ch)); - - switch (ch) - { - case '(': case ')': - case '=': case ',': case ';': - { - token = TOKEN_TYPE (ch); - break; - } - - default: - { - if (isdigit (ch) || ch == '.' || ch == '-') - { - scanin->putback (ch); - (*scanin) >> num_value; - token = TOK_NUM; - return; - } - - (*scanin).putback (ch); - (*scanin) >> string_value; - - int nr = 0; - while (defkw[nr].kw) - { - if (string_value == defkw[nr].name) - { - token = defkw[nr].kw; - return; - } - } - - token = TOK_STRING; - } - } - } - - void CSGScanner :: Error (const string & err) - { - stringstream errstr; - errstr << "Parsing error in line " << linenum << ": " << endl << err << endl; - /* - errstr << "input continues with <<<"; - for (int i = 0; i < 50; i++) - { - char ch; - scanin->get(ch); - errstr << ch; - if (scanin->eof()) - { - errstr << "(end of file)"; - break; - } - } - errstr << endl << ">>> stop parsing" << endl; - throw Exception (errstr.str()); - */ - } - - - - - - void ParseCSG (istream & istr) - { - CSGScanner scan(istr); - - do - { - scan.ReadNext(); - cout << "token = " << int(scan.GetToken()) << endl; - } - while (scan.GetToken() != TOK_END); - } - - -}; - diff --git a/Netgen/libsrc/csg/curve2d.cpp b/Netgen/libsrc/csg/curve2d.cpp deleted file mode 100644 index 7091e87af9..0000000000 --- a/Netgen/libsrc/csg/curve2d.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <csg.hpp> - -namespace netgen -{ -CircleCurve2d :: CircleCurve2d (const Point<2> & acenter, double arad) - { - center = acenter; - rad = arad; - } - -void CircleCurve2d :: Project (Point<2> & p) const - { - Vec<2> v = p - center; - v *= rad/v.Length(); - p = center + v; - } - -void CircleCurve2d :: NormalVector (const Point<2> & p, Vec<2> & n) const - { - n = p - center; - n /= n.Length(); - } - - - - - - -QuadraticCurve2d :: QuadraticCurve2d () -{ - cxx = cyy = cxy = cx = cy = c = 0; -} - -void QuadraticCurve2d :: Read (istream & ist) -{ - ist >> cxx >> cyy >> cxy >> cx >> cy >> c; -} - - -void QuadraticCurve2d :: Project (Point<2> & p) const -{ - double f, x, y, gradx, grady, grad2; - int its = 0; - - x = p(0); - y = p(1); - - do - { - f = cxx * x * x + cyy * y * y + cxy * x * y + cx * x + cy * y + c; - gradx = 2 * cxx * x + cxy * y + cx; - grady = 2 * cyy * y + cxy * x + cy; - grad2 = gradx * gradx + grady * grady; - - x -= f * gradx / grad2; - y -= f * grady / grad2; - - // (*mycout) << "x = " << x << " y = " << y << " f = " << f << endl; - its++; - } - while (fabs (f) > 1e-8 && its < 20); - if (its >= 20) - cerr << "QuadraticCurve2d::Project: many iterations, f = " << f << endl; - p(0) = x; - p(1) = y; -} - - -void QuadraticCurve2d :: NormalVector (const Point<2> & p, Vec<2> & n) const -{ - n(0) = 2 * cxx * p(0) + cxy * p(1) + cx; - n(1) = 2 * cyy * p(1) + cxy * p(0) + cy; - n.Normalize(); -} -} diff --git a/Netgen/libsrc/csg/curve2d.hpp b/Netgen/libsrc/csg/curve2d.hpp deleted file mode 100644 index 917bd53205..0000000000 --- a/Netgen/libsrc/csg/curve2d.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef FILE_CURVE2D -#define FILE_CURVE2D - -/**************************************************************************/ -/* File: curve2d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 24. Jul. 96 */ -/**************************************************************************/ - -/* - - 2D Curve repesentation - -*/ - - - -/// -class Curve2d : public Manifold - { - public: - /// - virtual void Project (Point<2> & p) const = 0; - /// - virtual void NormalVector (const Point<2> & p, Vec<2> & n) const = 0; - }; - -/// -class CircleCurve2d : public Curve2d - { - /// - Point<2> center; - /// - double rad; - public: - /// - CircleCurve2d (const Point<2> & acenter, double arad); - /// - virtual void Project (Point<2> & p) const; - /// - virtual void NormalVector (const Point<2> & p, Vec<2> & n) const; - }; - -/// -class QuadraticCurve2d : public Curve2d -{ - /// - double cxx, cyy, cxy, cx, cy, c; -public: - /// - QuadraticCurve2d (); - /// - void Read (istream & ist); - /// - virtual void Project (Point<2> & p) const; - /// - virtual void NormalVector (const Point<2> & p, Vec<2> & n) const; -}; -#endif diff --git a/Netgen/libsrc/csg/edgeflw.cpp b/Netgen/libsrc/csg/edgeflw.cpp deleted file mode 100644 index 50b425f84f..0000000000 --- a/Netgen/libsrc/csg/edgeflw.cpp +++ /dev/null @@ -1,1524 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - -#undef DEVELOP - -namespace netgen -{ - - EdgeCalculation :: - EdgeCalculation (const CSGeometry & ageometry, - ARRAY<SpecialPoint> & aspecpoints) - : geometry(ageometry), specpoints(aspecpoints) - { - Box<3> bbox; - if (specpoints.Size() >= 1) - bbox.Set (specpoints[0].p); - else - { bbox.Set (Point<3> (0,0,0)); bbox.Add (Point<3> (1,1,1)); } - for (int i = 1; i < specpoints.Size(); i++) - bbox.Add (specpoints[i].p); - - searchtree = new Point3dTree (bbox.PMin(), bbox.PMax()); - meshpoint_tree = new Point3dTree (bbox.PMin(), bbox.PMax()); - - for (int i = 0; i < specpoints.Size(); i++) - searchtree->Insert (specpoints[i].p, i); - } - - EdgeCalculation :: ~EdgeCalculation() - { - delete searchtree; - delete meshpoint_tree; - } - - - void EdgeCalculation :: Calc(double h, Mesh & mesh) - { - PrintMessage (1, "Find edges"); - PushStatus ("Find edges"); - - CalcEdges1 (h, mesh); - SplitEqualOneSegEdges (mesh); - FindClosedSurfaces (h, mesh); - PrintMessage (3, cntedge, " edges found"); - - PopStatus (); - } - - - - - - void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh) - { - ARRAY<int> hsp(specpoints.Size()); - ARRAY<int> glob2hsp(specpoints.Size()); - ARRAY<int> startpoints, endpoints; - - int pos, ep; - int layer; - - Point<3> p, np; - int pi1, s1, s2; - - ARRAY<Point<3> > edgepoints; - ARRAY<double> curvelength; - int copyedge, copyfromedge = -1, copyedgeidentification = -1; - - ARRAY<int> locsurfind, locind; - - // double len, corr, lam; - // double steplen, cursteplen, loch, - double hd; - - int checkedcopy = 0; - - // double size = geometry.MaxSize(); - // double epspointdist2 = sqr (size) * 1e-12; - - - // copy special points to work with - for (int i = 0; i < specpoints.Size(); i++) - { - hsp[i] = i; - glob2hsp[i] = i; - } - - - cntedge = 0; - INDEX_2_HASHTABLE<int> identification_used(100); // identification i already used for startpoint j - - - while (hsp.Size()) - { - SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size()); - - edgepoints.SetSize (0); - curvelength.SetSize (0); - - - pi1 = 0; - copyedge = 0; - // identifyable point available ? - - // (*testout) << endl; - - for (int i = 0; i < geometry.identifications.Size() && !pi1; i++) - for (int j = checkedcopy; j < startpoints.Size() && !pi1; j++) - - if (geometry.identifications[i]->IdentifyableCandidate (specpoints[startpoints[j]])) - - { - int pi1cand = 0; - double mindist = 1e10; - - for (int k = 0; k < hsp.Size() && !pi1; k++) - { - if (identification_used.Used (INDEX_2(i, startpoints[j])) || - identification_used.Used (INDEX_2(i, hsp[k]))) continue; - - if (geometry.identifications[i] - ->Identifyable(specpoints[startpoints[j]], specpoints[hsp[k]]) || - geometry.identifications[i] - ->Identifyable(specpoints[hsp[k]], specpoints[startpoints[j]])) - { - if (Dist (specpoints[startpoints[j]].p, specpoints[hsp[k]].p) < mindist) - { - mindist = Dist (specpoints[startpoints[j]].p, specpoints[hsp[k]].p); - pi1cand = k+1; - } - } - } - - - if (pi1cand) - { - pi1 = pi1cand; - copyedge = 1; - copyfromedge = j+1; - copyedgeidentification = i+1; - - identification_used.Set (INDEX_2(i, startpoints[j]), 1); - identification_used.Set (INDEX_2(i, hsp.Get(pi1)), 1); - } - } - - - // cannot copy from other ege ? - if (!pi1) - checkedcopy = startpoints.Size(); - - // unconditional special point available ? - if (!pi1) - for (int i = 1; i <= hsp.Size(); i++) - if (specpoints[hsp.Get(i)].unconditional == 1) - { - pi1 = i; - break; - } - - - if (!pi1) - { - // only unconditional points available, choose first - pi1 = 1; - } - - layer = specpoints[hsp.Get(pi1)].GetLayer(); - - - if (!specpoints[hsp.Get(pi1)].unconditional) - { - specpoints[hsp.Elem(pi1)].unconditional = 1; - for (int i = 1; i <= hsp.Size(); i++) - if (i != pi1 && - Dist (specpoints[hsp.Get(pi1)].p, specpoints[hsp.Get(i)].p) < 1e-8 && - (specpoints[hsp.Get(pi1)].v + specpoints[hsp.Get(i)].v).Length() < 1e-4) - { - // opposite direction - specpoints[hsp.Elem(i)].unconditional = 1; - } - } - - cntedge++; - startpoints.Append (hsp.Get(pi1)); - -#ifdef DEVELOP - (*testout) << "edge nr " << cntedge << endl; - (*testout) << "start followedge: p1 = " << specpoints[hsp.Get(pi1)].p - << ", v = " << specpoints[hsp.Get(pi1)].v << endl; -#endif - - FollowEdge (pi1, ep, pos, hsp, h, mesh, - edgepoints, curvelength); - - - if (multithread.terminate) - return; - - if (!ep) - { - // ignore starting point - hsp.DeleteElement (pi1); - cout << "yes, this happens" << endl; - continue; - } - - - - endpoints.Append (hsp.Get(ep)); - - - double elen = 0; - for (int i = 1; i <= edgepoints.Size()-1; i++) - elen += Dist (edgepoints.Get(i), edgepoints.Get(i+1)); - - - int shortedge = 0; - for (int i = 1; i <= geometry.identifications.Size(); i++) - if (geometry.identifications.Get(i)->ShortEdge(specpoints[hsp.Get(pi1)], specpoints[hsp.Get(ep)])) - shortedge = 1; - // (*testout) << "shortedge = " << shortedge << endl; - - - if (!shortedge) - { - mesh.RestrictLocalHLine (Point3d (specpoints[hsp.Get(pi1)].p), - Point3d (specpoints[hsp.Get(ep)].p), - elen / mparam.segmentsperedge); - } - - s1 = specpoints[hsp.Get(pi1)].s1; - s2 = specpoints[hsp.Get(pi1)].s2; - - - // delete initial, terminal and conditional points - -#ifdef DEVELOP - (*testout) << "terminal point: p = " << specpoints[hsp.Get(ep)].p - << ", v = " << specpoints[hsp.Get(ep)].v << endl; -#endif - - searchtree -> DeleteElement (hsp.Get(ep)); - searchtree -> DeleteElement (hsp.Get(pi1)); - - if (ep > pi1) - { - glob2hsp[hsp[ep-1]] = -1; - glob2hsp[hsp.Last()] = ep-1; - hsp.DeleteElement (ep); - - glob2hsp[hsp[pi1-1]] = -1; - glob2hsp[hsp.Last()] = pi1-1; - hsp.DeleteElement (pi1); - } - else - { - glob2hsp[hsp[pi1-1]] = -1; - glob2hsp[hsp.Last()] = pi1-1; - hsp.DeleteElement (pi1); - - glob2hsp[hsp[ep-1]] = -1; - glob2hsp[hsp.Last()] = ep-1; - hsp.DeleteElement (ep); - } - - - for (int j = 1; j <= edgepoints.Size()-1; j++) - { - p = edgepoints.Get(j); - np = Center (p, edgepoints.Get(j+1)); - hd = Dist (p, np); - - - Box<3> boxp (np - (1.2 * hd) * Vec<3> (1, 1, 1), - np + (1.2 * hd) * Vec<3> (1, 1, 1)); - searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind); - - for (int i = 0; i < locind.Size(); i++) - { - if ( specpoints[locind[i]].HasSurfaces (s1, s2) && - specpoints[locind[i]].unconditional == 0) - { - searchtree -> DeleteElement (locind[i]); - - int li = glob2hsp[locind[i]]; - glob2hsp[locind[i]] = -1; - glob2hsp[hsp.Last()] = li; - hsp.Delete (li); - } - } - - - /* - for (int i = 1; i <= hsp.Size(); i++) - if ( specpoints[hsp.Get(i)].HasSurfaces (s1, s2) && - specpoints[hsp.Get(i)].unconditional == 0 && - Dist2 (np, specpoints[hsp.Get(i)].p) < 1.2 * hd) - { - searchtree -> DeleteElement (hsp.Get(i)+1); - hsp.DeleteElement (i); - i--; - } - */ - } - - - ARRAY<Segment> refedges; - ARRAY<bool> refedgesinv; - - - AnalyzeEdge (s1, s2, pos, layer, - edgepoints, - refedges, refedgesinv); - - for (int i = 0; i < refedges.Size(); i++) - refedges[i].edgenr = cntedge; - - - - -#ifdef DEVELOP - (*testout) << "edge " << cntedge << endl - << "startp: " << specpoints[startpoints.Last()].p - << ", v = " << specpoints[startpoints.Last()].v << endl - // << "copy = " << copyedge << endl - << refedges.Size() << " refedges: "; - for (int i = 1; i <= refedges.Size(); i++) - (*testout) << " " << refedges.Get(i).si; - (*testout) << endl; - (*testout) << "inv[1] = " << refedgesinv.Get(1) << endl; -#endif - - if (!copyedge) - { - // int oldnseg = mesh.GetNSeg(); - - if (!shortedge) - StoreEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - else - StoreShortEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - - - /* - for (int i = oldnseg+1; i <= mesh.GetNSeg(); i++) - for (int j = 1; j <= oldnseg; j++) - { - const Point<3> & l1p1 = mesh.Point (mesh.LineSegment(i).p1); - const Point<3> & l1p2 = mesh.Point (mesh.LineSegment(i).p2); - const Point<3> & l2p1 = mesh.Point (mesh.LineSegment(j).p1); - const Point<3> & l2p2 = mesh.Point (mesh.LineSegment(j).p2); - Vec<3> vl1(l1p1, l1p2); - for (double lamk = 0; lamk <= 1; lamk += 0.1) - { - Point<3> l2p = l1p1 + lamk * vl1; - double dist = sqrt (MinDistLP2 (l2p1, l2p2, l2p)); - if (dist > 1e-12) - mesh.RestrictLocalH (l2p, 3*dist); - } - } - */ - } - else - { - CopyEdge (refedges, refedgesinv, - copyfromedge, - specpoints[startpoints.Get(copyfromedge)].p, - specpoints[endpoints.Get(copyfromedge)].p, - edgepoints.Get(1), edgepoints.Last(), - copyedgeidentification, - layer, - mesh); - } - - } - } - - - - - - /* - If two or more edges share the same initial and end-points, - then they need at least two segments - */ - void EdgeCalculation :: - SplitEqualOneSegEdges (Mesh & mesh) - { - // int i, j; - SegmentIndex si; - PointIndex pi; - - ARRAY<int> osedges(cntedge); - INDEX_2_HASHTABLE<int> osedgesht (cntedge+1); - - osedges = 2; - - // count segments on edges - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - osedges.Elem(seg.edgenr)--; - } - - // (*testout) << "osedges = " << osedges << endl; - - // flag one segment edges - for (int i = 0; i < cntedge; i++) - osedges[i] = (osedges[i] > 0) ? 1 : 0; - - // (*testout) << "osedges, now = " << osedges << endl; - - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr)) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2)) - osedgesht.Set (i2, 2); - else - osedgesht.Set (i2, 1); - } - } - } - - - // one edge 1 segment, other 2 segments - // yes, it happens ! - point_on_edge_problem = 0; - for (int i = 1; i <= osedgesht.GetNBags(); i++) - for (int j = 1; j <= osedgesht.GetBagSize(i); j++) - { - INDEX_2 i2; - int val; - osedgesht.GetData (i, j, i2, val); - - const Point<3> & p1 = mesh[PointIndex(i2.I1())]; - const Point<3> & p2 = mesh[PointIndex(i2.I2())]; - Vec<3> v = p2 - p1; - double vlen = v.Length(); - v /= vlen; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (pi != i2.I1() && pi != i2.I2()) - { - const Point<3> & p = mesh[pi]; - Vec<3> v2 = p - p1; - double lam = (v2 * v); - if (lam > 0 && lam < vlen) - { - Point<3> hp = p1 + lam * v; - if (Dist (p, hp) < 1e-4 * vlen) - { - PrintWarning ("Point on edge !!!"); - cout << "seg: " << i2 << ", p = " << pi << endl; - osedgesht.Set (i2, 2); - point_on_edge_problem = 1; - } - } - } - } - - - // insert new points - osedges = -1; - - int nseg = mesh.GetNSeg(); - for (si = 0; si < nseg; si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2) && - osedgesht.Get (i2) == 2 && - osedges.Elem(seg.edgenr) == -1) - { - Point<3> newp = Center (mesh[PointIndex(seg.p1)], - mesh[PointIndex(seg.p2)]); - - ProjectToEdge (geometry.GetSurface(seg.surfnr1), - geometry.GetSurface(seg.surfnr2), - newp); - - osedges.Elem(seg.edgenr) = - mesh.AddPoint (newp, mesh[PointIndex(seg.p1)].GetLayer()); - meshpoint_tree -> Insert (newp, osedges.Elem(seg.edgenr)); - } - } - } - - - for (int i = 1; i <= nseg; i++) - { - Segment & seg = mesh.LineSegment (i); - if (seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr) != -1) - { - Segment newseg = seg; - newseg.p1 = osedges.Get(seg.edgenr); - seg.p2 = osedges.Get(seg.edgenr); - mesh.AddSegment (newseg); - } - } - } - - } - - - - void EdgeCalculation :: - FollowEdge (int pi1, int & ep, int & pos, - const ARRAY<int> & hsp, - double h, const Mesh & mesh, - ARRAY<Point<3> > & edgepoints, - ARRAY<double> & curvelength) - { - int s1, s2; - double len, steplen, cursteplen, loch; - Point<3> p, np, pnp; - Vec<3> a1, a2, t; - - ARRAY<int> locind; - - double size = geometry.MaxSize(); - double epspointdist2 = size * 1e-6; - epspointdist2 = sqr (epspointdist2); - int uselocalh = mparam.uselocalh; - - - s1 = specpoints[hsp.Get(pi1)].s1; - s2 = specpoints[hsp.Get(pi1)].s2; - - p = specpoints[hsp.Get(pi1)].p; - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - - t = Cross (a1, a2); - t.Normalize(); - - pos = (specpoints[hsp.Get(pi1)].v * t) > 0; - if (!pos) t *= -1; - - - edgepoints.Append (p); - curvelength.Append (0); - len = 0; - - loch = min2 (geometry.GetSurface(s1) -> LocH (p, 3, 1, h), - geometry.GetSurface(s2) -> LocH (p, 3, 1, h)); - - - - if (uselocalh) - { - double lh = mesh.GetH(p); - if (lh < loch) - loch = lh; - } - - steplen = 0.1 * loch; - - do - { - if (multithread.terminate) - return; - - if (fabs (p(0)) + fabs (p(1)) + fabs (p(2)) > 100000) - { - ep = 0; - PrintWarning ("Give up line"); - break; - } - - if (steplen > 0.1 * loch) steplen = 0.1 * loch; - - steplen *= 2; - do - { - steplen *= 0.5; - np = p + steplen * t; - pnp = np; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), pnp); - } - while (Dist (np, pnp) > 0.1 * steplen); - - cursteplen = steplen; - if (Dist (np, pnp) < 0.01 * steplen) steplen *= 2; - - - np = pnp; - ep = 0; - - double hvtmin = 1.5 * cursteplen; - - Box<3> boxp (p - (2 * cursteplen) * Vec<3> (1, 1, 1), - p + (2 * cursteplen) * Vec<3> (1, 1, 1)); - - searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind); - - for (int i = 0; i < locind.Size(); i++) - { - Vec<3> hv = specpoints[locind[i]].p - p; - if (hv.Length2() > 9 * cursteplen * cursteplen) - continue; - - double hvt = hv * t; - hv -= hvt * t; - - if (hv.Length() < 0.2 * cursteplen && - hvt > 0 && - // hvt < 1.5 * cursteplen && - hvt < hvtmin && - specpoints[locind[i]].unconditional == 1 && - (specpoints[locind[i]].v + t).Length() < 0.4 ) - { - Point<3> hep = specpoints[locind[i]].p; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), hep); - - - if (Dist2 (hep, specpoints[locind[i]].p) < epspointdist2 ) - { - geometry.GetSurface(s1) -> CalcGradient (hep, a1); - geometry.GetSurface(s2) -> CalcGradient (hep, a2); - Vec<3> ept = Cross (a1, a2); - ept /= ept.Length(); - if (!pos) ept *= -1; - - if ( (specpoints[locind[i]].v + ept).Length() < 1e-4 ) - { - np = specpoints[locind[i]].p; - - for (int jj = 0; jj < hsp.Size(); jj++) - if (hsp[jj] == locind[i]) - ep = jj+1; - - if (!ep) - cerr << "endpoint not found" << endl; - // ep = i; - hvtmin = hvt; - // break; - } - } - } - } - - - - - /* - for (int i = 1; i <= hsp.Size(); i++) - { - if (!boxp.IsIn (specpoints[hsp.Get(i)].p)) - continue; - - Vec<3> hv = specpoints[hsp.Get(i)].p - p; - if (hv.Length2() > 9 * cursteplen * cursteplen) - continue; - - double hvt = hv * t; - hv -= hvt * t; - - if (hv.Length() < 0.2 * cursteplen && - hvt > 0 && - // hvt < 1.5 * cursteplen && - hvt < hvtmin && - specpoints[hsp.Get(i)].unconditional == 1 && - (specpoints[hsp.Get(i)].v + t).Length() < 0.4 ) - { - Point<3> hep = specpoints[hsp.Get(i)].p; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), hep); - - - if (Dist2 (hep, specpoints[hsp.Get(i)].p) < epspointdist2 ) - { - geometry.GetSurface(s1) -> CalcGradient (hep, a1); - geometry.GetSurface(s2) -> CalcGradient (hep, a2); - Vec<3> ept = Cross (a1, a2); - ept /= ept.Length(); - if (!pos) ept *= -1; - - if ( (specpoints[hsp.Get(i)].v + ept).Length() < 1e-4 ) - { - np = specpoints[hsp.Get(i)].p; - ep = i; - hvtmin = hvt; - // break; - } - } - } - } - */ - - loch = min2 (geometry.GetSurface(s1) -> LocH (np, 3, 1, h), - geometry.GetSurface(s2) -> LocH (np, 3, 1, h)); - - if (uselocalh) - { - double lh = mesh.GetH(np); - if (lh < loch) - loch = lh; - } - - - len += Dist (p, np) / loch; - edgepoints.Append (np); - curvelength.Append (len); - - p = np; - - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - } - while (! ep); - } - - - - - - - - void EdgeCalculation :: - AnalyzeEdge (int s1, int s2, int pos, int layer, - const ARRAY<Point<3> > & edgepoints, - ARRAY<Segment> & refedges, - ARRAY<bool> & refedgesinv) - { - int i, j, k, l; - int hi; - Point<3> hp; - Vec<3> t, a1, a2, m, n; - Segment seg; - Solid * locsol; - ARRAY<int> locsurfind; - - /* - int pi1 = 0, pi2 = 0; - extern Mesh * mesh; - for (i = 1; i <= mesh->GetNP(); i++) - { - if (Dist2 (edgepoints.Get(1), mesh->Point(i)) < 1e-12) - pi1 = i; - if (Dist2 (edgepoints.Last(), mesh->Point(i)) < 1e-12) - pi2 = i; - } - (*testout) << "Analyze edge: " << pi1 << " - " << pi2 << ", pts = " << edgepoints.Size() << endl; - (*testout) << "p1 = " << edgepoints.Get(1) << " pl = " << edgepoints.Last() << endl; - */ - bool debug = 0; - /* - Dist2 (Point<3> (1.824, -0.104, -0.95), edgepoints.Get(1)) < 1e-6 || - Dist2 (Point<3> (1.824, -0.104, -0.95), edgepoints.Last()) < 1e-6 || - Dist2 (Point<3> (1.72149, -0.26069, -0.95), edgepoints.Get(1)) < 1e-6 || - Dist2 (Point<3> (1.72149, -0.26069, -0.95), edgepoints.Last()) < 1e-6; - */ - - if (debug) - { - (*testout) << "tubious edge !!!" << endl; - (*testout) << "edgepoints = " << edgepoints << endl; - (*testout) << "s1, s2 = " << s1 << " - " << s2 << endl; - } - - refedges.SetSize(0); - refedgesinv.SetSize(0); - hp = Center (edgepoints[0], edgepoints[1]); - ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp); - - geometry.GetSurface(s1) -> CalcGradient (hp, a1); - geometry.GetSurface(s2) -> CalcGradient (hp, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - - for (i = 0; i < geometry.GetNTopLevelObjects(); i++) - { - if (geometry.GetTopLevelObject(i)->GetLayer() != layer) - continue; - - const Solid * sol = geometry.GetTopLevelObject(i)->GetSolid(); - const Surface * surf = geometry.GetTopLevelObject(i)->GetSurface(); - - sol -> TangentialSolid (hp, locsol); - - if (!locsol) continue; - - BoxSphere<3> boxp (hp, hp); - boxp.Increase (1e-5); - boxp.CalcDiamCenter(); - - ReducePrimitiveIterator rpi(boxp); - UnReducePrimitiveIterator urpi; - - ((Solid*)locsol) -> IterateSolid (rpi); - - locsol -> CalcSurfaceInverse (); - - if (!surf) - { - locsol -> GetSurfaceIndices (locsurfind); - } - else - { - /* - if (fabs (surf->CalcFunctionValue (hp)) < 1e-6) - continue; - */ - locsurfind.SetSize(1); - locsurfind[0] = -1; - for (j = 0; j < geometry.GetNSurf(); j++) - if (geometry.GetSurface(j) == surf) - { - locsurfind[0] = j; - // geometry.GetSurfaceClassRepresentant(j); - break; - } - } - - ((Solid*)locsol) -> IterateSolid (urpi); - - - if (debug) - (*testout) << "edge of tlo " << i << ", has " << locsurfind.Size() << " faces." << endl; - - - for (j = locsurfind.Size()-1; j >= 0; j--) - if (fabs (geometry.GetSurface(locsurfind[j]) - ->CalcFunctionValue (hp) ) > 1e-6) - locsurfind.Delete(j); - - if (debug) - (*testout) << locsurfind.Size() << " faces on hp" << endl; - - for (j = 0; j < locsurfind.Size(); j++) - { - int lsi = locsurfind[j]; - int rlsi = geometry.GetSurfaceClassRepresentant(lsi); - - Vec<3> rn; - - // n is outer normal to solid - n = geometry.GetSurface(lsi) -> GetNormalVector (hp); - if (geometry.GetSurface (lsi)->Inverse()) - n *= -1; - - if (fabs (t * n) > 1e-4) continue; - if (debug) - { - (*testout) << "face " << locsurfind.Get(j) << ", rep = " << rlsi - << " has (t*n) = " << (t*n) << endl; - (*testout) << "n = " << n << endl; - } - - // rn is normal to class representant - rn = geometry.GetSurface(rlsi) -> GetNormalVector (hp); - - int sameasref = ((n * rn) > 0); - - m = Cross (t, rn); - m.Normalize(); - - if (debug) - (*testout) << "m = " << m << endl; - - for (k = 1; k <= 2; k ++) - { - bool edgeinv = (k == 2); - - if (debug) - { - (*testout) << "onface(" << hp << ", " << m << ")= " << flush; - (*testout) << locsol->OnFace (hp, m) << flush; - (*testout) << " vec2in = " - << locsol -> VectorIn2 (hp, m, n) << " and " - << locsol -> VectorIn2 (hp, m, -1 * n) << endl; - } - - // if (locsol -> OnFace (hp, m)) - if (locsol -> VectorIn2 (hp, m, n) == 0 && - locsol -> VectorIn2 (hp, m, -1 * n) == 1) - { - if (debug) - (*testout) << "is true" << endl; - hi = 0; - for (l = 1; l <= refedges.Size(); l++) - { - if (refedges.Get(l).si == rlsi && - refedgesinv.Get(l) == edgeinv) - hi = l; - } - - if (!hi) - { - seg.si = rlsi; - seg.domin = -1; - seg.domout = -1; - seg.tlosurf = -1; - seg.surfnr1 = s1; - seg.surfnr2 = s2; - hi = refedges.Append (seg); - refedgesinv.Append (edgeinv); - } - - if (!surf) - { - if (sameasref) - refedges.Elem(hi).domin = i; - else - refedges.Elem(hi).domout = i; - } - else - refedges.Elem(hi).tlosurf = i; - - if (debug) - (*testout) << "add ref seg:" - << "si = " << refedges.Get(hi).si - << ", domin = " << refedges.Get(hi).domin - << ", domout = " << refedges.Get(hi).domout - << ", surfnr1/2 = " << refedges.Get(hi).surfnr1 - << ", " << refedges.Get(hi).surfnr2 - << ", inv = " << refedgesinv.Get(hi) - << ", refedgenr = " << hi - << endl; - } - else - { - if (debug) - (*testout) << "is false" << endl; - } - m *= -1; - } - } - delete locsol; - } - } - - - - void EdgeCalculation :: - StoreEdge (const ARRAY<Segment> & refedges, - const ARRAY<bool> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - - double len, corr, lam; - PointIndex thispi, lastpi; - Point<3> p, np; - Segment seg; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints.Get(1), edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - - // generate initial point - p = edgepoints.Get(1); - lastpi = -1; - - /* - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist (mesh[pi], p) < 1e-6) - { - lastpi = pi; - break; - } - */ - ARRAY<int> locsearch; - meshpoint_tree -> GetIntersecting (p-Vec<3> (1e-6, 1e-6, 1e-6), - p+Vec<3> (1e-6, 1e-6, 1e-6), locsearch); - if (locsearch.Size()) - lastpi = locsearch[0]; - - - - if (lastpi == -1) - { - lastpi = mesh.AddPoint (p, layer); - meshpoint_tree -> Insert (p, lastpi); - } - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength.Get(j) < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength.Get(j-1)) / - (curvelength.Get(j) - curvelength.Get(j-1)); - - np(0) = (1-lam) * edgepoints.Get(j-1)(0) + lam * edgepoints.Get(j)(0); - np(1) = (1-lam) * edgepoints.Get(j-1)(1) + lam * edgepoints.Get(j)(1); - np(2) = (1-lam) * edgepoints.Get(j-1)(2) + lam * edgepoints.Get(j)(2); - - - thispi = -1; - if (i == ne) - { - /* - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist(mesh[pi], np) < 1e-6) - thispi = pi; - */ - - meshpoint_tree -> GetIntersecting (np-Vec<3> (1e-6, 1e-6, 1e-6), - np+Vec<3> (1e-6, 1e-6, 1e-6), locsearch); - if (locsearch.Size()) - thispi = locsearch[0]; - } - - if (thispi == -1) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np, layer); - meshpoint_tree -> Insert (np, thispi); - } - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = lastpi; - seg.p2 = thispi; - } - else - { - seg.p1 = thispi; - seg.p2 = lastpi; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - - double maxh = min2 (geometry.GetSurface(seg.surfnr1)->GetMaxH(), - geometry.GetSurface(seg.surfnr2)->GetMaxH()); - - if (seg.domin != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domin) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domin)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.domout != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domout) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domout)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.tlosurf != -1) - { - double hi = geometry.GetTopLevelObject(seg.tlosurf) -> GetMaxH(); - maxh = min2 (maxh, hi); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - } - - p = np; - lastpi = thispi; - } - -#ifdef DEVELOP - (*testout) << " eplast = " << lastpi << " = " << p << endl; -#endif - } - - - - - - - void EdgeCalculation :: - StoreShortEdge (const ARRAY<Segment> & refedges, - const ARRAY<bool> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - PointIndex pi; - // int ne; - Segment seg; - - /* - double len, corr, lam; - int thispi, lastpi; - Point<3> p, np; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints[1], edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - */ - - // generate initial point - Point<3> p = edgepoints[0]; - PointIndex pi1 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi1 = pi; - break; - } - - if (pi1 == -1) - { - pi1 = mesh.AddPoint (p, layer); - meshpoint_tree -> Insert (p, pi1); - } - - p = edgepoints.Last(); - PointIndex pi2 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi2 = pi; - break; - } - if (pi2==-1) - { - pi2 = mesh.AddPoint (p, layer); - meshpoint_tree -> Insert (p, pi2); - } - - /* - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength[j] < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength[j-1]) / - (curvelength[j] - curvelength[j-1]); - - np(0) = (1-lam) * edgepoints[j-1](0) + lam * edgepoints[j](0); - np(1) = (1-lam) * edgepoints[j-1](1) + lam * edgepoints[j](1); - np(2) = (1-lam) * edgepoints[j-1](2) + lam * edgepoints[j](2); - - - thispi = 0; - if (i == ne) - for (j = 1; j <= mesh.GetNP(); j++) - if (Dist(mesh.Point(j), np) < 1e-6) - thispi = j; - - if (!thispi) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np); - } - */ - - for (int k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = pi1; - seg.p2 = pi2; - } - else - { - seg.p1 = pi2; - seg.p2 = pi1; - } - - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - } - } - - - - - - - - void EdgeCalculation :: - CopyEdge (const ARRAY<Segment> & refedges, - const ARRAY<bool> & refedgesinv, - int copyfromedge, - const Point<3> & fromstart, const Point<3> & fromend, - const Point<3> & tostart, const Point<3> & toend, - int copyedgeidentification, - int layer, - Mesh & mesh) - { - int k; - PointIndex pi; - - // copy start and end points - for (int i = 1; i <= 2; i++) - { - Point<3> fromp = - (i == 1) ? fromstart : fromend; - Point<3> top = - (i == 1) ? tostart : toend; - - PointIndex frompi = -1; - PointIndex topi = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - if (Dist2 (mesh[pi], fromp) <= 1e-16) - frompi = pi; - if (Dist2 (mesh[pi], top) <= 1e-16) - topi = pi; - } - - if (topi == -1) - { - topi = mesh.AddPoint (top, layer); - meshpoint_tree -> Insert (top, topi); - } - - const Identification & csi = - (*geometry.identifications.Get(copyedgeidentification)); - - if (csi.Identifyable (mesh[frompi], mesh[topi])) - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - else if (csi.Identifyable (mesh[topi], mesh[frompi])) - mesh.GetIdentifications().Add(topi, frompi, copyedgeidentification); - else - { - cerr << "edgeflw.cpp: should identify, but cannot"; - exit(1); - } - /* - (*testout) << "Add Identification from CopyEdge, p1 = " - << mesh[PointIndex(frompi)] << ", p2 = " - << mesh[PointIndex(topi)] << endl; - - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - */ - } - - int oldns = mesh.GetNSeg(); - for (int i = 1; i <= oldns; i++) - { - // real copy, since array might be reallocated !! - const Segment oldseg = mesh.LineSegment(i); - if (oldseg.edgenr != copyfromedge) - continue; - if (oldseg.seginfo == 0) - continue; - - int pi1 = oldseg.p1; - int pi2 = oldseg.p2; - - int npi1 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi1); - int npi2 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi2); - - Segment seg; - - for (k = 1; k <= refedges.Size(); k++) - { - bool inv = refedgesinv.Get(k); - - // other edge is inverse - if (oldseg.seginfo == 1) - inv = !inv; - - // (*testout) << "inv, now = " << inv << endl; - - if (inv) - { - seg.p1 = npi1; - seg.p2 = npi2; - } - else - { - seg.p1 = npi2; - seg.p2 = npi1; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = refedgesinv.Get(k) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "copy seg " << seg.p1 << "-" << seg.p2 << endl; -#ifdef DEVELOP - - (*testout) << "copy seg, face = " << seg.si << ": " - << " inv = " << inv << ", refinv = " << refedgesinv.Get(k) - << mesh.Point(seg.p1) << ", " << mesh.Point(seg.p2) << endl; -#endif - - } - - } - } - - - - - - - - void EdgeCalculation :: - FindClosedSurfaces (double h, Mesh & mesh) - { - // if there is no special point at a sphere, one has to add a segment pair - - int i, j; - int nsol; - int nsurf = geometry.GetNSurf(); - int layer; - - BitArray pointatsurface (nsurf); - Point<3> p1, p2; - Vec<3> nv, tv; - Solid * tansol; - ARRAY<int> tansurfind; - // const Solid * sol; - - nsol = geometry.GetNTopLevelObjects(); - - - pointatsurface.Clear(); - - /* - for (i = 1; i <= specpoints.Size(); i++) - { - int classrep; - - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s1); - pointatsurface.Set (classrep); - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s2); - pointatsurface.Set (classrep); - // pointatsurface.Set (specpoints[i].s1); - // pointatsurface.Set (specpoints[i].s2); - } - */ - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - int classrep; - -#ifdef DEVELOP - (*testout) << seg.surfnr1 << ", " << seg.surfnr2 << ", si = " << seg.si << endl; -#endif - classrep = geometry.GetSurfaceClassRepresentant (seg.si); - - pointatsurface.Set (classrep); - } - - - for (i = 0; i < nsurf; i++) - { - int classrep = geometry.GetSurfaceClassRepresentant (i); - - if (!pointatsurface.Test(classrep)) - { - const Surface * s = geometry.GetSurface(i); - p1 = s -> GetSurfacePoint(); - nv = s -> GetNormalVector (p1); - - double hloc = - min2 (s->LocH (p1, 3, 1, h), mesh.GetH(p1)); - - tv = nv.GetNormal (); - tv *= (hloc / tv.Length()); - p2 = p1 + tv; - s->Project (p2); - - - Segment seg1; - seg1.si = i; - seg1.domin = -1; - seg1.domout = -1; - - Segment seg2; - seg2.si = i; - seg2.domin = -1; - seg2.domout = -1; - - seg1.surfnr1 = i; - seg2.surfnr1 = i; - seg1.surfnr2 = i; - seg2.surfnr2 = i; - - for (j = 0; j < nsol; j++) - { - if (geometry.GetTopLevelObject(j)->GetSurface()) - continue; - - const Solid * sol = geometry.GetTopLevelObject(j)->GetSolid(); - sol -> TangentialSolid (p1, tansol); - layer = geometry.GetTopLevelObject(j)->GetLayer(); - - if (tansol) - { - tansol -> GetSurfaceIndices (tansurfind); - - if (tansurfind.Size() == 1 && tansurfind.Get(1) == i) - { - if (!tansol->VectorIn(p1, nv)) - { - seg1.domin = j; - seg2.domin = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - else - { - seg1.domout = j; - seg2.domout = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - // seg.s2 = i; - // seg.invs1 = surfaces[i] -> Inverse(); - // seg.invs2 = ! (surfaces[i] -> Inverse()); - } - delete tansol; - } - } - - - if (seg1.domin != -1 || seg1.domout != -1) - { - mesh.AddPoint (p1, layer); - mesh.AddPoint (p2, layer); - seg1.p1 = mesh.GetNP()-1; - seg1.p2 = mesh.GetNP(); - seg2.p2 = mesh.GetNP()-1; - seg2.p1 = mesh.GetNP(); - seg1.geominfo[0].trignum = 1; - seg1.geominfo[1].trignum = 1; - seg2.geominfo[0].trignum = 1; - seg2.geominfo[1].trignum = 1; - mesh.AddSegment (seg1); - mesh.AddSegment (seg2); - - PrintMessage (5, "Add line segment to smooth surface"); - -#ifdef DEVELOP - (*testout) << "Add segment at smooth surface " << i; - if (i != classrep) (*testout) << ", classrep = " << classrep; - (*testout) << ": " - << mesh.Point (mesh.GetNP()-1) << " - " - << mesh.Point (mesh.GetNP()) << endl; -#endif - } - } - } - } - -} diff --git a/Netgen/libsrc/csg/edgeflw.hpp b/Netgen/libsrc/csg/edgeflw.hpp deleted file mode 100644 index beb1f690a9..0000000000 --- a/Netgen/libsrc/csg/edgeflw.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef FILE_EDGEFLW -#define FILE_EDGEFLW - -/**************************************************************************/ -/* File: edgeflw.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - -/* - - Edge - following function and - Projection to edge of implicitly given edge - -*/ - - -/** - Calculates edges. - The edges of a solid geometry are computed. Special - points have to be given. - */ -extern void CalcEdges (const CSGeometry & geometry, - const ARRAY<SpecialPoint> & specpoints, - double h, Mesh & mesh); - - - - - -class EdgeCalculation -{ - const CSGeometry & geometry; - ARRAY<SpecialPoint> & specpoints; - Point3dTree * searchtree; - Point3dTree * meshpoint_tree; - int cntedge; -public: - EdgeCalculation (const CSGeometry & ageometry, - ARRAY<SpecialPoint> & aspecpoints); - - ~EdgeCalculation(); - - void Calc(double h, Mesh & mesh); - - -private: - void CalcEdges1 (double h, Mesh & mesh); - - - void FollowEdge (int pi1, int & ep, int & pos, - // const ARRAY<SpecialPoint> & hsp, - const ARRAY<int> & hsp, - double h, const Mesh & mesh, - ARRAY<Point<3> > & edgepoints, - ARRAY<double> & curvelength); - - - void AnalyzeEdge (int s1, int s2, int pos, int layer, - const ARRAY<Point<3> > & edgepoints, - ARRAY<Segment> & refedges, - ARRAY<bool> & refedgesinv); - - void StoreEdge (const ARRAY<Segment> & refedges, - const ARRAY<bool> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh); - - void StoreShortEdge (const ARRAY<Segment> & refedges, - const ARRAY<bool> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh); - - void CopyEdge (const ARRAY<Segment> & refedges, - const ARRAY<bool> & refedgesinv, - int copyfromedge, - const Point<3> & fromstart, const Point<3> & fromend, - const Point<3> & tostart, const Point<3> & toend, - int copyedgeidentification, - int layer, - Mesh & mesh); - - - void SplitEqualOneSegEdges (Mesh & mesh); - void FindClosedSurfaces (double h, Mesh & mesh); - - -public: - bool point_on_edge_problem; - -}; - - - -#endif diff --git a/Netgen/libsrc/csg/edgeflw2.cpp b/Netgen/libsrc/csg/edgeflw2.cpp deleted file mode 100644 index 87239c05bb..0000000000 --- a/Netgen/libsrc/csg/edgeflw2.cpp +++ /dev/null @@ -1,1404 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - -#undef DEVELOP - -namespace netgen -{ - - EdgeCalculation :: - EdgeCalculation (const CSGeometry & ageometry, - const ARRAY<SpecialPoint> & aspecpoints) - : geometry(ageometry), specpoints(aspecpoints) - { - ; - } - - - - void EdgeCalculation :: Calc(double h, Mesh & mesh) - { - PrintMessage (1, "Find edges"); - PushStatus ("Find edges"); - - CalcEdges1 (h, mesh); - SplitEqualOneSegEdges (mesh); - FindClosedSurfaces (h, mesh); - PrintMessage (3, cntedge, " edges found"); - - PopStatus (); - } - - - - - void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh) - { - ARRAY<SpecialPoint> hsp(specpoints.Size()); - ARRAY<SpecialPoint> startpoints, endpoints; - - int i, j, k, l, hi, pos, ep, ne; - int layer; - - Vec<3> a1, a2, t, n, m; - Point<3> p, np, pnp, hp; - - Segment seg; - int pi1, s1, s2; - int lastpi, thispi; - - ARRAY<Point<3> > edgepoints; - ARRAY<double> curvelength; - int copyedge, copyfromedge, copyedgeidentification; - - ARRAY<int> locsurfind; - - double len, corr, lam; - double steplen, cursteplen, loch, hd; - - int checkedcopy = 0; - - double size = geometry.MaxSize(); // globflags.GetNumFlag ("maxsize", 500); - double epspointdist2 = size * 1e-6; // globflags.GetNumFlag ("epspointdist", size * 1e-6); - epspointdist2 = sqr (epspointdist2); - - - Solid * locsol; - - - // copy special points to work with - for (i = 0; i < specpoints.Size(); i++) - hsp[i] = specpoints[i]; - - - cntedge = 0; - - while (hsp.Size()) - { - SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size()); - - edgepoints.SetSize (0); - curvelength.SetSize (0); - - - pi1 = 0; - copyedge = 0; - // identifyable point available ? - - // (*testout) << endl; - - for (i = 1; i <= geometry.identifications.Size() && !pi1; i++) - { - for (j = checkedcopy+1; j <= startpoints.Size() && !pi1; j++) - { - - if (geometry.identifications.Get(i)->IdentifyableCandidate (startpoints.Get(j))) - - { - int pi1cand = 0; - double mindist = 1e10; - - for (k = 1; k <= hsp.Size() && !pi1; k++) - { -#ifdef DEVELOP - (*testout) << "check kand = " << hsp.Get(k).p - << ", v = " << hsp.Get(k).v - << endl; -#endif - if (geometry.identifications.Get(i) - ->Identifyable(startpoints.Get(j), hsp.Get(k)) || - geometry.identifications.Get(i) - ->Identifyable(hsp.Get(k), startpoints.Get(j))) - { - -#ifdef DEVELOP - (*testout) << "identifiable, dist = " - << Dist (startpoints.Get(j).p, hsp.Get(k).p) << endl; -#endif - - if (Dist (startpoints.Get(j).p, hsp.Get(k).p) < mindist) - { - mindist = Dist (startpoints.Get(j).p, hsp.Get(k).p); - pi1cand = k; - } - /* - pi1 = k; - copyedge = 1; - copyfromedge = j; - copyedgeidentification = i; - - (*testout) << "copy edge startpoint from " - << startpoints.Get(j).p << " - " - << startpoints.Get(j).v - << " to " - << hsp.Get(k).p << " - " << hsp.Get(k).v << endl; - */ - } - } - - if (pi1cand) - { - pi1 = pi1cand; - copyedge = 1; - copyfromedge = j; - copyedgeidentification = i; -#ifdef DEVELOP - (*testout) << "copy edge startpoint from " - << startpoints.Get(j).p << " - " - << startpoints.Get(j).v - << " to " - << hsp.Get(pi1).p << " - " << hsp.Get(pi1).v << endl; -#endif - } - } - } - } - - - // cannot copy from other ege ? - if (!pi1) - checkedcopy = startpoints.Size(); - - // unconditional special point available ? - if (!pi1) - for (i = 1; i <= hsp.Size() && pi1 == 0; i++) - if (hsp.Get(i).unconditional == 1) - pi1 = i; - - - if (!pi1) - { - // only unconditional points available, choose first - pi1 = 1; - } - - layer = hsp.Get(pi1).GetLayer(); - - - if (!hsp.Get(pi1).unconditional) - { - hsp.Elem(pi1).unconditional = 1; - for (i = 1; i <= hsp.Size(); i++) - if (i != pi1 && Dist (hsp.Get(pi1).p, hsp.Get(i).p) < 1e-8 && - (hsp.Get(pi1).v + hsp.Get(i).v).Length() < 1e-4) - { - // opposite direction - hsp.Elem(i).unconditional = 1; - } - } - - cntedge++; - startpoints.Append (hsp.Get(pi1)); - -#ifdef DEVELOP - (*testout) << "edge nr " << cntedge << endl; - (*testout) << "start followedge: p1 = " << hsp.Get(pi1).p << ", v = " << hsp.Get(pi1).v << endl; -#endif - - FollowEdge (pi1, ep, pos, hsp, h, mesh, - edgepoints, curvelength); - - - if (multithread.terminate) - return; - - if (!ep) - { - // ignore starting point - hsp.DeleteElement (pi1); - continue; - } - - - - endpoints.Append (hsp.Get(ep)); - - - double elen = 0; - for (i = 1; i <= edgepoints.Size()-1; i++) - elen += Dist (edgepoints.Get(i), edgepoints.Get(i+1)); - - - int shortedge = 0; - for (i = 1; i <= geometry.identifications.Size(); i++) - if (geometry.identifications.Get(i)->ShortEdge(hsp.Get(pi1), hsp.Get(ep))) - shortedge = 1; - (*testout) << "shortedge = " << shortedge << endl; - - - if (!shortedge) - { - mesh.RestrictLocalHLine (Point3d (hsp.Get(pi1).p), - Point3d (hsp.Get(ep).p), - elen / mparam.segmentsperedge); - } - - s1 = hsp.Get(pi1).s1; - s2 = hsp.Get(pi1).s2; - - - // delete initial, terminal and conditional points - -#ifdef DEVELOP - (*testout) << "terminal point: p = " << hsp.Get(ep).p << ", v = " << hsp.Get(ep).v << endl; -#endif - if (ep > pi1) - { - hsp.DeleteElement (ep); - hsp.DeleteElement (pi1); - } - else - { - hsp.DeleteElement (pi1); - hsp.DeleteElement (ep); - } - - - for (j = 1; j <= edgepoints.Size()-1; j++) - { - p = edgepoints.Get(j); - np = Center (p, edgepoints.Get(j+1)); - hd = Dist2 (p, np); - - for (i = 1; i <= hsp.Size(); i++) - if ( hsp.Get(i).HasSurfaces (s1, s2) && - hsp.Get(i).unconditional == 0 && - Dist2 (np, hsp.Get(i).p) < 1.2 * hd) - { - hsp.DeleteElement (i); - i--; - } - } - - - ARRAY<Segment> refedges; - ARRAY<int> refedgesinv; - - - AnalyzeEdge (s1, s2, pos, layer, - edgepoints, - refedges, refedgesinv); - - for (i = 1; i <= refedges.Size(); i++) - refedges.Elem(i).edgenr = cntedge; - - -#ifdef DEVELOP - (*testout) << "edge " << cntedge << endl - << "startp: " << startpoints.Last().p - << ", v = " << startpoints.Last().v << endl - << "copy = " << copyedge << endl - << refedges.Size() << " refedges: "; - for (i = 1; i <= refedges.Size(); i++) - (*testout) << " " << refedges.Get(i).si; - (*testout) << endl; - (*testout) << "inv[1] = " << refedgesinv.Get(1) << endl; -#endif - - if (!copyedge) - { - int oldnseg = mesh.GetNSeg(); - - if (!shortedge) - StoreEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - else - StoreShortEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - - - /* - for (i = oldnseg+1; i <= mesh.GetNSeg(); i++) - for (j = 1; j <= oldnseg; j++) - { - const Point<3> & l1p1 = mesh.Point (mesh.LineSegment(i).p1); - const Point<3> & l1p2 = mesh.Point (mesh.LineSegment(i).p2); - const Point<3> & l2p1 = mesh.Point (mesh.LineSegment(j).p1); - const Point<3> & l2p2 = mesh.Point (mesh.LineSegment(j).p2); - Vec<3> vl1(l1p1, l1p2); - for (double lamk = 0; lamk <= 1; lamk += 0.1) - { - Point<3> l2p = l1p1 + lamk * vl1; - double dist = sqrt (MinDistLP2 (l2p1, l2p2, l2p)); - if (dist > 1e-12) - mesh.RestrictLocalH (l2p, 3*dist); - } - } - */ - } - else - { - CopyEdge (refedges, refedgesinv, - copyfromedge, - startpoints.Get(copyfromedge).p, - endpoints.Get(copyfromedge).p, - edgepoints.Get(1), edgepoints.Last(), - copyedgeidentification, - layer, - mesh); - } - - } - } - - - - /* - If two or more edges share the same initial and end-points, - then they need at least two segments - */ - void EdgeCalculation :: - SplitEqualOneSegEdges (Mesh & mesh) - { - int i, j; - SegmentIndex si; - PointIndex pi; - - ARRAY<int> osedges(cntedge); - INDEX_2_HASHTABLE<int> osedgesht (cntedge+1); - - osedges = 2; - - // count segments on edges - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - osedges.Elem(seg.edgenr)--; - } - - (*testout) << "osedges = " << osedges << endl; - - // flag one segment edges - for (i = 0; i < cntedge; i++) - osedges[i] = (osedges[i] > 0) ? 1 : 0; - - (*testout) << "osedges, now = " << osedges << endl; - - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr)) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2)) - osedgesht.Set (i2, 2); - else - osedgesht.Set (i2, 1); - } - } - } - - - // one edge 1 segment, other 2 segments - // yes, it happens ! - - for (i = 1; i <= osedgesht.GetNBags(); i++) - for (j = 1; j <= osedgesht.GetBagSize(i); j++) - { - INDEX_2 i2; - int val; - osedgesht.GetData (i, j, i2, val); - - const Point<3> & p1 = mesh[PointIndex(i2.I1())]; - const Point<3> & p2 = mesh[PointIndex(i2.I2())]; - Vec<3> v = p2 - p1; - double vlen = v.Length(); - v /= vlen; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (pi != i2.I1() && pi != i2.I2()) - { - const Point<3> & p = mesh[pi]; - Vec<3> v2 = p - p1; - double lam = (v2 * v); - if (lam > 0 && lam < vlen) - { - Point<3> hp = p1 + lam * v; - if (Dist (p, hp) < 1e-4 * vlen) - { - PrintSysError ("Point on edge !!!"); - cout << "seg: " << i2 << ", p = " << pi << endl; - osedgesht.Set (i2, 2); - } - } - } - } - - - // insert new points - osedges = -1; - - int nseg = mesh.GetNSeg(); - for (si = 0; si < nseg; si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2) && - osedgesht.Get (i2) == 2 && - osedges.Elem(seg.edgenr) == -1) - { - Point<3> newp = Center (mesh[PointIndex(seg.p1)], - mesh[PointIndex(seg.p2)]); - - ProjectToEdge (geometry.GetSurface(seg.surfnr1), - geometry.GetSurface(seg.surfnr2), - newp); - - osedges.Elem(seg.edgenr) = - mesh.AddPoint (newp, mesh[PointIndex(seg.p1)].GetLayer()); - } - } - } - - - for (i = 1; i <= nseg; i++) - { - Segment & seg = mesh.LineSegment (i); - if (seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr) != -1) - { - Segment newseg = seg; - newseg.p1 = osedges.Get(seg.edgenr); - seg.p2 = osedges.Get(seg.edgenr); - mesh.AddSegment (newseg); - } - } - } - - } - - - - void EdgeCalculation :: - FollowEdge (int pi1, int & ep, int & pos, - const ARRAY<SpecialPoint> & hsp, - double h, const Mesh & mesh, - ARRAY<Point<3> > & edgepoints, - ARRAY<double> & curvelength) - { - int i, j, s1, s2; - double len, steplen, cursteplen, loch; - Point<3> p, np, pnp; - Vec<3> a1, a2, t; - - - double size = geometry.MaxSize(); - double epspointdist2 = size * 1e-6; - epspointdist2 = sqr (epspointdist2); - int uselocalh = mparam.uselocalh; - - - s1 = hsp.Get(pi1).s1; - s2 = hsp.Get(pi1).s2; - - p = hsp.Get(pi1).p; - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - - t = Cross (a1, a2); - t.Normalize(); - - pos = (hsp.Get(pi1).v * t) > 0; - if (!pos) t *= -1; - - - edgepoints.Append (p); - curvelength.Append (0); - len = 0; - - loch = min2 (geometry.GetSurface(s1) -> LocH (p, 3, 1, h), - geometry.GetSurface(s2) -> LocH (p, 3, 1, h)); - - - - if (uselocalh) - { - double lh = mesh.GetH(p); - if (lh < loch) - loch = lh; - } - - steplen = 0.1 * loch; - - do - { - if (multithread.terminate) - return; - - if (fabs (p(0)) + fabs (p(1)) + fabs (p(2)) > 10000) - { - ep = 0; - PrintWarning ("Give up line"); - break; - } - - if (steplen > 0.1 * loch) steplen = 0.1 * loch; - - steplen *= 2; - do - { - steplen *= 0.5; - np = p + steplen * t; - pnp = np; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), pnp); - } - while (Dist (np, pnp) > 0.1 * steplen); - - cursteplen = steplen; - if (Dist (np, pnp) < 0.01 * steplen) steplen *= 2; - - - np = pnp; - -#ifdef MYGRAPH - if (silentflag <= 2) - { - MyLine3D (p, np, rot); - MyDraw (); - } -#endif - - ep = 0; - - double hvtmin = 1.5 * cursteplen; - - Box<3> boxp (p - (2 * cursteplen) * Vec<3> (1, 1, 1), - p + (2 * cursteplen) * Vec<3> (1, 1, 1)); - - for (i = 1; i <= hsp.Size(); i++) - // if ( i != pi1 && hsp.Get(i).HasSurfaces (s1, s2) ) - { - if (!boxp.IsIn (hsp.Get(i).p)) - continue; - - Vec<3> hv = hsp.Get(i).p - p; - if (hv.Length2() > 9 * cursteplen * cursteplen) - continue; - - /* - if (!hsp.Get(i).HasSurfaces (s1, s2)) - continue; // test for dalibor-problem - */ - - double hvt = hv * t; - hv -= hvt * t; - - if (hv.Length() < 0.2 * cursteplen && - hvt > 0 && - // hvt < 1.5 * cursteplen && - hvt < hvtmin && - hsp.Get(i).unconditional == 1 && - (hsp.Get(i).v + t).Length() < 0.4 ) - { - Point<3> hep = hsp.Get(i).p; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), hep); - - - if (Dist2 (hep, hsp.Get(i).p) < epspointdist2 ) - { - geometry.GetSurface(s1) -> CalcGradient (hep, a1); - geometry.GetSurface(s2) -> CalcGradient (hep, a2); - Vec<3> ept = Cross (a1, a2); - ept /= ept.Length(); - if (!pos) ept *= -1; - - if ( (hsp.Get(i).v + ept).Length() < 1e-4 ) - { - np = hsp.Get(i).p; - ep = i; - hvtmin = hvt; - // break; - } - } - } - } - - loch = min2 (geometry.GetSurface(s1) -> LocH (np, 3, 1, h), - geometry.GetSurface(s2) -> LocH (np, 3, 1, h)); - - if (uselocalh) - { - double lh = mesh.GetH(np); - if (lh < loch) - loch = lh; - } - - - len += Dist (p, np) / loch; - edgepoints.Append (np); - curvelength.Append (len); - - p = np; - - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - } - while (! ep); - } - - - - - - - - void EdgeCalculation :: - AnalyzeEdge (int s1, int s2, int pos, int layer, - const ARRAY<Point<3> > & edgepoints, - ARRAY<Segment> & refedges, - ARRAY<int> & refedgesinv) - { - int i, j, k, l; - int hi; - Point<3> hp; - Vec<3> t, a1, a2, m, n; - Segment seg; - Solid * locsol; - ARRAY<int> locsurfind; - - /* - int pi1 = 0, pi2 = 0; - extern Mesh * mesh; - for (i = 1; i <= mesh->GetNP(); i++) - { - if (Dist2 (edgepoints.Get(1), mesh->Point(i)) < 1e-12) - pi1 = i; - if (Dist2 (edgepoints.Last(), mesh->Point(i)) < 1e-12) - pi2 = i; - } - (*testout) << "Analyze edge: " << pi1 << " - " << pi2 << ", pts = " << edgepoints.Size() << endl; - (*testout) << "p1 = " << edgepoints.Get(1) << " pl = " << edgepoints.Last() << endl; - */ - int debug = 0; - /* - Dist2 (Point<3> (2.69642, 1.1866, 2.03), edgepoints.Get(1)) < 1e-6 || - Dist2 (Point<3> (2.69642, 1.1866, 2.03), edgepoints.Last()) < 1e-6; - */ - - if (debug) - { - // (*testout) << "tubious edge !!!" << endl; - (*testout) << "s1, s2 = " << s1 << " - " << s2 << endl; - } - - refedges.SetSize(0); - refedgesinv.SetSize(0); - hp = Center (edgepoints.Get(1), edgepoints.Get(2)); - ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp); - - geometry.GetSurface(s1) -> CalcGradient (hp, a1); - geometry.GetSurface(s2) -> CalcGradient (hp, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - - (*testout) << "t = " << t << endl; - - for (i = 0; i < geometry.GetNTopLevelObjects(); i++) - { - (*testout) << "layer = " << layer - << ", tlo-layer = " << geometry.GetTopLevelObject(i)->GetLayer() << endl; - if (geometry.GetTopLevelObject(i)->GetLayer() != layer) - continue; - - const Solid * sol = geometry.GetTopLevelObject(i)->GetSolid(); - const Surface * surf = geometry.GetTopLevelObject(i)->GetSurface(); - - sol -> TangentialSolid (hp, locsol); - if (!locsol) continue; - - BoxSphere<3> boxp (hp, hp); - boxp.Increase (1e-5); - boxp.CalcDiamCenter(); - - ReducePrimitiveIterator rpi(boxp); - UnReducePrimitiveIterator urpi; - - ((Solid*)locsol) -> IterateSolid (rpi); - - locsol -> CalcSurfaceInverse (); - - - if (!surf) - { - locsol -> GetSurfaceIndices (locsurfind); - } - else - { - /* - if (fabs (surf->CalcFunctionValue (hp)) < 1e-6) - continue; - */ - locsurfind.SetSize(1); - locsurfind[0] = -1; - for (j = 0; j < geometry.GetNSurf(); j++) - if (geometry.GetSurface(j) == surf) - { - locsurfind[0] = j; - // geometry.GetSurfaceClassRepresentant(j); - break; - } - } - - ((Solid*)locsol) -> IterateSolid (urpi); - - - if (debug) - (*testout) << "edge of tlo " << i << ", has " << locsurfind.Size() << " faces." << endl; - - - for (j = locsurfind.Size()-1; j >= 0; j--) - if (fabs (geometry.GetSurface(locsurfind[j]) - ->CalcFunctionValue (hp) ) > 1e-6) - locsurfind.DeleteElement(j+1); - - if (debug) - (*testout) << locsurfind.Size() << " faces on hp" << endl; - - for (j = 0; j < locsurfind.Size(); j++) - { - int lsi = locsurfind[j]; - int rlsi = geometry.GetSurfaceClassRepresentant(lsi); - - Vec<3> rn; - - // n is outer normal to solid - geometry.GetSurface(lsi) -> GetNormalVector (hp, n); - if (geometry.GetSurface (lsi)->Inverse()) - n *= -1; - - if (fabs (t * n) > 1e-4) continue; - if (debug) - { - (*testout) << "face " << locsurfind.Get(j) << ", rep = " << rlsi - << " has (t*n) = " << (t*n) << endl; - (*testout) << "n = " << n << endl; - } - - // rn is normal to class representant - geometry.GetSurface(rlsi) -> GetNormalVector (hp, rn); - - int sameasref = ((n * rn) > 0); - - m = Cross (t, rn); - m.Normalize(); - - - for (k = 1; k <= 2; k ++) - { - bool edgeinv = (k == 2); - - if (debug) - { - (*testout) << "onface(" << hp << ", " << m << ")= " - << locsol->OnFace (hp, m); - (*testout) << " vec2in = " - << locsol -> VectorIn2 (hp, m, n) << " and " - << locsol -> VectorIn2 (hp, m, -1 * n) << endl; - } - - // if (locsol -> OnFace (hp, m)) - if (locsol -> VectorIn2 (hp, m, n) == 0 && - locsol -> VectorIn2 (hp, m, -1 * n) == 1) - { - hi = 0; - for (l = 1; l <= refedges.Size(); l++) - { - if (refedges.Get(l).si == rlsi && - refedgesinv.Get(l) == edgeinv) - hi = l; - } - - if (!hi) - { - seg.si = rlsi; - seg.domin = -1; - seg.domout = -1; - seg.tlosurf = -1; - seg.surfnr1 = s1; - seg.surfnr2 = s2; - hi = refedges.Append (seg); - refedgesinv.Append (edgeinv); - } - - if (!surf) - { - if (sameasref) - refedges.Elem(hi).domin = i; - else - refedges.Elem(hi).domout = i; - } - else - refedges.Elem(hi).tlosurf = i; - - if (debug) - (*testout) << "add ref seg:" - << "si = " << refedges.Get(hi).si - << ", domin = " << refedges.Get(hi).domin - << ", domout = " << refedges.Get(hi).domout - << ", surfnr1/2 = " << refedges.Get(hi).surfnr1 - << ", " << refedges.Get(hi).surfnr2 - << ", inv = " << refedgesinv.Get(hi) - << ", refedgenr = " << hi - << endl; - } - m *= -1; - } - } - delete locsol; - } - } - - - - void EdgeCalculation :: - StoreEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - - double len, corr, lam; - PointIndex thispi, lastpi; - Point<3> p, np; - Segment seg; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints.Get(1), edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - - // generate initial point - p = edgepoints.Get(1); - lastpi = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist (mesh[pi], p) < 1e-6) - { - lastpi = pi; - break; - } - - if (lastpi == -1) - lastpi = mesh.AddPoint (p, layer); - - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength.Get(j) < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength.Get(j-1)) / - (curvelength.Get(j) - curvelength.Get(j-1)); - - np(0) = (1-lam) * edgepoints.Get(j-1)(0) + lam * edgepoints.Get(j)(0); - np(1) = (1-lam) * edgepoints.Get(j-1)(1) + lam * edgepoints.Get(j)(1); - np(2) = (1-lam) * edgepoints.Get(j-1)(2) + lam * edgepoints.Get(j)(2); - - - thispi = -1; - if (i == ne) - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist(mesh[pi], np) < 1e-6) - thispi = pi; - - if (thispi == -1) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np, layer); - } - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = lastpi; - seg.p2 = thispi; - } - else - { - seg.p1 = thispi; - seg.p2 = lastpi; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - - double maxh = min2 (geometry.GetSurface(seg.surfnr1)->GetMaxH(), - geometry.GetSurface(seg.surfnr2)->GetMaxH()); - - if (seg.domin != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domin) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domin)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.domout != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domout) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domout)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.tlosurf != -1) - { - double hi = geometry.GetTopLevelObject(seg.tlosurf) -> GetMaxH(); - maxh = min2 (maxh, hi); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - } - - p = np; - lastpi = thispi; - } - -#ifdef DEVELOP - (*testout) << " eplast = " << lastpi << " = " << p << endl; -#endif - } - - - - - - - void EdgeCalculation :: - StoreShortEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - Segment seg; - - /* - double len, corr, lam; - int thispi, lastpi; - Point<3> p, np; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints[1], edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - */ - - // generate initial point - Point<3> p = edgepoints[0]; - PointIndex pi1 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi1 = pi; - break; - } - - if (pi1 == -1) pi1 = mesh.AddPoint (p, layer); - - p = edgepoints.Last(); - PointIndex pi2 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi2 = pi; - break; - } - if (pi2==-1) pi2 = mesh.AddPoint (p, layer); - - /* - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength[j] < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength[j-1]) / - (curvelength[j] - curvelength[j-1]); - - np(0) = (1-lam) * edgepoints[j-1](0) + lam * edgepoints[j](0); - np(1) = (1-lam) * edgepoints[j-1](1) + lam * edgepoints[j](1); - np(2) = (1-lam) * edgepoints[j-1](2) + lam * edgepoints[j](2); - - - thispi = 0; - if (i == ne) - for (j = 1; j <= mesh.GetNP(); j++) - if (Dist(mesh.Point(j), np) < 1e-6) - thispi = j; - - if (!thispi) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np); - } - */ - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = pi1; - seg.p2 = pi2; - } - else - { - seg.p1 = pi2; - seg.p2 = pi1; - } - - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - } - } - - - - - - - - void EdgeCalculation :: - CopyEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - int copyfromedge, - const Point<3> & fromstart, const Point<3> & fromend, - const Point<3> & tostart, const Point<3> & toend, - int copyedgeidentification, - int layer, - Mesh & mesh) - { - int i, j, k; - PointIndex pi; - - // copy start and end points - for (i = 1; i <= 2; i++) - { - Point<3> fromp = - (i == 1) ? fromstart : fromend; - Point<3> top = - (i == 1) ? tostart : toend; - - PointIndex frompi = -1; - PointIndex topi = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - if (Dist2 (mesh[pi], fromp) <= 1e-16) - frompi = pi; - if (Dist2 (mesh[pi], top) <= 1e-16) - topi = pi; - } - - if (topi == -1) - topi = mesh.AddPoint (top, layer); - - const Identification & csi = - (*geometry.identifications.Get(copyedgeidentification)); - - if (csi.Identifyable (mesh[frompi], mesh[topi])) - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - else if (csi.Identifyable (mesh[topi], mesh[frompi])) - mesh.GetIdentifications().Add(topi, frompi, copyedgeidentification); - else - { - cerr << "edgeflw.cpp: should identify, but cannot"; - exit(1); - } - /* - (*testout) << "Add Identification from CopyEdge, p1 = " - << mesh[PointIndex(frompi)] << ", p2 = " - << mesh[PointIndex(topi)] << endl; - - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - */ - } - - int oldns = mesh.GetNSeg(); - for (i = 1; i <= oldns; i++) - { - // real copy, since array might be reallocated !! - const Segment oldseg = mesh.LineSegment(i); - if (oldseg.edgenr != copyfromedge) - continue; - if (oldseg.seginfo == 0) - continue; - - int pi1 = oldseg.p1; - int pi2 = oldseg.p2; - - int npi1 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi1); - int npi2 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi2); - - Segment seg; - - for (k = 1; k <= refedges.Size(); k++) - { - int inv = refedgesinv.Get(k); - - // other edge is inverse - if (oldseg.seginfo == 1) - inv = !inv; - - // (*testout) << "inv, now = " << inv << endl; - - if (inv) - { - seg.p1 = npi1; - seg.p2 = npi2; - } - else - { - seg.p1 = npi2; - seg.p2 = npi1; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = refedgesinv.Get(k) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "copy seg " << seg.p1 << "-" << seg.p2 << endl; -#ifdef DEVELOP - - (*testout) << "copy seg, face = " << seg.si << ": " - << " inv = " << inv << ", refinv = " << refedgesinv.Get(k) - << mesh.Point(seg.p1) << ", " << mesh.Point(seg.p2) << endl; -#endif - - } - - } - } - - - - - - - - void EdgeCalculation :: - FindClosedSurfaces (double h, Mesh & mesh) - { - // if there is no special point at a sphere, one has to add a segment pair - - int i, j; - int nsol; - int nsurf = geometry.GetNSurf(); - int layer; - - BitArray pointatsurface (nsurf); - Point<3> p1, p2; - Vec<3> nv, tv; - Solid * tansol; - ARRAY<int> tansurfind; - // const Solid * sol; - - nsol = geometry.GetNTopLevelObjects(); - - - pointatsurface.Clear(); - - /* - for (i = 1; i <= specpoints.Size(); i++) - { - int classrep; - - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s1); - pointatsurface.Set (classrep); - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s2); - pointatsurface.Set (classrep); - // pointatsurface.Set (specpoints[i].s1); - // pointatsurface.Set (specpoints[i].s2); - } - */ - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - int classrep; - -#ifdef DEVELOP - (*testout) << seg.surfnr1 << ", " << seg.surfnr2 << ", si = " << seg.si << endl; -#endif - classrep = geometry.GetSurfaceClassRepresentant (seg.si); - - pointatsurface.Set (classrep); - } - - - for (i = 0; i < nsurf; i++) - { - int classrep = geometry.GetSurfaceClassRepresentant (i); - - if (!pointatsurface.Test(classrep)) - { - const Surface * s = geometry.GetSurface(i); - p1 = s -> GetSurfacePoint(); - s -> GetNormalVector (p1, nv); - - double hloc = - min2 (s->LocH (p1, 3, 1, h), mesh.GetH(p1)); - - tv = nv.GetNormal (); - tv *= (hloc / tv.Length()); - p2 = p1 + tv; - s->Project (p2); - - - Segment seg1; - seg1.si = i; - seg1.domin = -1; - seg1.domout = -1; - - Segment seg2; - seg2.si = i; - seg2.domin = -1; - seg2.domout = -1; - - seg1.surfnr1 = i; - seg2.surfnr1 = i; - seg1.surfnr2 = i; - seg2.surfnr2 = i; - - for (j = 0; j < nsol; j++) - { - if (geometry.GetTopLevelObject(j)->GetSurface()) - continue; - - const Solid * sol = geometry.GetTopLevelObject(j)->GetSolid(); - sol -> TangentialSolid (p1, tansol); - layer = geometry.GetTopLevelObject(j)->GetLayer(); - - if (tansol) - { - tansol -> GetSurfaceIndices (tansurfind); - - if (tansurfind.Size() == 1 && tansurfind.Get(1) == i) - { - if (!tansol->VectorIn(p1, nv)) - { - seg1.domin = j; - seg2.domin = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - else - { - seg1.domout = j; - seg2.domout = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - // seg.s2 = i; - // seg.invs1 = surfaces[i] -> Inverse(); - // seg.invs2 = ! (surfaces[i] -> Inverse()); - } - delete tansol; - } - } - - - if (seg1.domin != -1 || seg1.domout != -1) - { - mesh.AddPoint (p1, layer); - mesh.AddPoint (p2, layer); - seg1.p1 = mesh.GetNP()-1; - seg1.p2 = mesh.GetNP(); - seg2.p2 = mesh.GetNP()-1; - seg2.p1 = mesh.GetNP(); - seg1.geominfo[0].trignum = 1; - seg1.geominfo[1].trignum = 1; - seg2.geominfo[0].trignum = 1; - seg2.geominfo[1].trignum = 1; - mesh.AddSegment (seg1); - mesh.AddSegment (seg2); - - PrintMessage (5, "Add line segment to smooth surface"); - -#ifdef DEVELOP - (*testout) << "Add segment at smooth surface " << i; - if (i != classrep) (*testout) << ", classrep = " << classrep; - (*testout) << ": " - << mesh.Point (mesh.GetNP()-1) << " - " - << mesh.Point (mesh.GetNP()) << endl; -#endif - } - } - } - } - -} diff --git a/Netgen/libsrc/csg/edgeflw_new.cpp b/Netgen/libsrc/csg/edgeflw_new.cpp deleted file mode 100644 index 8aa9f0263b..0000000000 --- a/Netgen/libsrc/csg/edgeflw_new.cpp +++ /dev/null @@ -1,1553 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - -#undef DEVELOP - -namespace netgen -{ - - EdgeCalculation :: - EdgeCalculation (const CSGeometry & ageometry, - ARRAY<SpecialPoint> & aspecpoints) - : geometry(ageometry), specpoints(aspecpoints) - { - Box<3> bbox; - if (specpoints.Size() >= 1) - bbox.Set (specpoints[0].p); - for (int i = 1; i < specpoints.Size(); i++) - bbox.Add (specpoints[i].p); - - searchtree = new Point3dTree (bbox.PMin(), bbox.PMax()); - meshpoint_tree = new Point3dTree (bbox.PMin(), bbox.PMax()); - - for (int i = 0; i < specpoints.Size(); i++) - searchtree->Insert (specpoints[i].p, i); - } - - EdgeCalculation :: ~EdgeCalculation() - { - delete searchtree; - delete meshpoint_tree; - } - - - void EdgeCalculation :: Calc(double h, Mesh & mesh) - { - (*testout) << "Find edges" << endl; - PrintMessage (1, "Find edges"); - PushStatus ("Find edges"); - - CalcEdges1 (h, mesh); - SplitEqualOneSegEdges (mesh); - FindClosedSurfaces (h, mesh); - PrintMessage (3, cntedge, " edges found"); - - for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) - (*testout) << "seg " << si << " = " << mesh[si] << endl; - PopStatus (); - } - - - - - - void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh) - { - ARRAY<int> hsp(specpoints.Size()); - ARRAY<int> glob2hsp(specpoints.Size()); - ARRAY<int> startpoints, endpoints; - - int i, j, k, l, hi, pos, ep, ne; - int layer; - - Vec<3> a1, a2, t, n, m; - Point<3> p, np, pnp, hp; - - Segment seg; - int pi1, s1, s2; - int lastpi, thispi; - - ARRAY<Point<3> > edgepoints; - ARRAY<double> curvelength; - int copyedge, copyfromedge, copyedgeidentification; - - ARRAY<int> locsurfind, locind; - - double len, corr, lam; - double steplen, cursteplen, loch, hd; - - int checkedcopy = 0; - - double size = geometry.MaxSize(); // globflags.GetNumFlag ("maxsize", 500); - double epspointdist2 = size * 1e-6; // globflags.GetNumFlag ("epspointdist", size * 1e-6); - epspointdist2 = sqr (epspointdist2); - - - - Solid * locsol; - - - // copy special points to work with - for (i = 0; i < specpoints.Size(); i++) - { - hsp[i] = i; - glob2hsp[i] = i; - } - - - cntedge = 0; - - while (hsp.Size()) - { - SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size()); - - edgepoints.SetSize (0); - curvelength.SetSize (0); - - - pi1 = 0; - copyedge = 0; - // identifyable point available ? - - // (*testout) << endl; - - for (i = 1; i <= geometry.identifications.Size() && !pi1; i++) - { - for (j = checkedcopy+1; j <= startpoints.Size() && !pi1; j++) - { - - if (geometry.identifications.Get(i)->IdentifyableCandidate (specpoints[startpoints.Get(j)])) - - { - int pi1cand = 0; - double mindist = 1e10; - - for (k = 1; k <= hsp.Size() && !pi1; k++) - { -#ifdef DEVELOP - (*testout) << "check kand = " << hsp.Get(k).p - << ", v = " << hsp.Get(k).v - << endl; -#endif - if (geometry.identifications.Get(i) - ->Identifyable(specpoints[startpoints.Get(j)], specpoints[hsp.Get(k)]) || - geometry.identifications.Get(i) - ->Identifyable(specpoints[hsp.Get(k)], specpoints[startpoints.Get(j)])) - { - -#ifdef DEVELOP - (*testout) << "identifiable, dist = " - << Dist (startpoints.Get(j).p, hsp.Get(k).p) << endl; -#endif - - if (Dist (specpoints[startpoints.Get(j)].p, specpoints[hsp.Get(k)].p) < mindist) - { - mindist = Dist (specpoints[startpoints.Get(j)].p, specpoints[hsp.Get(k)].p); - pi1cand = k; - } - /* - pi1 = k; - copyedge = 1; - copyfromedge = j; - copyedgeidentification = i; - - (*testout) << "copy edge startpoint from " - << startpoints.Get(j).p << " - " - << startpoints.Get(j).v - << " to " - << hsp.Get(k).p << " - " << hsp.Get(k).v << endl; - */ - } - } - - if (pi1cand) - { - pi1 = pi1cand; - copyedge = 1; - copyfromedge = j; - copyedgeidentification = i; -#ifdef DEVELOP - (*testout) << "copy edge startpoint from " - << startpoints.Get(j).p << " - " - << startpoints.Get(j).v - << " to " - << specpoints[hsp.Get(pi1)].p << " - " << hsp.Get(pi1).v << endl; -#endif - } - } - } - } - - - // cannot copy from other ege ? - if (!pi1) - checkedcopy = startpoints.Size(); - - // unconditional special point available ? - if (!pi1) - for (i = 1; i <= hsp.Size(); i++) - if (specpoints[hsp.Get(i)].unconditional == 1) - { - pi1 = i; - break; - } - - - if (!pi1) - { - // only unconditional points available, choose first - pi1 = 1; - } - - layer = specpoints[hsp.Get(pi1)].GetLayer(); - - - if (!specpoints[hsp.Get(pi1)].unconditional) - { - specpoints[hsp.Elem(pi1)].unconditional = 1; - for (i = 1; i <= hsp.Size(); i++) - if (i != pi1 && - Dist (specpoints[hsp.Get(pi1)].p, specpoints[hsp.Get(i)].p) < 1e-8 && - (specpoints[hsp.Get(pi1)].v + specpoints[hsp.Get(i)].v).Length() < 1e-4) - { - // opposite direction - specpoints[hsp.Elem(i)].unconditional = 1; - } - } - - cntedge++; - startpoints.Append (hsp.Get(pi1)); - -#ifdef DEVELOP - (*testout) << "edge nr " << cntedge << endl; - (*testout) << "start followedge: p1 = " << hsp.Get(pi1).p << ", v = " << hsp.Get(pi1).v << endl; -#endif - - FollowEdge (pi1, ep, pos, hsp, h, mesh, - edgepoints, curvelength); - - - if (multithread.terminate) - return; - - if (!ep) - { - // ignore starting point - hsp.DeleteElement (pi1); - cout << "yes, this happens" << endl; - continue; - } - - - - endpoints.Append (hsp.Get(ep)); - - - double elen = 0; - for (i = 1; i <= edgepoints.Size()-1; i++) - elen += Dist (edgepoints.Get(i), edgepoints.Get(i+1)); - - - int shortedge = 0; - for (i = 1; i <= geometry.identifications.Size(); i++) - if (geometry.identifications.Get(i)->ShortEdge(specpoints[hsp.Get(pi1)], specpoints[hsp.Get(ep)])) - shortedge = 1; - // (*testout) << "shortedge = " << shortedge << endl; - - - if (!shortedge) - { - mesh.RestrictLocalHLine (Point3d (specpoints[hsp.Get(pi1)].p), - Point3d (specpoints[hsp.Get(ep)].p), - elen / mparam.segmentsperedge); - } - - s1 = specpoints[hsp.Get(pi1)].s1; - s2 = specpoints[hsp.Get(pi1)].s2; - - - // delete initial, terminal and conditional points - -#ifdef DEVELOP - (*testout) << "terminal point: p = " << hsp.Get(ep).p << ", v = " << hsp.Get(ep).v << endl; -#endif - - searchtree -> DeleteElement (hsp.Get(ep)); - searchtree -> DeleteElement (hsp.Get(pi1)); - - if (ep > pi1) - { - glob2hsp[hsp[ep-1]] = -1; - glob2hsp[hsp.Last()] = ep-1; - hsp.DeleteElement (ep); - - glob2hsp[hsp[pi1-1]] = -1; - glob2hsp[hsp.Last()] = pi1-1; - hsp.DeleteElement (pi1); - } - else - { - glob2hsp[hsp[pi1-1]] = -1; - glob2hsp[hsp.Last()] = pi1-1; - hsp.DeleteElement (pi1); - - glob2hsp[hsp[ep-1]] = -1; - glob2hsp[hsp.Last()] = ep-1; - hsp.DeleteElement (ep); - } - - - for (j = 1; j <= edgepoints.Size()-1; j++) - { - p = edgepoints.Get(j); - np = Center (p, edgepoints.Get(j+1)); - hd = Dist (p, np); - - - Box<3> boxp (np - (1.2 * hd) * Vec<3> (1, 1, 1), - np + (1.2 * hd) * Vec<3> (1, 1, 1)); - searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind); - - for (i = 0; i < locind.Size(); i++) - { - if ( specpoints[locind[i]].HasSurfaces (s1, s2) && - specpoints[locind[i]].unconditional == 0) - { - searchtree -> DeleteElement (locind[i]); - - int li = glob2hsp[locind[i]]; - glob2hsp[locind[i]] = -1; - glob2hsp[hsp.Last()] = li; - hsp.Delete (li); - } - } - - - /* - for (i = 1; i <= hsp.Size(); i++) - if ( specpoints[hsp.Get(i)].HasSurfaces (s1, s2) && - specpoints[hsp.Get(i)].unconditional == 0 && - Dist2 (np, specpoints[hsp.Get(i)].p) < 1.2 * hd) - { - searchtree -> DeleteElement (hsp.Get(i)+1); - hsp.DeleteElement (i); - i--; - } - */ - } - - - ARRAY<Segment> refedges; - ARRAY<int> refedgesinv; - - - AnalyzeEdge (s1, s2, pos, layer, - edgepoints, - refedges, refedgesinv); - - for (i = 1; i <= refedges.Size(); i++) - refedges.Elem(i).edgenr = cntedge; - - -#ifdef DEVELOP - (*testout) << "edge " << cntedge << endl - << "startp: " << startpoints.Last().p - << ", v = " << startpoints.Last().v << endl - << "copy = " << copyedge << endl - << refedges.Size() << " refedges: "; - for (i = 1; i <= refedges.Size(); i++) - (*testout) << " " << refedges.Get(i).si; - (*testout) << endl; - (*testout) << "inv[1] = " << refedgesinv.Get(1) << endl; -#endif - - if (!copyedge) - { - int oldnseg = mesh.GetNSeg(); - - if (!shortedge) - StoreEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - else - StoreShortEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - - - /* - for (i = oldnseg+1; i <= mesh.GetNSeg(); i++) - for (j = 1; j <= oldnseg; j++) - { - const Point<3> & l1p1 = mesh.Point (mesh.LineSegment(i).p1); - const Point<3> & l1p2 = mesh.Point (mesh.LineSegment(i).p2); - const Point<3> & l2p1 = mesh.Point (mesh.LineSegment(j).p1); - const Point<3> & l2p2 = mesh.Point (mesh.LineSegment(j).p2); - Vec<3> vl1(l1p1, l1p2); - for (double lamk = 0; lamk <= 1; lamk += 0.1) - { - Point<3> l2p = l1p1 + lamk * vl1; - double dist = sqrt (MinDistLP2 (l2p1, l2p2, l2p)); - if (dist > 1e-12) - mesh.RestrictLocalH (l2p, 3*dist); - } - } - */ - } - else - { - CopyEdge (refedges, refedgesinv, - copyfromedge, - specpoints[startpoints.Get(copyfromedge)].p, - specpoints[endpoints.Get(copyfromedge)].p, - edgepoints.Get(1), edgepoints.Last(), - copyedgeidentification, - layer, - mesh); - } - - } - } - - - - /* - If two or more edges share the same initial and end-points, - then they need at least two segments - */ - void EdgeCalculation :: - SplitEqualOneSegEdges (Mesh & mesh) - { - int i, j; - SegmentIndex si; - PointIndex pi; - - ARRAY<int> osedges(cntedge); - INDEX_2_HASHTABLE<int> osedgesht (cntedge+1); - - osedges = 2; - - // count segments on edges - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - osedges.Elem(seg.edgenr)--; - } - - (*testout) << "osedges = " << osedges << endl; - - // flag one segment edges - for (i = 0; i < cntedge; i++) - osedges[i] = (osedges[i] > 0) ? 1 : 0; - - (*testout) << "osedges, now = " << osedges << endl; - - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr)) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2)) - osedgesht.Set (i2, 2); - else - osedgesht.Set (i2, 1); - } - } - } - - - // one edge 1 segment, other 2 segments - // yes, it happens ! - - for (i = 1; i <= osedgesht.GetNBags(); i++) - for (j = 1; j <= osedgesht.GetBagSize(i); j++) - { - INDEX_2 i2; - int val; - osedgesht.GetData (i, j, i2, val); - - const Point<3> & p1 = mesh[PointIndex(i2.I1())]; - const Point<3> & p2 = mesh[PointIndex(i2.I2())]; - Vec<3> v = p2 - p1; - double vlen = v.Length(); - v /= vlen; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (pi != i2.I1() && pi != i2.I2()) - { - const Point<3> & p = mesh[pi]; - Vec<3> v2 = p - p1; - double lam = (v2 * v); - if (lam > 0 && lam < vlen) - { - Point<3> hp = p1 + lam * v; - if (Dist (p, hp) < 1e-4 * vlen) - { - PrintSysError ("Point on edge !!!"); - cout << "seg: " << i2 << ", p = " << pi << endl; - osedgesht.Set (i2, 2); - } - } - } - } - - - // insert new points - osedges = -1; - - int nseg = mesh.GetNSeg(); - for (si = 0; si < nseg; si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2) && - osedgesht.Get (i2) == 2 && - osedges.Elem(seg.edgenr) == -1) - { - Point<3> newp = Center (mesh[PointIndex(seg.p1)], - mesh[PointIndex(seg.p2)]); - - ProjectToEdge (geometry.GetSurface(seg.surfnr1), - geometry.GetSurface(seg.surfnr2), - newp); - - osedges.Elem(seg.edgenr) = - mesh.AddPoint (newp, mesh[PointIndex(seg.p1)].GetLayer()); - meshpoint_tree -> Insert (newp, osedges.Elem(seg.edgenr)); - } - } - } - - - for (i = 1; i <= nseg; i++) - { - Segment & seg = mesh.LineSegment (i); - if (seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr) != -1) - { - Segment newseg = seg; - newseg.p1 = osedges.Get(seg.edgenr); - seg.p2 = osedges.Get(seg.edgenr); - mesh.AddSegment (newseg); - } - } - } - - } - - - - void EdgeCalculation :: - FollowEdge (int pi1, int & ep, int & pos, - const ARRAY<int> & hsp, - double h, const Mesh & mesh, - ARRAY<Point<3> > & edgepoints, - ARRAY<double> & curvelength) - { - int i, j, s1, s2; - double len, steplen, cursteplen, loch; - Point<3> p, np, pnp; - Vec<3> a1, a2, t; - - ARRAY<int> locind; - - double size = geometry.MaxSize(); - double epspointdist2 = size * 1e-6; - epspointdist2 = sqr (epspointdist2); - int uselocalh = mparam.uselocalh; - - - s1 = specpoints[hsp.Get(pi1)].s1; - s2 = specpoints[hsp.Get(pi1)].s2; - - p = specpoints[hsp.Get(pi1)].p; - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - - t = Cross (a1, a2); - t.Normalize(); - - pos = (specpoints[hsp.Get(pi1)].v * t) > 0; - if (!pos) t *= -1; - - - edgepoints.Append (p); - curvelength.Append (0); - len = 0; - - loch = min2 (geometry.GetSurface(s1) -> LocH (p, 3, 1, h), - geometry.GetSurface(s2) -> LocH (p, 3, 1, h)); - - - - if (uselocalh) - { - double lh = mesh.GetH(p); - if (lh < loch) - loch = lh; - } - - steplen = 0.1 * loch; - - do - { - if (multithread.terminate) - return; - - if (fabs (p(0)) + fabs (p(1)) + fabs (p(2)) > 10000) - { - ep = 0; - PrintWarning ("Give up line"); - break; - } - - if (steplen > 0.1 * loch) steplen = 0.1 * loch; - - steplen *= 2; - do - { - steplen *= 0.5; - np = p + steplen * t; - pnp = np; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), pnp); - } - while (Dist (np, pnp) > 0.1 * steplen); - - cursteplen = steplen; - if (Dist (np, pnp) < 0.01 * steplen) steplen *= 2; - - - np = pnp; - -#ifdef MYGRAPH - if (silentflag <= 2) - { - MyLine3D (p, np, rot); - MyDraw (); - } -#endif - - ep = 0; - - double hvtmin = 1.5 * cursteplen; - - Box<3> boxp (p - (2 * cursteplen) * Vec<3> (1, 1, 1), - p + (2 * cursteplen) * Vec<3> (1, 1, 1)); - - searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind); - - for (i = 0; i < locind.Size(); i++) - { - Vec<3> hv = specpoints[locind[i]].p - p; - if (hv.Length2() > 9 * cursteplen * cursteplen) - continue; - - double hvt = hv * t; - hv -= hvt * t; - - if (hv.Length() < 0.2 * cursteplen && - hvt > 0 && - // hvt < 1.5 * cursteplen && - hvt < hvtmin && - specpoints[locind[i]].unconditional == 1 && - (specpoints[locind[i]].v + t).Length() < 0.4 ) - { - Point<3> hep = specpoints[locind[i]].p; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), hep); - - - if (Dist2 (hep, specpoints[locind[i]].p) < epspointdist2 ) - { - geometry.GetSurface(s1) -> CalcGradient (hep, a1); - geometry.GetSurface(s2) -> CalcGradient (hep, a2); - Vec<3> ept = Cross (a1, a2); - ept /= ept.Length(); - if (!pos) ept *= -1; - - if ( (specpoints[locind[i]].v + ept).Length() < 1e-4 ) - { - np = specpoints[locind[i]].p; - - for (int jj = 0; jj < hsp.Size(); jj++) - if (hsp[jj] == locind[i]) - ep = jj+1; - - if (!ep) - cerr << "endpoint not found" << endl; - // ep = i; - hvtmin = hvt; - // break; - } - } - } - } - - - - - /* - for (i = 1; i <= hsp.Size(); i++) - { - if (!boxp.IsIn (specpoints[hsp.Get(i)].p)) - continue; - - Vec<3> hv = specpoints[hsp.Get(i)].p - p; - if (hv.Length2() > 9 * cursteplen * cursteplen) - continue; - - double hvt = hv * t; - hv -= hvt * t; - - if (hv.Length() < 0.2 * cursteplen && - hvt > 0 && - // hvt < 1.5 * cursteplen && - hvt < hvtmin && - specpoints[hsp.Get(i)].unconditional == 1 && - (specpoints[hsp.Get(i)].v + t).Length() < 0.4 ) - { - Point<3> hep = specpoints[hsp.Get(i)].p; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), hep); - - - if (Dist2 (hep, specpoints[hsp.Get(i)].p) < epspointdist2 ) - { - geometry.GetSurface(s1) -> CalcGradient (hep, a1); - geometry.GetSurface(s2) -> CalcGradient (hep, a2); - Vec<3> ept = Cross (a1, a2); - ept /= ept.Length(); - if (!pos) ept *= -1; - - if ( (specpoints[hsp.Get(i)].v + ept).Length() < 1e-4 ) - { - np = specpoints[hsp.Get(i)].p; - ep = i; - hvtmin = hvt; - // break; - } - } - } - } - */ - - loch = min2 (geometry.GetSurface(s1) -> LocH (np, 3, 1, h), - geometry.GetSurface(s2) -> LocH (np, 3, 1, h)); - - if (uselocalh) - { - double lh = mesh.GetH(np); - if (lh < loch) - loch = lh; - } - - - len += Dist (p, np) / loch; - edgepoints.Append (np); - curvelength.Append (len); - - p = np; - - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - } - while (! ep); - } - - - - - - - - void EdgeCalculation :: - AnalyzeEdge (int s1, int s2, int pos, int layer, - const ARRAY<Point<3> > & edgepoints, - ARRAY<Segment> & refedges, - ARRAY<int> & refedgesinv) - { - int i, j, k, l; - int hi; - Point<3> hp; - Vec<3> t, a1, a2, m, n; - Segment seg; - Solid * locsol; - ARRAY<int> locsurfind; - - /* - int pi1 = 0, pi2 = 0; - extern Mesh * mesh; - for (i = 1; i <= mesh->GetNP(); i++) - { - if (Dist2 (edgepoints.Get(1), mesh->Point(i)) < 1e-12) - pi1 = i; - if (Dist2 (edgepoints.Last(), mesh->Point(i)) < 1e-12) - pi2 = i; - } - (*testout) << "Analyze edge: " << pi1 << " - " << pi2 << ", pts = " << edgepoints.Size() << endl; - (*testout) << "p1 = " << edgepoints.Get(1) << " pl = " << edgepoints.Last() << endl; - */ - int debug = 0; - /* - Dist2 (Point<3> (2.69642, 1.1866, 2.03), edgepoints.Get(1)) < 1e-6 || - Dist2 (Point<3> (2.69642, 1.1866, 2.03), edgepoints.Last()) < 1e-6; - */ - - if (debug) - { - // (*testout) << "tubious edge !!!" << endl; - (*testout) << "s1, s2 = " << s1 << " - " << s2 << endl; - } - - refedges.SetSize(0); - refedgesinv.SetSize(0); - hp = Center (edgepoints.Get(1), edgepoints.Get(2)); - ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp); - - geometry.GetSurface(s1) -> CalcGradient (hp, a1); - geometry.GetSurface(s2) -> CalcGradient (hp, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - - (*testout) << "t = " << t << endl; - - for (i = 0; i < geometry.GetNTopLevelObjects(); i++) - { - (*testout) << "layer = " << layer - << ", tlo-layer = " << geometry.GetTopLevelObject(i)->GetLayer() << endl; - if (geometry.GetTopLevelObject(i)->GetLayer() != layer) - continue; - - const Solid * sol = geometry.GetTopLevelObject(i)->GetSolid(); - const Surface * surf = geometry.GetTopLevelObject(i)->GetSurface(); - - sol -> TangentialSolid (hp, locsol); - if (!locsol) continue; - - BoxSphere<3> boxp (hp, hp); - boxp.Increase (1e-5); - boxp.CalcDiamCenter(); - - ReducePrimitiveIterator rpi(boxp); - UnReducePrimitiveIterator urpi; - - ((Solid*)locsol) -> IterateSolid (rpi); - - locsol -> CalcSurfaceInverse (); - - - if (!surf) - { - locsol -> GetSurfaceIndices (locsurfind); - } - else - { - /* - if (fabs (surf->CalcFunctionValue (hp)) < 1e-6) - continue; - */ - locsurfind.SetSize(1); - locsurfind[0] = -1; - for (j = 0; j < geometry.GetNSurf(); j++) - if (geometry.GetSurface(j) == surf) - { - locsurfind[0] = j; - // geometry.GetSurfaceClassRepresentant(j); - break; - } - } - - ((Solid*)locsol) -> IterateSolid (urpi); - - - if (debug) - (*testout) << "edge of tlo " << i << ", has " << locsurfind.Size() << " faces." << endl; - - - for (j = locsurfind.Size()-1; j >= 0; j--) - if (fabs (geometry.GetSurface(locsurfind[j]) - ->CalcFunctionValue (hp) ) > 1e-6) - locsurfind.DeleteElement(j+1); - - if (debug) - (*testout) << locsurfind.Size() << " faces on hp" << endl; - - for (j = 0; j < locsurfind.Size(); j++) - { - int lsi = locsurfind[j]; - int rlsi = geometry.GetSurfaceClassRepresentant(lsi); - - Vec<3> rn; - - // n is outer normal to solid - geometry.GetSurface(lsi) -> GetNormalVector (hp, n); - if (geometry.GetSurface (lsi)->Inverse()) - n *= -1; - - if (fabs (t * n) > 1e-4) continue; - if (debug) - { - (*testout) << "face " << locsurfind.Get(j) << ", rep = " << rlsi - << " has (t*n) = " << (t*n) << endl; - (*testout) << "n = " << n << endl; - } - - // rn is normal to class representant - geometry.GetSurface(rlsi) -> GetNormalVector (hp, rn); - - int sameasref = ((n * rn) > 0); - - m = Cross (t, rn); - m.Normalize(); - - - for (k = 1; k <= 2; k ++) - { - bool edgeinv = (k == 2); - - if (debug) - { - (*testout) << "onface(" << hp << ", " << m << ")= " - << locsol->OnFace (hp, m); - (*testout) << " vec2in = " - << locsol -> VectorIn2 (hp, m, n) << " and " - << locsol -> VectorIn2 (hp, m, -1 * n) << endl; - } - - // if (locsol -> OnFace (hp, m)) - if (locsol -> VectorIn2 (hp, m, n) == 0 && - locsol -> VectorIn2 (hp, m, -1 * n) == 1) - { - hi = 0; - for (l = 1; l <= refedges.Size(); l++) - { - if (refedges.Get(l).si == rlsi && - refedgesinv.Get(l) == edgeinv) - hi = l; - } - - if (!hi) - { - seg.si = rlsi; - seg.domin = -1; - seg.domout = -1; - seg.tlosurf = -1; - seg.surfnr1 = s1; - seg.surfnr2 = s2; - hi = refedges.Append (seg); - refedgesinv.Append (edgeinv); - } - - if (!surf) - { - if (sameasref) - refedges.Elem(hi).domin = i; - else - refedges.Elem(hi).domout = i; - } - else - refedges.Elem(hi).tlosurf = i; - - if (debug) - (*testout) << "add ref seg:" - << "si = " << refedges.Get(hi).si - << ", domin = " << refedges.Get(hi).domin - << ", domout = " << refedges.Get(hi).domout - << ", surfnr1/2 = " << refedges.Get(hi).surfnr1 - << ", " << refedges.Get(hi).surfnr2 - << ", inv = " << refedgesinv.Get(hi) - << ", refedgenr = " << hi - << endl; - } - m *= -1; - } - } - delete locsol; - } - } - - - - void EdgeCalculation :: - StoreEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - - double len, corr, lam; - PointIndex thispi, lastpi; - Point<3> p, np; - Segment seg; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints.Get(1), edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - - // generate initial point - p = edgepoints.Get(1); - lastpi = -1; - - /* - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist (mesh[pi], p) < 1e-6) - { - lastpi = pi; - break; - } - */ - ARRAY<int> locsearch; - meshpoint_tree -> GetIntersecting (p-Vec<3> (1e-6, 1e-6, 1e-6), - p+Vec<3> (1e-6, 1e-6, 1e-6), locsearch); - if (locsearch.Size()) - lastpi = locsearch[0]; - - - - if (lastpi == -1) - { - lastpi = mesh.AddPoint (p, layer); - meshpoint_tree -> Insert (p, lastpi); - } - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength.Get(j) < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength.Get(j-1)) / - (curvelength.Get(j) - curvelength.Get(j-1)); - - np(0) = (1-lam) * edgepoints.Get(j-1)(0) + lam * edgepoints.Get(j)(0); - np(1) = (1-lam) * edgepoints.Get(j-1)(1) + lam * edgepoints.Get(j)(1); - np(2) = (1-lam) * edgepoints.Get(j-1)(2) + lam * edgepoints.Get(j)(2); - - - thispi = -1; - if (i == ne) - { - /* - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist(mesh[pi], np) < 1e-6) - thispi = pi; - */ - - meshpoint_tree -> GetIntersecting (np-Vec<3> (1e-6, 1e-6, 1e-6), - np+Vec<3> (1e-6, 1e-6, 1e-6), locsearch); - if (locsearch.Size()) - thispi = locsearch[0]; - } - - if (thispi == -1) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np, layer); - meshpoint_tree -> Insert (np, thispi); - } - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = lastpi; - seg.p2 = thispi; - } - else - { - seg.p1 = thispi; - seg.p2 = lastpi; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - - double maxh = min2 (geometry.GetSurface(seg.surfnr1)->GetMaxH(), - geometry.GetSurface(seg.surfnr2)->GetMaxH()); - - if (seg.domin != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domin) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domin)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.domout != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domout) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domout)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.tlosurf != -1) - { - double hi = geometry.GetTopLevelObject(seg.tlosurf) -> GetMaxH(); - maxh = min2 (maxh, hi); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - } - - p = np; - lastpi = thispi; - } - -#ifdef DEVELOP - (*testout) << " eplast = " << lastpi << " = " << p << endl; -#endif - } - - - - - - - void EdgeCalculation :: - StoreShortEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - Segment seg; - - /* - double len, corr, lam; - int thispi, lastpi; - Point<3> p, np; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints[1], edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - */ - - // generate initial point - Point<3> p = edgepoints[0]; - PointIndex pi1 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi1 = pi; - break; - } - - if (pi1 == -1) - { - pi1 = mesh.AddPoint (p, layer); - meshpoint_tree -> Insert (p, pi1); - } - - p = edgepoints.Last(); - PointIndex pi2 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi2 = pi; - break; - } - if (pi2==-1) - { - pi2 = mesh.AddPoint (p, layer); - meshpoint_tree -> Insert (p, pi2); - } - - /* - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength[j] < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength[j-1]) / - (curvelength[j] - curvelength[j-1]); - - np(0) = (1-lam) * edgepoints[j-1](0) + lam * edgepoints[j](0); - np(1) = (1-lam) * edgepoints[j-1](1) + lam * edgepoints[j](1); - np(2) = (1-lam) * edgepoints[j-1](2) + lam * edgepoints[j](2); - - - thispi = 0; - if (i == ne) - for (j = 1; j <= mesh.GetNP(); j++) - if (Dist(mesh.Point(j), np) < 1e-6) - thispi = j; - - if (!thispi) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np); - } - */ - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = pi1; - seg.p2 = pi2; - } - else - { - seg.p1 = pi2; - seg.p2 = pi1; - } - - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - } - } - - - - - - - - void EdgeCalculation :: - CopyEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - int copyfromedge, - const Point<3> & fromstart, const Point<3> & fromend, - const Point<3> & tostart, const Point<3> & toend, - int copyedgeidentification, - int layer, - Mesh & mesh) - { - int i, j, k; - PointIndex pi; - - // copy start and end points - for (i = 1; i <= 2; i++) - { - Point<3> fromp = - (i == 1) ? fromstart : fromend; - Point<3> top = - (i == 1) ? tostart : toend; - - PointIndex frompi = -1; - PointIndex topi = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - if (Dist2 (mesh[pi], fromp) <= 1e-16) - frompi = pi; - if (Dist2 (mesh[pi], top) <= 1e-16) - topi = pi; - } - - if (topi == -1) - { - topi = mesh.AddPoint (top, layer); - meshpoint_tree -> Insert (top, topi); - } - - const Identification & csi = - (*geometry.identifications.Get(copyedgeidentification)); - - if (csi.Identifyable (mesh[frompi], mesh[topi])) - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - else if (csi.Identifyable (mesh[topi], mesh[frompi])) - mesh.GetIdentifications().Add(topi, frompi, copyedgeidentification); - else - { - cerr << "edgeflw.cpp: should identify, but cannot"; - exit(1); - } - /* - (*testout) << "Add Identification from CopyEdge, p1 = " - << mesh[PointIndex(frompi)] << ", p2 = " - << mesh[PointIndex(topi)] << endl; - - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - */ - } - - int oldns = mesh.GetNSeg(); - for (i = 1; i <= oldns; i++) - { - // real copy, since array might be reallocated !! - const Segment oldseg = mesh.LineSegment(i); - if (oldseg.edgenr != copyfromedge) - continue; - if (oldseg.seginfo == 0) - continue; - - int pi1 = oldseg.p1; - int pi2 = oldseg.p2; - - int npi1 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi1); - int npi2 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi2); - - Segment seg; - - for (k = 1; k <= refedges.Size(); k++) - { - int inv = refedgesinv.Get(k); - - // other edge is inverse - if (oldseg.seginfo == 1) - inv = !inv; - - // (*testout) << "inv, now = " << inv << endl; - - if (inv) - { - seg.p1 = npi1; - seg.p2 = npi2; - } - else - { - seg.p1 = npi2; - seg.p2 = npi1; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = refedgesinv.Get(k) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "copy seg " << seg.p1 << "-" << seg.p2 << endl; -#ifdef DEVELOP - - (*testout) << "copy seg, face = " << seg.si << ": " - << " inv = " << inv << ", refinv = " << refedgesinv.Get(k) - << mesh.Point(seg.p1) << ", " << mesh.Point(seg.p2) << endl; -#endif - - } - - } - } - - - - - - - - void EdgeCalculation :: - FindClosedSurfaces (double h, Mesh & mesh) - { - // if there is no special point at a sphere, one has to add a segment pair - - int i, j; - int nsol; - int nsurf = geometry.GetNSurf(); - int layer; - - BitArray pointatsurface (nsurf); - Point<3> p1, p2; - Vec<3> nv, tv; - Solid * tansol; - ARRAY<int> tansurfind; - // const Solid * sol; - - nsol = geometry.GetNTopLevelObjects(); - - - pointatsurface.Clear(); - - /* - for (i = 1; i <= specpoints.Size(); i++) - { - int classrep; - - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s1); - pointatsurface.Set (classrep); - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s2); - pointatsurface.Set (classrep); - // pointatsurface.Set (specpoints[i].s1); - // pointatsurface.Set (specpoints[i].s2); - } - */ - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - int classrep; - -#ifdef DEVELOP - (*testout) << seg.surfnr1 << ", " << seg.surfnr2 << ", si = " << seg.si << endl; -#endif - classrep = geometry.GetSurfaceClassRepresentant (seg.si); - - pointatsurface.Set (classrep); - } - - - for (i = 0; i < nsurf; i++) - { - int classrep = geometry.GetSurfaceClassRepresentant (i); - - if (!pointatsurface.Test(classrep)) - { - const Surface * s = geometry.GetSurface(i); - p1 = s -> GetSurfacePoint(); - s -> GetNormalVector (p1, nv); - - double hloc = - min2 (s->LocH (p1, 3, 1, h), mesh.GetH(p1)); - - tv = nv.GetNormal (); - tv *= (hloc / tv.Length()); - p2 = p1 + tv; - s->Project (p2); - - - Segment seg1; - seg1.si = i; - seg1.domin = -1; - seg1.domout = -1; - - Segment seg2; - seg2.si = i; - seg2.domin = -1; - seg2.domout = -1; - - seg1.surfnr1 = i; - seg2.surfnr1 = i; - seg1.surfnr2 = i; - seg2.surfnr2 = i; - - for (j = 0; j < nsol; j++) - { - if (geometry.GetTopLevelObject(j)->GetSurface()) - continue; - - const Solid * sol = geometry.GetTopLevelObject(j)->GetSolid(); - sol -> TangentialSolid (p1, tansol); - layer = geometry.GetTopLevelObject(j)->GetLayer(); - - if (tansol) - { - tansol -> GetSurfaceIndices (tansurfind); - - if (tansurfind.Size() == 1 && tansurfind.Get(1) == i) - { - if (!tansol->VectorIn(p1, nv)) - { - seg1.domin = j; - seg2.domin = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - else - { - seg1.domout = j; - seg2.domout = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - // seg.s2 = i; - // seg.invs1 = surfaces[i] -> Inverse(); - // seg.invs2 = ! (surfaces[i] -> Inverse()); - } - delete tansol; - } - } - - - if (seg1.domin != -1 || seg1.domout != -1) - { - mesh.AddPoint (p1, layer); - mesh.AddPoint (p2, layer); - seg1.p1 = mesh.GetNP()-1; - seg1.p2 = mesh.GetNP(); - seg2.p2 = mesh.GetNP()-1; - seg2.p1 = mesh.GetNP(); - seg1.geominfo[0].trignum = 1; - seg1.geominfo[1].trignum = 1; - seg2.geominfo[0].trignum = 1; - seg2.geominfo[1].trignum = 1; - mesh.AddSegment (seg1); - mesh.AddSegment (seg2); - - PrintMessage (5, "Add line segment to smooth surface"); - -#ifdef DEVELOP - (*testout) << "Add segment at smooth surface " << i; - if (i != classrep) (*testout) << ", classrep = " << classrep; - (*testout) << ": " - << mesh.Point (mesh.GetNP()-1) << " - " - << mesh.Point (mesh.GetNP()) << endl; -#endif - } - } - } - } - -} diff --git a/Netgen/libsrc/csg/edgeflw_old.cpp b/Netgen/libsrc/csg/edgeflw_old.cpp deleted file mode 100644 index 5321dfd17d..0000000000 --- a/Netgen/libsrc/csg/edgeflw_old.cpp +++ /dev/null @@ -1,1405 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - -#undef DEVELOP - -namespace netgen -{ - - EdgeCalculation :: - EdgeCalculation (const CSGeometry & ageometry, - ARRAY<SpecialPoint> & aspecpoints) - : geometry(ageometry), specpoints(aspecpoints) - { - ; - } - - EdgeCalculation :: ~EdgeCalculation () - { ; } - - void EdgeCalculation :: Calc(double h, Mesh & mesh) - { - PrintMessage (1, "Find edges"); - PushStatus ("Find edges"); - - CalcEdges1 (h, mesh); - SplitEqualOneSegEdges (mesh); - FindClosedSurfaces (h, mesh); - PrintMessage (3, cntedge, " edges found"); - - PopStatus (); - } - - - - - void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh) - { - ARRAY<SpecialPoint> hsp(specpoints.Size()); - ARRAY<SpecialPoint> startpoints, endpoints; - - int i, j, k, l, hi, pos, ep, ne; - int layer; - - Vec<3> a1, a2, t, n, m; - Point<3> p, np, pnp, hp; - - Segment seg; - int pi1, s1, s2; - int lastpi, thispi; - - ARRAY<Point<3> > edgepoints; - ARRAY<double> curvelength; - int copyedge, copyfromedge, copyedgeidentification; - - ARRAY<int> locsurfind; - - double len, corr, lam; - double steplen, cursteplen, loch, hd; - - int checkedcopy = 0; - - double size = geometry.MaxSize(); // globflags.GetNumFlag ("maxsize", 500); - double epspointdist2 = size * 1e-6; // globflags.GetNumFlag ("epspointdist", size * 1e-6); - epspointdist2 = sqr (epspointdist2); - - - Solid * locsol; - - - // copy special points to work with - for (i = 0; i < specpoints.Size(); i++) - hsp[i] = specpoints[i]; - - - cntedge = 0; - - while (hsp.Size()) - { - SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size()); - - edgepoints.SetSize (0); - curvelength.SetSize (0); - - - pi1 = 0; - copyedge = 0; - // identifyable point available ? - - // (*testout) << endl; - - for (i = 1; i <= geometry.identifications.Size() && !pi1; i++) - { - for (j = checkedcopy+1; j <= startpoints.Size() && !pi1; j++) - { - - if (geometry.identifications.Get(i)->IdentifyableCandidate (startpoints.Get(j))) - - { - int pi1cand = 0; - double mindist = 1e10; - - for (k = 1; k <= hsp.Size() && !pi1; k++) - { -#ifdef DEVELOP - (*testout) << "check kand = " << hsp.Get(k).p - << ", v = " << hsp.Get(k).v - << endl; -#endif - if (geometry.identifications.Get(i) - ->Identifyable(startpoints.Get(j), hsp.Get(k)) || - geometry.identifications.Get(i) - ->Identifyable(hsp.Get(k), startpoints.Get(j))) - { - -#ifdef DEVELOP - (*testout) << "identifiable, dist = " - << Dist (startpoints.Get(j).p, hsp.Get(k).p) << endl; -#endif - - if (Dist (startpoints.Get(j).p, hsp.Get(k).p) < mindist) - { - mindist = Dist (startpoints.Get(j).p, hsp.Get(k).p); - pi1cand = k; - } - /* - pi1 = k; - copyedge = 1; - copyfromedge = j; - copyedgeidentification = i; - - (*testout) << "copy edge startpoint from " - << startpoints.Get(j).p << " - " - << startpoints.Get(j).v - << " to " - << hsp.Get(k).p << " - " << hsp.Get(k).v << endl; - */ - } - } - - if (pi1cand) - { - pi1 = pi1cand; - copyedge = 1; - copyfromedge = j; - copyedgeidentification = i; -#ifdef DEVELOP - (*testout) << "copy edge startpoint from " - << startpoints.Get(j).p << " - " - << startpoints.Get(j).v - << " to " - << hsp.Get(pi1).p << " - " << hsp.Get(pi1).v << endl; -#endif - } - } - } - } - - - // cannot copy from other ege ? - if (!pi1) - checkedcopy = startpoints.Size(); - - // unconditional special point available ? - if (!pi1) - for (i = 1; i <= hsp.Size() && pi1 == 0; i++) - if (hsp.Get(i).unconditional == 1) - pi1 = i; - - - if (!pi1) - { - // only unconditional points available, choose first - pi1 = 1; - } - - layer = hsp.Get(pi1).GetLayer(); - - - if (!hsp.Get(pi1).unconditional) - { - hsp.Elem(pi1).unconditional = 1; - for (i = 1; i <= hsp.Size(); i++) - if (i != pi1 && Dist (hsp.Get(pi1).p, hsp.Get(i).p) < 1e-8 && - (hsp.Get(pi1).v + hsp.Get(i).v).Length() < 1e-4) - { - // opposite direction - hsp.Elem(i).unconditional = 1; - } - } - - cntedge++; - startpoints.Append (hsp.Get(pi1)); - -#ifdef DEVELOP - (*testout) << "edge nr " << cntedge << endl; - (*testout) << "start followedge: p1 = " << hsp.Get(pi1).p << ", v = " << hsp.Get(pi1).v << endl; -#endif - - FollowEdge (pi1, ep, pos, hsp, h, mesh, - edgepoints, curvelength); - - - if (multithread.terminate) - return; - - if (!ep) - { - // ignore starting point - hsp.DeleteElement (pi1); - continue; - } - - - - endpoints.Append (hsp.Get(ep)); - - - double elen = 0; - for (i = 1; i <= edgepoints.Size()-1; i++) - elen += Dist (edgepoints.Get(i), edgepoints.Get(i+1)); - - - int shortedge = 0; - for (i = 1; i <= geometry.identifications.Size(); i++) - if (geometry.identifications.Get(i)->ShortEdge(hsp.Get(pi1), hsp.Get(ep))) - shortedge = 1; - (*testout) << "shortedge = " << shortedge << endl; - - - if (!shortedge) - { - mesh.RestrictLocalHLine (Point3d (hsp.Get(pi1).p), - Point3d (hsp.Get(ep).p), - elen / mparam.segmentsperedge); - } - - s1 = hsp.Get(pi1).s1; - s2 = hsp.Get(pi1).s2; - - - // delete initial, terminal and conditional points - -#ifdef DEVELOP - (*testout) << "terminal point: p = " << hsp.Get(ep).p << ", v = " << hsp.Get(ep).v << endl; -#endif - if (ep > pi1) - { - hsp.DeleteElement (ep); - hsp.DeleteElement (pi1); - } - else - { - hsp.DeleteElement (pi1); - hsp.DeleteElement (ep); - } - - - for (j = 1; j <= edgepoints.Size()-1; j++) - { - p = edgepoints.Get(j); - np = Center (p, edgepoints.Get(j+1)); - hd = Dist2 (p, np); - - for (i = 1; i <= hsp.Size(); i++) - if ( hsp.Get(i).HasSurfaces (s1, s2) && - hsp.Get(i).unconditional == 0 && - Dist2 (np, hsp.Get(i).p) < 1.2 * hd) - { - hsp.DeleteElement (i); - i--; - } - } - - - ARRAY<Segment> refedges; - ARRAY<int> refedgesinv; - - - AnalyzeEdge (s1, s2, pos, layer, - edgepoints, - refedges, refedgesinv); - - for (i = 1; i <= refedges.Size(); i++) - refedges.Elem(i).edgenr = cntedge; - - -#ifdef DEVELOP - (*testout) << "edge " << cntedge << endl - << "startp: " << startpoints.Last().p - << ", v = " << startpoints.Last().v << endl - << "copy = " << copyedge << endl - << refedges.Size() << " refedges: "; - for (i = 1; i <= refedges.Size(); i++) - (*testout) << " " << refedges.Get(i).si; - (*testout) << endl; - (*testout) << "inv[1] = " << refedgesinv.Get(1) << endl; -#endif - - if (!copyedge) - { - int oldnseg = mesh.GetNSeg(); - - if (!shortedge) - StoreEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - else - StoreShortEdge (refedges, refedgesinv, - edgepoints, curvelength, layer, mesh); - - - /* - for (i = oldnseg+1; i <= mesh.GetNSeg(); i++) - for (j = 1; j <= oldnseg; j++) - { - const Point<3> & l1p1 = mesh.Point (mesh.LineSegment(i).p1); - const Point<3> & l1p2 = mesh.Point (mesh.LineSegment(i).p2); - const Point<3> & l2p1 = mesh.Point (mesh.LineSegment(j).p1); - const Point<3> & l2p2 = mesh.Point (mesh.LineSegment(j).p2); - Vec<3> vl1(l1p1, l1p2); - for (double lamk = 0; lamk <= 1; lamk += 0.1) - { - Point<3> l2p = l1p1 + lamk * vl1; - double dist = sqrt (MinDistLP2 (l2p1, l2p2, l2p)); - if (dist > 1e-12) - mesh.RestrictLocalH (l2p, 3*dist); - } - } - */ - } - else - { - CopyEdge (refedges, refedgesinv, - copyfromedge, - startpoints.Get(copyfromedge).p, - endpoints.Get(copyfromedge).p, - edgepoints.Get(1), edgepoints.Last(), - copyedgeidentification, - layer, - mesh); - } - - } - } - - - - /* - If two or more edges share the same initial and end-points, - then they need at least two segments - */ - void EdgeCalculation :: - SplitEqualOneSegEdges (Mesh & mesh) - { - int i, j; - SegmentIndex si; - PointIndex pi; - - ARRAY<int> osedges(cntedge); - INDEX_2_HASHTABLE<int> osedgesht (cntedge+1); - - osedges = 2; - - // count segments on edges - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - osedges.Elem(seg.edgenr)--; - } - - (*testout) << "osedges = " << osedges << endl; - - // flag one segment edges - for (i = 0; i < cntedge; i++) - osedges[i] = (osedges[i] > 0) ? 1 : 0; - - (*testout) << "osedges, now = " << osedges << endl; - - for (si = 0; si < mesh.GetNSeg(); si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr)) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2)) - osedgesht.Set (i2, 2); - else - osedgesht.Set (i2, 1); - } - } - } - - - // one edge 1 segment, other 2 segments - // yes, it happens ! - - for (i = 1; i <= osedgesht.GetNBags(); i++) - for (j = 1; j <= osedgesht.GetBagSize(i); j++) - { - INDEX_2 i2; - int val; - osedgesht.GetData (i, j, i2, val); - - const Point<3> & p1 = mesh[PointIndex(i2.I1())]; - const Point<3> & p2 = mesh[PointIndex(i2.I2())]; - Vec<3> v = p2 - p1; - double vlen = v.Length(); - v /= vlen; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (pi != i2.I1() && pi != i2.I2()) - { - const Point<3> & p = mesh[pi]; - Vec<3> v2 = p - p1; - double lam = (v2 * v); - if (lam > 0 && lam < vlen) - { - Point<3> hp = p1 + lam * v; - if (Dist (p, hp) < 1e-4 * vlen) - { - PrintSysError ("Point on edge !!!"); - cout << "seg: " << i2 << ", p = " << pi << endl; - osedgesht.Set (i2, 2); - } - } - } - } - - - // insert new points - osedges = -1; - - int nseg = mesh.GetNSeg(); - for (si = 0; si < nseg; si++) - { - const Segment & seg = mesh[si]; - if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort (); - if (osedgesht.Used (i2) && - osedgesht.Get (i2) == 2 && - osedges.Elem(seg.edgenr) == -1) - { - Point<3> newp = Center (mesh[PointIndex(seg.p1)], - mesh[PointIndex(seg.p2)]); - - ProjectToEdge (geometry.GetSurface(seg.surfnr1), - geometry.GetSurface(seg.surfnr2), - newp); - - osedges.Elem(seg.edgenr) = - mesh.AddPoint (newp, mesh[PointIndex(seg.p1)].GetLayer()); - } - } - } - - - for (i = 1; i <= nseg; i++) - { - Segment & seg = mesh.LineSegment (i); - if (seg.edgenr >= 1 && seg.edgenr <= cntedge) - { - if (osedges.Get(seg.edgenr) != -1) - { - Segment newseg = seg; - newseg.p1 = osedges.Get(seg.edgenr); - seg.p2 = osedges.Get(seg.edgenr); - mesh.AddSegment (newseg); - } - } - } - - } - - - - void EdgeCalculation :: - FollowEdge (int pi1, int & ep, int & pos, - const ARRAY<SpecialPoint> & hsp, - double h, const Mesh & mesh, - ARRAY<Point<3> > & edgepoints, - ARRAY<double> & curvelength) - { - int i, j, s1, s2; - double len, steplen, cursteplen, loch; - Point<3> p, np, pnp; - Vec<3> a1, a2, t; - - - double size = geometry.MaxSize(); - double epspointdist2 = size * 1e-6; - epspointdist2 = sqr (epspointdist2); - int uselocalh = mparam.uselocalh; - - - s1 = hsp.Get(pi1).s1; - s2 = hsp.Get(pi1).s2; - - p = hsp.Get(pi1).p; - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - - t = Cross (a1, a2); - t.Normalize(); - - pos = (hsp.Get(pi1).v * t) > 0; - if (!pos) t *= -1; - - - edgepoints.Append (p); - curvelength.Append (0); - len = 0; - - loch = min2 (geometry.GetSurface(s1) -> LocH (p, 3, 1, h), - geometry.GetSurface(s2) -> LocH (p, 3, 1, h)); - - - - if (uselocalh) - { - double lh = mesh.GetH(p); - if (lh < loch) - loch = lh; - } - - steplen = 0.1 * loch; - - do - { - if (multithread.terminate) - return; - - if (fabs (p(0)) + fabs (p(1)) + fabs (p(2)) > 10000) - { - ep = 0; - PrintWarning ("Give up line"); - break; - } - - if (steplen > 0.1 * loch) steplen = 0.1 * loch; - - steplen *= 2; - do - { - steplen *= 0.5; - np = p + steplen * t; - pnp = np; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), pnp); - } - while (Dist (np, pnp) > 0.1 * steplen); - - cursteplen = steplen; - if (Dist (np, pnp) < 0.01 * steplen) steplen *= 2; - - - np = pnp; - -#ifdef MYGRAPH - if (silentflag <= 2) - { - MyLine3D (p, np, rot); - MyDraw (); - } -#endif - - ep = 0; - - double hvtmin = 1.5 * cursteplen; - - Box<3> boxp (p - (2 * cursteplen) * Vec<3> (1, 1, 1), - p + (2 * cursteplen) * Vec<3> (1, 1, 1)); - - for (i = 1; i <= hsp.Size(); i++) - // if ( i != pi1 && hsp.Get(i).HasSurfaces (s1, s2) ) - { - if (!boxp.IsIn (hsp.Get(i).p)) - continue; - - Vec<3> hv = hsp.Get(i).p - p; - if (hv.Length2() > 9 * cursteplen * cursteplen) - continue; - - /* - if (!hsp.Get(i).HasSurfaces (s1, s2)) - continue; // test for dalibor-problem - */ - - double hvt = hv * t; - hv -= hvt * t; - - if (hv.Length() < 0.2 * cursteplen && - hvt > 0 && - // hvt < 1.5 * cursteplen && - hvt < hvtmin && - hsp.Get(i).unconditional == 1 && - (hsp.Get(i).v + t).Length() < 0.4 ) - { - Point<3> hep = hsp.Get(i).p; - ProjectToEdge (geometry.GetSurface(s1), - geometry.GetSurface(s2), hep); - - - if (Dist2 (hep, hsp.Get(i).p) < epspointdist2 ) - { - geometry.GetSurface(s1) -> CalcGradient (hep, a1); - geometry.GetSurface(s2) -> CalcGradient (hep, a2); - Vec<3> ept = Cross (a1, a2); - ept /= ept.Length(); - if (!pos) ept *= -1; - - if ( (hsp.Get(i).v + ept).Length() < 1e-4 ) - { - np = hsp.Get(i).p; - ep = i; - hvtmin = hvt; - // break; - } - } - } - } - - loch = min2 (geometry.GetSurface(s1) -> LocH (np, 3, 1, h), - geometry.GetSurface(s2) -> LocH (np, 3, 1, h)); - - if (uselocalh) - { - double lh = mesh.GetH(np); - if (lh < loch) - loch = lh; - } - - - len += Dist (p, np) / loch; - edgepoints.Append (np); - curvelength.Append (len); - - p = np; - - geometry.GetSurface(s1) -> CalcGradient (p, a1); - geometry.GetSurface(s2) -> CalcGradient (p, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - } - while (! ep); - } - - - - - - - - void EdgeCalculation :: - AnalyzeEdge (int s1, int s2, int pos, int layer, - const ARRAY<Point<3> > & edgepoints, - ARRAY<Segment> & refedges, - ARRAY<int> & refedgesinv) - { - int i, j, k, l; - int hi; - Point<3> hp; - Vec<3> t, a1, a2, m, n; - Segment seg; - Solid * locsol; - ARRAY<int> locsurfind; - - /* - int pi1 = 0, pi2 = 0; - extern Mesh * mesh; - for (i = 1; i <= mesh->GetNP(); i++) - { - if (Dist2 (edgepoints.Get(1), mesh->Point(i)) < 1e-12) - pi1 = i; - if (Dist2 (edgepoints.Last(), mesh->Point(i)) < 1e-12) - pi2 = i; - } - (*testout) << "Analyze edge: " << pi1 << " - " << pi2 << ", pts = " << edgepoints.Size() << endl; - (*testout) << "p1 = " << edgepoints.Get(1) << " pl = " << edgepoints.Last() << endl; - */ - int debug = 0; - /* - Dist2 (Point<3> (2.69642, 1.1866, 2.03), edgepoints.Get(1)) < 1e-6 || - Dist2 (Point<3> (2.69642, 1.1866, 2.03), edgepoints.Last()) < 1e-6; - */ - - if (debug) - { - // (*testout) << "tubious edge !!!" << endl; - (*testout) << "s1, s2 = " << s1 << " - " << s2 << endl; - } - - refedges.SetSize(0); - refedgesinv.SetSize(0); - hp = Center (edgepoints.Get(1), edgepoints.Get(2)); - ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp); - - geometry.GetSurface(s1) -> CalcGradient (hp, a1); - geometry.GetSurface(s2) -> CalcGradient (hp, a2); - t = Cross (a1, a2); - t.Normalize(); - if (!pos) t *= -1; - - (*testout) << "t = " << t << endl; - - for (i = 0; i < geometry.GetNTopLevelObjects(); i++) - { - (*testout) << "layer = " << layer - << ", tlo-layer = " << geometry.GetTopLevelObject(i)->GetLayer() << endl; - if (geometry.GetTopLevelObject(i)->GetLayer() != layer) - continue; - - const Solid * sol = geometry.GetTopLevelObject(i)->GetSolid(); - const Surface * surf = geometry.GetTopLevelObject(i)->GetSurface(); - - sol -> TangentialSolid (hp, locsol); - if (!locsol) continue; - - BoxSphere<3> boxp (hp, hp); - boxp.Increase (1e-5); - boxp.CalcDiamCenter(); - - ReducePrimitiveIterator rpi(boxp); - UnReducePrimitiveIterator urpi; - - ((Solid*)locsol) -> IterateSolid (rpi); - - locsol -> CalcSurfaceInverse (); - - - if (!surf) - { - locsol -> GetSurfaceIndices (locsurfind); - } - else - { - /* - if (fabs (surf->CalcFunctionValue (hp)) < 1e-6) - continue; - */ - locsurfind.SetSize(1); - locsurfind[0] = -1; - for (j = 0; j < geometry.GetNSurf(); j++) - if (geometry.GetSurface(j) == surf) - { - locsurfind[0] = j; - // geometry.GetSurfaceClassRepresentant(j); - break; - } - } - - ((Solid*)locsol) -> IterateSolid (urpi); - - - if (debug) - (*testout) << "edge of tlo " << i << ", has " << locsurfind.Size() << " faces." << endl; - - - for (j = locsurfind.Size()-1; j >= 0; j--) - if (fabs (geometry.GetSurface(locsurfind[j]) - ->CalcFunctionValue (hp) ) > 1e-6) - locsurfind.DeleteElement(j+1); - - if (debug) - (*testout) << locsurfind.Size() << " faces on hp" << endl; - - for (j = 0; j < locsurfind.Size(); j++) - { - int lsi = locsurfind[j]; - int rlsi = geometry.GetSurfaceClassRepresentant(lsi); - - Vec<3> rn; - - // n is outer normal to solid - geometry.GetSurface(lsi) -> GetNormalVector (hp, n); - if (geometry.GetSurface (lsi)->Inverse()) - n *= -1; - - if (fabs (t * n) > 1e-4) continue; - if (debug) - { - (*testout) << "face " << locsurfind.Get(j) << ", rep = " << rlsi - << " has (t*n) = " << (t*n) << endl; - (*testout) << "n = " << n << endl; - } - - // rn is normal to class representant - geometry.GetSurface(rlsi) -> GetNormalVector (hp, rn); - - int sameasref = ((n * rn) > 0); - - m = Cross (t, rn); - m.Normalize(); - - - for (k = 1; k <= 2; k ++) - { - bool edgeinv = (k == 2); - - if (debug) - { - (*testout) << "onface(" << hp << ", " << m << ")= " - << locsol->OnFace (hp, m); - (*testout) << " vec2in = " - << locsol -> VectorIn2 (hp, m, n) << " and " - << locsol -> VectorIn2 (hp, m, -1 * n) << endl; - } - - // if (locsol -> OnFace (hp, m)) - if (locsol -> VectorIn2 (hp, m, n) == 0 && - locsol -> VectorIn2 (hp, m, -1 * n) == 1) - { - hi = 0; - for (l = 1; l <= refedges.Size(); l++) - { - if (refedges.Get(l).si == rlsi && - refedgesinv.Get(l) == edgeinv) - hi = l; - } - - if (!hi) - { - seg.si = rlsi; - seg.domin = -1; - seg.domout = -1; - seg.tlosurf = -1; - seg.surfnr1 = s1; - seg.surfnr2 = s2; - hi = refedges.Append (seg); - refedgesinv.Append (edgeinv); - } - - if (!surf) - { - if (sameasref) - refedges.Elem(hi).domin = i; - else - refedges.Elem(hi).domout = i; - } - else - refedges.Elem(hi).tlosurf = i; - - if (debug) - (*testout) << "add ref seg:" - << "si = " << refedges.Get(hi).si - << ", domin = " << refedges.Get(hi).domin - << ", domout = " << refedges.Get(hi).domout - << ", surfnr1/2 = " << refedges.Get(hi).surfnr1 - << ", " << refedges.Get(hi).surfnr2 - << ", inv = " << refedgesinv.Get(hi) - << ", refedgenr = " << hi - << endl; - } - m *= -1; - } - } - delete locsol; - } - } - - - - void EdgeCalculation :: - StoreEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - - double len, corr, lam; - PointIndex thispi, lastpi; - Point<3> p, np; - Segment seg; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints.Get(1), edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - - // generate initial point - p = edgepoints.Get(1); - lastpi = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist (mesh[pi], p) < 1e-6) - { - lastpi = pi; - break; - } - - if (lastpi == -1) - lastpi = mesh.AddPoint (p, layer); - - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength.Get(j) < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength.Get(j-1)) / - (curvelength.Get(j) - curvelength.Get(j-1)); - - np(0) = (1-lam) * edgepoints.Get(j-1)(0) + lam * edgepoints.Get(j)(0); - np(1) = (1-lam) * edgepoints.Get(j-1)(1) + lam * edgepoints.Get(j)(1); - np(2) = (1-lam) * edgepoints.Get(j-1)(2) + lam * edgepoints.Get(j)(2); - - - thispi = -1; - if (i == ne) - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist(mesh[pi], np) < 1e-6) - thispi = pi; - - if (thispi == -1) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np, layer); - } - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = lastpi; - seg.p2 = thispi; - } - else - { - seg.p1 = thispi; - seg.p2 = lastpi; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - - double maxh = min2 (geometry.GetSurface(seg.surfnr1)->GetMaxH(), - geometry.GetSurface(seg.surfnr2)->GetMaxH()); - - if (seg.domin != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domin) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domin)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.domout != -1) - { - const Solid * s1 = - geometry.GetTopLevelObject(seg.domout) -> GetSolid(); - maxh = min2 (maxh, s1->GetMaxH()); - maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domout)->GetMaxH()); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - if (seg.tlosurf != -1) - { - double hi = geometry.GetTopLevelObject(seg.tlosurf) -> GetMaxH(); - maxh = min2 (maxh, hi); - mesh.RestrictLocalH (p, maxh); - mesh.RestrictLocalH (np, maxh); - } - } - - p = np; - lastpi = thispi; - } - -#ifdef DEVELOP - (*testout) << " eplast = " << lastpi << " = " << p << endl; -#endif - } - - - - - - - void EdgeCalculation :: - StoreShortEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - const ARRAY<Point<3> > & edgepoints, - const ARRAY<double> & curvelength, - int layer, - Mesh & mesh) - { - - // Calculate optimal element-length - int i, j, k; - PointIndex pi; - int ne; - Segment seg; - - /* - double len, corr, lam; - int thispi, lastpi; - Point<3> p, np; - - - const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); - const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); - - len = curvelength.Last(); - ne = int (len + 0.5); - if (ne == 0) ne = 1; - if (Dist2 (edgepoints[1], edgepoints.Last()) < 1e-8 && - ne <= 6) - ne = 6; - corr = len / ne; - */ - - // generate initial point - Point<3> p = edgepoints[0]; - PointIndex pi1 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi1 = pi; - break; - } - - if (pi1 == -1) pi1 = mesh.AddPoint (p, layer); - - p = edgepoints.Last(); - PointIndex pi2 = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (Dist (mesh[pi], p) < 1e-6) - { - pi2 = pi; - break; - } - if (pi2==-1) pi2 = mesh.AddPoint (p, layer); - - /* - - j = 1; - for (i = 1; i <= ne; i++) - { - while (curvelength[j] < i * corr && j < curvelength.Size()) j++; - - lam = (i * corr - curvelength[j-1]) / - (curvelength[j] - curvelength[j-1]); - - np(0) = (1-lam) * edgepoints[j-1](0) + lam * edgepoints[j](0); - np(1) = (1-lam) * edgepoints[j-1](1) + lam * edgepoints[j](1); - np(2) = (1-lam) * edgepoints[j-1](2) + lam * edgepoints[j](2); - - - thispi = 0; - if (i == ne) - for (j = 1; j <= mesh.GetNP(); j++) - if (Dist(mesh.Point(j), np) < 1e-6) - thispi = j; - - if (!thispi) - { - ProjectToEdge (surf1, surf2, np); - thispi = mesh.AddPoint (np); - } - */ - - for (k = 1; k <= refedges.Size(); k++) - { - if (refedgesinv.Get(k)) - { - seg.p1 = pi1; - seg.p2 = pi2; - } - else - { - seg.p1 = pi2; - seg.p2 = pi1; - } - - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "add seg " << seg.p1 << "-" << seg.p2 << endl; - } - } - - - - - - - - void EdgeCalculation :: - CopyEdge (const ARRAY<Segment> & refedges, - const ARRAY<int> & refedgesinv, - int copyfromedge, - const Point<3> & fromstart, const Point<3> & fromend, - const Point<3> & tostart, const Point<3> & toend, - int copyedgeidentification, - int layer, - Mesh & mesh) - { - int i, j, k; - PointIndex pi; - - // copy start and end points - for (i = 1; i <= 2; i++) - { - Point<3> fromp = - (i == 1) ? fromstart : fromend; - Point<3> top = - (i == 1) ? tostart : toend; - - PointIndex frompi = -1; - PointIndex topi = -1; - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - if (Dist2 (mesh[pi], fromp) <= 1e-16) - frompi = pi; - if (Dist2 (mesh[pi], top) <= 1e-16) - topi = pi; - } - - if (topi == -1) - topi = mesh.AddPoint (top, layer); - - const Identification & csi = - (*geometry.identifications.Get(copyedgeidentification)); - - if (csi.Identifyable (mesh[frompi], mesh[topi])) - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - else if (csi.Identifyable (mesh[topi], mesh[frompi])) - mesh.GetIdentifications().Add(topi, frompi, copyedgeidentification); - else - { - cerr << "edgeflw.cpp: should identify, but cannot"; - exit(1); - } - /* - (*testout) << "Add Identification from CopyEdge, p1 = " - << mesh[PointIndex(frompi)] << ", p2 = " - << mesh[PointIndex(topi)] << endl; - - mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); - */ - } - - int oldns = mesh.GetNSeg(); - for (i = 1; i <= oldns; i++) - { - // real copy, since array might be reallocated !! - const Segment oldseg = mesh.LineSegment(i); - if (oldseg.edgenr != copyfromedge) - continue; - if (oldseg.seginfo == 0) - continue; - - int pi1 = oldseg.p1; - int pi2 = oldseg.p2; - - int npi1 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi1); - int npi2 = geometry.identifications.Get(copyedgeidentification) - -> GetIdentifiedPoint (mesh, pi2); - - Segment seg; - - for (k = 1; k <= refedges.Size(); k++) - { - int inv = refedgesinv.Get(k); - - // other edge is inverse - if (oldseg.seginfo == 1) - inv = !inv; - - // (*testout) << "inv, now = " << inv << endl; - - if (inv) - { - seg.p1 = npi1; - seg.p2 = npi2; - } - else - { - seg.p1 = npi2; - seg.p2 = npi1; - } - seg.si = refedges.Get(k).si; - seg.domin = refedges.Get(k).domin; - seg.domout = refedges.Get(k).domout; - seg.tlosurf = refedges.Get(k).tlosurf; - seg.edgenr = refedges.Get(k).edgenr; - seg.surfnr1 = refedges.Get(k).surfnr1; - seg.surfnr2 = refedges.Get(k).surfnr2; - seg.seginfo = 0; - if (k == 1) seg.seginfo = refedgesinv.Get(k) ? 2 : 1; - mesh.AddSegment (seg); - // (*testout) << "copy seg " << seg.p1 << "-" << seg.p2 << endl; -#ifdef DEVELOP - - (*testout) << "copy seg, face = " << seg.si << ": " - << " inv = " << inv << ", refinv = " << refedgesinv.Get(k) - << mesh.Point(seg.p1) << ", " << mesh.Point(seg.p2) << endl; -#endif - - } - - } - } - - - - - - - - void EdgeCalculation :: - FindClosedSurfaces (double h, Mesh & mesh) - { - // if there is no special point at a sphere, one has to add a segment pair - - int i, j; - int nsol; - int nsurf = geometry.GetNSurf(); - int layer; - - BitArray pointatsurface (nsurf); - Point<3> p1, p2; - Vec<3> nv, tv; - Solid * tansol; - ARRAY<int> tansurfind; - // const Solid * sol; - - nsol = geometry.GetNTopLevelObjects(); - - - pointatsurface.Clear(); - - /* - for (i = 1; i <= specpoints.Size(); i++) - { - int classrep; - - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s1); - pointatsurface.Set (classrep); - classrep = geometry.GetSurfaceClassRepresentant (specpoints[i].s2); - pointatsurface.Set (classrep); - // pointatsurface.Set (specpoints[i].s1); - // pointatsurface.Set (specpoints[i].s2); - } - */ - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - int classrep; - -#ifdef DEVELOP - (*testout) << seg.surfnr1 << ", " << seg.surfnr2 << ", si = " << seg.si << endl; -#endif - classrep = geometry.GetSurfaceClassRepresentant (seg.si); - - pointatsurface.Set (classrep); - } - - - for (i = 0; i < nsurf; i++) - { - int classrep = geometry.GetSurfaceClassRepresentant (i); - - if (!pointatsurface.Test(classrep)) - { - const Surface * s = geometry.GetSurface(i); - p1 = s -> GetSurfacePoint(); - s -> GetNormalVector (p1, nv); - - double hloc = - min2 (s->LocH (p1, 3, 1, h), mesh.GetH(p1)); - - tv = nv.GetNormal (); - tv *= (hloc / tv.Length()); - p2 = p1 + tv; - s->Project (p2); - - - Segment seg1; - seg1.si = i; - seg1.domin = -1; - seg1.domout = -1; - - Segment seg2; - seg2.si = i; - seg2.domin = -1; - seg2.domout = -1; - - seg1.surfnr1 = i; - seg2.surfnr1 = i; - seg1.surfnr2 = i; - seg2.surfnr2 = i; - - for (j = 0; j < nsol; j++) - { - if (geometry.GetTopLevelObject(j)->GetSurface()) - continue; - - const Solid * sol = geometry.GetTopLevelObject(j)->GetSolid(); - sol -> TangentialSolid (p1, tansol); - layer = geometry.GetTopLevelObject(j)->GetLayer(); - - if (tansol) - { - tansol -> GetSurfaceIndices (tansurfind); - - if (tansurfind.Size() == 1 && tansurfind.Get(1) == i) - { - if (!tansol->VectorIn(p1, nv)) - { - seg1.domin = j; - seg2.domin = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - else - { - seg1.domout = j; - seg2.domout = j; - seg1.tlosurf = j; - seg2.tlosurf = j; - } - // seg.s2 = i; - // seg.invs1 = surfaces[i] -> Inverse(); - // seg.invs2 = ! (surfaces[i] -> Inverse()); - } - delete tansol; - } - } - - - if (seg1.domin != -1 || seg1.domout != -1) - { - mesh.AddPoint (p1, layer); - mesh.AddPoint (p2, layer); - seg1.p1 = mesh.GetNP()-1; - seg1.p2 = mesh.GetNP(); - seg2.p2 = mesh.GetNP()-1; - seg2.p1 = mesh.GetNP(); - seg1.geominfo[0].trignum = 1; - seg1.geominfo[1].trignum = 1; - seg2.geominfo[0].trignum = 1; - seg2.geominfo[1].trignum = 1; - mesh.AddSegment (seg1); - mesh.AddSegment (seg2); - - PrintMessage (5, "Add line segment to smooth surface"); - -#ifdef DEVELOP - (*testout) << "Add segment at smooth surface " << i; - if (i != classrep) (*testout) << ", classrep = " << classrep; - (*testout) << ": " - << mesh.Point (mesh.GetNP()-1) << " - " - << mesh.Point (mesh.GetNP()) << endl; -#endif - } - } - } - } - -} diff --git a/Netgen/libsrc/csg/explicitcurve2d.cpp b/Netgen/libsrc/csg/explicitcurve2d.cpp deleted file mode 100644 index b1eef537c8..0000000000 --- a/Netgen/libsrc/csg/explicitcurve2d.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include <mystdlib.h> -#include <csg.hpp> - -namespace netgen -{ -ExplicitCurve2d :: ExplicitCurve2d () - { - ; - } - - -void ExplicitCurve2d :: Project (Point<2> & p) const - { - double t; - t = ProjectParam (p); - p = Eval (t); - } - -double ExplicitCurve2d :: NumericalProjectParam (const Point<2> & p, double lb, double ub) const - { - double t; - Vec<2> tan; - Vec<2> curv; - Point<2> cp; - double f, fl, fu; - int cnt; - - tan = EvalPrime (lb); - cp = Eval (lb); - fl = tan * (cp - p); - if (fl > 0) // changed by wmf, originally fl >= 0 - { - // cerr << "tan = " << tan << " cp - p = " << (cp - p) << endl; - // cerr << "ExplicitCurve2d::NumericalProject: lb wrong" << endl; - return 0; - } - - tan = EvalPrime (ub); - cp = Eval (ub); - fu = tan * (cp - p); - if (fu < 0) // changed by wmf, originally fu <= 0 - { - // cerr << "tan = " << tan << " cp - p = " << (cp - p) << endl; - // cerr << "ExplicitCurve2d::NumericalProject: ub wrong" << endl; - return 0; - } - - cnt = 0; - while (ub - lb > 1e-12 && fu - fl > 1e-12) - { - cnt++; - if (cnt > 50) - { - (*testout) << "Num Proj, cnt = " << cnt << endl; - } - - t = (lb * fu - ub * fl) / (fu - fl); - if (t > 0.9 * ub + 0.1 * lb) t = 0.9 * ub + 0.1 * lb; - if (t < 0.1 * ub + 0.9 * lb) t = 0.1 * ub + 0.9 * lb; - - tan = EvalPrime (t); - cp = Eval (t); - f = tan * (cp - p); - - if (f >= 0) - { - ub = t; - fu = f; - } - else - { - lb = t; - fl = f; - } - } - - return t; - } - - -Vec<2> ExplicitCurve2d :: Normal (double t) const -{ - Vec<2> tan = EvalPrime (t); - tan.Normalize(); - return Vec<2> (tan(1), -tan(0)); -} - - -void ExplicitCurve2d :: NormalVector (const Point<2> & p, Vec<2> & n) const - { - double t = ProjectParam (p); - n = Normal (t); - } - - -Point<2> ExplicitCurve2d :: CurvCircle (double t) const - { - Point<2> cp; - Vec<2> tan, n, curv; - double den; - - cp = Eval (t); - tan = EvalPrime (t); - n = Normal (t); - curv = EvalPrimePrime (t); - - den = n * curv; - if (fabs (den) < 1e-12) - return cp + 1e12 * n; - - return cp + (tan.Length2() / den) * n; - } - - -double ExplicitCurve2d :: MaxCurvature () const - { - double t, tmin, tmax, dt; - double curv; - Vec<2> tan; - double maxcurv; - - maxcurv = 0; - - tmin = MinParam (); - tmax = MaxParam (); - dt = (tmax - tmin) / 1000; - for (t = tmin; t <= tmax+dt; t += dt) - if (SectionUsed (t)) - { - tan = EvalPrime (t); - curv = fabs ( (Normal(t) * EvalPrimePrime(t)) / tan.Length2()); - if (curv > maxcurv) maxcurv = curv; - } - return maxcurv; - } - -double ExplicitCurve2d :: MaxCurvatureLoc (const Point<2> & p, double rad) const - { - double t, tmin, tmax, dt; - double curv; - Vec<2> tan; - double maxcurv; - - maxcurv = 0; - - tmin = MinParam (); - tmax = MaxParam (); - dt = (tmax - tmin) / 1000; - for (t = tmin; t <= tmax+dt; t += dt) - if (Dist (Eval(t), p) < rad) - { - tan = EvalPrime (t); - curv = fabs ( (Normal(t) * EvalPrimePrime(t)) / tan.Length2()); - if (curv > maxcurv) maxcurv = curv; - } - - return maxcurv; - } - -} diff --git a/Netgen/libsrc/csg/explicitcurve2d.hpp b/Netgen/libsrc/csg/explicitcurve2d.hpp deleted file mode 100644 index af405aed3c..0000000000 --- a/Netgen/libsrc/csg/explicitcurve2d.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef FILE_EXPLICITCURVE2D -#define FILE_EXPLICITCURVE2D - -/**************************************************************************/ -/* File: explicitcurve2d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 14. Oct. 96 */ -/**************************************************************************/ - -/* - - Explicit 2D Curve repesentation - -*/ - - - -/// -class ExplicitCurve2d : public Curve2d -{ -public: - /// - ExplicitCurve2d (); - - /// - virtual void Project (Point<2> & p) const; - /// - virtual double ProjectParam (const Point<2> & p) const = 0; - /// - virtual double NumericalProjectParam (const Point<2> & p, double lb, double ub) const; - /// - virtual double MinParam () const = 0; - /// - virtual double MaxParam () const = 0; - /// - virtual Point<2> Eval (double t) const = 0; - /// - virtual Vec<2> EvalPrime (double t) const = 0; - /// - virtual Vec<2> Normal (double t) const; - /// - virtual void NormalVector (const Point<2> & p, Vec<2> & n) const; - /// - virtual Vec<2> EvalPrimePrime (double t) const = 0; - - /// - virtual double MaxCurvature () const; - /// - virtual double MaxCurvatureLoc (const Point<2> & p, double rad) const; - - /// - virtual Point<2> CurvCircle (double t) const; - /// - virtual void Print (ostream & /* str */) const { }; - - /// - virtual int SectionUsed (double /* t */) const { return 1; } - /// - virtual void Reduce (const Point<2> & /* p */, double /* rad */) { }; - /// - virtual void UnReduce () { }; -}; - - -/// -class BSplineCurve2d : public ExplicitCurve2d -{ - /// - ARRAY<Point<2> > points; - /// - ARRAY<int> intervallused; - /// - int redlevel; - -public: - /// - BSplineCurve2d (); - /// - void AddPoint (const Point<2> & apoint); - - bool Inside (const Point<2> & p, double & dist) const; - - /// - virtual double ProjectParam (const Point<2> & p) const; - /// - virtual double MinParam () const { return 0; } - /// - virtual double MaxParam () const { return points.Size(); } - /// - virtual Point<2> Eval (double t) const; - /// - virtual Vec<2> EvalPrime (double t) const; - /// - virtual Vec<2> EvalPrimePrime (double t) const; - /// - virtual void Print (ostream & str) const; - - /// - virtual int SectionUsed (double t) const; - /// - virtual void Reduce (const Point<2> & p, double rad); - /// - virtual void UnReduce (); -}; - - - - -#endif diff --git a/Netgen/libsrc/csg/extrusion.cpp b/Netgen/libsrc/csg/extrusion.cpp deleted file mode 100644 index acf9b863bc..0000000000 --- a/Netgen/libsrc/csg/extrusion.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include <mystdlib.h> - -#include <linalg.hpp> -#include <csg.hpp> - -namespace netgen -{ - - - - ExtrusionSurface :: ExtrusionSurface (const Point<3> & ap0, - const Vec<3> & aex, - const Vec<3> & aey, - BSplineCurve2d * acurve, - int asegnr) - : p0(ap0), ex(aex), ey(aey), curve(acurve), segnr(asegnr) - { - ; - } - - ExtrusionSurface :: ~ExtrusionSurface () - { - ; - } - - void ExtrusionSurface :: DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2) - { - ; - } - - void ExtrusionSurface :: ToPlane (const Point<3> & p3d, Point<2> & pplane, - double h, int & zone) const - { - ; - } - - void ExtrusionSurface :: FromPlane (const Point<2> & pplane, - Point<3> & p3d, double h) const - { - ; - } - - - void ExtrusionSurface :: Project (Point<3> & p) const - { - ; - } - - - double ExtrusionSurface :: CalcFunctionValue (const Point<3> & point) const - { - return 0; - } - - void ExtrusionSurface :: CalcGradient (const Point<3> & point, Vec<3> & grad) const - { - ; - } - - Point<3> ExtrusionSurface :: GetSurfacePoint () const - { - return Point<3> (0,0,0); - } - - double ExtrusionSurface :: HesseNorm () const - { - return 1; - } - - void ExtrusionSurface :: Print (ostream & str) const - { - ; - } - - void ExtrusionSurface :: GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & boundingbox, - double facets) const - { - Point<2> p2d; - Point<3> p; - int n = int(facets)+1; - Vec<3> ez = Cross (ex, ey); - cout << "ex = " << ex << endl; - cout << "ey = " << ey << endl; - for (double t = 0; t < 1.0001; t += 1.0 / n) - { - cout << "t = " << t << endl; - p2d = curve -> Eval (segnr+t); - p = p0 + p2d(0) * ex + p2d(1) * ey; - cout << "p2d = " << p2d << endl; - cout << "add point " << p << endl; - tas.AddPoint (p); - tas.AddPoint (p + ez); - } - - for (int i = 0; i < n; i++) - { - cout << "add trig " << endl; - tas.AddTriangle (TATriangle (0, 2*i, 2*i+2, 2*i+1)); - tas.AddTriangle (TATriangle (0, 2*i+2, 2*i+3, 2*i+1)); - } - } - - - - -Extrusion :: Extrusion (const Point<3> & ap0, - const Vec<3> & aex, - const Vec<3> & aey, - const ARRAY< Point<2> > & points) - : p0(ap0), ex(aex), ey(aey) -{ - int i; - - ex.Normalize(); - ey -= (ex*ey) * ex; - ey.Normalize(); - - for (i = 0; i < points.Size(); i++) - curve.AddPoint (points[i]); - - surfs.SetSize (points.Size()/2); - for (i = 0; i < surfs.Size(); i++) - surfs = new ExtrusionSurface (p0, ex, ey, &curve, i); -} - -Extrusion :: ~Extrusion () -{ - int i; - for (i = 0; i < surfs.Size(); i++) - delete surfs[i]; -} - - -INSOLID_TYPE Extrusion :: BoxInSolid (const BoxSphere<3> & box) const -{ - Vec<3> p0c = box.Center() - p0; - Point<2> p2d (ex*p0c, ey*p0c); - double r = box.Diam() / 2; - double dist; - bool inside = - curve.Inside (p2d, dist); - - if (inside && dist > r) return IS_INSIDE; - if (!inside && dist > r) return IS_OUTSIDE; - return DOES_INTERSECT; -} - - -INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p, - double eps) const -{ - Vec<3> p0c = p - p0; - Point<2> p2d (ex*p0c, ey*p0c); - double dist; - bool inside = - curve.Inside (p2d, dist); - - if (dist < eps) return DOES_INTERSECT; - if (inside) return IS_INSIDE; - return IS_OUTSIDE; -} - - -INSOLID_TYPE Extrusion :: VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const -{ - Point<3> p2 = p + (1e-3/(v.Length()+1e-16)) * v; - return PointInSolid (p2, eps); -} - - -} diff --git a/Netgen/libsrc/csg/extrusion.hpp b/Netgen/libsrc/csg/extrusion.hpp deleted file mode 100644 index ff5a47b4e1..0000000000 --- a/Netgen/libsrc/csg/extrusion.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef FILE_EXTRUSION -#define FILE_EXTRUSION - -/**************************************************************************/ -/* File: extrusion.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 17. Mar. 2003 */ -/**************************************************************************/ - -/* - -extrusion of 2D curve - -*/ - - -class ExtrusionSurface : public Surface -{ -protected: - BSplineCurve2d * curve; - int segnr; - Point<3> p0; - Vec<3> ex, ey; -public: - ExtrusionSurface (const Point<3> & ap0, - const Vec<3> & aex, - const Vec<3> & aey, - BSplineCurve2d * acurve, - int asegnr); - virtual ~ExtrusionSurface (); - - virtual void DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2); - - virtual void ToPlane (const Point<3> & p3d, Point<2> & pplane, - double h, int & zone) const; - - virtual void FromPlane (const Point<2> & pplane, - Point<3> & p3d, double h) const; - - - virtual void Project (Point<3> & p) const; - - - virtual double CalcFunctionValue (const Point<3> & point) const; - - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; - - virtual Point<3> GetSurfacePoint () const; - - virtual double HesseNorm () const; - - virtual void Print (ostream & str) const; - virtual void GetTriangleApproximation (TriangleApproximation & tas, - const Box<3> & boundingbox, - double facets) const; -}; - - -class Extrusion : public Primitive -{ -protected: - Point<3> p0; - Vec<3> ex, ey; - BSplineCurve2d curve; - ARRAY<ExtrusionSurface*> surfs; - -public: - Extrusion (const Point<3> & ap0, - const Vec<3> & aex, - const Vec<3> & aey, - const ARRAY< Point<2> > & points); - virtual ~Extrusion (); - - - - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const; - - virtual int GetNSurfaces() const { return surfs.Size(); } - virtual Surface & GetSurface (int i) { return *surfs[i]; } - virtual const Surface & GetSurface (int i) const { return *surfs[i]; } -}; - -#endif diff --git a/Netgen/libsrc/csg/gencyl.cpp b/Netgen/libsrc/csg/gencyl.cpp deleted file mode 100644 index 01c893d4a3..0000000000 --- a/Netgen/libsrc/csg/gencyl.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - -GeneralizedCylinder :: GeneralizedCylinder (ExplicitCurve2d & acrosssection, - Point<3> ap, Vec<3> ae1, Vec<3> ae2) - : crosssection(acrosssection) -{ - planep = ap; - planee1 = ae1; - planee2 = ae2; - planee3 = Cross (planee1, planee2); - (*testout) << "Vecs = " << planee1 << " " << planee2 << " " << planee3 << endl; -} - - -void GeneralizedCylinder :: Project (Point<3> & p) const -{ - Point<2> p2d; - double z; - - p2d = Point<2> (planee1 * (p - planep), planee2 * (p - planep)); - z = planee3 * (p - planep); - - crosssection.Project (p2d); - - p = planep + p2d(0) * planee1 + p2d(1) * planee2 + z * planee3; -} - -int GeneralizedCylinder ::BoxInSolid (const BoxSphere<3> & box) const -{ - Point<3> p3d; - Point<2> p2d, projp; - double t; - Vec<2> tan, n; - - p3d = box.Center(); - - p2d = Point<2> (planee1 * (p3d - planep), planee2 * (p3d - planep)); - t = crosssection.ProjectParam (p2d); - - projp = crosssection.Eval (t); - tan = crosssection.EvalPrime (t); - n(0) = tan(1); - n(1) = -tan(0); - - if (Dist (p2d, projp) < box.Diam()/2) - return 2; - - if (n * (p2d - projp) > 0) - { - return 0; - } - - return 1; -} - -double GeneralizedCylinder :: CalcFunctionValue (const Point<3> & point) const -{ - Point<2> p2d, projp; - double t; - Vec<2> tan, n; - - - p2d = Point<2> (planee1 * (point - planep), planee2 * (point - planep)); - t = crosssection.ProjectParam (p2d); - - projp = crosssection.Eval (t); - tan = crosssection.EvalPrime (t); - n(0) = tan(1); - n(1) = -tan(0); - - n /= n.Length(); - return n * (p2d - projp); -} - -void GeneralizedCylinder :: CalcGradient (const Point<3> & point, Vec<3> & grad) const -{ - Point<2> p2d, projp; - double t; - Vec<2> tan, n; - - - p2d = Point<2> (planee1 * (point - planep), planee2 * (point - planep)); - t = crosssection.ProjectParam (p2d); - - projp = crosssection.Eval (t); - tan = crosssection.EvalPrime (t); - n(0) = tan(1); - n(1) = -tan(0); - - n /= n.Length(); - grad = n(0) * planee1 + n(1) * planee2; -} - - -void GeneralizedCylinder :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const -{ - Point<2> p2d, projp; - double t, dist, val; - Point<2> curvp; - Vec<2> curvpp; - Mat<2> h2d; - Mat<3,2> vmat; - int i, j, k, l; - - p2d = Point<2> (planee1 * (point - planep), planee2 * (point - planep)); - t = crosssection.ProjectParam (p2d); - - curvp = crosssection.CurvCircle (t); - curvpp = p2d-curvp; - dist = curvpp.Length(); - curvpp /= dist; - - h2d(1, 1) = (1 - curvpp(0) * curvpp(0) ) / dist; - h2d(1, 2) = h2d(2, 1) = (- curvpp(0) * curvpp(1) ) / dist; - h2d(2, 2) = (1 - curvpp(1) * curvpp(1) ) / dist; - - vmat(0,0) = planee1(0); - vmat(1,0) = planee1(1); - vmat(2,0) = planee1(2); - vmat(0,1) = planee2(0); - vmat(1,1) = planee2(1); - vmat(2,1) = planee2(2); - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - { - val = 0; - for (k = 0; k < 2; k++) - for (l = 0; l < 2; l++) - val += vmat(i,k) * h2d(k,l) * vmat(j,l); - hesse(i,j) = val; - } -} - - -double GeneralizedCylinder :: HesseNorm () const -{ - return crosssection.MaxCurvature(); -} - -double GeneralizedCylinder :: MaxCurvatureLoc (const Point<3> & c, double rad) const -{ - Point<2> c2d = Point<2> (planee1 * (c - planep), planee2 * (c - planep)); - return crosssection.MaxCurvatureLoc(c2d, rad); -} - - - -Point<3> GeneralizedCylinder :: GetSurfacePoint () const -{ - Point<2> p2d; - p2d = crosssection.Eval(0); - return planep + p2d(0) * planee1 + p2d(1) * planee2; -} - -void GeneralizedCylinder :: Reduce (const BoxSphere<3> & box) -{ - Point<2> c2d = Point<2> (planee1 * (box.Center() - planep), - planee2 * (box.Center() - planep)); - crosssection.Reduce (c2d, box.Diam()/2); -} - -void GeneralizedCylinder :: UnReduce () -{ - crosssection.UnReduce (); -} - -void GeneralizedCylinder :: Print (ostream & str) const -{ - str << "Generalized Cylinder" << endl; - crosssection.Print (str); -} - -#ifdef MYGRAPH -void GeneralizedCylinder :: Plot (const class ROT3D & rot) const -{ - Point<2> p2d; - Point<3> p, oldp; - double t, tmin, tmax, dt; - - tmin = crosssection.MinParam(); - tmax = crosssection.MaxParam(); - dt = (tmax - tmin)/ 500; - - p2d = crosssection.Eval(tmin); - p = planep + p2d(0) * planee1 + p2d(1) * planee2; - - for (t = tmin; t <= tmax+dt; t += dt) - { - if (crosssection.SectionUsed (t)) - MySetColor (RED); - else - MySetColor (BLUE); - - oldp = p; - p2d = crosssection.Eval(t); - p = planep + p2d(0) * planee1 + p2d(1) * planee2; - MyLine3D (p, oldp, rot); - } - -} - -#endif -} diff --git a/Netgen/libsrc/csg/gencyl.hpp b/Netgen/libsrc/csg/gencyl.hpp deleted file mode 100644 index 424c867a92..0000000000 --- a/Netgen/libsrc/csg/gencyl.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef FILE_GENCYL -#define FILE_GENCYL - -/**************************************************************************/ -/* File: gencyl.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 14. Oct. 96 */ -/**************************************************************************/ - -/* - - Generalized Cylinder - -*/ - - -/// -class GeneralizedCylinder : public Surface -{ - /// - ExplicitCurve2d & crosssection; - /// - Point<3> planep; - /// - Vec<3> planee1, planee2, planee3; - - /// Vec<3> ex, ey, ez; - Vec2d e2x, e2y; - /// - Point<3> cp; - -public: - /// - GeneralizedCylinder (ExplicitCurve2d & acrosssection, - Point<3> ap, Vec<3> ae1, Vec<3> ae2); - - /// - virtual void Project (Point<3> & p) const; - - /// - virtual int BoxInSolid (const BoxSphere<3> & box) const; - /// 0 .. no, 1 .. yes, 2 .. maybe - - virtual double CalcFunctionValue (const Point<3> & point) const; - /// - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; - /// - virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; - /// - virtual double HesseNorm () const; - /// - virtual double MaxCurvatureLoc (const Point<3> & c, double rad) const; - /// - virtual Point<3> GetSurfacePoint () const; - /// - virtual void Print (ostream & str) const; - - /// - virtual void Reduce (const BoxSphere<3> & box); - /// - virtual void UnReduce (); -}; - -#endif diff --git a/Netgen/libsrc/csg/genmesh.cpp b/Netgen/libsrc/csg/genmesh.cpp deleted file mode 100644 index c052624a42..0000000000 --- a/Netgen/libsrc/csg/genmesh.cpp +++ /dev/null @@ -1,684 +0,0 @@ -#include <mystdlib.h> - - -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - - -namespace netgen -{ - ARRAY<SpecialPoint> specpoints; - static ARRAY<MeshPoint> spoints; - -#define TCL_OK 0 -#define TCL_ERROR 1 - - - - static void FindPoints (CSGeometry & geom, Mesh & mesh) - { - PrintMessage (1, "Start Findpoints"); - - char * savetask = multithread.task; - multithread.task = "Find points"; - - for (int i = 0; i < geom.GetNUserPoints(); i++) - { - mesh.AddPoint (geom.GetUserPoint (i)); - mesh.AddLockedPoint (PointIndex (i+1)); - } - - SpecialPointCalculation spc; - - if (spoints.Size() == 0) - spc.CalcSpecialPoints (geom, spoints); - - PrintMessage (2, "Analyze spec points"); - spc.AnalyzeSpecialPoints (geom, spoints, specpoints); - - PrintMessage (5, "done"); - - (*testout) << specpoints.Size() << " special points:" << endl; - for (int i = 0; i < specpoints.Size(); i++) - specpoints[i].Print (*testout); - - /* - for (int i = 1; i <= geom.identifications.Size(); i++) - geom.identifications.Elem(i)->IdentifySpecialPoints (specpoints); - */ - multithread.task = savetask; - } - - - - - - - static void FindEdges (CSGeometry & geom, Mesh & mesh) - { - EdgeCalculation ec (geom, specpoints); - ec.Calc (mparam.maxh, mesh); - - for (int i = 0; i < geom.singedges.Size(); i++) - geom.singedges[i]->FindPointsOnEdge (mesh); - for (int i = 0; i < geom.singpoints.Size(); i++) - geom.singpoints[i]->FindPoints (mesh); - - for (int i = 1; i <= mesh.GetNSeg(); i++) - { - int ok = 0; - for (int k = 1; k <= mesh.GetNFD(); k++) - if (mesh.GetFaceDescriptor(k).SegmentFits (mesh.LineSegment(i))) - ok = k; - - if (!ok) - ok = mesh.AddFaceDescriptor (FaceDescriptor (mesh.LineSegment(i))); - - mesh.LineSegment(i).si = ok; - } - - for (int i = 0; i < geom.identifications.Size(); i++) - geom.identifications[i]->IdentifyPoints (mesh); - for (int i = 0; i < geom.identifications.Size(); i++) - geom.identifications[i]->IdentifyFaces (mesh); - - - - // find intersecting segments - PrintMessage (3, "Check intersecting edges"); - - if (!ec.point_on_edge_problem) - for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) - for (SegmentIndex sj = 0; sj < si; sj++) - { - if (!mesh[si].seginfo || !mesh[sj].seginfo) continue; - if (mesh[mesh[si].p1].GetLayer() != mesh[mesh[sj].p2].GetLayer()) continue; - - Point<3> pi1 = mesh[mesh[si].p1]; - Point<3> pi2 = mesh[mesh[si].p2]; - Point<3> pj1 = mesh[mesh[sj].p1]; - Point<3> pj2 = mesh[mesh[sj].p2]; - Vec<3> vi = pi2 - pi1; - Vec<3> vj = pj2 - pj1; - - if (sqr (vi * vj) > (1-1e-6) * Abs2 (vi) * Abs2 (vj)) continue; - - // pi1 + vi t = pj1 + vj s - Mat<3,2> mat; - Vec<3> rhs; - Vec<2> sol; - - for (int j = 0; j < 3; j++) - { - mat(j,0) = vi(j); - mat(j,1) = -vj(j); - rhs(j) = pj1(j)-pi1(j); - } - - mat.Solve (rhs, sol); - - if (sol(0) > 1e-6 && sol(0) < 1-1e-6 && - sol(1) > 1e-6 && sol(1) < 1-1e-6 && - Abs (rhs - mat*sol) < 1e-6) - { - Point<3> ip = pi1 + sol(0) * vi; - cout << "Intersection at " << ip << endl; - - geom.AddUserPoint (ip); - spoints.Append (MeshPoint (ip, mesh[mesh[si].p1].GetLayer())); - mesh.AddPoint (ip); - } - } - } - - - - - - - static void MeshSurface (CSGeometry & geom, Mesh & mesh) - { - char * savetask = multithread.task; - multithread.task = "Surface meshing"; - - ARRAY<Segment> segments; - int noldp = mesh.GetNP(); - - double starttime = GetTime(); - - // find master faces from identified - ARRAY<int> masterface(mesh.GetNFD()); - for (int i = 1; i <= mesh.GetNFD(); i++) - masterface.Elem(i) = i; - - ARRAY<INDEX_2> fpairs; - bool changed; - do - { - changed = 0; - for (int i = 0; i < geom.identifications.Size(); i++) - { - geom.identifications[i]->GetIdentifiedFaces (fpairs); - - for (int j = 0; j < fpairs.Size(); j++) - { - if (masterface.Get(fpairs[j].I1()) < - masterface.Get(fpairs[j].I2())) - { - changed = 1; - masterface.Elem(fpairs[j].I2()) = - masterface.Elem(fpairs[j].I1()); - } - if (masterface.Get(fpairs[j].I2()) < - masterface.Get(fpairs[j].I1())) - { - changed = 1; - masterface.Elem(fpairs[j].I1()) = - masterface.Elem(fpairs[j].I2()); - } - } - } - } - while (changed); - - - int bccnt=0; - for (int k = 0; k < geom.GetNSurf(); k++) - bccnt = max2 (bccnt, geom.GetSurface(k)->GetBCProperty()); - - for (int k = 1; k <= mesh.GetNFD(); k++) - { - FaceDescriptor & fd = mesh.GetFaceDescriptor(k); - const Surface * surf = geom.GetSurface(fd.SurfNr()); - - if (fd.TLOSurface() && - geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetBCProp() > 0) - fd.SetBCProperty (geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetBCProp()); - else if (surf -> GetBCProperty() != -1) - fd.SetBCProperty (surf->GetBCProperty()); - else - { - bccnt++; - fd.SetBCProperty (bccnt); - } - - for (int l = 0; l < geom.bcmodifications.Size(); l++) - { - if (geom.GetSurfaceClassRepresentant (fd.SurfNr()) == - geom.GetSurfaceClassRepresentant (geom.bcmodifications[l].si) && - (fd.DomainIn() == geom.bcmodifications[l].tlonr+1 || - fd.DomainOut() == geom.bcmodifications[l].tlonr+1)) - { - fd.SetBCProperty (geom.bcmodifications[l].bcnr); - } - } - } - - - for (int j = 0; j < geom.singfaces.Size(); j++) - { - ARRAY<int> surfs; - geom.GetIndependentSurfaceIndices (geom.singfaces[j]->GetSolid(), - geom.BoundingBox(), surfs); - for (int k = 1; k <= mesh.GetNFD(); k++) - { - FaceDescriptor & fd = mesh.GetFaceDescriptor(k); - for (int l = 0; l < surfs.Size(); l++) - if (surfs[l] == fd.SurfNr()) - { - if (geom.singfaces[j]->GetDomainNr() == fd.DomainIn()) - fd.domin_singular = 1; - if (geom.singfaces[j]->GetDomainNr() == fd.DomainOut()) - fd.domout_singular = 1; - } - } - } - - - // assemble edge hash-table - mesh.CalcSurfacesOfNode(); - - for (int k = 1; k <= mesh.GetNFD(); k++) - { - multithread.percent = 100.0 * k / (mesh.GetNFD()+1e-10); - - if (masterface.Get(k) != k) - continue; - - FaceDescriptor & fd = mesh.GetFaceDescriptor(k); - - (*testout) << "Surface " << k << endl; - (*testout) << "Face Descriptor: " << fd << endl; - PrintMessage (1, "Surface ", k, " / ", mesh.GetNFD()); - - int oldnf = mesh.GetNSE(); - - const Surface * surf = - geom.GetSurface((mesh.GetFaceDescriptor(k).SurfNr())); - - - Meshing2Surfaces meshing(*surf, geom.BoundingBox()); - meshing.SetStartTime (starttime); - - for (PointIndex pi = PointIndex::BASE; pi < noldp+PointIndex::BASE; pi++) - meshing.AddPoint (mesh[pi], pi); - - segments.SetSize (0); - - for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) - if (mesh[si].si == k) - segments.Append (mesh[si]); - - for (int i = 1; i <= geom.identifications.Size(); i++) - geom.identifications.Get(i)-> - BuildSurfaceElements(segments, mesh, surf); - - for (int si = 0; si < segments.Size(); si++) - { - PointGeomInfo gi; - gi.trignum = k; - meshing.AddBoundaryElement (segments[si].p1 + 1 - PointIndex::BASE, - segments[si].p2 + 1 - PointIndex::BASE, - gi, gi); - } - - double maxh = mparam.maxh; - if (fd.DomainIn() != 0) - { - const Solid * s1 = - geom.GetTopLevelObject(fd.DomainIn()-1) -> GetSolid(); - if (s1->GetMaxH() < maxh) - maxh = s1->GetMaxH(); - maxh = min2(maxh, geom.GetTopLevelObject(fd.DomainIn()-1)->GetMaxH()); - } - if (fd.DomainOut() != 0) - { - const Solid * s1 = - geom.GetTopLevelObject(fd.DomainOut()-1) -> GetSolid(); - if (s1->GetMaxH() < maxh) - maxh = s1->GetMaxH(); - maxh = min2(maxh, geom.GetTopLevelObject(fd.DomainOut()-1)->GetMaxH()); - } - if (fd.TLOSurface() != 0) - { - double hi = geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetMaxH(); - if (hi < maxh) maxh = hi; - } - - (*testout) << "domin = " << fd.DomainIn() << ", domout = " << fd.DomainOut() - << ", tlo-surf = " << fd.TLOSurface() - << " mpram.maxh = " << mparam.maxh << ", maxh = " << maxh << endl; - - mparam.checkoverlap = 0; - - MESHING2_RESULT res = - meshing.GenerateMesh (mesh, maxh, k); - - if (res != MESHING2_OK) - { - PrintError ("Problem in Surface mesh generation"); - throw NgException ("Problem in Surface mesh generation"); - } - - if (multithread.terminate) return; - - for (int i = oldnf+1; i <= mesh.GetNSE(); i++) - mesh.SurfaceElement(i).SetIndex (k); - - - // mesh.CalcSurfacesOfNode(); - if (segments.Size()) - { - // surface was meshed, not copied - PrintMessage (2, "Optimize Surface"); - for (int i = 1; i <= mparam.optsteps2d; i++) - { - if (multithread.terminate) return; - - { - MeshOptimize2dSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.EdgeSwapping (mesh, (i > mparam.optsteps2d/2)); - } - - if (multithread.terminate) return; - { - // mesh.CalcSurfacesOfNode(); - - MeshOptimize2dSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.ImproveMesh (mesh); - } - - { - MeshOptimize2dSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.CombineImprove (mesh); - // mesh.CalcSurfacesOfNode(); - } - - if (multithread.terminate) return; - { - MeshOptimize2dSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.ImproveMesh (mesh); - } - } - } - - - PrintMessage (3, (mesh.GetNSE() - oldnf), " elements, ", mesh.GetNP(), " points"); - -#ifdef OPENGL - extern void Render(); - Render(); -#endif - } - - mesh.Compress(); - - do - { - changed = 0; - for (int k = 1; k <= mesh.GetNFD(); k++) - { - multithread.percent = 100.0 * k / (mesh.GetNFD()+1e-10); - - if (masterface.Get(k) == k) - continue; - - FaceDescriptor & fd = mesh.GetFaceDescriptor(k); - - (*testout) << "Surface " << k << endl; - (*testout) << "Face Descriptor: " << fd << endl; - PrintMessage (2, "Surface ", k); - - int oldnf = mesh.GetNSE(); - - const Surface * surf = - geom.GetSurface((mesh.GetFaceDescriptor(k).SurfNr())); - - /* - if (surf -> GetBCProperty() != -1) - fd.SetBCProperty (surf->GetBCProperty()); - else - { - bccnt++; - fd.SetBCProperty (bccnt); - } - */ - - segments.SetSize (0); - for (int i = 1; i <= mesh.GetNSeg(); i++) - { - Segment * seg = &mesh.LineSegment(i); - if (seg->si == k) - segments.Append (*seg); - } - - for (int i = 1; i <= geom.identifications.Size(); i++) - { - geom.identifications.Elem(i)->GetIdentifiedFaces (fpairs); - int found = 0; - for (int j = 1; j <= fpairs.Size(); j++) - if (fpairs.Get(j).I1() == k || fpairs.Get(j).I2() == k) - found = 1; - - if (!found) - continue; - - geom.identifications.Get(i)-> - BuildSurfaceElements(segments, mesh, surf); - if (!segments.Size()) - break; - } - - - if (multithread.terminate) return; - - for (int i = oldnf+1; i <= mesh.GetNSE(); i++) - mesh.SurfaceElement(i).SetIndex (k); - - - if (!segments.Size()) - { - masterface.Elem(k) = k; - changed = 1; - } - - PrintMessage (3, (mesh.GetNSE() - oldnf), " elements, ", mesh.GetNP(), " points"); - } - -#ifdef OPENGL - extern void Render(); - Render(); -#endif - } - while (changed); - - mesh.SplitSeparatedFaces(); - mesh.CalcSurfacesOfNode(); - - multithread.task = savetask; - } - - - - - - - - int GenerateMesh (CSGeometry & geom, - Mesh *& mesh, - int perfstepsstart, int perfstepsend, - const char * optstr) - { - - if (mesh && mesh->GetNSE() && - !geom.GetNSolids()) - { - if (perfstepsstart < MESHCONST_MESHVOLUME) - perfstepsstart = MESHCONST_MESHVOLUME; - } - - - - if (perfstepsstart <= MESHCONST_ANALYSE) - { - delete mesh; - mesh = new Mesh(); - - mesh->SetGlobalH (mparam.maxh); - - ARRAY<double> maxhdom(geom.GetNTopLevelObjects()); - for (int i = 0; i < maxhdom.Size(); i++) - maxhdom[i] = geom.GetTopLevelObject(i)->GetMaxH(); - - mesh->SetMaxHDomain (maxhdom); - - if (mparam.uselocalh) - { - double maxsize = geom.MaxSize(); - mesh->SetLocalH (Point<3>(-maxsize, -maxsize, -maxsize), - Point<3>(maxsize, maxsize, maxsize), - mparam.grading); - - mesh -> LoadLocalMeshSize (mparam.meshsizefilename); - } - - spoints.SetSize(0); - FindPoints (geom, *mesh); - - PrintMessage (5, "find points done"); - -#ifdef LOG_STREAM - (*logout) << "Special points found" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl << endl; -#endif - } - - - if (multithread.terminate || perfstepsend <= MESHCONST_ANALYSE) - return TCL_OK; - - - if (perfstepsstart <= MESHCONST_MESHEDGES) - { - FindEdges (geom, *mesh); - if (multithread.terminate) return TCL_OK; -#ifdef LOG_STREAM - (*logout) << "Edges meshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - - - if (multithread.terminate) - return TCL_OK; - - if (mparam.uselocalh) - { - mesh->CalcLocalH(); - mesh->DeleteMesh(); - - FindPoints (geom, *mesh); - if (multithread.terminate) return TCL_OK; - FindEdges (geom, *mesh); - if (multithread.terminate) return TCL_OK; - - mesh->DeleteMesh(); - - FindPoints (geom, *mesh); - if (multithread.terminate) return TCL_OK; - FindEdges (geom, *mesh); - if (multithread.terminate) return TCL_OK; - } - } - - if (multithread.terminate || perfstepsend <= MESHCONST_MESHEDGES) - return TCL_OK; - - - if (perfstepsstart <= MESHCONST_MESHSURFACE) - { - MeshSurface (geom, *mesh); - if (multithread.terminate) return TCL_OK; - -#ifdef LOG_STREAM - (*logout) << "Surfaces meshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - - if (mparam.uselocalh && 0) - { - mesh->CalcLocalH(); - mesh->DeleteMesh(); - - FindPoints (geom, *mesh); - if (multithread.terminate) return TCL_OK; - FindEdges (geom, *mesh); - if (multithread.terminate) return TCL_OK; - - MeshSurface (geom, *mesh); - if (multithread.terminate) return TCL_OK; - } - -#ifdef LOG_STREAM - (*logout) << "Surfaces remeshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - -#ifdef STAT_STREAM - (*statout) << mesh->GetNSeg() << " & " - << mesh->GetNSE() << " & - &" - << GetTime() << " & " << endl; -#endif - - MeshQuality2d (*mesh); - mesh->CalcSurfacesOfNode(); - } - - if (multithread.terminate || perfstepsend <= MESHCONST_OPTSURFACE) - return TCL_OK; - - - if (perfstepsstart <= MESHCONST_MESHVOLUME) - { - multithread.task = "Volume meshing"; - - MESHING3_RESULT res = - MeshVolume (mparam, *mesh); - - if (res != MESHING3_OK) return TCL_ERROR; - - if (multithread.terminate) return TCL_OK; - - RemoveIllegalElements (*mesh); - if (multithread.terminate) return TCL_OK; - - MeshQuality3d (*mesh); - - for (int i = 0; i < geom.GetNTopLevelObjects(); i++) - mesh->SetMaterial (i+1, geom.GetTopLevelObject(i)->GetMaterial().c_str()); - - -#ifdef STAT_STREAM - (*statout) << GetTime() << " & "; -#endif - -#ifdef LOG_STREAM - (*logout) << "Volume meshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - } - - if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME) - return TCL_OK; - - - if (perfstepsstart <= MESHCONST_OPTVOLUME) - { - multithread.task = "Volume optimization"; - - OptimizeVolume (mparam, *mesh); - if (multithread.terminate) return TCL_OK; - -#ifdef STAT_STREAM - (*statout) << GetTime() << " & " - << mesh->GetNE() << " & " - << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; -#endif - -#ifdef LOG_STREAM - (*logout) << "Volume optimized" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - } - - return TCL_OK; - } -} diff --git a/Netgen/libsrc/csg/geometry.cpp b/Netgen/libsrc/csg/geometry.cpp deleted file mode 100644 index 14806ee9cb..0000000000 --- a/Netgen/libsrc/csg/geometry.cpp +++ /dev/null @@ -1,1792 +0,0 @@ -/* A Bison parser, made from geometry.yy - by GNU bison 1.35. */ - -#define YYBISON 1 /* Identify Bison output. */ - -# define NUM 257 -# define TOK_SOLID 258 -# define TOK_RECO 259 -# define TOK_TLO 260 -# define TOK_BOUNDINGBOX 261 -# define IDENT 262 -# define IDENTSOLID 263 -# define TOK_SPHERE 264 -# define TOK_CYLINDER 265 -# define TOK_CONE 266 -# define TOK_PLAIN 267 -# define TOK_TUBE 268 -# define TOK_GENCYL 269 -# define TOK_ORTHOBRICK 270 -# define TOK_POLYHEDRON 271 -# define TOK_REVOLUTION 272 -# define TOK_OR 273 -# define TOK_AND 274 -# define TOK_NOT 275 -# define TOK_TRANSLATE 276 -# define TOK_MULTITRANSLATE 277 -# define TOK_ROTATE 278 -# define TOK_MULTIROTATE 279 -# define TOK_SINGULAR 280 -# define TOK_EDGE 281 -# define TOK_POINT 282 -# define TOK_IDENTIFY 283 -# define TOK_CLOSESURFACES 284 -# define TOK_CLOSEEDGES 285 -# define TOK_PERIODIC 286 -# define TOK_BOUNDARYCONDITION 287 - -#line 1 "geometry.yy" - -//define YYDEBUG 1 - -extern int yylex (); - -#include <mystdlib.h> - -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - -namespace netgen -{ -netgen::CSGeometry * parsegeom; -} - -using namespace netgen; - -// extern ARRAY<Surface*> surfaces; -// extern SYMBOLTABLE<Solid*> solids; - - -int yyerror (char * s); -splinetube * tube; -spline3d * middlecurve; -Point<3> splinep1; -BSplineCurve2d *bspline; -Flags parseflags; -extern int linenum; -ARRAY<double> doublearray; -ARRAY<char*> stringarray; - -Polyhedra * polyhedron; -// Revolution * revolution; - -#line 38 "geometry.yy" -#ifndef YYSTYPE -typedef union { -double val; -char * chptr; -Solid * solidtype; -} yystype; -# define YYSTYPE yystype -# define YYSTYPE_IS_TRIVIAL 1 -#endif -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - - - -#define YYFINAL 260 -#define YYFLAG -32768 -#define YYNTBASE 42 - -/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 287 ? yytranslate[x] : 67) - -/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ -static const char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 36, 37, 2, 2, 38, 39, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, - 2, 35, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 40, 2, 41, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33 -}; - -#if YYDEBUG -static const short yyprhs[] = -{ - 0, 0, 1, 6, 7, 11, 12, 19, 21, 23, - 27, 31, 34, 38, 49, 66, 85, 100, 115, 116, - 125, 136, 149, 166, 185, 189, 191, 195, 197, 203, - 209, 217, 221, 223, 227, 229, 233, 245, 246, 252, - 253, 254, 261, 262, 266, 272, 279, 285, 291, 296, - 300, 305, 320, 329, 334, 335, 338, 339, 342, 345, - 350, 355, 360, 365, 366, 371, 373, 377, 378, 383, - 385, 389, 391 -}; -static const short yyrhs[] = -{ - -1, 43, 5, 44, 54, 0, 0, 44, 45, 34, - 0, 0, 4, 8, 35, 47, 46, 56, 0, 48, - 0, 9, 0, 47, 19, 47, 0, 47, 20, 47, - 0, 21, 47, 0, 36, 47, 37, 0, 10, 36, - 3, 38, 3, 38, 3, 34, 3, 37, 0, 11, - 36, 3, 38, 3, 38, 3, 34, 3, 38, 3, - 38, 3, 34, 3, 37, 0, 12, 36, 3, 38, - 3, 38, 3, 34, 3, 34, 3, 38, 3, 38, - 3, 34, 3, 37, 0, 13, 36, 3, 38, 3, - 38, 3, 34, 3, 38, 3, 38, 3, 37, 0, - 16, 36, 3, 38, 3, 38, 3, 34, 3, 38, - 3, 38, 3, 37, 0, 0, 17, 36, 49, 50, - 34, 34, 51, 37, 0, 22, 36, 3, 38, 3, - 38, 3, 34, 47, 37, 0, 23, 36, 3, 38, - 3, 38, 3, 34, 3, 34, 47, 37, 0, 24, - 36, 3, 38, 3, 38, 3, 34, 3, 38, 3, - 38, 3, 34, 47, 37, 0, 25, 36, 3, 38, - 3, 38, 3, 34, 3, 38, 3, 38, 3, 34, - 3, 34, 47, 37, 0, 50, 34, 52, 0, 52, - 0, 51, 34, 53, 0, 53, 0, 3, 38, 3, - 38, 3, 0, 3, 38, 3, 38, 3, 0, 3, - 38, 3, 38, 3, 38, 3, 0, 67, 34, 68, - 0, 68, 0, 3, 38, 3, 0, 70, 0, 70, - 38, 69, 0, 3, 38, 3, 38, 3, 38, 3, - 38, 3, 38, 3, 0, 0, 3, 38, 3, 72, - 73, 0, 0, 0, 38, 3, 38, 3, 74, 73, - 0, 0, 54, 55, 34, 0, 26, 27, 3, 9, - 9, 0, 26, 28, 3, 9, 9, 9, 0, 29, - 30, 9, 9, 56, 0, 29, 31, 9, 9, 9, - 0, 29, 32, 9, 9, 0, 6, 9, 56, 0, - 6, 9, 9, 56, 0, 7, 36, 3, 38, 3, - 38, 3, 34, 3, 38, 3, 38, 3, 37, 0, - 28, 36, 3, 38, 3, 38, 3, 37, 0, 33, - 9, 9, 3, 0, 0, 57, 58, 0, 0, 59, - 58, 0, 39, 66, 0, 39, 66, 35, 66, 0, - 39, 66, 35, 3, 0, 39, 66, 35, 60, 0, - 39, 66, 35, 63, 0, 0, 40, 61, 62, 41, - 0, 3, 0, 62, 38, 3, 0, 0, 40, 64, - 65, 41, 0, 66, 0, 65, 38, 66, 0, 8, - 0, 9, 0 -}; - -#endif - -#if YYDEBUG -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const short yyrline[] = -{ - 0, 61, 61, 79, 81, 84, 84, 94, 96, 97, - 98, 99, 100, 103, 112, 123, 135, 144, 158, 158, - 197, 206, 222, 231, 285, 287, 289, 291, 293, 300, - 306, 315, 317, 319, 331, 333, 335, 345, 345, 354, - 356, 356, 372, 374, 377, 385, 394, 409, 425, 439, - 453, 470, 477, 482, 511, 511, 516, 518, 521, 524, - 526, 528, 530, 535, 535, 540, 542, 545, 545, 556, - 563, 574, 576 -}; -#endif - - -#if (YYDEBUG) || defined YYERROR_VERBOSE - -/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ -static const char *const yytname[] = -{ - "$", "error", "$undefined.", "NUM", "TOK_SOLID", "TOK_RECO", "TOK_TLO", - "TOK_BOUNDINGBOX", "IDENT", "IDENTSOLID", "TOK_SPHERE", "TOK_CYLINDER", - "TOK_CONE", "TOK_PLAIN", "TOK_TUBE", "TOK_GENCYL", "TOK_ORTHOBRICK", - "TOK_POLYHEDRON", "TOK_REVOLUTION", "TOK_OR", "TOK_AND", "TOK_NOT", - "TOK_TRANSLATE", "TOK_MULTITRANSLATE", "TOK_ROTATE", "TOK_MULTIROTATE", - "TOK_SINGULAR", "TOK_EDGE", "TOK_POINT", "TOK_IDENTIFY", - "TOK_CLOSESURFACES", "TOK_CLOSEEDGES", "TOK_PERIODIC", - "TOK_BOUNDARYCONDITION", "';'", "'='", "'('", "')'", "','", "'-'", - "'['", "']'", "input", "@1", "recsoliddef", "soliddef", "@2", "solid", - "solidprimitive", "@3", "polyhedronpoints", "polyhedronfaces", - "polyhedronpoint", "polyhedronface", "recadddef", "adddef", "flaglist", - "@6", "recflaglist", "flag", "numlistbrack", "@7", "numlist", - "stringlistbrack", "@8", "stringlist", "anyident", 0 -}; -#endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const short yyr1[] = -{ - 0, 43, 42, 44, 44, 46, 45, 47, 47, 47, - 47, 47, 47, 48, 48, 48, 48, 48, 49, 48, - 48, 48, 48, 48, 50, 50, 51, 51, 52, 53, - 53, 67, 67, 68, 69, 69, 70, 72, 71, 73, - 74, 73, 54, 54, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 57, 56, 58, 58, 59, 59, - 59, 59, 59, 61, 60, 62, 62, 64, 63, 65, - 65, 66, 66 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const short yyr2[] = -{ - 0, 0, 4, 0, 3, 0, 6, 1, 1, 3, - 3, 2, 3, 10, 16, 18, 14, 14, 0, 8, - 10, 12, 16, 18, 3, 1, 3, 1, 5, 5, - 7, 3, 1, 3, 1, 3, 11, 0, 5, 0, - 0, 6, 0, 3, 5, 6, 5, 5, 4, 3, - 4, 14, 8, 4, 0, 2, 0, 2, 2, 4, - 4, 4, 4, 0, 4, 1, 3, 0, 4, 1, - 3, 1, 1 -}; - -/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ -static const short yydefact[] = -{ - 1, 0, 3, 42, 0, 0, 2, 0, 4, 0, - 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 7, 54, 49, 56, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 11, - 0, 0, 0, 0, 0, 0, 0, 54, 50, 0, - 55, 56, 0, 0, 0, 0, 54, 0, 48, 53, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 9, 10, 6, 71, 72, 58, 57, 0, 44, - 0, 0, 46, 47, 0, 0, 0, 0, 0, 0, - 0, 25, 0, 0, 0, 0, 0, 0, 45, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 60, 67, 61, 62, 59, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, - 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, - 0, 0, 27, 0, 0, 0, 0, 65, 0, 0, - 69, 0, 0, 0, 0, 0, 0, 28, 0, 0, - 19, 0, 0, 0, 0, 0, 64, 0, 68, 0, - 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, - 0, 66, 70, 0, 13, 0, 0, 0, 0, 0, - 20, 0, 0, 0, 0, 0, 0, 0, 0, 29, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, - 0, 0, 51, 0, 0, 0, 0, 30, 0, 0, - 0, 0, 16, 17, 0, 0, 0, 0, 0, 0, - 14, 0, 22, 0, 0, 0, 15, 23, 0, 0, - 0 -}; - -static const short yydefgoto[] = -{ - 258, 1, 3, 5, 67, 40, 41, 85, 110, 161, - 111, 162, 6, 15, 43, 44, 70, 71, 133, 150, - 168, 134, 151, 169, 96 -}; - -static const short yypact[] = -{ - -32768, 5,-32768, 18, 21, 7, 14, 11,-32768, 52, - 35, 36, 39, 28, 56, 42, 2, 58, 66, 74, - 75, 76, 71, 72, 73, 77,-32768,-32768, 48, 49, - 51, 53, 55, 57, 2, 59, 60, 61, 62, 2, - 54,-32768,-32768,-32768, 44, 50, 81, 83, 63, 85, - 90, 91, 99, 100, 101, 102, 103, 104,-32768,-32768, - 105, 106, 107, 108, -3, 2, 2,-32768,-32768, 47, - -32768, 44, 109, 110, 111, 112,-32768, 113,-32768,-32768, - 78, 79, 80, 86, 87, 118, 88, 89, 92, 93, - -32768,-32768,-32768,-32768,-32768,-32768, 94,-32768, 95,-32768, - 114, 96,-32768,-32768, 125, 129, 132, 133, 134, 115, - 116,-32768, 135, 136, 137, 138, -1, 139,-32768, 140, - 117, 119, 120, 121, 122, 141, 1, 123, 124, 126, - 127,-32768, 142,-32768,-32768,-32768, 144, 130, 143, 145, - 146, 148, 149, 128, 151,-32768, 153, 160, 165, 166, - 167, 47, 168,-32768, 147, 150, 152, 154, 155, 169, - 156, -28,-32768, 157, 158, 159, 161,-32768, -8, 16, - -32768, 162, 170, 171, 172, 173, 176,-32768, 177, 151, - -32768, 2, 179, 180, 182, 184,-32768, 47,-32768, 187, - 164, 174, 163, 175, 178, 183,-32768, 25, 181, 185, - 186,-32768,-32768, 188,-32768, 193, 195, 196, 199, 200, - -32768, 2, 201, 202, 203, 189, 190, 191, 192, 194, - 29, 197, 198, 204, 205, 206, 208, 211, 214,-32768, - 215, 217,-32768, 209, 207, 210, 212,-32768, 216, 218, - 219, 222,-32768,-32768, 2, 228, 220, 221, 31, 224, - -32768, 230,-32768, 2, 223, 33,-32768,-32768, 234, 237, - -32768 -}; - -static const short yypgoto[] = -{ - -32768,-32768,-32768,-32768,-32768, -34,-32768,-32768,-32768,-32768, - -13, -65,-32768,-32768, -39,-32768, 213,-32768,-32768,-32768, - -32768,-32768,-32768,-32768, -115 -}; - - -#define YYLAST 284 - - -static const short yytable[] = -{ - 59, 135, 131, 68, 109, 64, 179, 94, 95, 180, - 2, 27, 28, 29, 30, 31, 65, 66, 32, 33, - 9, 10, 4, 34, 35, 36, 37, 38, 93, 7, - 185, 91, 92, 186, 90, 144, 170, 102, 39, 132, - 11, 8, 12, 13, 65, 66, 16, 14, 65, 66, - 65, 66, 65, 66, 187, 94, 95, 188, 22, 23, - 24, 17, 210, 19, 20, 25, 229, 42, 252, 45, - 257, 18, 202, 65, 66, 21, 26, 46, 47, 48, - 49, 50, 51, 69, 53, 54, 52, 55, 72, 56, - 73, 57, 74, 58, 76, 60, 61, 62, 63, 77, - 78, 75, 79, 80, 81, 82, 83, 84, 86, 87, - 88, 89, 98, 145, 196, 101, 104, 105, 106, 99, - 100, 109, 103, 118, 107, 108, 112, 113, 120, 116, - 114, 115, 121, 117, 119, 122, 123, 124, 127, 128, - 129, 130, 136, 137, 143, -63, 154, 197, 155, 156, - 126, 157, 158, 125, 160, 138, 163, 139, 140, 141, - 142, 146, 147, 164, 148, 149, 159, 153, 165, 166, - 167, 171, 177, 190, 191, 192, 193, 220, 152, 194, - 195, 172, 198, 199, 173, 200, 174, 201, 175, 176, - 203, 181, 182, 183, 178, 184, 215, 206, 216, 217, - 189, 204, 218, 219, 221, 222, 223, 0, 233, 234, - 248, 235, 205, 207, 236, 211, 208, 237, 238, 255, - 239, 209, 246, 212, 213, 247, 214, 224, 225, 226, - 227, 249, 228, 254, 259, 230, 231, 260, 0, 0, - 0, 232, 0, 240, 0, 241, 0, 242, 0, 243, - 244, 0, 245, 0, 0, 251, 0, 250, 253, 0, - 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 97 -}; - -static const short yycheck[] = -{ - 34, 116, 3, 42, 3, 39, 34, 8, 9, 37, - 5, 9, 10, 11, 12, 13, 19, 20, 16, 17, - 6, 7, 4, 21, 22, 23, 24, 25, 67, 8, - 38, 65, 66, 41, 37, 34, 151, 76, 36, 40, - 26, 34, 28, 29, 19, 20, 35, 33, 19, 20, - 19, 20, 19, 20, 38, 8, 9, 41, 30, 31, - 32, 9, 37, 27, 28, 9, 37, 9, 37, 3, - 37, 36, 187, 19, 20, 36, 34, 3, 3, 3, - 9, 9, 9, 39, 36, 36, 9, 36, 38, 36, - 9, 36, 9, 36, 9, 36, 36, 36, 36, 9, - 9, 38, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 126, 179, 3, 38, 38, 38, 9, - 9, 3, 9, 9, 38, 38, 38, 38, 3, 35, - 38, 38, 3, 38, 38, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 181, 3, 3, - 34, 3, 3, 38, 3, 38, 3, 38, 38, 38, - 38, 38, 38, 3, 38, 38, 38, 37, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 211, 34, 3, - 3, 34, 3, 3, 34, 3, 34, 3, 34, 34, - 3, 34, 34, 34, 38, 34, 3, 34, 3, 3, - 38, 37, 3, 3, 3, 3, 3, -1, 3, 3, - 244, 3, 38, 38, 3, 34, 38, 3, 3, 253, - 3, 38, 3, 38, 38, 3, 38, 38, 38, 38, - 38, 3, 38, 3, 0, 38, 38, 0, -1, -1, - -1, 37, -1, 34, -1, 38, -1, 37, -1, 37, - 34, -1, 34, -1, -1, 34, -1, 37, 34, -1, - 37, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 71 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison/bison.simple" - -/* Skeleton output parser for bison, - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser when - the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -#ifndef YYPARSE_RETURN_TYPE -#define YYPARSE_RETURN_TYPE int -#endif - -#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || ((YYLTYPE_IS_TRIVIAL || ! YYLSP_NEEDED) && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; -# if YYLSP_NEEDED - YYLTYPE yyls; -# endif -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# if YYLSP_NEEDED -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAX) -# else -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAX) -# endif - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up"); \ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). - - When YYLLOC_DEFAULT is run, CURRENT is set the location of the - first token. By default, to implement support for ranges, extend - its range to the last symbol. */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#if YYPURE -# if YYLSP_NEEDED -# ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -# else -# define YYLEX yylex (&yylval, &yylloc) -# endif -# else /* !YYLSP_NEEDED */ -# ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -# else -# define YYLEX yylex (&yylval) -# endif -# endif /* !YYLSP_NEEDED */ -#else /* !YYPURE */ -# define YYLEX yylex () -#endif /* !YYPURE */ - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -#endif /* !YYDEBUG */ - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - -#ifdef YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif -#endif - -#line 319 "/usr/share/bison/bison.simple" - - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -# define YYPARSE_PARAM_DECL -# else -# define YYPARSE_PARAM_ARG YYPARSE_PARAM -# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -# endif -#else /* !YYPARSE_PARAM */ -# define YYPARSE_PARAM_ARG -# define YYPARSE_PARAM_DECL -#endif /* !YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -# ifdef YYPARSE_PARAM -YYPARSE_RETURN_TYPE yyparse (void *); -# else -YYPARSE_RETURN_TYPE yyparse (void); -# endif -#endif - -/* YY_DECL_VARIABLES -- depending whether we use a pure parser, - variables are global, or local to YYPARSE. */ - -#define YY_DECL_NON_LSP_VARIABLES \ -/* The lookahead symbol. */ \ -int yychar; \ - \ -/* The semantic value of the lookahead symbol. */ \ -YYSTYPE yylval; \ - \ -/* Number of parse errors so far. */ \ -int yynerrs; - -#if YYLSP_NEEDED -# define YY_DECL_VARIABLES \ -YY_DECL_NON_LSP_VARIABLES \ - \ -/* Location data for the lookahead symbol. */ \ -YYLTYPE yylloc; -#else -# define YY_DECL_VARIABLES \ -YY_DECL_NON_LSP_VARIABLES -#endif - - -/* If nonreentrant, generate the variables here. */ - -#if !YYPURE -YY_DECL_VARIABLES -#endif /* !YYPURE */ - -YYPARSE_RETURN_TYPE -yyparse (YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - /* If reentrant, generate the variables here. */ -#if YYPURE - YY_DECL_VARIABLES -#endif /* !YYPURE */ - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yychar1 = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - -#if YYLSP_NEEDED - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; -#endif - -#if YYLSP_NEEDED -# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -# define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - YYSIZE_T yystacksize = YYINITDEPTH; - - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; -#if YYLSP_NEEDED - YYLTYPE yyloc; -#endif - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; -#if YYLSP_NEEDED - yylsp = yyls; -#endif - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. */ -# if YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - yyls = yyls1; -# else - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); -# endif - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - goto yyoverflowlab; - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); -# if YYLSP_NEEDED - YYSTACK_RELOCATE (yyls); -# endif -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; -#if YYLSP_NEEDED - yylsp = yyls + yysize - 1; -#endif - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yychar1 = YYTRANSLATE (yychar); - -#if YYDEBUG - /* We have to keep this `#if YYDEBUG', since we use variables - which are defined only if `YYDEBUG' is set. */ - if (yydebug) - { - YYFPRINTF (stderr, "Next token is %d (%s", - yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise - meaning of a token, for further debugging info. */ -# ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -# endif - YYFPRINTF (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %d (%s), ", - yychar, yytname[yychar1])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to the semantic value of - the lookahead token. This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - -#if YYLSP_NEEDED - /* Similarly for the default location. Let the user run additional - commands if for instance locations are ranges. */ - yyloc = yylsp[1-yylen]; - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); -#endif - -#if YYDEBUG - /* We have to keep this `#if YYDEBUG', since we use variables which - are defined only if `YYDEBUG' is set. */ - if (yydebug) - { - int yyi; - - YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) - YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); - YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - switch (yyn) { - -case 1: -#line 62 "geometry.yy" -{ - linenum = 1; - ; - break;} -case 2: -#line 69 "geometry.yy" -{ - int i; - extern ARRAY<char*> parsestrings; - for (i = 0; i < parsestrings.Size(); i++) - delete [] parsestrings[i]; - parsestrings.SetSize(0); - ; - break;} -case 5: -#line 86 "geometry.yy" -{ parsegeom->SetSolid(yyvsp[-2].chptr, new Solid (Solid::ROOT, yyvsp[0].solidtype)); - ; - break;} -case 6: -#line 89 "geometry.yy" -{ - parsegeom->SetFlags(yyvsp[-4].chptr, parseflags); - ; - break;} -case 8: -#line 96 "geometry.yy" -{ yyval.solidtype = (Solid*)parsegeom->GetSolid(yyvsp[0].chptr); ; - break;} -case 9: -#line 97 "geometry.yy" -{ yyval.solidtype = new Solid (Solid::UNION, yyvsp[-2].solidtype, yyvsp[0].solidtype); ; - break;} -case 10: -#line 98 "geometry.yy" -{ yyval.solidtype = new Solid (Solid::SECTION, yyvsp[-2].solidtype, yyvsp[0].solidtype); ; - break;} -case 11: -#line 99 "geometry.yy" -{ yyval.solidtype = new Solid (Solid::SUB, yyvsp[0].solidtype); ; - break;} -case 12: -#line 100 "geometry.yy" -{ yyval.solidtype = yyvsp[-1].solidtype; ; - break;} -case 13: -#line 106 "geometry.yy" -{ - OneSurfacePrimitive * surf = new Sphere (Point<3> (yyvsp[-7].val, yyvsp[-5].val, yyvsp[-3].val), yyvsp[-1].val); - parsegeom -> AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - yyval.solidtype = new Solid (surf); - ; - break;} -case 14: -#line 116 "geometry.yy" -{ - OneSurfacePrimitive * surf = new Cylinder (Point<3> (yyvsp[-13].val, yyvsp[-11].val, yyvsp[-9].val), - Point<3> (yyvsp[-7].val, yyvsp[-5].val, yyvsp[-3].val), yyvsp[-1].val); - parsegeom->AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - yyval.solidtype = new Solid (surf); - ; - break;} -case 15: -#line 128 "geometry.yy" -{ - OneSurfacePrimitive * surf = new Cone (Point<3> (yyvsp[-15].val, yyvsp[-13].val, yyvsp[-11].val), - Point<3> (yyvsp[-7].val, yyvsp[-5].val, yyvsp[-3].val), yyvsp[-9].val, yyvsp[-1].val); - parsegeom->AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - yyval.solidtype = new Solid (surf); - ; - break;} -case 16: -#line 137 "geometry.yy" -{ - OneSurfacePrimitive * surf = new Plane ( Point<3> (yyvsp[-11].val, yyvsp[-9].val, yyvsp[-7].val), - Vec<3> (yyvsp[-5].val, yyvsp[-3].val, yyvsp[-1].val) ); - parsegeom->AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - yyval.solidtype = new Solid (surf); - ; - break;} -case 17: -#line 146 "geometry.yy" -{ - Primitive * nprim = new OrthoBrick (Point<3> (yyvsp[-11].val, yyvsp[-9].val, yyvsp[-7].val), - Point<3> (yyvsp[-5].val, yyvsp[-3].val, yyvsp[-1].val)); - for (int j = 0; j < nprim->GetNSurfaces(); j++) - { - parsegeom->AddSurface (&nprim->GetSurface(j)); - nprim->SetSurfaceId (j, parsegeom->GetNSurf()-1); - yyval.solidtype = new Solid (nprim); - } - ; - break;} -case 18: -#line 159 "geometry.yy" -{ - polyhedron = new Polyhedra (); - ; - break;} -case 19: -#line 164 "geometry.yy" -{ - int j; - for (j = 0; j < polyhedron->GetNSurfaces(); j++) - { - parsegeom->AddSurface (&polyhedron->GetSurface(j)); - polyhedron->SetSurfaceId (j, parsegeom->GetNSurf()-1); - yyval.solidtype = new Solid (polyhedron); - } - ; - break;} -case 20: -#line 198 "geometry.yy" -{ - Solid * nsol = yyvsp[-1].solidtype -> Copy(*parsegeom); - Vec<3> v(yyvsp[-7].val, yyvsp[-5].val, yyvsp[-3].val); - Transformation<3> trans(v); - nsol -> Transform (trans); - yyval.solidtype = nsol; - ; - break;} -case 21: -#line 207 "geometry.yy" -{ - int i; - Solid * hsol = yyvsp[-1].solidtype; - for (i = 1; i <= yyvsp[-3].val; i++) - { - Solid * nsol = yyvsp[-1].solidtype -> Copy(*parsegeom); - Vec<3> v(yyvsp[-9].val, yyvsp[-7].val, yyvsp[-5].val); - v *= i; - Transformation<3> trans(v); - nsol -> Transform (trans); - hsol = new Solid (Solid::UNION, hsol, nsol); - } - yyval.solidtype = hsol; - ; - break;} -case 22: -#line 223 "geometry.yy" -{ - Solid * nsol = yyvsp[-1].solidtype -> Copy(*parsegeom); - Point<3> c(yyvsp[-13].val, yyvsp[-11].val, yyvsp[-9].val); - Transformation<3> rot(c, yyvsp[-7].val, yyvsp[-5].val, yyvsp[-3].val); - nsol -> Transform (rot); - yyval.solidtype = nsol; - ; - break;} -case 23: -#line 234 "geometry.yy" -{ - int i; - Solid * hsol = yyvsp[-1].solidtype; - - Point<3> c(yyvsp[-15].val, yyvsp[-13].val, yyvsp[-11].val); - Transformation<3> trans(c, yyvsp[-9].val, yyvsp[-7].val, yyvsp[-5].val); - Transformation<3> multi(Vec<3>(0,0,0)); - Transformation<3> ht; - - for (i = 1; i <= yyvsp[-3].val; i++) - { - Solid * nsol = yyvsp[-1].solidtype -> Copy(*parsegeom); - nsol -> Transform (multi); - hsol = new Solid (Solid::UNION, hsol, nsol); - - ht=multi; - multi.Combine (trans, ht); - } - yyval.solidtype = hsol; - ; - break;} -case 28: -#line 295 "geometry.yy" -{ - polyhedron->AddPoint (Point<3> (yyvsp[-4].val, yyvsp[-2].val, yyvsp[0].val)); - cout << " " << yyvsp[-4].val << " " << yyvsp[-2].val << " " << yyvsp[0].val << endl; - ; - break;} -case 29: -#line 302 "geometry.yy" -{ - polyhedron->AddFace (int(yyvsp[-4].val)-1, int(yyvsp[-2].val)-1, int(yyvsp[0].val)-1); - cout << yyvsp[-4].val << " " << yyvsp[-2].val << " " << yyvsp[0].val << endl; - ; - break;} -case 30: -#line 307 "geometry.yy" -{ - cout << "face, 1 = " << yyvsp[-6].val << " " << yyvsp[-4].val << " " << yyvsp[-2].val << " " << yyvsp[0].val << endl; - polyhedron->AddFace (int(yyvsp[-6].val)-1, int(yyvsp[-4].val)-1, int(yyvsp[-2].val)-1); - polyhedron->AddFace (int(yyvsp[-6].val)-1, int(yyvsp[-2].val)-1, int(yyvsp[0].val)-1); - cout << yyvsp[-6].val << yyvsp[-4].val << yyvsp[-2].val << yyvsp[0].val << endl; - ; - break;} -case 33: -#line 321 "geometry.yy" -{ -// revolution->AddPoint (Point<2> ($1, $3)); - cout << " " << yyvsp[-2].val << " " << yyvsp[0].val << endl; - ; - break;} -case 36: -#line 338 "geometry.yy" -{ - middlecurve->AddSegment (splinep1, Point<3> (yyvsp[-10].val, yyvsp[-8].val, yyvsp[-6].val), Point<3> (yyvsp[-4].val, yyvsp[-2].val, yyvsp[0].val)); - splinep1(0) = yyvsp[-4].val; splinep1(1) = yyvsp[-2].val; splinep1(2) = yyvsp[0].val; - ; - break;} -case 37: -#line 347 "geometry.yy" -{ - bspline = new BSplineCurve2d; - bspline -> AddPoint (Point<2> (yyvsp[-2].val, yyvsp[0].val)); - cout << "first point" << endl; - ; - break;} -case 39: -#line 355 "geometry.yy" -{ ; - break;} -case 40: -#line 357 "geometry.yy" -{ - bspline -> AddPoint (Point<2> (yyvsp[-2].val, yyvsp[0].val)); - cout << "Add Point: " << yyvsp[-2].val << "-" << yyvsp[0].val << endl; - ; - break;} -case 44: -#line 379 "geometry.yy" -{ cout << "singular edge:" << yyvsp[-2].val << " between " - << yyvsp[-1].chptr << " and " << yyvsp[0].chptr << endl; - parsegeom->singedges.Append - (new SingularEdge (yyvsp[-2].val, parsegeom->GetSolid(yyvsp[-1].chptr), - parsegeom->GetSolid(yyvsp[0].chptr))); - ; - break;} -case 45: -#line 387 "geometry.yy" -{ cout << "singular point:" << yyvsp[-3].val << " between " - << yyvsp[-2].chptr << ", " << yyvsp[-1].chptr << " and " << yyvsp[0].chptr << endl; - parsegeom->singpoints.Append - (new SingularPoint (yyvsp[-3].val, parsegeom->GetSolid(yyvsp[-2].chptr), - parsegeom->GetSolid(yyvsp[-1].chptr), - parsegeom->GetSolid(yyvsp[0].chptr))); - ; - break;} -case 46: -#line 396 "geometry.yy" -{ - ARRAY<int> si1, si2; - parsegeom->GetSolid(yyvsp[-2].chptr)->GetSurfaceIndices(si1); - parsegeom->GetSolid(yyvsp[-1].chptr)->GetSurfaceIndices(si2); - - parsegeom->AddIdentification ( - new CloseSurfaceIdentification ( - parsegeom->GetNIdentifications()+1, - *parsegeom, - parsegeom->GetSurface (si1[0]), - parsegeom->GetSurface (si2[0]), - parseflags)); - ; - break;} -case 47: -#line 411 "geometry.yy" -{ - ARRAY<int> si1, si2, si3; - parsegeom->GetSolid(yyvsp[-2].chptr)->GetSurfaceIndices(si1); - parsegeom->GetSolid(yyvsp[-1].chptr)->GetSurfaceIndices(si2); - parsegeom->GetSolid(yyvsp[0].chptr)->GetSurfaceIndices(si3); - - parsegeom->AddIdentification ( - new CloseEdgesIdentification ( - parsegeom->GetNIdentifications()+1, - *parsegeom, - parsegeom->GetSurface (si1.Get(1)), - parsegeom->GetSurface (si2.Get(1)), - parsegeom->GetSurface (si3.Get(1)))); - ; - break;} -case 48: -#line 427 "geometry.yy" -{ - ARRAY<int> si1, si2; - parsegeom->GetSolid(yyvsp[-1].chptr)->GetSurfaceIndices(si1); - parsegeom->GetSolid(yyvsp[0].chptr)->GetSurfaceIndices(si2); - - parsegeom->AddIdentification ( - new PeriodicIdentification ( - parsegeom->GetNIdentifications()+1, - *parsegeom, - parsegeom->GetSurface (si1.Get(1)), - parsegeom->GetSurface (si2.Get(1)))); - ; - break;} -case 49: -#line 441 "geometry.yy" -{ - int tlonr = - parsegeom->SetTopLevelObject ((Solid*)parsegeom->GetSolid(yyvsp[-1].chptr)); - TopLevelObject * tlo = parsegeom->GetTopLevelObject (tlonr); - if (parseflags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = parseflags.GetNumListFlag ("col"); - tlo->SetRGB (col[0], col[1], col[2]); - } - if (parseflags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - ; - break;} -case 50: -#line 455 "geometry.yy" -{ - ARRAY<int> si; - parsegeom->GetSolid(yyvsp[-1].chptr)->GetSurfaceIndices(si); - int tlonr = - parsegeom->SetTopLevelObject ((Solid*)parsegeom->GetSolid(yyvsp[-2].chptr), - (Surface*)parsegeom->GetSurface(si.Get(1))); - TopLevelObject * tlo = parsegeom->GetTopLevelObject (tlonr); - if (parseflags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = parseflags.GetNumListFlag ("col"); - tlo->SetRGB (col.Get(1), col.Get(2), col.Get(3)); - } - if (parseflags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - ; - break;} -case 51: -#line 473 "geometry.yy" -{ - parsegeom->SetBoundingBox (Box<3> (Point<3> (yyvsp[-11].val, yyvsp[-9].val, yyvsp[-7].val), - Point<3> (yyvsp[-5].val, yyvsp[-3].val, yyvsp[-1].val))); - ; - break;} -case 52: -#line 479 "geometry.yy" -{ - parsegeom->AddUserPoint (Point<3> (yyvsp[-5].val, yyvsp[-3].val, yyvsp[-1].val)); - ; - break;} -case 53: -#line 484 "geometry.yy" -{ - CSGeometry::BCModification bcm; - ARRAY<int> si; - - parsegeom->GetSolid(yyvsp[-2].chptr)->GetSurfaceIndices(si); - - bcm.tlonr = -1; - int i; - for (i = 0; i < parsegeom->GetNTopLevelObjects(); i++) - if (strcmp (parsegeom->GetTopLevelObject(i)->GetSolid()->Name(), yyvsp[-1].chptr) == 0) - { - bcm.tlonr = i; - break; - } - - bcm.bcnr = int(yyvsp[0].val); - for (i = 0; i < si.Size(); i++) - { - bcm.si = si[i]; - parsegeom->bcmodifications.Append (bcm); - } - ; - break;} -case 54: -#line 512 "geometry.yy" -{ parseflags.DeleteFlags (); ; - break;} -case 58: -#line 523 "geometry.yy" -{ parseflags.SetFlag (yyvsp[0].chptr); ; - break;} -case 59: -#line 525 "geometry.yy" -{ parseflags.SetFlag (yyvsp[-2].chptr, yyvsp[0].chptr); ; - break;} -case 60: -#line 527 "geometry.yy" -{ parseflags.SetFlag (yyvsp[-2].chptr, yyvsp[0].val); ; - break;} -case 61: -#line 529 "geometry.yy" -{ parseflags.SetFlag (yyvsp[-2].chptr, doublearray); ; - break;} -case 62: -#line 531 "geometry.yy" -{ parseflags.SetFlag (yyvsp[-2].chptr, stringarray); ; - break;} -case 63: -#line 536 "geometry.yy" -{ doublearray.SetSize (0); ; - break;} -case 65: -#line 541 "geometry.yy" -{ doublearray.Append (yyvsp[0].val); ; - break;} -case 66: -#line 542 "geometry.yy" -{ doublearray.Append (yyvsp[0].val); ; - break;} -case 67: -#line 547 "geometry.yy" -{ - int i; - for (i = 0; i < stringarray.Size(); i++) - delete stringarray[i]; - stringarray.SetSize (0); - ; - break;} -case 69: -#line 558 "geometry.yy" -{ - stringarray.Append (new char[strlen(yyvsp[0].chptr)+1]); - strcpy (stringarray.Last(), yyvsp[0].chptr); - ; - break;} -case 70: -#line 564 "geometry.yy" -{ - stringarray.Append (new char[strlen(yyvsp[0].chptr)+1]); - strcpy (stringarray.Last(), yyvsp[0].chptr); - ; - break;} -case 71: -#line 575 "geometry.yy" -{ yyval.chptr = yyvsp[0].chptr; ; - break;} -case 72: -#line 576 "geometry.yy" -{ yyval.chptr = yyvsp[0].chptr; ; - break;} -} - -#line 709 "/usr/share/bison/bison.simple" - - - yyvsp -= yylen; - yyssp -= yylen; -#if YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG - if (yydebug) - { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; -#if YYLSP_NEEDED - *++yylsp = yyloc; -#endif - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("parse error, unexpected ") + 1; - yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "parse error, unexpected "); - yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("parse error; also virtual memory exhausted"); - } - else -#endif /* defined (YYERROR_VERBOSE) */ - yyerror ("parse error"); - } - goto yyerrlab1; - - -/*--------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action | -`--------------------------------------------------*/ -yyerrlab1: - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - YYDPRINTF ((stderr, "Discarding token %d (%s).\n", - yychar, yytname[yychar1])); - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - - -/*-------------------------------------------------------------------. -| yyerrdefault -- current state does not do anything special for the | -| error token. | -`-------------------------------------------------------------------*/ -yyerrdefault: -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - - /* If its default is to accept any token, ok. Otherwise pop it. */ - yyn = yydefact[yystate]; - if (yyn) - goto yydefault; -#endif - - -/*---------------------------------------------------------------. -| yyerrpop -- pop the current state because it cannot handle the | -| error token | -`---------------------------------------------------------------*/ -yyerrpop: - if (yyssp == yyss) - YYABORT; - yyvsp--; - yystate = *--yyssp; -#if YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG - if (yydebug) - { - short *yyssp1 = yyss - 1; - YYFPRINTF (stderr, "Error: state stack now"); - while (yyssp1 != yyssp) - YYFPRINTF (stderr, " %d", *++yyssp1); - YYFPRINTF (stderr, "\n"); - } -#endif - -/*--------------. -| yyerrhandle. | -`--------------*/ -yyerrhandle: - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; -#if YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -/*---------------------------------------------. -| yyoverflowab -- parser overflow comes here. | -`---------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} -#line 577 "geometry.yy" - - - -int yyerror (char * s) -{ - cerr << s << " in line " << linenum << endl; - return 0; -} - diff --git a/Netgen/libsrc/csg/geometry.h b/Netgen/libsrc/csg/geometry.h deleted file mode 100644 index d84e8db183..0000000000 --- a/Netgen/libsrc/csg/geometry.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef BISON_GEOMETRY_H -# define BISON_GEOMETRY_H - -#ifndef YYSTYPE -typedef union { -double val; -char * chptr; -Solid * solidtype; -} yystype; -# define YYSTYPE yystype -# define YYSTYPE_IS_TRIVIAL 1 -#endif -# define NUM 257 -# define TOK_SOLID 258 -# define TOK_RECO 259 -# define TOK_TLO 260 -# define TOK_BOUNDINGBOX 261 -# define IDENT 262 -# define IDENTSOLID 263 -# define TOK_SPHERE 264 -# define TOK_CYLINDER 265 -# define TOK_CONE 266 -# define TOK_PLAIN 267 -# define TOK_TUBE 268 -# define TOK_GENCYL 269 -# define TOK_ORTHOBRICK 270 -# define TOK_POLYHEDRON 271 -# define TOK_REVOLUTION 272 -# define TOK_OR 273 -# define TOK_AND 274 -# define TOK_NOT 275 -# define TOK_TRANSLATE 276 -# define TOK_MULTITRANSLATE 277 -# define TOK_ROTATE 278 -# define TOK_MULTIROTATE 279 -# define TOK_SINGULAR 280 -# define TOK_EDGE 281 -# define TOK_POINT 282 -# define TOK_IDENTIFY 283 -# define TOK_CLOSESURFACES 284 -# define TOK_CLOSEEDGES 285 -# define TOK_PERIODIC 286 -# define TOK_BOUNDARYCONDITION 287 - - -extern YYSTYPE yylval; - -#endif /* not BISON_GEOMETRY_H */ diff --git a/Netgen/libsrc/csg/geometry.ll b/Netgen/libsrc/csg/geometry.ll deleted file mode 100644 index bb2edbc9f5..0000000000 --- a/Netgen/libsrc/csg/geometry.ll +++ /dev/null @@ -1,94 +0,0 @@ -%{ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - - - -// extern SYMBOLTABLE<Solid*> solids; -namespace netgen { -extern CSGeometry * parsegeom; -} -using namespace netgen; - -#include "geometry.h" - - -ARRAY<char*> parsestrings; -int linenum; -%} - -dig [0-9] -id [a-zA-Z][a-zA-Z0-9]* -num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? -num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? -number {num1}|{num2} -%x incl -%x comment - -%% -algebraic3d { return TOK_RECO; } -solid { return TOK_SOLID; } -tlo { return TOK_TLO; } -and { return TOK_AND; } -or { return TOK_OR; } -not { return TOK_NOT; } -translate { return TOK_TRANSLATE; } -multitranslate { return TOK_MULTITRANSLATE; } -rotate { return TOK_ROTATE; } -multirotate { return TOK_MULTIROTATE; } -sphere { return TOK_SPHERE; } -cylinder { return TOK_CYLINDER; } -cone { return TOK_CONE; } -plain { return TOK_PLAIN; } -plane { return TOK_PLAIN; } -tube { return TOK_TUBE; } -gencyl { return TOK_GENCYL; } -orthobrick { return TOK_ORTHOBRICK; } -polyhedron { return TOK_POLYHEDRON; } -revolution { return TOK_REVOLUTION; } - -singular { return TOK_SINGULAR; } -edge { return TOK_EDGE; } -point { return TOK_POINT; } - -identify { return TOK_IDENTIFY; } -closesurfaces { return TOK_CLOSESURFACES; } -closeedges { return TOK_CLOSEEDGES; } -periodic { return TOK_PERIODIC; } -boundarycondition { return TOK_BOUNDARYCONDITION; } -boundingbox { return TOK_BOUNDINGBOX; } - -{number} { yylval.val = atof (YYText()); return NUM; } -{id}+ { - yylval.chptr = new char [YYLeng()+1]; - parsestrings.Append (yylval.chptr); - strcpy (yylval.chptr, YYText()); - if (parsegeom->GetSolid (yylval.chptr)) - return IDENTSOLID; - else - return IDENT; - } -[ \t] /* eat up ws */ -. { return int(*YYText()); } -\n { linenum++; } -"##".*\n { linenum++; cout << (YYText()+2) ; } /* line comment */ -"#".*\n { linenum++; } /* line comment */ - - -%% - -extern FlexLexer * lexer; - -int yylex () - { - return lexer -> yylex(); - } - -extern "C" int yywrap () - { - return 1; - } diff --git a/Netgen/libsrc/csg/geometry.yy b/Netgen/libsrc/csg/geometry.yy deleted file mode 100644 index 49dd63a53a..0000000000 --- a/Netgen/libsrc/csg/geometry.yy +++ /dev/null @@ -1,585 +0,0 @@ -%{ -//define YYDEBUG 1 - -extern int yylex (); - -#include <mystdlib.h> - -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - -namespace netgen -{ -netgen::CSGeometry * parsegeom; -} - -using namespace netgen; - -// extern ARRAY<Surface*> surfaces; -// extern SYMBOLTABLE<Solid*> solids; - - -int yyerror (char * s); -splinetube * tube; -spline3d * middlecurve; -Point<3> splinep1; -BSplineCurve2d *bspline; -Flags parseflags; -extern int linenum; -ARRAY<double> doublearray; -ARRAY<char*> stringarray; - -Polyhedra * polyhedron; -// Revolution * revolution; -%} - -%union { -double val; -char * chptr; -Solid * solidtype; -} - -%token <val> NUM -%token TOK_SOLID, TOK_RECO, TOK_TLO, TOK_BOUNDINGBOX -%token <chptr> IDENT IDENTSOLID -%token <solidtype> TOK_SPHERE TOK_CYLINDER TOK_CONE TOK_PLAIN TOK_TUBE TOK_GENCYL TOK_ORTHOBRICK TOK_POLYHEDRON TOK_REVOLUTION -%left <solidtype> TOK_OR TOK_AND TOK_NOT -%token <solidtype> TOK_TRANSLATE TOK_MULTITRANSLATE TOK_ROTATE TOK_MULTIROTATE -%type <solidtype> solid solidprimitive -%type <void> splinesegmentlist splinesegment readbspline bsplinepointlist -%type <chptr> anyident -%token TOK_SINGULAR TOK_EDGE TOK_POINT -%token TOK_IDENTIFY TOK_CLOSESURFACES TOK_CLOSEEDGES TOK_PERIODIC -%token TOK_BOUNDARYCONDITION -%type <void> polyhedronpoints polyhedronfaces polyhedronpoint polyhedronface -%type <void> revolutionpoints revolutionpoint - - -%% -input: - { - linenum = 1; - } - TOK_RECO - recsoliddef - recadddef - - { - int i; - extern ARRAY<char*> parsestrings; - for (i = 0; i < parsestrings.Size(); i++) - delete [] parsestrings[i]; - parsestrings.SetSize(0); - } - ; - - -recsoliddef: - /* empty */ - | recsoliddef soliddef ';' - ; - -soliddef: - TOK_SOLID IDENT '=' solid - { parsegeom->SetSolid($2, new Solid (Solid::ROOT, $4)); - } - flaglist - { - parsegeom->SetFlags($2, parseflags); - } - ; - -solid: - solidprimitive - | IDENTSOLID { $$ = (Solid*)parsegeom->GetSolid($1); } - | solid TOK_OR solid { $$ = new Solid (Solid::UNION, $1, $3); } - | solid TOK_AND solid { $$ = new Solid (Solid::SECTION, $1, $3); } - | TOK_NOT solid { $$ = new Solid (Solid::SUB, $2); } - | '(' solid ')' { $$ = $2; } - ; - -solidprimitive: - TOK_SPHERE '(' NUM ',' NUM ',' NUM ';' - NUM ')' - { - OneSurfacePrimitive * surf = new Sphere (Point<3> ($3, $5, $7), $9); - parsegeom -> AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - $$ = new Solid (surf); - } - | TOK_CYLINDER '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ';' - NUM ')' - - { - OneSurfacePrimitive * surf = new Cylinder (Point<3> ($3, $5, $7), - Point<3> ($9, $11, $13), $15); - parsegeom->AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - $$ = new Solid (surf); - } - | TOK_CONE '(' NUM ',' NUM ',' NUM ';' - NUM ';' - NUM ',' NUM ',' NUM ';' - NUM ')' - - { - OneSurfacePrimitive * surf = new Cone (Point<3> ($3, $5, $7), - Point<3> ($11, $13, $15), $9, $17); - parsegeom->AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - $$ = new Solid (surf); - } - | TOK_PLAIN '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ')' - { - OneSurfacePrimitive * surf = new Plane ( Point<3> ($3, $5, $7), - Vec<3> ($9, $11, $13) ); - parsegeom->AddSurface (surf); - surf->SetSurfaceId (0, parsegeom->GetNSurf()-1); - $$ = new Solid (surf); - } - | TOK_ORTHOBRICK '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ')' - { - Primitive * nprim = new OrthoBrick (Point<3> ($3, $5, $7), - Point<3> ($9, $11, $13)); - for (int j = 0; j < nprim->GetNSurfaces(); j++) - { - parsegeom->AddSurface (&nprim->GetSurface(j)); - nprim->SetSurfaceId (j, parsegeom->GetNSurf()-1); - $$ = new Solid (nprim); - } - } - - - | TOK_POLYHEDRON '(' - { - polyhedron = new Polyhedra (); - } - polyhedronpoints ';' ';' - polyhedronfaces ')' - { - int j; - for (j = 0; j < polyhedron->GetNSurfaces(); j++) - { - parsegeom->AddSurface (&polyhedron->GetSurface(j)); - polyhedron->SetSurfaceId (j, parsegeom->GetNSurf()-1); - $$ = new Solid (polyhedron); - } - } - - -/* - | TOK_REVOLUTION '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ';' - { - revolution = new Revolution (Point<3> ($3, $5, $7), - Point<3> ($9, $11, $13)); - } - revolutionpoints - ')' - { - revolution -> Finish (); - int j; - for (j = 0; j < revolution->GetNSurfaces(); j++) - { - parsegeom->AddSurface (&revolution->GetSurface(j)); - revolution->SetSurfaceId (j, parsegeom->GetNSurf()-1); - $$ = new Solid (revolution); - } - } -*/ - - - | TOK_TRANSLATE '(' NUM ',' NUM ',' NUM ';' solid ')' - { - Solid * nsol = $9 -> Copy(*parsegeom); - Vec<3> v($3, $5, $7); - Transformation<3> trans(v); - nsol -> Transform (trans); - $$ = nsol; - } - - | TOK_MULTITRANSLATE '(' NUM ',' NUM ',' NUM ';' NUM ';' solid ')' - { - int i; - Solid * hsol = $11; - for (i = 1; i <= $9; i++) - { - Solid * nsol = $11 -> Copy(*parsegeom); - Vec<3> v($3, $5, $7); - v *= i; - Transformation<3> trans(v); - nsol -> Transform (trans); - hsol = new Solid (Solid::UNION, hsol, nsol); - } - $$ = hsol; - } - - | TOK_ROTATE '(' NUM ',' NUM ',' NUM ';' NUM ',' NUM ',' NUM ';' solid ')' - { - Solid * nsol = $15 -> Copy(*parsegeom); - Point<3> c($3, $5, $7); - Transformation<3> rot(c, $9, $11, $13); - nsol -> Transform (rot); - $$ = nsol; - } - - | TOK_MULTIROTATE '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ';' - NUM ';' solid ')' - { - int i; - Solid * hsol = $17; - - Point<3> c($3, $5, $7); - Transformation<3> trans(c, $9, $11, $13); - Transformation<3> multi(Vec<3>(0,0,0)); - Transformation<3> ht; - - for (i = 1; i <= $15; i++) - { - Solid * nsol = $17 -> Copy(*parsegeom); - nsol -> Transform (multi); - hsol = new Solid (Solid::UNION, hsol, nsol); - - ht=multi; - multi.Combine (trans, ht); - } - $$ = hsol; - } - - -/* - | TOK_TUBE '(' NUM ',' NUM ',' NUM ',' - { - middlecurve = new spline3d; - splinep1.X() = $3; splinep1.Y() = $5; splinep1.Z() = $7; - } - splinesegmentlist ';' NUM ')' - { - Surface * surf = new splinetube (*middlecurve, $12); - parsegeom->AddSurface (surf); - $$ = new Solid (surf, parsegeom->GetNSurf()); - } - - | TOK_GENCYL '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ';' - readbspline - ')' - { - Surface * surf = new GeneralizedCylinder - (*bspline, Point<3> ($3, $5, $7), Vec<3> ($9, $11, $13), - Vec<3> ($15, $17, $19) ); - parsegeom->AddSurface (surf); - $$ = new Solid (surf, parsegeom->GetNSurf()); - } -*/ - ; - - -polyhedronpoints: - polyhedronpoints ';' polyhedronpoint - | polyhedronpoint - ; -polyhedronfaces: - polyhedronfaces ';' polyhedronface - | polyhedronface - ; -polyhedronpoint: - NUM ',' NUM ',' NUM - { - polyhedron->AddPoint (Point<3> ($1, $3, $5)); - cout << " " << $1 << " " << $3 << " " << $5 << endl; - } - ; -polyhedronface: - NUM ',' NUM ',' NUM - { - polyhedron->AddFace (int($1)-1, int($3)-1, int($5)-1); - cout << $1 << " " << $3 << " " << $5 << endl; - } - | NUM ',' NUM ',' NUM ',' NUM - { - cout << "face, 1 = " << $1 << " " << $3 << " " << $5 << " " << $7 << endl; - polyhedron->AddFace (int($1)-1, int($3)-1, int($5)-1); - polyhedron->AddFace (int($1)-1, int($5)-1, int($7)-1); - cout << $1 << $3 << $5 << $7 << endl; - } - ; - -revolutionpoints: - revolutionpoints ';' revolutionpoint - | revolutionpoint - ; -revolutionpoint: - NUM ',' NUM - { -// revolution->AddPoint (Point<2> ($1, $3)); - cout << " " << $1 << " " << $3 << endl; - } - ; - - - - - -splinesegmentlist: - splinesegment - | splinesegment ',' splinesegmentlist - ; -splinesegment: - NUM ',' NUM ',' NUM ',' - NUM ',' NUM ',' NUM - { - middlecurve->AddSegment (splinep1, Point<3> ($1, $3, $5), Point<3> ($7, $9, $11)); - splinep1(0) = $7; splinep1(1) = $9; splinep1(2) = $11; - } - ; - - -readbspline: - NUM ',' NUM - { - bspline = new BSplineCurve2d; - bspline -> AddPoint (Point<2> ($1, $3)); - cout << "first point" << endl; - } - bsplinepointlist - ; -bsplinepointlist: - /* empty */ { } - | ',' NUM ',' NUM - { - bspline -> AddPoint (Point<2> ($2, $4)); - cout << "Add Point: " << $2 << "-" << $4 << endl; - } - bsplinepointlist - ; - - - - - - - - - -recadddef: - /* empty */ - | recadddef adddef ';' - ; - -adddef: - TOK_SINGULAR TOK_EDGE NUM IDENTSOLID IDENTSOLID - { cout << "singular edge:" << $3 << " between " - << $4 << " and " << $5 << endl; - parsegeom->singedges.Append - (new SingularEdge ($3, parsegeom->GetSolid($4), - parsegeom->GetSolid($5))); - } - | - TOK_SINGULAR TOK_POINT NUM IDENTSOLID IDENTSOLID IDENTSOLID - { cout << "singular point:" << $3 << " between " - << $4 << ", " << $5 << " and " << $6 << endl; - parsegeom->singpoints.Append - (new SingularPoint ($3, parsegeom->GetSolid($4), - parsegeom->GetSolid($5), - parsegeom->GetSolid($6))); - } - | - TOK_IDENTIFY TOK_CLOSESURFACES IDENTSOLID IDENTSOLID flaglist - { - ARRAY<int> si1, si2; - parsegeom->GetSolid($3)->GetSurfaceIndices(si1); - parsegeom->GetSolid($4)->GetSurfaceIndices(si2); - - parsegeom->AddIdentification ( - new CloseSurfaceIdentification ( - parsegeom->GetNIdentifications()+1, - *parsegeom, - parsegeom->GetSurface (si1[0]), - parsegeom->GetSurface (si2[0]), - parseflags)); - } - | - TOK_IDENTIFY TOK_CLOSEEDGES IDENTSOLID IDENTSOLID IDENTSOLID - { - ARRAY<int> si1, si2, si3; - parsegeom->GetSolid($3)->GetSurfaceIndices(si1); - parsegeom->GetSolid($4)->GetSurfaceIndices(si2); - parsegeom->GetSolid($5)->GetSurfaceIndices(si3); - - parsegeom->AddIdentification ( - new CloseEdgesIdentification ( - parsegeom->GetNIdentifications()+1, - *parsegeom, - parsegeom->GetSurface (si1.Get(1)), - parsegeom->GetSurface (si2.Get(1)), - parsegeom->GetSurface (si3.Get(1)))); - } - | - TOK_IDENTIFY TOK_PERIODIC IDENTSOLID IDENTSOLID - { - ARRAY<int> si1, si2; - parsegeom->GetSolid($3)->GetSurfaceIndices(si1); - parsegeom->GetSolid($4)->GetSurfaceIndices(si2); - - parsegeom->AddIdentification ( - new PeriodicIdentification ( - parsegeom->GetNIdentifications()+1, - *parsegeom, - parsegeom->GetSurface (si1.Get(1)), - parsegeom->GetSurface (si2.Get(1)))); - } - | - TOK_TLO IDENTSOLID flaglist - { - int tlonr = - parsegeom->SetTopLevelObject ((Solid*)parsegeom->GetSolid($2)); - TopLevelObject * tlo = parsegeom->GetTopLevelObject (tlonr); - if (parseflags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = parseflags.GetNumListFlag ("col"); - tlo->SetRGB (col[0], col[1], col[2]); - } - if (parseflags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - } - | - TOK_TLO IDENTSOLID IDENTSOLID flaglist - { - ARRAY<int> si; - parsegeom->GetSolid($3)->GetSurfaceIndices(si); - int tlonr = - parsegeom->SetTopLevelObject ((Solid*)parsegeom->GetSolid($2), - (Surface*)parsegeom->GetSurface(si.Get(1))); - TopLevelObject * tlo = parsegeom->GetTopLevelObject (tlonr); - if (parseflags.NumListFlagDefined ("col")) - { - const ARRAY<double> & col = parseflags.GetNumListFlag ("col"); - tlo->SetRGB (col.Get(1), col.Get(2), col.Get(3)); - } - if (parseflags.GetDefineFlag ("transparent")) - tlo->SetTransparent (1); - } - | - TOK_BOUNDINGBOX '(' NUM ',' NUM ',' NUM ';' - NUM ',' NUM ',' NUM ')' - { - parsegeom->SetBoundingBox (Box<3> (Point<3> ($3, $5, $7), - Point<3> ($9, $11, $13))); - } - | - TOK_POINT '(' NUM ',' NUM ',' NUM ')' - { - parsegeom->AddUserPoint (Point<3> ($3, $5, $7)); - } - | - TOK_BOUNDARYCONDITION IDENTSOLID IDENTSOLID NUM - { - CSGeometry::BCModification bcm; - ARRAY<int> si; - - parsegeom->GetSolid($2)->GetSurfaceIndices(si); - - bcm.tlonr = -1; - int i; - for (i = 0; i < parsegeom->GetNTopLevelObjects(); i++) - if (strcmp (parsegeom->GetTopLevelObject(i)->GetSolid()->Name(), $3) == 0) - { - bcm.tlonr = i; - break; - } - - bcm.bcnr = int($4); - for (i = 0; i < si.Size(); i++) - { - bcm.si = si[i]; - parsegeom->bcmodifications.Append (bcm); - } - } - ; - - - - -flaglist: - { parseflags.DeleteFlags (); } - recflaglist - ; - -recflaglist: - /* empty */ - | flag recflaglist - ; - -flag: - '-' anyident - { parseflags.SetFlag ($2); } - | '-' anyident '=' anyident - { parseflags.SetFlag ($2, $4); } - | '-' anyident '=' NUM - { parseflags.SetFlag ($2, $4); } - | '-' anyident '=' numlistbrack - { parseflags.SetFlag ($2, doublearray); } - | '-' anyident '=' stringlistbrack - { parseflags.SetFlag ($2, stringarray); } - ; - - -numlistbrack: - '[' { doublearray.SetSize (0); } - numlist ']' - ; - -numlist: - NUM { doublearray.Append ($1); } - | numlist ',' NUM { doublearray.Append ($3); } - ; - -stringlistbrack: - '[' - { - int i; - for (i = 0; i < stringarray.Size(); i++) - delete stringarray[i]; - stringarray.SetSize (0); - } - stringlist ']' - ; - -stringlist: - anyident - { - stringarray.Append (new char[strlen($1)+1]); - strcpy (stringarray.Last(), $1); - } - - | stringlist ',' anyident - { - stringarray.Append (new char[strlen($3)+1]); - strcpy (stringarray.Last(), $3); - } - ; - - - - - -anyident: - IDENT { $$ = $1; } - | IDENTSOLID { $$ = $1; } -%% - - -int yyerror (char * s) -{ - cerr << s << " in line " << linenum << endl; - return 0; -} - diff --git a/Netgen/libsrc/csg/geoml.hpp b/Netgen/libsrc/csg/geoml.hpp deleted file mode 100644 index e7974ad206..0000000000 --- a/Netgen/libsrc/csg/geoml.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FILE_GEOML -#define FILE_GEOML - -/* *************************************************************************/ -/* File: geoml.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 21. Jun. 98 */ -/* *************************************************************************/ - -#include <geom/geom.hh> - -#include <geom/solid.hh> -#include <geom/algprim.hh> -#include <geom/adtree.hh> -#include <geom/csgeom.hh> -#endif diff --git a/Netgen/libsrc/csg/identify.cpp b/Netgen/libsrc/csg/identify.cpp deleted file mode 100644 index 4622ee42bb..0000000000 --- a/Netgen/libsrc/csg/identify.cpp +++ /dev/null @@ -1,1508 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - - -namespace netgen -{ -Identification :: Identification (int anr, const CSGeometry & ageom) - : geom(ageom), identfaces(10) -{ - nr = anr; -} - -Identification :: ~Identification () -{ - ; -} - - -ostream & operator<< (ostream & ost, Identification & ident) -{ - ident.Print (ost); - return ost; -} - - -/* -void Identification :: IdentifySpecialPoints (ARRAY<class SpecialPoint> & points) -{ - ; -} -*/ - - -int Identification :: -Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const -{ - cout << "Identification::Identifyable called for base-class" << endl; - return 0; -} - -int Identification :: -Identifyable (const Point<3> & p1, const Point<3> & sp2) const -{ - cout << "Identification::Identifyable called for base-class" << endl; - return 0; -} - - -int Identification :: -IdentifyableCandidate (const SpecialPoint & sp1) const -{ - return 1; -} - - -int Identification :: -ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const -{ - return 0; -} - -int Identification :: GetIdentifiedPoint (class Mesh & mesh, int pi) -{ - cout << "Identification::GetIdentifiedPoint called for base-class" << endl; - return -1; -} - -void Identification :: IdentifyPoints (Mesh & mesh) -{ - cout << "Identification::IdentifyPoints called for base-class" << endl; - ; -} - -void Identification :: IdentifyFaces (class Mesh & mesh) -{ - cout << "Identification::IdentifyFaces called for base-class" << endl; - ; -} - -void Identification :: -BuildSurfaceElements (ARRAY<Segment> & segs, - Mesh & mesh, const Surface * surf) -{ - cout << "Identification::BuildSurfaceElements called for base-class" << endl; - ; -} - - -void Identification :: -BuildVolumeElements (ARRAY<class Element2d> & surfels, - class Mesh & mesh) -{ - ; -} - -void Identification :: -GetIdentifiedFaces (ARRAY<INDEX_2> & idfaces) const -{ - idfaces.SetSize(0); - for (int i = 1; i <= identfaces.GetNBags(); i++) - for (int j = 1; j <= identfaces.GetBagSize(i); j++) - { - INDEX_2 i2; - int val; - identfaces.GetData (i, j, i2, val); - idfaces.Append (i2); - } -} - - - - -PeriodicIdentification :: -PeriodicIdentification (int anr, - const CSGeometry & ageom, - const Surface * as1, - const Surface * as2) - : Identification(anr, ageom) -{ - s1 = as1; - s2 = as2; -} - -PeriodicIdentification :: ~PeriodicIdentification () -{ - ; -} - -/* -void PeriodicIdentification :: IdentifySpecialPoints -(ARRAY<class SpecialPoint> & points) -{ - int i, j; - int bestj; - double bestval, val; - - for (i = 1; i <= points.Size(); i++) - { - Point<3> p1 = points.Get(i).p; - Point<3> hp1 = p1; - s1->Project (hp1); - if (Dist (p1, hp1) > 1e-6) continue; - - Vec<3> n1; - s1->GetNormalVector (p1, n1); - n1 /= n1.Length(); - if ( fabs(n1 * points.Get(i).v) > 1e-3) - continue; - - bestval = 1e8; - bestj = 1; - for (j = 1; j <= points.Size(); j++) - { - Point<3> p2= points.Get(j).p; - Point<3> hp2 = p2; - s2->Project (hp2); - if (Dist (p2, hp2) > 1e-6) continue; - - Vec<3> n2; - s2->GetNormalVector (p2, n2); - n2 /= n2.Length(); - if ( fabs(n2 * points.Get(j).v) > 1e-3) - continue; - - - Vec<3> v(p1, p2); - double vl = v.Length(); - double cl = fabs (v*n1); - - val = 1 - cl*cl/(vl*vl); - - val += (points.Get(i).v - points.Get(j).v).Length(); - - if (val < bestval) - { - bestj = j; - bestval = val; - } - } - - (*testout) << "Identify Periodic special points: pi = " - << points.Get(i).p << ", vi = " << points.Get(i).v - << " pj = " << points.Get(bestj).p - << ", vj = " << points.Get(bestj).v - << " bestval = " << bestval << endl; - } -} -*/ - -int PeriodicIdentification :: -Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const -{ - int i; - double val; - - SpecialPoint hsp1 = sp1; - SpecialPoint hsp2 = sp2; - - for (i = 1; i <= 1; i++) - { - // Swap (hsp1, hsp2); - - if (!s1->PointOnSurface (hsp1.p)) - continue; - - Vec<3> n1; - n1 = s1->GetNormalVector (hsp1.p); - n1 /= n1.Length(); - if ( fabs(n1 * hsp1.v) > 1e-3) - continue; - - - if (!s2->PointOnSurface(hsp2.p)) - continue; - - Vec<3> n2; - n2 = s2->GetNormalVector (hsp2.p); - n2 /= n2.Length(); - if ( fabs(n2 * hsp2.v) > 1e-3) - continue; - - - Vec<3> v = hsp2.p - hsp1.p; - double vl = v.Length(); - double cl = fabs (v*n1); - - - val = 1 - cl*cl/(vl*vl); - val += (hsp1.v - hsp2.v).Length(); - - if (val < 1e-3) - { - return 1; - } - } - - return 0; -} - -int PeriodicIdentification :: -Identifyable (const Point<3> & p1, const Point<3> & p2) const -{ - return (s1->PointOnSurface (p1) && - s2->PointOnSurface (p2)); -} - - - - -int PeriodicIdentification :: -GetIdentifiedPoint (class Mesh & mesh, int pi) -{ - const Surface * sold, *snew; - const Point<3> & p = mesh.Point (pi); - - if (s1->PointOnSurface (p)) - { - snew = s2; - } - else - { - if (s2->PointOnSurface (p)) - { - snew = s1; - } - else - { - cerr << "GetIdenfifiedPoint: Not possible" << endl; - exit (1); - } - } - - // project to other surface - Point<3> hp = p; - snew->Project (hp); - - int i; - int newpi = 0; - for (i = 1; i <= mesh.GetNP(); i++) - if (Dist2 (mesh.Point(i), hp) < 1e-12) - { - newpi = i; - break; - } - if (!newpi) - newpi = mesh.AddPoint (hp); - - if (snew == s2) - mesh.GetIdentifications().Add (pi, newpi, nr); - else - mesh.GetIdentifications().Add (newpi, pi, nr); - - /* - (*testout) << "Identify points(periodic), nr = " << nr << ": " << mesh.Point(pi) - << " and " << mesh.Point(newpi) - << ((snew == s2) ? "" : " inverse") - << endl; - */ - return newpi; -} - - -void PeriodicIdentification :: IdentifyPoints (class Mesh & mesh) -{ - int i, j; - for (i = 1; i <= mesh.GetNP(); i++) - { - Point<3> p = mesh.Point(i); - if (s1->PointOnSurface (p)) - { - Point<3> pp = p; - s2->Project (pp); - for (j = 1; j <= mesh.GetNP(); j++) - if (Dist2(mesh.Point(j), pp) < 1e-6) - { - mesh.GetIdentifications().Add (i, j, nr); - /* - (*testout) << "Identify points(periodic:), nr = " << nr << ": " - << mesh.Point(i) << " - " << mesh.Point(j) << endl; - */ - } - } - } -} - - -void PeriodicIdentification :: IdentifyFaces (class Mesh & mesh) -{ - int i, j, k, l; - int fi1, fi2, side; - for (i = 1; i <= mesh.GetNFD(); i++) - for (j = 1; j <= mesh.GetNFD(); j++) - { - int surfi = mesh.GetFaceDescriptor(i).SurfNr(); - int surfj = mesh.GetFaceDescriptor(j).SurfNr(); - if (surfi == surfj) - continue; - - if (geom.GetSurface (surfi) != s1 || - geom.GetSurface (surfj) != s2) - continue; - - int idok = 1; - - - // (*testout) << "check faces " << i << " and " << j << endl; - for (side = 1; side <= 2 && idok; side++) - { - if (side == 1) - { - fi1 = i; - fi2 = j; - } - else - { - fi1 = j; - fi2 = i; - } - - for (k = 1; k <= mesh.GetNSeg(); k++) - { - const Segment & seg1 = mesh.LineSegment(k); - if (seg1.si != fi1) - continue; - - int foundother = 0; - for (l = 1; l <= mesh.GetNSeg(); l++) - { - const Segment & seg2 = mesh.LineSegment(l); - if (seg2.si != fi2) - continue; - - // (*testout) << "seg1 = " << seg1.p1 << "-" << seg1.p2 << ", seg2 = " << seg2.p1 << "-" << seg2.p2; - - if (side == 1) - { - if (mesh.GetIdentifications().Get (seg1.p1, seg2.p1) && - mesh.GetIdentifications().Get (seg1.p2, seg2.p2)) - { - foundother = 1; - break; - } - - if (mesh.GetIdentifications().Get (seg1.p1, seg2.p2) && - mesh.GetIdentifications().Get (seg1.p2, seg2.p1)) - { - foundother = 1; - break; - } - } - else - { - if (mesh.GetIdentifications().Get (seg2.p1, seg1.p1) && - mesh.GetIdentifications().Get (seg2.p2, seg1.p2)) - { - foundother = 1; - break; - } - - if (mesh.GetIdentifications().Get (seg2.p1, seg1.p2) && - mesh.GetIdentifications().Get (seg2.p2, seg1.p1)) - { - foundother = 1; - break; - } - } - } - - if (!foundother) - { - idok = 0; - break; - } - } - } - - - if (idok) - { - // (*testout) << "Identify faces " << i << " and " << j << endl; - INDEX_2 fpair(i,j); - fpair.Sort(); - identfaces.Set (fpair, 1); - } - } -} - - - -void PeriodicIdentification :: -BuildSurfaceElements (ARRAY<Segment> & segs, - Mesh & mesh, const Surface * surf) -{ - int i1, i2; - int found = 0; - int i, j, k; - int fother; - - - int facei = segs.Get(1).si; - int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); - - - if (geom.GetSurface(surfnr) == s1 || - geom.GetSurface(surfnr) == s2) - { - // (*testout) << "surfs found !" << endl; - - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & sel = mesh.SurfaceElement(i); - INDEX_2 fpair (facei, sel.GetIndex()); - fpair.Sort(); - if (identfaces.Used (fpair)) - { - found = 1; - fother = sel.GetIndex(); - - // copy element - Element2d newel(3); - newel.SetIndex (facei); - for (k = 1; k <= 3; k++) - { - newel.PNum(k) = - GetIdentifiedPoint (mesh, sel.PNum(k)); - } - - Vec<3> nt = Cross (Point<3> (mesh.Point (newel.PNum(2)))- - Point<3> (mesh.Point (newel.PNum(1))), - Point<3> (mesh.Point (newel.PNum(3)))- - Point<3> (mesh.Point (newel.PNum(1)))); - - Vec<3> nsurf; - nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh.Point(newel.PNum(1))); - if (nsurf * nt < 0) - Swap (newel.PNum(2), newel.PNum(3)); - - mesh.AddSurfaceElement (newel); - } - } - } - - if (found) - { - (*mycout) << " copy face " << facei << " from face " << fother; - segs.SetSize(0); - } -} - - - - - - - - -void PeriodicIdentification :: Print (ostream & ost) const -{ - ost << "Periodic Identifiaction, surfaces: " - << s1->Name() << " - " << s2->Name() << endl; - s1->Print (ost); - ost << " - "; - s2->Print (ost); - ost << endl; -} - - -void PeriodicIdentification :: GetData (ostream & ost) const -{ - ost << "periodic " << s1->Name() << " " << s2->Name(); -} - - - - - - - -CloseSurfaceIdentification :: -CloseSurfaceIdentification (int anr, - const CSGeometry & ageom, - const Surface * as1, - const Surface * as2, - const TopLevelObject * adomain, - const Flags & flags) - : Identification(anr, ageom) -{ - s1 = as1; - s2 = as2; - domain = adomain; - ref_levels = int (flags.GetNumFlag ("reflevels", 2)); - ref_levels_s1 = int (flags.GetNumFlag ("reflevels1", 0)); - ref_levels_s2 = int (flags.GetNumFlag ("reflevels2", 0)); - slices = flags.GetNumListFlag ("slices"); - // eps_n = 1e-3; - eps_n = 1e-6; - - dom_surf_valid = 0; -} - -CloseSurfaceIdentification :: ~CloseSurfaceIdentification () -{ - ; -} - -void CloseSurfaceIdentification :: Print (ostream & ost) const -{ - ost << "CloseSurface Identifiaction, surfaces: " - << s1->Name() << " - " << s2->Name() << endl; - s1->Print (ost); - s2->Print (ost); - ost << endl; -} - - -void CloseSurfaceIdentification :: GetData (ostream & ost) const -{ - ost << "close surface " << s1->Name() << " " << s2->Name(); -} - - -/* -void CloseSurfaceIdentification :: IdentifySpecialPoints -(ARRAY<class SpecialPoint> & points) -{ - int i, j; - int bestj; - double bestval, val; - - for (i = 1; i <= points.Size(); i++) - { - Point<3> p1 = points.Get(i).p; - Vec<3> n1; - - if (!s1->PointOnSurface (p1)) - continue; - - s1->GetNormalVector (p1, n1); - n1 /= n1.Length(); - if ( fabs(n1 * points.Get(i).v) > 1e-3) - continue; - - bestval = 1e8; - bestj = 1; - for (j = 1; j <= points.Size(); j++) - { - Point<3> p2= points.Get(j).p; - if (!s2->PointOnSurface (p2)) - continue; - - Vec<3> n2; - s2->GetNormalVector (p2, n2); - n2 /= n2.Length(); - if ( fabs(n2 * points.Get(j).v) > 1e-3) - continue; - - - Vec<3> v(p1, p2); - double vl = v.Length(); - double cl = fabs (v*n1); - - val = 1 - cl*cl/(vl*vl); - - val += (points.Get(i).v - points.Get(j).v).Length(); - - if (val < bestval) - { - bestj = j; - bestval = val; - } - } - - (*testout) << "Identify close surfaces special points: pi = " - << points.Get(i).p << ", vi = " << points.Get(i).v - << " pj = " << points.Get(bestj).p - << ", vj = " << points.Get(bestj).v - << " bestval = " << bestval << endl; - } -} -*/ - -int CloseSurfaceIdentification :: -Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const -{ - - if (!dom_surf_valid) - { - const_cast<bool&> (dom_surf_valid) = 1; - ARRAY<int> & hsurf = const_cast<ARRAY<int>&> (domain_surfaces); - - if (domain) - { - BoxSphere<3> hbox (geom.BoundingBox()); - geom.GetIndependentSurfaceIndices (domain->GetSolid(), hbox, - hsurf); - } - else - { - hsurf.SetSize (geom.GetNSurf()); - for (int j = 0; j < hsurf.Size(); j++) - hsurf[j] = j; - } - } - - - - if (!s1->PointOnSurface (sp1.p)) - return 0; - - Vec<3> n1 = s1->GetNormalVector (sp1.p); - n1.Normalize(); - if ( fabs(n1 * sp1.v) > eps_n) - return 0; - - if (!s2->PointOnSurface(sp2.p)) - return 0; - - Vec<3> n2 = s2->GetNormalVector (sp2.p); - n2.Normalize(); - if ( fabs(n2 * sp2.v) > eps_n) - return 0; - - // must have joint surface - bool joint = 0; - // for (int j = 0; j < geom.GetNSurf(); j++) - for (int jj = 0; jj < domain_surfaces.Size(); jj++) - { - int j = domain_surfaces[jj]; - if (geom.GetSurface(j) -> PointOnSurface(sp1.p) && - geom.GetSurface(j) -> PointOnSurface(sp2.p) ) - { - Vec<3> hn1 = geom.GetSurface(j)->GetNormalVector (sp1.p); - Vec<3> hn2 = geom.GetSurface(j)->GetNormalVector (sp2.p); - - if (hn1 * hn2 > 0) - { - joint = 1; - break; - } - } - } - if (!joint) return 0; - - Vec<3> v = sp2.p - sp1.p; - double vl = v.Length(); - double cl = fabs (v*n1); - - if (cl > (1-eps_n*eps_n) * vl && (sp1.v - sp2.v).Length() < 0.1) - return 1; - - return 0; -} - -int CloseSurfaceIdentification :: -Identifyable (const Point<3> & p1, const Point<3> & p2) const -{ - return (s1->PointOnSurface (p1) && s2->PointOnSurface (p2)); -} - - - - -int CloseSurfaceIdentification :: -IdentifyableCandidate (const SpecialPoint & sp1) const -{ - if (s1->PointOnSurface (sp1.p)) - { - Vec<3> n1; - n1 = s1->GetNormalVector (sp1.p); - n1.Normalize(); - if ( fabs(n1 * sp1.v) > eps_n) - return 0; - return 1; - } - - if (s2->PointOnSurface (sp1.p)) - { - Vec<3> n1; - n1 = s2->GetNormalVector (sp1.p); - n1.Normalize(); - if ( fabs(n1 * sp1.v) > eps_n) - return 0; - return 1; - } - return 0; -} - - - -int CloseSurfaceIdentification :: -ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const -{ - if ( (s1->PointOnSurface (sp1.p) && s2->PointOnSurface (sp2.p)) || - (s1->PointOnSurface (sp2.p) && s2->PointOnSurface (sp1.p)) ) - { - return 1; - } - return 0; -} - - - -int CloseSurfaceIdentification :: -GetIdentifiedPoint (class Mesh & mesh, int pi) -{ - const Surface * sold, *snew; - const Point<3> & p = mesh.Point (pi); - - ARRAY<int,PointIndex::BASE> identmap(mesh.GetNP()); - mesh.GetIdentifications().GetMap (nr, identmap); - if (identmap.Get(pi)) - return identmap.Get(pi); - - if (s1->PointOnSurface (p)) - { - snew = s2; - } - else - { - if (s2->PointOnSurface (p)) - { - snew = s1; - } - else - { - (*testout) << "GetIdenfifiedPoint: Not possible" << endl; - (*testout) << "p = " << p << endl; - (*testout) << "surf1: "; - s1->Print (*testout); - (*testout) << endl; - (*testout) << "surf2: "; - s2->Print (*testout); - (*testout) << endl; - - cerr << "GetIdenfifiedPoint: Not possible" << endl; - exit (1); - } - } - - // project to other surface - Point<3> hp = p; - snew->Project (hp); - - int i; - int newpi = 0; - for (i = 1; i <= mesh.GetNP(); i++) - if (Dist2 (mesh.Point(i), hp) < 1e-12) - // if (Dist2 (mesh.Point(i), hp) < 1 * Dist2 (hp, p)) - { - newpi = i; - break; - } - if (!newpi) - newpi = mesh.AddPoint (hp); - - if (snew == s2) - mesh.GetIdentifications().Add (pi, newpi, nr); - else - mesh.GetIdentifications().Add (newpi, pi, nr); - - /* - (*testout) << "Identify points(closesurface), nr = " << nr << ": " << mesh.Point(pi) - << " and " << mesh.Point(newpi) - << ((snew == s2) ? "" : " inverse") - << endl; - */ - return newpi; -} - - - - - -void CloseSurfaceIdentification :: IdentifyPoints (Mesh & mesh) -{ - int i, j; - int i1, i2; - - int np = mesh.GetNP(); - BitArray ons2(np); - ons2.Clear(); - for (i2 = 1; i2 <= np; i2++) - if (s2->PointOnSurface (mesh.Point(i2))) - ons2.Set (i2); - - for (i1 = 1; i1 <= np; i1++) - { - const Point<3> p1 = mesh.Point(i1); - if (s1->PointOnSurface (p1)) - { - int candi2 = 0; - double mindist = 1e10; - - Vec<3> n1; - n1 = s1->GetNormalVector (p1); - n1.Normalize(); - - for (i2 = 1; i2 <= np; i2++) - { - if (i2 == i1) - continue; - - const Point<3> p2 = mesh.Point(i2); - - if (!ons2.Test(i2)) - continue; - /* - if (!s2->PointOnSurface (p2)) - continue; - */ - Vec<3> n = p2 - p1; - n.Normalize(); - - - bool joint = 0; - for (int jj = 0; jj < domain_surfaces.Size(); jj++) - { - int j = domain_surfaces[jj]; - if (geom.GetSurface(j) -> PointOnSurface(p1) && - geom.GetSurface(j) -> PointOnSurface(p2) ) - { - Vec<3> hn1 = geom.GetSurface(j)->GetNormalVector (p1); - Vec<3> hn2 = geom.GetSurface(j)->GetNormalVector (p2); - - if (hn1 * hn2 > 0) - { - joint = 1; - break; - } - } - } - if (!joint) continue; - - - - - if (fabs (n * n1) > 0.9 && - Dist (p1, p2) < mindist) - { - candi2 = i2; - mindist = Dist (p1, p2); - } - } - - if (candi2) - { - // (*testout) << "identify points " << p1 << " - " << mesh.Point(candi2) << endl; - (*testout) << "Add Identification from CSI2, p1 = " - << mesh[PointIndex(i1)] << ", p2 = " - << mesh[PointIndex(candi2)] << endl; - - mesh.GetIdentifications().Add (i1, candi2, nr); - } - } - } -} - - - -void CloseSurfaceIdentification :: IdentifyFaces (class Mesh & mesh) -{ - int i, j, k, l; - int fi1, fi2, side; - - int s1rep, s2rep; - for (i = 0; i < geom.GetNSurf(); i++) - { - if (geom.GetSurface (i) == s1) - s1rep = geom.GetSurfaceClassRepresentant(i); - if (geom.GetSurface (i) == s2) - s2rep = geom.GetSurfaceClassRepresentant(i); - } - - for (i = 1; i <= mesh.GetNFD(); i++) - for (j = 1; j <= mesh.GetNFD(); j++) - { - int surfi = mesh.GetFaceDescriptor(i).SurfNr(); - int surfj = mesh.GetFaceDescriptor(j).SurfNr(); - if (surfi == surfj) - continue; - - if (s1rep != surfi || s2rep != surfj) - continue; - - /* - if (geom.GetSurface (surfi) != s1 || - geom.GetSurface (surfj) != s2) - continue; - */ - - int idok = 1; - - - // (*testout) << "check faces " << i << " and " << j << endl; - for (side = 1; side <= 2 && idok; side++) - { - if (side == 1) - { - fi1 = i; - fi2 = j; - } - else - { - fi1 = j; - fi2 = i; - } - - for (k = 1; k <= mesh.GetNSeg(); k++) - { - const Segment & seg1 = mesh.LineSegment(k); - if (seg1.si != fi1) - continue; - - int foundother = 0; - for (l = 1; l <= mesh.GetNSeg(); l++) - { - const Segment & seg2 = mesh.LineSegment(l); - if (seg2.si != fi2) - continue; - - // (*testout) << "seg1 = " << seg1.p1 << "-" << seg1.p2 << ", seg2 = " << seg2.p1 << "-" << seg2.p2; - - if (side == 1) - { - if (mesh.GetIdentifications().Get (seg1.p1, seg2.p1) && - mesh.GetIdentifications().Get (seg1.p2, seg2.p2)) - { - foundother = 1; - break; - } - - if (mesh.GetIdentifications().Get (seg1.p1, seg2.p2) && - mesh.GetIdentifications().Get (seg1.p2, seg2.p1)) - { - foundother = 1; - break; - } - } - else - { - if (mesh.GetIdentifications().Get (seg2.p1, seg1.p1) && - mesh.GetIdentifications().Get (seg2.p2, seg1.p2)) - { - foundother = 1; - break; - } - - if (mesh.GetIdentifications().Get (seg2.p1, seg1.p2) && - mesh.GetIdentifications().Get (seg2.p2, seg1.p1)) - { - foundother = 1; - break; - } - } - } - - if (!foundother) - { - idok = 0; - break; - } - } - } - - - if (idok) - { - // (*testout) << "Identify faces " << i << " and " << j << endl; - INDEX_2 fpair(i,j); - fpair.Sort(); - identfaces.Set (fpair, 1); - } - } -} - - - -void CloseSurfaceIdentification :: -BuildSurfaceElements (ARRAY<Segment> & segs, - Mesh & mesh, const Surface * surf) -{ - int i1, i2; - int found = 0, cntquads = 0; - int i, j, k; - - // insert quad layer: - for (i1 = 1; i1 <= segs.Size(); i1++) - for (i2 = 1; i2 < i1; i2++) - { - const Segment & s1 = segs.Get(i1); - const Segment & s2 = segs.Get(i2); - if ( (mesh.GetIdentifications().Get (s1.p1, s2.p2) == nr && - mesh.GetIdentifications().Get (s1.p2, s2.p1) == nr) || - (mesh.GetIdentifications().Get (s2.p1, s1.p2) == nr && - mesh.GetIdentifications().Get (s2.p2, s1.p1) == nr) - ) - { - Element2d el(4); - el.PNum(1) = s1.p1; - el.PNum(2) = s1.p2; - el.PNum(3) = s2.p1; - el.PNum(4) = s2.p2; - - Vec<3> n = Cross (Point<3> (mesh.Point(el.PNum(2)))- - Point<3> (mesh.Point(el.PNum(1))), - Point<3> (mesh.Point(el.PNum(4)))- - Point<3> (mesh.Point(el.PNum(1)))); - - Vec<3> ns; - ns = surf->GetNormalVector (mesh.Point(el.PNum(1))); - // (*testout) << "n = " << n << " ns = " << ns << endl; - if (n * ns < 0) - { - // (*testout) << "Swap the quad" << endl; - Swap (el.PNum(1), el.PNum(2)); - Swap (el.PNum(3), el.PNum(4)); - } - - mesh.AddSurfaceElement (el); - (*testout) << "add rect element: " - << mesh.Point (el.PNum(1)) << " - " - << mesh.Point (el.PNum(2)) << " - " - << mesh.Point (el.PNum(3)) << " - " - << mesh.Point (el.PNum(4)) << endl; - found = 1; - cntquads++; - } - } - - if (found) - { - (*mycout) << " insert quad layer of " << cntquads - << " elements at face " << segs.Get(1).si << endl; - segs.SetSize(0); - } - else - { - BuildSurfaceElements2 (segs, mesh, surf); - } - - /* - int fother; - int facei = segs.Get(1).si; - int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); - - int foundid = 0; - for (i = 1; i <= identfaces.GetNBags(); i++) - for (j = 1; j <= identfaces.GetBagSize(i); j++) - { - INDEX_2 i2; - int data; - identfaces.GetData (i, j, i2, data); - if (i2.I1() == facei || i2.I2() == facei) - foundid = 1; - } - - // (*testout) << "facei = " << facei << ", surfnr = " << surfnr << endl; - - if (foundid) - { - // (*testout) << "surfaces found" << endl; - // copy surface - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & sel = mesh.SurfaceElement(i); - INDEX_2 fpair (facei, sel.GetIndex()); - fpair.Sort(); - if (identfaces.Used (fpair)) - { - found = 1; - fother = sel.GetIndex(); - - // copy element - Element2d newel(3); - newel.SetIndex (facei); - for (k = 1; k <= 3; k++) - { - newel.PNum(k) = - GetIdentifiedPoint (mesh, sel.PNum(k)); - // cout << "id-point = " << sel.PNum(k) << ", np = " << newel.PNum(k) << endl; - } - - Vec<3> nt = Cross (Vec<3> (mesh.Point (newel.PNum(1)), mesh.Point (newel.PNum(2))), - Vec<3> (mesh.Point (newel.PNum(1)), mesh.Point (newel.PNum(3)))); - Vec<3> nsurf; - nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh.Point(newel.PNum(1))); - if (nsurf * nt < 0) - Swap (newel.PNum(2), newel.PNum(3)); - - mesh.AddSurfaceElement (newel); - } - } - } - - if (found) - (*mycout) << " copy face " << facei << " from face " << fother; - } - - if (found) - segs.SetSize(0); - */ -} - - - - - - -void CloseSurfaceIdentification :: -BuildSurfaceElements2 (ARRAY<Segment> & segs, - Mesh & mesh, const Surface * surf) -{ - int i1, i2; - int found = 0, cntquads = 0; - int i, j, k; - - int fother; - int facei = segs.Get(1).si; - int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); - - int foundid = 0; - for (i = 1; i <= identfaces.GetNBags(); i++) - for (j = 1; j <= identfaces.GetBagSize(i); j++) - { - INDEX_2 i2; - int data; - identfaces.GetData (i, j, i2, data); - if (i2.I1() == facei || i2.I2() == facei) - foundid = 1; - } - - // (*testout) << "facei = " << facei << ", surfnr = " << surfnr << endl; - - /* - if (geom.GetSurface(surfnr) == s1 || - geom.GetSurface(surfnr) == s2) - */ - if (foundid) - { - // (*testout) << "surfaces found" << endl; - // copy surface - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & sel = mesh.SurfaceElement(i); - INDEX_2 fpair (facei, sel.GetIndex()); - fpair.Sort(); - if (identfaces.Used (fpair)) - { - found = 1; - fother = sel.GetIndex(); - - // copy element - Element2d newel(3); - newel.SetIndex (facei); - for (k = 1; k <= 3; k++) - { - newel.PNum(k) = - GetIdentifiedPoint (mesh, sel.PNum(k)); - // cout << "id-point = " << sel.PNum(k) << ", np = " << newel.PNum(k) << endl; - } - - Vec<3> nt = Cross (Point<3> (mesh.Point (newel.PNum(2)))- - Point<3> (mesh.Point (newel.PNum(1))), - Point<3> (mesh.Point (newel.PNum(3)))- - Point<3> (mesh.Point (newel.PNum(1)))); - Vec<3> nsurf; - nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh.Point(newel.PNum(1))); - if (nsurf * nt < 0) - Swap (newel.PNum(2), newel.PNum(3)); - - mesh.AddSurfaceElement (newel); - } - } - } - - if (found) - { - (*mycout) << " copy face " << facei << " from face " << fother; - segs.SetSize(0); - } -} - - - - - - - - - - - - - - -void CloseSurfaceIdentification :: -BuildVolumeElements (ARRAY<class Element2d> & surfels, - class Mesh & mesh) -{ - ; -} - - - - - - - - - - - - - -/* ***************** Close Edges Identification ********** */ - - - -CloseEdgesIdentification :: -CloseEdgesIdentification (int anr, - const CSGeometry & ageom, - const Surface * afacet, - const Surface * as1, - const Surface * as2) - : Identification(anr, ageom) -{ - facet = afacet; - s1 = as1; - s2 = as2; -} - -CloseEdgesIdentification :: ~CloseEdgesIdentification () -{ - ; -} - -void CloseEdgesIdentification :: Print (ostream & ost) const -{ - ost << "CloseEdges Identifiaction, facet = " - << facet->Name() << ", surfaces: " - << s1->Name() << " - " << s2->Name() << endl; - facet->Print (ost); - s1->Print (ost); - s2->Print (ost); - ost << endl; -} - - -void CloseEdgesIdentification :: GetData (ostream & ost) const -{ - ost << "closeedges " << facet->Name() << " " - << s1->Name() << " " << s2->Name(); -} - - -/* -void CloseEdgesIdentification :: IdentifySpecialPoints -(ARRAY<class SpecialPoint> & points) -{ - int i, j; - int bestj; - double bestval, val; - - for (i = 1; i <= points.Size(); i++) - { - Point<3> p1 = points.Get(i).p; - Vec<3> n1; - - if (!s1->PointOnSurface (p1)) - continue; - - s1->GetNormalVector (p1, n1); - n1 /= n1.Length(); - if ( fabs(n1 * points.Get(i).v) > 1e-3) - continue; - - bestval = 1e8; - bestj = 1; - for (j = 1; j <= points.Size(); j++) - { - Point<3> p2= points.Get(j).p; - if (!s2->PointOnSurface (p2)) - continue; - - Vec<3> n2; - s2->GetNormalVector (p2, n2); - n2 /= n2.Length(); - if ( fabs(n2 * points.Get(j).v) > 1e-3) - continue; - - - Vec<3> v(p1, p2); - double vl = v.Length(); - double cl = fabs (v*n1); - - val = 1 - cl*cl/(vl*vl); - - val += (points.Get(i).v - points.Get(j).v).Length(); - - if (val < bestval) - { - bestj = j; - bestval = val; - } - } - - (*testout) << "Identify close surfaces special points: pi = " - << points.Get(i).p << ", vi = " << points.Get(i).v - << " pj = " << points.Get(bestj).p - << ", vj = " << points.Get(bestj).v - << " bestval = " << bestval << endl; - } -} -*/ - -int CloseEdgesIdentification :: -Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const -{ - int i; - double val; - - SpecialPoint hsp1 = sp1; - SpecialPoint hsp2 = sp2; - - for (i = 1; i <= 1; i++) - { - if (!s1->PointOnSurface (hsp1.p)) - continue; - - Vec<3> n1; - n1 = s1->GetNormalVector (hsp1.p); - n1 /= n1.Length(); - if ( fabs(n1 * hsp1.v) > 1e-3) - continue; - - - if (!s2->PointOnSurface(hsp2.p)) - continue; - - Vec<3> n2; - n2 = s2->GetNormalVector (hsp2.p); - n2 /= n2.Length(); - if ( fabs(n2 * hsp2.v) > 1e-3) - continue; - - - Vec<3> v = hsp2.p - hsp1.p; - double vl = v.Length(); - double cl = fabs (v*n1); - - - val = 1 - cl*cl/(vl*vl); - val += (hsp1.v - hsp2.v).Length(); - - if (val < 1e-3) - { - return 1; - } - } - - return 0; -} - - - - -void CloseEdgesIdentification :: IdentifyPoints (Mesh & mesh) -{ - int i, j; - int i1, i2; - - int np = mesh.GetNP(); - for (i1 = 1; i1 <= np; i1++) - for (i2 = 1; i2 <= np; i2++) - { - if (i2 == i1) - continue; - - const Point<3> p1 = mesh.Point(i1); - const Point<3> p2 = mesh.Point(i2); - Point<3> pp1 = p1; - Point<3> pp2 = p2; - - s1->Project (pp1); - facet->Project (pp1); - s2->Project (pp2); - facet->Project (pp2); - - if (Dist (p1, pp1) > 1e-6 || Dist (p2, pp2) > 1e-6) - continue; - - Vec<3> n1, nf, t; - Vec<3> n = p2 - p1; - n.Normalize(); - - n1 = s1->GetNormalVector (p1); - nf = facet->GetNormalVector (p1); - t = Cross (n1, nf); - t /= t.Length(); - - if (fabs (n * t) < 0.5) - { - (*testout) << "close edges identify points " << p1 << " - " << p2 << endl; - mesh.GetIdentifications().Add (i1, i2, nr); - } - } -} - -void CloseEdgesIdentification :: -BuildSurfaceElements (ARRAY<Segment> & segs, - Mesh & mesh, const Surface * surf) -{ - int i1, i2; - int found = 0; - int i, j, k; - - if (surf != facet) - return; - - for (i1 = 1; i1 <= segs.Size(); i1++) - for (i2 = 1; i2 < i1; i2++) - { - const Segment & s1 = segs.Get(i1); - const Segment & s2 = segs.Get(i2); - if (mesh.GetIdentifications().Get (s1.p1, s2.p2) && - mesh.GetIdentifications().Get (s1.p2, s2.p1)) - { - Element2d el(4); - el.PNum(1) = s1.p1; - el.PNum(2) = s1.p2; - el.PNum(3) = s2.p2; - el.PNum(4) = s2.p1; - - Vec<3> n = Cross (Point<3> (mesh.Point(el.PNum(2)))- - Point<3> (mesh.Point(el.PNum(1))), - Point<3> (mesh.Point(el.PNum(3)))- - Point<3> (mesh.Point(el.PNum(1)))); - Vec<3> ns; - ns = surf->GetNormalVector (mesh.Point(el.PNum(1))); - (*testout) << "n = " << n << " ns = " << ns << endl; - if (n * ns < 0) - { - (*testout) << "Swap the quad" << endl; - Swap (el.PNum(1), el.PNum(2)); - Swap (el.PNum(3), el.PNum(4)); - } - - - Swap (el.PNum(3), el.PNum(4)); - mesh.AddSurfaceElement (el); - (*testout) << "add rect element: " - << mesh.Point (el.PNum(1)) << " - " - << mesh.Point (el.PNum(2)) << " - " - << mesh.Point (el.PNum(3)) << " - " - << mesh.Point (el.PNum(4)) << endl; - found = 1; - } - } - - if (found) - segs.SetSize(0); -} - -} diff --git a/Netgen/libsrc/csg/identify.hpp b/Netgen/libsrc/csg/identify.hpp deleted file mode 100644 index 16e371b200..0000000000 --- a/Netgen/libsrc/csg/identify.hpp +++ /dev/null @@ -1,180 +0,0 @@ - -#ifndef FILE_IDENTIFY -#define FILE_IDENTIFY - -/**************************************************************************/ -/* File: identify.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 1. Aug. 99 */ -/**************************************************************************/ - -/** - Identify surfaces for periodic b.c. or - thin domains -*/ - - -class SpecialPoint; -class Identification -{ -protected: - const CSGeometry & geom; - // identified faces, index sorted - INDEX_2_HASHTABLE<int> identfaces; - int nr; - -public: - Identification (int anr, const CSGeometry & ageom); - virtual ~Identification (); - virtual void Print (ostream & ost) const = 0; - virtual void GetData (ostream & ost) const = 0; - - /// obsolete - // virtual void IdentifySpecialPoints (ARRAY<class SpecialPoint> & points); - - /// can identify both special points (fixed direction) - /// (identified points, same tangent) - virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const; - /// - virtual int Identifyable (const Point<3> & p1, const Point<3> & sp2) const; - /// is it possible to identify sp1 with some other ? - virtual int IdentifyableCandidate (const SpecialPoint & sp1) const; - - /// are points (if connected) by a short edge (direction anyhow) ? - virtual int ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const; - - /// add entries in mesh identification tables - virtual void IdentifyPoints (class Mesh & mesh); - - /// add entries to identified faces (based on segment infos) - virtual void IdentifyFaces (class Mesh & mesh); - - /// get point on other surface, add entry in mesh identifications - virtual int GetIdentifiedPoint (class Mesh & mesh, int pi1); - - /// copy surfaces, or fill rectangles - virtual void BuildSurfaceElements (ARRAY<class Segment> & segs, - class Mesh & mesh, - const Surface * surf); - - /// insert volume elements in thin layers - virtual void BuildVolumeElements (ARRAY<class Element2d> & surfels, - class Mesh & mesh); - - /// get list of identified faces - virtual void GetIdentifiedFaces (ARRAY<INDEX_2> & idfaces) const; - - friend ostream & operator<< (ostream & ost, Identification & ident); -}; - - -class PeriodicIdentification : public Identification -{ - const Surface * s1; - const Surface * s2; -public: - PeriodicIdentification (int anr, - const CSGeometry & ageom, - const Surface * as1, - const Surface * as2); - virtual ~PeriodicIdentification (); - virtual void Print (ostream & ost) const; - virtual void GetData (ostream & ost) const; - - - // virtual void IdentifySpecialPoints (ARRAY<class SpecialPoint> & points); - virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const; - virtual int Identifyable (const Point<3> & p1, const Point<3> & sp2) const; - virtual int GetIdentifiedPoint (class Mesh & mesh, int pi1); - virtual void IdentifyPoints (class Mesh & mesh); - virtual void IdentifyFaces (class Mesh & mesh); - virtual void BuildSurfaceElements (ARRAY<class Segment> & segs, - class Mesh & mesh, - const Surface * surf); -}; - - -/// -class TopLevelObject; -class CloseSurfaceIdentification : public Identification -{ - const Surface * s1; - const Surface * s2; - const TopLevelObject * domain; - /// number of refinement levels (in Z-refinement) - int ref_levels; - /// number of refinement levels for layer next to s1 (in Z-refinement) - int ref_levels_s1; - /// number of refinement levels for layer next to s2 (in Z-refinement) - int ref_levels_s2; - /// - double eps_n; - ARRAY<double> slices; - /// used only for domain-local identification: - ARRAY<int> domain_surfaces; - /// - bool dom_surf_valid; -public: - CloseSurfaceIdentification (int anr, - const CSGeometry & ageom, - const Surface * as1, - const Surface * as2, - const TopLevelObject * adomain, - const Flags & flags); - virtual ~CloseSurfaceIdentification (); - - virtual void Print (ostream & ost) const; - virtual void GetData (ostream & ost) const; - - - // virtual void IdentifySpecialPoints (ARRAY<class SpecialPoint> & points); - virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const; - virtual int Identifyable (const Point<3> & p1, const Point<3> & sp2) const; - virtual int IdentifyableCandidate (const SpecialPoint & sp1) const; - virtual int ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const; - virtual int GetIdentifiedPoint (class Mesh & mesh, int pi1); - const ARRAY<double> & GetSlices () const { return slices; } - virtual void IdentifyPoints (class Mesh & mesh); - virtual void IdentifyFaces (class Mesh & mesh); - virtual void BuildSurfaceElements (ARRAY<class Segment> & segs, - class Mesh & mesh, - const Surface * surf); - void BuildSurfaceElements2 (ARRAY<class Segment> & segs, - class Mesh & mesh, - const Surface * surf); - - virtual void BuildVolumeElements (ARRAY<class Element2d> & surfels, - class Mesh & mesh); - - int RefLevels () const { return ref_levels; } - int RefLevels1 () const { return ref_levels_s1; } - int RefLevels2 () const { return ref_levels_s2; } -}; - - -class CloseEdgesIdentification : public Identification -{ - const Surface * facet; - const Surface * s1; - const Surface * s2; -public: - CloseEdgesIdentification (int anr, - const CSGeometry & ageom, - const Surface * afacet, - const Surface * as1, - const Surface * as2); - virtual ~CloseEdgesIdentification (); - virtual void Print (ostream & ost) const; - virtual void GetData (ostream & ost) const; - - // virtual void IdentifySpecialPoints (ARRAY<class SpecialPoint> & points); - virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2) const; - - - virtual void IdentifyPoints (class Mesh & mesh); - virtual void BuildSurfaceElements (ARRAY<class Segment> & segs, - class Mesh & mesh, - const Surface * surf); -}; - -#endif diff --git a/Netgen/libsrc/csg/lex.yy.cpp b/Netgen/libsrc/csg/lex.yy.cpp deleted file mode 100644 index 31c180c05d..0000000000 --- a/Netgen/libsrc/csg/lex.yy.cpp +++ /dev/null @@ -1,1834 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header: /cvsroot/gmsh/Netgen/libsrc/csg/lex.yy.cpp,v 1.1 2004-06-26 17:58:14 geuzaine Exp $ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include <stdlib.h> -#include <iostream.h> -#include <unistd.h> - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - istream* yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - - -#define FLEX_DEBUG -typedef unsigned char YY_CHAR; -#define yytext_ptr yytext -#define YY_INTERACTIVE - -#define FLEX_DEBUG - -#include <FlexLexer.h> - - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 37 -#define YY_END_OF_BUFFER 38 -static yyconst short int yy_accept[222] = - { 0, - 0, 0, 0, 0, 0, 0, 38, 33, 32, 34, - 33, 33, 33, 30, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 37, 0, - 36, 0, 0, 30, 30, 30, 0, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 5, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 0, 35, 0, 0, 30, 31, 4, 31, - 31, 31, 31, 31, 31, 31, 31, 6, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 3, 31, - 31, 0, 30, 31, 31, 31, 13, 31, 22, 31, - - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 16, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 14, 15, 23, 31, 31, 31, - 31, 2, 31, 31, 31, 31, 31, 31, 31, 31, - 17, 31, 31, 31, 31, 31, 31, 31, 9, 31, - 11, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 12, 24, 31, 31, 31, 27, 31, 31, - 21, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 7, 31, 31, 31, 26, 31, 31, 31, - - 18, 19, 20, 1, 31, 29, 31, 10, 31, 31, - 31, 31, 31, 25, 31, 31, 8, 31, 31, 28, - 0 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, - 1, 1, 5, 1, 5, 6, 1, 7, 7, 7, - 8, 7, 7, 7, 7, 7, 7, 1, 1, 1, - 1, 1, 1, 1, 9, 9, 9, 9, 10, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 1, 1, 1, 1, 1, 1, 11, 12, 13, 14, - - 15, 16, 17, 18, 19, 9, 20, 21, 22, 23, - 24, 25, 9, 26, 27, 28, 29, 30, 9, 31, - 32, 9, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[33] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2 - } ; - -static yyconst short int yy_base[226] = - { 0, - 0, 0, 0, 0, 0, 0, 77, 706, 706, 706, - 30, 29, 31, 34, 38, 40, 43, 61, 45, 47, - 50, 58, 64, 66, 87, 76, 105, 124, 706, 67, - 706, 57, 68, 0, 71, 89, 98, 82, 102, 108, - 112, 110, 114, 120, 126, 129, 133, 144, 141, 147, - 150, 153, 156, 161, 158, 163, 166, 169, 176, 178, - 185, 191, 53, 706, 199, 193, 201, 203, 205, 207, - 209, 212, 214, 216, 221, 218, 230, 232, 235, 237, - 240, 242, 244, 247, 253, 260, 262, 265, 267, 271, - 275, 277, 279, 281, 284, 288, 292, 294, 297, 299, - - 301, 303, 306, 308, 311, 313, 316, 318, 330, 332, - 334, 338, 340, 342, 346, 348, 351, 357, 368, 360, - 370, 372, 378, 380, 384, 388, 394, 396, 398, 400, - 402, 405, 409, 411, 414, 421, 423, 426, 428, 430, - 434, 436, 441, 443, 446, 448, 452, 454, 456, 463, - 468, 470, 472, 476, 478, 480, 485, 491, 482, 493, - 495, 497, 502, 505, 511, 515, 517, 519, 521, 528, - 531, 535, 540, 542, 545, 547, 550, 552, 554, 557, - 559, 561, 564, 566, 572, 575, 577, 579, 584, 586, - 590, 592, 596, 602, 610, 612, 614, 616, 619, 623, - - 628, 630, 632, 634, 638, 640, 642, 646, 648, 653, - 655, 657, 659, 661, 663, 667, 669, 672, 676, 681, - 706, 699, 701, 41, 703 - } ; - -static yyconst short int yy_def[226] = - { 0, - 221, 1, 222, 222, 222, 222, 221, 221, 221, 221, - 223, 221, 221, 221, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 221, 223, - 221, 225, 221, 14, 221, 221, 221, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 225, 221, 221, 221, 221, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 221, 221, 224, 224, 224, 224, 224, 224, 224, - - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 0, 221, 221, 221, 221 - } ; - -static yyconst short int yy_nxt[739] = - { 0, - 8, 9, 10, 11, 12, 13, 14, 14, 15, 15, - 16, 17, 18, 15, 19, 15, 20, 15, 21, 15, - 15, 22, 23, 24, 25, 26, 27, 28, 15, 15, - 15, 15, 31, 32, 33, 34, 34, 35, 35, 36, - 34, 34, 39, 37, 38, 38, 38, 38, 37, 38, - 38, 38, 38, 38, 38, 64, 38, 38, 46, 64, - 40, 47, 41, 48, 38, 38, 42, 38, 38, 31, - 38, 38, 38, 38, 35, 35, 221, 35, 35, 221, - 65, 43, 38, 38, 44, 65, 49, 50, 38, 38, - 55, 51, 45, 38, 38, 35, 35, 221, 37, 56, - - 221, 52, 66, 37, 67, 67, 221, 53, 38, 38, - 54, 38, 38, 221, 38, 38, 38, 38, 38, 38, - 38, 38, 221, 57, 68, 69, 38, 38, 58, 59, - 38, 38, 38, 38, 221, 38, 38, 71, 70, 38, - 38, 221, 72, 221, 60, 74, 73, 38, 38, 61, - 38, 38, 62, 38, 38, 75, 38, 38, 76, 38, - 38, 77, 38, 38, 38, 38, 81, 38, 38, 38, - 38, 221, 38, 38, 78, 38, 38, 79, 80, 82, - 221, 83, 38, 38, 38, 38, 221, 84, 86, 87, - 85, 38, 38, 88, 221, 90, 221, 38, 38, 67, - - 67, 89, 91, 92, 221, 93, 93, 67, 67, 38, - 38, 38, 38, 38, 38, 38, 38, 94, 38, 38, - 38, 38, 38, 38, 38, 38, 97, 38, 38, 95, - 99, 221, 98, 100, 221, 96, 38, 38, 38, 38, - 101, 38, 38, 38, 38, 221, 38, 38, 38, 38, - 38, 38, 103, 38, 38, 104, 221, 102, 105, 38, - 38, 221, 106, 110, 107, 221, 38, 38, 38, 38, - 109, 38, 38, 38, 38, 108, 111, 38, 38, 113, - 112, 38, 38, 93, 93, 93, 93, 38, 38, 115, - 38, 38, 116, 114, 38, 38, 221, 117, 38, 38, - - 38, 38, 118, 38, 38, 38, 38, 38, 38, 38, - 38, 221, 38, 38, 38, 38, 119, 38, 38, 38, - 38, 122, 38, 38, 38, 38, 221, 126, 121, 123, - 120, 124, 221, 125, 221, 128, 38, 38, 38, 38, - 38, 38, 221, 127, 38, 38, 38, 38, 38, 38, - 129, 132, 38, 38, 38, 38, 221, 38, 38, 130, - 221, 136, 131, 38, 38, 133, 38, 38, 134, 137, - 221, 138, 221, 135, 38, 38, 38, 38, 38, 38, - 141, 140, 221, 139, 38, 38, 38, 38, 142, 145, - 38, 38, 221, 146, 38, 38, 221, 143, 221, 144, - - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 147, 38, 38, 221, 149, 38, 38, 38, 38, 221, - 38, 38, 150, 151, 153, 221, 148, 38, 38, 38, - 38, 152, 38, 38, 38, 38, 38, 38, 221, 156, - 38, 38, 38, 38, 158, 155, 154, 38, 38, 38, - 38, 159, 38, 38, 38, 38, 157, 221, 38, 38, - 38, 38, 38, 38, 160, 164, 163, 221, 161, 38, - 38, 162, 221, 166, 38, 38, 38, 38, 38, 38, - 167, 165, 38, 38, 38, 38, 38, 38, 38, 38, - 168, 38, 38, 221, 170, 221, 171, 38, 38, 38, - - 38, 38, 38, 38, 38, 176, 221, 169, 38, 38, - 172, 38, 38, 174, 178, 177, 173, 38, 38, 221, - 175, 38, 38, 38, 38, 38, 38, 38, 38, 180, - 179, 183, 221, 184, 38, 38, 221, 38, 38, 185, - 181, 38, 38, 221, 182, 186, 38, 38, 38, 38, - 187, 38, 38, 38, 38, 188, 38, 38, 38, 38, - 38, 38, 190, 38, 38, 38, 38, 38, 38, 189, - 38, 194, 38, 38, 221, 193, 221, 191, 38, 38, - 192, 38, 38, 38, 38, 38, 38, 198, 221, 195, - 38, 38, 38, 38, 221, 196, 38, 38, 38, 38, - - 221, 197, 38, 38, 221, 201, 199, 221, 38, 38, - 200, 221, 202, 221, 203, 204, 38, 38, 38, 38, - 38, 38, 38, 38, 221, 38, 38, 221, 207, 38, - 38, 221, 205, 208, 38, 38, 38, 38, 38, 38, - 38, 38, 206, 209, 38, 38, 38, 38, 38, 38, - 221, 210, 38, 38, 38, 38, 211, 221, 212, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 213, 221, 38, 38, 38, 38, 217, 38, 38, - 221, 214, 38, 38, 215, 218, 216, 38, 38, 221, - 221, 221, 221, 221, 221, 219, 221, 221, 220, 29, - - 29, 30, 30, 63, 63, 7, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221 - } ; - -static yyconst short int yy_chk[739] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 11, 11, 12, 12, 12, 13, 13, 14, - 14, 14, 224, 14, 15, 15, 16, 16, 14, 17, - 17, 19, 19, 20, 20, 63, 21, 21, 19, 32, - 16, 20, 16, 21, 22, 22, 17, 18, 18, 30, - 23, 23, 24, 24, 33, 33, 7, 35, 35, 0, - 35, 18, 26, 26, 18, 35, 22, 23, 38, 38, - 26, 24, 18, 25, 25, 36, 36, 0, 36, 26, - - 0, 25, 37, 36, 37, 37, 0, 25, 39, 39, - 25, 27, 27, 0, 40, 40, 42, 42, 41, 41, - 43, 43, 0, 27, 40, 41, 44, 44, 27, 27, - 28, 28, 45, 45, 0, 46, 46, 43, 42, 47, - 47, 0, 44, 0, 28, 46, 45, 49, 49, 28, - 48, 48, 28, 50, 50, 47, 51, 51, 48, 52, - 52, 49, 53, 53, 55, 55, 53, 54, 54, 56, - 56, 0, 57, 57, 50, 58, 58, 51, 52, 54, - 0, 54, 59, 59, 60, 60, 0, 55, 57, 58, - 56, 61, 61, 59, 0, 61, 0, 62, 62, 66, - - 66, 60, 62, 65, 0, 65, 65, 67, 67, 68, - 68, 69, 69, 70, 70, 71, 71, 68, 72, 72, - 73, 73, 74, 74, 76, 76, 72, 75, 75, 70, - 74, 0, 73, 75, 0, 71, 77, 77, 78, 78, - 76, 79, 79, 80, 80, 0, 81, 81, 82, 82, - 83, 83, 79, 84, 84, 80, 0, 77, 81, 85, - 85, 0, 81, 85, 82, 0, 86, 86, 87, 87, - 84, 88, 88, 89, 89, 83, 86, 90, 90, 88, - 87, 91, 91, 92, 92, 93, 93, 94, 94, 91, - 95, 95, 94, 90, 96, 96, 0, 95, 97, 97, - - 98, 98, 96, 99, 99, 100, 100, 101, 101, 102, - 102, 0, 103, 103, 104, 104, 98, 105, 105, 106, - 106, 102, 107, 107, 108, 108, 0, 106, 101, 103, - 100, 104, 0, 105, 0, 108, 109, 109, 110, 110, - 111, 111, 0, 107, 112, 112, 113, 113, 114, 114, - 109, 112, 115, 115, 116, 116, 0, 117, 117, 110, - 0, 117, 111, 118, 118, 113, 120, 120, 114, 117, - 0, 118, 0, 116, 119, 119, 121, 121, 122, 122, - 120, 119, 0, 118, 123, 123, 124, 124, 121, 123, - 125, 125, 0, 124, 126, 126, 0, 122, 0, 122, - - 127, 127, 128, 128, 129, 129, 130, 130, 131, 131, - 128, 132, 132, 0, 130, 133, 133, 134, 134, 0, - 135, 135, 131, 133, 135, 0, 129, 136, 136, 137, - 137, 134, 138, 138, 139, 139, 140, 140, 0, 138, - 141, 141, 142, 142, 140, 137, 136, 143, 143, 144, - 144, 142, 145, 145, 146, 146, 139, 0, 147, 147, - 148, 148, 149, 149, 143, 147, 146, 0, 144, 150, - 150, 145, 0, 150, 151, 151, 152, 152, 153, 153, - 152, 148, 154, 154, 155, 155, 156, 156, 159, 159, - 153, 157, 157, 0, 155, 0, 156, 158, 158, 160, - - 160, 161, 161, 162, 162, 161, 0, 154, 163, 163, - 157, 164, 164, 159, 163, 162, 158, 165, 165, 0, - 160, 166, 166, 167, 167, 168, 168, 169, 169, 165, - 164, 168, 0, 169, 170, 170, 0, 171, 171, 170, - 166, 172, 172, 0, 167, 171, 173, 173, 174, 174, - 172, 175, 175, 176, 176, 175, 177, 177, 178, 178, - 179, 179, 177, 180, 180, 181, 181, 182, 182, 176, - 183, 183, 184, 184, 0, 182, 0, 179, 185, 185, - 180, 186, 186, 187, 187, 188, 188, 187, 0, 184, - 189, 189, 190, 190, 0, 185, 191, 191, 192, 192, - - 0, 186, 193, 193, 0, 190, 188, 0, 194, 194, - 189, 0, 191, 0, 192, 194, 195, 195, 196, 196, - 197, 197, 198, 198, 0, 199, 199, 0, 198, 200, - 200, 0, 195, 199, 201, 201, 202, 202, 203, 203, - 204, 204, 196, 200, 205, 205, 206, 206, 207, 207, - 0, 205, 208, 208, 209, 209, 207, 0, 209, 210, - 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, - 215, 210, 0, 216, 216, 217, 217, 215, 218, 218, - 0, 211, 219, 219, 212, 216, 213, 220, 220, 0, - 0, 0, 0, 0, 0, 218, 0, 0, 219, 222, - - 222, 223, 223, 225, 225, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221 - } ; - -static yyconst short int yy_rule_linenum[37] = - { 0, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 54, 55, 56, 58, 59, 60, 61, 62, 63, 65, - 66, 75, 76, 77, 78, 79 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "geometry.ll" -#define INITIAL 0 -#line 2 "geometry.ll" -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - - - -// extern SYMBOLTABLE<Solid*> solids; -namespace netgen { -extern CSGeometry * parsegeom; -} -using namespace netgen; - -#include "geometry.h" - - -ARRAY<char*> parsestrings; -int linenum; -#define incl 1 - -#define comment 2 - -#line 594 "lex.yy.cc" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -#define ECHO LexerOutput( yytext, yyleng ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) LexerError( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yyFlexLexer::yylex() -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 32 "geometry.ll" - -#line 723 "lex.yy.cc" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = &cin; - - if ( ! yyout ) - yyout = &cout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 222 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 706 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - if ( yy_flex_debug ) - { - if ( yy_act == 0 ) - cerr << "--scanner backing up\n"; - else if ( yy_act < 37 ) - cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] << - "(\"" << yytext << "\")\n"; - else if ( yy_act == 37 ) - cerr << "--accepting default rule (\"" << yytext << "\")\n"; - else if ( yy_act == 38 ) - cerr << "--(end of buffer or a NUL)\n"; - else - cerr << "--EOF (start condition " << YY_START << ")\n"; - } - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 33 "geometry.ll" -{ return TOK_RECO; } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 34 "geometry.ll" -{ return TOK_SOLID; } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 35 "geometry.ll" -{ return TOK_TLO; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 36 "geometry.ll" -{ return TOK_AND; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 37 "geometry.ll" -{ return TOK_OR; } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 38 "geometry.ll" -{ return TOK_NOT; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 39 "geometry.ll" -{ return TOK_TRANSLATE; } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 40 "geometry.ll" -{ return TOK_MULTITRANSLATE; } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 41 "geometry.ll" -{ return TOK_ROTATE; } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 42 "geometry.ll" -{ return TOK_MULTIROTATE; } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 43 "geometry.ll" -{ return TOK_SPHERE; } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 44 "geometry.ll" -{ return TOK_CYLINDER; } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 45 "geometry.ll" -{ return TOK_CONE; } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 46 "geometry.ll" -{ return TOK_PLAIN; } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 47 "geometry.ll" -{ return TOK_PLAIN; } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 48 "geometry.ll" -{ return TOK_TUBE; } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 49 "geometry.ll" -{ return TOK_GENCYL; } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 50 "geometry.ll" -{ return TOK_ORTHOBRICK; } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 51 "geometry.ll" -{ return TOK_POLYHEDRON; } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 52 "geometry.ll" -{ return TOK_REVOLUTION; } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 54 "geometry.ll" -{ return TOK_SINGULAR; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 55 "geometry.ll" -{ return TOK_EDGE; } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 56 "geometry.ll" -{ return TOK_POINT; } - YY_BREAK -case 24: -YY_RULE_SETUP -#line 58 "geometry.ll" -{ return TOK_IDENTIFY; } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 59 "geometry.ll" -{ return TOK_CLOSESURFACES; } - YY_BREAK -case 26: -YY_RULE_SETUP -#line 60 "geometry.ll" -{ return TOK_CLOSEEDGES; } - YY_BREAK -case 27: -YY_RULE_SETUP -#line 61 "geometry.ll" -{ return TOK_PERIODIC; } - YY_BREAK -case 28: -YY_RULE_SETUP -#line 62 "geometry.ll" -{ return TOK_BOUNDARYCONDITION; } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 63 "geometry.ll" -{ return TOK_BOUNDINGBOX; } - YY_BREAK -case 30: -YY_RULE_SETUP -#line 65 "geometry.ll" -{ yylval.val = atof (YYText()); return NUM; } - YY_BREAK -case 31: -YY_RULE_SETUP -#line 66 "geometry.ll" -{ - yylval.chptr = new char [YYLeng()+1]; - parsestrings.Append (yylval.chptr); - strcpy (yylval.chptr, YYText()); - if (parsegeom->GetSolid (yylval.chptr)) - return IDENTSOLID; - else - return IDENT; - } - YY_BREAK -case 32: -YY_RULE_SETUP -#line 75 "geometry.ll" -/* eat up ws */ - YY_BREAK -case 33: -YY_RULE_SETUP -#line 76 "geometry.ll" -{ return int(*YYText()); } - YY_BREAK -case 34: -YY_RULE_SETUP -#line 77 "geometry.ll" -{ linenum++; } - YY_BREAK -case 35: -YY_RULE_SETUP -#line 78 "geometry.ll" -{ linenum++; cout << (YYText()+2) ; } /* line comment */ - YY_BREAK -case 36: -YY_RULE_SETUP -#line 79 "geometry.ll" -{ linenum++; } /* line comment */ - YY_BREAK -case 37: -YY_RULE_SETUP -#line 82 "geometry.ll" -ECHO; - YY_BREAK -#line 1013 "lex.yy.cc" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(incl): -case YY_STATE_EOF(comment): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - -yyFlexLexer::yyFlexLexer( istream* arg_yyin, ostream* arg_yyout ) - { - yyin = arg_yyin; - yyout = arg_yyout; - yy_c_buf_p = 0; - yy_init = 1; - yy_start = 0; - yy_flex_debug = 0; - yylineno = 1; // this will only get updated if %option yylineno - - yy_did_buffer_switch_on_eof = 0; - - yy_looking_for_trail_begin = 0; - yy_more_flag = 0; - yy_more_len = 0; - yy_more_offset = yy_prev_more_offset = 0; - - yy_start_stack_ptr = yy_start_stack_depth = 0; - yy_start_stack = 0; - - yy_current_buffer = 0; - -#ifdef YY_USES_REJECT - yy_state_buf = new yy_state_type[YY_BUF_SIZE + 2]; -#else - yy_state_buf = 0; -#endif - } - -yyFlexLexer::~yyFlexLexer() - { - delete yy_state_buf; - yy_delete_buffer( yy_current_buffer ); - } - -void yyFlexLexer::switch_streams( istream* new_in, ostream* new_out ) - { - if ( new_in ) - { - yy_delete_buffer( yy_current_buffer ); - yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); - } - - if ( new_out ) - yyout = new_out; - } - -#ifdef YY_INTERACTIVE -int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) -#else -int yyFlexLexer::LexerInput( char* buf, int max_size ) -#endif - { - if ( yyin->eof() || yyin->fail() ) - return 0; - -#ifdef YY_INTERACTIVE - yyin->get( buf[0] ); - - if ( yyin->eof() ) - return 0; - - if ( yyin->bad() ) - return -1; - - return 1; - -#else - (void) yyin->read( buf, max_size ); - - if ( yyin->bad() ) - return -1; - else - return yyin->gcount(); -#endif - } - -void yyFlexLexer::LexerOutput( const char* buf, int size ) - { - (void) yyout->write( buf, size ); - } - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -int yyFlexLexer::yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -yy_state_type yyFlexLexer::yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 222 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 222 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 221); - - return yy_is_jam ? 0 : yy_current_state; - } - - -void yyFlexLexer::yyunput( int c, register char* yy_bp ) - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } - - -int yyFlexLexer::yyinput() - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - - return c; - } - - -void yyFlexLexer::yyrestart( istream* input_file ) - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -void yyFlexLexer::yy_load_buffer_state() - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size ) - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#include<unistd.h> -void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file ) - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - b->yy_is_interactive = 0; - } - - -void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#endif - - -#ifndef YY_NO_SCAN_STRING -#endif - - -#ifndef YY_NO_SCAN_BYTES -#endif - - -#ifndef YY_NO_PUSH_STATE -void yyFlexLexer::yy_push_state( int new_state ) - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -void yyFlexLexer::yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -int yyFlexLexer::yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - - -void yyFlexLexer::LexerError( yyconst char msg[] ) - { - cerr << msg << '\n'; - exit( YY_EXIT_FAILURE ); - } - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 82 "geometry.ll" - - -extern FlexLexer * lexer; - -int yylex () - { - return lexer -> yylex(); - } - -extern "C" int yywrap () - { - return 1; - } diff --git a/Netgen/libsrc/csg/manifold.cpp b/Netgen/libsrc/csg/manifold.cpp deleted file mode 100644 index 9733389d67..0000000000 --- a/Netgen/libsrc/csg/manifold.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include <csg.hpp> - -namespace netgen -{ -Manifold :: Manifold () -{ - ; -} - -Manifold :: ~Manifold () -{ - ; -} -} diff --git a/Netgen/libsrc/csg/manifold.hpp b/Netgen/libsrc/csg/manifold.hpp deleted file mode 100644 index 5deb7236a7..0000000000 --- a/Netgen/libsrc/csg/manifold.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef FILE_MANIFOLD -#define FILE_MANIFOLD - -/**************************************************************************/ -/* File: manifold.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 7. Aug. 96 */ -/**************************************************************************/ - -/** - Basis class for manifolds in 2d and 3d -*/ -class Manifold -{ -public: - /// - Manifold (); - /// - virtual ~Manifold (); -}; - -#endif diff --git a/Netgen/libsrc/csg/meshsurf.cpp b/Netgen/libsrc/csg/meshsurf.cpp deleted file mode 100644 index 0a7d7c74a0..0000000000 --- a/Netgen/libsrc/csg/meshsurf.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include <mystdlib.h> - -#include <csg.hpp> -#include <meshing.hpp> - - - -namespace netgen -{ - /* -Meshing2Surfaces :: Meshing2Surfaces (const Surface & asurface) - : surface(asurface) -{ - ; -} - */ -Meshing2Surfaces :: Meshing2Surfaces (const Surface & asurf, - const Box<3> & abb) - : Meshing2(Box3d(abb.PMin(), abb.PMax())), surface(asurf) -{ - ; -} - - -void Meshing2Surfaces :: DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2) -{ - ((Surface&)surface).DefineTangentialPlane (p1, p2); -} - -void Meshing2Surfaces :: TransformToPlain (const Point3d & locpoint, - const MultiPointGeomInfo & geominfo, - Point2d & planepoint, - double h, int & zone) -{ - Point<2> hp; - surface.ToPlane (locpoint, hp, h, zone); - planepoint.X() = hp(0); - planepoint.Y() = hp(1); -} - -int Meshing2Surfaces :: TransformFromPlain (Point2d & planepoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h) -{ - Point<3> hp; - Point<2> hp2 (planepoint.X(), planepoint.Y()); - surface.FromPlane (hp2, hp, h); - locpoint = hp; - gi.trignum = 1; - return 0; -} - - - -double Meshing2Surfaces :: CalcLocalH (const Point3d & p, double gh) const -{ - return surface.LocH (p, 3, 1, gh); - /* - double loch = mesh.lochfunc->GetH(p); - if (gh < loch) loch = gh; - return loch; - */ -} - - - - - - -MeshOptimize2dSurfaces :: MeshOptimize2dSurfaces (const CSGeometry & ageometry) - : MeshOptimize2d(), geometry(ageometry) -{ - ; -} - - -void MeshOptimize2dSurfaces :: ProjectPoint (INDEX surfind, Point3d & p) const -{ - Point<3> hp = p; - geometry.GetSurface(surfind)->Project (hp); - p = hp; -} - -void MeshOptimize2dSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, - Point3d & p) const -{ - Point<3> hp = p; - ProjectToEdge ( geometry.GetSurface(surfind), - geometry.GetSurface(surfind2), hp); - p = hp; -} - - -void MeshOptimize2dSurfaces :: -GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const -{ - Vec<3> hn = n; - geometry.GetSurface(surfind)->CalcGradient (p, hn); - hn.Normalize(); - n = hn; - - /* - if (geometry.GetSurface(surfind)->Inverse()) - n *= -1; - */ -} - - - - - - - -RefinementSurfaces :: RefinementSurfaces (const CSGeometry & ageometry) - : Refinement(), geometry(ageometry) -{ - ; -} - -RefinementSurfaces :: ~RefinementSurfaces () -{ - ; -} - -void RefinementSurfaces :: -PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi) -{ - Point<3> hnewp; - hnewp = p1+secpoint*(p2-p1); - - if (surfi != -1) - { - geometry.GetSurface (surfi) -> Project (hnewp); - newgi.trignum = 1; - } - - newp = hnewp; -} - -void RefinementSurfaces :: -PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi) -{ - Point<3> hnewp = p1+secpoint*(p2-p1); - if (surfi1 != -1 && surfi2 != -1 && surfi1 != surfi2) - { - ProjectToEdge (geometry.GetSurface(surfi1), - geometry.GetSurface(surfi2), - hnewp); - // (*testout) << "Pointbetween, newp = " << hnewp << endl - // << ", err = " << sqrt (sqr (hnewp(0))+ sqr(hnewp(1)) + sqr (hnewp(2))) - 1 << endl; - newgi.edgenr = 1; - } - else if (surfi1 != -1) - { - geometry.GetSurface (surfi1) -> Project (hnewp); - } - - newp = hnewp; -} - - -void RefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) -{ - if (surfi != -1) - geometry.GetSurface (surfi) -> Project (p); -} -} diff --git a/Netgen/libsrc/csg/meshsurf.hpp b/Netgen/libsrc/csg/meshsurf.hpp deleted file mode 100644 index 023c2eef70..0000000000 --- a/Netgen/libsrc/csg/meshsurf.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef FILE_MESHSURF -#define FILE_MESHSURF - -/// -class Meshing2Surfaces : public Meshing2 -{ - /// - const Surface & surface; - -public: - /// - // Meshing2Surfaces (const Surface & asurf); - /// - Meshing2Surfaces (const Surface & asurf, const Box<3> & aboundingbox); - -protected: - /// - virtual void DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2); - /// - virtual void TransformToPlain (const Point3d & locpoint, - const MultiPointGeomInfo & geominfo, - Point2d & plainpoint, - double h, int & zone); - /// - virtual int TransformFromPlain (Point2d & plainpoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h); - /// - virtual double CalcLocalH (const Point3d & p, double gh) const; -}; - - - -/// -class MeshOptimize2dSurfaces : public MeshOptimize2d - { - /// - const CSGeometry & geometry; - -public: - /// - MeshOptimize2dSurfaces (const CSGeometry & ageometry); - - /// - virtual void ProjectPoint (INDEX surfind, Point3d & p) const; - /// - virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point3d & p) const; - /// - virtual void GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const; -}; - - - - - -class RefinementSurfaces : public Refinement -{ - const CSGeometry & geometry; - -public: - RefinementSurfaces (const CSGeometry & ageometry); - virtual ~RefinementSurfaces (); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi); - - virtual void ProjectToSurface (Point<3> & p, int surfi); -}; - - - -#endif - diff --git a/Netgen/libsrc/csg/polyhedra.cpp b/Netgen/libsrc/csg/polyhedra.cpp deleted file mode 100644 index f0ce2f63f5..0000000000 --- a/Netgen/libsrc/csg/polyhedra.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include <mystdlib.h> - -#include <linalg.hpp> -#include <csg.hpp> - -namespace netgen -{ - -Polyhedra::Face::Face (int pi1, int pi2, int pi3, const ARRAY<Point<3> > & points) -{ - pnums[0] = pi1; - pnums[1] = pi2; - pnums[2] = pi3; - - bbox.Set (points[pi1]); - bbox.Add (points[pi2]); - bbox.Add (points[pi3]); - - v1 = points[pi2] - points[pi1]; - v2 = points[pi3] - points[pi1]; - - n = Cross (v1, v2); - nn = n; - nn.Normalize(); - // PseudoInverse (v1, v2, w1, w2); - - Mat<2,3> mat; - Mat<3,2> inv; - for (int i = 0; i < 3; i++) - { - mat(0,i) = v1(i); - mat(1,i) = v2(i); - } - CalcInverse (mat, inv); - for (int i = 0; i < 3; i++) - { - w1(i) = inv(i,0); - w2(i) = inv(i,1); - } -} - - -Polyhedra :: Polyhedra () -{ - surfaceactive.SetSize(0); - surfaceids.SetSize(0); -} - -Polyhedra :: ~Polyhedra () -{ - ; -} - -Primitive * Polyhedra :: CreateDefault () -{ - return new Polyhedra(); -} - -INSOLID_TYPE Polyhedra :: BoxInSolid (const BoxSphere<3> & box) const -{ - /* - for (i = 1; i <= faces.Size(); i++) - if (FaceBoxIntersection (i, box)) - return DOES_INTERSECT; - */ - for (int i = 0; i < faces.Size(); i++) - { - if (!faces[i].bbox.Intersect (box)) - continue; - - const Point<3> & p1 = points[faces[i].pnums[0]]; - const Point<3> & p2 = points[faces[i].pnums[1]]; - const Point<3> & p3 = points[faces[i].pnums[2]]; - - if (fabs (faces[i].nn * (p1 - box.Center())) > box.Diam()/2) - continue; - - double dist2 = MinDistTP2 (p1, p2, p3, box.Center()); - if (dist2 < sqr (box.Diam()/2)) - return DOES_INTERSECT; - }; - - return PointInSolid (box.Center(), 1e-3 * box.Diam()); -} - - -INSOLID_TYPE Polyhedra :: PointInSolid (const Point<3> & p, - double eps) const -{ - Vec<3> n, v1, v2; - - // random (?) numbers: - n(0) = 0.123871; - n(1) = 0.15432; - n(2) = 0.43989; - - int cnt = 0; - Point<3> pmeps (p(0) - eps, p(1) - eps, p(2) - eps); - - for (int i = 0; i < faces.Size(); i++) - { - const Point<3> & fpmax = faces[i].bbox.PMax(); - if (fpmax(0) < pmeps(0) || - fpmax(1) < pmeps(1) || - fpmax(2) < pmeps(2)) continue; - - const Point<3> & p1 = points[faces[i].pnums[0]]; - - Vec<3> v0 = p - p1; - double lam3 = -(faces[i].n * v0) / (faces[i].n * n); - - if (lam3 < -eps) continue; - Vec<3> rs = v0 + lam3 * n; - - double lam1 = (faces[i].w1 * rs); - double lam2 = (faces[i].w2 * rs); - - if (lam3 < eps) - { - if (lam1 >= -eps && lam2 >= -eps && lam1+lam2 <= 1+eps) - return DOES_INTERSECT; - } - else if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1) - { // lam3 > 0 - cnt++; - } - - } - - // (*testout) << " inside = " << (cnt % 2) << endl; - return (cnt % 2) ? IS_INSIDE : IS_OUTSIDE; -} - - - -INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const -{ - int point_on_n_faces = 0; - INSOLID_TYPE res; - - Vec<3> vn = v; - vn.Normalize(); - for (int i = 0; i < faces.Size(); i++) - { - const Point<3> & p1 = points[faces[i].pnums[0]]; - - Vec<3> v0 = p - p1; - double lam3 = -(faces[i].n * v0); - - if (fabs (lam3) > eps) continue; - - double lam1 = (faces[i].w1 * v0); - double lam2 = (faces[i].w2 * v0); - - if (lam1 >= -eps && lam2 >= -eps && lam1+lam2 <= 1+eps) - { - point_on_n_faces++; - - double scal = vn * faces[i].n; - - res = DOES_INTERSECT; - if (scal > eps) res = IS_OUTSIDE; - if (scal < -eps) res = IS_INSIDE; - } - } - - if (point_on_n_faces == 1) - return res; - - - Point<3> p2 = p + (1e-3/(v.Length()+1e-16)) * v; - res = PointInSolid (p2, eps); - // (*testout) << "p = " << p << " v = " << v << " p2 = " << p2 << endl; - // (*testout) << "polyeder::vecinsolid = " << int(res) << endl; - return res; -} - - -INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const -{ - int point_on_n_faces = 0; - INSOLID_TYPE res; - - Vec<3> v1n = v1; - v1n.Normalize(); - Vec<3> v2n = v2; - v2n.Normalize(); - - - for (int i = 0; i < faces.Size(); i++) - { - const Point<3> & p1 = points[faces[i].pnums[0]]; - - Vec<3> v0 = p - p1; - double lam3 = -(faces[i].n * v0); - - if (fabs (lam3) > eps) continue; - - double lam1 = (faces[i].w1 * v0); - double lam2 = (faces[i].w2 * v0); - - if (lam1 >= -eps && lam2 >= -eps && lam1+lam2 <= 1+eps) - { - double scal1 = v1n * faces[i].n; - if (fabs (scal1) > eps) continue; - - - point_on_n_faces++; - - double scal2 = v2n * faces[i].n; - res = DOES_INTERSECT; - if (scal2 > eps) res = IS_OUTSIDE; - if (scal2 < -eps) res = IS_INSIDE; - } - } - - if (point_on_n_faces == 1) - return res; - - - - - return Primitive :: VecInSolid2 (p, v1, v2, eps); -} - - - - -void Polyhedra :: GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const -{ - classname = "Polyhedra"; - coeffs.SetSize(0); - coeffs.Append (points.Size()); - coeffs.Append (faces.Size()); - coeffs.Append (planes.Size()); - - /* - int i, j; - for (i = 1; i <= planes.Size(); i++) - { - planes.Elem(i)->Print (*testout); - } - for (i = 1; i <= faces.Size(); i++) - { - (*testout) << "face " << i << " has plane " << faces.Get(i).planenr << endl; - for (j = 1; j <= 3; j++) - (*testout) << points.Get(faces.Get(i).pnums[j-1]); - (*testout) << endl; - } - */ -} - -void Polyhedra :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - ; -} - -void Polyhedra :: Reduce (const BoxSphere<3> & box) -{ - for (int i = 0; i < planes.Size(); i++) - surfaceactive[i] = 0; - - for (int i = 0; i < faces.Size(); i++) - if (FaceBoxIntersection (i, box)) - surfaceactive[faces[i].planenr] = 1; -} - -void Polyhedra :: UnReduce () -{ - for (int i = 0; i < planes.Size(); i++) - surfaceactive[i] = 1; -} - -int Polyhedra :: AddPoint (const Point<3> & p) -{ - return points.Append (p); -} - -int Polyhedra :: AddFace (int pi1, int pi2, int pi3) -{ - faces.Append (Face (pi1, pi2, pi3, points)); - - Point<3> p1 = points[pi1]; - Point<3> p2 = points[pi2]; - Point<3> p3 = points[pi3]; - - Vec<3> v1 = p2 - p1; - Vec<3> v2 = p3 - p1; - - Vec<3> n = Cross (v1, v2); - n.Normalize(); - - Plane pl (p1, n); - int inverse; - int identicto = -1; - for (int i = 0; i < planes.Size(); i++) - if (pl.IsIdentic (*planes[i], inverse, 1e-6)) - { - if (!inverse) - identicto = i; - } - // cout << "is identic = " << identicto << endl; - - if (identicto != -1) - faces.Last().planenr = identicto; - else - { - planes.Append (new Plane (p1, n)); - surfaceactive.Append (1); - surfaceids.Append (0); - faces.Last().planenr = planes.Size()-1; - } - - return faces.Size(); -} - - - -int Polyhedra :: FaceBoxIntersection (int fnr, const BoxSphere<3> & box) const -{ - /* - (*testout) << "check face box intersection, fnr = " << fnr << endl; - (*testout) << "box = " << box << endl; - (*testout) << "face-box = " << faces[fnr].bbox << endl; - */ - - if (!faces[fnr].bbox.Intersect (box)) - return 0; - - const Point<3> & p1 = points[faces[fnr].pnums[0]]; - const Point<3> & p2 = points[faces[fnr].pnums[1]]; - const Point<3> & p3 = points[faces[fnr].pnums[2]]; - - double dist2 = MinDistTP2 (p1, p2, p3, box.Center()); - /* - (*testout) << "p1 = " << p1 << endl; - (*testout) << "p2 = " << p2 << endl; - (*testout) << "p3 = " << p3 << endl; - - (*testout) << "box.Center() = " << box.Center() << endl; - (*testout) << "center = " << box.Center() << endl; - (*testout) << "dist2 = " << dist2 << endl; - (*testout) << "diam = " << box.Diam() << endl; - */ - if (dist2 < sqr (box.Diam()/2)) - { - // (*testout) << "intersect" << endl; - return 1; - } - return 0; -} -} diff --git a/Netgen/libsrc/csg/polyhedra.hpp b/Netgen/libsrc/csg/polyhedra.hpp deleted file mode 100644 index 529cfff40d..0000000000 --- a/Netgen/libsrc/csg/polyhedra.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef FILE_POLYHEDRA -#define FILE_POLYHEDRA - - -/**************************************************************************/ -/* File: polyhedra.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 19. Mar. 2000 */ -/**************************************************************************/ - -/* - - Polyhedral primitive - -*/ - -class Polyhedra : public Primitive -{ - class Face { - public: - int pnums[3]; - int planenr; - - Box<3> bbox; - // Point<3> center; - Vec<3> v1, v2; // edges - Vec<3> w1, w2; // pseudo-inverse - Vec<3> n; // normal to face - Vec<3> nn; // normed normal - - Face () { ; } - Face (int pi1, int pi2, int pi3, const ARRAY<Point<3> > & points); - }; - - ARRAY<Point<3> > points; - ARRAY<Face> faces; - ARRAY<Plane*> planes; - -public: - Polyhedra (); - virtual ~Polyhedra (); - static Primitive * CreateDefault (); - - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const; - - // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid - virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const; - - virtual int GetNSurfaces() const - { return planes.Size(); } - virtual Surface & GetSurface (int i) - { return *planes[i]; } - virtual const Surface & GetSurface (int i) const - { return *planes[i]; } - - virtual void GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - - virtual void Reduce (const BoxSphere<3> & box); - virtual void UnReduce (); - - int AddPoint (const Point<3> & p); - int AddFace (int pi1, int pi2, int pi3); - -protected: - int FaceBoxIntersection (int fnr, const BoxSphere<3> & box) const; - // void CalcData(); -}; - -#endif diff --git a/Netgen/libsrc/csg/revolution.cpp b/Netgen/libsrc/csg/revolution.cpp deleted file mode 100644 index e235012e43..0000000000 --- a/Netgen/libsrc/csg/revolution.cpp +++ /dev/null @@ -1,151 +0,0 @@ -#include <mystdlib.h> - -#include <linalg.hpp> -#include <csg.hpp> - -namespace netgen -{ - -#ifdef NONE - -Revolution :: Revolution (const Point<3> & ap1, const Point<3> & ap2) -{ - p1 = ap1; - p2 = ap2; - v12 = p2 - p1; - v12.Normalize(); -} - -Revolution :: ~Revolution () -{ - ; -} - -Primitive * Revolution :: CreateDefault () -{ - return new Revolution( Point<3> (0, 0, 0), - Point<3> (1, 0, 0)); -} - -INSOLID_TYPE Revolution :: BoxInSolid (const BoxSphere<3> & box) const -{ - int i; - - Vec<3> v = box.Center() - p1; - double x = v * v12; - double y = sqrt (v.Length2() - x*x); - - Point<2> lp1, lp2; - for (i = 1; i <= polygon.GetNP(); i++) - { - polygon.GetLine (i, lp1, lp2); - - double dist2 = MinDistLP2 (lp1, lp2, Point<2>(x,y)); - if (dist2 < sqr (box.Diam())) - return DOES_INTERSECT; - }; - - return PointInSolid (box.Center(), 1e-3 * box.Diam()); -} - - -INSOLID_TYPE Revolution :: PointInSolid (const Point<3> & p, - double eps) const -{ - int i, cnt; - - Vec<3> v(p1, p); - double x = v * v12; - double y = sqrt (v.Length2() - x*x); - - if (polygon.IsOn (Point<2> (x, y))) - return DOES_INTERSECT; - if (polygon.IsIn (Point<2> (x, y))) - return IS_INSIDE; - else - return IS_OUTSIDE; -} - - - -INSOLID_TYPE Revolution :: VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const -{ - Point<3> p2 = p + (1e-3/(v.Length()+1e-16)) * v; - return PointInSolid (p2, eps); -} - - -void Revolution :: GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const -{ - classname = "Revolution"; - coeffs.SetSize(0); - coeffs.Append (polygon.GetNP()); -} - -void Revolution :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - ; -} - -void Revolution :: Reduce (const BoxSphere<3> & box) -{ - int i; - - for (i = 1; i <= polygon.GetNP(); i++) - surfaceactive.Elem (i) = 0; - - - Vec<3> v = box.Center() - p1; - double x = v * v12; - double y = sqrt (v.Length2() - x*x); - - Point<2> lp1, lp2; - for (i = 1; i <= polygon.GetNP(); i++) - { - polygon.GetLine (i, lp1, lp2); - - double dist2 = MinDistLP2 (lp1, lp2, Point<2>(x,y)); - if (dist2 < sqr (box.Diam()/2)) - surfaceactive.Elem(i) = 1; - }; -} - -void Revolution :: UnReduce () -{ - for (int i = 0; i < polygon.GetNP(); i++) - surfaceactive[i] = 1; -} - - -int Revolution :: AddPoint (const Point<2> & p) -{ - polygon.AddPoint (p); - return polygon.GetNP(); -} - -void Revolution :: Finish () -{ - int i; - Point<2> lp1, lp2; - Point<3> cp1, cp2; - - for (i = 1; i <= polygon.GetNP(); i++) - { - polygon.GetLine (i, lp1, lp2); - cp1 = p1 + lp1.X() * v12; - cp2 = p1 + lp2.X() * v12; - - faces.Append (new Cone (cp1, cp2, - fabs (lp1.Y()), - fabs (lp2.Y()))); - - invsurf.Append (lp1.X() < lp2.X()); - } -} - - -#endif -} diff --git a/Netgen/libsrc/csg/revolution.hpp b/Netgen/libsrc/csg/revolution.hpp deleted file mode 100644 index d57102d306..0000000000 --- a/Netgen/libsrc/csg/revolution.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef FILE_REVOLUTION -#define FILE_REVOLUTION - - -/**************************************************************************/ -/* File: revolution.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 12. Oct. 2000 */ -/**************************************************************************/ - -/* - - Primitive of revolution - -*/ - - -#ifdef NONE - -class Revolution : public Primitive -{ - Point<3> p1, p2; - Vec<3> v12; - Polygon2d polygon; - ARRAY<Cone*> faces; - ARRAY<int> invsurf; -public: - Revolution (const Point<3> & ap1, const Point<3> & ap2); - ~Revolution (); - static Primitive * CreateDefault (); - - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const; - - virtual int GetNSurfaces() const - { return faces.Size(); } - virtual Surface & GetSurface (int i) - { return *faces.Elem(i); } - virtual const Surface & GetSurface (int i = 1) const - { return *faces.Get(i); } - - virtual int SurfaceInverted (int i = 1) const - { return invsurf.Get(i); } - - virtual void GetPrimitiveData (char *& classname, ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - - virtual void Reduce (const BoxSphere<3> & box); - virtual void UnReduce (); - - int AddPoint (const Point<2> & p); - void Finish (); -protected: - // int FaceBoxIntersection (int fnr, const BoxSphere<3> & box) const; - // void CalcData(); -}; - - -#endif - -#endif diff --git a/Netgen/libsrc/csg/singularref.cpp b/Netgen/libsrc/csg/singularref.cpp deleted file mode 100644 index add7bfdf65..0000000000 --- a/Netgen/libsrc/csg/singularref.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ - -SingularEdge :: SingularEdge (double abeta, - const Solid * asol1, - const Solid * asol2) -{ - beta = abeta; - - if (beta > 1) - { - beta = 1; - cout << "Warning: beta set to 1" << endl; - } - if (beta <= 1e-3) - { - beta = 1e-3; - cout << "Warning: beta set to minimal value 0.001" << endl; - } - - sol1 = asol1; - sol2 = asol2; -} - -void SingularEdge :: FindPointsOnEdge (class Mesh & mesh) -{ - (*testout) << "find points on edge" << endl; - int j; - points.SetSize(0); - segms.SetSize(0); - for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) - { - INDEX_2 i2 (mesh[si].p1, mesh[si].p2); - - bool onedge = 1; - for (j = 1; j <= 2; j++) - { - const Point<3> p = mesh[ PointIndex (i2.I(j)) ]; - if (sol1->IsIn (p, 1e-3) && sol2->IsIn(p, 1e-3) && - !sol1->IsStrictIn (p, 1e-3) && !sol2->IsStrictIn(p, 1e-3)) - { - ; - } - else - onedge = 0; - } - if (onedge) - { - segms.Append (i2); - PrintMessage (5, "sing segment ", i2.I1(), " - ", i2.I2()); - points.Append (mesh[ PointIndex (i2.I1())]); - points.Append (mesh[ PointIndex (i2.I2())]); - mesh[si].singedge_left = 1; - mesh[si].singedge_right = 1; - } - } - - /* - (*testout) << "Singular points:" << endl; - for (int i = 0; i < points.Size(); i++) - (*testout) << points[i] << endl; - */ -} - -void SingularEdge :: SetMeshSize (class Mesh & mesh, double globalh) -{ - double hloc = pow (globalh, 1/beta); - for (int i = 0; i < points.Size(); i++) - mesh.RestrictLocalH (points[i], hloc); -} - - - -SingularPoint :: SingularPoint (double abeta, - const Solid * asol1, - const Solid * asol2, - const Solid * asol3) -{ - beta = abeta; - sol1 = asol1; - sol2 = asol2; - sol3 = asol3; -} - - -void SingularPoint :: FindPoints (class Mesh & mesh) -{ - points.SetSize(0); - for (PointIndex pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - const Point<3> p = mesh[pi]; - if (sol1->IsIn (p) && sol2->IsIn(p) && sol3->IsIn(p) && - !sol1->IsStrictIn (p) && !sol2->IsStrictIn(p) && !sol3->IsStrictIn(p)) - { - points.Append (p); - PrintMessage (5, "Point (", p(0), ", ", p(1), ", ", p(2), ") is singular"); - mesh[pi].SetSingular(); - } - } -} - - -void SingularPoint :: SetMeshSize (class Mesh & mesh, double globalh) -{ - double hloc = pow (globalh, 1/beta); - for (int i = 1; i <= points.Size(); i++) - mesh.RestrictLocalH (points.Get(i), hloc); -} -} diff --git a/Netgen/libsrc/csg/singularref.hpp b/Netgen/libsrc/csg/singularref.hpp deleted file mode 100644 index d52dcf8f8c..0000000000 --- a/Netgen/libsrc/csg/singularref.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef FILE_SINGULARREF -#define FILE_SINGULARREF - -/**************************************************************************/ -/* File: singularref.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 25. Sep. 99 */ -/**************************************************************************/ - -/** - Control for local refinement -*/ - - - -/** - Singular Face. - Causes a bounday layer mesh refinement. - All elements in subdomain domnr will get a boundary layer - on faces sharing the solid sol - */ -class SingularFace -{ -public: - int domnr; - const Solid *sol; - // ARRAY<Point<3> > points; - // ARRAY<INDEX_2> segms; -public: - SingularFace (int adomnr, const Solid * asol) - : domnr(adomnr), sol(asol) { ; } - const Solid * GetSolid() const { return sol; } - int GetDomainNr () const { return domnr; } -}; - - -/// -class SingularEdge -{ -public: - double beta; - const Solid *sol1, *sol2; - ARRAY<Point<3> > points; - ARRAY<INDEX_2> segms; -public: - SingularEdge (double abeta, const Solid * asol1, const Solid * asol2); - void FindPointsOnEdge (class Mesh & mesh); - void SetMeshSize (class Mesh & mesh, double globalh); -}; - - -/// -class SingularPoint -{ -public: - double beta; - const Solid *sol1, *sol2, *sol3; - ARRAY<Point<3> > points; - -public: - SingularPoint (double abeta, const Solid * asol1, const Solid * asol2, - const Solid * asol3); - void FindPoints (class Mesh & mesh); - void SetMeshSize (class Mesh & mesh, double globalh); -}; - - -#endif diff --git a/Netgen/libsrc/csg/solid.cpp b/Netgen/libsrc/csg/solid.cpp deleted file mode 100644 index 08d20f78a4..0000000000 --- a/Netgen/libsrc/csg/solid.cpp +++ /dev/null @@ -1,1217 +0,0 @@ -#include <mystdlib.h> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - using namespace netgen; - - - /* - SolidIterator :: SolidIterator () - { - ; - } - - SolidIterator :: ~SolidIterator () - { - ; - } - */ - - - - // int Solid :: cntnames = 0; - - Solid :: Solid (Primitive * aprim) - { - op = TERM; - prim = aprim; - s1 = s2 = NULL; - maxh = 1e10; - name = NULL; - } - - Solid :: Solid (optyp aop, Solid * as1, Solid * as2) - { - op = aop; - s1 = as1; - s2 = as2; - prim = NULL; - name = NULL; - maxh = 1e10; - } - - Solid :: ~Solid () - { - // cout << "delete solid, op = " << int(op) << endl; - delete [] name; - - switch (op) - { - case UNION: - case SECTION: - { - if (s1->op != ROOT) delete s1; - if (s2->op != ROOT) delete s2; - break; - } - case SUB: - // case ROOT: - { - if (s1->op != ROOT) delete s1; - break; - } - case TERM: - { - // cout << "has term" << endl; - delete prim; - break; - } - default: - break; - } - } - - void Solid :: SetName (const char * aname) - { - delete [] name; - name = new char[strlen (aname)+1]; - strcpy (name, aname); - } - - - Solid * Solid :: Copy (CSGeometry & geom) const - { - Solid * nsol; - switch (op) - { - case TERM: case TERM_REF: - { - Primitive * nprim = prim->Copy(); - geom.AddSurfaces (nprim); - nsol = new Solid (nprim); - break; - } - - case SECTION: - case UNION: - { - nsol = new Solid (op, s1->Copy(geom), s2->Copy(geom)); - break; - } - - case SUB: - { - nsol = new Solid (SUB, s1 -> Copy (geom)); - break; - } - - case ROOT: - { - nsol = s1->Copy(geom); - break; - } - } - - return nsol; - } - - - void Solid :: Transform (Transformation<3> & trans) - { - switch (op) - { - case TERM: case TERM_REF: - { - prim -> Transform (trans); - break; - } - case SECTION: - case UNION: - { - s1 -> Transform (trans); - s2 -> Transform (trans); - break; - } - - case SUB: - case ROOT: - { - s1 -> Transform (trans); - break; - } - } - } - - - - void Solid :: IterateSolid (SolidIterator & it, - bool only_once) - { - if (only_once) - { - if (visited) - return; - - visited = 1; - } - - it.Do (this); - - switch (op) - { - case SECTION: - { - s1->IterateSolid (it, only_once); - s2->IterateSolid (it, only_once); - break; - } - case UNION: - { - s1->IterateSolid (it, only_once); - s2->IterateSolid (it, only_once); - break; - } - case SUB: - case ROOT: - { - s1->IterateSolid (it, only_once); - break; - } - } - } - - - - - bool Solid :: IsIn (const Point<3> & p, double eps) const - { - switch (op) - { - case TERM: case TERM_REF: - { - INSOLID_TYPE ist = prim->PointInSolid (p, eps); - return ( (ist == IS_INSIDE) || (ist == DOES_INTERSECT) ) ? 1 : 0; - } - case SECTION: - return s1->IsIn (p, eps) && s2->IsIn (p, eps); - case UNION: - return s1->IsIn (p, eps) || s2->IsIn (p, eps); - case SUB: - return !s1->IsStrictIn (p, eps); - case ROOT: - return s1->IsIn (p, eps); - } - return 0; - } - - bool Solid :: IsStrictIn (const Point<3> & p, double eps) const - { - switch (op) - { - case TERM: case TERM_REF: - { - INSOLID_TYPE ist = prim->PointInSolid (p, eps); - return (ist == IS_INSIDE) ? 1 : 0; - } - case SECTION: - return s1->IsStrictIn(p, eps) && s2->IsStrictIn(p, eps); - case UNION: - return s1->IsStrictIn(p, eps) || s2->IsStrictIn(p, eps); - case SUB: - return !s1->IsIn (p, eps); - case ROOT: - return s1->IsStrictIn (p, eps); - } - return 0; - } - - bool Solid :: VectorIn (const Point<3> & p, const Vec<3> & v, - double eps) const - { - Vec<3> hv; - switch (op) - { - case TERM: case TERM_REF: - { - INSOLID_TYPE ist = prim->VecInSolid (p, v, eps); - return (ist == IS_INSIDE || ist == DOES_INTERSECT) ? 1 : 0; - } - case SECTION: - return s1 -> VectorIn (p, v, eps) && s2 -> VectorIn (p, v, eps); - case UNION: - return s1 -> VectorIn (p, v, eps) || s2 -> VectorIn (p, v, eps); - case SUB: - return !s1->VectorStrictIn(p, v, eps); - case ROOT: - return s1->VectorIn(p, v, eps); - } - return 0; - } - - bool Solid :: VectorStrictIn (const Point<3> & p, const Vec<3> & v, - double eps) const - { - Vec<3> hv; - switch (op) - { - case TERM: case TERM_REF: - { - INSOLID_TYPE ist = prim->VecInSolid (p, v, eps); - return (ist == IS_INSIDE) ? 1 : 0; - } - case SECTION: - return s1 -> VectorStrictIn (p, v, eps) && - s2 -> VectorStrictIn (p, v, eps); - case UNION: - return s1 -> VectorStrictIn (p, v, eps) || - s2 -> VectorStrictIn (p, v, eps); - case SUB: - return !s1->VectorIn(p, v, eps); - case ROOT: - return s1->VectorStrictIn(p, v, eps); - } - return 0; - } - - - bool Solid::VectorIn2 (const Point<3> & p, const Vec<3> & v1, - const Vec<3> & v2, double eps) const - { - if (VectorStrictIn (p, v1, eps)) - return 1; - if (!VectorIn (p, v1, eps)) - return 0; - - bool res = VectorIn2Rec (p, v1, v2, eps); - return res; - } - - bool Solid::VectorIn2Rec (const Point<3> & p, const Vec<3> & v1, - const Vec<3> & v2, double eps) const - { - switch (op) - { - case TERM: case TERM_REF: - return prim->VecInSolid2 (p, v1, v2, eps); - case SECTION: - return s1->VectorIn2Rec (p, v1, v2, eps) && - s2->VectorIn2Rec (p, v1, v2, eps); - case UNION: - return s1->VectorIn2Rec (p, v1, v2, eps) || - s2->VectorIn2Rec (p, v1, v2, eps); - case SUB: - return !s1->VectorIn2Rec (p, v1, v2, eps); - case ROOT: - return s1->VectorIn2Rec (p, v1, v2, eps); - } - return 0; - } - - - - - - - void Solid :: Print (ostream & str) const - { - switch (op) - { - case TERM: case TERM_REF: - { - str << prim->GetSurfaceId(0); - for (int i = 1; i < prim->GetNSurfaces(); i++) - str << "," << prim->GetSurfaceId(i); - break; - } - case SECTION: - { - str << "("; - s1 -> Print (str); - str << " AND "; - s2 -> Print (str); - str << ")"; - break; - } - case UNION: - { - str << "("; - s1 -> Print (str); - str << " OR "; - s2 -> Print (str); - str << ")"; - break; - } - case SUB: - { - str << " NOT "; - s1 -> Print (str); - break; - } - case ROOT: - { - str << " [" << name << "="; - s1 -> Print (str); - str << "] "; - break; - } - } - } - - - - void Solid :: GetSolidData (ostream & ost, int first) const - { - switch (op) - { - case SECTION: - { - ost << "("; - s1 -> GetSolidData (ost, 0); - ost << " AND "; - s2 -> GetSolidData (ost, 0); - ost << ")"; - break; - } - case UNION: - { - ost << "("; - s1 -> GetSolidData (ost, 0); - ost << " OR "; - s2 -> GetSolidData (ost, 0); - ost << ")"; - break; - } - case SUB: - { - ost << "NOT "; - s1 -> GetSolidData (ost, 0); - break; - } - case TERM: case TERM_REF: - { - if (name) - ost << name; - else - ost << "(noname)"; - break; - } - case ROOT: - { - if (first) - s1 -> GetSolidData (ost, 0); - else - ost << name; - break; - } - } - } - - - - static Solid * CreateSolidExpr (istream & ist, const SYMBOLTABLE<Solid*> & solids); - static Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE<Solid*> & solids); - static Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE<Solid*> & solids); - - static void ReadString (istream & ist, char * str) - { - char * hstr = str; - char ch; - - while (1) - { - ist.get(ch); - if (!ist.good()) break; - - if (!isspace (ch)) - { - ist.putback (ch); - break; - } - } - - while (1) - { - ist.get(ch); - if (!ist.good()) break; - if (isalpha(ch) || isdigit(ch)) - { - *str = ch; - str++; - } - else - { - ist.putback (ch); - break; - } - } - *str = 0; - // cout << "Read string (" << hstr << ")" - // << "put back: " << ch << endl; - } - - - Solid * CreateSolidExpr (istream & ist, const SYMBOLTABLE<Solid*> & solids) - { - // cout << "create expr" << endl; - - Solid *s1, *s2; - char str[100]; - - s1 = CreateSolidTerm (ist, solids); - ReadString (ist, str); - if (strcmp (str, "OR") == 0) - { - // cout << " OR "; - s2 = CreateSolidExpr (ist, solids); - return new Solid (Solid::UNION, s1, s2); - } - - // cout << "no OR found, put back string: " << str << endl; - int i; - for (i = strlen(str)-1; i >= 0; i--) - ist.putback (str[i]); - - return s1; - } - - Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE<Solid*> & solids) - { - // cout << "create term" << endl; - - Solid *s1, *s2; - char str[100]; - - s1 = CreateSolidPrim (ist, solids); - ReadString (ist, str); - if (strcmp (str, "AND") == 0) - { - // cout << " AND "; - s2 = CreateSolidTerm (ist, solids); - return new Solid (Solid::SECTION, s1, s2); - } - - - // cout << "no AND found, put back string: " << str << endl; - int i; - for (i = strlen(str)-1; i >= 0; i--) - ist.putback (str[i]); - - return s1; - } - - Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE<Solid*> & solids) - { - Solid * s1; - char ch; - char str[100]; - - ist >> ch; - if (ch == '(') - { - s1 = CreateSolidExpr (ist, solids); - ist >> ch; // ')' - // cout << "close back " << ch << endl; - return s1; - } - ist.putback (ch); - - ReadString (ist, str); - if (strcmp (str, "NOT") == 0) - { - // cout << " NOT "; - s1 = CreateSolidPrim (ist, solids); - return new Solid (Solid::SUB, s1); - } - - (*testout) << "get terminal " << str << endl; - s1 = solids.Get(str); - if (s1) - { - // cout << "primitive: " << str << endl; - return s1; - } - cerr << "syntax error" << endl; - - return NULL; - } - - - Solid * Solid :: CreateSolid (istream & ist, const SYMBOLTABLE<Solid*> & solids) - { - Solid * nsol = CreateSolidExpr (ist, solids); - nsol = new Solid (ROOT, nsol); - (*testout) << "Print new sol: "; - nsol -> Print (*testout); - (*testout) << endl; - return nsol; - } - - - - void Solid :: Boundaries (const Point<3> & p, ARRAY<int> & bounds) const - { - int in, strin; - bounds.SetSize (0); - RecBoundaries (p, bounds, in, strin); - } - - void Solid :: RecBoundaries (const Point<3> & p, ARRAY<int> & bounds, - int & in, int & strin) const - { - switch (op) - { - case TERM: case TERM_REF: - { - /* - double val; - val = surf->CalcFunctionValue (p); - in = (val < 1e-6); - strin = (val < -1e-6); - if (in && !strin) bounds.Append (id); - */ - if (prim->PointInSolid (p, 1e-6) == DOES_INTERSECT) - bounds.Append (prim->GetSurfaceId (1)); - break; - } - case SECTION: - { - int i, in1, in2, strin1, strin2; - ARRAY<int> bounds1, bounds2; - - s1 -> RecBoundaries (p, bounds1, in1, strin1); - s2 -> RecBoundaries (p, bounds2, in2, strin2); - - if (in1 && in2) - { - for (i = 1; i <= bounds1.Size(); i++) - bounds.Append (bounds1.Get(i)); - for (i = 1; i <= bounds2.Size(); i++) - bounds.Append (bounds2.Get(i)); - } - in = (in1 && in2); - strin = (strin1 && strin2); - break; - } - case UNION: - { - int i, in1, in2, strin1, strin2; - ARRAY<int> bounds1, bounds2; - - s1 -> RecBoundaries (p, bounds1, in1, strin1); - s2 -> RecBoundaries (p, bounds2, in2, strin2); - - if (!strin1 && !strin2) - { - for (i = 1; i <= bounds1.Size(); i++) - bounds.Append (bounds1.Get(i)); - for (i = 1; i <= bounds2.Size(); i++) - bounds.Append (bounds2.Get(i)); - } - in = (in1 || in2); - strin = (strin1 || strin2); - break; - } - case SUB: - { - int hin, hstrin; - s1 -> RecBoundaries (p, bounds, hin, hstrin); - in = !hstrin; - strin = !hin; - break; - } - - case ROOT: - { - s1 -> RecBoundaries (p, bounds, in, strin); - break; - } - } - } - - - - void Solid :: TangentialSolid (const Point<3> & p, Solid *& tansol) const - { - int in, strin; - RecTangentialSolid (p, tansol, in, strin); - } - - void Solid :: RecTangentialSolid (const Point<3> & p, Solid *& tansol, - int & in, int & strin) const - { - tansol = NULL; - - switch (op) - { - case TERM: case TERM_REF: - { - /* - double val; - val = surf->CalcFunctionValue (p); - in = (val < 1e-6); - strin = (val < -1e-6); - if (in && !strin) - tansol = new Solid (surf, id); - */ - - INSOLID_TYPE ist = prim->PointInSolid(p, 1e-6); - - in = (ist == IS_INSIDE || ist == DOES_INTERSECT); - strin = (ist == IS_INSIDE); - - if (ist == DOES_INTERSECT) - { - tansol = new Solid (prim); - tansol -> op = TERM_REF; - } - break; - } - case SECTION: - { - int in1, in2, strin1, strin2; - Solid * tansol1, * tansol2; - - s1 -> RecTangentialSolid (p, tansol1, in1, strin1); - s2 -> RecTangentialSolid (p, tansol2, in2, strin2); - - if (in1 && in2) - { - if (tansol1 && tansol2) - tansol = new Solid (SECTION, tansol1, tansol2); - else if (tansol1) - tansol = tansol1; - else if (tansol2) - tansol = tansol2; - } - in = (in1 && in2); - strin = (strin1 && strin2); - break; - } - case UNION: - { - int in1, in2, strin1, strin2; - Solid * tansol1, * tansol2; - - s1 -> RecTangentialSolid (p, tansol1, in1, strin1); - s2 -> RecTangentialSolid (p, tansol2, in2, strin2); - - if (!strin1 && !strin2) - { - if (tansol1 && tansol2) - tansol = new Solid (UNION, tansol1, tansol2); - else if (tansol1) - tansol = tansol1; - else if (tansol2) - tansol = tansol2; - } - in = (in1 || in2); - strin = (strin1 || strin2); - break; - } - case SUB: - { - int hin, hstrin; - Solid * tansol1; - - s1 -> RecTangentialSolid (p, tansol1, hin, hstrin); - - if (tansol1) - tansol = new Solid (SUB, tansol1); - in = !hstrin; - strin = !hin; - break; - } - case ROOT: - { - s1 -> RecTangentialSolid (p, tansol, in, strin); - break; - } - } - } - - - - - void Solid :: TangentialSolid2 (const Point<3> & p, - const Vec<3> & t, - Solid *& tansol) const - { - int in, strin; - RecTangentialSolid2 (p, t, tansol, in, strin); - } - - void Solid :: RecTangentialSolid2 (const Point<3> & p, const Vec<3> & t, - Solid *& tansol, - int & in, int & strin) const - { - tansol = NULL; - - switch (op) - { - case TERM: case TERM_REF: - { - /* - double val; - val = surf->CalcFunctionValue (p); - in = (val < 1e-6); - strin = (val < -1e-6); - if (in && !strin) - tansol = new Solid (surf, id); - */ - - INSOLID_TYPE ist = prim->PointInSolid(p, 1e-6); - if (ist == DOES_INTERSECT) - ist = prim->VecInSolid (p, t, 1e-6); - - in = (ist == IS_INSIDE || ist == DOES_INTERSECT); - strin = (ist == IS_INSIDE); - - if (ist == DOES_INTERSECT) - { - tansol = new Solid (prim); - tansol -> op = TERM_REF; - } - break; - } - case SECTION: - { - int in1, in2, strin1, strin2; - Solid * tansol1, * tansol2; - - s1 -> RecTangentialSolid2 (p, t, tansol1, in1, strin1); - s2 -> RecTangentialSolid2 (p, t, tansol2, in2, strin2); - - if (in1 && in2) - { - if (tansol1 && tansol2) - tansol = new Solid (SECTION, tansol1, tansol2); - else if (tansol1) - tansol = tansol1; - else if (tansol2) - tansol = tansol2; - } - in = (in1 && in2); - strin = (strin1 && strin2); - break; - } - case UNION: - { - int in1, in2, strin1, strin2; - Solid * tansol1, * tansol2; - - s1 -> RecTangentialSolid2 (p, t, tansol1, in1, strin1); - s2 -> RecTangentialSolid2 (p, t, tansol2, in2, strin2); - - if (!strin1 && !strin2) - { - if (tansol1 && tansol2) - tansol = new Solid (UNION, tansol1, tansol2); - else if (tansol1) - tansol = tansol1; - else if (tansol2) - tansol = tansol2; - } - in = (in1 || in2); - strin = (strin1 || strin2); - break; - } - case SUB: - { - int hin, hstrin; - Solid * tansol1; - - s1 -> RecTangentialSolid2 (p, t, tansol1, hin, hstrin); - - if (tansol1) - tansol = new Solid (SUB, tansol1); - in = !hstrin; - strin = !hin; - break; - } - case ROOT: - { - s1 -> RecTangentialSolid2 (p, t, tansol, in, strin); - break; - } - } - } - - - - - int Solid :: Edge (const Point<3> & p, const Vec<3> & v) const - { - int in, strin, faces; - RecEdge (p, v, in, strin, faces); - return faces >= 2; - } - - int Solid :: OnFace (const Point<3> & p, const Vec<3> & v) const - { - int in, strin, faces; - RecEdge (p, v, in, strin, faces); - return faces >= 1; - } - - - void Solid :: RecEdge (const Point<3> & p, const Vec<3> & v, - int & in, int & strin, int & faces) const - { - switch (op) - { - case TERM: case TERM_REF: - { - INSOLID_TYPE ist = prim->VecInSolid (p, v, 1e-6); - in = (ist == IS_INSIDE || ist == DOES_INTERSECT); - strin = (ist == IS_INSIDE); - /* - in = VectorIn (p, v); - strin = VectorStrictIn (p, v); - */ - faces = 0; - - if (in && ! strin) - { - // faces = 1; - int i; - Vec<3> grad; - for (i = 0; i < prim->GetNSurfaces(); i++) - { - double val = prim->GetSurface(i).CalcFunctionValue(p); - prim->GetSurface(i).CalcGradient (p, grad); - if (fabs (val) < 1e-6 && fabs (v * grad) < 1e-6) - faces++; - } - } - // else - // faces = 0; - break; - } - case SECTION: - { - int in1, in2, strin1, strin2, faces1, faces2; - - s1 -> RecEdge (p, v, in1, strin1, faces1); - s2 -> RecEdge (p, v, in2, strin2, faces2); - - faces = 0; - if (in1 && in2) - faces = faces1 + faces2; - in = in1 && in2; - strin = strin1 && strin2; - break; - } - case UNION: - { - int in1, in2, strin1, strin2, faces1, faces2; - - s1 -> RecEdge (p, v, in1, strin1, faces1); - s2 -> RecEdge (p, v, in2, strin2, faces2); - - faces = 0; - if (!strin1 && !strin2) - faces = faces1 + faces2; - in = in1 || in2; - strin = strin1 || strin2; - break; - } - case SUB: - { - int in1, strin1; - s1 -> RecEdge (p, v, in1, strin1, faces); - in = !strin1; - strin = !in1; - break; - } - case ROOT: - { - s1 -> RecEdge (p, v, in, strin, faces); - break; - } - } - } - - - void Solid :: CalcSurfaceInverse () - { - CalcSurfaceInverseRec (0); - } - - void Solid :: CalcSurfaceInverseRec (int inv) - { - switch (op) - { - case TERM: case TERM_REF: - { - int priminv; - for (int i = 0; i < prim->GetNSurfaces(); i++) - { - priminv = prim->SurfaceInverted(i); - if (inv) priminv = 1 - priminv; - prim->GetSurface(i).SetInverse (priminv); - } - break; - } - case UNION: - case SECTION: - { - s1 -> CalcSurfaceInverseRec (inv); - s2 -> CalcSurfaceInverseRec (inv); - break; - } - case SUB: - { - s1 -> CalcSurfaceInverseRec (1 - inv); - break; - } - case ROOT: - { - s1 -> CalcSurfaceInverseRec (inv); - break; - } - } - } - - - Solid * Solid :: GetReducedSolid (const BoxSphere<3> & box) const - { - INSOLID_TYPE in; - return RecGetReducedSolid (box, in); - } - - Solid * Solid :: RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const - { - Solid * redsol = NULL; - - switch (op) - { - case TERM: - case TERM_REF: - { - in = prim -> BoxInSolid (box); - if (in == DOES_INTERSECT) - { - redsol = new Solid (prim); - redsol -> op = TERM_REF; - } - break; - } - case SECTION: - { - INSOLID_TYPE in1, in2; - Solid * redsol1, * redsol2; - - redsol1 = s1 -> RecGetReducedSolid (box, in1); - redsol2 = s2 -> RecGetReducedSolid (box, in2); - - if (in1 == IS_OUTSIDE || in2 == IS_OUTSIDE) - { - if (in1 == DOES_INTERSECT) delete redsol1; - if (in2 == DOES_INTERSECT) delete redsol2; - in = IS_OUTSIDE; - } - else - { - if (in1 == DOES_INTERSECT || in2 == DOES_INTERSECT) - in = DOES_INTERSECT; - else - in = IS_INSIDE; - - if (in1 == DOES_INTERSECT && in2 == DOES_INTERSECT) - redsol = new Solid (SECTION, redsol1, redsol2); - else if (in1 == DOES_INTERSECT) - redsol = redsol1; - else if (in2 == DOES_INTERSECT) - redsol = redsol2; - } - break; - } - - case UNION: - { - INSOLID_TYPE in1, in2; - Solid * redsol1, * redsol2; - - redsol1 = s1 -> RecGetReducedSolid (box, in1); - redsol2 = s2 -> RecGetReducedSolid (box, in2); - - if (in1 == IS_INSIDE || in2 == IS_INSIDE) - { - if (in1 == DOES_INTERSECT) delete redsol1; - if (in2 == DOES_INTERSECT) delete redsol2; - in = IS_INSIDE; - } - else - { - if (in1 == DOES_INTERSECT || in2 == DOES_INTERSECT) in = DOES_INTERSECT; - else in = IS_OUTSIDE; - - if (in1 == DOES_INTERSECT && in2 == DOES_INTERSECT) - redsol = new Solid (UNION, redsol1, redsol2); - else if (in1 == DOES_INTERSECT) - redsol = redsol1; - else if (in2 == DOES_INTERSECT) - redsol = redsol2; - } - break; - } - - case SUB: - { - INSOLID_TYPE in1; - Solid * redsol1 = s1 -> RecGetReducedSolid (box, in1); - - switch (in1) - { - case IS_OUTSIDE: in = IS_INSIDE; break; - case IS_INSIDE: in = IS_OUTSIDE; break; - case DOES_INTERSECT: in = DOES_INTERSECT; break; - } - - if (redsol1) - redsol = new Solid (SUB, redsol1); - break; - } - - case ROOT: - { - INSOLID_TYPE in1; - redsol = s1 -> RecGetReducedSolid (box, in1); - in = in1; - break; - } - } - return redsol; - } - - - int Solid :: NumPrimitives () const - { - switch (op) - { - case TERM: case TERM_REF: - { - return 1; - } - case UNION: - case SECTION: - { - return s1->NumPrimitives () + s2 -> NumPrimitives(); - } - case SUB: - case ROOT: - { - return s1->NumPrimitives (); - } - } - return 0; - } - - void Solid :: GetSurfaceIndices (ARRAY<int> & surfind) const - { - surfind.SetSize (0); - RecGetSurfaceIndices (surfind); - } - - void Solid :: RecGetSurfaceIndices (ARRAY<int> & surfind) const - { - switch (op) - { - case TERM: case TERM_REF: - { - /* - int i; - for (i = 1; i <= surfind.Size(); i++) - if (surfind.Get(i) == prim->GetSurfaceId()) - return; - surfind.Append (prim->GetSurfaceId()); - break; - */ - for (int j = 0; j < prim->GetNSurfaces(); j++) - if (prim->SurfaceActive (j)) - { - bool found = 0; - int siprim = prim->GetSurfaceId(j); - - for (int i = 0; i < surfind.Size(); i++) - if (surfind[i] == siprim) - { - found = 1; - break; - } - if (!found) surfind.Append (siprim); - } - break; - } - case UNION: - case SECTION: - { - s1 -> RecGetSurfaceIndices (surfind); - s2 -> RecGetSurfaceIndices (surfind); - break; - } - case SUB: - case ROOT: - { - s1 -> RecGetSurfaceIndices (surfind); - break; - } - } - } - - - - void Solid :: GetSurfaceIndices (IndexSet & iset) const - { - iset.Clear(); - RecGetSurfaceIndices (iset); - } - - void Solid :: RecGetSurfaceIndices (IndexSet & iset) const - { - switch (op) - { - case TERM: case TERM_REF: - { - /* - int i; - for (i = 1; i <= surfind.Size(); i++) - if (surfind.Get(i) == prim->GetSurfaceId()) - return; - surfind.Append (prim->GetSurfaceId()); - break; - */ - for (int j = 0; j < prim->GetNSurfaces(); j++) - if (prim->SurfaceActive (j)) - { - int siprim = prim->GetSurfaceId(j); - iset.Add (siprim); - } - break; - } - case UNION: - case SECTION: - { - s1 -> RecGetSurfaceIndices (iset); - s2 -> RecGetSurfaceIndices (iset); - break; - } - case SUB: - case ROOT: - { - s1 -> RecGetSurfaceIndices (iset); - break; - } - } - } - - - - - - BlockAllocator Solid :: ball(sizeof (Solid)); -} diff --git a/Netgen/libsrc/csg/solid.hpp b/Netgen/libsrc/csg/solid.hpp deleted file mode 100644 index 796729125a..0000000000 --- a/Netgen/libsrc/csg/solid.hpp +++ /dev/null @@ -1,195 +0,0 @@ -#ifndef FILE_SOLID -#define FILE_SOLID - -/**************************************************************************/ -/* File: solid.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 1. Dez. 95 */ -/**************************************************************************/ - -/* - - Constructive Solid Model (csg) - -*/ - - - - -class Solid; - -class SolidIterator -{ -public: - SolidIterator () { ; } - virtual ~SolidIterator () { ; } - virtual void Do (Solid * sol) = 0; -}; - - - -class Solid -{ -public: - - typedef enum optyp1 { TERM, TERM_REF, SECTION, UNION, SUB, ROOT, DUMMY } optyp; - -private: - char * name; - Primitive * prim; - Solid * s1, * s2; - - optyp op; - bool visited; - double maxh; - - // static int cntnames; - -public: - Solid (Primitive * aprim); - Solid (optyp aop, Solid * as1, Solid * as2 = NULL); - ~Solid (); - - const char * Name () const { return name; } - void SetName (const char * aname); - - Solid * Copy (class CSGeometry & geom) const; - void Transform (Transformation<3> & trans); - - - void IterateSolid (SolidIterator & it, bool only_once = 0); - - - void Boundaries (const Point<3> & p, ARRAY<int> & bounds) const; - int NumPrimitives () const; - void GetSurfaceIndices (ARRAY<int> & surfind) const; - void GetSurfaceIndices (IndexSet & iset) const; - - Primitive * GetPrimitive () - { return (op == TERM || op == TERM_REF) ? prim : NULL; } - const Primitive * GetPrimitive () const - { return (op == TERM || op == TERM_REF) ? prim : NULL; } - - Solid * S1() { return s1; } - Solid * S2() { return s2; } - - // geometric tests - - bool IsIn (const Point<3> & p, double eps = 1e-6) const; - bool IsStrictIn (const Point<3> & p, double eps = 1e-6) const; - bool VectorIn (const Point<3> & p, const Vec<3> & v, double eps = 1e-6) const; - bool VectorStrictIn (const Point<3> & p, const Vec<3> & v, double eps = 1e-6) const; - - bool VectorIn2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, - double eps = 1e-6) const; - bool VectorIn2Rec (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, - double eps = 1e-6) const; - - - /// - void TangentialSolid (const Point<3> & p, Solid *& tansol) const; - /// - void TangentialSolid2 (const Point<3> & p, const Vec<3> & t, - Solid *& tansol) const; - /// - int Edge (const Point<3> & p, const Vec<3> & v) const; - /// - int OnFace (const Point<3> & p, const Vec<3> & v) const; - /// - void Print (ostream & str) const; - /// - void CalcSurfaceInverse (); - /// - Solid * GetReducedSolid (const BoxSphere<3> & box) const; - - - void SetMaxH (double amaxh) - { maxh = amaxh; } - double GetMaxH () const - { return maxh; } - - void GetSolidData (ostream & ost, int first = 1) const; - static Solid * CreateSolid (istream & ist, const SYMBOLTABLE<Solid*> & solids); - - - static BlockAllocator ball; - void * operator new(size_t /* s */) - { - return ball.Alloc(); - } - - void operator delete (void * p) - { - ball.Free (p); - } - - -protected: - /// - - void RecBoundaries (const Point<3> & p, ARRAY<int> & bounds, - int & in, int & strin) const; - /// - void RecTangentialSolid (const Point<3> & p, Solid *& tansol, - int & in, int & strin) const; - /// - void RecTangentialSolid2 (const Point<3> & p, const Vec<3> & vec, - Solid *& tansol, int & in, int & strin) const; - /// - void RecEdge (const Point<3> & p, const Vec<3> & v, - int & in, int & strin, int & faces) const; - /// - void CalcSurfaceInverseRec (int inv); - /// - Solid * RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const; - /// - void RecGetSurfaceIndices (ARRAY<int> & surfind) const; - void RecGetSurfaceIndices (IndexSet & iset) const; - - friend class SolidIterator; - friend class ClearVisitedIt; - friend class RemoveDummyIterator; - friend class CSGeometry; -}; - - -inline ostream & operator<< (ostream & ost, const Solid & sol) -{ - sol.Print (ost); - return ost; -} - - - - - - -class ReducePrimitiveIterator : public SolidIterator -{ - const BoxSphere<3> & box; -public: - ReducePrimitiveIterator (const BoxSphere<3> & abox) - : SolidIterator(), box(abox) { ; } - virtual ~ReducePrimitiveIterator () { ; } - virtual void Do (Solid * sol) - { - if (sol -> GetPrimitive()) - sol -> GetPrimitive() -> Reduce (box); - } -}; - - -class UnReducePrimitiveIterator : public SolidIterator -{ -public: - UnReducePrimitiveIterator () { ; } - virtual ~UnReducePrimitiveIterator () { ; } - virtual void Do (Solid * sol) - { - if (sol -> GetPrimitive()) - sol -> GetPrimitive() -> UnReduce (); - } -}; - - -#endif diff --git a/Netgen/libsrc/csg/specpoin.cpp b/Netgen/libsrc/csg/specpoin.cpp deleted file mode 100644 index c9b2477bb0..0000000000 --- a/Netgen/libsrc/csg/specpoin.cpp +++ /dev/null @@ -1,1231 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - - -/* - Special Point calculation uses the global Flags: - - relydegtest when to rely on degeneration ? - calccp calculate points of intersection ? - cpeps1 eps for degenerated poi - calcep calculate points of extreme coordinates ? - epeps1 eps for degenerated edge - epeps2 eps for axis parallel pec - epspointdist eps for distance of special points -*/ - - -namespace netgen -{ - void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp); - - - - SpecialPoint :: SpecialPoint (const SpecialPoint & sp) - { - p = sp.p; - v = sp.v; - s1 = sp.s1; - s2 = sp.s2; - layer = sp.layer; - unconditional = sp.unconditional; - } - - SpecialPoint & SpecialPoint :: operator= (const SpecialPoint & sp) - { - p = sp.p; - v = sp.v; - s1 = sp.s1; - s2 = sp.s2; - layer = sp.layer; - unconditional = sp.unconditional; - return *this; - } - - - void SpecialPoint :: Print (ostream & str) - { - str << "p = " << p << " v = " << v - << " s1/s2 = " << s1 << "/" << s2 - << " layer = " << layer - << endl; - } - - - static ARRAY<int> numprim_hist; - - SpecialPointCalculation :: SpecialPointCalculation () - { - ; - } - - void SpecialPointCalculation :: - CalcSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & apoints) - { - geometry = &ageometry; - points = &apoints; - - size = geometry->MaxSize(); - (*testout) << "Find Special Points" << endl; - (*testout) << "maxsize = " << size << endl; - - cpeps1 = 1e-6; - epeps1 = 1e-3; - epeps2 = 1e-6; - - epspointdist2 = sqr (size * 1e-8); - relydegtest = size * 1e-4; - - - BoxSphere<3> box (Point<3> (-size, -size, -size), - Point<3> ( size, size, size)); - - box.CalcDiamCenter(); - PrintMessage (3, "main-solids: ", geometry->GetNTopLevelObjects()); - - numprim_hist.SetSize (geometry->GetNSurf()+1); - numprim_hist = 0; - - for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - const TopLevelObject * tlo = geometry->GetTopLevelObject(i); - - (*testout) << "tlo " << i << ":" << endl - << *tlo->GetSolid() << endl; - - CalcSpecialPointsRec (tlo->GetSolid(), tlo->GetLayer(), - box, 1, 1, 1); - } - - // add user point: - for (int i = 0; i < geometry->GetNUserPoints(); i++) - AddPoint (geometry->GetUserPoint(i), 1); - - PrintMessage (3, "Found points ", apoints.Size()); - - for (int i = 0; i < boxesinlevel.Size(); i++) - (*testout) << "level " << i << " has " - << boxesinlevel[i] << " boxes" << endl; - (*testout) << "numprim_histogramm = " << endl << numprim_hist << endl; - } - - - - void SpecialPointCalculation :: - CalcSpecialPointsRec (const Solid * sol, int layer, - const BoxSphere<3> & box, - int level, bool calccp, bool calcep) - { - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - - if (!sol) return; - - if (level >= 100) - { - MyStr err = - MyStr("Problems in CalcSpecialPoints\nPoint: ") + MyStr (box.Center()); - throw NgException (err.c_str()); - } - - - bool decision; - bool possiblecrossp, possibleexp; // possible cross or extremalpoint - bool surecrossp, sureexp; // sure ... - - static ARRAY<int> locsurf; // attention: array is static - - static int cntbox = 0; - cntbox++; - - if (level <= boxesinlevel.Size()) - boxesinlevel.Elem(level)++; - else - boxesinlevel.Append (1); - - /* - numprim = sol -> NumPrimitives(); - sol -> GetSurfaceIndices (locsurf); - */ - - geometry -> GetIndependentSurfaceIndices (sol, box, locsurf); - int numprim = locsurf.Size(); - - numprim_hist[numprim]++; - - Point<3> p = box.Center(); - - - possiblecrossp = (numprim >= 3) && calccp; - surecrossp = 0; - - if (possiblecrossp && (locsurf.Size() <= 5 || level > 50)) - { - decision = 1; - surecrossp = 0; - - for (int k1 = 1; k1 <= locsurf.Size() - 2; k1++) - for (int k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) - for (int k3 = k2 + 1; k3 <= locsurf.Size(); k3++) - { - int nc, deg; - nc = CrossPointNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), p ); - - deg = CrossPointDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), box ); - - if (!nc && !deg) decision = 0; - if (nc) surecrossp = 1; - } - - if (decision && surecrossp) - { - for (int k1 = 1; k1 <= locsurf.Size() - 2; k1++) - for (int k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) - for (int k3 = k2 + 1; k3 <= locsurf.Size(); k3++) - { - if (CrossPointNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), p ) ) - { - Point<3> pp = p; - CrossPointNewton - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), pp); - - BoxSphere<3> hbox (pp, pp); - hbox.Increase (1e-8); - - if (pp(0) > box.PMin()(0) - 1e-5 && - pp(0) < box.PMax()(0) + 1e-5 && - pp(1) > box.PMin()(1) - 1e-5 && - pp(1) < box.PMax()(1) + 1e-5 && - pp(2) > box.PMin()(2) - 1e-5 && - pp(2) < box.PMax()(2) + 1e-5 && - sol -> IsIn (pp) && !sol->IsStrictIn (pp) && - !CrossPointDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), hbox )) - - { - // AddCrossPoint (locsurf, sol, p); - BoxSphere<3> boxp (pp, pp); - boxp.Increase (1e-3); - boxp.CalcDiamCenter(); - ARRAY<int> locsurf2; - - geometry -> GetIndependentSurfaceIndices (sol, boxp, locsurf2); - - bool found1 = 0, found2 = 0, found3 = 0; - for (int i = 0; i < locsurf2.Size(); i++) - { - if (locsurf2[i] == locsurf.Get(k1)) found1 = 1; - if (locsurf2[i] == locsurf.Get(k2)) found2 = 1; - if (locsurf2[i] == locsurf.Get(k3)) found3 = 1; - } - - if (found1 && found2 && found3) - if (AddPoint (pp, layer)) - { - (*testout) << "Crosspoint found: " << pp - << " diam = " << box.Diam() - << ", surfs: " - << locsurf.Get(k1) << "," - << locsurf.Get(k2) << "," - << locsurf.Get(k3) << endl; - } - } - } - } - } - - if (decision) - possiblecrossp = 0; - } - - - - - possibleexp = (numprim >= 2) && calcep; - - - if (numprim == 2) - { - const Surface * surf1 = geometry->GetSurface(locsurf[0]); - const Surface * surf2 = geometry->GetSurface(locsurf[1]); - - const Plane * plane1 = dynamic_cast<const Plane*> (surf1); - const Plane * plane2 = dynamic_cast<const Plane*> (surf2); - const QuadraticSurface * quadric1 = dynamic_cast<const QuadraticSurface*> (surf1); - const QuadraticSurface * quadric2 = dynamic_cast<const QuadraticSurface*> (surf2); - - if (plane1 && plane2) - possibleexp = 0; - else - { - ARRAY<Point<3> > pts; - if (plane1 && quadric2) - { - ComputeExtremalPoints (plane1, quadric2, pts); - possibleexp = 0; - } - else if (plane2 && quadric1) - { - ComputeExtremalPoints (plane2, quadric1, pts); - possibleexp = 0; - } - - for (int j = 0; j < pts.Size(); j++) - if (Dist (pts[j], box.Center()) < box.Diam()/2 && - sol -> IsIn (pts[j]) && !sol->IsStrictIn (pts[j]) ) - { - if (AddPoint (pts[j], layer)) - (*testout) << "Extremal point found: " << pts[j] << endl; - } - } - } - - - if (possibleexp && (locsurf.Size() <= 5 || level >= 50)) - { - decision = 1; - sureexp = 0; - - /* - (*testout) << "extremal surfs = "; - for (int k5 = 0; k5 < locsurf.Size(); k5++) - (*testout) << typeid(*geometry->GetSurface(locsurf[k5])).name() << " "; - (*testout) << "\n"; - */ - - for (int k1 = 0; k1 < locsurf.Size() - 1; k1++) - for (int k2 = k1+1; k2 < locsurf.Size(); k2++) - { - const Surface * surf1 = geometry->GetSurface(locsurf[k1]); - const Surface * surf2 = geometry->GetSurface(locsurf[k2]); - /* - (*testout) << "edgecheck, types = " << typeid(*surf1).name() << ", " << typeid(*surf2).name() - << "edge-newton-conv = " << EdgeNewtonConvergence (surf1, surf2, p) - << "edge-deg = " << EdgeDegenerated (surf1, surf2, box) - << "\n"; - */ - if (EdgeNewtonConvergence (surf1, surf2, p) ) - sureexp = 1; - else - { - if (!EdgeDegenerated (surf1, surf2, box)) - decision = 0; - } - } - - if (decision && sureexp) - { - for (int k1 = 0; k1 < locsurf.Size() - 1; k1++) - for (int k2 = k1+1; k2 < locsurf.Size(); k2++) - { - const Surface * surf1 = geometry->GetSurface(locsurf[k1]); - const Surface * surf2 = geometry->GetSurface(locsurf[k2]); - - if (EdgeNewtonConvergence (surf1, surf2, p)) - { - EdgeNewton (surf1, surf2, p); - - Point<3> pp; - if (IsEdgeExtremalPoint (surf1, surf2, p, pp, box.Diam()/2)) - { - (*testout) << "extremalpoint (nearly) found:" << pp << endl; - - if (Dist (pp, box.Center()) < box.Diam()/2 && - sol -> IsIn (pp) && !sol->IsStrictIn (pp) ) - { - if (AddPoint (pp, layer)) - (*testout) << "Extremal point found: " << pp << endl; - } - } - } - } - } - if (decision) - possibleexp = 0; - } - - - - if (possiblecrossp || possibleexp) - { - BoxSphere<3> sbox; - for (int i = 0; i < 8; i++) - { - box.GetSubBox (i, sbox); - sbox.Increase (1e-4 * sbox.Diam()); - - Solid * redsol = sol -> GetReducedSolid (sbox); - - if (redsol) - { - CalcSpecialPointsRec (redsol, layer, sbox, level+1, calccp, calcep); - delete redsol; - } - } - } - } - - - - - - /******* Tests for Point of intersection **********************/ - - - - bool SpecialPointCalculation :: - CrossPointNewtonConvergence (const Surface * f1, - const Surface * f2, - const Surface * f3, - const Point<3> & p) - { - Vec<3> grad, rs, x; - Mat<3> jacobi, inv; - - f1->CalcGradient (p, grad); - jacobi(0,0) = grad(0); - jacobi(0,1) = grad(1); - jacobi(0,2) = grad(2); - - f2->CalcGradient (p, grad); - jacobi(1,0) = grad(0); - jacobi(1,1) = grad(1); - jacobi(1,2) = grad(2); - - f3->CalcGradient (p, grad); - jacobi(2,0) = grad(0); - jacobi(2,1) = grad(1); - jacobi(2,2) = grad(2); - - if (fabs (Det (jacobi)) > 1e-8) - { - double gamma = f1 -> HesseNorm() + f2 -> HesseNorm() + f3 -> HesseNorm(); - if (gamma == 0.0) return 1; - - CalcInverse (jacobi, inv); - - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - rs(2) = f3->CalcFunctionValue (p); - - x = inv * rs; - - double beta = 0; - for (int i = 0; i < 3; i++) - { - double sum = 0; - for (int j = 0; j < 3; j++) - sum += fabs (inv(i,j)); - if (sum > beta) beta = sum; - } - double eta = Abs (x); - - return (beta * gamma * eta < 0.1); - } - return 0; - - } - - - - - bool SpecialPointCalculation :: - CrossPointDegenerated (const Surface * f1, - const Surface * f2, - const Surface * f3, - const BoxSphere<3> & box) const - { - Mat<3> mat; - Vec<3> g1, g2, g3; - double normprod; - - if (box.Diam() > relydegtest) return 0; - - f1->CalcGradient (box.Center(), g1); - normprod = Abs2 (g1); - - f2->CalcGradient (box.Center(), g2); - normprod *= Abs2 (g2); - - f3->CalcGradient (box.Center(), g3); - normprod *= Abs2 (g3); - - for (int i = 0; i < 3; i++) - { - mat(i,0) = g1(i); - mat(i,1) = g2(i); - mat(i,2) = g3(i); - } - - return sqr (Det (mat)) < sqr(cpeps1) * normprod; - } - - - - - - void SpecialPointCalculation :: CrossPointNewton (const Surface * f1, - const Surface * f2, - const Surface * f3, Point<3> & p) - { - Vec<3> g1, g2, g3; - Vec<3> rs, sol; - Mat<3> mat; - - int i = 10; - while (i > 0) - { - i--; - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - rs(2) = f3->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - f3->CalcGradient (p, g3); - - for (int j = 0; j < 3; j++) - { - mat(0, j) = g1(j); - mat(1, j) = g2(j); - mat(2, j) = g3(j); - } - mat.Solve (rs, sol); - if (sol.Length2() < 1e-24 && i > 1) i = 1; - - p -= sol; - } - } - - - - - /******* Tests for Point on edges **********************/ - - - - - bool SpecialPointCalculation :: - EdgeNewtonConvergence (const Surface * f1, const Surface * f2, - const Point<3> & p) - { - Vec<3> g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - Mat<3,2> inv; - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - if ( sqr(g1 * g2) < (1 - 1e-8) * Abs2 (g1) * Abs2 (g2)) - { - double gamma = f1 -> HesseNorm() + f2 -> HesseNorm(); - if (gamma < 1e-32) return 1; - gamma = sqr (gamma); - - for (int i = 0; i < 3; i++) - { - mat(0,i) = g1(i); - mat(1,i) = g2(i); - } - - CalcInverse (mat, inv); - - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - sol = inv * vrs; - - double beta = 0; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - beta += inv(i,j) * inv(i,j); - // beta = sqrt (beta); - - double eta = Abs2 (sol); - - // alpha = beta * gamma * eta; - return (beta * gamma * eta < 0.01); - } - return 0; - } - - - - - bool SpecialPointCalculation :: - EdgeDegenerated (const Surface * f1, - const Surface * f2, - const BoxSphere<3> & box) const - { - // perform newton steps. normals parallel ? - // if not decideable: return 0 - - Point<3> p = box.Center(); - Vec<3> g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - - int i = 20; - while (i > 0) - { - if (Dist2 (p, box.Center()) > sqr(box.Diam())) - return 0; - - i--; - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - if ( sqr (g1 * g2) > (1 - 1e-10) * Abs2 (g1) * Abs2 (g2)) - return 1; - - for (int j = 0; j < 3; j++) - { - mat(0,j) = g1(j); - mat(1,j) = g2(j); - } - mat.Solve (vrs, sol); - - if (Abs2 (sol) < 1e-24 && i > 1) i = 1; - p -= sol; - } - - return 0; - } - - - - - - - void SpecialPointCalculation :: EdgeNewton (const Surface * f1, - const Surface * f2, Point<3> & p) - { - Vec<3> g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - - int i = 10; - while (i > 0) - { - i--; - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - for (int j = 0; j < 3; j++) - { - mat(0,j) = g1(j); - mat(1,j) = g2(j); - } - mat.Solve (vrs, sol); - - if (Abs2 (sol) < 1e-24 && i > 1) i = 1; - p -= sol; - } - } - - - - bool SpecialPointCalculation :: - IsEdgeExtremalPoint (const Surface * f1, const Surface * f2, - const Point<3> & p, Point<3> & pp, double rad) - { - Vec<3> g1, g2, t, t1, t2; - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - t = Cross (g1, g2); - t.Normalize(); - - Point<3> p1 = p + rad * t; - Point<3> p2 = p - rad * t; - - EdgeNewton (f1, f2, p1); - EdgeNewton (f1, f2, p2); - - f1->CalcGradient (p1, g1); - f2->CalcGradient (p1, g2); - t1 = Cross (g1, g2); - t1.Normalize(); - - f1->CalcGradient (p2, g1); - f2->CalcGradient (p2, g2); - t2 = Cross (g1, g2); - t2.Normalize(); - - double val = 1e-8 * rad * rad; - for (int j = 0; j < 3; j++) - if ( (t1(j) * t2(j) < -val) ) - { - pp = p; - ExtremalPointNewton (f1, f2, j+1, pp); - return 1; - } - - return 0; - } - - - - - - - - - - /********** Tests of Points of extremal coordinates ****************/ - - - void SpecialPointCalculation :: ExtremalPointNewton (const Surface * f1, - const Surface * f2, - int dir, Point<3> & p) - { - Vec<3> g1, g2, v, curv; - Vec<3> rs, x, y1, y2, y; - Mat<3> h1, h2; - Mat<3> jacobi; - - int i = 50; - while (i > 0) - { - i--; - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - - f1 -> CalcHesse (p, h1); - f2 -> CalcHesse (p, h2); - - v = Cross (g1, g2); - - rs(2) = v(dir-1); - - jacobi(0,0) = g1(0); - jacobi(0,1) = g1(1); - jacobi(0,2) = g1(2); - - jacobi(1,0) = g2(0); - jacobi(1,1) = g2(1); - jacobi(1,2) = g2(2); - - - switch (dir) - { - case 1: - { - y1(0) = 0; - y1(1) = g2(2); - y1(2) = -g2(1); - y2(0) = 0; - y2(1) = -g1(2); - y2(2) = g1(1); - break; - } - case 2: - { - y1(0) = -g2(2); - y1(1) = 0; - y1(2) = g2(0); - y2(0) = g1(2); - y2(1) = 0; - y2(2) = -g1(0); - break; - } - case 3: - { - y1(0) = g2(1); - y1(1) = -g2(0); - y1(2) = 0; - y2(0) = -g1(1); - y2(1) = g1(0); - y2(2) = 0; - break; - } - } - - y = h1 * y1 + h2 * y2; - - jacobi(2,0) = y(0); - jacobi(2,1) = y(1); - jacobi(2,2) = y(2); - - jacobi.Solve (rs, x); - - if (Abs2 (x) < 1e-24 && i > 1) - { - i = 1; - } - - p -= x; - } - - - if (Abs2 (x) > 1e-20) - { - (*testout) << "Error: extremum Newton not convergent" << endl; - (*testout) << "dir = " << dir << endl; - (*testout) << "p = " << p << endl; - (*testout) << "x = " << x << endl; - } - } - - - - void SpecialPointCalculation :: - ComputeExtremalPoints (const Plane * plane, - const QuadraticSurface * quadric, - ARRAY<Point<3> > & pts) - { - // 3 equations: - // surf1 = 0 <===> plane_a + plane_b x = 0; - // surf2 = 0 <===> quad_a + quad_b x + x^T quad_c x = 0 - // (grad 1 x grad 2)(i) = 0 <====> (grad 1 x e_i) . grad_2 = 0 - - pts.SetSize (0); - - Point<3> p0(0,0,0); - double plane_a, quad_a; - Vec<3> plane_b, quad_b, ei; - Mat<3> quad_c; - - plane_a = plane -> CalcFunctionValue(p0); - plane -> CalcGradient (p0, plane_b); - - quad_a = quadric -> CalcFunctionValue(p0); - quadric -> CalcGradient (p0, quad_b); - quadric -> CalcHesse (p0, quad_c); - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - quad_c(i,j) *= 0.5; - - for (int dir = 0; dir <= 2; dir++) - { - ei = 0.0; ei(dir) = 1; - Vec<3> v1 = Cross (plane_b, ei); - - // grad_2 . v1 ... linear: - double g2v1_c = v1 * quad_b; - Vec<3> g2v1_l = 2.0 * (quad_c * v1); - - // find line of two linear equations: - - Vec<2> rhs; - Vec<3> sol; - Mat<2,3> mat; - - for (int j = 0; j < 3; j++) - { - mat(0,j) = plane_b(j); - mat(1,j) = g2v1_l(j); - } - rhs(0) = -plane_a; - rhs(1) = -g2v1_c; - - Vec<3> t = Cross (plane_b, g2v1_l); - if (Abs2(t) > 0) - { - mat.Solve (rhs, sol); - - // solve quadratic equation along line sol + alpha t .... - double a = quad_a + quad_b * sol + sol * (quad_c * sol); - double b = quad_b * t + 2 * (sol * (quad_c * t)); - double c = t * (quad_c * t); - - // solve a + b alpha + c alpha^2: - - if (fabs (c) > 1e-32) - { - double disc = sqr (0.5*b/c) - a/c; - if (disc > 0) - { - disc = sqrt (disc); - double alpha1 = -0.5*b/c + disc; - double alpha2 = -0.5*b/c - disc; - - pts.Append (Point<3> (sol+alpha1*t)); - pts.Append (Point<3> (sol+alpha2*t)); - /* - cout << "sol1 = " << sol + alpha1 * t - << ", sol2 = " << sol + alpha2 * t << endl; - */ - } - } - } - } - } - - - - - - - /* - bool SpecialPointCalculation :: ExtremalPointPossible (const Surface * f1, - const Surface * f2, - int dir, - const BoxSphere<3> & box) - { - double hn1, hn2, gn1, gn2; - Point<3> p; - Vec<3> g1, g2, v; - double f3; - double r = box.Diam()/2; - - p = box.Center(); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - - gn1 = g1.Length(); - gn2 = g2.Length(); - - hn1 = f1 -> HesseNorm (); - hn2 = f2 -> HesseNorm (); - - v = Cross (g1, g2); - f3 = fabs (v(dir-1)); - - // (*testout) << "f3 = " << f3 << " r = " << r - // << "normbound = " - // << (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1)) << endl; - - return (f3 <= 3 * r * (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1))); - } - - - - bool SpecialPointCalculation :: - ExtremalPointNewtonConvergence (const Surface * f1, const Surface * f2, - int dir, - const BoxSphere<3> & box) - { - return box.Diam() < 1e-8; - } - - - bool SpecialPointCalculation :: - ExtremalPointDegenerated (const Surface * f1, const Surface * f2, - int dir, const BoxSphere<3> & box) - { - double gn1, gn2; - Point<3> p; - Vec<3> g1, g2, v; - double maxderiv; - double minv; - Vec<3> curv, t; - Vec<2> rs, x; - Mat<3> h1, h2; - Mat<2> a, inv; - double leftside; - - if (box.Diam() > relydegtest) return 0; - - p = box.Center(); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - gn1 = g1.Length(); - gn2 = g2.Length(); - - v = Cross (g1, g2); - if (Abs (v) < epeps1 * gn1 * gn2) return 1; // irregular edge - - f1 -> CalcHesse (p, h1); - f2 -> CalcHesse (p, h2); - - // hn1 = f1 -> HesseNorm (); - // hn2 = f2 -> HesseNorm (); - - t = v; - a(0, 0) = g1 * g1; - a(0, 1) = - a(1, 0) = g1 * g2; - a(1, 1) = g2 * g2; - - rs(0) = g1(dir-1); - rs(1) = g2(dir-1); - - a.Solve (rs, x); - - // (*testout) << "g1 = " << g1 << " g2 = " << g2 << endl; - // (*testout) << "lam = " << x << endl; - // (*testout) << "h2 = " << h2 << endl; - - leftside = fabs (x(0) * ( t * (h1 * t)) + - x(1) * ( t * (h2 * t))); - - // (*testout) << "leftside = " << leftside << endl; - - if (leftside < epeps2 * Abs2 (v)) return 1; - - return 0; - } - */ - - - bool SpecialPointCalculation :: AddPoint (const Point<3> & p, int layer) - { - for (int i = 0; i < points->Size(); i++) - if (Dist2 ( (*points)[i], p) < epspointdist2 && - (*points)[i].GetLayer() == layer) - return 0; - - points->Append (MeshPoint(p, layer)); - PrintMessageCR (3, "Found points ", points->Size()); - return 1; - } - - - - - - - - void SpecialPointCalculation :: - AnalyzeSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & apoints, - ARRAY<SpecialPoint> & specpoints) - { - ARRAY<int> surfind; - ARRAY<int> surfind2; - - ARRAY<Vec<3> > normalvecs; - Vec<3> t, nsurf; - Point<3> p; - - ARRAY<int> specpoint2point; - specpoints.SetSize (0); - - geometry = &ageometry; - - (*testout) << "AnalyzeSpecialPoints\n"; - - - Box<3> bbox; - if (apoints.Size()) - bbox.Set (apoints[0]); - else - { bbox.Set (Point<3> (0,0,0)); bbox.Add (Point<3> (1,1,1)); } - for (int i = 1; i < apoints.Size(); i++) - bbox.Add (apoints[i]); - bbox.Increase (0.1 * Dist (bbox.PMin(), bbox.PMax())); - - Point3dTree searchtree (bbox.PMin(), bbox.PMax()); - ARRAY<int> locsearch; - - for (int si = 0; si < ageometry.GetNTopLevelObjects(); si++) - { - // (*testout) << "main solid " << si << "\n"; - - const Solid * sol = ageometry.GetTopLevelObject(si)->GetSolid(); - const Surface * surf = ageometry.GetTopLevelObject(si)->GetSurface(); - - for (int i = 0; i < apoints.Size(); i++) - { - p = apoints[i]; - if (ageometry.GetTopLevelObject(si)->GetLayer() != - apoints[i].GetLayer()) - continue; - - // (*testout) << "Point " << apoints[i] << "\n"; - - Solid * locsol; - sol -> TangentialSolid (p, locsol); - if (!locsol) continue; - - // get all surface indices, - if (surf) - { - locsol -> GetSurfaceIndices (surfind); - bool hassurf = 0; - for (int m = 0; m < surfind.Size(); m++) - if (ageometry.GetSurface(surfind[m]) == surf) - hassurf = 1; - - if (!hassurf) - continue; - - nsurf = surf->GetNormalVector (p); - } - - // get independent surfaces of tangential solid - - BoxSphere<3> box(p,p); - box.Increase (1e-6); - box.CalcDiamCenter(); - ageometry.GetIndependentSurfaceIndices (locsol, box, surfind); - - normalvecs.SetSize(surfind.Size()); - for (int j = 0; j < surfind.Size(); j++) - normalvecs[j] = - ageometry.GetSurface(surfind[j]) -> GetNormalVector(apoints[i]); - - for (int j = 0; j < normalvecs.Size(); j++) - for (int k = j+1; k < normalvecs.Size(); k++) - for (int l = 1; l <= 2; l++) - { - t = Cross (normalvecs[j], normalvecs[k]); - if (Abs2 (t) < 1e-8) - { - cerr << "AnalyzePoint: Surfaces degenerated" << "\n"; - break; - } - t.Normalize(); - if (l == 2) t *= -1; - - // try tangential direction t - - // (*testout) << "check tangential " << t << "\n"; - - if (surf && fabs (nsurf * t) > 1e-6) - continue; - - if (!surf) - { - ageometry.GetIndependentSurfaceIndices - (locsol, p, t, surfind2); - - bool found1 = 0, found2 = 0; - for (int ii = 0; ii < surfind2.Size(); ii++) - { - if (surfind2[ii] == surfind[j]) - found1 = 1; - if (surfind2[ii] == surfind[k]) - found2 = 1; - } - if (!found1 || !found2) - continue; - } - - - bool isedge; - - // isedge = locsol -> Edge (apoints.Get(i), t); - - // edge must be on tangential surface - isedge = - locsol->VectorIn (p, t) && - !locsol->VectorStrictIn (p, t); - - // (*testout) << "isedge,1 = " << isedge << "\n"; - - // there must exist at least two different faces on edge - if (isedge) - { - int cnts = 0; - for (int m = 0; m < surfind.Size(); m++) - { - if (fabs (normalvecs[m] * t) > 1e-6) - continue; - - Vec<3> s = Cross (normalvecs[m], t); - Vec<3> t2a = t + 0.01 *s; - Vec<3> t2b = t - 0.01 *s; - - /* - (*testout) << "nv = " << normalvecs[m] << ", s = " << s << "\n"; - (*testout) << "t2a = " << t2a << ", t2b = " << t2b << "\n"; - (*testout) << "via = " - << locsol->VectorIn (p, t2a) << "/" - << locsol->VectorStrictIn (p, t2a); - (*testout) << "vib = " - << locsol->VectorIn (p, t2b) << "/" - << locsol->VectorStrictIn (p, t2b) << "\n"; - */ - - bool isface = - (locsol->VectorIn (p, t2a) && - !locsol->VectorStrictIn (p, t2a)) - || - (locsol->VectorIn (p, t2b) && - !locsol->VectorStrictIn (p, t2b)); - - if (isface) - { - cnts++; - } - } - if (cnts < 2) isedge = 0; - } - - if (isedge) - { - int spi = -1; - - searchtree.GetIntersecting (apoints[i]-Vec3d(1e-4,1e-4,1e-4), - apoints[i]+Vec3d(1e-4,1e-4,1e-4), - locsearch); - - for (int m = 0; m < locsearch.Size(); m++) - if (Dist2 (specpoints[locsearch[m]].p, apoints[i]) < 1e-8 - && Abs2(specpoints[locsearch[m]].v - t) < 1e-8) - { - spi = locsearch[m]; - break; - } - - - if (spi == -1) - { - spi = specpoints.Append (SpecialPoint()) - 1; - specpoint2point.Append (i); - specpoints.Last().unconditional = 0; - searchtree.Insert (apoints[i], spi); - } - - specpoints[spi].p = apoints[i]; - specpoints[spi].v = t; - if (surfind.Size() >= 3) - specpoints[spi].unconditional = 1; - specpoints[spi].s1 = surfind[j]; - specpoints[spi].s2 = surfind[k]; - specpoints[spi].layer = apoints[i].GetLayer(); - for (int up = 0; up < geometry->GetNUserPoints(); up++) - if (Dist (geometry->GetUserPoint(up), apoints[i]) < 1e-10) - specpoints[spi].unconditional = 1; - } - - } - delete locsol; - } - } - - // if special point is unconditional on some solid, - // it must be unconditional everywhere: - - BitArray uncond (apoints.Size()); - uncond.Clear(); - - for (int i = 0; i < specpoints.Size(); i++) - if (specpoints[i].unconditional) - uncond.Set (specpoint2point[i]); - - for (int i = 0; i < specpoints.Size(); i++) - specpoints[i].unconditional = - uncond.Test (specpoint2point[i]) ? 1 : 0; - } -} diff --git a/Netgen/libsrc/csg/specpoin.hpp b/Netgen/libsrc/csg/specpoin.hpp deleted file mode 100644 index 8fd26f3207..0000000000 --- a/Netgen/libsrc/csg/specpoin.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef FILE_SPECPOIN -#define FILE_SPECPOIN - - -/**************************************************************************/ -/* File: specpoin.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - -/* - -Special Point Calculation - -*/ - -class Surface; -class Solid; - -/// Special point. -class SpecialPoint -{ -public: - /// coordinates - Point<3> p; - /// tangential to edge - Vec<3> v; - /// - int layer; - /// point must be used in mesh - bool unconditional; - - /// surfaces defining edge - int s1, s2; - - /// - SpecialPoint () : p(0,0,0), v(0,0,0), layer(0), unconditional(0), s1(0), s2(0) - { ; } - - /// - SpecialPoint (const SpecialPoint & sp2); - - /// - SpecialPoint & operator= (const SpecialPoint & sp2); - - /// - void Print (ostream & str); - - - int GetLayer() const { return layer; } - - /// - bool HasSurfaces (int as1, int as2) const - { - return (s1 == as1 && s2 == as2 || s1 == as2 && s2 == as1); - } -}; - - - -/// -class SpecialPointCalculation -{ -private: - /// - const CSGeometry * geometry; - /// - ARRAY<MeshPoint> * points; - /// - ARRAY<long int> boxesinlevel; - - /// - double size; - /// - double relydegtest; // maximal dimension of bisection intervall for - /// test of degeneration parameters - double cpeps1, epeps1, epeps2, epspointdist2; - -public: - - /// - SpecialPointCalculation (); - - /// - void CalcSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & points); - /// - void AnalyzeSpecialPoints (const CSGeometry & geometry, - ARRAY<MeshPoint> & points, - ARRAY<SpecialPoint> & specpoints); - -protected: - /// - void CalcSpecialPointsRec (const Solid * sol, int layer, - const BoxSphere<3> & box, - int level, - bool calccp, bool calcep); - - - /// - bool CrossPointNewtonConvergence (const Surface * f1, const Surface * f2, - const Surface * f3, const Point<3> & p); - /// - bool CrossPointDegenerated (const Surface * f1, const Surface * f2, - const Surface * f3, const BoxSphere<3> & box) const; - /// - void CrossPointNewton (const Surface * f1, const Surface * f2, - const Surface * f3, Point<3> & p); - - bool EdgeNewtonConvergence (const Surface * f1, const Surface * f2, - const Point<3> & p); - /// - bool EdgeDegenerated (const Surface * f1, const Surface * f2, - const BoxSphere<3> & box) const; - /// - void EdgeNewton (const Surface * f1, const Surface * f2, - Point<3> & p); - /// - bool IsEdgeExtremalPoint (const Surface * f1, const Surface * f2, - const Point<3> & p, Point<3> & pp, double rad); - - - - /* - /// - bool ExtremalPointPossible (const Surface * f1, const Surface * f2, - int dir, const BoxSphere<3> & box); - /// - bool ExtremalPointDegenerated (const Surface * f1, const Surface * f2, - int dir, const BoxSphere<3> & box); - /// - bool ExtremalPointNewtonConvergence (const Surface * f1, const Surface * f2, - int dir, const BoxSphere<3> & box); - */ - /// - void ExtremalPointNewton (const Surface * f1, const Surface * f2, - int dir, Point<3> & p); - - - /// - bool AddPoint (const Point<3> & p, int layer); - - void ComputeExtremalPoints (const Plane * plane, - const QuadraticSurface * quadric, - ARRAY<Point<3> > & pts); -}; - -#endif - - diff --git a/Netgen/libsrc/csg/specpoin_new.cpp b/Netgen/libsrc/csg/specpoin_new.cpp deleted file mode 100644 index 4ac2c130fa..0000000000 --- a/Netgen/libsrc/csg/specpoin_new.cpp +++ /dev/null @@ -1,1367 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - - -/* - Special Point calculation uses the global Flags: - - size .. 500 cube = [-size, size]^3 - relydegtest when to rely on degeneration ? - calccp calculate points of intersection ? - cpeps1 eps for degenerated poi - calcep calculate points of extreme coordinates ? - epeps1 eps for degenerated edge - epeps2 eps for axis parallel pec - epspointdist eps for distance of special points -*/ - - -namespace netgen -{ -void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp); - - - -SpecialPoint :: SpecialPoint (const SpecialPoint & sp) -{ - p = sp.p; - v = sp.v; - s1 = sp.s1; - s2 = sp.s2; - layer = sp.layer; - unconditional = sp.unconditional; -} - -SpecialPoint & SpecialPoint :: operator= (const SpecialPoint & sp) -{ - p = sp.p; - v = sp.v; - s1 = sp.s1; - s2 = sp.s2; - layer = sp.layer; - unconditional = sp.unconditional; - return *this; -} - - -void SpecialPoint :: Print (ostream & str) -{ - str << "p = " << p << " v = " << v - << " s1/s2 = " << s1 << "/" << s2 - << " layer = " << layer - << endl; -} - - - - -SpecialPointCalculation :: SpecialPointCalculation () -{ - ; -} - -void SpecialPointCalculation :: -CalcSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & apoints) -{ - int i; - - geometry = &ageometry; - points = &apoints; - - size = geometry->MaxSize(); - (*testout) << "Find Special Points" << endl; - (*testout) << "maxsize = " << size << endl; - - cpeps1 = 1e-6; - epeps1 = 1e-3; - epeps2 = 1e-6; - - epspointdist2 = sqr (size * 1e-8); - relydegtest = size * 1e-4; - - - BoxSphere<3> box (Point<3> (-size, -size, -size), - Point<3> ( size, size, size)); - - box.CalcDiamCenter(); - PrintMessage (3, "main-solids: ", geometry->GetNTopLevelObjects()); - - for (i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - (*testout) << "tlo " << i << ":" << endl; - const TopLevelObject * tlo = geometry->GetTopLevelObject(i); - tlo->GetSolid()->Print (*testout); - (*testout) << endl; - CalcSpecialPointsRec (tlo->GetSolid(), tlo->GetLayer(), - box, 1, 1, 1); - } - - PrintDot ('\n'); - - - // add user point: - for (i = 0; i < geometry->GetNUserPoints(); i++) - AddPoint (geometry->GetUserPoint(i), 1); - - PrintMessage (3, apoints.Size(), " special points"); - - for (i = 0; i < boxesinlevel.Size(); i++) - (*testout) << "level " << i << " has " - << boxesinlevel[i] << " boxes" << endl; -} - - - -// int debug; -void SpecialPointCalculation :: -CalcSpecialPointsRec (const Solid * sol, int layer, - const BoxSphere<3> & box, - int level, bool calccp, bool calcep) -{ - if (multithread.terminate) - return; - - int i; - BoxSphere<3> sbox; - Solid * redsol; - - int numprim; - - bool decision; - bool possiblecrossp, possibleexp; // possible cross or extremalpoint - bool surecrossp, sureexp; // sure ... - - static ARRAY<int> locsurf; // attention: array is static - - - Point<3> p; - int k1, k2, k3; - int extremdir; - double hd; - - if (!sol) return; - - if (level >= 100) - { - cerr << "Problems in CalcSpecialPoints" << endl; - cerr << "Point: " << box.Center() << endl; - exit (1); - } - - static int cntbox = 0; - cntbox++; - if (cntbox % 10000 == 0) - PrintDot (); - - if (level <= boxesinlevel.Size()) - boxesinlevel.Elem(level)++; - else - boxesinlevel.Append (1); - - /* - numprim = sol -> NumPrimitives(); - sol -> GetSurfaceIndices (locsurf); - */ - - // debug = 0; - // box.IsIn (Point<3> (4.9, 1.279, 2.8)); - - - geometry -> GetIndependentSurfaceIndices (sol, box, locsurf); - numprim = locsurf.Size(); - - /* - if (debug) - { - (*testout) << "box = " << box.PMin() << "-" << box.PMax() - << " np = " << numprim << " : "; - for (i = 1; i <= locsurf.Size(); i++) - (*testout) << " " << locsurf.Get(i); - (*testout) << " diam = " << box.Diam(); - (*testout) << " numprim = " << numprim; - (*testout) << endl; - } - */ - - - p = box.Center(); - - /* - (*testout) << "box = " << box.PMin() << " - " << box.PMax() - << ", lev = " << level - << ", nprim = " << sol->NumPrimitives() - << ", lsurf = " << locsurf.Size() << endl; - - for (i = 1; i <= locsurf.Size(); i++) - geometry->GetSurface (locsurf.Get(i)) -> Print (*testout); - sol -> Print (*testout); - */ - - /* - for (i = 1; i <= locsurf.Size(); i++) - (*testout) << locsurf.Get(i) << " "; - (*testout) << "C = " << box.Center() << " diam = " << box.Diam() << endl; - */ - - possiblecrossp = (numprim >= 3) && calccp; - surecrossp = 0; - - if (possiblecrossp && (locsurf.Size() <= 10)) - { - decision = 1; - surecrossp = 0; - - for (k1 = 1; k1 <= locsurf.Size() - 2; k1++) - for (k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) - for (k3 = k2 + 1; k3 <= locsurf.Size(); k3++) - { - int nc, deg; - nc = CrossPointNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), p ); - - deg = CrossPointDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), box ); - - if (!nc && !deg) decision = 0; - if (nc) surecrossp = 1; - } - - if (decision && surecrossp) - { - for (k1 = 1; k1 <= locsurf.Size() - 2; k1++) - for (k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) - for (k3 = k2 + 1; k3 <= locsurf.Size(); k3++) - { - if (CrossPointNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), p ) ) - { - Point<3> pp = p; - CrossPointNewton - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), pp); - - BoxSphere<3> hbox (pp, pp); - hbox.Increase (1e-8); - - if (pp(0) > box.PMin()(0) - 1e-5 && - pp(0) < box.PMax()(0) + 1e-5 && - pp(1) > box.PMin()(1) - 1e-5 && - pp(1) < box.PMax()(1) + 1e-5 && - pp(2) > box.PMin()(2) - 1e-5 && - pp(2) < box.PMax()(2) + 1e-5 && - sol -> IsIn (pp) && !sol->IsStrictIn (pp) && - !CrossPointDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), hbox )) - - { - // AddCrossPoint (locsurf, sol, p); - BoxSphere<3> boxp (pp, pp); - boxp.Increase (1e-3); - boxp.CalcDiamCenter(); - ARRAY<int> locsurf2; - - geometry -> GetIndependentSurfaceIndices (sol, boxp, locsurf2); - - /* - ReducePrimitiveIterator rpi(boxp); - UnReducePrimitiveIterator urpi; - - ((Solid*)sol) -> IterateSolid (rpi); - sol -> GetIndependentSurfaceIndices (locsurf2); - ((Solid*)sol) -> IterateSolid (urpi); - */ - bool found1 = 0, found2 = 0, found3 = 0; - for (i = 1; i <= locsurf2.Size(); i++) - { - if (locsurf2.Get(i) == locsurf.Get(k1)) - found1 = 1; - if (locsurf2.Get(i) == locsurf.Get(k2)) - found2 = 1; - if (locsurf2.Get(i) == locsurf.Get(k3)) - found3 = 1; - } - - if (found1 && found2 && found3) - if (AddPoint (pp, layer)) - { - (*testout) << "Crosspoint found: " << pp - << " diam = " << box.Diam() << endl; - (*testout) << "surfs: " - << locsurf.Get(k1) << "," - << locsurf.Get(k2) << "," - << locsurf.Get(k3) << endl; - } - } - } - } - } - - if (decision) - possiblecrossp = 0; - } - - - - - possibleexp = (numprim >= 2) && calcep; - - if (possibleexp && (locsurf.Size() <= 10)) - { - decision = 1; - sureexp = 0; - - for (k1 = 1; k1 <= locsurf.Size() - 1; k1++) - for (k2 = k1+1; k2 <= locsurf.Size(); k2++) - { - bool nc, deg; - - nc = EdgeNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p); - - deg = EdgeDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - box); - - if (!nc && !deg) decision = 0; - if (nc) sureexp = 1; - - /* - if (debug) - { - (*testout) << "p = " << p << " s1,2 = " << locsurf.Get(k1) << ", " << locsurf.Get(k2) - << " nc = " << nc << " deg = " << deg << endl; - } - */ - } - - if (decision && sureexp) - { - for (k1 = 1; k1 <= locsurf.Size() - 1; k1++) - for (k2 = k1+1; k2 <= locsurf.Size(); k2++) - { - if ( - EdgeNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p) ) - { - EdgeNewton - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p); - - Point<3> pp; - if (IsEdgeExtremalPoint - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p, pp, box.Diam()/2)) - { - (*testout) << "extremalpoint (nearly) found:" - << pp - << endl; - if (Dist (pp, box.Center()) < box.Diam()/2 && - sol -> IsIn (pp) && !sol->IsStrictIn (pp) ) - { - // AddExtremalPoint (locsurf.Get(k1), locsurf.Get(k2), p); - if (AddPoint (pp, layer)) - (*testout) << "Extremal point found: " << pp << endl; - } - } - } - } - } - if (decision) - possibleexp = 0; - } - - - - if (possiblecrossp || possibleexp) - { - for (i = 0; i < 8; i++) - { - box.GetSubBox (i, sbox); - sbox.Increase (1e-4 * sbox.Diam()); - - redsol = sol -> GetReducedSolid (sbox); - - if (redsol) - { - CalcSpecialPointsRec (redsol, layer, sbox, level+1, calccp, calcep); - delete redsol; - } - } - } -} - - - - - -/******* Tests for Point of intersection **********************/ - - - -bool SpecialPointCalculation :: -CrossPointNewtonConvergence (const Surface * f1, - const Surface * f2, - const Surface * f3, - const Point<3> & p) -{ - int i; - Vec<3> grad; - Vec<3> rs, x; - Mat<3> jacobi, inv; - double alpha, beta, gamma, eta; - double sum; - int j; - - - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - rs(2) = f3->CalcFunctionValue (p); - - f1->CalcGradient (p, grad); - jacobi(0,0) = grad(0); - jacobi(0,1) = grad(1); - jacobi(0,2) = grad(2); - - f2->CalcGradient (p, grad); - jacobi(1,0) = grad(0); - jacobi(1,1) = grad(1); - jacobi(1,2) = grad(2); - - f3->CalcGradient (p, grad); - jacobi(2,0) = grad(0); - jacobi(2,1) = grad(1); - jacobi(2,2) = grad(2); - - alpha = 1; - if (fabs (Det (jacobi)) > 1e-8) - { - CalcInverse (jacobi, inv); - x = inv * rs; - - gamma = f1 -> HesseNorm() + f2 -> HesseNorm() + f3 -> HesseNorm(); - beta = 0; - for (i = 0; i < 3; i++) - { - sum = 0; - for (j = 0; j < 3; j++) - sum += fabs (inv(i,j)); - beta = max2 (beta, sum); - } - eta = Abs (x); - - alpha = beta * gamma * eta; - } - - return (alpha < 0.1); -} - - - - -bool SpecialPointCalculation :: -CrossPointDegenerated (const Surface * f1, - const Surface * f2, - const Surface * f3, - const BoxSphere<3> & box) const -{ - Mat<3> mat; - Vec<3> grad, g1, g2, g3; - double normprod; - - if (box.Diam() > relydegtest) return 0; - - f1->CalcGradient (box.Center(), g1); - normprod = Abs (g1); - - f2->CalcGradient (box.Center(), g2); - normprod *= Abs (g2); - - f3->CalcGradient (box.Center(), g3); - normprod *= Abs (g3); - - for (int i = 0; i < 3; i++) - { - mat(i,0) = g1(i); - mat(i,1) = g2(i); - mat(i,2) = g3(i); - } - - if (fabs (Det (mat)) < cpeps1 * normprod) - return 1; - else - return 0; -} - - - - - -void SpecialPointCalculation :: CrossPointNewton (const Surface * f1, - const Surface * f2, - const Surface * f3, Point<3> & p) -{ - int i; - Vec<3> g1, g2, g3; - Vec<3> rs, sol; - Mat<3> mat; - - i = 10; - while (i > 0) - { - i--; - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - rs(2) = f3->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - f3->CalcGradient (p, g3); - - for (int j = 0; j < 3; j++) - { - mat(0, j) = g1(j); - mat(1, j) = g2(j); - mat(2, j) = g3(j); - } - mat.Solve (rs, sol); - /* - Transpose (g1, g2, g3); - SolveLinearSystem (g1, g2, g3, rs, sol); - */ - if (sol.Length() < 1e-12 && i > 1) i = 1; - - p -= sol; - } -} - - - - -/******* Tests for Point on edges **********************/ - - - - -bool SpecialPointCalculation :: -EdgeNewtonConvergence (const Surface * f1, const Surface * f2, - const Point<3> & p) -{ - int i; - Vec<3> g1, g2, sol; - Vec<2> vrs; - double alpha, beta, gamma, eta; - double sum; - Mat<2,3> mat; - Mat<3,2> inv; - int j; - - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - for (i = 0; i < 3; i++) - { - mat(0,i) = g1(i); - mat(1,i) = g2(i); - } - - alpha = 1; - - if ( fabs(g1 * g2) < (1 - 1e-8) * Abs (g1) * Abs (g2)) - { - CalcInverse (mat, inv); - sol = inv * vrs; - - // SolveLinearSystemLS (g1, g2, vrs, sol); - - gamma = f1 -> HesseNorm() + f2 -> HesseNorm(); - - /* - Vec<3> inv1, inv2; - PseudoInverse (g1, g2, inv1, inv2); - */ - - beta = 0; - for (i = 0; i < 3; i++) - for (j = 0; j < 2; j++) - beta += inv(i,j) * inv(i,j); - beta = sqrt (beta); - - // beta = inv1.Length() + inv2.Length(); - eta = Abs (sol); - alpha = beta * gamma * eta; - } - return (alpha < 0.1); -} - - - - -bool SpecialPointCalculation :: -EdgeDegenerated (const Surface * f1, - const Surface * f2, - const BoxSphere<3> & box) const -{ - // perform newton steps. normals parallel ? - // if not decideable: return 0 - - - Point<3> p = box.Center(); - int i; - Vec<3> grad, g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - - i = 20; - while (i > 0) - { - if (Dist (p, box.Center()) > box.Diam()) - return 0; - - i--; - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - if ( fabs (g1 * g2) > (1 - 1e-10) * Abs (g1) * Abs (g2)) - return 1; - - for (int j = 0; j < 3; j++) - { - mat(0,j) = g1(j); - mat(1,j) = g2(j); - } - mat.Solve (vrs, sol); - // SolveLinearSystemLS (g1, g2, vrs, sol); - - if (Abs (sol) < 1e-12 && i > 1) i = 1; - p -= sol; - } - - return 0; -} - - - - - - -void SpecialPointCalculation :: EdgeNewton (const Surface * f1, - const Surface * f2, Point<3> & p) -{ - int i; - Vec<3> grad, g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - - i = 10; - while (i > 0) - { - i--; - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - for (int j = 0; j < 3; j++) - { - mat(0,j) = g1(j); - mat(1,j) = g2(j); - } - mat.Solve (vrs, sol); - // SolveLinearSystemLS (g1, g2, vrs, sol); - - if (Abs (sol) < 1e-12 && i > 1) i = 1; - p -= sol; - } -} - - - -bool SpecialPointCalculation :: -IsEdgeExtremalPoint (const Surface * f1, const Surface * f2, - const Point<3> & p, Point<3> & pp, double rad) -{ - Vec<3> g1, g2, t, t1, t2; - int j; - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - t = Cross (g1, g2); - t.Normalize(); - - Point<3> p1 = p + rad * t; - Point<3> p2 = p - rad * t; - - EdgeNewton (f1, f2, p1); - EdgeNewton (f1, f2, p2); - - - f1->CalcGradient (p1, g1); - f2->CalcGradient (p1, g2); - t1 = Cross (g1, g2); - t1.Normalize(); - - f1->CalcGradient (p2, g1); - f2->CalcGradient (p2, g2); - t2 = Cross (g1, g2); - t2.Normalize(); - - double val = 1e-8 * rad * rad; - for (j = 0; j < 3; j++) - if ( (t1(j) * t2(j) < -val) ) - { - pp = p; - ExtremalPointNewton (f1, f2, j+1, pp); - return 1; - } - - return 0; -} - - - - - - - - - -/********** Tests of Points of extremal coordinates ****************/ - - -void SpecialPointCalculation :: ExtremalPointNewton (const Surface * f1, - const Surface * f2, - int dir, Point<3> & p) -{ - int i; - - Vec<3> g1, g2, v, curv; - Vec<3> rs, x, y1, y2, y; - Mat<3> h1, h2; - Mat<3> jacobi; - - - if (dir < 1 || dir > 3) - { - cerr << "Error: Illegal extremdir" << endl; - return; - } - - i = 50; - while (i > 0) - { - i--; - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - - f1 -> CalcHesse (p, h1); - f2 -> CalcHesse (p, h2); - - - v = Cross (g1, g2); - - rs(2) = v(dir-1); - - jacobi(0,0) = g1(0); - jacobi(0,1) = g1(1); - jacobi(0,2) = g1(2); - - jacobi(1,0) = g2(0); - jacobi(1,1) = g2(1); - jacobi(1,2) = g2(2); - - - switch (dir) - { - case 1: - { - y1(0) = 0; - y1(1) = g2(2); - y1(2) = -g2(1); - y2(0) = 0; - y2(1) = -g1(2); - y2(2) = g1(1); - break; - } - case 2: - { - y1(0) = -g2(2); - y1(1) = 0; - y1(2) = g2(0); - y2(0) = g1(2); - y2(1) = 0; - y2(2) = -g1(0); - break; - } - case 3: - { - y1(0) = g2(1); - y1(1) = -g2(0); - y1(2) = 0; - y2(0) = -g1(1); - y2(1) = g1(0); - y2(2) = 0; - break; - } - } - - y = h1 * y1 + h2 * y2; - - jacobi(2,0) = y(0); - jacobi(2,1) = y(1); - jacobi(2,2) = y(2); - - jacobi.Solve (rs, x); - /* - CalcInverse (jacobi, inv); - inv.Mult (rs, x); - */ - // (*testout) << "err = " << x.L2Norm() << endl; - - if (Abs (x) < 1e-12 && i > 1) - { - // (*testout) << "convergent in " << (10 - i) << " steps " << endl; - - i = 1; - } - - p -= x; - } - - if (Abs (x) > 1e-10) - { - (*testout) << "Error: extremum Newton not convergent" << endl; - (*testout) << "dir = " << dir << endl; - (*testout) << "p = " << p << endl; - (*testout) << "x = " << x << endl; - } -} - - - - -bool SpecialPointCalculation :: ExtremalPointPossible (const Surface * f1, - const Surface * f2, - int dir, - const BoxSphere<3> & box) -{ - double hn1, hn2, gn1, gn2; - Point<3> p; - Vec<3> g1, g2, v; - double f3; - double r = box.Diam()/2; - - p = box.Center(); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - - gn1 = g1.Length(); - gn2 = g2.Length(); - - hn1 = f1 -> HesseNorm (); - hn2 = f2 -> HesseNorm (); - - v = Cross (g1, g2); - f3 = fabs (v(dir-1)); - - // (*testout) << "f3 = " << f3 << " r = " << r - // << "normbound = " - // << (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1)) << endl; - - return (f3 <= 3 * r * (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1))); -} - - - -bool SpecialPointCalculation :: -ExtremalPointNewtonConvergence (const Surface * f1, const Surface * f2, - int dir, - const BoxSphere<3> & box) -{ - return box.Diam() < 1e-8; -} - - -bool SpecialPointCalculation :: -ExtremalPointDegenerated (const Surface * f1, const Surface * f2, - int dir, const BoxSphere<3> & box) -{ - double gn1, gn2; - Point<3> p; - Vec<3> g1, g2, v; - double maxderiv; - double minv; - Vec<3> curv, t; - Vec<2> rs, x; - Mat<3> h1, h2; - Mat<2> a, inv; - double leftside; - - if (box.Diam() > relydegtest) return 0; - - p = box.Center(); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - gn1 = g1.Length(); - gn2 = g2.Length(); - - v = Cross (g1, g2); - if (Abs (v) < epeps1 * gn1 * gn2) return 1; // irregular edge - - f1 -> CalcHesse (p, h1); - f2 -> CalcHesse (p, h2); - - // hn1 = f1 -> HesseNorm (); - // hn2 = f2 -> HesseNorm (); - - t = v; - a(0, 0) = g1 * g1; - a(0, 1) = - a(1, 0) = g1 * g2; - a(1, 1) = g2 * g2; - - rs(0) = g1(dir-1); - rs(1) = g2(dir-1); - - a.Solve (rs, x); - - /* - CalcInverse (a, inv); - inv.Mult (rs, x); // x .. Lagrangeparameter - */ - // (*testout) << "g1 = " << g1 << " g2 = " << g2 << endl; - // (*testout) << "lam = " << x << endl; - // (*testout) << "h2 = " << h2 << endl; - - leftside = fabs (x(0) * ( t * (h1 * t)) + - x(1) * ( t * (h2 * t))); - - // (*testout) << "leftside = " << leftside << endl; - - if (leftside < epeps2 * Abs2 (v)) return 1; - - return 0; -} - - - -bool SpecialPointCalculation :: AddPoint (const Point<3> & p, int layer) -{ - for (int i = 0; i < points->Size(); i++) - if (Dist2 ( (*points)[i], p) < epspointdist2 && - (*points)[i].GetLayer() == layer) - return 0; - - points->Append (MeshPoint(p, layer)); - return 1; -} - - - - - - - -/* -void SpecialPointCalculation :: -AnalyzeSpecialPoints (const CSGeometry & ageometry, - ARRAY<Point<3> > & apoints, - ARRAY<SpecialPoint> & specpoints) -{ - int si, i, j, k, l, m, spi; - Solid * locsol; - ARRAY<int> surfind; - ARRAY<Vec<3>> normalvecs; - const Solid * sol; - Vec<3> t; - Point<3> p; - - ARRAY<int> specpoint2point; - specpoints.SetSize (0); - - (*testout) << "AnalyzeSpecialPoints" << endl; - - for (si = 1; si <= ageometry.GetNTopLevelObjects(); si++) - { - (*testout) << "main solid " << si << endl; - - sol = ageometry.GetTopLevelObject(si)->GetSolid(); - for (i = 1; i <= apoints.Size(); i++) - { - p = apoints.Get(i); - - sol -> TangentialSolid (p, locsol); - if (!locsol) continue; - - (*testout) << "Point " << apoints.Get(i) << endl; - - locsol -> GetSurfaceIndices (surfind); - for (j = surfind.Size(); j >= 1; j--) - if (fabs (ageometry.GetSurface(surfind.Get(j))-> - CalcFunctionValue (p)) > 1e-6) - surfind.DeleteElement (j); - - - - (*testout) << "Surfaces: "; - for (j = 1; j <= surfind.Size(); j++) - (*testout) << surfind.Get(j) << " "; - (*testout) << endl; - - normalvecs.SetSize(surfind.Size()); - for (j = 1; j <= surfind.Size(); j++) - ageometry.GetSurface(surfind.Get(j)) -> - GetNormalVector(apoints.Get(i), normalvecs.Elem(j)); - - for (j = 1; j <= normalvecs.Size() - 1; j ++) - for (k = j+1; k <= normalvecs.Size(); k++) - for (l = 1; l <= 2; l++) - { - t = Cross (normalvecs.Get(j), normalvecs.Get(k)); - if (t.Length2() < 1e-8) - { - cerr << "AnalyzePoint: Surfaces degenerated" << endl; - break; - } - t /= t.Length(); - if (l == 2) t *= -1; - - if (locsol -> Edge (apoints.Get(i), t)) - { - spi = 0; - for (m = 1; m <= specpoints.Size(); m++) - if (Dist2 (specpoints.Get(m).p, apoints.Get(i)) < 1e-8 - && (specpoints.Get(m).v - t).Length2() < 1e-8) - { - spi = m; - break; - } - if (!spi) - { - spi = specpoints.Append (SpecialPoint()); - specpoint2point.Append (i); - specpoints.Last().unconditional = 0; - } - specpoints.Elem(spi).p = apoints.Get(i); - specpoints.Elem(spi).v = t; - if (surfind.Size() >= 3) - specpoints.Elem(spi).unconditional = 1; - specpoints.Elem(spi).s1 = surfind.Get(j); - specpoints.Elem(spi).s2 = surfind.Get(k); - (*testout) << "spi = " << spi - << " uncond = " << specpoints.Get(spi).unconditional - << " t = " << t << endl; - } - - } - delete locsol; - } - } - - // if special point is unconditional on some solid, - // it must be unconditional everywhere: - - BitArray uncond (apoints.Size()); - uncond.Clear(); - - for (i = 1; i <= specpoints.Size(); i++) - if (specpoints.Get(i).unconditional) - uncond.Set (specpoint2point.Get(i)); - - for (i = 1; i <= specpoints.Size(); i++) - specpoints.Elem(i).unconditional = - uncond.Test (specpoint2point.Get(i)) ? 1 : 0; -} -*/ - - - -void SpecialPointCalculation :: -AnalyzeSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & apoints, - ARRAY<SpecialPoint> & specpoints) -{ - int si, i, j, k, l, m, spi; - - Solid * locsol; - ARRAY<int> surfind; - ARRAY<int> surfind2; - - ARRAY<Vec<3> > normalvecs; - const Solid * sol; - const Surface * surf; - - Vec<3> t, nsurf; - Point<3> p; - - ARRAY<int> specpoint2point; - specpoints.SetSize (0); - - geometry = &ageometry; - - (*testout) << "AnalyzeSpecialPoints\n"; - - - Box<3> bbox; - if (apoints.Size()) - bbox.Set (apoints[0]); - for (int i = 1; i < apoints.Size(); i++) - bbox.Add (apoints[i]); - bbox.Increase (0.1 * Dist (bbox.PMin(), bbox.PMax())); - - Point3dTree searchtree (bbox.PMin(), bbox.PMax()); - ARRAY<int> locsearch; - - for (si = 0; si < ageometry.GetNTopLevelObjects(); si++) - { - (*testout) << "main solid " << si << "\n"; - - sol = ageometry.GetTopLevelObject(si)->GetSolid(); - surf = ageometry.GetTopLevelObject(si)->GetSurface(); - - for (i = 0; i < apoints.Size(); i++) - { - p = apoints[i]; - if (ageometry.GetTopLevelObject(si)->GetLayer() != - apoints[i].GetLayer()) - continue; - - (*testout) << "Point " << apoints[i] << "\n"; - - sol -> TangentialSolid (p, locsol); - if (!locsol) continue; - - // get all surface indices, - if (surf) - { - locsol -> GetSurfaceIndices (surfind); - bool hassurf = 0; - for (m = 0; m < surfind.Size(); m++) - if (ageometry.GetSurface(surfind[m]) == surf) - hassurf = 1; - - if (!hassurf) - continue; - - surf->GetNormalVector (p, nsurf); - } - - // get independent surfaces of tangential solid - - BoxSphere<3> box(p,p); - box.Increase (1e-6); - box.CalcDiamCenter(); - ageometry.GetIndependentSurfaceIndices (locsol, box, surfind); - - - (*testout) << "surfind.size = " << surfind.Size() << endl; - - /* - locsol -> GetSurfaceIndices (surfind); - for (j = surfind.Size(); j >= 1; j--) - if (fabs (ageometry.GetSurface(surfind.Get(j))-> - CalcFunctionValue (p)) > 1e-6) - surfind.DeleteElement (j); - */ - - /* - (*testout) << "Surfaces: "; - for (j = 0; j < surfind.Size(); j++) - (*testout) << surfind[j] << " "; - (*testout) << "\n"; - */ - - - normalvecs.SetSize(surfind.Size()); - for (j = 0; j < surfind.Size(); j++) - ageometry.GetSurface(surfind[j]) -> - GetNormalVector(apoints[i], normalvecs[j]); - - for (j = 0; j < normalvecs.Size(); j++) - for (k = j+1; k < normalvecs.Size(); k++) - for (l = 1; l <= 2; l++) - { - t = Cross (normalvecs[j], normalvecs[k]); - if (Abs2 (t) < 1e-8) - { - cerr << "AnalyzePoint: Surfaces degenerated" << "\n"; - break; - } - t.Normalize(); - if (l == 2) t *= -1; - - // try tangential direction t - - // (*testout) << "check tangential " << t << "\n"; - - if (surf && fabs (nsurf * t) > 1e-6) - continue; - - if (!surf) - { - ageometry.GetIndependentSurfaceIndices - (locsol, p, t, surfind2); - - bool found1 = 0, found2 = 0; - for (int ii = 0; ii < surfind2.Size(); ii++) - { - if (surfind2[ii] == surfind[j]) - found1 = 1; - if (surfind2[ii] == surfind[k]) - found2 = 1; - } - if (!found1 || !found2) - continue; - } - - - bool isedge; - - // isedge = locsol -> Edge (apoints.Get(i), t); - - // edge must be on tangential surface - isedge = - locsol->VectorIn (p, t) && - !locsol->VectorStrictIn (p, t); - - // (*testout) << "isedge,1 = " << isedge << "\n"; - - // there must exist at least two different faces on edge - if (isedge) - { - int cnts = 0; - for (m = 0; m < surfind.Size(); m++) - { - if (fabs (normalvecs[m] * t) > 1e-6) - continue; - - Vec<3> s = Cross (normalvecs[m], t); - Vec<3> t2a = t + 0.01 *s; - Vec<3> t2b = t - 0.01 *s; - - /* - (*testout) << "nv = " << normalvecs[m] << ", s = " << s << "\n"; - (*testout) << "t2a = " << t2a << ", t2b = " << t2b << "\n"; - (*testout) << "via = " - << locsol->VectorIn (p, t2a) << "/" - << locsol->VectorStrictIn (p, t2a); - (*testout) << "vib = " - << locsol->VectorIn (p, t2b) << "/" - << locsol->VectorStrictIn (p, t2b) << "\n"; - */ - - bool isface = - (locsol->VectorIn (p, t2a) && - !locsol->VectorStrictIn (p, t2a)) - || - (locsol->VectorIn (p, t2b) && - !locsol->VectorStrictIn (p, t2b)); - - if (isface) - { - cnts++; - } - } - if (cnts < 2) isedge = 0; - } - - if (isedge) - { - spi = -1; - - searchtree.GetIntersecting (apoints[i]-Vec3d(1e-4,1e-4,1e-4), - apoints[i]+Vec3d(1e-4,1e-4,1e-4), - locsearch); - - for (m = 0; m < locsearch.Size(); m++) - if (Dist2 (specpoints[locsearch[m]].p, apoints[i]) < 1e-8 - && Abs2(specpoints[locsearch[m]].v - t) < 1e-8) - { - spi = locsearch[m]; - break; - } - - /* - for (m = 0; m < specpoints.Size(); m++) - if (Dist2 (specpoints[m].p, apoints[i]) < 1e-8 - && Abs2(specpoints[m].v - t) < 1e-8) - { - spi = m; - break; - } - */ - if (spi == -1) - { - spi = specpoints.Append (SpecialPoint()) - 1; - specpoint2point.Append (i); - specpoints.Last().unconditional = 0; - searchtree.Insert (apoints[i], spi); - } - specpoints[spi].p = apoints[i]; - specpoints[spi].v = t; - if (surfind.Size() >= 3) - specpoints[spi].unconditional = 1; - specpoints[spi].s1 = surfind[j]; - specpoints[spi].s2 = surfind[k]; - specpoints[spi].layer = apoints[i].GetLayer(); - for (int up = 0; up < geometry->GetNUserPoints(); up++) - if (Dist (geometry->GetUserPoint(up), apoints[i]) < 1e-10) - specpoints[spi].unconditional = 1; - - /* - (*testout) << "spi = " << spi - << " uncond = " << specpoints[spi].unconditional - << " t = " << t << "\n"; - */ - } - - } - delete locsol; - } - } - - // if special point is unconditional on some solid, - // it must be unconditional everywhere: - - BitArray uncond (apoints.Size()); - uncond.Clear(); - - for (i = 0; i < specpoints.Size(); i++) - if (specpoints[i].unconditional) - uncond.Set (specpoint2point[i]); - - for (i = 0; i < specpoints.Size(); i++) - specpoints[i].unconditional = - uncond.Test (specpoint2point[i]) ? 1 : 0; -} -} diff --git a/Netgen/libsrc/csg/specpoin_old.cpp b/Netgen/libsrc/csg/specpoin_old.cpp deleted file mode 100644 index 0f30ef7298..0000000000 --- a/Netgen/libsrc/csg/specpoin_old.cpp +++ /dev/null @@ -1,1370 +0,0 @@ -#include <mystdlib.h> -#include <meshing.hpp> -#include <csg.hpp> - - -/* - - Special Point calculation uses the global Flags: - - - size .. 500 cube = [-size, size]^3 - relydegtest when to rely on degeneration ? - calccp calculate points of intersection ? - cpeps1 eps for degenerated poi - calcep calculate points of extreme coordinates ? - epeps1 eps for degenerated edge - epeps2 eps for axis parallel pec - epspointdist eps for distance of special points -*/ - - -namespace netgen -{ -void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp); - - - - /* -SpecialPoint :: SpecialPoint () - : p(), v(), layer(0) -{ - ; -} - */ - - -SpecialPoint :: SpecialPoint (const SpecialPoint & sp) -{ - p = sp.p; - v = sp.v; - s1 = sp.s1; - s2 = sp.s2; - layer = sp.layer; - unconditional = sp.unconditional; -} - -SpecialPoint & SpecialPoint :: operator= (const SpecialPoint & sp) -{ - p = sp.p; - v = sp.v; - s1 = sp.s1; - s2 = sp.s2; - layer = sp.layer; - unconditional = sp.unconditional; - return *this; -} - -/* -bool SpecialPoint :: HasSurfaces (int as1, int as2) const -{ - return (s1 == as1 && s2 == as2 || s1 == as2 && s2 == as1); -} -*/ -void SpecialPoint :: Print (ostream & str) -{ - str << "p = " << p << " v = " << v - << " s1/s2 = " << s1 << "/" << s2 - << " layer = " << layer - << endl; -} - - - - -SpecialPointCalculation :: SpecialPointCalculation () -{ - ; -} - -void SpecialPointCalculation :: -CalcSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & apoints) -{ - int i; - - geometry = &ageometry; - points = &apoints; - - size = geometry->MaxSize(); // globflags.GetNumFlag ("maxsize", 500); - (*testout) << "Find Special Points" << endl; - (*testout) << "maxsize = " << size << endl; - - cpeps1 = 1e-6; - epeps1 = 1e-3; - epeps2 = 1e-6; - - epspointdist2 = sqr (size * 1e-8); - relydegtest = size * 1e-4; - - - BoxSphere<3> box (Point<3> (-size, -size, -size), - Point<3> ( size, size, size)); - box.CalcDiamCenter(); - PrintMessage (3, "main-solids: ", geometry->GetNTopLevelObjects()); - - for (i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - (*testout) << "tlo " << i << ":" << endl; - const TopLevelObject * tlo = geometry->GetTopLevelObject(i); - tlo->GetSolid()->Print (*testout); - (*testout) << endl; - CalcSpecialPointsRec (tlo->GetSolid(), tlo->GetLayer(), - box, 1, 1, 1); - } - - PrintDot ('\n'); - - - // add user point: - int found = 0; - for (i = 0; i < geometry->GetNUserPoints(); i++) - AddPoint (geometry->GetUserPoint(i), 1); - - PrintMessage (3, apoints.Size(), " special points"); - - for (i = 0; i < boxesinlevel.Size(); i++) - (*testout) << "level " << i << " has " - << boxesinlevel[i] << " boxes" << endl; -} - - - -int debug; -void SpecialPointCalculation :: -CalcSpecialPointsRec (const Solid * sol, int layer, - const BoxSphere<3> & box, - int level, bool calccp, bool calcep) -{ - if (multithread.terminate) - return; - - int i; - BoxSphere<3> sbox; - Solid * redsol; - - int numprim; - - bool decision; - bool possiblecrossp, possibleexp; // possible cross or extremalpoint - bool surecrossp, sureexp; // sure ... - - static ARRAY<int> locsurf; // attention: array is static - - - Point<3> p; - int k1, k2, k3; - int extremdir; - double hd; - - if (!sol) return; - - - if (level >= 100) - { - cerr << "Problems in CalcSpecialPoints" << endl; - cerr << "Point: " << box.Center() << endl; - exit (1); - } - - static int cntbox = 0; - cntbox++; - if (cntbox % 10000 == 0) - PrintDot (); - - if (level <= boxesinlevel.Size()) - boxesinlevel.Elem(level)++; - else - boxesinlevel.Append (1); - - /* - numprim = sol -> NumPrimitives(); - sol -> GetSurfaceIndices (locsurf); - */ - - debug = 0; - // box.IsIn (Point<3> (4.9, 1.279, 2.8)); - - - geometry -> GetIndependentSurfaceIndices (sol, box, locsurf); - numprim = locsurf.Size(); - - if (debug) - { - (*testout) << "box = " << box.PMin() << "-" << box.PMax() - << " np = " << numprim << " : "; - for (i = 1; i <= locsurf.Size(); i++) - (*testout) << " " << locsurf.Get(i); - (*testout) << " diam = " << box.Diam(); - (*testout) << " numprim = " << numprim; - (*testout) << endl; - } - - p = box.Center(); - - /* - (*testout) << "box = " << box.PMin() << " - " << box.PMax() - << ", lev = " << level - << ", nprim = " << sol->NumPrimitives() - << ", lsurf = " << locsurf.Size() << endl; - - for (i = 1; i <= locsurf.Size(); i++) - geometry->GetSurface (locsurf.Get(i)) -> Print (*testout); - sol -> Print (*testout); - */ - - /* - for (i = 1; i <= locsurf.Size(); i++) - (*testout) << locsurf.Get(i) << " "; - (*testout) << "C = " << box.Center() << " diam = " << box.Diam() << endl; - */ - - possiblecrossp = (numprim >= 3) && calccp; - surecrossp = 0; - - if (possiblecrossp && (locsurf.Size() <= 10)) - { - decision = 1; - surecrossp = 0; - - for (k1 = 1; k1 <= locsurf.Size() - 2; k1++) - for (k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) - for (k3 = k2 + 1; k3 <= locsurf.Size(); k3++) - { - int nc, deg; - nc = CrossPointNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), p ); - - deg = CrossPointDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), box ); - - if (!nc && !deg) decision = 0; - if (nc) surecrossp = 1; - } - - if (decision && surecrossp) - { - for (k1 = 1; k1 <= locsurf.Size() - 2; k1++) - for (k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) - for (k3 = k2 + 1; k3 <= locsurf.Size(); k3++) - { - if (CrossPointNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), p ) ) - { - Point<3> pp = p; - CrossPointNewton - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), pp); - - BoxSphere<3> hbox (pp, pp); - hbox.Increase (1e-8); - - if (pp(0) > box.PMin()(0) - 1e-5 && - pp(0) < box.PMax()(0) + 1e-5 && - pp(1) > box.PMin()(1) - 1e-5 && - pp(1) < box.PMax()(1) + 1e-5 && - pp(2) > box.PMin()(2) - 1e-5 && - pp(2) < box.PMax()(2) + 1e-5 && - sol -> IsIn (pp) && !sol->IsStrictIn (pp) && - !CrossPointDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - geometry->GetSurface(locsurf.Get(k3)), hbox )) - - { - // AddCrossPoint (locsurf, sol, p); - BoxSphere<3> boxp (pp, pp); - boxp.Increase (1e-3); - boxp.CalcDiamCenter(); - ARRAY<int> locsurf2; - - geometry -> GetIndependentSurfaceIndices (sol, boxp, locsurf2); - - /* - ReducePrimitiveIterator rpi(boxp); - UnReducePrimitiveIterator urpi; - - ((Solid*)sol) -> IterateSolid (rpi); - sol -> GetIndependentSurfaceIndices (locsurf2); - ((Solid*)sol) -> IterateSolid (urpi); - */ - bool found1 = 0, found2 = 0, found3 = 0; - for (i = 1; i <= locsurf2.Size(); i++) - { - if (locsurf2.Get(i) == locsurf.Get(k1)) - found1 = 1; - if (locsurf2.Get(i) == locsurf.Get(k2)) - found2 = 1; - if (locsurf2.Get(i) == locsurf.Get(k3)) - found3 = 1; - } - - if (found1 && found2 && found3) - if (AddPoint (pp, layer)) - { - (*testout) << "Crosspoint found: " << pp - << " diam = " << box.Diam() << endl; - (*testout) << "surfs: " - << locsurf.Get(k1) << "," - << locsurf.Get(k2) << "," - << locsurf.Get(k3) << endl; - } - } - } - } - } - - if (decision) - possiblecrossp = 0; - } - - - - - possibleexp = (numprim >= 2) && calcep; - - if (possibleexp && (locsurf.Size() <= 10)) - { - decision = 1; - sureexp = 0; - - for (k1 = 1; k1 <= locsurf.Size() - 1; k1++) - for (k2 = k1+1; k2 <= locsurf.Size(); k2++) - { - bool nc, deg; - - nc = EdgeNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p); - - deg = EdgeDegenerated - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - box); - - if (!nc && !deg) decision = 0; - if (nc) sureexp = 1; - - if (debug) - { - (*testout) << "p = " << p << " s1,2 = " << locsurf.Get(k1) << ", " << locsurf.Get(k2) - << " nc = " << nc << " deg = " << deg << endl; - } - } - - if (decision && sureexp) - { - for (k1 = 1; k1 <= locsurf.Size() - 1; k1++) - for (k2 = k1+1; k2 <= locsurf.Size(); k2++) - { - if ( - EdgeNewtonConvergence - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p) ) - { - EdgeNewton - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p); - - Point<3> pp; - if (IsEdgeExtremalPoint - (geometry->GetSurface(locsurf.Get(k1)), - geometry->GetSurface(locsurf.Get(k2)), - p, pp, box.Diam()/2)) - { - (*testout) << "extremalpoint (nearly) found:" - << pp - << endl; - if (Dist (pp, box.Center()) < box.Diam()/2 && - sol -> IsIn (pp) && !sol->IsStrictIn (pp) ) - { - // AddExtremalPoint (locsurf.Get(k1), locsurf.Get(k2), p); - if (AddPoint (pp, layer)) - (*testout) << "Extremal point found: " << pp << endl; - } - } - } - } - } - if (decision) - possibleexp = 0; - } - - - - if (possiblecrossp || possibleexp) - { - for (i = 0; i < 8; i++) - { - box.GetSubBox (i, sbox); - sbox.Increase (1e-4 * sbox.Diam()); - - redsol = sol -> GetReducedSolid (sbox); - - if (redsol) - { - CalcSpecialPointsRec (redsol, layer, sbox, level+1, calccp, calcep); - delete redsol; - } - } - } -} - - - - - -/******* Tests for Point of intersection **********************/ - - - -bool SpecialPointCalculation :: -CrossPointNewtonConvergence (const Surface * f1, - const Surface * f2, - const Surface * f3, - const Point<3> & p) -{ - int i; - Vec<3> grad; - Vec<3> rs, x; - Mat<3> jacobi, inv; - double alpha, beta, gamma, eta; - double sum; - int j; - - - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - rs(2) = f3->CalcFunctionValue (p); - - f1->CalcGradient (p, grad); - jacobi(0,0) = grad(0); - jacobi(0,1) = grad(1); - jacobi(0,2) = grad(2); - - f2->CalcGradient (p, grad); - jacobi(1,0) = grad(0); - jacobi(1,1) = grad(1); - jacobi(1,2) = grad(2); - - f3->CalcGradient (p, grad); - jacobi(2,0) = grad(0); - jacobi(2,1) = grad(1); - jacobi(2,2) = grad(2); - - alpha = 1; - if (fabs (Det (jacobi)) > 1e-8) - { - CalcInverse (jacobi, inv); - x = inv * rs; - - gamma = f1 -> HesseNorm() + f2 -> HesseNorm() + f3 -> HesseNorm(); - beta = 0; - for (i = 0; i < 3; i++) - { - sum = 0; - for (j = 0; j < 3; j++) - sum += fabs (inv(i,j)); - beta = max2 (beta, sum); - } - eta = Abs (x); - - alpha = beta * gamma * eta; - } - - return (alpha < 0.1); -} - - - - -bool SpecialPointCalculation :: -CrossPointDegenerated (const Surface * f1, - const Surface * f2, - const Surface * f3, - const BoxSphere<3> & box) const -{ - Mat<3> mat; - Vec<3> grad, g1, g2, g3; - double normprod; - - if (box.Diam() > relydegtest) return 0; - - f1->CalcGradient (box.Center(), g1); - normprod = Abs (g1); - - f2->CalcGradient (box.Center(), g2); - normprod *= Abs (g2); - - f3->CalcGradient (box.Center(), g3); - normprod *= Abs (g3); - - for (int i = 0; i < 3; i++) - { - mat(i,0) = g1(i); - mat(i,1) = g2(i); - mat(i,2) = g3(i); - } - - if (fabs (Det (mat)) < cpeps1 * normprod) - return 1; - else - return 0; -} - - - - - -void SpecialPointCalculation :: CrossPointNewton (const Surface * f1, - const Surface * f2, - const Surface * f3, Point<3> & p) -{ - int i; - Vec<3> g1, g2, g3; - Vec<3> rs, sol; - Mat<3> mat; - - i = 10; - while (i > 0) - { - i--; - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - rs(2) = f3->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - f3->CalcGradient (p, g3); - - for (int j = 0; j < 3; j++) - { - mat(0, j) = g1(j); - mat(1, j) = g2(j); - mat(2, j) = g3(j); - } - mat.Solve (rs, sol); - /* - Transpose (g1, g2, g3); - SolveLinearSystem (g1, g2, g3, rs, sol); - */ - if (sol.Length() < 1e-12 && i > 1) i = 1; - - p -= sol; - } -} - - - - -/******* Tests for Point on edges **********************/ - - - - -bool SpecialPointCalculation :: -EdgeNewtonConvergence (const Surface * f1, const Surface * f2, - const Point<3> & p) -{ - int i; - Vec<3> g1, g2, sol; - Vec<2> vrs; - double alpha, beta, gamma, eta; - double sum; - Mat<2,3> mat; - Mat<3,2> inv; - int j; - - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - for (i = 0; i < 3; i++) - { - mat(0,i) = g1(i); - mat(1,i) = g2(i); - } - - alpha = 1; - - if ( fabs(g1 * g2) < (1 - 1e-8) * Abs (g1) * Abs (g2)) - { - CalcInverse (mat, inv); - sol = inv * vrs; - - // SolveLinearSystemLS (g1, g2, vrs, sol); - - gamma = f1 -> HesseNorm() + f2 -> HesseNorm(); - - /* - Vec<3> inv1, inv2; - PseudoInverse (g1, g2, inv1, inv2); - */ - - beta = 0; - for (i = 0; i < 3; i++) - for (j = 0; j < 2; j++) - beta += inv(i,j) * inv(i,j); - beta = sqrt (beta); - - // beta = inv1.Length() + inv2.Length(); - eta = Abs (sol); - alpha = beta * gamma * eta; - } - return (alpha < 0.1); -} - - - - -bool SpecialPointCalculation :: -EdgeDegenerated (const Surface * f1, - const Surface * f2, - const BoxSphere<3> & box) const -{ - // perform newton steps. normals parallel ? - // if not decideable: return 0 - - - Point<3> p = box.Center(); - int i; - Vec<3> grad, g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - - i = 20; - while (i > 0) - { - if (Dist (p, box.Center()) > box.Diam()) - return 0; - - i--; - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - if ( fabs (g1 * g2) > (1 - 1e-10) * Abs (g1) * Abs (g2)) - return 1; - - for (int j = 0; j < 3; j++) - { - mat(0,j) = g1(j); - mat(1,j) = g2(j); - } - mat.Solve (vrs, sol); - // SolveLinearSystemLS (g1, g2, vrs, sol); - - if (Abs (sol) < 1e-12 && i > 1) i = 1; - p -= sol; - } - - return 0; - /* - return 0; - - static DenseMatrix jacobi(3); - Vec<3> grad, g1, g2, g3; - double normprod; - - if (box.Diam() > relydegtest) return 0; - - f1->CalcGradient (box.Center(), g1); - normprod = g1.Length(); - - f2->CalcGradient (box.Center(), g2); - normprod *= g2.Length(); - - if (fabs (g1 * g2) < 1e-8 * normprod) - return 1; - else - return 0; - */ -} - - - - - - -void SpecialPointCalculation :: EdgeNewton (const Surface * f1, - const Surface * f2, Point<3> & p) -{ - int i; - Vec<3> grad, g1, g2, sol; - Vec<2> vrs; - Mat<2,3> mat; - - i = 10; - while (i > 0) - { - i--; - vrs(0) = f1->CalcFunctionValue (p); - vrs(1) = f2->CalcFunctionValue (p); - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - for (int j = 0; j < 3; j++) - { - mat(0,j) = g1(j); - mat(1,j) = g2(j); - } - mat.Solve (vrs, sol); - // SolveLinearSystemLS (g1, g2, vrs, sol); - - if (Abs (sol) < 1e-12 && i > 1) i = 1; - p -= sol; - } -} - - - -bool SpecialPointCalculation :: -IsEdgeExtremalPoint (const Surface * f1, const Surface * f2, - const Point<3> & p, Point<3> & pp, double rad) -{ - Vec<3> g1, g2, t, t1, t2; - int j; - - f1->CalcGradient (p, g1); - f2->CalcGradient (p, g2); - - t = Cross (g1, g2); - t.Normalize(); - - Point<3> p1 = p + rad * t; - Point<3> p2 = p - rad * t; - - EdgeNewton (f1, f2, p1); - EdgeNewton (f1, f2, p2); - - - f1->CalcGradient (p1, g1); - f2->CalcGradient (p1, g2); - t1 = Cross (g1, g2); - t1.Normalize(); - - f1->CalcGradient (p2, g1); - f2->CalcGradient (p2, g2); - t2 = Cross (g1, g2); - t2.Normalize(); - - double val = 1e-8 * rad * rad; - for (j = 0; j < 3; j++) - if ( (t1(j) * t2(j) < -val) ) - { - pp = p; - ExtremalPointNewton (f1, f2, j+1, pp); - return 1; - } - - return 0; -} - - - - - - - - - -/********** Tests of Points of extremal coordinates ****************/ - - -void SpecialPointCalculation :: ExtremalPointNewton (const Surface * f1, - const Surface * f2, - int dir, Point<3> & p) -{ - int i; - - Vec<3> g1, g2, v, curv; - Vec<3> rs, x, y1, y2, y; - Mat<3> h1, h2; - Mat<3> jacobi; - - - if (dir < 1 || dir > 3) - { - cerr << "Error: Illegal extremdir" << endl; - return; - } - - i = 50; - while (i > 0) - { - i--; - rs(0) = f1->CalcFunctionValue (p); - rs(1) = f2->CalcFunctionValue (p); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - - f1 -> CalcHesse (p, h1); - f2 -> CalcHesse (p, h2); - - - v = Cross (g1, g2); - - rs(2) = v(dir-1); - - jacobi(0,0) = g1(0); - jacobi(0,1) = g1(1); - jacobi(0,2) = g1(2); - - jacobi(1,0) = g2(0); - jacobi(1,1) = g2(1); - jacobi(1,2) = g2(2); - - - switch (dir) - { - case 1: - { - y1(0) = 0; - y1(1) = g2(2); - y1(2) = -g2(1); - y2(0) = 0; - y2(1) = -g1(2); - y2(2) = g1(1); - break; - } - case 2: - { - y1(0) = -g2(2); - y1(1) = 0; - y1(2) = g2(0); - y2(0) = g1(2); - y2(1) = 0; - y2(2) = -g1(0); - break; - } - case 3: - { - y1(0) = g2(1); - y1(1) = -g2(0); - y1(2) = 0; - y2(0) = -g1(1); - y2(1) = g1(0); - y2(2) = 0; - break; - } - } - - y = h1 * y1 + h2 * y2; - - jacobi(2,0) = y(0); - jacobi(2,1) = y(1); - jacobi(2,2) = y(2); - - jacobi.Solve (rs, x); - /* - CalcInverse (jacobi, inv); - inv.Mult (rs, x); - */ - // (*testout) << "err = " << x.L2Norm() << endl; - - if (Abs (x) < 1e-12 && i > 1) - { - // (*testout) << "convergent in " << (10 - i) << " steps " << endl; - - i = 1; - } - - p -= x; - } - - if (Abs (x) > 1e-10) - { - (*testout) << "Error: extremum Newton not convergent" << endl; - (*testout) << "dir = " << dir << endl; - (*testout) << "p = " << p << endl; - (*testout) << "x = " << x << endl; - } -} - - - - -bool SpecialPointCalculation :: ExtremalPointPossible (const Surface * f1, - const Surface * f2, - int dir, - const BoxSphere<3> & box) -{ - double hn1, hn2, gn1, gn2; - Point<3> p; - Vec<3> g1, g2, v; - double f3; - double r = box.Diam()/2; - - p = box.Center(); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - - gn1 = g1.Length(); - gn2 = g2.Length(); - - hn1 = f1 -> HesseNorm (); - hn2 = f2 -> HesseNorm (); - - v = Cross (g1, g2); - f3 = fabs (v(dir-1)); - - // (*testout) << "f3 = " << f3 << " r = " << r - // << "normbound = " - // << (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1)) << endl; - - return (f3 <= 3 * r * (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1))); -} - - - -bool SpecialPointCalculation :: -ExtremalPointNewtonConvergence (const Surface * f1, const Surface * f2, - int dir, - const BoxSphere<3> & box) -{ - return box.Diam() < 1e-8; -} - - -bool SpecialPointCalculation :: -ExtremalPointDegenerated (const Surface * f1, const Surface * f2, - int dir, const BoxSphere<3> & box) -{ - double gn1, gn2; - Point<3> p; - Vec<3> g1, g2, v; - double maxderiv; - double minv; - Vec<3> curv, t; - Vec<2> rs, x; - Mat<3> h1, h2; - Mat<2> a, inv; - double leftside; - - if (box.Diam() > relydegtest) return 0; - - p = box.Center(); - - f1 -> CalcGradient (p, g1); - f2 -> CalcGradient (p, g2); - gn1 = g1.Length(); - gn2 = g2.Length(); - - v = Cross (g1, g2); - if (Abs (v) < epeps1 * gn1 * gn2) return 1; // irregular edge - - f1 -> CalcHesse (p, h1); - f2 -> CalcHesse (p, h2); - - // hn1 = f1 -> HesseNorm (); - // hn2 = f2 -> HesseNorm (); - - t = v; - a(0, 0) = g1 * g1; - a(0, 1) = - a(1, 0) = g1 * g2; - a(1, 1) = g2 * g2; - - rs(0) = g1(dir-1); - rs(1) = g2(dir-1); - - a.Solve (rs, x); - - /* - CalcInverse (a, inv); - inv.Mult (rs, x); // x .. Lagrangeparameter - */ - // (*testout) << "g1 = " << g1 << " g2 = " << g2 << endl; - // (*testout) << "lam = " << x << endl; - // (*testout) << "h2 = " << h2 << endl; - - leftside = fabs (x(0) * ( t * (h1 * t)) + - x(1) * ( t * (h2 * t))); - - // (*testout) << "leftside = " << leftside << endl; - - if (leftside < epeps2 * Abs2 (v)) return 1; - - return 0; -} - - - -bool SpecialPointCalculation :: AddPoint (const Point<3> & p, int layer) -{ - for (int i = 0; i < points->Size(); i++) - if (Dist2 ( (*points)[i], p) < epspointdist2 && - (*points)[i].GetLayer() == layer) - return 0; - - points->Append (MeshPoint(p, layer)); - return 1; -} - - - - - - - -/* -void SpecialPointCalculation :: -AnalyzeSpecialPoints (const CSGeometry & ageometry, - ARRAY<Point<3> > & apoints, - ARRAY<SpecialPoint> & specpoints) -{ - int si, i, j, k, l, m, spi; - Solid * locsol; - ARRAY<int> surfind; - ARRAY<Vec<3>> normalvecs; - const Solid * sol; - Vec<3> t; - Point<3> p; - - ARRAY<int> specpoint2point; - specpoints.SetSize (0); - - (*testout) << "AnalyzeSpecialPoints" << endl; - - for (si = 1; si <= ageometry.GetNTopLevelObjects(); si++) - { - (*testout) << "main solid " << si << endl; - - sol = ageometry.GetTopLevelObject(si)->GetSolid(); - for (i = 1; i <= apoints.Size(); i++) - { - p = apoints.Get(i); - - sol -> TangentialSolid (p, locsol); - if (!locsol) continue; - - (*testout) << "Point " << apoints.Get(i) << endl; - - locsol -> GetSurfaceIndices (surfind); - for (j = surfind.Size(); j >= 1; j--) - if (fabs (ageometry.GetSurface(surfind.Get(j))-> - CalcFunctionValue (p)) > 1e-6) - surfind.DeleteElement (j); - - - - (*testout) << "Surfaces: "; - for (j = 1; j <= surfind.Size(); j++) - (*testout) << surfind.Get(j) << " "; - (*testout) << endl; - - normalvecs.SetSize(surfind.Size()); - for (j = 1; j <= surfind.Size(); j++) - ageometry.GetSurface(surfind.Get(j)) -> - GetNormalVector(apoints.Get(i), normalvecs.Elem(j)); - - for (j = 1; j <= normalvecs.Size() - 1; j ++) - for (k = j+1; k <= normalvecs.Size(); k++) - for (l = 1; l <= 2; l++) - { - t = Cross (normalvecs.Get(j), normalvecs.Get(k)); - if (t.Length2() < 1e-8) - { - cerr << "AnalyzePoint: Surfaces degenerated" << endl; - break; - } - t /= t.Length(); - if (l == 2) t *= -1; - - if (locsol -> Edge (apoints.Get(i), t)) - { - spi = 0; - for (m = 1; m <= specpoints.Size(); m++) - if (Dist2 (specpoints.Get(m).p, apoints.Get(i)) < 1e-8 - && (specpoints.Get(m).v - t).Length2() < 1e-8) - { - spi = m; - break; - } - if (!spi) - { - spi = specpoints.Append (SpecialPoint()); - specpoint2point.Append (i); - specpoints.Last().unconditional = 0; - } - specpoints.Elem(spi).p = apoints.Get(i); - specpoints.Elem(spi).v = t; - if (surfind.Size() >= 3) - specpoints.Elem(spi).unconditional = 1; - specpoints.Elem(spi).s1 = surfind.Get(j); - specpoints.Elem(spi).s2 = surfind.Get(k); - (*testout) << "spi = " << spi - << " uncond = " << specpoints.Get(spi).unconditional - << " t = " << t << endl; - } - - } - delete locsol; - } - } - - // if special point is unconditional on some solid, - // it must be unconditional everywhere: - - BitArray uncond (apoints.Size()); - uncond.Clear(); - - for (i = 1; i <= specpoints.Size(); i++) - if (specpoints.Get(i).unconditional) - uncond.Set (specpoint2point.Get(i)); - - for (i = 1; i <= specpoints.Size(); i++) - specpoints.Elem(i).unconditional = - uncond.Test (specpoint2point.Get(i)) ? 1 : 0; -} -*/ - - - -void SpecialPointCalculation :: -AnalyzeSpecialPoints (const CSGeometry & ageometry, - ARRAY<MeshPoint> & apoints, - ARRAY<SpecialPoint> & specpoints) -{ - int si, i, j, k, l, m, spi; - - Solid * locsol; - ARRAY<int> surfind; - ARRAY<int> surfind2; - - ARRAY<Vec<3> > normalvecs; - const Solid * sol; - const Surface * surf; - - Vec<3> t, nsurf; - Point<3> p; - - ARRAY<int> specpoint2point; - specpoints.SetSize (0); - - geometry = &ageometry; - - (*testout) << "AnalyzeSpecialPoints\n"; - - for (si = 0; si < ageometry.GetNTopLevelObjects(); si++) - { - (*testout) << "main solid " << si << "\n"; - - sol = ageometry.GetTopLevelObject(si)->GetSolid(); - surf = ageometry.GetTopLevelObject(si)->GetSurface(); - - for (i = 0; i < apoints.Size(); i++) - { - p = apoints[i]; - if (ageometry.GetTopLevelObject(si)->GetLayer() != - apoints[i].GetLayer()) - continue; - - // (*testout) << "Point " << apoints[i] << "\n"; - - sol -> TangentialSolid (p, locsol); - if (!locsol) continue; - - // get all surface indices, - if (surf) - { - locsol -> GetSurfaceIndices (surfind); - bool hassurf = 0; - for (m = 0; m < surfind.Size(); m++) - if (ageometry.GetSurface(surfind[m]) == surf) - hassurf = 1; - - if (!hassurf) - continue; - - surf->GetNormalVector (p, nsurf); - } - - // get independent surfaces of tangential solid - - BoxSphere<3> box(p,p); - box.Increase (1e-6); - box.CalcDiamCenter(); - ageometry.GetIndependentSurfaceIndices (locsol, box, surfind); - - - /* - locsol -> GetSurfaceIndices (surfind); - for (j = surfind.Size(); j >= 1; j--) - if (fabs (ageometry.GetSurface(surfind.Get(j))-> - CalcFunctionValue (p)) > 1e-6) - surfind.DeleteElement (j); - */ - - /* - (*testout) << "Surfaces: "; - for (j = 0; j < surfind.Size(); j++) - (*testout) << surfind[j] << " "; - (*testout) << "\n"; - */ - - - normalvecs.SetSize(surfind.Size()); - for (j = 0; j < surfind.Size(); j++) - ageometry.GetSurface(surfind[j]) -> - GetNormalVector(apoints[i], normalvecs[j]); - - for (j = 0; j < normalvecs.Size(); j++) - for (k = j+1; k < normalvecs.Size(); k++) - for (l = 1; l <= 2; l++) - { - t = Cross (normalvecs[j], normalvecs[k]); - if (Abs2 (t) < 1e-8) - { - cerr << "AnalyzePoint: Surfaces degenerated" << "\n"; - break; - } - t.Normalize(); - if (l == 2) t *= -1; - - // try tangential direction t - - // (*testout) << "check tangential " << t << "\n"; - - if (surf && fabs (nsurf * t) > 1e-6) - continue; - - if (!surf) - { - ageometry.GetIndependentSurfaceIndices - (locsol, p, t, surfind2); - - bool found1 = 0, found2 = 0; - for (int ii = 0; ii < surfind2.Size(); ii++) - { - if (surfind2[ii] == surfind[j]) - found1 = 1; - if (surfind2[ii] == surfind[k]) - found2 = 1; - } - if (!found1 || !found2) - continue; - } - - - bool isedge; - - // isedge = locsol -> Edge (apoints.Get(i), t); - - // edge must be on tangential surface - isedge = - locsol->VectorIn (p, t) && - !locsol->VectorStrictIn (p, t); - - // (*testout) << "isedge,1 = " << isedge << "\n"; - - // there must exist at least two different faces on edge - if (isedge) - { - int cnts = 0; - for (m = 0; m < surfind.Size(); m++) - { - if (fabs (normalvecs[m] * t) > 1e-6) - continue; - - Vec<3> s = Cross (normalvecs[m], t); - Vec<3> t2a = t + 0.01 *s; - Vec<3> t2b = t - 0.01 *s; - - /* - (*testout) << "nv = " << normalvecs[m] << ", s = " << s << "\n"; - (*testout) << "t2a = " << t2a << ", t2b = " << t2b << "\n"; - (*testout) << "via = " - << locsol->VectorIn (p, t2a) << "/" - << locsol->VectorStrictIn (p, t2a); - (*testout) << "vib = " - << locsol->VectorIn (p, t2b) << "/" - << locsol->VectorStrictIn (p, t2b) << "\n"; - */ - - bool isface = - (locsol->VectorIn (p, t2a) && - !locsol->VectorStrictIn (p, t2a)) - || - (locsol->VectorIn (p, t2b) && - !locsol->VectorStrictIn (p, t2b)); - - if (isface) - { - cnts++; - } - } - if (cnts < 2) isedge = 0; - } - - if (isedge) - { - spi = -1; - for (m = 0; m < specpoints.Size(); m++) - if (Dist2 (specpoints[m].p, apoints[i]) < 1e-8 - && Abs2(specpoints[m].v - t) < 1e-8) - { - spi = m; - break; - } - if (spi == -1) - { - spi = specpoints.Append (SpecialPoint()) - 1; - specpoint2point.Append (i); - specpoints.Last().unconditional = 0; - } - specpoints[spi].p = apoints[i]; - specpoints[spi].v = t; - if (surfind.Size() >= 3) - specpoints[spi].unconditional = 1; - specpoints[spi].s1 = surfind[j]; - specpoints[spi].s2 = surfind[k]; - specpoints[spi].layer = apoints[i].GetLayer(); - for (int up = 0; up < geometry->GetNUserPoints(); up++) - if (Dist (geometry->GetUserPoint(up), apoints[i]) < 1e-10) - specpoints[spi].unconditional = 1; - - /* - (*testout) << "spi = " << spi - << " uncond = " << specpoints[spi].unconditional - << " t = " << t << "\n"; - */ - } - - } - delete locsol; - } - } - - // if special point is unconditional on some solid, - // it must be unconditional everywhere: - - BitArray uncond (apoints.Size()); - uncond.Clear(); - - for (i = 0; i < specpoints.Size(); i++) - if (specpoints[i].unconditional) - uncond.Set (specpoint2point[i]); - - for (i = 0; i < specpoints.Size(); i++) - specpoints[i].unconditional = - uncond.Test (specpoint2point[i]) ? 1 : 0; -} -} diff --git a/Netgen/libsrc/csg/spline3d.cpp b/Netgen/libsrc/csg/spline3d.cpp deleted file mode 100644 index 455493ad6f..0000000000 --- a/Netgen/libsrc/csg/spline3d.cpp +++ /dev/null @@ -1,355 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ -splinesegment3d :: splinesegment3d (const Point<3> & ap1, const Point<3> & ap2, - const Point<3> & ap3) -{ - p1 = ap1; - p2 = ap2; - p3 = ap3; -} - - -/* - todo - Tip von Joerg Stiller: - setzt Du in - void splinesegment3d :: Evaluate - Zeilen 54 und 56 - b2 = 2 * t * (1-t); - b2 /= sqrt(2); - Das heisst, Du wichtest das zweite Bersteinpolynom mit - w2 = 1 / sqrt(2); - Das ist aber nur fuer 45-Grad-Segmente korrekt. Fuer den - allgemeinen Fall funktioniert - w2 = ( e(p3 - p1), e(p2 - p1) ); // also cos(winkel(p3-p1, p2-p1)) - bzw. schoen symmetrisch - w2 = ( e(p3 - p1), e(p2 - p1) )/2 + ( e(p1 - p3), e(p2 - p3) )/2; - Das ist natuerlich kein C++ Code sondern symbolisch, wobei - e(p3 - p1) ist der von p1 zu p3 zeigende Einheitsvektor und - (a, b) steht fuer das Skalarprodukt zweier Vektoren etc. - - Eine vergleichbare Information steht auch irgendwo im Hoscheck & Lasser. - Ich habe das Buch aber eben nicht zur Hand. -*/ - -void splinesegment3d :: Evaluate (double t, Point<3> & p) const -{ - double x, y, z, w; - double b1, b2, b3; - - b1 = (1-t)*(1-t); - b2 = 2 * t * (1-t); - b3 = t * t; - - b2 /= sqrt(double(2)); - - x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3; - y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3; - z = p1(2) * b1 + p2(2) * b2 + p3(2) * b3; - w = b1 + b2 + b3; - - p(0) = x / w; - p(1) = y / w; - p(2) = z / w; -} - -void splinesegment3d :: EvaluateTangent (double t, Vec<3> & tang) const -{ - double x, y, z, w, xprime, yprime, zprime, wprime; - double b1, b2, b3, b1prime, b2prime, b3prime; - - b1 = (1-t)*(1-t); - b2 = 2 * t * (1-t); - b3 = t * t; - b2 /= sqrt(double(2)); - - b1prime = 2 * t - 2; - b2prime = - 4 * t + 2; - b3prime = 2 * t; - b2prime /= sqrt(double(2)); - - - x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3; - y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3; - z = p1(2) * b1 + p2(2) * b2 + p3(2) * b3; - w = b1 + b2 + b3; - - xprime = p1(0) * b1prime + p2(0) * b2prime + p3(0) * b3prime; - yprime = p1(1) * b1prime + p2(1) * b2prime + p3(1) * b3prime; - zprime = p1(2) * b1prime + p2(2) * b2prime + p3(2) * b3prime; - wprime = b1prime + b2prime + b3prime; - - tang(0) = (w * xprime - x * wprime) / (w * w); - tang(1) = (w * yprime - y * wprime) / (w * w); - tang(2) = (w * zprime - z * wprime) / (w * w); -} - - -void spline3d :: AddSegment (const Point<3> & ap1, const Point<3> & ap2, - const Point<3> & ap3) -{ - segments.Append (new splinesegment3d (ap1, ap2, ap3)); -} - -void spline3d :: Evaluate (double t, Point<3> & p) const -{ - int nr; - double loct; - static int cnt = 0; - - cnt++; - if (cnt % 10000 == 0) (*mycout) << "Evaluate calls: " << cnt << endl; - - while (t < 0) t += GetNumSegments(); - while (t >= GetNumSegments()) t -= GetNumSegments(); - nr = 1 + int (t); - loct = t - nr + 1; - segments.Get(nr)->Evaluate (loct, p); -} - -void spline3d :: EvaluateTangent (double t, Vec<3> & tang) const -{ - int nr; - double loct; - - while (t < 0) t += GetNumSegments(); - while (t >= GetNumSegments()) t -= GetNumSegments(); - nr = 1 + int (t); - loct = t - nr + 1; - segments.Get(nr)->EvaluateTangent (loct, tang); -} - - -double spline3d :: ProjectToSpline (Point<3> & p) const -{ - double t, tl, tu, dt, dist, mindist, optt; - Point<3> hp; - Vec<3> tanx, px; - - dt = 0.01; - mindist = 0; - for (t = 0; t <= GetNumSegments() + dt/2; t += dt) - { - Evaluate (t, hp); - dist = Dist (hp, p); - if (t == 0 || dist < mindist) - { - optt = t; - mindist = dist; - } - } - - - tu = optt + dt; - tl = optt - dt; - while (tu - tl > 1e-2) - { - optt = 0.5 * (tu + tl); - Evaluate (optt, hp); - EvaluateTangent (optt, tanx); - if (tanx * (hp - p) > 0) - tu = optt; - else - tl = optt; - } - - optt = 0.5 * (tu + tl); - - optt = ProjectToSpline (p, optt); - return optt; -} - - -double spline3d :: ProjectToSpline (Point<3> & p, double optt) const -{ - double tl, tu, dt, val, dval, valu, vall; - Point<3> hp; - Vec<3> tanx, px; - int its = 0; - int cnt = 1000; - do - { - dt = 1e-8; - tl = optt - dt; - tu = optt + dt; - - EvaluateTangent (optt, tanx); - Evaluate (optt, hp); - px = hp - p; - val = px * tanx; - - EvaluateTangent (tl, tanx); - Evaluate (tl, hp); - px = hp - p; - vall = px * tanx; - - EvaluateTangent (tu, tanx); - Evaluate (tu, hp); - px = hp - p; - valu = px * tanx; - - dval = (valu - vall) / (2 * dt); - - if (its % 100 == 99) - (*testout) << "optt = " << optt - << " val = " << val - << " dval = " << dval << endl; - optt -= val / dval; - its++; - if (fabs(val) < 1e-8 && cnt > 5) cnt = 5; - cnt--; - } - while (cnt > 0); - - Evaluate (optt, p); - return optt; -} - - -splinetube :: splinetube (const spline3d & amiddlecurve, double ar) - : Surface(), middlecurve (amiddlecurve), r(ar) -{ - (*mycout) << "Splinetube Allocated, r = " << r << endl; - -} - -void splinetube :: DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2) -{ - double t; - double phi, z; - - p1 = ap1; - p2 = ap2; - cp = p1; - t = middlecurve.ProjectToSpline (cp); - ex = p1 - cp; - middlecurve.EvaluateTangent (t, ez); - ex.Normalize(); - ez.Normalize(); - ey = Cross (ez, ex); - - phi = r * atan2 (ey * (p2-cp), ex * (p2-cp)); - z = ez * (p2 - cp); - e2x(0) = phi; - e2x(1) = z; - e2x.Normalize(); - e2y(1) = e2x(0); - e2y(0) = -e2x(1); - - // (*testout) << "Defineplane: " << endl - // << "p1 = " << p1 << " p2 = " << p2 << endl - // << "pc = " << cp << endl - // << "ex = " << ex << " ey = " << ey << " ez = " << ez << endl - // << "phi = " << phi << " z = " << z << endl - // << "e2x = " << e2x << " e2y = " << e2y << endl; -} - -void splinetube :: ToPlane (const Point<3> & p3d, Point<2> & pplain, double h, - int & zone) const -{ - Vec<2> v; - v(0) = r * atan2 (ey * (p3d-cp), ex * (p3d-cp)); - v(1) = ez * (p3d - cp); - zone = 0; - if (v(0) > r * 2) zone = 1; - if (v(0) < r * 2) zone = 2; - - pplain(0) = (v * e2x) / h; - pplain(1) = (v * e2y) / h; -} - -void splinetube :: FromPlane (const Point<2> & pplain, Point<3> & p3d, double h) const -{ - Vec<2> v; - - v(0) = pplain(0) * h * e2x(0) + pplain(1) * h * e2y(0); - v(1) = pplain(0) * h * e2x(1) + pplain(1) * h * e2y(1); - - p3d = p1 + v(0) * ey + v(1) * ez; - - Project (p3d); -} - -void splinetube :: Project (Point<3> & p3d) const -{ - Point<3> hp; - - hp = p3d; - middlecurve.ProjectToSpline (hp); - - p3d = hp + (r / Dist(p3d, hp)) * (p3d - hp); -} - - - -double splinetube :: CalcFunctionValue (const Point<3> & point) const -{ - Point<3> hcp; - double rad; - - hcp = point; - middlecurve.ProjectToSpline (hcp); - rad = Dist (hcp, point); - return 0.5 * (rad * rad / r - r); -} - -void splinetube :: CalcGradient (const Point<3> & point, Vec<3> & grad) const -{ - Point<3> hcp; - - hcp = point; - middlecurve.ProjectToSpline (hcp); - - grad = point - hcp; - grad /= r; -} - - - - -Point<3> splinetube :: GetSurfacePoint () const -{ - Point<3> p; - Vec<3> t, n; - - middlecurve.Evaluate (0, p); - middlecurve.EvaluateTangent (0, t); - n = t.GetNormal (); - n *= r; - (*mycout) << "p = " << p << " t = " << t << " n = " << n << endl; - return p + n; -} - -void splinetube :: Print (ostream & str) const -{ - int i; - str << "SplineTube, " - << middlecurve.GetNumSegments () << " segments, r = " << r << endl; - for (i = 1; i <= middlecurve.GetNumSegments(); i++) - str << middlecurve.P1(i) << " - " - << middlecurve.P2(i) << " - " - << middlecurve.P3(i) << endl; -} - - -int splinetube :: BoxInSolid (const BoxSphere<3> & box) const - // 0 .. no, 1 .. yes, 2 .. maybe -{ - Point<3> pc = box.Center(); - middlecurve.ProjectToSpline (pc); - double d = Dist (pc, box.Center()); - - if (d < r - box.Diam()/2) return 1; - if (d > r + box.Diam()/2) return 0; - return 2; -} -} diff --git a/Netgen/libsrc/csg/spline3d.hpp b/Netgen/libsrc/csg/spline3d.hpp deleted file mode 100644 index 753788459f..0000000000 --- a/Netgen/libsrc/csg/spline3d.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/// -class splinesegment3d - { - /// - Point<3> p1, p2, p3; - - public: - /// - splinesegment3d (const Point<3> & ap1, const Point<3> & ap2, - const Point<3> & ap3); - /// - void Evaluate (double t, Point<3> & p) const; - /// - void EvaluateTangent (double t, Vec<3> & tang) const; - /// - const Point<3> & P1() const { return p1; } - /// - const Point<3> & P2() const { return p2; } - /// - const Point<3> & P3() const { return p3; } - }; - -/// -class spline3d - { - /// - ARRAY<splinesegment3d *> segments; - - public: - /// - spline3d () { }; - /// - void AddSegment (const Point<3> & ap1, const Point<3> & ap2, const Point<3> & ap3); - /// - int GetNumSegments () const { return segments.Size(); } - /// - double ProjectToSpline (Point<3> & p) const; - /// - double ProjectToSpline (Point<3> & p, double t) const; - /// - void Evaluate (double t, Point<3> & p) const; - /// - void EvaluateTangent (double t, Vec<3> & tang) const; - /// - const Point<3> & P1(int i) const { return segments.Get(i)->P1(); } - /// - const Point<3> & P2(int i) const { return segments.Get(i)->P2(); } - /// - const Point<3> & P3(int i) const { return segments.Get(i)->P3(); } - }; - -/// -class splinetube : public Surface - { - /// - const spline3d & middlecurve; - /// - double r; -/// Vec<3> ex, ey, ez; - Vec<2> e2x, e2y; - /// - Point<3> cp; - - public: - /// - splinetube (const spline3d & amiddlecurve, double ar); - - /// - virtual void DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2); - /// - virtual void ToPlane (const Point<3> & p, Point<2> & pplain, double h, int & zone) const; - /// - virtual void FromPlane (const Point<2> & pplain, Point<3> & p, double h) const; - /// - virtual void Project (Point<3> & p) const; - -// virtual int RootInBox (const box3d & box) const { return 0; } - /// 0 .. no, 1 .. yes, 2 .. maybe - - virtual int BoxInSolid (const BoxSphere<3> & box) const; - /// 0 .. no, 1 .. yes, 2 .. maybe - - virtual double CalcFunctionValue (const Point<3> & point) const; - /// - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; - /// - virtual double HesseNorm () const { return 0.5 / r; } - /// - virtual Point<3> GetSurfacePoint () const; - /// - virtual void Print (ostream & str) const; - }; diff --git a/Netgen/libsrc/csg/surface.cpp b/Netgen/libsrc/csg/surface.cpp deleted file mode 100644 index 8b8d58127a..0000000000 --- a/Netgen/libsrc/csg/surface.cpp +++ /dev/null @@ -1,392 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <csg.hpp> - -#include <linalg.hpp> -#include <meshing.hpp> - - -namespace netgen -{ -Surface :: Surface () -{ - maxh = 1e10; - name = new char[7]; - strcpy (name, "noname"); - bcprop = -1; -} - -Surface :: ~Surface() -{ - delete [] name; -} - - -void Surface :: SetName (const char * aname) -{ - delete [] name; - name = new char[strlen (aname)+1]; - strcpy (name, aname); -} - - -int Surface :: PointOnSurface (const Point<3> & p, - double eps) const -{ - double val = CalcFunctionValue (p); - return fabs (val) < eps; -} - - -void Surface :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const -{ - double dx = 1e-5; - Point<3> hp1, hp2; - Vec<3> g1, g2; - - for (int i = 0; i < 3; i++) - { - hp1 = point; - hp2 = point; - - hp1(i) += dx; - hp2(i) -= dx; - - CalcGradient (hp1, g1); - CalcGradient (hp2, g2); - - for (int j = 0; j < 3; j++) - hesse(i, j) = (g1(j) - g2(j)) / (2 * dx); - } -} - -/* -void Surface :: GetNormalVector (const Point<3> & p, Vec<3> & n) const -{ - CalcGradient (p, n); - n.Normalize(); -} -*/ -Vec<3> Surface :: GetNormalVector (const Point<3> & p) const -{ - Vec<3> n; - CalcGradient (p, n); - n.Normalize(); - return n; -} - -void Surface :: DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2) -{ - p1 = ap1; - p2 = ap2; - - ez = GetNormalVector (p1); - ex = p2 - p1; - ex -= (ex * ez) * ez; - ex.Normalize(); - ey = Cross (ez, ex); -} - -void Surface :: ToPlane (const Point<3> & p3d, Point<2> & pplane, - double h, int & zone) const -{ - Vec<3> p1p, n; - - n = GetNormalVector (p3d); - if (n * ez < 0) - { - zone = -1; - pplane(0) = 1e8; - pplane(1) = 1e9; - return; - } - - p1p = p3d - p1; - pplane(0) = (p1p * ex) / h; - pplane(1) = (p1p * ey) / h; - zone = 0; -} - -void Surface :: FromPlane (const Point<2> & pplane, - Point<3> & p3d, double h) const -{ - p3d = p1 - + (h * pplane(0)) * ex - + (h * pplane(1)) * ey; - - Project (p3d); -} - -void Surface :: Project (Point<3> & p) const -{ - Vec<3> n; - double val; - - for (int i = 1; i <= 10; i++) - { - val = CalcFunctionValue (p); - if (fabs (val) < 1e-12) return; - - CalcGradient (p, n); - p -= (val / Abs2 (n)) * n; - } -} - -double Surface :: MaxCurvature () const -{ - return 0.5 * HesseNorm (); -} - -double Surface :: -MaxCurvatureLoc (const Point<3> & /* c */ , double /* rad */) const -{ - return MaxCurvature (); -} - - - -double Surface :: LocH (const Point<3> & p, double x, - double c, double hmax) const - // finds h <= hmax, s.t. h * \kappa_x*h < c -{ - /* - double h, hmin, kappa; - hmin = 0; - - while (hmin < 0.9 * hmax) - { - h = 0.5 * (hmin + hmax); - kappa = 2 * MaxCurvatureLoc (p, x * h); - - if (kappa * h >= c) - hmax = h; - else - hmin = h; - } - return h; - */ - - double hret; - double kappa = MaxCurvatureLoc (p, x*hmax); - - kappa *= c * mparam.curvaturesafety; - - if (hmax * kappa < 1) - hret = hmax; - else - hret = 1 / kappa; - - if (maxh < hret) - hret = maxh; - - return hret; -} - - - - -Primitive :: Primitive () -{ - surfaceids.SetSize (1); - surfaceactive.SetSize (1); - surfaceactive[0] = 1; -} - -Primitive :: ~Primitive() -{ - ; -} - -int Primitive :: GetSurfaceId (int i) const -{ - return surfaceids[i]; -} - -void Primitive :: SetSurfaceId (int i, int id) -{ - surfaceids[i] = id; -} - - - - -void Primitive :: GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const -{ - classname = "undef"; - coeffs.SetSize (0); -} - -void Primitive :: SetPrimitiveData (ARRAY<double> & coeffs) -{ - ; -} - -Primitive * Primitive :: CreatePrimitive (const char * classname) -{ - if (strcmp (classname, "sphere") == 0) - return Sphere::CreateDefault(); - if (strcmp (classname, "plane") == 0) - return Plane::CreateDefault(); - if (strcmp (classname, "cylinder") == 0) - return Cylinder::CreateDefault(); - if (strcmp (classname, "cone") == 0) - return Cone::CreateDefault(); - if (strcmp (classname, "brick") == 0) - return Brick::CreateDefault(); - - cout << "cannot create primitive " << classname << endl; - return NULL; -} - - -Primitive * Primitive :: Copy () const -{ - cout << "Primitive called for baseclass" << endl; - return NULL; -} - - -void Primitive :: Transform (Transformation<3> & trans) -{ - cout << "transform called for baseclass" << endl; -} - - -INSOLID_TYPE Primitive :: -VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const -{ - Point<3> hp = p + 1e-3 * v1 + 1e-5 * v2; - - INSOLID_TYPE res = PointInSolid (hp, eps); - // (*testout) << "vectorin2, type = " << typeid(*this).name() << ", res = " << res << endl; - - return res; -} - - - - - - -OneSurfacePrimitive :: OneSurfacePrimitive() -{ - ; -} - -OneSurfacePrimitive :: ~OneSurfacePrimitive() -{ - ; -} - - -INSOLID_TYPE OneSurfacePrimitive :: -PointInSolid (const Point<3> & p, - double eps) const -{ - double hv1 = (GetSurface(0).CalcFunctionValue(p)); - if (hv1 <= -eps) - return IS_INSIDE; - if (hv1 >= eps) - return IS_OUTSIDE; - return DOES_INTERSECT; -} - -INSOLID_TYPE OneSurfacePrimitive :: -VecInSolid (const Point<3> & p, const Vec<3> & v, - double eps) const -{ - Vec<3> hv; - double hv1; - GetSurface(0).CalcGradient (p, hv); - - hv1 = v * hv; - - if (hv1 <= -eps) - return IS_INSIDE; - if (hv1 >= eps) - return IS_OUTSIDE; - - return DOES_INTERSECT; -} - - -INSOLID_TYPE OneSurfacePrimitive :: -VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const -{ - Vec<3> hv; - double hv1, hv2; - - GetSurface(0).CalcGradient (p, hv); - - hv1 = v1 * hv; - if (hv1 <= -eps) - return IS_INSIDE; - if (hv1 >= eps) - return IS_OUTSIDE; - - hv2 = v2 * hv; - if (hv2 <= 0) - return IS_INSIDE; - else - return IS_OUTSIDE; -} - - - - -int OneSurfacePrimitive :: GetNSurfaces() const -{ - return 1; -} - -Surface & OneSurfacePrimitive :: GetSurface (int i) -{ - return *this; -} - -const Surface & OneSurfacePrimitive :: GetSurface (int i) const -{ - return *this; -} - - - - - - -void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp) -{ - Vec<2> rs, lam; - Vec<3> a1, a2; - Mat<2> a; - - int i = 10; - while (i > 0) - { - i--; - rs(0) = f1 -> CalcFunctionValue (hp); - rs(1) = f2 -> CalcFunctionValue (hp); - f1->CalcGradient (hp, a1); - f2->CalcGradient (hp, a2); - - a(0,0) = a1 * a1; - a(0,1) = a(1,0) = a1 * a2; - a(1,1) = a2 * a2; - - a.Solve (rs, lam); - - hp -= lam(0) * a1 + lam(1) * a2; - - if (Abs2 (rs) < 1e-24 && i > 1) i = 1; - } -} -} diff --git a/Netgen/libsrc/csg/surface.hpp b/Netgen/libsrc/csg/surface.hpp deleted file mode 100644 index db0b4a74d2..0000000000 --- a/Netgen/libsrc/csg/surface.hpp +++ /dev/null @@ -1,301 +0,0 @@ -#ifndef FILE_SURFACE -#define FILE_SURFACE - -/**************************************************************************/ -/* File: surface.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 1. Dez. 95 */ -/**************************************************************************/ - - - - -// class DenseMatrix; -// class Box3dSphere; -class TriangleApproximation; - -/** - Basis class for implicit surface geometry. - This class is used for generation of surface meshes - in NETGEN as well as for mesh refinement in FEPP. - */ - - - - -class Surface -{ -protected: - /// invert normal vector - bool inverse; - /// maximal h in surface - double maxh; - /// name of surface - char * name; - /// boundary condition nr - int bcprop; - /// - -public: - Surface (); - /** @name Tangential plane. - The tangential plane is used for surface mesh generation. - */ - - virtual ~Surface(); - -protected: - /** @name Points in the surface defining tangential plane. - Tangential plane is taken in p1, the local x-axis - is directed to p2. - */ - //@{ - /// - Point<3> p1; - /// - Point<3> p2; - //@} - /** @name Base-vectos for local coordinate system. */ - //@{ - /// in plane, directed p1->p2 - Vec<3> ex; - /// in plane - Vec<3> ey; - /// outer normal direction - Vec<3> ez; - //@} -public: - - void SetName (const char * aname); - const char * Name () const { return name; } - - //@{ - /** - Defines tangential plane in ap1. - The local x-coordinate axis point to the direction of ap2 */ - virtual void DefineTangentialPlane (const Point<3> & ap1, - const Point<3> & ap2); - - /// Transforms 3d point p3d to local coordinates pplane - virtual void ToPlane (const Point<3> & p3d, Point<2> & pplane, - double h, int & zone) const; - - /// Transforms point pplane in local coordinates to 3d point - virtual void FromPlane (const Point<2> & pplane, - Point<3> & p3d, double h) const; - //@} - - - /// Move Point p to closes point in surface - virtual void Project (Point<3> & p) const; - - - virtual int IsIdentic (const Surface & /* s2 */, int & /* inv */, - double /* eps */) const - { return 0; } - - /// - virtual int PointOnSurface (const Point<3> & p, - double eps = 1e-6) const; - - - /** @name Implicit function. - Calculate function value and derivatives. - */ - //@{ - /// Calculate implicit function value in point point - virtual double CalcFunctionValue (const Point<3> & point) const = 0; - - /** - Calc gradient of implicit function. - gradient should be O(1) at surface - */ - virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const = 0; - - /** - Calculate second derivatives of implicit function. - */ - virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; - - /** - Returns outer normal vector. - */ - // virtual void GetNormalVector (const Point<3> & p, Vec<3> & n) const; - virtual Vec<3> GetNormalVector (const Point<3> & p) const; - - /** - Upper bound for spectral norm of Hesse-matrix - */ - virtual double HesseNorm () const = 0; - - /** - Upper bound for spectral norm of Hesse-matrix in the - rad - environment of point c. - */ - virtual double HesseNormLoc (const Point<3> & /* c */, - double /* rad */) const - { return HesseNorm (); } - //@} - - - /// - virtual double MaxCurvature () const; - /// - virtual double MaxCurvatureLoc (const Point<3> & /* c */ , - double /* rad */) const; - - /** Returns any point in the surface. - Needed to start surface mesh generation e.g. on sphere */ - virtual Point<3> GetSurfacePoint () const = 0; - - /// - bool Inverse () const { return inverse; } - /// - void SetInverse (bool ainverse) { inverse = ainverse; } - /// - virtual void Print (ostream & str) const = 0; - - /// - virtual void Reduce (const BoxSphere<3> & /* box */) { }; - /// - virtual void UnReduce () { }; - - /// set max h in surface - void SetMaxH (double amaxh) { maxh = amaxh; } - /// - double GetMaxH () const { return maxh; } - /// - int GetBCProperty () const { return bcprop; } - /// - void SetBCProperty (int abc) { bcprop = abc; } - - /** Determine local mesh-size. - Find - \[ h \leq hmax, \] - such that - \[ h \times \kappa (x) \leq c \qquad \mbox{in} B(x, h), \] - where kappa(x) is the curvature in x. */ - virtual double LocH (const Point<3> & p, double x, - double c, double hmax) const; - - /** - Gets Approximation by triangles, - where qual is about the number of triangles per radius - */ - virtual void GetTriangleApproximation (TriangleApproximation & /* tas */, - const Box<3> & /* boundingbox */, - double /* facets */ ) const { }; - -#ifdef MYGRAPH - /// - virtual void Plot (const class ROT3D & /* rot */) const { }; -#endif - }; - - -typedef enum { IS_OUTSIDE = 0, IS_INSIDE = 1, DOES_INTERSECT = 2} -INSOLID_TYPE; - - - - -class Primitive -{ - -public: - - Primitive (); - - virtual ~Primitive(); - - - /* - Check, whether box intersects solid defined by surface. - - return values: - 0 .. box outside solid \\ - 1 .. box in solid \\ - 2 .. can't decide (allowed, iff box is close to solid) - */ - virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const = 0; - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const = 0; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const = 0; - - // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid - virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const; - - - virtual int GetNSurfaces() const = 0; - virtual Surface & GetSurface (int i = 0) = 0; - virtual const Surface & GetSurface (int i = 0) const = 0; - - ARRAY<int> surfaceids; - ARRAY<int> surfaceactive; - - int GetSurfaceId (int i = 0) const; - void SetSurfaceId (int i, int id); - int SurfaceActive (int i) const { return surfaceactive[i]; } - virtual int SurfaceInverted (int i = 0) const { return 0; } - - virtual void GetPrimitiveData (char *& classname, - ARRAY<double> & coeffs) const; - virtual void SetPrimitiveData (ARRAY<double> & coeffs); - static Primitive * CreatePrimitive (const char * classname); - - - virtual void Reduce (const BoxSphere<3> & /* box */) { }; - virtual void UnReduce () { }; - - virtual Primitive * Copy () const; - virtual void Transform (Transformation<3> & trans); -}; - - - - -class OneSurfacePrimitive : public Surface, public Primitive -{ -public: - OneSurfacePrimitive(); - ~OneSurfacePrimitive(); - - virtual INSOLID_TYPE PointInSolid (const Point<3> & p, - double eps) const; - virtual INSOLID_TYPE VecInSolid (const Point<3> & p, - const Vec<3> & v, - double eps) const; - virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, - const Vec<3> & v1, - const Vec<3> & v2, - double eps) const; - - - virtual int GetNSurfaces() const; - virtual Surface & GetSurface (int i = 0); - virtual const Surface & GetSurface (int i = 0) const; -}; - - - - - - -/** - Projects point to edge. - The point hp is projected to the edge descibed by f1 and f2. - It is assumed that the edge is non-degenerated, and the - (generalized) Newton method converges. - */ -extern void ProjectToEdge (const Surface * f1, - const Surface * f2, - Point<3> & hp); - - - -#endif diff --git a/Netgen/libsrc/csg/triapprox.cpp b/Netgen/libsrc/csg/triapprox.cpp deleted file mode 100644 index 403716155b..0000000000 --- a/Netgen/libsrc/csg/triapprox.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> - - -namespace netgen -{ - - TriangleApproximation :: TriangleApproximation () - { - ; - } - - int TriangleApproximation :: - AddTriangle (const TATriangle & tri, bool invert) - { - trigs.Append (tri); - if (invert) - { - trigs.Last()[1] = tri[2]; - trigs.Last()[2] = tri[1]; - } - return trigs.Size()-1; - } - - - void TriangleApproximation :: RemoveUnusedPoints () - { - BitArray used(GetNP()); - ARRAY<int> map (GetNP()); - int i, j; - int cnt = 0; - - used.Clear(); - for (i = 0; i < GetNT(); i++) - for (j = 0; j < 3; j++) - used.Set (GetTriangle (i)[j]); - - for (i = 0; i < GetNP(); i++) - if (used.Test(i)) - map[i] = cnt++; - - for (i = 0; i < GetNT(); i++) - for (j = 0; j < 3; j++) - trigs[i][j] = map[trigs[i][j]]; - - for (i = 0; i < GetNP(); i++) - if (used.Test(i)) - { - points[map[i]] = points[i]; - normals[map[i]] = normals[i]; - } - - points.SetSize (cnt); - normals.SetSize (cnt); - } -} diff --git a/Netgen/libsrc/csg/triapprox.hpp b/Netgen/libsrc/csg/triapprox.hpp deleted file mode 100644 index 7b2db16b09..0000000000 --- a/Netgen/libsrc/csg/triapprox.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef FILE_TRIAPPROX -#define FILE_TRIAPPROX - -/**************************************************************************/ -/* File: triapprox.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 2. Mar. 98 */ -/**************************************************************************/ - -/** - Triangulated approxiamtion to true surface -*/ - - -class TATriangle -{ - int pi[3]; - int surfind; -public: - TATriangle () { ; } - - TATriangle (int si, int pi1, int pi2, int pi3) - { surfind = si; pi[0] = pi1; pi[1] = pi2; pi[2] = pi3; } - - int SurfaceIndex() const { return surfind; } - int & SurfaceIndex() { return surfind; } - - int & operator[] (int i) { return pi[i]; } - const int & operator[] (int i) const { return pi[i]; } -}; - - -class TriangleApproximation -{ - ARRAY<Point<3> > points; - ARRAY<Vec<3> > normals; - ARRAY<TATriangle> trigs; - -public: - TriangleApproximation(); - int GetNP () const { return points.Size(); } - int GetNT () const { return trigs.Size(); } - - int AddPoint (const Point<3> & p) { points.Append (p); return points.Size()-1; } - int AddNormal (const Vec<3> & n) { normals.Append (n); return normals.Size()-1; } - int AddTriangle (const TATriangle & tri, bool invert = 0); - - const Point<3> & GetPoint (int i) const { return points[i]; } - const TATriangle & GetTriangle (int i) const { return trigs[i]; } - const Vec<3> & GetNormal (int i) const { return normals[i]; } - - void RemoveUnusedPoints (); - - friend class CSGeometry; -}; - -#endif diff --git a/Netgen/libsrc/general/Makefile b/Netgen/libsrc/general/Makefile deleted file mode 100644 index 65a387a844..0000000000 --- a/Netgen/libsrc/general/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for general purpose data types -# -src = array.cpp bitarray.cpp hashtabl.cpp symbolta.cpp table.cpp flags.cpp \ - spbita2d.cpp seti.cpp optmem.cpp sort.cpp mystring.cpp parthreads.cpp \ - moveablemem.cpp dynamicmem.cpp ngexception.cpp -# -lib = gen -libpath = libsrc/general -# -include ../makefile.inc - diff --git a/Netgen/libsrc/general/array.cpp b/Netgen/libsrc/general/array.cpp deleted file mode 100644 index e3bc3e6fdf..0000000000 --- a/Netgen/libsrc/general/array.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef FILE_NGSTD_ARRAYCPP -#define FILE_NGSTD_ARRAYCPP -// necessary for SGI ???? - -/**************************************************************************/ -/* File: array.cpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - Abstract data type ARRAY -*/ - -#include <mystdlib.h> -#include <myadt.hpp> -#include <assert.h> - - -namespace netgen -{ - using namespace netgen; - -#ifdef NONE - void BASE_ARRAY :: ReSize (int minsize, int elementsize) - { - cout << "resize, minsize = " << minsize << endl; - - if (inc == -1) - throw Exception ("Try to resize fixed size array"); - - - void * p; - int nsize = (inc) ? allocsize + inc : 2 * allocsize; - if (nsize < minsize) nsize = minsize; - - if (data) - { - p = new char [nsize * elementsize]; - - int mins = (nsize < actsize) ? nsize : actsize; - memcpy (p, data, mins * elementsize); - - delete [] static_cast<char*> (data); - data = p; - } - else - { - data = new char[nsize * elementsize]; - } - - allocsize = nsize; - cout << "resize done" << endl; - } - - - - void BASE_ARRAY :: RangeCheck (int i) const - { - if (i < 0 || i >= actsize) - throw ArrayRangeException (); - } - - void BASE_ARRAY :: CheckNonEmpty () const - { - if (!actsize) - { - throw Exception ("Array should not be empty"); - // cerr << "Array souldn't be empty"; - } - } -#endif -} -#endif - diff --git a/Netgen/libsrc/general/array.hpp b/Netgen/libsrc/general/array.hpp deleted file mode 100644 index c953cedeff..0000000000 --- a/Netgen/libsrc/general/array.hpp +++ /dev/null @@ -1,478 +0,0 @@ -#ifndef FILE_ARRAY -#define FILE_ARRAY - -/**************************************************************************/ -/* File: array.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - - -/** - A simple array container. - Array represented by size and data-pointer. - No memory allocation and deallocation, must be provided by user. - Helper functions for printing. - Optional range check by macro RANGE_CHECK - */ - -template <class T, int BASE = 0> -class FlatArray -{ -protected: - /// the size - int size; - /// the data - T * data; -public: - - /// provide size and memory - inline FlatArray (int asize, T * adata) - : size(asize), data(adata) { ; } - - /// the size - inline int Size() const { return size; } - - - /// access array. - inline T & operator[] (int i) - { -#ifdef DEBUG - if (i-BASE < 0 || i-BASE >= size) - cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; -#endif - - return data[i-BASE]; - } - - - /// Access array. - inline const T & operator[] (int i) const - { -#ifdef DEBUG - if (i-BASE < 0 || i-BASE >= size) - cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; -#endif - - return data[i-BASE]; - } - - /// - T & Elem (int i) - { -#ifdef DEBUG - if (i < 1 || i > size) - cout << "ARRAY<" << typeid(T).name() - << ">::Elem out of range, i = " << i - << ", s = " << size << endl; -#endif - - return ((T*)data)[i-1]; - } - - /// - const T & Get (int i) const - { -#ifdef DEBUG - if (i < 1 || i > size) - cout << "ARRAY<" << typeid(T).name() << ">::Get out of range, i = " << i - << ", s = " << size << endl; -#endif - - return ((const T*)data)[i-1]; - } - - /// - void Set (int i, const T & el) - { -#ifdef DEBUG - if (i < 1 || i > size) - cout << "ARRAY<" << typeid(T).name() << ">::Set out of range, i = " << i - << ", s = " << size << endl; -#endif - - ((T*)data)[i-1] = el; - } - - - /// access last element. check by macro CHECK_RANGE - T & Last () - { - return data[size-1]; - } - - /// access last element. check by macro CHECK_RANGE - const T & Last () const - { - return data[size-1]; - } - - /// Fill array with value val - FlatArray & operator= (const T & val) - { - for (int i = 0; i < size; i++) - data[i] = val; - return *this; - } -}; - - - - -// print array -template <class T, int BASE> -inline ostream & operator<< (ostream & s, const FlatArray<T,BASE> & a) -{ - for (int i = BASE; i < a.Size()+BASE; i++) - s << i << ": " << a[i] << endl; - return s; -} - - - - -/** - Dynamic array container. - - ARRAY<T> is an automatically increasing array container. - The allocated memory doubles on overflow. - Either the container takes care of memory allocation and deallocation, - or the user provides one block of data. -*/ -template <class T, int BASE = 0> -class ARRAY : public FlatArray<T, BASE> -{ -protected: - /// physical size of array - int allocsize; - /// memory is responsibility of container - bool ownmem; - -public: - - /// Generate array of logical and physical size asize - explicit ARRAY(int asize = 0) - : FlatArray<T, BASE> (asize, asize ? new T[asize] : 0) - { - allocsize = asize; - ownmem = 1; - } - - /// Generate array in user data - ARRAY(int asize, T* adata) - : FlatArray<T, BASE> (asize, adata) - { - allocsize = asize; - ownmem = 0; - } - - /// array copy - explicit ARRAY (const ARRAY<T> & a2) - : FlatArray<T, BASE> (a2.Size(), a2.Size() ? new T[a2.Size()] : 0) - { - allocsize = this->size; - ownmem = 1; - for (int i = BASE; i < this->size+BASE; i++) - (*this)[i] = a2[i]; - } - - - - /// if responsible, deletes memory - ~ARRAY() - { - if (ownmem) - delete [] this->data; - } - - /// Change logical size. If necessary, do reallocation. Keeps contents. - void SetSize(int nsize) - { - if (nsize > allocsize) - ReSize (nsize); - this->size = nsize; - } - - /// Change physical size. Keeps logical size. Keeps contents. - void SetAllocSize (int nallocsize) - { - if (nallocsize > allocsize) - ReSize (nallocsize); - } - - - /// Add element at end of array. reallocation if necessary. - int Append (const T & el) - { - if (this->size == allocsize) - ReSize (this->size+1); - this->data[this->size] = el; - this->size++; - return this->size; - } - - - /// Delete element i (0-based). Move last element to position i. - void Delete (int i) - { -#ifdef CHECK_ARRAY_RANGE - RangeCheck (i+1); -#endif - - this->data[i] = this->data[this->size-1]; - this->size--; - // DeleteElement (i+1); - } - - - /// Delete element i (1-based). Move last element to position i. - void DeleteElement (int i) - { -#ifdef CHECK_ARRAY_RANGE - RangeCheck (i); -#endif - - this->data[i-1] = this->data[this->size-1]; - this->size--; - } - - /// Delete last element. - void DeleteLast () - { - this->size--; - } - - /// Deallocate memory - void DeleteAll () - { - if (ownmem) - delete [] this->data; - this->data = 0; - this->size = allocsize = 0; - } - - /// Fill array with val - ARRAY & operator= (const T & val) - { - FlatArray<T, BASE>::operator= (val); - return *this; - } - - /// array copy - ARRAY & operator= (const ARRAY & a2) - { - SetSize (a2.Size()); - for (int i = BASE; i < this->size+BASE; i++) - (*this)[i] = a2[i]; - return *this; - } - -private: - - /// resize array, at least to size minsize. copy contents - void ReSize (int minsize) - { - int nsize = 2 * allocsize; - if (nsize < minsize) nsize = minsize; - - if (this->data) - { - T * p = new T[nsize]; - - int mins = (nsize < this->size) ? nsize : this->size; - memcpy (p, this->data, mins * sizeof(T)); - - if (ownmem) - delete [] this->data; - ownmem = 1; - this->data = p; - } - else - { - this->data = new T[nsize]; - ownmem = 1; - } - - allocsize = nsize; - } -}; - - - -template <class T, int S> -class ArrayMem : public ARRAY<T> -{ - // T mem[S]; - // char mem[S*sizeof(T)]; - double mem[(S*sizeof(T)+7) / 8]; -public: - /// Generate array of logical and physical size asize - explicit ArrayMem(int asize = 0) - : ARRAY<T> (S, static_cast<T*> (static_cast<void*>(&mem[0]))) - { - this->SetSize (asize); - } - - ArrayMem & operator= (const T & val) - { - ARRAY<T>::operator= (val); - return *this; - } -}; - - - - - - - - - - - -/// -template <class T> class MoveableArray -{ - int size; - int allocsize; - MoveableMem<T> data; - -public: - - MoveableArray() - { - size = allocsize = 0; - data.SetName ("MoveableArray"); - } - - MoveableArray(int asize) - : size(asize), allocsize(asize), data(asize) - { ; } - - ~MoveableArray () { ; } - - int Size() const { return size; } - - void SetSize(int nsize) - { - if (nsize > allocsize) - { - data.ReAlloc (nsize); - allocsize = nsize; - } - size = nsize; - } - - void SetAllocSize (int nallocsize) - { - data.ReAlloc (nallocsize); - allocsize = nallocsize; - } - - /// - T & operator[] (int i) - { return ((T*)data)[i]; } - - /// - const T & operator[] (int i) const - { return ((const T*)data)[i]; } - - /// - T & Elem (int i) - { return ((T*)data)[i-1]; } - - /// - const T & Get (int i) const - { return ((const T*)data)[i-1]; } - - /// - void Set (int i, const T & el) - { ((T*)data)[i-1] = el; } - - /// - T & Last () - { return ((T*)data)[size-1]; } - - /// - const T & Last () const - { return ((const T*)data)[size-1]; } - - /// - int Append (const T & el) - { - if (size == allocsize) - { - SetAllocSize (2*allocsize+1); - } - ((T*)data)[size] = el; - size++; - return size; - } - - /// - void Delete (int i) - { - DeleteElement (i+1); - } - - /// - void DeleteElement (int i) - { - ((T*)data)[i-1] = ((T*)data)[size-1]; - size--; - } - - /// - void DeleteLast () - { size--; } - - /// - void DeleteAll () - { - size = allocsize = 0; - data.Free(); - } - - /// - void PrintMemInfo (ostream & ost) const - { - ost << Size() << " elements of size " << sizeof(T) << " = " - << Size() * sizeof(T) << endl; - } - - MoveableArray & operator= (const T & el) - { - for (int i = 0; i < size; i++) - ((T*)data)[i] = el; - return *this; - } - - void SetName (char * aname) - { - data.SetName(aname); - } -private: - /// - MoveableArray & operator= (MoveableArray &); - /// - MoveableArray (const MoveableArray &); -}; - - -template <class T> -inline ostream & operator<< (ostream & ost, MoveableArray<T> & a) -{ - for (int i = 0; i < a.Size(); i++) - ost << i << ": " << a[i] << endl; - return ost; -} - - - - - - - - -#endif - diff --git a/Netgen/libsrc/general/autoptr.hpp b/Netgen/libsrc/general/autoptr.hpp deleted file mode 100644 index b90841408b..0000000000 --- a/Netgen/libsrc/general/autoptr.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef FILE_AUTOPTR -#define FILE_AUTOPTR - -/**************************************************************************/ -/* File: autoptr.hpp */ -/* Author: STL, Joachim Schoeberl */ -/* Date: 29. Dec. 02 */ -/**************************************************************************/ - -template <typename T> -class AutoPtr -{ -private: - T * ptr; -public: - typedef T* pT; - explicit AutoPtr (T * p = 0) { ptr = p; } - ~AutoPtr () { delete ptr; } - - T & operator*() const { return *ptr; } - T* operator->() const { return ptr; } - T *& Ptr() { return ptr; } - T * Ptr() const { return ptr; } - void Reset(T * p = 0) { if (p != ptr) { delete ptr; ptr = p; } } - operator bool () { return ptr != 0; } -private: - AutoPtr (AutoPtr &) { ; } - AutoPtr & operator= (AutoPtr &) { ; } -}; - -#endif diff --git a/Netgen/libsrc/general/bitarray.cpp b/Netgen/libsrc/general/bitarray.cpp deleted file mode 100644 index 0d03fd5c45..0000000000 --- a/Netgen/libsrc/general/bitarray.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************/ -/* File: bitarray.cc */ -/* Autho: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - data type BitArray -*/ - -#include <mystdlib.h> -#include <myadt.hpp> - - -namespace netgen -{ - using namespace netgen; - - BitArray :: BitArray () - { - size = 0; - data = NULL; - } - - BitArray :: BitArray (int asize) - { - size = 0; - data = NULL; - SetSize (asize); - } - - BitArray :: ~BitArray () - { - delete [] data; - } - - void BitArray :: SetSize (int asize) - { - if (size == asize) return; - delete [] data; - - size = asize; - data = new unsigned char [Addr (size)+1]; - } - - void BitArray :: Set () - { - if (!size) return; - for (int i = 0; i <= Addr (size); i++) - data[i] = UCHAR_MAX; - } - - void BitArray :: Clear () - { - if (!size) return; - for (int i = 0; i <= Addr (size); i++) - data[i] = 0; - } - - - - void BitArray :: Invert () - { - if (!size) return; - for (int i = 0; i <= Addr (size); i++) - data[i] ^= 255; - } - - void BitArray :: And (const BitArray & ba2) - { - if (!size) return; - for (int i = 0; i <= Addr (size); i++) - data[i] &= ba2.data[i]; - } - - - void BitArray :: Or (const BitArray & ba2) - { - if (!size) return; - for (int i = 0; i <= Addr (size); i++) - data[i] |= ba2.data[i]; - } - - - - - - - - - - - - template <int BASE> - void BitArrayChar<BASE> :: Set () - { - data = 1; - } - - template <int BASE> - void BitArrayChar<BASE> :: Clear () - { - data = 0; - } - - - template <int BASE> - void BitArrayChar<BASE> :: Invert () - { - for (int i = BASE; i < data.Size()+BASE; i++) - data[i] = 1 - data[i]; - } - - template <int BASE> - void BitArrayChar<BASE> :: And (const BitArrayChar & ba2) - { - for (int i = BASE; i < data.Size()+BASE; i++) - data[i] &= ba2.data[i]; - } - - - template <int BASE> - void BitArrayChar<BASE> :: Or (const BitArrayChar & ba2) - { - for (int i = BASE; i < data.Size()+BASE; i++) - data[i] |= ba2.data[i]; - } - - - template class BitArrayChar<0>; - template class BitArrayChar<1>; -} diff --git a/Netgen/libsrc/general/bitarray.hpp b/Netgen/libsrc/general/bitarray.hpp deleted file mode 100644 index 1b7042fa5a..0000000000 --- a/Netgen/libsrc/general/bitarray.hpp +++ /dev/null @@ -1,207 +0,0 @@ -#ifndef FILE_BitArray -#define FILE_BitArray - -/**************************************************************************/ -/* File: bitarray.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -#include <limits.h> - -/** - data type BitArray - - BitArray is a compressed array of Boolean information. By Set and Clear - the whole array or one bit can be set or reset, respectively. - Test returns the state of the accoring bit. - No range checking is done. - - index ranges from 0 to size-1 -*/ -class BitArray -{ - /// - INDEX size; - /// - unsigned char * data; - -public: - /// - BitArray (); - /// - BitArray (INDEX asize); - /// - ~BitArray (); - - /// - void SetSize (INDEX asize); - /// - inline INDEX Size () const; - - /// - void Set (); - /// - inline void Set (INDEX i); - /// - void Clear (); - /// - inline void Clear (INDEX i); - /// - inline int Test (INDEX i) const; - /// - void Invert (); - /// - void And (const BitArray & ba2); - /// - void Or (const BitArray & ba2); -private: - /// - inline unsigned char Mask (INDEX i) const; - /// - inline INDEX Addr (INDEX i) const; - - /// - BitArray & operator= (BitArray &); - /// - BitArray (const BitArray &); -}; - - - - - -// print bitarray -inline ostream & operator<< (ostream & s, const BitArray & a) -{ - for (int i = 1; i <= a.Size(); i++) - { - s << a.Test(i); - if (i % 40 == 0) s << "\n"; - } - if (a.Size() % 40 != 0) s << "\n"; - return s; -} - - - -inline -INDEX BitArray :: Size () const - { - return size; - } - -inline -unsigned char BitArray :: Mask (INDEX i) const - { - return char(1) << (i % CHAR_BIT); - } - -inline -INDEX BitArray :: Addr (INDEX i) const - { - return (i / CHAR_BIT); - } - -inline -void BitArray :: Set (INDEX i) - { - data[Addr(i)] |= Mask(i); - } - -inline -void BitArray :: Clear (INDEX i) - { - data[Addr(i)] &= ~Mask(i); - } - -inline -int BitArray :: Test (INDEX i) const - { - return (data[i / CHAR_BIT] & (char(1) << (i % CHAR_BIT) ) ) ? 1 : 0; - } - - - - - - - - -/** - data type BitArrayChar - - BitArray is an array of Boolean information. By Set and Clear - the whole array or one bit can be set or reset, respectively. - Test returns the state of the accoring bit. - No range checking is done. -*/ -template <int BASE = 1> -class BitArrayChar -{ - /// - ARRAY<char,BASE> data; - -public: - /// - BitArrayChar () - { ; } - /// - BitArrayChar (int asize) - : data(asize) - { ; } - /// - ~BitArrayChar () - { ; } - - /// - void SetSize (int asize) - { data.SetSize(asize); } - - /// - inline int Size () const - { return data.Size(); } - - /// - void Set (); - /// - inline void Set (int i) - { data[i] = 1; } - /// - void Clear (); - /// - inline void Clear (int i) - { data[i] = 0; } - /// - inline int Test (int i) const - { return data[i]; } - /// - void Invert (); - /// - void And (const BitArrayChar & ba2); - /// - void Or (const BitArrayChar & ba2); -private: - /// copy bitarray is not supported - BitArrayChar & operator= (BitArrayChar &) { return *this; } - /// copy bitarray is not supported - BitArrayChar (const BitArrayChar &) { ; } -}; - - - - -template <int BASE> -inline ostream & operator<< (ostream & s, const BitArrayChar<BASE> & a) -{ - for (int i = BASE; i < a.Size()+BASE; i++) - { - s << a.Test(i); - if ( (i-BASE) % 40 == 39) s << "\n"; - } - if (a.Size() % 40 != 0) s << "\n"; - return s; -} - - -#endif diff --git a/Netgen/libsrc/general/dynamicmem.cpp b/Netgen/libsrc/general/dynamicmem.cpp deleted file mode 100644 index 66b22cb4a7..0000000000 --- a/Netgen/libsrc/general/dynamicmem.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include <iostream> -#include <iomanip> - -#include <myadt.hpp> -using namespace std; - -namespace netgen -{ - -BaseDynamicMem * BaseDynamicMem::first = 0; -BaseDynamicMem * BaseDynamicMem::last = 0; - - -BaseDynamicMem :: BaseDynamicMem () -{ - prev = last; - next = 0; - - if (last) last->next = this; - last = this; - if (!first) first = this; - - size = 0; - ptr = 0; - name = 0; -} - -BaseDynamicMem :: ~BaseDynamicMem () -{ - Free(); - - if (next) next->prev = prev; - else last = prev; - if (prev) prev->next = next; - else first = next; - - delete [] name; -} - -void BaseDynamicMem :: SetName (const char * aname) -{ - delete [] name; - if (aname) - { - name = new char[strlen(aname)+1]; - strcpy (name, aname); - } -} - - -void BaseDynamicMem :: Alloc (size_t s) -{ - size = s; - // ptr = new char[s]; - ptr = (char*)malloc (s); -} - -void BaseDynamicMem :: ReAlloc (size_t s) -{ - if (size == s) return; - - char * old = ptr; - // ptr = new char[s]; - ptr = (char*)malloc(s); - memmove (ptr, old, (s < size) ? s : size); - // delete old; - free (old); - size = s; -} - -void BaseDynamicMem :: Free () -{ - // delete ptr; - free (ptr); - ptr = 0; -} - -void BaseDynamicMem :: Swap (BaseDynamicMem & m2) -{ - int hi; - char * cp; - hi = size; size = m2.size; m2.size = hi; - cp = ptr; ptr = m2.ptr; m2.ptr = cp; - cp = name; name = m2.name; m2.name = cp; -} - - -void BaseDynamicMem :: Print () -{ - cout << "****************** Dynamic Mem Report ****************" << endl; - BaseDynamicMem * p = first; - int mem = 0; - int cnt = 0; - while (p) - { - mem += p->size; - cnt++; - - cout << setw(10) << p->size << " Bytes"; - if (p->name) - cout << " in block " << p->name; - cout << endl; - - p = p->next; - } - - if (mem > 100000000) - cout << "memory in dynamic memory: " << mem/1048576 << " MB" << endl; - else if (mem > 100000) - cout << "memory in dynamic memory: " << mem/1024 << " kB" << endl; - else - cout << "memory in dynamic memory: " << mem << " Bytes" << endl; - cout << "number of blocks: " << cnt << endl; - // cout << "******************************************************" << endl; -} - -} diff --git a/Netgen/libsrc/general/dynamicmem.hpp b/Netgen/libsrc/general/dynamicmem.hpp deleted file mode 100644 index 501020988e..0000000000 --- a/Netgen/libsrc/general/dynamicmem.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef FILE_DYNAMICMEM -#define FILE_DYNAMICMEM - -/**************************************************************************/ -/* File: dynamicmem.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 12. Feb. 2003 */ -/**************************************************************************/ - - - - -class BaseDynamicMem -{ -private: - static BaseDynamicMem *first, *last; - - BaseDynamicMem *prev, *next; - size_t size; - char * ptr; - char * name; - -protected: - BaseDynamicMem (); - ~BaseDynamicMem (); - void Alloc (size_t s); - void ReAlloc (size_t s); - void Free (); - char * Ptr() { return ptr; } - const char * Ptr() const { return ptr; } - void Swap (BaseDynamicMem & m2); -public: - void SetName (const char * aname); - static void Print (); -}; - - -template <typename T> -class DynamicMem : public BaseDynamicMem -{ -public: - DynamicMem () - : BaseDynamicMem () - { - ; - } - DynamicMem (size_t s) - : BaseDynamicMem () - { - Alloc (s); - } - void Alloc (size_t s) - { - BaseDynamicMem::Alloc (sizeof(T) * s); - } - void ReAlloc (size_t s) - { - BaseDynamicMem::ReAlloc (sizeof(T) * s); - } - void Free () - { - BaseDynamicMem::Free (); - } - - const T * Ptr() const - { - return reinterpret_cast<const T*> (BaseDynamicMem::Ptr()); - } - - T * Ptr() - { - return reinterpret_cast<T*> (BaseDynamicMem::Ptr()); - } - - operator const T* () const - { - return reinterpret_cast<const T*> (BaseDynamicMem::Ptr()); - } - - operator T* () - { - return reinterpret_cast<T*> (BaseDynamicMem::Ptr()); - } - - void Swap (DynamicMem<T> & m2) - { - BaseDynamicMem::Swap (m2); - } -protected: - DynamicMem (const DynamicMem & m); - DynamicMem & operator= (const DynamicMem & m); -}; - -#endif diff --git a/Netgen/libsrc/general/flags.cpp b/Netgen/libsrc/general/flags.cpp deleted file mode 100644 index 9cce0cef2f..0000000000 --- a/Netgen/libsrc/general/flags.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************/ -/* File: flags.cc */ -/* Author: Joachim Schoeberl */ -/* Date: 10. Oct. 96 */ -/**************************************************************************/ - -/* - Datatype Flags -*/ - -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - using namespace netgen; - - Flags :: Flags () - { - ; - } - - Flags :: ~Flags () - { - DeleteFlags (); - } - - void Flags :: DeleteFlags () - { - for (int i = 0; i < strflags.Size(); i++) - delete [] strflags[i]; - for (int i = 0; i < numlistflags.Size(); i++) - delete numlistflags[i]; - strflags.DeleteAll(); - numflags.DeleteAll(); - defflags.DeleteAll(); - strlistflags.DeleteAll(); - numlistflags.DeleteAll(); - } - - void Flags :: SetFlag (const char * name, const char * val) - { - char * hval = new char[strlen (val) + 1]; - strcpy (hval, val); - strflags.Set (name, hval); - } - - void Flags :: SetFlag (const char * name, double val) - { - numflags.Set (name, val); - } - - void Flags :: SetFlag (const char * name) - { - defflags.Set (name, 1); - } - - - void Flags :: SetFlag (const char * name, const ARRAY<char*> & val) - { - ARRAY<char*> * strarray = new ARRAY<char*>; - for (int i = 1; i <= val.Size(); i++) - { - strarray->Append (new char[strlen(val.Get(i))+1]); - strcpy (strarray->Last(), val.Get(i)); - } - strlistflags.Set (name, strarray); - } - - void Flags :: SetFlag (const char * name, const ARRAY<double> & val) - { - ARRAY<double> * numarray = new ARRAY<double>; - for (int i = 1; i <= val.Size(); i++) - numarray->Append (val.Get(i)); - numlistflags.Set (name, numarray); - } - - - - - - const char * - Flags :: GetStringFlag (const char * name, const char * def) const - { - if (strflags.Used (name)) - return strflags.Get(name); - else - return def; - } - - double Flags :: GetNumFlag (const char * name, double def) const - { - if (numflags.Used (name)) - return numflags.Get(name); - else - return def; - } - - const double * Flags :: GetNumFlagPtr (const char * name) const - { - if (numflags.Used (name)) - return & ((SYMBOLTABLE<double>&)numflags).Elem(name); - else - return NULL; - } - - double * Flags :: GetNumFlagPtr (const char * name) - { - if (numflags.Used (name)) - return & ((SYMBOLTABLE<double>&)numflags).Elem(name); - else - return NULL; - } - - int Flags :: GetDefineFlag (const char * name) const - { - return defflags.Used (name); - } - - - const ARRAY<char*> & - Flags :: GetStringListFlag (const char * name) const - { - if (strlistflags.Used (name)) - return *strlistflags.Get(name); - else - { - static ARRAY<char*> hstra(0); - return hstra; - } - } - - const ARRAY<double> & - Flags ::GetNumListFlag (const char * name) const - { - if (numlistflags.Used (name)) - return *numlistflags.Get(name); - else - { - static ARRAY<double> hnuma(0); - return hnuma; - } - } - - - int Flags :: StringFlagDefined (const char * name) const - { - return strflags.Used (name); - } - - int Flags :: NumFlagDefined (const char * name) const - { - return numflags.Used (name); - } - - int Flags :: StringListFlagDefined (const char * name) const - { - return strlistflags.Used (name); - } - - int Flags :: NumListFlagDefined (const char * name) const - { - return numlistflags.Used (name); - } - - - void Flags :: SaveFlags (const char * filename) const - { - int i; - ofstream outfile (filename); - - for (i = 1; i <= strflags.Size(); i++) - outfile << strflags.GetName(i) << " = " << strflags.Get(i) << endl; - for (i = 1; i <= numflags.Size(); i++) - outfile << numflags.GetName(i) << " = " << numflags.Get(i) << endl; - for (i = 1; i <= defflags.Size(); i++) - outfile << defflags.GetName(i) << endl; - } - - - - void Flags :: PrintFlags (ostream & ost) const - { - int i; - - for (i = 1; i <= strflags.Size(); i++) - ost << strflags.GetName(i) << " = " << strflags.Get(i) << endl; - for (i = 1; i <= numflags.Size(); i++) - ost << numflags.GetName(i) << " = " << numflags.Get(i) << endl; - for (i = 1; i <= defflags.Size(); i++) - ost << defflags.GetName(i) << endl; - } - - - void Flags :: LoadFlags (const char * filename) - { - char name[100], str[100]; - char ch; - double val; - ifstream infile(filename); - - // (*logout) << "Load flags from " << filename << endl << endl; - while (infile.good()) - { - infile >> name; - if (strlen (name) == 0) break; - - if (name[0] == '/' && name[1] == '/') - { - // (*logout) << "comment: "; - ch = 0; - while (ch != '\n' && infile.good()) - { - ch = infile.get(); - // (*logout) << ch; - } - continue; - } - - // (*logout) << name; - ch = 0; - infile >> ch; - if (ch != '=') - { - // (*logout) << endl; - infile.putback (ch); - SetFlag (name); - } - else - { - infile >> val; - if (!infile.good()) - { - infile.clear(); - infile >> str; - SetFlag (name, str); - // (*logout) << " = " << str << endl; - } - else - { - SetFlag (name, val); - // (*logout) << " = " << val << endl; - } - } - } - // (*logout) << endl; - } - - - void Flags :: SetCommandLineFlag (const char * st) - { - // cout << "clflag = " << st << endl; - istringstream inst( (char *)st); - // istrstream defined with char * (not const char * ?????) - - char name[100]; - double val; - - - if (st[0] != '-') - { - cerr << "flag must start with '-'" << endl; - return; - } - - const char * pos = strchr (st, '='); - - if (!pos) - { - // (cout) << "Add def flag: " << st+1 << endl; - SetFlag (st+1); - } - else - { - // cout << "pos = " << pos << endl; - - strncpy (name, st+1, (pos-st)-1); - name[pos-st-1] = 0; - - // cout << "name = " << name << endl; - - pos++; - char * endptr = NULL; - - val = strtod (pos, &endptr); - - // cout << "val = " << val << endl; - - if (endptr == pos) - { - // (cout) << "Add String Flag: " << name << " = " << pos << endl; - SetFlag (name, pos); - } - else - { - // (cout) << "Add Num Flag: " << name << " = " << val << endl; - SetFlag (name, val); - } - } - - - /* - inst >> name; - (*mycout) << "name = " << name << endl; - - ch = 0; - inst >> ch; - if (ch != '=') - { - SetFlag (name); - } - else - { - inst >> val; - if (!inst.good()) - { - inst.clear(); - inst >> str; - SetFlag (name, str); - (*mycout) << "str = " << str << endl; - } - else - { - SetFlag (name, val); - (*mycout) << "val = " << val << endl; - } - } - */ - } -} diff --git a/Netgen/libsrc/general/flags.hpp b/Netgen/libsrc/general/flags.hpp deleted file mode 100644 index 7c62f7815b..0000000000 --- a/Netgen/libsrc/general/flags.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef FILE_FLAGS -#define FILE_FLAGS - - -/**************************************************************************/ -/* File: flags.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 10. Oct. 96 */ -/**************************************************************************/ - -/** - Flag - Table. - A flag table maintains string variables, numerical - variables and boolean flags. -*/ -class Flags -{ - /// - SYMBOLTABLE<char *> strflags; - /// - SYMBOLTABLE<double> numflags; - /// - SYMBOLTABLE<int> defflags; - /// - SYMBOLTABLE<ARRAY<char*>*> strlistflags; - /// - SYMBOLTABLE<ARRAY<double>*> numlistflags; -public: - /// - Flags (); - /// - ~Flags (); - - /// Deletes all flags - void DeleteFlags (); - /// Sets string flag, overwrite if exists - void SetFlag (const char * name, const char * val); - /// Sets numerical flag, overwrite if exists - void SetFlag (const char * name, double val); - /// Sets boolean flag - void SetFlag (const char * name); - /// Sets string arary falg - void SetFlag (const char * name, const ARRAY<char*> & val); - /// Sets double array flag - void SetFlag (const char * name, const ARRAY<double> & val); - - /// Save flags to file - void SaveFlags (const char * filename) const; - /// write flags to stream - void PrintFlags (ostream & ost) const; - /// Load flags from file - void LoadFlags (const char * filename); - /// set flag of form -name=hello -val=0.5 -defined - void SetCommandLineFlag (const char * st); - - /// Returns string flag, default value if not exists - const char * GetStringFlag (const char * name, const char * def) const; - /// Returns numerical flag, default value if not exists - double GetNumFlag (const char * name, double def) const; - /// Returns address of numerical flag, null if not exists - const double * GetNumFlagPtr (const char * name) const; - /// Returns address of numerical flag, null if not exists - double * GetNumFlagPtr (const char * name); - /// Returns boolean flag - int GetDefineFlag (const char * name) const; - /// Returns string list flag, empty array if not exist - const ARRAY<char*> & GetStringListFlag (const char * name) const; - /// Returns num list flag, empty array if not exist - const ARRAY<double> & GetNumListFlag (const char * name) const; - - - /// Test, if string flag is defined - int StringFlagDefined (const char * name) const; - /// Test, if num flag is defined - int NumFlagDefined (const char * name) const; - /// Test, if string list flag is defined - int StringListFlagDefined (const char * name) const; - /// Test, if num list flag is defined - int NumListFlagDefined (const char * name) const; -}; - -#endif - diff --git a/Netgen/libsrc/general/hashtabl.cpp b/Netgen/libsrc/general/hashtabl.cpp deleted file mode 100644 index 0485ab6045..0000000000 --- a/Netgen/libsrc/general/hashtabl.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/**************************************************************************/ -/* File: hashtabl.cpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - Abstract data type HASHTABLE -*/ - -#include <algorithm> -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - using namespace netgen; - - void INDEX_4 :: Sort () - { - if (i[0] > i[1]) Swap (i[0], i[1]); - if (i[2] > i[3]) Swap (i[2], i[3]); - if (i[0] > i[2]) Swap (i[0], i[2]); - if (i[1] > i[3]) Swap (i[1], i[3]); - if (i[1] > i[2]) Swap (i[1], i[2]); - } - - - - void INDEX_4Q :: Sort () - { - if (min2 (i[1], i[2]) < min2 (i[0], i[3])) - { Swap (i[0], i[1]); Swap (i[2], i[3]);} - if (i[3] < i[0]) - { Swap (i[0], i[3]); Swap (i[1], i[2]);} - if (i[3] < i[1]) - { Swap (i[1], i[3]); } - } - - - ostream & operator<<(ostream & s, const INDEX_2 & i2) - { - return s << i2.I1() << ", " << i2.I2(); - } - - ostream & operator<<(ostream & s, const INDEX_3 & i3) - { - return s << i3.I1() << ", " << i3.I2() << ", " << i3.I3(); - } - - ostream & operator<<(ostream & s, const INDEX_4 & i4) - { - return s << i4.I1() << ", " << i4.I2() << ", " << i4.I3() << ", " << i4.I4(); - } - - ostream & operator<<(ostream & s, const INDEX_4Q & i4) - { - return s << i4.I1() << ", " << i4.I2() << ", " << i4.I3() << ", " << i4.I4(); - } - - - int BASE_INDEX_HASHTABLE :: Position (int bnr, const INDEX & ind) const - { - int i; - for (i = 1; i <= hash.EntrySize (bnr); i++) - if (hash.Get(bnr, i) == ind) - return i; - return 0; - } - - - - /* - int BASE_INDEX_2_HASHTABLE :: Position (int bnr, const INDEX_2 & ind) const - { - int i; - for (i = 1; i <= hash.EntrySize (bnr); i++) - if (hash.Get(bnr, i) == ind) - return i; - return 0; - } - */ - - void BASE_INDEX_2_HASHTABLE :: PrintStat (ostream & ost) const - { - int n = hash.Size(); - int i; - int sumn = 0, sumnn = 0; - - for (i = 1; i <= n; i++) - { - sumn += hash.EntrySize(i); - sumnn += sqr (hash.EntrySize(i)); - } - - ost << "Hashtable: " << endl - << "size : " << n << endl - << "elements per row : " << (double(sumn) / double(n)) << endl - << "av. acces time : " - << (sumn ? (double (sumnn) / double(sumn)) : 0) << endl; - } - - - /* - int BASE_INDEX_3_HASHTABLE :: Position (int bnr, const INDEX_3 & ind) const - { - int i; - const INDEX_3 * pi = &hash.Get(bnr, 1); - int n = hash.EntrySize(bnr); - for (i = 1; i <= n; ++i, ++pi) - { - if (*pi == ind) - return i; - } - - return 0; - } - */ - - - - - - - - - - - - - - - - - - BASE_INDEX_2_CLOSED_HASHTABLE :: - BASE_INDEX_2_CLOSED_HASHTABLE (int size) - : hash(size) - { - hash.SetName ("i2-hashtable, hash"); - - invalid = -1; - int i; - for (i = 1; i <= size; i++) - hash.Elem(i).I1() = invalid; - } - - void BASE_INDEX_2_CLOSED_HASHTABLE :: - BaseSetSize (int size) - { - int i; - hash.SetSize(size); - for (i = 1; i <= size; i++) - hash.Elem(i).I1() = invalid; - } - - - int BASE_INDEX_2_CLOSED_HASHTABLE :: - Position2 (const INDEX_2 & ind) const - { - int i; - - i = HashValue(ind); - while (1) - { - i++; - if (i > hash.Size()) i = 1; - if (hash.Get(i) == ind) return i; - if (hash.Get(i).I1() == invalid) return 0; - } - } - - - - int BASE_INDEX_2_CLOSED_HASHTABLE :: - PositionCreate2 (const INDEX_2 & ind, int & apos) - { - int i; - - i = HashValue(ind); - while (1) - { - i++; - if (i > hash.Size()) i = 1; - if (hash.Get(i) == ind) - { - apos = i; - return 0; - } - if (hash.Get(i).I1() == invalid) - { - hash.Elem(i) = ind; - apos = i; - return 1; - } - } - } - - int BASE_INDEX_2_CLOSED_HASHTABLE :: UsedElements () const - { - int i, n = hash.Size(); - int cnt = 0; - for (i = 1; i <= n; i++) - if (hash.Get(i).I1() != invalid) - cnt++; - return cnt; - } - - - - - - - - - - - - BASE_INDEX_3_CLOSED_HASHTABLE :: - BASE_INDEX_3_CLOSED_HASHTABLE (int size) - : hash(size) - { - hash.SetName ("i3-hashtable, hash"); - - invalid = -1; - int i; - for (i = 1; i <= size; i++) - hash.Elem(i).I1() = invalid; - } - - void BASE_INDEX_3_CLOSED_HASHTABLE :: - BaseSetSize (int size) - { - int i; - hash.SetSize(size); - for (i = 1; i <= size; i++) - hash.Elem(i).I1() = invalid; - } - - - int BASE_INDEX_3_CLOSED_HASHTABLE :: - Position2 (const INDEX_3 & ind) const - { - int i; - - i = HashValue(ind); - while (1) - { - i++; - if (i > hash.Size()) i = 1; - if (hash.Get(i) == ind) return i; - if (hash.Get(i).I1() == invalid) return 0; - } - } - - - - int BASE_INDEX_3_CLOSED_HASHTABLE :: - PositionCreate2 (const INDEX_3 & ind, int & apos) - { - int i; - - i = HashValue(ind); - while (1) - { - i++; - if (i > hash.Size()) i = 1; - if (hash.Get(i) == ind) - { - apos = i; - return 0; - } - if (hash.Get(i).I1() == invalid) - { - hash.Elem(i) = ind; - apos = i; - return 1; - } - } - } - - int BASE_INDEX_3_CLOSED_HASHTABLE :: UsedElements () const - { - int i, n = hash.Size(); - int cnt = 0; - for (i = 1; i <= n; i++) - if (hash.Get(i).I1() != invalid) - cnt++; - return cnt; - } - - -} - diff --git a/Netgen/libsrc/general/hashtabl.hpp b/Netgen/libsrc/general/hashtabl.hpp deleted file mode 100644 index b3e0e93f7e..0000000000 --- a/Netgen/libsrc/general/hashtabl.hpp +++ /dev/null @@ -1,1000 +0,0 @@ -#ifndef FILE_HASHTABL -#define FILE_HASHTABL - -/**************************************************************************/ -/* File: hashtabl.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/** - Abstract data type HASHTABLE. - Hash is done by one INDEX -*/ -class BASE_INDEX_HASHTABLE -{ -protected: - /// keys are stored in this table - TABLE<INDEX> hash; - -public: - /// - BASE_INDEX_HASHTABLE (int size) - : hash (size) { }; - -protected: - /// - int HashValue (const INDEX & ind) const - { - return ind % hash.Size() + 1; - } - - /// - int Position (int bnr, const INDEX & ind) const; -}; - -/// -template <class T> -class INDEX_HASHTABLE : private BASE_INDEX_HASHTABLE -{ - /// - TABLE<T> cont; - -public: - /// - inline INDEX_HASHTABLE (int size); - /// - inline void Set (const INDEX & hash, const T & acont); - /// - inline const T & Get (const INDEX & ahash) const; - /// - inline bool Used (const INDEX & ahash) const; - /// - inline int GetNBags () const; - /// - inline int GetBagSize (int bnr) const; - /// - inline void GetData (int bnr, int colnr, INDEX & ahash, T & acont) const; - - /// - inline void PrintMemInfo (ostream & ost) const; -}; - - - - - - - - - - - -/// -class BASE_INDEX_2_HASHTABLE -{ -protected: - /// - TABLE<INDEX_2> hash; - -public: - /// - BASE_INDEX_2_HASHTABLE (int size) - : hash (size) { }; - - /// - void PrintStat (ostream & ost) const; - void BaseSetSize(int s) {hash.SetSize(s);} -protected: - /// - int HashValue (const INDEX_2 & ind) const - { - return (ind.I1() + ind.I2()) % hash.Size() + 1; - } - /// - int Position (int bnr, const INDEX_2 & ind) const - { - int i; - for (i = 1; i <= hash.EntrySize (bnr); i++) - if (hash.Get(bnr, i) == ind) - return i; - return 0; - } -}; - - -/// -template <class T> -class INDEX_2_HASHTABLE : public BASE_INDEX_2_HASHTABLE -{ - /// - TABLE<T> cont; - -public: - /// - INDEX_2_HASHTABLE (int size) - : BASE_INDEX_2_HASHTABLE (size), cont(size) - { ; } - - /// - void SetSize(int s) - { - cont.SetSize(s); - BaseSetSize(s); - } - - /// - void Set (const INDEX_2 & ahash, const T & acont) - { - int bnr = HashValue (ahash); - int pos = Position (bnr, ahash); - if (pos) - cont.Set (bnr, pos, acont); - else - { - hash.Add1 (bnr, ahash); - cont.Add1 (bnr, acont); - } - } - - /// - const T & Get (const INDEX_2 & ahash) const - { - int bnr = HashValue (ahash); - int pos = Position (bnr, ahash); - return cont.Get (bnr, pos); - } - - /// - bool Used (const INDEX_2 & ahash) const - { - return (Position (HashValue (ahash), ahash)) ? 1 : 0; - } - - /// - int GetNBags () const - { - return cont.Size(); - } - - /// - int GetBagSize (int bnr) const - { - return cont.EntrySize (bnr); - } - - /// - void GetData (int bnr, int colnr, - INDEX_2 & ahash, T & acont) const - { - ahash = hash.Get(bnr, colnr); - acont = cont.Get(bnr, colnr); - } - - /// - void SetData (int bnr, int colnr, - const INDEX_2 & ahash, const T & acont) - { - hash.Set(bnr, colnr, ahash); - cont.Set(bnr, colnr, acont); - } - - /// - void PrintMemInfo (ostream & ost) const - { - ost << "Hash: " << endl; - hash.PrintMemInfo (ost); - ost << "Cont: " << endl; - cont.PrintMemInfo (ost); - } - - - - class Iterator - { - const INDEX_2_HASHTABLE & ht; - int bagnr, pos; - public: - Iterator (const INDEX_2_HASHTABLE & aht, - int abagnr, int apos) - : ht(aht), bagnr(abagnr), pos(apos) - { ; } - - int BagNr() const { return bagnr; } - int Pos() const { return pos; } - - void operator++ (int) - { - // cout << "begin Operator ++: bagnr = " << bagnr << " - pos = " << pos << endl; - pos++; - while (bagnr < ht.GetNBags() && - pos == ht.GetBagSize(bagnr+1)) - { - pos = 0; - bagnr++; - } - // cout << "end Operator ++: bagnr = " << bagnr << " - pos = " << pos << endl; - } - - bool operator != (int i) const - { - return bagnr != i; - } - - }; - - Iterator Begin () const - { - Iterator it(*this, 0, -1); - it++; - return it; - } - - int End() const - { - return GetNBags(); - } - - void GetData (const Iterator & it, - INDEX_2 & ahash, T & acont) const - { - ahash = hash[it.BagNr()][it.Pos()]; - acont = cont[it.BagNr()][it.Pos()]; - } - - const INDEX_2 & GetHash (const Iterator & it) const - { return hash[it.BagNr()][it.Pos()]; } - - const T & GetData (const Iterator & it) const - { return cont[it.BagNr()][it.Pos()]; } -}; - - - -template <typename T> -inline ostream & operator<< (ostream & ost, const INDEX_2_HASHTABLE<T> & ht) -{ - for (typename INDEX_2_HASHTABLE<T>::Iterator it = ht.Begin(); - it != ht.End(); it++) - { - ost << ht.GetHash(it) << ": " << ht.GetData(it) << endl; - } - - return ost; -} - - - - - - - -/// -class BASE_INDEX_3_HASHTABLE -{ -protected: - /// - TABLE<INDEX_3> hash; - -public: - /// - BASE_INDEX_3_HASHTABLE (int size) - : hash (size) { }; - -protected: - /// - int HashValue (const INDEX_3 & ind) const - { - return (ind.I1() + ind.I2() + ind.I3()) % hash.Size() + 1; - } - - /// - int Position (int bnr, const INDEX_3 & ind) const - { - const INDEX_3 * pi = &hash.Get(bnr, 1); - int n = hash.EntrySize(bnr); - for (int i = 1; i <= n; ++i, ++pi) - { - if (*pi == ind) - return i; - } - - return 0; - } - - -}; - - -/// -template <class T> -class INDEX_3_HASHTABLE : private BASE_INDEX_3_HASHTABLE -{ - /// - TABLE<T> cont; - -public: - /// - inline INDEX_3_HASHTABLE (int size); - /// - inline void Set (const INDEX_3 & ahash, const T & acont); - /// - inline const T & Get (const INDEX_3 & ahash) const; - /// - inline bool Used (const INDEX_3 & ahash) const; - /// - inline int GetNBags () const; - /// - inline int GetBagSize (int bnr) const; - /// - inline void SetData (int bnr, int colnr, const INDEX_3 & ahash, const T & acont); - /// - inline void GetData (int bnr, int colnr, INDEX_3 & ahash, T & acont) const; - /// returns position, if not existing, will create (create == return 1) - inline int PositionCreate (const INDEX_3 & ahash, int & bnr, int & colnr); - /// - inline void SetSize (int size); - - /// - inline void PrepareSet (const INDEX_3 & ahash); - /// - inline void AllocateElements (); - - /// - inline void PrintMemInfo (ostream & ost) const; - /// - inline void DeleteData (); -}; - - - - - - - - -/// Closed Hashing HT - -class BASE_INDEX_2_CLOSED_HASHTABLE -{ -protected: - /// - MoveableArray<INDEX_2> hash; - /// - int invalid; -public: - /// - BASE_INDEX_2_CLOSED_HASHTABLE (int size); - - int Size() const { return hash.Size(); } - int UsedPos (int pos) const { return ! (hash.Get(pos).I1() == invalid); } - int UsedElements () const; - - /// - int HashValue (const INDEX_2 & ind) const - { - return (ind.I1() + 71 * ind.I2()) % hash.Size() + 1; - } - - - int Position (const INDEX_2 & ind) const - { - int i = HashValue(ind); - while (1) - { - if (hash.Get(i) == ind) return i; - if (hash.Get(i).I1() == invalid) return 0; - i++; - if (i > hash.Size()) i = 1; - } - /* - int pos = HashValue (ind); - if (hash.Get(pos) == ind) return pos; - return Position2 (ind); - */ - } - - // returns 1, if new postion is created - int PositionCreate (const INDEX_2 & ind, int & apos) - { - int i = HashValue (ind); - if (hash.Get(i) == ind) - { - apos = i; - return 0; - } - if (hash.Get(i).I1() == invalid) - { - hash.Elem(i) = ind; - apos = i; - return 1; - } - return PositionCreate2 (ind, apos); - } - -protected: - /// - - int Position2 (const INDEX_2 & ind) const; - int PositionCreate2 (const INDEX_2 & ind, int & apos); - void BaseSetSize (int asize); -}; - - -template <class T> -class INDEX_2_CLOSED_HASHTABLE : public BASE_INDEX_2_CLOSED_HASHTABLE -{ - /// - MoveableArray<T> cont; - -public: - /// - inline INDEX_2_CLOSED_HASHTABLE (int size); - /// - inline void Set (const INDEX_2 & ahash, const T & acont); - /// - inline const T & Get (const INDEX_2 & ahash) const; - /// - inline bool Used (const INDEX_2 & ahash) const; - /// - inline void SetData (int pos, const INDEX_2 & ahash, const T & acont); - /// - inline void GetData (int pos, INDEX_2 & ahash, T & acont) const; - /// - inline void SetData (int pos, const T & acont); - /// - inline void GetData (int pos, T & acont) const; - /// - const T & GetData (int pos) { return cont.Get(pos); } - /// - inline void SetSize (int size); - /// - inline void PrintMemInfo (ostream & ost) const; - /// - inline void DeleteData () - { SetSize (cont.Size()); } - - void SetName (const char * aname) - { - cont.SetName(aname); - hash.SetName(aname); - } -}; - - - - - - - - - - - - - -class BASE_INDEX_3_CLOSED_HASHTABLE -{ -protected: - /// - MoveableArray<INDEX_3> hash; - /// - int invalid; -public: - /// - BASE_INDEX_3_CLOSED_HASHTABLE (int size); - - int Size() const { return hash.Size(); } - bool UsedPos (int pos) const { return ! (hash.Get(pos).I1() == invalid); } - int UsedElements () const; - - /// - int HashValue (const INDEX_3 & ind) const - { - return (ind.I1() + 15 * ind.I2() + 41 * ind.I3()) % hash.Size() + 1; - } - - int Position (const INDEX_3 & ind) const - { - int i = HashValue(ind); - while (1) - { - if (hash.Get(i) == ind) return i; - if (hash.Get(i).I1() == invalid) return 0; - i++; - if (i > hash.Size()) i = 1; - } - /* - int pos = HashValue (ind); - if (hash.Get(pos) == ind) return pos; - return Position2 (ind); - */ - } - - // returns 1, if new postion is created - int PositionCreate (const INDEX_3 & ind, int & apos) - { - int i = HashValue (ind); - if (hash.Get(i) == ind) - { - apos = i; - return 0; - } - if (hash.Get(i).I1() == invalid) - { - hash.Elem(i) = ind; - apos = i; - return 1; - } - return PositionCreate2 (ind, apos); - } - - -protected: - /// - - int Position2 (const INDEX_3 & ind) const; - int PositionCreate2 (const INDEX_3 & ind, int & apos); - void BaseSetSize (int asize); -}; - - -template <class T> -class INDEX_3_CLOSED_HASHTABLE : public BASE_INDEX_3_CLOSED_HASHTABLE -{ - /// - MoveableArray<T> cont; - -public: - /// - inline INDEX_3_CLOSED_HASHTABLE (int size); - /// - inline void Set (const INDEX_3 & ahash, const T & acont); - /// - inline const T & Get (const INDEX_3 & ahash) const; - /// - inline bool Used (const INDEX_3 & ahash) const; - /// - inline void SetData (int pos, const INDEX_3 & ahash, const T & acont); - /// - inline void GetData (int pos, INDEX_3 & ahash, T & acont) const; - /// - inline void SetData (int pos, const T & acont); - /// - inline void GetData (int pos, T & acont) const; - /// - inline const T & GetData (int pos) const; - /// - inline void SetSize (int size); - /// - inline void PrintMemInfo (ostream & ost) const; - /// - inline void DeleteData () - { SetSize (cont.Size()); } - - void SetName (const char * aname) - { - cont.SetName(aname); - hash.SetName(aname); - } -}; - - - - - - - - - - - - - - - - -template<class T> -inline INDEX_3_HASHTABLE<T> :: INDEX_3_HASHTABLE (int size) - : BASE_INDEX_3_HASHTABLE (size), cont(size) -{ - ; -} - -template<class T> -inline int INDEX_3_HASHTABLE<T> :: PositionCreate (const INDEX_3 & ahash, int & bnr, int & colnr) -{ - bnr = HashValue (ahash); - colnr = Position (bnr, ahash); - if (!colnr) - { - hash.Add (bnr, ahash); - cont.AddEmpty (bnr); - colnr = cont.EntrySize (bnr); - return 1; - } - return 0; -} - - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: Set (const INDEX_3 & ahash, const T & acont) -{ - int bnr = HashValue (ahash); - int pos = Position (bnr, ahash); - if (pos) - cont.Set (bnr, pos, acont); - else - { - hash.Add1 (bnr, ahash); - cont.Add1 (bnr, acont); - } -} - -template<class T> -inline const T & INDEX_3_HASHTABLE<T> :: Get (const INDEX_3 & ahash) const -{ - int bnr = HashValue (ahash); - int pos = Position (bnr, ahash); - return cont.Get (bnr, pos); -} - -template<class T> -inline bool INDEX_3_HASHTABLE<T> :: Used (const INDEX_3 & ahash) const -{ - return (Position (HashValue (ahash), ahash)) ? 1 : 0; -} - -template<class T> -inline int INDEX_3_HASHTABLE<T> :: GetNBags () const -{ - return cont.Size(); -} - -template<class T> -inline int INDEX_3_HASHTABLE<T> :: GetBagSize (int bnr) const -{ - return cont.EntrySize (bnr); -} - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: GetData (int bnr, int colnr, INDEX_3 & ahash, T & acont) const -{ - ahash = hash.Get(bnr, colnr); - acont = cont.Get(bnr, colnr); -} - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: SetData (int bnr, int colnr, const INDEX_3 & ahash, const T & acont) -{ - hash.Set(bnr, colnr, ahash); - cont.Set(bnr, colnr, acont); -} - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: SetSize (int size) -{ - hash.SetSize (size); - cont.SetSize (size); -} - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: DeleteData () -{ - int n = hash.Size(); - hash.SetSize (n); - cont.SetSize (n); -} - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: PrepareSet (const INDEX_3 & ahash) -{ - int bnr = HashValue (ahash); - hash.IncSizePrepare (bnr-1); - cont.IncSizePrepare (bnr-1); -} - - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: AllocateElements () -{ - hash.AllocateElementsOneBlock(); - cont.AllocateElementsOneBlock(); -} - - - -template<class T> -inline void INDEX_3_HASHTABLE<T> :: PrintMemInfo (ostream & ost) const - { - ost << "Hash: " << endl; - hash.PrintMemInfo (ost); - ost << "Cont: " << endl; - cont.PrintMemInfo (ost); - } - - - - - -template<class T> -inline INDEX_HASHTABLE<T> :: INDEX_HASHTABLE (int size) - : BASE_INDEX_HASHTABLE (size), cont(size) - { - ; - } - -template<class T> -inline void INDEX_HASHTABLE<T> :: Set (const INDEX & ahash, const T & acont) - { - int bnr = HashValue (ahash); - int pos = Position (bnr, ahash); - if (pos) - cont.Set (bnr, pos, acont); - else - { - hash.Add (bnr, ahash); - cont.Add (bnr, acont); - } - } - -template<class T> -inline const T & INDEX_HASHTABLE<T> :: Get (const INDEX & ahash) const - { - int bnr = HashValue (ahash); - int pos = Position (bnr, ahash); - return cont.Get (bnr, pos); - } - -template<class T> -inline bool INDEX_HASHTABLE<T> :: Used (const INDEX & ahash) const - { - return (Position (HashValue (ahash), ahash)) ? 1 : 0; - } - -template<class T> -inline int INDEX_HASHTABLE<T> :: GetNBags () const - { - return hash.Size(); - } - -template<class T> -inline int INDEX_HASHTABLE<T> :: GetBagSize (int bnr) const - { - return hash.EntrySize(bnr); - } - -template<class T> -inline void INDEX_HASHTABLE<T> :: GetData (int bnr, int colnr, INDEX & ahash, T & acont) const - { - ahash = hash.Get(bnr, colnr); - acont = cont.Get(bnr, colnr); - } - -template<class T> -inline void INDEX_HASHTABLE<T> :: PrintMemInfo (ostream & ost) const - { - ost << "Hash: " << endl; - hash.PrintMemInfo (ost); - ost << "Cont: " << endl; - cont.PrintMemInfo (ost); - } - - - - - - - - - - - - - - - -/* *********** Closed Hashing ************************* */ - - - - -template<class T> -inline INDEX_2_CLOSED_HASHTABLE<T> :: -INDEX_2_CLOSED_HASHTABLE (int size) - : BASE_INDEX_2_CLOSED_HASHTABLE(size), cont(size) -{ - cont.SetName ("i2-hashtable, contents"); -} - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -Set (const INDEX_2 & ahash, const T & acont) -{ - int pos; - PositionCreate (ahash, pos); - hash.Elem(pos) = ahash; - cont.Elem(pos) = acont; -} - -template<class T> -inline const T & INDEX_2_CLOSED_HASHTABLE<T> :: -Get (const INDEX_2 & ahash) const -{ - int pos = Position (ahash); - return cont.Get(pos); -} - -template<class T> -inline bool INDEX_2_CLOSED_HASHTABLE<T> :: -Used (const INDEX_2 & ahash) const -{ - int pos = Position (ahash); - return (pos != 0); -} - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -SetData (int pos, const INDEX_2 & ahash, const T & acont) -{ - hash.Elem(pos) = ahash; - cont.Elem(pos) = acont; -} - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -GetData (int pos, INDEX_2 & ahash, T & acont) const -{ - ahash = hash.Get(pos); - acont = cont.Get(pos); -} - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -SetData (int pos, const T & acont) -{ - cont.Elem(pos) = acont; -} - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -GetData (int pos, T & acont) const -{ - acont = cont.Get(pos); -} - - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -SetSize (int size) -{ - BaseSetSize(size); - cont.SetSize(size); -} - - - -template<class T> -inline void INDEX_2_CLOSED_HASHTABLE<T> :: -PrintMemInfo (ostream & ost) const -{ - cout << "Hashtable: " << Size() - << " entries of size " << sizeof(INDEX_2) << " + " << sizeof(T) - << " = " << Size() * (sizeof(INDEX_2) + sizeof(T)) << " bytes." - << " Used els: " << UsedElements() - << endl; -} - - - - - - - - - - - - - - - - - -template<class T> -inline INDEX_3_CLOSED_HASHTABLE<T> :: -INDEX_3_CLOSED_HASHTABLE (int size) - : BASE_INDEX_3_CLOSED_HASHTABLE(size), cont(size) -{ - cont.SetName ("i3-hashtable, contents"); -} - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -Set (const INDEX_3 & ahash, const T & acont) -{ - int pos; - PositionCreate (ahash, pos); - hash.Elem(pos) = ahash; - cont.Elem(pos) = acont; -} - -template<class T> -inline const T & INDEX_3_CLOSED_HASHTABLE<T> :: -Get (const INDEX_3 & ahash) const -{ - int pos = Position (ahash); - return cont.Get(pos); -} - -template<class T> -inline bool INDEX_3_CLOSED_HASHTABLE<T> :: -Used (const INDEX_3 & ahash) const -{ - int pos = Position (ahash); - return (pos != 0); -} - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -SetData (int pos, const INDEX_3 & ahash, const T & acont) -{ - hash.Elem(pos) = ahash; - cont.Elem(pos) = acont; -} - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -GetData (int pos, INDEX_3 & ahash, T & acont) const -{ - ahash = hash.Get(pos); - acont = cont.Get(pos); -} - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -SetData (int pos, const T & acont) -{ - cont.Elem(pos) = acont; -} - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -GetData (int pos, T & acont) const -{ - acont = cont.Get(pos); -} - -template<class T> -inline const T & INDEX_3_CLOSED_HASHTABLE<T> :: -GetData (int pos) const -{ - return cont.Get(pos); -} - - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -SetSize (int size) -{ - BaseSetSize(size); - cont.SetSize(size); -} - - - -template<class T> -inline void INDEX_3_CLOSED_HASHTABLE<T> :: -PrintMemInfo (ostream & ost) const -{ - cout << "Hashtable: " << Size() - << " entries of size " << sizeof(INDEX_3) << " + " << sizeof(T) - << " = " << Size() * (sizeof(INDEX_3) + sizeof(T)) << " bytes" << endl; -} - - - - - - -#endif diff --git a/Netgen/libsrc/general/moveablemem.cpp b/Netgen/libsrc/general/moveablemem.cpp deleted file mode 100644 index cdfac0e7b8..0000000000 --- a/Netgen/libsrc/general/moveablemem.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include <iostream> -#include <iomanip> - -#include <myadt.hpp> -using namespace std; -namespace netgen -{ - - NgMutex mem_mutex; - - size_t BaseMoveableMem::totalsize = 0; // 500000000; - size_t BaseMoveableMem::used = 0; - char * BaseMoveableMem::largeblock = 0; - - BaseMoveableMem * BaseMoveableMem::first = 0; - BaseMoveableMem * BaseMoveableMem::last = 0; - - - BaseMoveableMem :: BaseMoveableMem (size_t s) - { - // cout << "Construct object begin" << endl; - // Print (); - - prev = last; - next = 0; - - if (last) last->next = this; - last = this; - if (!first) first = this; - - size = 0; - - if (prev) - pos = prev->pos + prev->size; - else - pos = 0; - - ptr = 0; - name = NULL; - - if (s) Alloc(s); -} - -BaseMoveableMem :: ~BaseMoveableMem () throw() -{ - Free(); - - if (next) next->prev = prev; - else last = prev; - if (prev) prev->next = next; - else first = next; - - if(name != NULL) - { - delete [] name; - name = NULL; - } -} - -void BaseMoveableMem :: SetName (const char * aname) -{ - if(name != NULL) - { - delete [] name; - name = NULL; - } - if (aname) - { - name = new char[strlen(aname)+1]; - strcpy (name, aname); - } -} - - -void BaseMoveableMem :: Alloc (size_t s) -{ - if (totalsize == 0) - { - size = s; - ptr = (char*) malloc(s); - return; - } - - - used += s - size; - - int r = s % 8; - if (r) s += 8-r; - if (prev) - pos = prev->pos + prev->size; - else - pos = 0; - size = s; - - if (next) - { - NgLock lock(mem_mutex); - lock.Lock(); - try - { - next->MoveTo (pos+size); - } - catch (NgException e) - { - lock.UnLock(); - throw NgException ("MoveableMem overflow"); - } - lock.UnLock(); - } - - if (size) - { - if (!largeblock) - { - cout << "moveable memory: allocate large block of " - << totalsize / 1048576 << " MB" << endl; - // largeblock = new char[totalsize]; - largeblock = (char*)malloc (totalsize); - } - ptr = largeblock+pos; - - if (pos + size > totalsize) - throw NgException ("MoveableMem overflow"); - } - else - ptr = 0; -} - -void BaseMoveableMem :: ReAlloc (size_t s) -{ - if (totalsize == 0) - { - if (size == s) return; - - char * old = ptr; - ptr = (char*)malloc(s); - memmove (ptr, old, (s < size) ? s : size); - free (old); - size = s; - return; - } - - Alloc (s); -} - -void BaseMoveableMem :: MoveTo (size_t newpos) -{ - // cout << "move block, oldpos = " << pos << "; newpos = " << newpos - // << ", size = " << size << endl; - static int move = 0; - - if (newpos + size > totalsize) - throw NgException ("MoveableMem overflow"); - if (newpos > pos) - { - if (next) next->MoveTo (newpos+size); - memmove (largeblock+newpos, largeblock+pos, size); - move += size; - } - else if (newpos < pos) - { - // cout << "move down: " << size << endl; - memmove (largeblock+newpos, largeblock+pos, size); - if (next) next->MoveTo (newpos+size); - move += size; - } - pos = newpos; - ptr = largeblock+pos; - // cout << "total move: " << move << endl; -} - -void BaseMoveableMem :: Free () throw() -{ - if (totalsize == 0) - { - free (ptr); - ptr = 0; - return; - } - - /* - cout << "free block, pos = " << pos << "size = " << size << endl; - cout << "before: " << endl; - Print(); - */ - used -= size; - if (next) - { - NgLock lock(mem_mutex); - lock.Lock(); - next->MoveTo (pos); - lock.UnLock(); - } - - size = 0; - ptr = 0; - // pos = 0; -} - -void BaseMoveableMem :: Swap (BaseMoveableMem & m2) throw() -{ - int hi; - // BaseMoveableMem * hp; - char * cp; - hi = size; size = m2.size; m2.size = hi; - hi = pos; pos = m2.pos; m2.pos = hi; - /* - hp = prev; prev = m2.prev; m2.prev = hp; - hp = next; next = m2.next; m2.next = hp; - */ - cp = ptr; ptr = m2.ptr; m2.ptr = cp; - cp = name; name = m2.name; m2.name = cp; -} - - -void BaseMoveableMem :: Print () -{ - cout << "****************** Moveable Mem Report ****************" << endl; - BaseMoveableMem * p = first; - int mem = 0; - int cnt = 0; - while (p) - { - mem += p->size; - cnt++; - - cout << setw(10) << p->size << " Bytes"; - cout << ", pos = " << p->pos; - // cout << ", addr = " << p->ptr; - if (p->name) - cout << " in block " << p->name; - cout << endl; - - p = p->next; - } - - if (mem > 100000000) - cout << "memory in moveable arena: " << mem/1048576 << " MB" << endl; - else if (mem > 100000) - cout << "memory in moveable arena: " << mem/1024 << " kB" << endl; - else - cout << "memory in moveable arena: " << mem << " Bytes" << endl; - cout << "number of blocks: " << cnt << endl; - - cout << " used = " << used << endl; - // cout << "******************************************************" << endl; -} - -} diff --git a/Netgen/libsrc/general/moveablemem.hpp b/Netgen/libsrc/general/moveablemem.hpp deleted file mode 100644 index 92a67ad6da..0000000000 --- a/Netgen/libsrc/general/moveablemem.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef FILE_MOVEABLEMEM -#define FILE_MOVEABLEMEM - -/**************************************************************************/ -/* File: moveablemem.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 12. Feb. 2003 */ -/**************************************************************************/ - - -extern NgMutex mem_mutex; - -class BaseMoveableMem -{ -public: - static size_t totalsize; - static size_t used; - -private: - static char * largeblock; - static BaseMoveableMem *first, *last; - - BaseMoveableMem *prev, *next; - size_t size, pos; - char * ptr; - char * name; - -protected: - BaseMoveableMem (size_t s = 0); - ~BaseMoveableMem () throw(); - void Alloc (size_t s); - void ReAlloc (size_t s); - void MoveTo (size_t newpos); - void Free () throw(); - char * Ptr() { return ptr; } - const char * Ptr() const { return ptr; } - void Swap (BaseMoveableMem & m2) throw(); -public: - void SetName (const char * aname); - static void Print (); -}; - - - - -template <typename T> -class MoveableMem : public BaseMoveableMem -{ -public: - MoveableMem (size_t s = 0) - : BaseMoveableMem (sizeof(T) * s) - { - ; - } - void Alloc (size_t s) - { - BaseMoveableMem::Alloc (sizeof(T) * s); - } - void ReAlloc (size_t s) - { - BaseMoveableMem::ReAlloc (sizeof(T) * s); - } - void Free () - { - BaseMoveableMem::Free (); - } - - const T * Ptr() const - { - return reinterpret_cast<const T*> (BaseMoveableMem::Ptr()); - } - - T * Ptr() - { - return reinterpret_cast<T*> (BaseMoveableMem::Ptr()); - } - - operator const T* () const - { - return reinterpret_cast<const T*> (BaseMoveableMem::Ptr()); - } - - operator T* () - { - return reinterpret_cast<T*> (BaseMoveableMem::Ptr()); - } - - void Swap (MoveableMem<T> & m2) - { - BaseMoveableMem::Swap (m2); - } -protected: - MoveableMem (const MoveableMem & m) { ; } - MoveableMem & operator= (const MoveableMem & m) { ; } -}; - -#endif diff --git a/Netgen/libsrc/general/myadt.hpp b/Netgen/libsrc/general/myadt.hpp deleted file mode 100644 index f74976d51f..0000000000 --- a/Netgen/libsrc/general/myadt.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef FILE_MYADT -#define FILE_MYADT - -/**************************************************************************/ -/* File: myadt.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - include for all abstract data types -*/ - - - -#include <mystdlib.h> -#include <mydefs.hpp> - - -namespace netgen -{ -#include "ngexception.hpp" -#include "parthreads.hpp" -#include "moveablemem.hpp" -#include "dynamicmem.hpp" - -#include "template.hpp" -#include "array.hpp" -#include "table.hpp" -#include "hashtabl.hpp" -#include "symbolta.hpp" -#include "bitarray.hpp" -#include "flags.hpp" -#include "spbita2d.hpp" -#include "seti.hpp" -#include "optmem.hpp" -#include "autoptr.hpp" -#include "sort.hpp" -#include "stack.hpp" -#include "mystring.hpp" -} - -#endif diff --git a/Netgen/libsrc/general/mystring.cpp b/Netgen/libsrc/general/mystring.cpp deleted file mode 100644 index 6b0f0cee74..0000000000 --- a/Netgen/libsrc/general/mystring.cpp +++ /dev/null @@ -1,386 +0,0 @@ - -//************************************************************** -// -// filename: mystring.cpp -// -// project: doctoral thesis -// -// autor: Dipl.-Ing. Gerstmayr Johannes -// -// generated: 20.12.98 -// last change: 20.12.98 -// description: implementation for strings -// remarks: -// -//************************************************************** - -// string class -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <gprim.hpp> - -/* -#include <iostream.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <fstream.h> -#include "mystring.hh" - - */ - -namespace netgen -{ - -void DefaultStringErrHandler() -{ - cerr << "Fehler : Bereichs�berschreitung bei Stringoperation\n" << flush; -} - -void (*MyStr::ErrHandler)() = DefaultStringErrHandler; - - /* -MyStr::MyStr() -{ - length = 0; - str = shortstr; - str[0] = 0; -} - */ - -MyStr::MyStr(const char *s) -{ - length = strlen(s); - - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, s); -} - -/* -MyStr::MyStr(char s) -{ - length = 1; - str = shortstr; - str[0] = s; - str[1] = (char)0; -} -*/ - -MyStr::MyStr(const MyStr& s) -{ - length = s.length; - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, s.str); -} - -MyStr::MyStr(int i) -{ - char buffer[32]; - sprintf(buffer, "%d", i); - length = strlen(buffer); - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, buffer); -} - -MyStr::MyStr(long l) -{ - char buffer[32]; - sprintf(buffer, "%ld", l); - length = strlen(buffer); - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, buffer); -} - -MyStr::MyStr(double d) -{ - char buffer[32]; - //if (fabs(d) < 1E-100) {d = 0;} - sprintf(buffer, "%g", d); - length = strlen(buffer); - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, buffer); -} - -MyStr::MyStr(const Point3d& p) -{ - char buffer[80]; - //if (fabs(d) < 1E-100) {d = 0;} - sprintf(buffer, "[%g, %g, %g]", p.X(), p.Y(), p.Z()); - length = strlen(buffer); - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, buffer); -} - -MyStr::MyStr(const Vec3d& p) -{ - char buffer[80]; - //if (fabs(d) < 1E-100) {d = 0;} - sprintf(buffer, "[%g, %g, %g]", p.X(), p.Y(), p.Z()); - length = strlen(buffer); - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, buffer); -} - -MyStr::MyStr(unsigned n, int) -{ - length = n; - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - str[n] = 0; -} - -MyStr::MyStr(const std::string & st) -{ - length = st.length(); - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy (str, st.c_str()); -} - - - -MyStr MyStr::Left(unsigned r) -{ - if(r > length) - { - MyStr::ErrHandler(); - MyStr s; - return s; - } - else - { - MyStr tmp(r, 0); - strncpy(tmp.str, str, r); - return tmp; - } -} - -MyStr MyStr::Right(unsigned l) -{ - if(l > length) - { - MyStr::ErrHandler(); - MyStr s; - return s; - } - else - { - MyStr tmp(l, 0); - strncpy(tmp.str, str + length - l, l); - return tmp; - } -} - -MyStr& MyStr::InsertAt(unsigned pos, const MyStr& s) -{ - if(pos > length) - { - MyStr::ErrHandler(); - return *this; - } - int newLength = length + s.length; - char *tmp = new char[newLength + 1]; - strncpy(tmp, str, pos); - strcpy(tmp + pos, s.str); - strcpy(tmp + pos + s.length, str + pos); - - if (length > SHORTLEN) delete str; - length = newLength; - if (length > SHORTLEN) - str = tmp; - else - { - strcpy (shortstr, tmp); - delete tmp; - str = shortstr; - } - return *this; -} - -MyStr &MyStr::WriteAt(unsigned pos, const MyStr& s) -{ - if(pos > length) - { - MyStr::ErrHandler(); - return *this; - } - int n = length - pos; - if(s.length < n) - n = s.length; - strncpy(str + pos, s.str, n); - return *this; -} - -void MyStr::ConvertTextToExcel() -{ - /* - for (int i = 0; i < Length(); i++) - { - if ((*this)[i]==',') {(*this)[i] = ';';} - else if ((*this)[i]=='.') {(*this)[i] = ',';} - } - */ -} - -void MyStr::ConvertExcelToText() -{ - /* - for (int i = 0; i < Length(); i++) - { - if ((*this)[i]==',') {(*this)[i] = '.';} - else if ((*this)[i]==';') {(*this)[i] = ',';} - } - */ -} - -MyStr& MyStr::operator = (const MyStr& s) -{ - if (length > SHORTLEN) delete str; - length = s.length; - if (length > SHORTLEN) - str = new char[length + 1]; - else - str = shortstr; - strcpy(str, s.str); - return *this; -} - -MyStr operator + (const MyStr& s1, const MyStr& s2) -{ - MyStr tmp(s1.length + s2.length, 0); - if (s1.length != 0) strcpy(tmp.str, s1.str); - if (s2.length != 0) strcpy(tmp.str + s1.length, s2.str); - return tmp; -} - -void MyStr::operator += (const MyStr& s) -{ - if (length+s.length <= SHORTLEN) - { - if (s.length != 0) strcpy(shortstr + length, s.str); - } - else - { - char *tmp = new char[length + s.length + 1]; - if (length != 0) strcpy(tmp, str); - if (s.length != 0) strcpy(tmp + length, s.str); - if (length > SHORTLEN) delete str; - length += s.length; - str = tmp; - } -} - -char& MyStr::operator [] (unsigned n) -{ - static char dummy; - if(n < length) - return str[n]; - else - { - MyStr::ErrHandler(); - return dummy; - } -} - -char MyStr::operator [] (unsigned n) const -{ - static char dummy; - if(n < length) - return str[n]; - else - { - MyStr::ErrHandler(); - return dummy; - } -} - -MyStr MyStr::operator () (unsigned l, unsigned r) -{ - if((l > r) || (r > length)) - { - MyStr::ErrHandler(); - MyStr s; - return s; - } - else - { - int n = r - l + 1; - MyStr tmp(n, 0); - strncpy(tmp.str, str + 1, n); - return tmp; - } -} - -istream& operator >> (istream& is, MyStr& s) -{ - const int buflen = 1000; - char buffer[buflen+1]; - - int end = 0; - s = ""; - MyStr str; - - while (!end) - { - is.get(buffer, buflen); - str = MyStr(buffer); - s += str; - if (is.peek() == EOF) {end = 1;} - } - - return is; -} - -/* -#ifdef __borland -::ifstream& operator >> (::ifstream& is, MyStr& s) // wb -{ // wb - const int buflen = 1000; // wb - char buffer[buflen+1]; // wb - // wb - int end = 0; // wb - s = ""; // wb - MyStr str; // wb - // wb - while (!end) // wb - { // wb - is.get(buffer, buflen); // wb - str = MyStr(buffer); // wb - s += str; // wb - if (is.peek() == EOF) {end = 1;} // wb - } // wb - // wb - return is; // wb -} - -#endif -*/ -} diff --git a/Netgen/libsrc/general/mystring.hpp b/Netgen/libsrc/general/mystring.hpp deleted file mode 100644 index cd6639552c..0000000000 --- a/Netgen/libsrc/general/mystring.hpp +++ /dev/null @@ -1,209 +0,0 @@ - -//************************************************************** -// -// filename: mystring.h -// -// project: doctoral thesis, program smart -// -// autor: Dipl.-Ing. Gerstmayr Johannes -// -// generated: 20.12.98 -// last change: 20.12.98 -// description: base class for strings -// remarks: string with n characters has -// 0..n-1 characters and at pos n a 0 -// -//************************************************************** - - -#ifndef MYSTRING__H -#define MYSTRING__H - -class Point3d; -class Vec3d; - -class MyStr; - -MyStr operator + (const MyStr &, const MyStr &); -int operator == (const MyStr &, const MyStr &); -int operator < (const MyStr &, const MyStr &); -int operator <= (const MyStr &, const MyStr &); -int operator > (const MyStr &, const MyStr &); -int operator >= (const MyStr &, const MyStr &); -int operator != (const MyStr &, const MyStr &); -ostream& operator << (ostream &, const MyStr &); -istream& operator >> (istream &, MyStr &); - -class MyStr -{ -public: - MyStr(); - MyStr(const char *); - MyStr(char); - MyStr(const MyStr &); - MyStr(int); - MyStr(long); - MyStr(double); - MyStr(const Point3d& p); - MyStr(const Vec3d& p); - MyStr(const std::string & st); - - ~MyStr(); - MyStr Left(unsigned); - MyStr Right(unsigned); - MyStr& InsertAt(unsigned, const MyStr &); - MyStr& WriteAt(unsigned, const MyStr &); - unsigned Length() const; - int Find(const char); - int Find(const char *); - int Find(const MyStr &); - MyStr& operator = (const MyStr &); - friend MyStr operator + (const MyStr &, const MyStr &); - void operator += (const MyStr &); - char* c_str(); - - //change every ',' -> ';', '.' -> ',' - void ConvertTextToExcel(); - //change every ','->'.', ';'->',' - void ConvertExcelToText(); - - MyStr operator () (unsigned, unsigned); - operator int(); - operator double(); - operator long(); - operator char *(); - char& operator [] (unsigned int); - char operator [] (unsigned int) const; - - friend int operator == (const MyStr &, const MyStr &); - friend int operator < (const MyStr &, const MyStr &); - friend int operator <= (const MyStr &, const MyStr &); - friend int operator > (const MyStr &, const MyStr &); - friend int operator >= (const MyStr &, const MyStr &); - friend int operator != (const MyStr &, const MyStr &); - friend ostream& operator << (ostream &, const MyStr &); - friend istream& operator >> (istream &, MyStr &); - static void SetToErrHandler(void (*)()); -private: - MyStr(unsigned, int); - char *str; - unsigned length; - enum { SHORTLEN = 24 }; - char shortstr[SHORTLEN+1]; - static void(*ErrHandler)(); -}; - - -inline MyStr::MyStr() -{ - length = 0; - str = shortstr; - str[0] = 0; -} - -inline MyStr::MyStr(char s) -{ - length = 1; - str = shortstr; - str[0] = s; - str[1] = (char)0; -} - -inline MyStr::~MyStr() -{ - if (length > SHORTLEN) - delete [] str; -} - -inline unsigned MyStr::Length() const -{ - return length; -} - -inline int MyStr::Find(const char c) -{ - char *pos = strchr(str, int(c)); - return pos ? int(pos - str) : -1; -} - -inline int MyStr::Find(const MyStr &s) -{ - char *pos = strstr(str, s.str); - return pos ? int(pos - str) : -1; -} - -inline int MyStr::Find(const char *s) -{ - char *pos = strstr(str, s); - return pos ? int(pos - str) : -1; -} - -inline MyStr::operator int() -{ - return atoi(str); -} - -inline MyStr::operator double() -{ - return atof(str); -} - -inline MyStr::operator long() -{ - return atol(str); -} - -inline MyStr::operator char *() -{ - return str; -} - -inline char* MyStr::c_str() -{ - return str; -} - - -inline int operator == (const MyStr &s1, const MyStr& s2) -{ - return strcmp(s1.str, s2.str) == 0; -} - -inline int operator < (const MyStr &s1, const MyStr& s2) -{ - return strcmp(s1.str, s2.str) < 0; -} - -inline int operator <= (const MyStr &s1, const MyStr& s2) -{ - return strcmp(s1.str, s2.str) <= 0; -} - -inline int operator > (const MyStr &s1, const MyStr& s2) -{ - return strcmp(s1.str, s2.str) > 0; -} - -inline int operator >= (const MyStr &s1, const MyStr& s2) -{ - return strcmp(s1.str, s2.str) >= 0; -} - -inline int operator != (const MyStr &s1, const MyStr& s2) -{ - return !(s1 == s2); -} - -inline ostream& operator << (ostream& os, const MyStr& s) -{ - return os << s.str; -} - -inline void MyStr::SetToErrHandler(void (*Handler)()) -{ - ErrHandler = Handler; -} - -#endif - - diff --git a/Netgen/libsrc/general/ngexception.cpp b/Netgen/libsrc/general/ngexception.cpp deleted file mode 100644 index 6746dd2521..0000000000 --- a/Netgen/libsrc/general/ngexception.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************/ -/* File: ngexception.cpp */ -/* Author: Joachim Schoeberl */ -/* Date: 16. Jan. 02 */ -/**************************************************************************/ - -#include <myadt.hpp> - -namespace netgen -{ - using namespace netgen; - - - - NgException :: NgException (const string & s) - : what(s) - { - ; - } - - - NgException :: ~NgException () - { - ; - } - - /// append string to description - void NgException :: Append (const string & s) - { - what += s; - } - -} diff --git a/Netgen/libsrc/general/ngexception.hpp b/Netgen/libsrc/general/ngexception.hpp deleted file mode 100644 index 56c561aa8c..0000000000 --- a/Netgen/libsrc/general/ngexception.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef FILE_NGEXCEPTION -#define FILE_NGEXCEPTION - -/**************************************************************************/ -/* File: ngexception.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 16. Jan. 2002 */ -/**************************************************************************/ - - -/// Base class for all ng exceptions -class NgException -{ - /// verbal description of exception - string what; -public: - /// - NgException (const string & s); - /// - virtual ~NgException (); - - /// append string to description - void Append (const string & s); - // void Append (const char * s); - - /// verbal description of exception - const string & What() const { return what; } -}; - -#endif diff --git a/Netgen/libsrc/general/optmem.cpp b/Netgen/libsrc/general/optmem.cpp deleted file mode 100644 index c8f961b12a..0000000000 --- a/Netgen/libsrc/general/optmem.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************/ -/* File: optmem.cc */ -/* Author: Joachim Schoeberl */ -/* Date: 04. Apr. 97 */ -/**************************************************************************/ - -/* - Abstract data type ARRAY -*/ - - -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - using namespace netgen; - - BlockAllocator :: BlockAllocator (unsigned asize, unsigned ablocks) - : bablocks (0) - { - if (asize < sizeof(void*)) - asize = sizeof(void*); - size = asize; - blocks = ablocks; - freelist = NULL; - } - - BlockAllocator :: ~BlockAllocator () - { - for (unsigned i = 0; i < bablocks.Size(); i++) - delete [] bablocks[i]; - } - - void BlockAllocator :: Alloc2 () - { - // return new char[size]; - // if (!freelist) - { - // cout << "BlockAlloc: " << size*blocks << endl; - char * hcp = new char [size * blocks]; - bablocks.Append (hcp); - bablocks.Last() = hcp; - for (unsigned i = 0; i < blocks-1; i++) - *(void**)&(hcp[i * size]) = &(hcp[ (i+1) * size]); - *(void**)&(hcp[(blocks-1)*size]) = NULL; - freelist = hcp; - } - /* - void * p = freelist; - freelist = *(void**)freelist; - return p; - */ - } - - /* - void BlockAllocator :: Free (void * p) - { - *(void**)p = freelist; - freelist = p; - } - */ -} diff --git a/Netgen/libsrc/general/optmem.hpp b/Netgen/libsrc/general/optmem.hpp deleted file mode 100644 index d9e5e2137e..0000000000 --- a/Netgen/libsrc/general/optmem.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef FILE_OPTMEM -#define FILE_OPTMEM - -/**************************************************************************/ -/* File: optmem.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 04. Apr. 97 */ -/**************************************************************************/ - -/** - Optimized Memory allocation classes -*/ - -class BlockAllocator -{ -private: - /// - unsigned size, blocks; - /// - void * freelist; - /// - ARRAY<char*> bablocks; -public: - /// - BlockAllocator (unsigned asize, unsigned ablocks = 100); - /// - ~BlockAllocator (); - /// - void * Alloc () - { - if (!freelist) - Alloc2(); - - void * p = freelist; - freelist = *(void**)freelist; - return p; - } - /// - void Free (void * p) - { - *(void**)p = freelist; - freelist = p; - } - - -private: - void Alloc2 (); -}; - - - -#endif diff --git a/Netgen/libsrc/general/parthreads.cpp b/Netgen/libsrc/general/parthreads.cpp deleted file mode 100644 index 81e9d0b6cc..0000000000 --- a/Netgen/libsrc/general/parthreads.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************/ -/* File: parthreads.cpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - - -#include <mystdlib.h> -#include <myadt.hpp> - -/* - -namespace netgen -{ - using namespace netgen; - -#ifdef WIN32 - - NgLock :: NgLock (NgMutex & mut) - : sl(&mut.cs) - { - ; - } - - void NgLock :: Lock () - { - sl.Lock(); - } - void NgLock :: UnLock () - { - sl.Unlock(); - } - - -#else - -#endif -} - -*/ diff --git a/Netgen/libsrc/general/parthreads.hpp b/Netgen/libsrc/general/parthreads.hpp deleted file mode 100644 index 99dd017633..0000000000 --- a/Netgen/libsrc/general/parthreads.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef FILE_PARTHREADS -#define FILE_PARTHREADS - -/**************************************************************************/ -/* File: parthreads.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 22. Nov. 2000 */ -/**************************************************************************/ - -/* - Parallel thread, Mutex, -*/ - -#ifdef NO_PARALLEL_THREADS - -class NgMutex { }; - -class NgLock -{ -public: - NgLock (NgMutex & mut, bool lock = 0) { ; } - void Lock () { ; } - void UnLock () { ; } -}; - - -#else - -#ifdef WIN32 - -class NgMutex -{ - CCriticalSection cs; - -public: - NgMutex () - { ; } - friend class NgLock; -}; - -class NgLock -{ - CSingleLock sl; - bool locked; -public: - NgLock (NgMutex & mut, bool lock = 0) - : sl(&mut.cs) - { - if (lock) sl.Lock(); - locked = lock; - } - - ~NgLock () - { - if (locked) sl.Unlock(); - } - - void Lock () - { - sl.Lock(); - locked = 1; - } - - void UnLock () - { - sl.Unlock(); - locked = 0; - } -}; - -#else - - -#include <pthread.h> - -class NgMutex -{ - pthread_mutex_t mut; -public: - NgMutex () - { - pthread_mutex_init (&mut, NULL); - } - friend class NgLock; -}; - -class NgLock -{ - pthread_mutex_t & mut; - bool locked; -public: - NgLock (NgMutex & ngmut, bool lock = 0) - : mut (ngmut.mut) - { - if (lock) pthread_mutex_lock (&mut); - locked = lock; - }; - - ~NgLock() - { - if (locked) pthread_mutex_unlock (&mut); - } - - void Lock () - { - pthread_mutex_lock (&mut); - locked = 1; - } - void UnLock () - { - pthread_mutex_unlock (&mut); - locked = 0; - } - /* - int TryLock () - { - return pthread_mutex_trylock (&mut); - } - */ -}; - -#endif - -#endif - -#endif diff --git a/Netgen/libsrc/general/seti.cpp b/Netgen/libsrc/general/seti.cpp deleted file mode 100644 index 702337f076..0000000000 --- a/Netgen/libsrc/general/seti.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - - -namespace netgen -{ - using namespace netgen; - - IndexSet :: IndexSet (int maxind) - { - SetMaxIndex (maxind); - } - - IndexSet :: ~IndexSet () - { - Clear(); - } - - - void IndexSet :: SetMaxIndex (int maxind) - { - if (maxind > flags.Size()) - { - flags.SetSize (2 * maxind); - flags.Clear(); - } - } - - /* - int IndexSet :: IsIn (int ind) const - { - return flags.Test (ind); - } - */ - - /* - void IndexSet :: Add (int ind) - { - if (ind > flags.Size()) - { - cerr << "out of range" << endl; - exit (1); - } - - if (!flags.Test(ind)) - { - set.Append (ind); - flags.Set (ind); - } - } - */ - - void IndexSet :: Del (int ind) - { - for (int i = 1; i <= set.Size(); i++) - if (set.Get(i) == ind) - { - set.DeleteElement (ind); - break; - } - flags.Clear (ind); - } - - void IndexSet :: Clear () - { - for (int i = 1; i <= set.Size(); i++) - flags.Clear (set.Get(i)); - set.SetSize (0); - } -} diff --git a/Netgen/libsrc/general/seti.hpp b/Netgen/libsrc/general/seti.hpp deleted file mode 100644 index 4ca0b8eb4e..0000000000 --- a/Netgen/libsrc/general/seti.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef FILE_SETI -#define FILE_SETI - - -/**************************************************************************/ -/* File: seti.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Mar. 98 */ -/**************************************************************************/ - -/** - Set of Integers - */ -class IndexSet -{ - ARRAY<int> set; - BitArray flags; -public: - IndexSet (int maxind); - - ~IndexSet (); - /// increase range to maxind - void SetMaxIndex (int maxind); - int IsIn (int ind) const - { - return flags.Test (ind); - } - - void Add (int ind) - { - if (!flags.Test(ind)) - { - set.Append (ind); - flags.Set (ind); - } - } - - void Del (int ind); - void Clear (); - - const ARRAY<int> & Array() { return set; } -}; - -#endif - diff --git a/Netgen/libsrc/general/sort.cpp b/Netgen/libsrc/general/sort.cpp deleted file mode 100644 index 264a132a74..0000000000 --- a/Netgen/libsrc/general/sort.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************/ -/* File: sort.cc */ -/* Author: Joachim Schoeberl */ -/* Date: 07. Jan. 00 */ -/**************************************************************************/ - -/* - Sorting -*/ - - -#include <algorithm> -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - -void Sort (const ARRAY<double> & values, - ARRAY<int> & order) -{ - int n = values.Size(); - int i, j; - - order.SetSize (n); - - for (i = 1; i <= n; i++) - order.Elem(i) = i; - for (i = 1; i <= n-1; i++) - for (j = 1; j <= n-1; j++) - if (values.Get(order.Elem(j)) > values.Get(order.Elem(j+1))) - { - Swap (order.Elem(j), order.Elem(j+1)); - } -} - - -void QickSortRec (const ARRAY<double> & values, - ARRAY<int> & order, - int left, int right) -{ - int i, j; - double midval; - - i = left; - j = right; - midval = values.Get(order.Get((i+j)/2)); - - do - { - while (values.Get(order.Get(i)) < midval) i++; - while (midval < values.Get(order.Get(j))) j--; - - if (i <= j) - { - Swap (order.Elem(i), order.Elem(j)); - i++; j--; - } - } - while (i <= j); - if (left < j) QickSortRec (values, order, left, j); - if (i < right) QickSortRec (values, order, i, right); -} - -void QickSort (const ARRAY<double> & values, - ARRAY<int> & order) -{ - int i, n = values.Size(); - order.SetSize (n); - for (i = 1; i <= n; i++) - order.Elem(i) = i; - - QickSortRec (values, order, 1, order.Size()); -} -} diff --git a/Netgen/libsrc/general/sort.hpp b/Netgen/libsrc/general/sort.hpp deleted file mode 100644 index 99c3291000..0000000000 --- a/Netgen/libsrc/general/sort.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FILE_SORT -#define FILE_SORT - -/**************************************************************************/ -/* File: sort.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 07. Jan. 00 */ -/**************************************************************************/ - - -// order(i) is sorted index of element i -extern void Sort (const ARRAY<double> & values, - ARRAY<int> & order); - -extern void QickSort (const ARRAY<double> & values, - ARRAY<int> & order); - - -#endif diff --git a/Netgen/libsrc/general/spbita2d.cpp b/Netgen/libsrc/general/spbita2d.cpp deleted file mode 100644 index e1e80e2cad..0000000000 --- a/Netgen/libsrc/general/spbita2d.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************/ -/* File: spbita2d.cpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - Implementation of sparse 2 dimensional bitarray -*/ - - -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - using namespace netgen; - - SPARSE_BIT_ARRAY_2D :: SPARSE_BIT_ARRAY_2D (int ah, int aw) - { - lines = NULL; - SetSize (ah, aw); - } - - SPARSE_BIT_ARRAY_2D :: ~SPARSE_BIT_ARRAY_2D () - { - DeleteElements (); - delete lines; - } - - - void SPARSE_BIT_ARRAY_2D :: SetSize (int ah, int aw) - { - DeleteElements(); - if (lines) - { - delete lines; - lines = NULL; - } - - if (!aw) aw = ah; - - height = ah; - width = aw; - - if (!ah) return; - lines = new linestruct[ah]; - - if (lines) - { - for (int i = 0; i < ah; i++) - { - lines[i].size = 0; - lines[i].maxsize = 0; - lines[i].col = NULL; - } - } - else - { - height = width = 0; - MyError ("SPARSE_ARRAY::SetSize: Out of memory"); - } - } - - - - void SPARSE_BIT_ARRAY_2D :: DeleteElements () - { - if (lines) - { - for (int i = 0; i < height; i++) - { - if (lines[i].col) - { - delete [] lines[i].col; - lines[i].col = NULL; - lines[i].size = 0; - lines[i].maxsize = 0; - } - } - } - } - - - int SPARSE_BIT_ARRAY_2D :: Test (int i, int j) const - { - int k, max, *col; - - if (!lines) return 0; - if (i < 1 || i > height) return 0; - - col = lines[i-1].col; - max = lines[i-1].size; - - for (k = 0; k < max; k++, col++) - if (*col == j) return 1; - - return 0; - } - - - - void SPARSE_BIT_ARRAY_2D :: Set(int i, int j) - { - int k, max, *col; - - i--; - col = lines[i].col; - max = lines[i].size; - - for (k = 0; k < max; k++, col++) - if (*col == j) - return; - - if (lines[i].size) - { - if (lines[i].size == lines[i].maxsize) - { - col = new int[lines[i].maxsize+2]; - if (col) - { - lines[i].maxsize += 2; - memcpy (col, lines[i].col, sizeof (int) * lines[i].size); - delete [] lines[i].col; - lines[i].col = col; - } - else - { - MyError ("SPARSE_BIT_ARRAY::Set: Out of mem 1"); - return; - } - } - else - col = lines[i].col; - - if (col) - { - k = lines[i].size-1; - while (k >= 0 && col[k] > j) - { - col[k+1] = col[k]; - k--; - } - - k++; - lines[i].size++; - col[k] = j; - return; - } - else - { - MyError ("SPARSE_ARRAY::Set: Out of memory 2"); - } - } - else - { - lines[i].col = new int[4]; - if (lines[i].col) - { - lines[i].maxsize = 4; - lines[i].size = 1; - lines[i].col[0] = j; - return; - } - else - { - MyError ("SparseMatrix::Elem: Out of memory 3"); - } - } - } - -} diff --git a/Netgen/libsrc/general/spbita2d.hpp b/Netgen/libsrc/general/spbita2d.hpp deleted file mode 100644 index db656653b1..0000000000 --- a/Netgen/libsrc/general/spbita2d.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef FILE_SPBITA2D -#define FILE_SPBITA2D - -/**************************************************************************/ -/* File: spbita2d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/** - Implementation of sparse 2 dimensional bitarray -*/ - - -class SPARSE_BIT_ARRAY_2D - { - class linestruct { public: INDEX size; INDEX maxsize; INDEX * col; }; - - /// - linestruct * lines; - /// - INDEX height, width; - - public: - - /// - SPARSE_BIT_ARRAY_2D (INDEX ah = 0, INDEX aw = 0); - /// - ~SPARSE_BIT_ARRAY_2D (); - - /// - void SetSize (INDEX ah, INDEX aw = 0); - /// - void DeleteElements (); - - /// - int Get (INDEX i, INDEX j) const; - - /// - INDEX Height () const { return height; } - /// - INDEX Width () const { return width; } - - /// - void Set (INDEX i, INDEX j); - /// - int Test (INDEX i, INDEX j) const; - - /// - INDEX BitsInLine (INDEX i) const { return lines[i-1].size; } - /// - INDEX GetIndex (INDEX i, INDEX nr) const { return lines[i-1].col[nr-1]; } - }; - - -#endif diff --git a/Netgen/libsrc/general/stack.hpp b/Netgen/libsrc/general/stack.hpp deleted file mode 100644 index db8dfad266..0000000000 --- a/Netgen/libsrc/general/stack.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef FILE_STACK -#define FILE_STACK - -/*****************************************************************************/ -/* File: stack.hh */ -/* Author: Wolfram Muehlhuber */ -/* Date: September 98 */ -/*****************************************************************************/ - -/* - - Stack class, based on a resizable array - - */ - - -#include "array.hpp" - - -/// -template <class T> class STACK -{ -public: - /// - inline STACK (INDEX asize = 0, INDEX ainc = 0); - /// - inline ~STACK (); - - /// - inline void Push (const T & el); - /// - inline T & Pop (); - /// - const inline T & Top () const; - /// - inline int IsEmpty () const; - /// - inline void MakeEmpty (); - -private: - /// - ARRAY<T> elems; - /// - INDEX size; -}; - - - - -/* - - Stack class, based on a resizable array - - */ - -template <class T> -inline STACK<T> :: STACK (INDEX asize, INDEX ainc) - : elems(asize, ainc) -{ - size = 0; -} - - -template <class T> -inline STACK<T> :: ~STACK () -{ - ; -} - - -template <class T> -inline void STACK<T> :: Push (const T & el) -{ - if (size < elems.Size()) - elems.Elem(++size) = el; - else - { - elems.Append(el); - size++; - } -} - - -template <class T> -inline T & STACK<T> :: Pop () -{ - return elems.Elem(size--); -} - - -template <class T> -const inline T & STACK<T> :: Top () const -{ - return elems.Get(size); -} - -template <class T> -inline int STACK<T> :: IsEmpty () const -{ - return (size == 0); -} - - -template <class T> -inline void STACK<T> :: MakeEmpty () -{ - size = 0; -} - - - -#endif diff --git a/Netgen/libsrc/general/stack.icc b/Netgen/libsrc/general/stack.icc deleted file mode 100644 index c0182a564b..0000000000 --- a/Netgen/libsrc/general/stack.icc +++ /dev/null @@ -1,67 +0,0 @@ -/*****************************************************************************/ -/* File: stack.hh */ -/* Author: Wolfram Muehlhuber */ -/* Date: September 98 */ -/*****************************************************************************/ - -/* - - Stack class, based on a resizable array - - */ - -template <class T> -inline STACK<T> :: STACK (INDEX asize, INDEX ainc) - : elems(asize, ainc) -{ - size = 0; -} - - -template <class T> -inline STACK<T> :: ~STACK () -{ - ; -} - - -template <class T> -inline void STACK<T> :: Push (const T & el) -{ - if (size < elems.Size()) - elems.Elem(++size) = el; - else - { - elems.Append(el); - size++; - } -} - - -template <class T> -inline T & STACK<T> :: Pop () -{ - return elems.Elem(size--); -} - - -template <class T> -const inline T & STACK<T> :: Top () const -{ - return elems.Get(size); -} - -template <class T> -inline int STACK<T> :: IsEmpty () const -{ - return (size == 0); -} - - -template <class T> -inline void STACK<T> :: MakeEmpty () -{ - size = 0; -} - - diff --git a/Netgen/libsrc/general/symbolta.cpp b/Netgen/libsrc/general/symbolta.cpp deleted file mode 100644 index b02daa65dc..0000000000 --- a/Netgen/libsrc/general/symbolta.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************/ -/* File: symbolta.cc */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - Abstract data type Symbol Table -*/ - -#include <mystdlib.h> -#include <myadt.hpp> - - -#ifndef FILE_SYMBOLTABLECC -#define FILE_SYMBOLTABLECC -// necessary for SGI ???? - - -namespace netgen -{ - using namespace netgen; - - BASE_SYMBOLTABLE :: BASE_SYMBOLTABLE () - { - ; - } - - - BASE_SYMBOLTABLE :: ~BASE_SYMBOLTABLE() - { - DelNames(); - } - - - void BASE_SYMBOLTABLE :: DelNames() - { - for (int i = 0; i < names.Size(); i++) - delete [] names[i]; - names.SetSize (0); - } - - int BASE_SYMBOLTABLE :: Index (const char * name) const - { - if (!name) return 0; - for (int i = 0; i < names.Size(); i++) - if (strcmp (names[i], name) == 0) return i+1; - return 0; - } -} - -#endif diff --git a/Netgen/libsrc/general/symbolta.hpp b/Netgen/libsrc/general/symbolta.hpp deleted file mode 100644 index 6b8916e8ea..0000000000 --- a/Netgen/libsrc/general/symbolta.hpp +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef FILE_SYMBOLTA -#define FILE_SYMBOLTA - - -/**************************************************************************/ -/* File: symbolta.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/** - Base class for the generic SYMBOLTABLE. - An array of identifiers is maintained. -*/ -class BASE_SYMBOLTABLE -{ -protected: - /// identifiers - ARRAY <char*> names; - -public: - /// Constructor - BASE_SYMBOLTABLE (); - /// - ~BASE_SYMBOLTABLE (); - /// - void DelNames (); - /// Index of symbol name, returns 0 if not used. - int Index (const char * name) const; -}; - - -/** - Abstract data type Symbol Table. - - To a string an value of the generic type T is associated. - The string is not copied into the symbol table class! -*/ -template <class T> -class SYMBOLTABLE : public BASE_SYMBOLTABLE -{ -private: - /// Associated data - ARRAY <T> data; - -public: - /// Creates a symboltable - inline SYMBOLTABLE (); - /// Returns size of symboltable - inline INDEX Size() const; - /// Returns reference to element, error if not used - inline T & Elem (const char * name); - /// Returns reference to i-th element - inline T & Elem (int i) - { return data.Elem(i); } - /// Returns element, error if not used - inline const T & Get (const char * name) const; - /// Returns i-th element - inline const T & Get (int i) const; - /// Returns name of i-th element - inline const char* GetName (int i) const; - /// Associates el to the string name, overrides if name is used - inline void Set (const char * name, const T & el); - /// Checks whether name is used - inline int Used (const char * name) const; - /// Deletes symboltable - inline void DeleteAll (); - - inline T & operator[] (int i) - { return data[i]; } - inline const T & operator[] (int i) const - { return data[i]; } - -private: - /// Prevents from copying symboltable by pointer assignment - SYMBOLTABLE<T> & operator= (SYMBOLTABLE<T> &); -}; - - - - -template <class T> -inline SYMBOLTABLE<T> :: SYMBOLTABLE () -{ - ; -} - - -template <class T> -inline INDEX SYMBOLTABLE<T> :: Size() const -{ - return data.Size(); -} - -template <class T> -inline T & SYMBOLTABLE<T> :: Elem (const char * name) -{ - int i = Index (name); - if (i) - return data.Elem (i); - else - return data.Elem(1); -} - -template <class T> -inline const T & SYMBOLTABLE<T> :: Get (const char * name) const -{ - int i; - i = Index (name); - if (i) - return data.Get(i); - else - return data.Get(1); -} - -template <class T> -inline const T & SYMBOLTABLE<T> :: Get (int i) const -{ - return data.Get(i); -} - -template <class T> -inline const char* SYMBOLTABLE<T> :: GetName (int i) const -{ - return names.Get(i); -} - -template <class T> -inline void SYMBOLTABLE<T> :: Set (const char * name, const T & el) -{ - int i; - i = Index (name); - if (i) - data.Set(i, el); - else - { - data.Append (el); - char * hname = new char [strlen (name) + 1]; - strcpy (hname, name); - names.Append (hname); - } -} - -template <class T> -inline int SYMBOLTABLE<T> :: Used (const char * name) const -{ - return (Index(name)) ? 1 : 0; -} - -template <class T> -inline void SYMBOLTABLE<T> :: DeleteAll () -{ - DelNames(); - data.DeleteAll(); -} - - -#endif diff --git a/Netgen/libsrc/general/table.cpp b/Netgen/libsrc/general/table.cpp deleted file mode 100644 index ed84789bf9..0000000000 --- a/Netgen/libsrc/general/table.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************/ -/* File: table.cpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - Abstract data type TABLE -*/ - -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - using namespace netgen; - - BASE_TABLE :: BASE_TABLE (int size) - : data(size) - { - for (int i = 0; i < size; i++) - { - data[i].maxsize = 0; - data[i].size = 0; - data[i].col = NULL; - } - oneblock = NULL; - } - - BASE_TABLE :: BASE_TABLE (const FlatArray<int> & entrysizes, int elemsize) - : data(entrysizes.Size()) - { - int i, cnt = 0; - int n = entrysizes.Size(); - - for (i = 0; i < n; i++) - cnt += entrysizes[i]; - oneblock = new char[elemsize * cnt]; - // mem_total_alloc_table += elemsize * cnt; - - cnt = 0; - for (i = 0; i < n; i++) - { - data[i].maxsize = entrysizes[i]; - data[i].size = 0; - - data[i].col = &oneblock[elemsize * cnt]; - cnt += entrysizes[i]; - } - } - - BASE_TABLE :: ~BASE_TABLE () - { - if (oneblock) - delete [] oneblock; - else - { - for (int i = 0; i < data.Size(); i++) - delete [] (char*)data[i].col; - } - } - - void BASE_TABLE :: SetSize (int size) - { - for (int i = 0; i < data.Size(); i++) - delete [] (char*)data[i].col; - - data.SetSize(size); - for (int i = 0; i < size; i++) - { - data[i].maxsize = 0; - data[i].size = 0; - data[i].col = NULL; - } - } - - void BASE_TABLE :: IncSize2 (int i, int elsize) - { -#ifdef DEBUG - if (i < 0 || i >= data.Size()) - { - MyError ("BASE_TABLE::Inc: Out of range"); - return; - } -#endif - - linestruct & line = data[i]; - if (line.size == line.maxsize) - { - void * p = new char [(line.maxsize+5) * elsize]; - - memcpy (p, line.col, line.maxsize * elsize); - delete [] (char*)line.col; - - line.col = p; - line.maxsize += 5; - } - - line.size++; - } - - - - /* - void BASE_TABLE :: DecSize (int i) - { -#ifdef DEBUG - if (i < 0 || i >= data.Size()) - { - MyError ("BASE_TABLE::Dec: Out of range"); - return; - } -#endif - - linestruct & line = data[i]; - -#ifdef DEBUG - if (line.size == 0) - { - MyError ("BASE_TABLE::Dec: EntrySize < 0"); - return; - } -#endif - - line.size--; - } - */ - - - - void BASE_TABLE :: AllocateElementsOneBlock (int elemsize) - { - int cnt = 0; - int n = data.Size(); - - for (int i = 0; i < n; i++) - cnt += data[i].maxsize; - oneblock = new char[elemsize * cnt]; - - cnt = 0; - for (int i = 0; i < n; i++) - { - data[i].size = 0; - data[i].col = &oneblock[elemsize * cnt]; - cnt += data[i].maxsize; - } - } - - - - int BASE_TABLE :: AllocatedElements () const - { - int els = 0; - for (int i = 0; i < data.Size(); i++) - els += data[i].maxsize; - return els; - } - - int BASE_TABLE :: UsedElements () const - { - int els = 0; - for (int i = 0; i < data.Size(); i++) - els += data[i].size; - return els; - } - -} diff --git a/Netgen/libsrc/general/table.hpp b/Netgen/libsrc/general/table.hpp deleted file mode 100644 index b986049b00..0000000000 --- a/Netgen/libsrc/general/table.hpp +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef FILE_TABLE -#define FILE_TABLE - -/**************************************************************************/ -/* File: table.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/// Base class to generic class TABLE. -class BASE_TABLE -{ -protected: - - /// - class linestruct - { - public: - /// - int size; - /// - int maxsize; - /// - void * col; - }; - - /// - ARRAY<linestruct> data; - char * oneblock; - -public: - /// - BASE_TABLE (int size); - /// - BASE_TABLE (const FlatArray<int> & entrysizes, int elemsize); - /// - ~BASE_TABLE (); - /// - void SetSize (int size); - - /// increment size of entry i by one, i is 0-based - void IncSize (int i, int elsize) - { - if (data[i].size < data[i].maxsize) - data[i].size++; - else - IncSize2 (i, elsize); - } - /// - void IncSize2 (int i, int elsize); - - // void DecSize (int i); - - /// - void AllocateElementsOneBlock (int elemsize); - - int AllocatedElements () const; - int UsedElements () const; -}; - - - - - - - -/** - Abstract data type TABLE. - - To an integer i in the range from 1 to size a set of elements of the - generic type T is associated. -*/ -template <class T, int BASE = 0> -class TABLE : public BASE_TABLE -{ -public: - /// Creates table. - inline TABLE () : BASE_TABLE(0) { ; } - - /// Creates table of size size - inline TABLE (int size) : BASE_TABLE (size) { ; } - - /// Creates fixed element size table - inline TABLE (const FlatArray<int,BASE> & entrysizes) - : BASE_TABLE (FlatArray<int> (entrysizes.Size(), const_cast<int*>(&entrysizes[BASE])), - sizeof(T)) - { ; } - - /// Changes Size of table to size, deletes data - inline void SetSize (int size) - { - BASE_TABLE::SetSize (size); - } - - - /// Inserts element acont into row i, BASE-based. Does not test if already used. - inline void Add (int i, const T & acont) - { - IncSize (i-BASE, sizeof (T)); - ((T*)data[i-BASE].col)[data[i-BASE].size-1] = acont; - } - - - /// Inserts element acont into row i, 1-based. Does not test if already used. - inline void Add1 (int i, const T & acont) - { - IncSize (i-1, sizeof (T)); - ((T*)data.Elem(i).col)[data.Elem(i).size-1] = acont; - } - - /// - void IncSizePrepare (int i) - { - data[i-BASE].maxsize++; - } - - - /// Inserts element acont into row i. BASE-based. Does not test if already used, assumes to have mem - inline void AddSave (int i, const T & acont) - { - ((T*)data[i-BASE].col)[data[i-BASE].size] = acont; - data[i-BASE].size++; - } - - /// Inserts element acont into row i. 1-based. Does not test if already used, assumes to have mem - inline void AddSave1 (int i, const T & acont) - { - ((T*)data.Elem(i).col)[data.Elem(i).size] = acont; - data.Elem(i).size++; - } - - /// Inserts element acont into row i. Does not test if already used. - inline void AddEmpty (int i) - { - IncSize (i-BASE, sizeof (T)); - } - - /** Set the nr-th element in the i-th row to acont. - Does not check for overflow. */ - inline void Set (int i, int nr, const T & acont) - { ((T*)data.Get(i).col)[nr-1] = acont; } - /** Returns the nr-th element in the i-th row. - Does not check for overflow. */ - inline const T & Get (int i, int nr) const - { return ((T*)data.Get(i).col)[nr-1]; } - - - /** Returns pointer to the first element in row i. */ - inline const T * GetLine (int i) const - { - return ((const T*)data.Get(i).col); - } - - - /// Returns size of the table. - inline int Size () const - { - return data.Size(); - } - - /// Returns size of the i-th row. - inline int EntrySize (int i) const - { return data.Get(i).size; } - - /* - inline void DecEntrySize (int i) - { DecSize(i); } - */ - void AllocateElementsOneBlock () - { BASE_TABLE::AllocateElementsOneBlock (sizeof(T)); } - - - inline void PrintMemInfo (ostream & ost) const - { - int els = AllocatedElements(); - ost << "table: allocaed " << els - << " a " << sizeof(T) << " Byts = " - << els * sizeof(T) - << " bytes in " << Size() << " bags." - << " used: " << UsedElements() - << endl; - } - - /// Access entry. - FlatArray<T> operator[] (int i) const - { -#ifdef DEBUG - if (i-BASE < 0 || i-BASE >= data.Size()) - cout << "table out of range, i = " << i << ", s = " << data.Size() << endl; -#endif - - return FlatArray<T> (data[i-BASE].size, (T*)data[i-BASE].col); - } -}; - - -template <class T, int BASE> -inline ostream & operator<< (ostream & ost, TABLE<T,BASE> & table) -{ - for (int i = BASE; i < table.Size()+BASE; i++) - { - ost << i << ": "; - FlatArray<T> row = table[i]; - for (int j = 0; j < row.Size(); j++) - ost << row[j] << " "; - ost << endl; - } - return ost; -} - -#endif - diff --git a/Netgen/libsrc/general/template.hpp b/Netgen/libsrc/general/template.hpp deleted file mode 100644 index 4bf983c06b..0000000000 --- a/Netgen/libsrc/general/template.hpp +++ /dev/null @@ -1,448 +0,0 @@ -#ifndef FILE_TEMPLATE -#define FILE_TEMPLATE - -/**************************************************************************/ -/* File: template.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - -/* - templates, global types, defines and variables -*/ - -/// The following value may be adapted to the hardware ! -#ifndef CLOCKS_PER_SEC -#define CLOCKS_PER_SEC 1000000 -#endif - - -// #include <iostream> -/** output stream for testing. - testout is opened by main */ -extern ostream * testout; - -/** use instead of cout */ -extern ostream * mycout; - -/** error output stream */ -extern ostream * myerr; - -/** Error messages display. - Error messages are displayed by this function */ -extern void MyError (const char * ch); - - -/** Rings the bell. - Produces nr beeps. */ -extern void MyBeep (int nr = 1); - - -template <class T> -inline void Swap (T & a, T & b) -{ - T temp = a; - a = b; - b = temp; -} - -/* -template <class T> -inline void swap (T & a, T & b) -{ - T temp = a; - a = b; - b = temp; -} -*/ - - - -/** - INDEX is a typedef for (at least) 4-byte integer - */ -typedef int INDEX; - -/** - BOOL is a typedef for boolean variables - */ -// typedef int BOOL; - -typedef int ELIND; -typedef int PIND; - - -class twoint -{ -public: /// - int i1, i2; /// - twoint() {}; - /// - twoint(int ii1, int ii2) {i1 = ii1; i2 = ii2;} - friend int operator== (const twoint& t1, const twoint& t2); - /// - void Swap() {int x = i1; i1 = i2; i2 = x;} - void Sort() {if (i1 > i2) {Swap();}} -}; - -inline int operator== (const twoint& t1, const twoint& t2) -{ - return t1.i1 == t2.i1 && t1.i2 == t2.i2; -} - -class threeint -{ -public: /// - int i1, i2, i3; /// - threeint() {}; - /// - threeint(int ii1, int ii2, int ii3) {i1 = ii1; i2 = ii2; i3 = ii3;} -}; - -/// -class twodouble -{ -public: - /// - double d1, d2; - /// - twodouble() {d1 = 0; d2 = 0;}; - /// - twodouble(double id1, double id2) {d1 = id1; d2 = id2;} - /// - void Swap() {double x = d1; d1 = d2; d2 = x;} -}; - -class fourint { public: int i1, i2, i3, i4; fourint() {}; }; - - -/// -class INDEX_2; -ostream & operator<<(ostream & s, const INDEX_2 & i2); - - -class INDEX_2 -{ - /// - INDEX i[2]; - -public: - /// - INDEX_2 () { } - /// - INDEX_2 (INDEX ai1, INDEX ai2) - { i[0] = ai1; i[1] = ai2; } - - /// - INDEX_2 (const INDEX_2 & in2) - { i[0] = in2.i[0]; i[1] = in2.i[1]; } - - /// - int operator== (const INDEX_2 & in2) const - { return i[0] == in2.i[0] && i[1] == in2.i[1]; } - - /// - - - INDEX_2 Sort () - { - if (i[0] > i[1]) - { - INDEX hi = i[0]; - i[0] = i[1]; - i[1] = hi; - } - return *this; - } - - static INDEX_2 Sort (int i1, int i2) - { - if (i1 > i2) - return INDEX_2 (i2,i1); - else - return INDEX_2 (i1,i2); - } - - - /// - INDEX & I1 () { return i[0]; } - /// - INDEX & I2 () { return i[1]; } - /// - INDEX & I (int j) { return i[j-1]; } - /// - const INDEX & I1 () const { return i[0]; } - /// - const INDEX & I2 () const { return i[1]; } - /// - const INDEX & I (int j) const { return i[j-1]; } - /// - int & operator[] (int j) { return i[j]; } - /// - const int & operator[] (int j) const { return i[j]; } - /// - friend ostream & operator<<(ostream & s, const INDEX_2 & i2); -}; - - -/// -class INDEX_3 -{ - /// - INDEX i[3]; - -public: - /// - INDEX_3 () { } - /// - INDEX_3 (INDEX ai1, INDEX ai2, INDEX ai3) - { i[0] = ai1; i[1] = ai2; i[2] = ai3; } - - /// - INDEX_3 (const INDEX_3 & in2) - { i[0] = in2.i[0]; i[1] = in2.i[1]; i[2] = in2.i[2]; } - - - static INDEX_3 Sort (INDEX_3 i3) - { - return i3.Sort(); - } - - static INDEX_3 Sort (int i1, int i2, int i3) - { - INDEX_3 i(i1, i2, i3); - return i.Sort(); - } - - /// - INDEX_3 Sort () - { - if (i[0] > i[1]) Swap (i[0], i[1]); - if (i[1] > i[2]) Swap (i[1], i[2]); - if (i[0] > i[1]) Swap (i[0], i[1]); - return *this; - } - - /// - int operator== (const INDEX_3 & in2) const - { return i[0] == in2.i[0] && i[1] == in2.i[1] && i[2] == in2.i[2];} - - /// - INDEX & I1 () { return i[0]; } - /// - INDEX & I2 () { return i[1]; } - /// - INDEX & I3 () { return i[2]; } - /// - INDEX & I (int j) { return i[j-1]; } - /// - const INDEX & I1 () const { return i[0]; } - /// - const INDEX & I2 () const { return i[1]; } - /// - const INDEX & I3 () const { return i[2]; } - /// - const INDEX & I (int j) const { return i[j-1]; } - /// - int & operator[] (int j) { return i[j]; } - /// - const int & operator[] (int j) const { return i[j]; } - - /// - friend ostream & operator<<(ostream & s, const INDEX_3 & i3); -}; - - - -/// -class INDEX_4 -{ - /// - INDEX i[4]; - -public: - /// - INDEX_4 () { } - /// - INDEX_4 (INDEX ai1, INDEX ai2, INDEX ai3, INDEX ai4) - { i[0] = ai1; i[1] = ai2; i[2] = ai3; i[3] = ai4; } - - /// - INDEX_4 (const INDEX_4 & in2) - { i[0] = in2.i[0]; i[1] = in2.i[1]; i[2] = in2.i[2]; i[3] = in2.i[3]; } - - /// - void Sort (); - - /// - int operator== (const INDEX_4 & in2) const - { return - i[0] == in2.i[0] && i[1] == in2.i[1] && - i[2] == in2.i[2] && i[3] == in2.i[3]; } - - /// - INDEX & I1 () { return i[0]; } - /// - INDEX & I2 () { return i[1]; } - /// - INDEX & I3 () { return i[2]; } - /// - INDEX & I4 () { return i[3]; } - /// - INDEX & I (int j) { return i[j-1]; } - /// - const INDEX & I1 () const { return i[0]; } - /// - const INDEX & I2 () const { return i[1]; } - /// - const INDEX & I3 () const { return i[2]; } - /// - const INDEX & I4 () const { return i[3]; } - /// - const INDEX & I (int j) const { return i[j-1]; } - /// - int & operator[] (int j) { return i[j]; } - /// - const int & operator[] (int j) const { return i[j]; } - - /// - friend ostream & operator<<(ostream & s, const INDEX_4 & i4); -}; - - - - - - - - -/// The sort preserves quads !!! -class INDEX_4Q -{ - /// - INDEX i[4]; - -public: - /// - INDEX_4Q () { } - /// - INDEX_4Q (INDEX ai1, INDEX ai2, INDEX ai3, INDEX ai4) - { i[0] = ai1; i[1] = ai2; i[2] = ai3; i[3] = ai4; } - - /// - INDEX_4Q (const INDEX_4Q & in2) - { i[0] = in2.i[0]; i[1] = in2.i[1]; i[2] = in2.i[2]; i[3] = in2.i[3]; } - - /// - void Sort (); - - /// - int operator== (const INDEX_4Q & in2) const - { return - i[0] == in2.i[0] && i[1] == in2.i[1] && - i[2] == in2.i[2] && i[3] == in2.i[3]; } - - /// - INDEX & I1 () { return i[0]; } - /// - INDEX & I2 () { return i[1]; } - /// - INDEX & I3 () { return i[2]; } - /// - INDEX & I4 () { return i[3]; } - /// - INDEX & I (int j) { return i[j-1]; } - /// - const INDEX & I1 () const { return i[0]; } - /// - const INDEX & I2 () const { return i[1]; } - /// - const INDEX & I3 () const { return i[2]; } - /// - const INDEX & I4 () const { return i[3]; } - /// - const INDEX & I (int j) const { return i[j-1]; } - /// - friend ostream & operator<<(ostream & s, const INDEX_4Q & i4); -}; - - - - - - - - - - - - -/// -template <class T> -inline T min2 (T a, T b) -{ - /// - return (a < b) ? a : b; -} -/// -template <class T> -inline T max2 (T a, T b) -{ - /// - return (a > b) ? a : b; -} -/// -template <class T> -inline T min3 (T a, T b, T c) -{ - /// - return (a < b) ? (a < c) ? a : c - : (b < c) ? b : c; -} -/// -template <class T> -inline T max3 (T a, T b, T c) -{ - /// - return (a > b) ? ((a > c) ? a : c) - : ((b > c) ? b : c); -} - -/// - -/// -template <class T> -inline int sgn (T a) -{ - return (a > 0) ? 1 : ( ( a < 0) ? -1 : 0 ); -} - -/// -template <class T> -inline T sqr (const T a) -{ - return a * a; -} - -/// -template <class T> -inline T pow3 (const T a) -{ - return a * a * a; -} - - - -/* -template <class T> -void BubbleSort (int size, T * data); - -template <class T> -void MergeSort (int size, T * data, T * help); -*/ - - - - - -#endif diff --git a/Netgen/libsrc/geom2d/Makefile b/Netgen/libsrc/geom2d/Makefile deleted file mode 100644 index 8371fa19e7..0000000000 --- a/Netgen/libsrc/geom2d/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for geometric library -# -src = spline2d.cpp geom2dmesh.cpp splinegeometry2.cpp genmesh2d.cpp -# -lib = geom2d -libpath = libsrc/geom2d -# -# -include ../makefile.inc -# - diff --git a/Netgen/libsrc/geom2d/genmesh2d.cpp b/Netgen/libsrc/geom2d/genmesh2d.cpp deleted file mode 100644 index 34f93b66ee..0000000000 --- a/Netgen/libsrc/geom2d/genmesh2d.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include <mystdlib.h> -#include <csg.hpp> -#include <geometry2d.hpp> -#include "meshing.hpp" - -namespace netgen -{ - - // static ARRAY<Point<2> > points2; - // static ARRAY<int> lp1, lp2; - - - extern void Optimize2d (Mesh & mesh, MeshingParameters & mp); - - - - - void MeshFromSpline2D (SplineGeometry2d & geometry, - Mesh *& mesh, - MeshingParameters & mp) - { - int i, j, domnr; - double elto0, minx, miny, maxx, maxy; - - // mp.Print(*testout); - - PointIndex pi; - SegmentIndex si; - SurfaceElementIndex sei; - - double h = mp.maxh; - - Box<2> bbox; - geometry.GetBoundingBox (bbox); - - if (bbox.Diam() < h) - { - h = bbox.Diam(); - mp.maxh = h; - } - - mesh = new Mesh; - mesh->SetDimension (2); - PrintMessage (1, "Generate Mesh from spline geometry"); - - geometry.PartitionBoundary (h, *mesh); - - for (i = 0; i < geometry.GetNP(); i++) - if (geometry.GetPoint(i).hpref) - { - double mindist = 1e99; - PointIndex mpi; - Point<2> gp = geometry.GetPoint(i); - Point<3> gp3(gp(0), gp(1), 0); - for (PointIndex pi = PointIndex::BASE; - pi < mesh->GetNP()+PointIndex::BASE; pi++) - if (Dist2(gp3, (*mesh)[pi]) < mindist) - { - mpi = pi; - mindist = Dist2(gp3, (*mesh)[pi]); - } - (*mesh)[mpi].SetSingular(); - } - - - int maxdomnr = 0; - for (si = 0; si < mesh->GetNSeg(); si++) - { - if ( (*mesh)[si].domin > maxdomnr) maxdomnr = (*mesh)[si].domin; - if ( (*mesh)[si].domout > maxdomnr) maxdomnr = (*mesh)[si].domout; - } - - mesh->ClearFaceDescriptors(); - for (i = 1; i <= maxdomnr; i++) - mesh->AddFaceDescriptor (FaceDescriptor (i, 0, 0, i)); - - Point3d pmin(bbox.PMin()(0), bbox.PMin()(1), -bbox.Diam()); - Point3d pmax(bbox.PMax()(0), bbox.PMax()(1), bbox.Diam()); - - mesh->SetLocalH (pmin, pmax, mparam.grading); - mesh->SetGlobalH (h); - - mesh->CalcLocalH(); - - int bnp = mesh->GetNP(); // boundary points - - for (domnr = 1; domnr <= maxdomnr; domnr++) - { - PrintMessage (3, "Meshing domain ", domnr, " / ", maxdomnr); - - int oldnf = mesh->GetNSE(); - - Meshing2 meshing (Box3d (pmin, pmax)); - - for (pi = PointIndex::BASE; - pi < bnp+PointIndex::BASE; pi++) - meshing.AddPoint ( (*mesh)[pi], pi); - - - PointGeomInfo gi; - gi.trignum = 1; - for (si = 0; si < mesh->GetNSeg(); si++) - { - if ( (*mesh)[si].domin == domnr) - meshing.AddBoundaryElement ( (*mesh)[si].p1 + 1 - PointIndex::BASE, - (*mesh)[si].p2 + 1 - PointIndex::BASE, gi, gi); - if ( (*mesh)[si].domout == domnr) - meshing.AddBoundaryElement ( (*mesh)[si].p2 + 1 - PointIndex::BASE, - (*mesh)[si].p1 + 1 - PointIndex::BASE, gi, gi); - } - - - mparam.checkoverlap = 0; - meshing.GenerateMesh (*mesh, h, domnr); - - for (sei = oldnf; sei < mesh->GetNSE(); sei++) - (*mesh)[sei].SetIndex (domnr); - } - - - int hsteps = mp.optsteps2d; - - mp.optimize2d = "smcm"; - mp.optsteps2d = hsteps/2; - Optimize2d (*mesh, mp); - - mp.optimize2d = "Smcm"; - mp.optsteps2d = (hsteps+1)/2; - Optimize2d (*mesh, mp); - - mp.optsteps2d = hsteps; - - mesh->Compress(); - mesh -> SetNextMajorTimeStamp(); - - -#ifdef OPENGL - extern void Render(); - Render(); -#endif - - } - - -} diff --git a/Netgen/libsrc/geom2d/geom2dmesh.cpp b/Netgen/libsrc/geom2d/geom2dmesh.cpp deleted file mode 100644 index 1b679bd3c0..0000000000 --- a/Netgen/libsrc/geom2d/geom2dmesh.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include <mystdlib.h> - -#include <csg.hpp> -#include <geometry2d.hpp> -#include <meshing.hpp> - -namespace netgen -{ - - Refinement2d :: Refinement2d (const SplineGeometry2d & ageometry) - : Refinement(), geometry(ageometry) - { - ; - } - - Refinement2d :: ~Refinement2d () - { - ; - } - - - void Refinement2d :: - PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi) - { - newp = p1+secpoint*(p2-p1); - newgi.trignum = 1; - } - - - - void Refinement2d :: - PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi) - { - Point<2> p2d; - - p2d = geometry.GetSplines().Get(ap1.edgenr) -> - GetPoint (((1-secpoint)*ap1.dist+secpoint*ap2.dist)); - - // (*testout) << "refine 2d line, ap1.dist, ap2.dist = " << ap1.dist << ", " << ap2.dist << endl; - // (*testout) << "p1, p2 = " << p1 << p2 << ", newp = " << p2d << endl; - - newp = Point3d (p2d(0), p2d(1), 0); - newgi.edgenr = ap1.edgenr; - newgi.dist = ((1-secpoint)*ap1.dist+secpoint*ap2.dist); - } - -} diff --git a/Netgen/libsrc/geom2d/geom2dmesh.hpp b/Netgen/libsrc/geom2d/geom2dmesh.hpp deleted file mode 100644 index 6912cd7752..0000000000 --- a/Netgen/libsrc/geom2d/geom2dmesh.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef FILE_GEOM2DMESH -#define FILE_GEOM2DMESH - -/**************************************************************************/ -/* File: geom2dmesh.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 22. Jan. 01 */ -/**************************************************************************/ - - -class Refinement2d : public Refinement -{ - const SplineGeometry2d & geometry; - -public: - Refinement2d (const SplineGeometry2d & ageometry); - virtual ~Refinement2d (); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi); - -}; - - - - - - -#endif diff --git a/Netgen/libsrc/geom2d/geometry2d.hpp b/Netgen/libsrc/geom2d/geometry2d.hpp deleted file mode 100644 index 80d276e340..0000000000 --- a/Netgen/libsrc/geom2d/geometry2d.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef FILE_GEOMETRY2D -#define FILE_GEOMETRY2D - -/* *************************************************************************/ -/* File: geometry2d.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Jul. 02 */ -/* *************************************************************************/ - -#include <myadt.hpp> -#include <gprim.hpp> - -namespace netgen -{ -#include "spline2d.hpp" -#include "splinegeometry2.hpp" -#include "geom2dmesh.hpp" -} - -#endif diff --git a/Netgen/libsrc/geom2d/spline2d.cpp b/Netgen/libsrc/geom2d/spline2d.cpp deleted file mode 100644 index 8609e064d1..0000000000 --- a/Netgen/libsrc/geom2d/spline2d.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/* - -2d Spline curve for Mesh generator - -*/ - -#include <mystdlib.h> -#include <csg.hpp> -#include <linalg.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "spline2d.hpp" - - - void CalcPartition (double l, double h, double r1, double r2, - double ra, double elto0, ARRAY<double> & points); - - - - // calculates length of spline-curve - double SplineSegment :: Length () const - { - Point<2> p, pold; - - int i, n = 100; - double dt = 1.0 / n; - - pold = GetPoint (0); - - double l = 0; - for (i = 1; i <= n; i++) - { - p = GetPoint (i * dt); - l += Dist (p, pold); - pold = p; - } - return l; - } - - - - // partitionizes spline curve - void SplineSegment :: Partition (double h, double elto0, - Mesh & mesh, Point3dTree & searchtree, int segnr) const - { - int i, j; - double l, r1, r2, ra; - double lold, dt, frac; - int n = 100; - Point<2> p, pold, mark, oldmark; - ARRAY<double> curvepoints; - double edgelength, edgelengthold; - l = Length(); - - r1 = StartPI().refatpoint; - r2 = EndPI().refatpoint; - ra = reffak; - - // cout << "Partition, l = " << l << ", h = " << h << endl; - CalcPartition (l, h, r1, r2, ra, elto0, curvepoints); - // cout << "curvepoints = " << curvepoints << endl; - - dt = 1.0 / n; - - l = 0; - j = 1; - - pold = GetPoint (0); - lold = 0; - oldmark = pold; - edgelengthold = 0; - ARRAY<int> locsearch; - - for (i = 1; i <= n; i++) - { - p = GetPoint (i*dt); - l = lold + Dist (p, pold); - while (j < curvepoints.Size() && (l >= curvepoints[j] || i == n)) - { - frac = (curvepoints[j]-lold) / (l-lold); - mark = pold + frac * (p-pold); - edgelength = i*dt + (frac-1)*dt; - { - PointIndex pi1 = -1, pi2 = -1; - - Point3d mark3(mark(0), mark(1), 0); - Point3d oldmark3(oldmark(0), oldmark(1), 0); - - Vec<3> v (1e-4*h, 1e-4*h, 1e-4*h); - searchtree.GetIntersecting (oldmark3 - v, oldmark3 + v, locsearch); - if (locsearch.Size()) pi1 = locsearch[0]; - - searchtree.GetIntersecting (mark3 - v, mark3 + v, locsearch); - if (locsearch.Size()) pi2 = locsearch[0]; - /* - for (PointIndex pk = PointIndex::BASE; - pk < mesh.GetNP()+PointIndex::BASE; pk++) - { - if (Dist (mesh[pk], oldmark3) < 1e-4 * h) pi1 = pk; - if (Dist (mesh[pk], mark3) < 1e-4 * h) pi2 = pk; - } - */ - - - // cout << "pi1 = " << pi1 << endl; - // cout << "pi2 = " << pi2 << endl; - - if (pi1 == -1) - { - pi1 = mesh.AddPoint(oldmark3); - searchtree.Insert (oldmark3, pi1); - } - if (pi2 == -1) - { - pi2 = mesh.AddPoint(mark3); - searchtree.Insert (mark3, pi2); - } - - // cout << "pi1 = " << pi1 << endl; - // cout << "pi2 = " << pi2 << endl; - - Segment seg; - seg.edgenr = segnr; - seg.si = bc; // segnr; - seg.p1 = pi1; - seg.p2 = pi2; - seg.domin = leftdom; - seg.domout = rightdom; - seg.epgeominfo[0].edgenr = segnr; - seg.epgeominfo[0].dist = edgelengthold; - seg.epgeominfo[1].edgenr = segnr; - seg.epgeominfo[1].dist = edgelength; - seg.singedge_left = hpref_left; - seg.singedge_right = hpref_right; - mesh.AddSegment (seg); - } - - oldmark = mark; - edgelengthold = edgelength; - j++; - } - - pold = p; - lold = l; - } - } - - - void SplineSegment :: GetPoints (int n, ARRAY<Point<2> > & points) - { - points.SetSize (n); - if (n >= 2) - for (int i = 0; i < n; i++) - points[i] = GetPoint(double(i) / (n-1)); - } - - - - /* - Implementation of line-segment from p1 to p2 - */ - - - LineSegment :: LineSegment (const GeomPoint2d & ap1, - const GeomPoint2d & ap2) - : p1(ap1), p2(ap2) - { - ; - } - - - Point<2> LineSegment :: GetPoint (double t) const - { - return p1 + t * (p2 - p1); - } - - double LineSegment :: Length () const - { - return Dist (p1, p2); - } - - - void LineSegment :: PrintCoeff (ostream & ost) const - { - double dx = p2(0) - p1(0); - double dy = p2(1) - p1(1); - ost << "0 0 0 " << dy << " " << -dx << " " - << dx * p1(1) - dy * p1(0) << endl; - } - - - - - - SplineSegment3 :: SplineSegment3 (const GeomPoint2d & ap1, - const GeomPoint2d & ap2, - const GeomPoint2d & ap3) - : p1(ap1), p2(ap2), p3(ap3) - { - ; - } - - Point<2> SplineSegment3 :: GetPoint (double t) const - { - double x, y, w; - double b1, b2, b3; - - b1 = (1-t)*(1-t); - b2 = sqrt(2.0) * t * (1-t); - b3 = t * t; - - x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3; - y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3; - w = b1 + b2 + b3; - - return Point<2> (x/w, y/w); - } - - - void SplineSegment3 :: PrintCoeff (ostream & ost) const - { - double t; - int i; - Point<2> p; - DenseMatrix a(6, 6); - DenseMatrix ata(6, 6); - Vector u(6), f(6); - - // ata.SetSymmetric(1); - - t = 0; - for (i = 1; i <= 5; i++, t += 0.25) - { - p = GetPoint (t); - a.Elem(i, 1) = p(0) * p(0); - a.Elem(i, 2) = p(1) * p(1); - a.Elem(i, 3) = p(0) * p(1); - a.Elem(i, 4) = p(0); - a.Elem(i, 5) = p(1); - a.Elem(i, 6) = 1; - } - a.Elem(6, 1) = 1; - - CalcAtA (a, ata); - - u = 0; - u.Elem(6) = 1; - a.MultTrans (u, f); - ata.Solve (f, u); - - for (i = 1; i <= 6; i++) - ost << u.Get(i) << " "; - ost << endl; - } - - - - - //######################################################################## - // circlesegment - - CircleSegment :: CircleSegment (const GeomPoint2d & ap1, - const GeomPoint2d & ap2, - const GeomPoint2d & ap3) - : p1(ap1), p2(ap2), p3(ap3) - { - Vec<2> v1,v2; - - v1 = p1 - p2; - v2 = p3 - p2; - - Point<2> p1t(p1(0)+v1[1], p1(1)-v1[0]); - Point<2> p2t(p3(0)+v2[1], p3(1)-v2[0]); - Line2d g1t(p1, p1t), g2t(p3, p2t); - - pm = CrossPoint (g1t,g2t); - radius = Dist(pm,StartPI()); - w1 = Angle(Vec2d (p1 - pm)); - w3 = Angle(Vec2d (p3 - pm)); - if ( fabs(w3-w1) > M_PI ) - { - if ( w3>M_PI ) w3 -= 2*M_PI; - if ( w1>M_PI ) w1 -= 2*M_PI; - } - } - - Point<2> CircleSegment :: GetPoint (double t) const - { - if (t >= 1.0) { return p3; } - - double phi = StartAngle() + t*(EndAngle()-StartAngle()); - Vec2d tmp(cos(phi),sin(phi)); - - return pm + Radius()*tmp; - } - - void CircleSegment :: PrintCoeff (ostream & ost) const - { - double a,b,c,d,e,f; - - a = b = 1.0; - c = 0.0; - d = -2.0 * pm[0]; - e = -2.0 * pm[1]; - f = sqr(pm[0]) + sqr(pm[1]) - sqr(Radius()); - - ost << a << " " << b << " " << c << " " << d << " " << e << " " << f ; - ost << endl; - } - - - - DiscretePointsSegment :: DiscretePointsSegment (const ARRAY<Point<2> > & apts) - : pts (apts), - p1 (apts[0](0), apts[0](1), 1), - p2 (apts.Last()(0), apts.Last()(1), 1) - - { ; } - - - DiscretePointsSegment :: ~DiscretePointsSegment () - { ; } - - Point<2> DiscretePointsSegment :: GetPoint (double t) const - { - double t1 = t * (pts.Size()-1); - int segnr = int(t1); - if (segnr < 0) segnr = 0; - if (segnr >= pts.Size()) segnr = pts.Size()-1; - - double rest = t1 - segnr; - - return Point<2> ((1-rest)*pts[segnr](0) + rest*pts[segnr+1](0), - (1-rest)*pts[segnr](1) + rest*pts[segnr+1](1)); - } - - - - - - - //######################################################################## - - - - - void CalcPartition (double l, double h, double r1, double r2, - double ra, double elto0, ARRAY<double> & points) - { - int i, j, n, nel; - double sum, t, dt, fun, fperel, oldf, f; - - n = 1000; - - points.SetSize (0); - - sum = 0; - dt = l / n; - t = 0.5 * dt; - for (i = 1; i <= n; i++) - { - fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2); - sum += dt / fun; - t += dt; - } - - nel = int (sum+1); - fperel = sum / nel; - - points.Append (0); - - i = 1; - oldf = 0; - t = 0.5 * dt; - for (j = 1; j <= n && i < nel; j++) - { - fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2); - - f = oldf + dt / fun; - - while (f > i * fperel && i < nel) - { - points.Append ( (l/n) * (j-1 + (i * fperel - oldf) / (f - oldf)) ); - i++; - } - oldf = f; - t += dt; - } - points.Append (l); - } - - -} diff --git a/Netgen/libsrc/geom2d/spline2d.hpp b/Netgen/libsrc/geom2d/spline2d.hpp deleted file mode 100644 index f107a137f1..0000000000 --- a/Netgen/libsrc/geom2d/spline2d.hpp +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef FILE_SPLINE2D -#define FILE_SPLINE2D - -/**************************************************************************/ -/* File: spline2d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 24. Jul. 96 */ -/**************************************************************************/ - - -/* - Spline curves for 2D mesh generation - */ - - -/// Geometry point -class GeomPoint2d : public Point<2> -{ -public: - /// refinement to point - double refatpoint; - bool hpref; - - GeomPoint2d () - { ; } - - /// - GeomPoint2d (double ax, double ay, double aref = 1) - : Point<2> (ax, ay), refatpoint(aref) { ; } -}; - - - -/// base class for 2d - segment -class SplineSegment -{ -public: - /// left domain - int leftdom; - /// right domain - int rightdom; - /// refinement at line - double reffak; - /// boundary condition number - int bc; - /// copy spline mesh from other spline (-1.. do not copy) - int copyfrom; - /// perfrom anisotropic refinement (hp-refinement) to edge - bool hpref_left; - bool hpref_right; - /// calculates length of curve - virtual double Length () const; - /// returns point at curve, 0 <= t <= 1 - virtual Point<2> GetPoint (double t) const = 0; - /// partitionizes curve - void Partition (double h, double elto0, - Mesh & mesh, Point3dTree & searchtree, int segnr) const; - /// returns initial point on curve - virtual const GeomPoint2d & StartPI () const = 0; - /// returns terminal point on curve - virtual const GeomPoint2d & EndPI () const = 0; - /** writes curve description for fepp: - for implicitly given quadratic curves, the 6 coefficients of - the polynomial - $$ a x^2 + b y^2 + c x y + d x + e y + f = 0 $$ - are written to ost */ - virtual void PrintCoeff (ostream & ost) const = 0; - - virtual void GetPoints (int n, ARRAY<Point<2> > & points); - - virtual string GetType(void) const {return "splinebase";} -}; - - -/// Straight line form p1 to p2 -class LineSegment : public SplineSegment -{ - /// - const GeomPoint2d &p1, &p2; -public: - /// - LineSegment (const GeomPoint2d & ap1, const GeomPoint2d & ap2); - /// - virtual double Length () const; - /// - virtual Point<2> GetPoint (double t) const; - /// - virtual const GeomPoint2d & StartPI () const { return p1; }; - /// - virtual const GeomPoint2d & EndPI () const { return p2; } - /// - virtual void PrintCoeff (ostream & ost) const; - - virtual string GetType(void) const {return "line";} -}; - - -/// curve given by a rational, quadratic spline (including ellipses) -class SplineSegment3 : public SplineSegment -{ - /// - const GeomPoint2d &p1, &p2, &p3; -public: - /// - SplineSegment3 (const GeomPoint2d & ap1, - const GeomPoint2d & ap2, - const GeomPoint2d & ap3); - /// - virtual Point<2> GetPoint (double t) const; - /// - virtual const GeomPoint2d & StartPI () const { return p1; }; - /// - virtual const GeomPoint2d & EndPI () const { return p3; } - /// - virtual void PrintCoeff (ostream & ost) const; - - virtual string GetType(void) const {return "spline3";} -}; - - -// Gundolf Haase 8/26/97 -/// A circle -class CircleSegment : public SplineSegment -{ - /// -private: - const GeomPoint2d &p1, &p2, &p3; - Point<2> pm; - double radius, w1,w3; -public: - /// - CircleSegment (const GeomPoint2d & ap1, - const GeomPoint2d & ap2, - const GeomPoint2d & ap3); - /// - virtual Point<2> GetPoint (double t) const; - /// - virtual const GeomPoint2d & StartPI () const { return p1; }; - /// - virtual const GeomPoint2d & EndPI () const { return p3; } - /// - virtual void PrintCoeff (ostream & ost) const; - /// - double Radius() const { return radius; } - /// - double StartAngle() const { return w1; } - /// - double EndAngle() const { return w3; } - - virtual string GetType(void) const {return "circle";} -}; - - -// Gundolf Haase 8/26/97 -/// elliptic curve with one axe parallel to line {P1,P2} -/* -class ellipsegment3 : public SplineSegment -{ - /// - GeomPoint2d *p1, *p2, *p3; -public: - /// - SplineSegment3 (GeomPoint2d * ap1, GeomPoint2d * ap2, GeomPoint2d * ap3); - /// - virtual Point<2> GetPoint (double t) const; - /// - virtual GeomPoint2d * StartPI () const { return p1; }; - /// - virtual GeomPoint2d * EndPI () const { return p3; } - /// - virtual void PrintCoeff (ostream & ost) const; -}; -*/ - - - - - - -/// -class DiscretePointsSegment : public SplineSegment -{ - ARRAY<Point<2> > pts; - GeomPoint2d p1, p2; -public: - /// - DiscretePointsSegment (const ARRAY<Point<2> > & apts); - /// - virtual ~DiscretePointsSegment (); - /// - virtual Point<2> GetPoint (double t) const; - /// - virtual const GeomPoint2d & StartPI () const { return p1; }; - /// - virtual const GeomPoint2d & EndPI () const { return p2; } - /// - virtual void PrintCoeff (ostream & /* ost */) const { ; } -}; - - - - - -#endif diff --git a/Netgen/libsrc/geom2d/splinegeometry2.cpp b/Netgen/libsrc/geom2d/splinegeometry2.cpp deleted file mode 100644 index a034d53989..0000000000 --- a/Netgen/libsrc/geom2d/splinegeometry2.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - -2d Spline curve for Mesh generator - -*/ - -#include <mystdlib.h> -#include <csg.hpp> -#include <linalg.hpp> -#include <meshing.hpp> - - -namespace netgen - -{ - -#include "spline2d.hpp" -#include "splinegeometry2.hpp" - - - -SplineGeometry2d :: ~SplineGeometry2d() -{ - for(int i=0; i<splines.Size(); i++) - { - delete splines[i]; - } - splines.DeleteAll(); - geompoints.DeleteAll(); -} - -void SplineGeometry2d :: Load (const char * filename) -{ - ifstream infile; - int nump, numseg, leftdom, rightdom; - double x, y; - int hi1, hi2, hi3; - double hd; - char buf[50], ch; - - infile.open (filename); - - if (! infile.good() ) - throw NgException(string ("2D Input file '") + - string (filename) + - string ("' not available!")); - - infile >> buf; // file recognition - infile >> elto0; - - infile >> nump; - for (int i = 0; i < nump; i++) - { - infile >> x >> y >> hd; - - Flags flags; - - ch = 'a'; - // infile >> ch; - do { - infile.get (ch); - } while (isspace(ch) && ch != '\n'); - while (ch == '-') - { - char flag[100]; - flag[0]='-'; - infile >> (flag+1); - flags.SetCommandLineFlag (flag); - ch = 'a'; - do { - infile.get (ch); - } while (isspace(ch) && ch != '\n'); - } - - if (infile.good()) - infile.putback (ch); - - geompoints.Append (GeomPoint2d(x, y, hd)); - geompoints.Last().hpref = flags.GetDefineFlag ("hpref"); - } - - infile >> numseg; - SplineSegment * spline = 0; - for (int i = 0; i < numseg; i++) - { - infile >> leftdom >> rightdom; - - // cout << "add spline " << i << ", left = " << leftdom << endl; - - infile >> buf; - // type of spline segement - if (strcmp (buf, "2") == 0) - { // a line - infile >> hi1 >> hi2; - spline = new LineSegment(geompoints[hi1-1], - geompoints[hi2-1]); - } - else if (strcmp (buf, "3") == 0) - { // a rational spline - infile >> hi1 >> hi2 >> hi3; - spline = new SplineSegment3 (geompoints[hi1-1], - geompoints[hi2-1], - geompoints[hi3-1]); - } - else if (strcmp (buf, "4") == 0) - { // an arc - infile >> hi1 >> hi2 >> hi3; - spline = new CircleSegment (geompoints[hi1-1], - geompoints[hi2-1], - geompoints[hi3-1]); - break; - } - else if (strcmp (buf, "discretepoints") == 0) - { - int npts; - infile >> npts; - ARRAY<Point<2> > pts(npts); - for (int j = 0; j < npts; j++) - infile >> pts[j](0) >> pts[j](1); - - spline = new DiscretePointsSegment (pts); - cout << "pts = " << pts << endl; - } - - infile >> spline->reffak; - spline -> leftdom = leftdom; - spline -> rightdom = rightdom; - splines.Append (spline); - - - Flags flags; - ch = 'a'; - infile >> ch; - while (ch == '-') - { - char flag[100]; - flag[0]='-'; - infile >> (flag+1); - flags.SetCommandLineFlag (flag); - ch = 'a'; - infile >> ch; - } - - if (infile.good()) - infile.putback (ch); - - splines.Last()->bc = int (flags.GetNumFlag ("bc", i+1)); - splines.Last()->hpref_left = int (flags.GetDefineFlag ("hpref")) || - int (flags.GetDefineFlag ("hprefleft")); - splines.Last()->hpref_right = int (flags.GetDefineFlag ("hpref")) || - int (flags.GetDefineFlag ("hprefright")); - splines.Last()->copyfrom = int (flags.GetNumFlag ("copy", -1)); - } - - - infile.close(); -} - - - -void SplineGeometry2d :: -PartitionBoundary (double h, Mesh & mesh2d) -{ - Box<2> bbox; - GetBoundingBox (bbox); - double dist = Dist (bbox.PMin(), bbox.PMax()); - Point<3> pmin(bbox.PMin()(0), bbox.PMin()(1), -dist); - Point<3> pmax(bbox.PMax()(0), bbox.PMax()(1), dist); - - cout << "searchtree from " << pmin << " to " << pmax << endl; - Point3dTree searchtree (pmin, pmax); - - for (int i = 0; i < splines.Size(); i++) - if (splines[i]->copyfrom == -1) - splines[i]->Partition(h, elto0, mesh2d, searchtree, i+1); - else - CopyEdgeMesh (splines[i]->copyfrom, i+1, mesh2d, searchtree); -} - - -void SplineGeometry2d :: CopyEdgeMesh (int from, int to, Mesh & mesh, Point3dTree & searchtree) -{ - int i, j, k; - - ARRAY<int, PointIndex::BASE> mappoints (mesh.GetNP()); - ARRAY<double, PointIndex::BASE> param (mesh.GetNP()); - mappoints = -1; - param = 0; - - Point3d pmin, pmax; - mesh.GetBox (pmin, pmax); - double diam2 = Dist2(pmin, pmax); - - cout << "copy edge, from = " << from << " to " << to << endl; - - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - if (seg.edgenr == from) - { - mappoints.Elem(seg.p1) = 1; - param.Elem(seg.p1) = seg.epgeominfo[0].dist; - - mappoints.Elem(seg.p2) = 1; - param.Elem(seg.p2) = seg.epgeominfo[1].dist; - } - } - - for (i = 1; i <= mappoints.Size(); i++) - { - if (mappoints.Get(i) != -1) - { - Point<2> newp = splines.Get(to)->GetPoint (param.Get(i)); - Point<3> newp3 (newp(0), newp(1), 0); - - int npi = -1; - - for (PointIndex pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - if (Dist2 (mesh.Point(pi), newp3) < 1e-12 * diam2) - npi = pi; - - if (npi == -1) - { - npi = mesh.AddPoint (newp3); - searchtree.Insert (newp3, npi); - } - - mappoints.Elem(i) = npi; - - mesh.GetIdentifications().Add (i, npi, to); - } - } - - // copy segments - int oldnseg = mesh.GetNSeg(); - for (i = 1; i <= oldnseg; i++) - { - const Segment & seg = mesh.LineSegment(i); - if (seg.edgenr == from) - { - Segment nseg; - nseg.edgenr = to; - nseg.si = splines.Get(to)->bc; - nseg.p1 = mappoints.Get(seg.p1); - nseg.p2 = mappoints.Get(seg.p2); - nseg.domin = splines.Get(to)->leftdom; - nseg.domout = splines.Get(to)->rightdom; - - nseg.epgeominfo[0].edgenr = to; - nseg.epgeominfo[0].dist = param.Get(seg.p1); - nseg.epgeominfo[1].edgenr = to; - nseg.epgeominfo[1].dist = param.Get(seg.p2); - mesh.AddSegment (nseg); - } - } -} - - -void SplineGeometry2d :: -GetBoundingBox (Box<2> & box) const -{ - if (!splines.Size()) - { - box.Set (Point<2> (0,0)); - return; - } - - ARRAY<Point<2> > points; - for (int i = 0; i < splines.Size(); i++) - { - splines[i]->GetPoints (20, points); - - if (i == 0) box.Set(points[0]); - for (int j = 0; j < points.Size(); j++) - box.Add (points[j]); - } -} - -void SplineGeometry2d :: -SetGrading (const double grading) -{ elto0 = grading;} - -void SplineGeometry2d :: -AppendPoint (const double x, const double y, const double reffac, const bool hpref) -{ - geompoints.Append (GeomPoint2d(x, y, reffac)); - geompoints.Last().hpref = hpref; -} - - -void SplineGeometry2d :: -AppendSegment(SplineSegment * spline, const int leftdomain, const int rightdomain, - const int bc, - const double reffac, const bool hprefleft, const bool hprefright, - const int copyfrom) -{ - spline -> leftdom = leftdomain; - spline -> rightdom = rightdomain; - spline -> bc = (bc >= 0) ? bc : (splines.Size()+1); - spline -> reffak = reffac; - spline -> hpref_left = hprefleft; - spline -> hpref_right = hprefright; - spline -> copyfrom = copyfrom; - - splines.Append(spline); -} - -void SplineGeometry2d :: -AppendLineSegment (const int n1, const int n2, const int leftdomain, const int rightdomain, - const int bc, - const double reffac, const bool hprefleft, const bool hprefright, - const int copyfrom) -{ - SplineSegment * spline = new LineSegment(geompoints[n1],geompoints[n2]); - AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); -} -void SplineGeometry2d :: -AppendSplineSegment (const int n1, const int n2, const int n3, const int leftdomain, const int rightdomain, - const int bc, - const double reffac, const bool hprefleft, const bool hprefright, - const int copyfrom) -{ - SplineSegment * spline = new SplineSegment3(geompoints[n1],geompoints[n2],geompoints[n3]); - AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); -} -void SplineGeometry2d :: -AppendCircleSegment (const int n1, const int n2, const int n3, const int leftdomain, const int rightdomain, - const int bc, - const double reffac, const bool hprefleft, const bool hprefright, - const int copyfrom) -{ - SplineSegment * spline = new CircleSegment(geompoints[n1],geompoints[n2],geompoints[n3]); - AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); -} -void SplineGeometry2d :: -AppendDiscretePointsSegment (const ARRAY< Point<2> > & points, const int leftdomain, const int rightdomain, - const int bc, - const double reffac, const bool hprefleft, const bool hprefright, - const int copyfrom) -{ - SplineSegment * spline = new DiscretePointsSegment(points); - AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); -} - -} diff --git a/Netgen/libsrc/geom2d/splinegeometry2.hpp b/Netgen/libsrc/geom2d/splinegeometry2.hpp deleted file mode 100644 index 66c2a4d79f..0000000000 --- a/Netgen/libsrc/geom2d/splinegeometry2.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef FILE_SPLINEGEOMETRY2 -#define FILE_SPLINEGEOMETRY2 - -/**************************************************************************/ -/* File: splinegeometry2.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 24. Jul. 96 */ -/**************************************************************************/ - - - -/// -extern void LoadBoundarySplines (const char * filename, - ARRAY<GeomPoint2d> & geompoints, - ARRAY<SplineSegment*> & splines, - double & elto0); -/// -extern void PartitionBoundary (const ARRAY<SplineSegment*> & splines, - double h, double elto0, - Mesh & mesh2d); - -class SplineGeometry2d -{ - ARRAY<GeomPoint2d> geompoints; - ARRAY<SplineSegment*> splines; - double elto0; - - -private: - void AppendSegment(SplineSegment * spline, const int leftdomain, const int rightdomain, - const int bc, - const double reffac, const bool hprefleft, const bool hprefright, - const int copyfrom); - -public: - ~SplineGeometry2d(); - - void Load (const char * filename); - void PartitionBoundary (double h, Mesh & mesh2d); - - void CopyEdgeMesh (int from, int to, Mesh & mesh2d, Point3dTree & searchtree); - - const ARRAY<SplineSegment*> & GetSplines () const - { return splines; } - - void GetBoundingBox (Box<2> & box) const; - - int GetNP () const { return geompoints.Size(); } - const GeomPoint2d & GetPoint(int i) const { return geompoints[i]; } - - void SetGrading (const double grading); - void AppendPoint (const double x, const double y, const double reffac = 1., const bool hpref = false); - - void AppendLineSegment (const int n1, const int n2, - const int leftdomain, const int rightdomain, const int bc = -1, - const double reffac = 1., - const bool hprefleft = false, const bool hprefright = false, - const int copyfrom = -1); - void AppendSplineSegment (const int n1, const int n2, const int n3, - const int leftdomain, const int rightdomain, const int bc = -1, - const double reffac = 1., - const bool hprefleft = false, const bool hprefright = false, - const int copyfrom = -1); - void AppendCircleSegment (const int n1, const int n2, const int n3, - const int leftdomain, const int rightdomain, const int bc = -1, - const double reffac = 1., - const bool hprefleft = false, const bool hprefright = false, - const int copyfrom = -1); - void AppendDiscretePointsSegment (const ARRAY< Point<2> > & points, - const int leftdomain, const int rightdomain, const int bc = -1, - const double reffac = 1., - const bool hprefleft = false, const bool hprefright = false, - const int copyfrom = -1); - -}; - - -void MeshFromSpline2D (SplineGeometry2d & geometry, - Mesh *& mesh, - MeshingParameters & mp); - - -#endif diff --git a/Netgen/libsrc/gprim/Makefile b/Netgen/libsrc/gprim/Makefile deleted file mode 100644 index 608e522844..0000000000 --- a/Netgen/libsrc/gprim/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Makefile for geometric library -# -src = geom2d.cpp geom3d.cpp \ - geomtest3d.cpp adtree.cpp transform3d.cpp geomfuncs.cpp - -# reftrans.cpp rot3d.cpp -# -lib = gprim -libpath = libsrc/gprim -# -# -include ../makefile.inc -# diff --git a/Netgen/libsrc/gprim/adtree.cpp b/Netgen/libsrc/gprim/adtree.cpp deleted file mode 100644 index 25f46183e2..0000000000 --- a/Netgen/libsrc/gprim/adtree.cpp +++ /dev/null @@ -1,2245 +0,0 @@ -#include <mystdlib.h> - - -#include <myadt.hpp> -// class DenseMatrix; -#include <gprim.hpp> - -namespace netgen -{ - - - /* ******************************* ADTree ******************************* */ - - - ADTreeNode :: ADTreeNode(int adim) - { - pi = -1; - - left = NULL; - right = NULL; - father = NULL; - nchilds = 0; - dim = adim; - data = new float [dim]; - boxmin = NULL; - boxmax = NULL; - } - - - - - ADTreeNode :: ~ADTreeNode() - { - delete data; - } - - - ADTree :: ADTree (int adim, const float * acmin, - const float * acmax) - : ela(0), stack(1000), stackdir(1000) - { - dim = adim; - cmin = new float [dim]; - cmax = new float [dim]; - memcpy (cmin, acmin, dim * sizeof(float)); - memcpy (cmax, acmax, dim * sizeof(float)); - - root = new ADTreeNode (dim); - root->sep = (cmin[0] + cmax[0]) / 2; - root->boxmin = new float [dim]; - root->boxmax = new float [dim]; - memcpy (root->boxmin, cmin, dim * sizeof(float)); - memcpy (root->boxmax, cmax, dim * sizeof(float)); - } - - ADTree :: ~ADTree () - { - ; - } - - void ADTree :: Insert (const float * p, int pi) - { - ADTreeNode *node; - ADTreeNode *next; - int dir; - int lr; - - float * bmin = new float [dim]; - float * bmax = new float [dim]; - - memcpy (bmin, cmin, dim * sizeof(float)); - memcpy (bmax, cmax, dim * sizeof(float)); - - - next = root; - dir = 0; - while (next) - { - node = next; - - if (node->pi == -1) - { - memcpy (node->data, p, dim * sizeof(float)); - node->pi = pi; - - if (ela.Size() < pi+1) - ela.SetSize (pi+1); - ela[pi] = node; - - return; - } - - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - - dir++; - if (dir == dim) - dir = 0; - } - - - next = new ADTreeNode(dim); - memcpy (next->data, p, dim * sizeof(float)); - next->pi = pi; - next->sep = (bmin[dir] + bmax[dir]) / 2; - next->boxmin = bmin; - next->boxmax = bmax; - - if (ela.Size() < pi+1) - ela.SetSize (pi+1); - ela[pi] = next; - - - if (lr) - node->right = next; - else - node->left = next; - next -> father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree :: DeleteElement (int pi) - { - ADTreeNode * node = ela[pi]; - - node->pi = -1; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - - void ADTree :: SetCriterion (ADTreeCriterion & acriterion) - { - criterion = & acriterion; - } - - - void ADTree :: Reset () - { - stack.Elem(1) = root; - stackdir.Elem(1) = 0; - stackindex = 1; - } - - - int ADTree:: Next () - { - ADTreeNode *node; - int dir; - - if (stackindex == 0) - return -1; - - do - { - node = stack.Get(stackindex); - dir = stackdir.Get(stackindex); - stackindex --; - - if (criterion -> Eval(node)) - { - int ndir = dir + 1; - if (ndir == dim) - ndir = 0; - - if (node -> left && criterion -> Eval (node->left)) - { - stackindex ++; - stack.Elem(stackindex) = node -> left; - stackdir.Elem(stackindex) = ndir; - } - if (node->right && criterion -> Eval (node -> right)) - { - stackindex++; - stack.Elem(stackindex) = node->right; - stackdir.Elem(stackindex) = ndir; - } - - if (node -> pi != -1) - return node->pi; - } - } - while (stackindex > 0); - - return -1; - } - - - void ADTree :: GetMatch (ARRAY <int> & matches) - { - int nodenr; - - Reset(); - - while ( (nodenr = Next()) != -1) - matches.Append (nodenr); - } - - - void ADTree :: PrintRec (ostream & ost, const ADTreeNode * node) const - { - - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (int i = 0; i < dim; i++) - ost << node->data[i] << " "; - ost << endl; - } - if (node->left) - { - ost << "l "; - PrintRec (ost, node->left); - } - if (node->right) - { - ost << "r "; - PrintRec (ost, node->right); - } - } - - - /* ******************************* ADTree3 ******************************* */ - - - ADTreeNode3 :: ADTreeNode3() - { - pi = -1; - - left = NULL; - right = NULL; - father = NULL; - nchilds = 0; - } - - void ADTreeNode3 :: DeleteChilds () - { - if (left) - { - left->DeleteChilds(); - delete left; - left = NULL; - } - if (right) - { - right->DeleteChilds(); - delete right; - right = NULL; - } - } - - - BlockAllocator ADTreeNode3 :: ball(sizeof (ADTreeNode3)); - - - void * ADTreeNode3 :: operator new(size_t s) - { - return ball.Alloc(); - } - - void ADTreeNode3 :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - - - ADTree3 :: ADTree3 (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 3 * sizeof(float)); - memcpy (cmax, acmax, 3 * sizeof(float)); - - root = new ADTreeNode3; - root->sep = (cmin[0] + cmax[0]) / 2; - } - - ADTree3 :: ~ADTree3 () - { - root->DeleteChilds(); - delete root; - } - - - void ADTree3 :: Insert (const float * p, int pi) - { - ADTreeNode3 *node; - ADTreeNode3 *next; - int dir; - int lr; - - float bmin[3]; - float bmax[3]; - - memcpy (bmin, cmin, 3 * sizeof(float)); - memcpy (bmax, cmax, 3 * sizeof(float)); - - next = root; - dir = 0; - while (next) - { - node = next; - - if (node->pi == -1) - { - memcpy (node->data, p, 3 * sizeof(float)); - node->pi = pi; - - if (ela.Size() < pi+1) - ela.SetSize (pi+1); - ela[pi] = node; - - return; - } - - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - - dir++; - if (dir == 3) - dir = 0; - } - - - next = new ADTreeNode3; - memcpy (next->data, p, 3 * sizeof(float)); - next->pi = pi; - next->sep = (bmin[dir] + bmax[dir]) / 2; - - - if (ela.Size() < pi+1) - ela.SetSize (pi+1); - ela[pi] = next; - - - if (lr) - node->right = next; - else - node->left = next; - next -> father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree3 :: DeleteElement (int pi) - { - ADTreeNode3 * node = ela[pi]; - - node->pi = -1; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree3 :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode3*> stack(1000); - static ARRAY<int> stackdir(1000); - ADTreeNode3 * node; - int dir, stacks; - - stack.SetSize (1000); - stackdir.SetSize(1000); - pis.SetSize(0); - - stack.Elem(1) = root; - stackdir.Elem(1) = 0; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - dir = stackdir.Get(stacks); - stacks--; - - if (node->pi != -1) - { - if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && - node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && - node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) - - pis.Append (node->pi); - } - - - int ndir = dir+1; - if (ndir == 3) - ndir = 0; - - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - } - } - - void ADTree3 :: PrintRec (ostream & ost, const ADTreeNode3 * node) const - { - - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (int i = 0; i < 3; i++) - ost << node->data[i] << " "; - ost << endl; - } - if (node->left) - PrintRec (ost, node->left); - if (node->right) - PrintRec (ost, node->right); - } - - - - - - - - -#ifdef ABC - - /* ******************************* ADTree3Div ******************************* */ - - - ADTreeNode3Div :: ADTreeNode3Div() - { - pi = 0; - - int i; - for (i = 0; i < ADTN_DIV; i++) - childs[i] = NULL; - - father = NULL; - nchilds = 0; - minx = 0; - dist = 1; - } - - void ADTreeNode3Div :: DeleteChilds () - { - int i; - for (i = 0; i < ADTN_DIV; i++) - if (childs[i]) - { - childs[i]->DeleteChilds(); - delete childs[i]; - childs[i] = NULL; - } - } - - - BlockAllocator ADTreeNode3Div :: ball(sizeof (ADTreeNode3Div)); - - void * ADTreeNode3Div :: operator new(size_t) - { - return ball.Alloc(); - } - - void ADTreeNode3Div :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - - - ADTree3Div :: ADTree3Div (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 3 * sizeof(float)); - memcpy (cmax, acmax, 3 * sizeof(float)); - - root = new ADTreeNode3Div; - - root->minx = cmin[0]; - root->dist = (cmax[0] - cmin[0]) / ADTN_DIV; - - // root->sep = (cmin[0] + cmax[0]) / 2; - } - - ADTree3Div :: ~ADTree3Div () - { - root->DeleteChilds(); - delete root; - } - - - void ADTree3Div :: Insert (const float * p, int pi) - { - ADTreeNode3Div *node; - ADTreeNode3Div *next; - int dir; - int bag; - - float bmin[3]; - float bmax[3]; - - memcpy (bmin, cmin, 3 * sizeof(float)); - memcpy (bmax, cmax, 3 * sizeof(float)); - - - next = root; - dir = 0; - while (next) - { - node = next; - - if (!node->pi) - { - memcpy (node->data, p, 3 * sizeof(float)); - node->pi = pi; - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = node; - - return; - } - - double dx = (bmax[dir] - bmin[dir]) / ADTN_DIV; - bag = int ((p[dir]-bmin[dir]) / dx); - - // (*testout) << "insert, bag = " << bag << endl; - - if (bag < 0) bag = 0; - if (bag >= ADTN_DIV) bag = ADTN_DIV-1; - - double nbmin = bmin[dir] + bag * dx; - double nbmax = bmin[dir] + (bag+1) * dx; - - /* - (*testout) << "bmin, max = " << bmin[dir] << "-" << bmax[dir] - << " p = " << p[dir]; - */ - next = node->childs[bag]; - bmin[dir] = nbmin; - bmax[dir] = nbmax; - - // (*testout) << "new bmin, max = " << bmin[dir] << "-" << bmax[dir] << endl; - - - /* - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - */ - - dir++; - if (dir == 3) - dir = 0; - } - - - next = new ADTreeNode3Div; - memcpy (next->data, p, 3 * sizeof(float)); - next->pi = pi; - - next->minx = bmin[dir]; - next->dist = (bmax[dir] - bmin[dir]) / ADTN_DIV; - // next->sep = (bmin[dir] + bmax[dir]) / 2; - - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = next; - - node->childs[bag] = next; - next -> father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree3Div :: DeleteElement (int pi) - { - ADTreeNode3Div * node = ela.Get(pi); - - node->pi = 0; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree3Div :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode3Div*> stack(1000); - static ARRAY<int> stackdir(1000); - ADTreeNode3Div * node; - int dir, i, stacks; - - stack.SetSize (1000); - stackdir.SetSize(1000); - pis.SetSize(0); - - stack.Elem(1) = root; - stackdir.Elem(1) = 0; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - dir = stackdir.Get(stacks); - stacks--; - - if (node->pi) - { - if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && - node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && - node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) - - pis.Append (node->pi); - } - - - int ndir = dir+1; - if (ndir == 3) - ndir = 0; - - int mini = int ( (bmin[dir] - node->minx) / node->dist ); - int maxi = int ( (bmax[dir] - node->minx) / node->dist ); - - // (*testout) << "get int, mini, maxi = " << mini << ", " << maxi << endl; - if (mini < 0) mini = 0; - if (maxi >= ADTN_DIV) maxi = ADTN_DIV-1; - - for (i = mini; i <= maxi; i++) - if (node->childs[i]) - { - stacks++; - stack.Elem(stacks) = node->childs[i]; - stackdir.Elem(stacks) = ndir; - } - - - /* - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - */ - } - } - - void ADTree3Div :: PrintRec (ostream & ost, const ADTreeNode3Div * node) const - { - - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - ost << " from " << node->minx << " - " << node->minx + node->dist*ADTN_DIV << " "; - for (int i = 0; i < 3; i++) - ost << node->data[i] << " "; - ost << endl; - } - int i; - for (i = 0; i < ADTN_DIV; i++) - if (node->childs[i]) - PrintRec (ost, node->childs[i]); - } - - - - - - - - - - - - - /* ******************************* ADTree3M ******************************* */ - - - ADTreeNode3M :: ADTreeNode3M() - { - int i; - for (i = 0; i < ADTN_SIZE; i++) - pi[i] = 0; - - left = NULL; - right = NULL; - father = NULL; - nchilds = 0; - } - - void ADTreeNode3M :: DeleteChilds () - { - if (left) - { - left->DeleteChilds(); - delete left; - left = NULL; - } - if (right) - { - right->DeleteChilds(); - delete right; - right = NULL; - } - } - - - BlockAllocator ADTreeNode3M :: ball(sizeof (ADTreeNode3M)); - - void * ADTreeNode3M :: operator new(size_t) - { - return ball.Alloc(); - } - - void ADTreeNode3M :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - - - ADTree3M :: ADTree3M (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 3 * sizeof(float)); - memcpy (cmax, acmax, 3 * sizeof(float)); - - root = new ADTreeNode3M; - root->sep = (cmin[0] + cmax[0]) / 2; - } - - ADTree3M :: ~ADTree3M () - { - root->DeleteChilds(); - delete root; - } - - - void ADTree3M :: Insert (const float * p, int pi) - { - ADTreeNode3M *node; - ADTreeNode3M *next; - int dir; - int lr; - int i; - float bmin[3]; - float bmax[3]; - - memcpy (bmin, cmin, 3 * sizeof(float)); - memcpy (bmax, cmax, 3 * sizeof(float)); - - next = root; - dir = 0; - while (next) - { - node = next; - - for (i = 0; i < ADTN_SIZE; i++) - if (!node->pi[i]) - { - memcpy (node->data[i], p, 3 * sizeof(float)); - node->pi[i] = pi; - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = node; - - return; - } - - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - - dir++; - if (dir == 3) - dir = 0; - } - - - next = new ADTreeNode3M; - memcpy (next->data[0], p, 3 * sizeof(float)); - next->pi[0] = pi; - next->sep = (bmin[dir] + bmax[dir]) / 2; - - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = next; - - - if (lr) - node->right = next; - else - node->left = next; - next -> father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree3M :: DeleteElement (int pi) - { - ADTreeNode3M * node = ela.Get(pi); - - int i; - for (i = 0; i < ADTN_SIZE; i++) - if (node->pi[i] == pi) - node->pi[i] = 0; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree3M :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode3M*> stack(1000); - static ARRAY<int> stackdir(1000); - ADTreeNode3M * node; - int dir, i, stacks; - - stack.SetSize (1000); - stackdir.SetSize(1000); - pis.SetSize(0); - - stack.Elem(1) = root; - stackdir.Elem(1) = 0; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - dir = stackdir.Get(stacks); - stacks--; - - int * hpi = node->pi; - for (i = 0; i < ADTN_SIZE; i++) - if (hpi[i]) - { - float * datai = &node->data[i][0]; - if (datai[0] >= bmin[0] && datai[0] <= bmax[0] && - datai[1] >= bmin[1] && datai[1] <= bmax[1] && - datai[2] >= bmin[2] && datai[2] <= bmax[2]) - - pis.Append (node->pi[i]); - } - - - int ndir = dir+1; - if (ndir == 3) - ndir = 0; - - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - } - } - - void ADTree3M :: PrintRec (ostream & ost, const ADTreeNode3M * node) const - { - - if (node->data) - { - // ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (int i = 0; i < 3; i++) - ost << node->data[i] << " "; - ost << endl; - } - if (node->left) - PrintRec (ost, node->left); - if (node->right) - PrintRec (ost, node->right); - } - - - - - - - - - - - - - /* ******************************* ADTree3F ******************************* */ - - - ADTreeNode3F :: ADTreeNode3F() - { - pi = 0; - father = NULL; - nchilds = 0; - int i; - for (i = 0; i < 8; i++) - childs[i] = NULL; - } - - void ADTreeNode3F :: DeleteChilds () - { - int i; - - for (i = 0; i < 8; i++) - { - if (childs[i]) - childs[i]->DeleteChilds(); - delete childs[i]; - childs[i] = NULL; - } - } - - - BlockAllocator ADTreeNode3F :: ball(sizeof (ADTreeNode3F)); - - void * ADTreeNode3F :: operator new(size_t) - { - return ball.Alloc(); - } - - void ADTreeNode3F :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - - - ADTree3F :: ADTree3F (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 3 * sizeof(float)); - memcpy (cmax, acmax, 3 * sizeof(float)); - - root = new ADTreeNode3F; - for (int i = 0; i < 3; i++) - root->sep[i] = (cmin[i] + cmax[i]) / 2; - } - - ADTree3F :: ~ADTree3F () - { - root->DeleteChilds(); - delete root; - } - - - void ADTree3F :: Insert (const float * p, int pi) - { - ADTreeNode3F *node; - ADTreeNode3F *next; - int lr; - - float bmin[3]; - float bmax[3]; - int i, dir; - - memcpy (bmin, cmin, 3 * sizeof(float)); - memcpy (bmax, cmax, 3 * sizeof(float)); - - - next = root; - while (next) - { - node = next; - - if (!node->pi) - { - memcpy (node->data, p, 3 * sizeof(float)); - node->pi = pi; - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = node; - - return; - } - - dir = 0; - for (i = 0; i < 3; i++) - { - if (node->sep[i] > p[i]) - { - bmax[i] = node->sep[i]; - } - else - { - bmin[i] = node->sep[i]; - dir += (1 << i); - } - } - next = node->childs[dir]; - - /* - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - */ - } - - - next = new ADTreeNode3F; - memcpy (next->data, p, 3 * sizeof(float)); - next->pi = pi; - - for (i = 0; i < 3; i++) - next->sep[i] = (bmin[i] + bmax[i]) / 2; - - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = next; - - node->childs[dir] = next; - next->father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree3F :: DeleteElement (int pi) - { - ADTreeNode3F * node = ela.Get(pi); - - node->pi = 0; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree3F :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode3F*> stack(1000); - ADTreeNode3F * node; - int dir, i, stacks; - - stack.SetSize (1000); - pis.SetSize(0); - - stack.Elem(1) = root; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - stacks--; - - if (node->pi) - { - if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && - node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && - node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) - - pis.Append (node->pi); - } - - - int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1; - int i1max = (bmax[0] < node->sep[0]) ? 0 : 1; - int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1; - int i2max = (bmax[1] < node->sep[1]) ? 0 : 1; - int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1; - int i3max = (bmax[2] < node->sep[2]) ? 0 : 1; - - int i1, i2, i3; - for (i1 = i1min; i1 <= i1max; i1++) - for (i2 = i2min; i2 <= i2max; i2++) - for (i3 = i3min; i3 <= i3max; i3++) - { - i = i1+2*i2+4*i3; - if (node->childs[i]) - { - stacks++; - stack.Elem(stacks) = node->childs[i]; - } - } - - /* - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - */ - } - } - - void ADTree3F :: PrintRec (ostream & ost, const ADTreeNode3F * node) const - { - int i; - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (i = 0; i < 3; i++) - ost << node->data[i] << " "; - ost << endl; - } - - for (i = 0; i < 8; i++) - if (node->childs[i]) - PrintRec (ost, node->childs[i]); - } - - - - - - - - - - - - - - /* ******************************* ADTree3FM ******************************* */ - - - ADTreeNode3FM :: ADTreeNode3FM() - { - father = NULL; - nchilds = 0; - int i; - - for (i = 0; i < ADTN_SIZE; i++) - pi[i] = 0; - - for (i = 0; i < 8; i++) - childs[i] = NULL; - } - - void ADTreeNode3FM :: DeleteChilds () - { - int i; - - for (i = 0; i < 8; i++) - { - if (childs[i]) - childs[i]->DeleteChilds(); - delete childs[i]; - childs[i] = NULL; - } - } - - - BlockAllocator ADTreeNode3FM :: ball(sizeof (ADTreeNode3FM)); - - void * ADTreeNode3FM :: operator new(size_t) - { - return ball.Alloc(); - } - - void ADTreeNode3FM :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - - - ADTree3FM :: ADTree3FM (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 3 * sizeof(float)); - memcpy (cmax, acmax, 3 * sizeof(float)); - - root = new ADTreeNode3FM; - for (int i = 0; i < 3; i++) - root->sep[i] = (cmin[i] + cmax[i]) / 2; - } - - ADTree3FM :: ~ADTree3FM () - { - root->DeleteChilds(); - delete root; - } - - - void ADTree3FM :: Insert (const float * p, int pi) - { - ADTreeNode3FM *node; - ADTreeNode3FM *next; - int lr; - - float bmin[3]; - float bmax[3]; - int i, dir; - - memcpy (bmin, cmin, 3 * sizeof(float)); - memcpy (bmax, cmax, 3 * sizeof(float)); - - next = root; - while (next) - { - node = next; - - for (i = 0; i < ADTN_SIZE; i++) - if (!node->pi[i]) - { - memcpy (node->data[i], p, 3 * sizeof(float)); - node->pi[i] = pi; - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = node; - - return; - } - - dir = 0; - for (i = 0; i < 3; i++) - { - if (node->sep[i] > p[i]) - { - bmax[i] = node->sep[i]; - } - else - { - bmin[i] = node->sep[i]; - dir += (1 << i); - } - } - next = node->childs[dir]; - - /* - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - */ - } - - - next = new ADTreeNode3FM; - memcpy (next->data[0], p, 3 * sizeof(float)); - next->pi[0] = pi; - - for (i = 0; i < 3; i++) - next->sep[i] = (bmin[i] + bmax[i]) / 2; - - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = next; - - node->childs[dir] = next; - next->father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree3FM :: DeleteElement (int pi) - { - ADTreeNode3FM * node = ela.Get(pi); - - int i; - for (i = 0; i < ADTN_SIZE; i++) - if (node->pi[i] == pi) - node->pi[i] = 0; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree3FM :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode3FM*> stack(1000); - ADTreeNode3FM * node; - int dir, i, stacks; - - stack.SetSize (1000); - pis.SetSize(0); - - stack.Elem(1) = root; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - stacks--; - - int * hpi = node->pi; - for (i = 0; i < ADTN_SIZE; i++) - if (hpi[i]) - { - float * datai = &node->data[i][0]; - if (datai[0] >= bmin[0] && datai[0] <= bmax[0] && - datai[1] >= bmin[1] && datai[1] <= bmax[1] && - datai[2] >= bmin[2] && datai[2] <= bmax[2]) - - pis.Append (node->pi[i]); - } - - /* - if (node->pi) - { - if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && - node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && - node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) - - pis.Append (node->pi); - } - */ - - int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1; - int i1max = (bmax[0] < node->sep[0]) ? 0 : 1; - int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1; - int i2max = (bmax[1] < node->sep[1]) ? 0 : 1; - int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1; - int i3max = (bmax[2] < node->sep[2]) ? 0 : 1; - - int i1, i2, i3; - for (i1 = i1min; i1 <= i1max; i1++) - for (i2 = i2min; i2 <= i2max; i2++) - for (i3 = i3min; i3 <= i3max; i3++) - { - i = i1+2*i2+4*i3; - if (node->childs[i]) - { - stacks++; - stack.Elem(stacks) = node->childs[i]; - } - } - - /* - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - */ - } - } - - void ADTree3FM :: PrintRec (ostream & ost, const ADTreeNode3FM * node) const - { - int i; - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (i = 0; i < 3; i++) - ost << node->data[i] << " "; - ost << endl; - } - - for (i = 0; i < 8; i++) - if (node->childs[i]) - PrintRec (ost, node->childs[i]); - } - - - - -#endif - - - - - - - /* ******************************* ADTree6 ******************************* */ - - - ADTreeNode6 :: ADTreeNode6() - { - pi = -1; - - left = NULL; - right = NULL; - father = NULL; - nchilds = 0; - } - - void ADTreeNode6 :: DeleteChilds () - { - if (left) - { - left->DeleteChilds(); - delete left; - left = NULL; - } - if (right) - { - right->DeleteChilds(); - delete right; - right = NULL; - } - } - - - BlockAllocator ADTreeNode6 :: ball (sizeof (ADTreeNode6)); - void * ADTreeNode6 :: operator new(size_t) - { - return ball.Alloc(); - } - - void ADTreeNode6 :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - ADTree6 :: ADTree6 (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 6 * sizeof(float)); - memcpy (cmax, acmax, 6 * sizeof(float)); - - root = new ADTreeNode6; - root->sep = (cmin[0] + cmax[0]) / 2; - } - - ADTree6 :: ~ADTree6 () - { - root->DeleteChilds(); - delete root; - } - - void ADTree6 :: Insert (const float * p, int pi) - { - ADTreeNode6 *node; - ADTreeNode6 *next; - int dir; - int lr; - - float bmin[6]; - float bmax[6]; - - - memcpy (bmin, cmin, 6 * sizeof(float)); - memcpy (bmax, cmax, 6 * sizeof(float)); - - next = root; - dir = 0; - while (next) - { - node = next; - - if (node->pi == -1) - { - memcpy (node->data, p, 6 * sizeof(float)); - node->pi = pi; - - if (ela.Size() < pi+1) - ela.SetSize (pi+1); - ela[pi] = node; - - return; - } - - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - - dir++; - if (dir == 6) - dir = 0; - } - - - next = new ADTreeNode6; - memcpy (next->data, p, 6 * sizeof(float)); - next->pi = pi; - next->sep = (bmin[dir] + bmax[dir]) / 2; - - - if (ela.Size() < pi+1) - ela.SetSize (pi+1); - ela[pi] = next; - - - if (lr) - node->right = next; - else - node->left = next; - next -> father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree6 :: DeleteElement (int pi) - { - ADTreeNode6 * node = ela[pi]; - - node->pi = -1; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree6 :: PrintMemInfo (ostream & ost) const - { - ost << Elements() << " elements a " << sizeof(ADTreeNode6) - << " Bytes = " - << Elements() * sizeof(ADTreeNode6) << endl; - ost << "maxind = " << ela.Size() << " = " << sizeof(ADTreeNode6*) * ela.Size() << " Bytes" << endl; - } - - - - class inttn6 { - public: - int dir; - ADTreeNode6 * node; - }; - - - - - void ADTree6 :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<inttn6> stack(10000); - ADTreeNode6 * node; - int dir, stacks; - - stack.SetSize (10000); - pis.SetSize(0); - - stack.Elem(1).node = root; - stack.Elem(1).dir = 0; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks).node; - dir = stack.Get(stacks).dir; - stacks--; - - if (node->pi != -1) - { - - // int in = 1; - // for (i = 0; i < 3; i++) - // if (/* node->data[i] < bmin[i] || */ node->data[i] > bmax[i] || - // node->data[i+3] < bmin[i+3] /* || node->data[i+3] > bmax[i+3] */ ) - // { - // in = 0; - // break; - // } - - // if (in) - // pis.Append (node->pi); - - if (node->data[0] > bmax[0] || - node->data[1] > bmax[1] || - node->data[2] > bmax[2] || - node->data[3] < bmin[3] || - node->data[4] < bmin[4] || - node->data[5] < bmin[5]) - ; - else - pis.Append (node->pi); - } - - - int ndir = dir+1; - if (ndir == 6) - ndir = 0; - - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks).node = node->left; - stack.Elem(stacks).dir = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks).node = node->right; - stack.Elem(stacks).dir = ndir; - } - } - } - - /* - void ADTree6 :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode6*> stack(10000); - static ARRAY<int> stackdir(10000); - ADTreeNode6 * node; - int dir, stacks; - - stack.SetSize (10000); - stackdir.SetSize(10000); - pis.SetSize(0); - - stack.Elem(1) = root; - stackdir.Elem(1) = 0; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - dir = stackdir.Get(stacks); - stacks--; - - if (node->pi) - { - - if (node->data[0] > bmax[0] || - node->data[1] > bmax[1] || - node->data[2] > bmax[2] || - node->data[3] < bmin[3] || - node->data[4] < bmin[4] || - node->data[5] < bmin[5]) - ; - else - pis.Append (node->pi); - } - - - int ndir = dir+1; - if (ndir == 6) - ndir = 0; - - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - } - } - */ - - - void ADTree6 :: PrintRec (ostream & ost, const ADTreeNode6 * node) const - { - - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (int i = 0; i < 6; i++) - ost << node->data[i] << " "; - ost << endl; - } - if (node->left) - PrintRec (ost, node->left); - if (node->right) - PrintRec (ost, node->right); - } - - - int ADTree6 :: DepthRec (const ADTreeNode6 * node) const - { - int ldepth = 0; - int rdepth = 0; - - if (node->left) - ldepth = DepthRec(node->left); - if (node->right) - rdepth = DepthRec(node->right); - return 1 + max2 (ldepth, rdepth); - } - - int ADTree6 :: ElementsRec (const ADTreeNode6 * node) const - { - int els = 1; - if (node->left) - els += ElementsRec(node->left); - if (node->right) - els += ElementsRec(node->right); - return els; - } - - - - - - -#ifdef ABC - - /* ******************************* ADTree6F ******************************* */ - - - ADTreeNode6F :: ADTreeNode6F() - { - pi = 0; - father = NULL; - nchilds = 0; - int i; - for (i = 0; i < 64; i++) - childs[i] = NULL; - } - - void ADTreeNode6F :: DeleteChilds () - { - int i; - - for (i = 0; i < 64; i++) - { - if (childs[i]) - childs[i]->DeleteChilds(); - delete childs[i]; - childs[i] = NULL; - } - } - - - BlockAllocator ADTreeNode6F :: ball(sizeof (ADTreeNode6F)); - - void * ADTreeNode6F :: operator new(size_t) - { - return ball.Alloc(); - } - - void ADTreeNode6F :: operator delete (void * p) - { - ball.Free (p); - } - - - - - - - - ADTree6F :: ADTree6F (const float * acmin, - const float * acmax) - : ela(0) - { - memcpy (cmin, acmin, 6 * sizeof(float)); - memcpy (cmax, acmax, 6 * sizeof(float)); - - root = new ADTreeNode6F; - for (int i = 0; i < 6; i++) - root->sep[i] = (cmin[i] + cmax[i]) / 2; - } - - ADTree6F :: ~ADTree6F () - { - root->DeleteChilds(); - delete root; - } - - - void ADTree6F :: Insert (const float * p, int pi) - { - ADTreeNode6F *node; - ADTreeNode6F *next; - int lr; - - float bmin[6]; - float bmax[6]; - int i, dir; - - memcpy (bmin, cmin, 6 * sizeof(float)); - memcpy (bmax, cmax, 6 * sizeof(float)); - - next = root; - while (next) - { - node = next; - - if (!node->pi) - { - memcpy (node->data, p, 6 * sizeof(float)); - node->pi = pi; - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = node; - - return; - } - - dir = 0; - for (i = 0; i < 6; i++) - { - if (node->sep[i] > p[i]) - { - bmax[i] = node->sep[i]; - } - else - { - bmin[i] = node->sep[i]; - dir += (1 << i); - } - } - next = node->childs[dir]; - - /* - if (node->sep > p[dir]) - { - next = node->left; - bmax[dir] = node->sep; - lr = 0; - } - else - { - next = node->right; - bmin[dir] = node->sep; - lr = 1; - } - */ - } - - - next = new ADTreeNode6F; - memcpy (next->data, p, 6 * sizeof(float)); - next->pi = pi; - - for (i = 0; i < 6; i++) - next->sep[i] = (bmin[i] + bmax[i]) / 2; - - - if (ela.Size() < pi) - ela.SetSize (pi); - ela.Elem(pi) = next; - - node->childs[dir] = next; - next->father = node; - - while (node) - { - node->nchilds++; - node = node->father; - } - } - - void ADTree6F :: DeleteElement (int pi) - { - ADTreeNode6F * node = ela.Get(pi); - - node->pi = 0; - - node = node->father; - while (node) - { - node->nchilds--; - node = node->father; - } - } - - void ADTree6F :: GetIntersecting (const float * bmin, - const float * bmax, - ARRAY<int> & pis) const - { - static ARRAY<ADTreeNode6F*> stack(1000); - ADTreeNode6F * node; - int dir, i, stacks; - - stack.SetSize (1000); - pis.SetSize(0); - - stack.Elem(1) = root; - stacks = 1; - - while (stacks) - { - node = stack.Get(stacks); - stacks--; - - if (node->pi) - { - if ( - node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && - node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && - node->data[2] >= bmin[2] && node->data[2] <= bmax[2] && - node->data[3] >= bmin[3] && node->data[3] <= bmax[3] && - node->data[4] >= bmin[4] && node->data[4] <= bmax[4] && - node->data[5] >= bmin[5] && node->data[5] <= bmax[5] - ) - - pis.Append (node->pi); - } - - - int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1; - int i1max = (bmax[0] < node->sep[0]) ? 0 : 1; - int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1; - int i2max = (bmax[1] < node->sep[1]) ? 0 : 1; - int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1; - int i3max = (bmax[2] < node->sep[2]) ? 0 : 1; - - int i4min = (bmin[3] <= node->sep[3]) ? 0 : 1; - int i4max = (bmax[3] < node->sep[3]) ? 0 : 1; - int i5min = (bmin[4] <= node->sep[4]) ? 0 : 1; - int i5max = (bmax[4] < node->sep[4]) ? 0 : 1; - int i6min = (bmin[5] <= node->sep[5]) ? 0 : 1; - int i6max = (bmax[5] < node->sep[5]) ? 0 : 1; - - int i1, i2, i3, i4, i5, i6; - for (i1 = i1min; i1 <= i1max; i1++) - for (i2 = i2min; i2 <= i2max; i2++) - for (i3 = i3min; i3 <= i3max; i3++) - for (i4 = i4min; i4 <= i4max; i4++) - for (i5 = i5min; i5 <= i5max; i5++) - for (i6 = i6min; i6 <= i6max; i6++) - { - i = i1 + 2*i2 + 4*i3 + 8*i4 + 16*i5 +32*i6; - if (node->childs[i]) - { - stacks++; - stack.Elem(stacks) = node->childs[i]; - } - } - - /* - if (node->left && bmin[dir] <= node->sep) - { - stacks++; - stack.Elem(stacks) = node->left; - stackdir.Elem(stacks) = ndir; - } - if (node->right && bmax[dir] >= node->sep) - { - stacks++; - stack.Elem(stacks) = node->right; - stackdir.Elem(stacks) = ndir; - } - */ - } - } - - void ADTree6F :: PrintRec (ostream & ost, const ADTreeNode6F * node) const - { - int i; - if (node->data) - { - ost << node->pi << ": "; - ost << node->nchilds << " childs, "; - for (i = 0; i < 6; i++) - ost << node->data[i] << " "; - ost << endl; - } - - for (i = 0; i < 64; i++) - if (node->childs[i]) - PrintRec (ost, node->childs[i]); - } - - - -#endif - - - - /* ************************************* Point3dTree ********************** */ - - - - Point3dTree :: Point3dTree (const Point3d & pmin, const Point3d & pmax) - { - float pmi[3], pma[3]; - for (int i = 0; i < 3; i++) - { - pmi[i] = pmin.X(i+1); - pma[i] = pmax.X(i+1); - } - tree = new ADTree3 (pmi, pma); - } - - Point3dTree :: ~Point3dTree () - { - delete tree; - } - - - - void Point3dTree :: Insert (const Point3d & p, int pi) - { - static float pd[3]; - pd[0] = p.X(); - pd[1] = p.Y(); - pd[2] = p.Z(); - tree->Insert (pd, pi); - } - - void Point3dTree :: GetIntersecting (const Point3d & pmin, const Point3d & pmax, - ARRAY<int> & pis) const - { - float pmi[3], pma[3]; - for (int i = 0; i < 3; i++) - { - pmi[i] = pmin.X(i+1); - pma[i] = pmax.X(i+1); - } - tree->GetIntersecting (pmi, pma, pis); - } - - - - - - - - - - - Box3dTree :: Box3dTree (const Point3d & apmin, const Point3d & apmax) - { - boxpmin = apmin; - boxpmax = apmax; - float tpmin[6], tpmax[6]; - for (int i = 0; i < 3; i++) - { - tpmin[i] = tpmin[i+3] = boxpmin.X(i+1); - tpmax[i] = tpmax[i+3] = boxpmax.X(i+1); - } - tree = new ADTree6 (tpmin, tpmax); - } - - Box3dTree :: ~Box3dTree () - { - delete tree; - } - - void Box3dTree :: Insert (const Point3d & bmin, const Point3d & bmax, int pi) - { - static float tp[6]; - - for (int i = 0; i < 3; i++) - { - tp[i] = bmin.X(i+1); - tp[i+3] = bmax.X(i+1); - } - - tree->Insert (tp, pi); - } - - void Box3dTree ::GetIntersecting (const Point3d & pmin, const Point3d & pmax, - ARRAY<int> & pis) const - { - float tpmin[6]; - float tpmax[6]; - - for (int i = 0; i < 3; i++) - { - tpmin[i] = boxpmin.X(i+1); - tpmax[i] = pmax.X(i+1); - - tpmin[i+3] = pmin.X(i+1); - tpmax[i+3] = boxpmax.X(i+1); - } - - tree->GetIntersecting (tpmin, tpmax, pis); - } - -} diff --git a/Netgen/libsrc/gprim/adtree.hpp b/Netgen/libsrc/gprim/adtree.hpp deleted file mode 100644 index 64f3509e1a..0000000000 --- a/Netgen/libsrc/gprim/adtree.hpp +++ /dev/null @@ -1,477 +0,0 @@ -#ifndef FILE_ADTREE -#define FILE_ADTREE - -/* *************************************************************************/ -/* File: adtree.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 16. Feb. 98 */ -/* Redesigned by Wolfram Muehlhuber, May 1998 */ -/* *************************************************************************/ - - - -/** - Alternating Digital Tree - */ - -#include <mystdlib.h> -#include <myadt.hpp> - -class ADTreeNode -{ -public: - ADTreeNode *left, *right, *father; - int dim; - float sep; - float *data; - float *boxmin; - float *boxmax; - int pi; - int nchilds; - - ADTreeNode (int adim); - ~ADTreeNode (); - - friend class ADTree; -}; - - -class ADTreeCriterion -{ -public: - ADTreeCriterion() { } - virtual int Eval (const ADTreeNode * node) const = 0; -}; - - -class ADTree -{ - int dim; - ADTreeNode * root; - float *cmin, *cmax; - ARRAY<ADTreeNode*> ela; - const ADTreeCriterion * criterion; - - ARRAY<ADTreeNode*> stack; - ARRAY<int> stackdir; - int stackindex; - -public: - ADTree (int adim, const float * acmin, - const float * acmax); - ~ADTree (); - - void Insert (const float * p, int pi); - // void GetIntersecting (const float * bmin, const float * bmax, - // ARRAY<int> & pis) const; - void SetCriterion (ADTreeCriterion & acriterion); - void Reset (); - int Next (); - void GetMatch (ARRAY<int> & matches); - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - - void PrintRec (ostream & ost, const ADTreeNode * node) const; -}; - - - -class ADTreeNode3 -{ -public: - ADTreeNode3 *left, *right, *father; - float sep; - float data[3]; - int pi; - int nchilds; - - ADTreeNode3 (); - void DeleteChilds (); - friend class ADTree3; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - - -class ADTree3 -{ - ADTreeNode3 * root; - float cmin[3], cmax[3]; - ARRAY<ADTreeNode3*> ela; - -public: - ADTree3 (const float * acmin, - const float * acmax); - ~ADTree3 (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - - void PrintRec (ostream & ost, const ADTreeNode3 * node) const; -}; - - -/* - -// divide each direction -#define ADTN_DIV 10 -class ADTreeNode3Div -{ -public: - ADTreeNode3Div *father; - ADTreeNode3Div *childs[ADTN_DIV]; - - float minx, dist; - float data[3]; - int pi; - int nchilds; - - ADTreeNode3Div (); - void DeleteChilds (); - friend class ADTree3Div; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - - -class ADTree3Div -{ - ADTreeNode3Div * root; - float cmin[3], cmax[3]; - ARRAY<ADTreeNode3Div*> ela; - -public: - ADTree3Div (const float * acmin, - const float * acmax); - ~ADTree3Div (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - - void PrintRec (ostream & ost, const ADTreeNode3Div * node) const; -}; - - - - -#define ADTN_SIZE 10 - -// multiple entries -class ADTreeNode3M -{ -public: - ADTreeNode3M *left, *right, *father; - float sep; - float data[ADTN_SIZE][3]; - int pi[ADTN_SIZE]; - int nchilds; - - ADTreeNode3M (); - void DeleteChilds (); - friend class ADTree3M; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - - -class ADTree3M -{ - ADTreeNode3M * root; - float cmin[3], cmax[3]; - ARRAY<ADTreeNode3M*> ela; - -public: - ADTree3M (const float * acmin, - const float * acmax); - ~ADTree3M (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - - void PrintRec (ostream & ost, const ADTreeNode3M * node) const; -}; - - - - - - -class ADTreeNode3F -{ -public: - ADTreeNode3F *father; - ADTreeNode3F *childs[8]; - float sep[3]; - float data[3]; - int pi; - int nchilds; - - ADTreeNode3F (); - void DeleteChilds (); - friend class ADTree3F; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - -// fat tree -class ADTree3F -{ - ADTreeNode3F * root; - float cmin[3], cmax[3]; - ARRAY<ADTreeNode3F*> ela; - -public: - ADTree3F (const float * acmin, - const float * acmax); - ~ADTree3F (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - - void PrintRec (ostream & ost, const ADTreeNode3F * node) const; -}; - - - - -class ADTreeNode3FM -{ -public: - ADTreeNode3FM *father; - ADTreeNode3FM *childs[8]; - float sep[3]; - float data[ADTN_SIZE][3]; - int pi[ADTN_SIZE]; - int nchilds; - - ADTreeNode3FM (); - void DeleteChilds (); - friend class ADTree3FM; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - -// fat tree -class ADTree3FM -{ - ADTreeNode3FM * root; - float cmin[3], cmax[3]; - ARRAY<ADTreeNode3FM*> ela; - -public: - ADTree3FM (const float * acmin, - const float * acmax); - ~ADTree3FM (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - - void PrintRec (ostream & ost, const ADTreeNode3FM * node) const; -}; - - - -*/ - - - - - -class ADTreeNode6 -{ -public: - ADTreeNode6 *left, *right, *father; - float sep; - float data[6]; - int pi; - int nchilds; - - ADTreeNode6 (); - void DeleteChilds (); - friend class ADTree6; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - - -class ADTree6 -{ - ADTreeNode6 * root; - float cmin[6], cmax[6]; - ARRAY<ADTreeNode6*> ela; - -public: - ADTree6 (const float * acmin, - const float * acmax); - ~ADTree6 (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - int Depth () const - { return DepthRec (root); } - int Elements () const - { return ElementsRec (root); } - - void PrintRec (ostream & ost, const ADTreeNode6 * node) const; - int DepthRec (const ADTreeNode6 * node) const; - int ElementsRec (const ADTreeNode6 * node) const; - - void PrintMemInfo (ostream & ost) const; -}; - - - - -/* - -class ADTreeNode6F -{ -public: - ADTreeNode6F * father; - ADTreeNode6F * childs[64]; - - float sep[6]; - float data[6]; - int pi; - int nchilds; - - ADTreeNode6F (); - void DeleteChilds (); - friend class ADTree6F; - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - - -class ADTree6F -{ - ADTreeNode6F * root; - float cmin[6], cmax[6]; - ARRAY<ADTreeNode6F*> ela; - -public: - ADTree6F (const float * acmin, - const float * acmax); - ~ADTree6F (); - - void Insert (const float * p, int pi); - void GetIntersecting (const float * bmin, const float * bmax, - ARRAY<int> & pis) const; - - void DeleteElement (int pi); - - - void Print (ostream & ost) const - { PrintRec (ost, root); } - int Depth () const - { return DepthRec (root); } - - void PrintRec (ostream & ost, const ADTreeNode6F * node) const; - int DepthRec (const ADTreeNode6F * node) const; -}; - - - - - - - -*/ - - - - - -class Point3dTree -{ - ADTree3 * tree; - -public: - Point3dTree (const Point3d & pmin, const Point3d & pmax); - ~Point3dTree (); - void Insert (const Point3d & p, int pi); - void DeleteElement (int pi) - { tree->DeleteElement(pi); } - void GetIntersecting (const Point3d & pmin, const Point3d & pmax, - ARRAY<int> & pis) const; - const ADTree3 & Tree() const { return *tree; }; -}; - - - -class Box3dTree -{ - ADTree6 * tree; - Point3d boxpmin, boxpmax; -public: - Box3dTree (const Point3d & apmin, const Point3d & apmax); - ~Box3dTree (); - void Insert (const Point3d & bmin, const Point3d & bmax, int pi); - void DeleteElement (int pi) - { tree->DeleteElement(pi); } - void GetIntersecting (const Point3d & pmin, const Point3d & pmax, - ARRAY<int> & pis) const; - - const ADTree6 & Tree() const { return *tree; }; -}; -#endif diff --git a/Netgen/libsrc/gprim/geom2d.cpp b/Netgen/libsrc/gprim/geom2d.cpp deleted file mode 100644 index 01463d0255..0000000000 --- a/Netgen/libsrc/gprim/geom2d.cpp +++ /dev/null @@ -1,485 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <gprim.hpp> - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -namespace netgen -{ - -ostream & operator<<(ostream & s, const Point2d & p) -{ - return s << "(" << p.px << ", " << p.py << ")"; -} - -ostream & operator<<(ostream & s, const Vec2d & v) -{ - return s << "(" << v.vx << ", " << v.vy << ")"; -} - -#ifdef none -ostream & operator<<(ostream & s, const Line2d & l) - { - return s << l.p1 << "-" << l.p2; -} - -ostream & operator<<(ostream & s, const TRIANGLE2D & t) -{ - return s << t.p1 << "-" << t.p2 << "-" << t.p3; -} -#endif - - -double Fastatan2 (double x, double y) -{ - if (y > 0) - { - if (x > 0) - return y / (x+y); - else - return 1 - x / (y-x); - } - else if (y < 0) - { - if (x < 0) - return 2 + y / (x+y); - else - return 3 - x / (y-x); - } - else - { - if (x >= 0) - return 0; - else - return 2; - } -} - - -double Angle (const Vec2d & v) -{ - if (v.X() == 0 && v.Y() == 0) return 0; - double ang = atan2 (v.Y(), v.X()); - if (ang < 0) ang+= 2 * M_PI; - return ang; -} - -double FastAngle (const Vec2d & v) -{ - return Fastatan2 (v.X(), v.Y()); -} - -double Angle (const Vec2d & v1, const Vec2d & v2) -{ - double ang = Angle(v2) - Angle(v1); - if (ang < 0) ang += 2 * M_PI; - return ang; -} - -double FastAngle (const Vec2d & v1, const Vec2d & v2) -{ - double ang = FastAngle(v2) - FastAngle(v1); - if (ang < 0) ang += 4; - return ang; -} - -/* -int CW (const Point2d & p1,const Point2d & p2,const Point2d & p3) -{ - return Cross (p2 - p1, p3 - p2) < 0; -} - -int CCW (const Point2d & p1,const Point2d & p2,const Point2d & p3) -{ - return Cross (p2 - p1, p3 - p2) > 0; -} -*/ - -double Dist2(const Line2d & g, const Line2d & h ) - { - double dd = 0.0, d1,d2,d3,d4; - Point2d cp = CrossPoint(g,h); - - if ( Parallel(g,h) || !IsOnLine(g,cp) || !IsOnLine(h,cp) ) - { - d1 = Dist2(g.P1(),h.P1()); - d2 = Dist2(g.P1(),h.P2()); - d3 = Dist2(g.P2(),h.P1()); - d4 = Dist2(g.P2(),h.P2()); - if (d1<d2) d2 = d1; - if (d3<d4) d4 = d3; - dd = ( d2 < d4 ) ? d2 : d4; - } - return dd; -} - - -Point2d CrossPoint (const Line2d & l1, const Line2d & l2) - { - double den = Cross (l1.Delta(), l2.Delta()); - double num = Cross ( (l2.P1() - l1.P1()), l2.Delta()); - - if (den == 0) return l1.P1(); - else - return l1.P1() + (num/den) * l1.Delta(); -} - - -int CrossPointBarycentric (const Line2d & l1, const Line2d & l2, - double & lam1, double & lam2) -{ - // p = l1.1 + lam1 (l1.2-l1.1) = l2.1 + lam2 (l2.2-l2.1) - double a11 = l1.p2.X() - l1.p1.X(); - double a21 = l1.p2.Y() - l1.p1.Y(); - double a12 = -(l2.p2.X() - l2.p1.X()); - double a22 = -(l2.p2.Y() - l2.p1.Y()); - - double b1 = l2.p1.X() - l1.p1.X(); - double b2 = l2.p1.Y() - l1.p1.Y(); - - double det = a11*a22 - a12 * a21; - if (det == 0) return 1; - - lam1 = (a22 * b1 - a12 * b2) / det; - lam2 = (a11 * b2 - a21 * b1) / det; - return 0; -} - - - - -int Parallel (const Line2d & l1, const Line2d & l2, double peps) - { - double p = fabs (Cross (l1.Delta(), l2.Delta())); - // (*mycout) << endl << p << " " << l1.Length() << " " << l2.Length() << endl; - return p <= peps * l1.Length() * l2.Length(); -} - -int IsOnLine (const Line2d & l, const Point2d & p, double heps) - { - double c1 = (p - l.P1()) * l.Delta(); - double c2 = (p - l.P2()) * l.Delta(); - double d = fabs (Cross ( (p - l.P1()), l.Delta())); - double len2 = l.Length2(); - - return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2; -} - -#ifdef none -int IsOnLine (const PLine2d & l, const Point2d & p, double heps) - { - double c1 = (p - l.P1()) * l.Delta(); - double c2 = (p - l.P2()) * l.Delta(); - double d = fabs (Cross ( (p - l.P1()), l.Delta())); - double len2 = l.Length2(); - - return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2; -} - -int IsOnLongLine (const Line2d & l, const Point2d & p) - { - double d = fabs (Cross ( (p - l.P1()), l.Delta())); - return d <= EPSGEOM * l.Length(); -} - -int Hit (const Line2d & l1, const Line2d & l2, double heps) - { - double den = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l2.P2())); - double num1 = Cross ( (l2.P1() - l1.P1()), (l2.P1() - l2.P2())); - double num2 = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l1.P1())); - num1 *= sgn (den); - num2 *= sgn (den); - den = fabs (den); - - int ch = (-den * heps <= num1 && num1 <= den * (1 + heps) && - -den * heps <= num2 && num2 <= den * (1 + heps)); - return ch; -} - - -void Line2d :: GetNormal (Line2d & n) const -{ - double ax = P2().X()-P1().X(), - ay = P2().Y()-P1().Y(); - Point2d mid(P1().X()+.5*ax, P1().Y()+.5*ay); - - n=Line2d(mid,Point2d(mid.X()+ay,mid.Y()-ax)) ; -} - -Vec2d Line2d :: NormalDelta () const -{ - Line2d tmp; - GetNormal(tmp); - return tmp.Delta(); -} - -int TRIANGLE2D :: IsOn (const Point2d & p) const - { - return IsOnLine (Line2d (p1, p2), p) || - IsOnLine (Line2d (p1, p3), p) || - IsOnLine (Line2d (p2, p3), p); - } - - -int TRIANGLE2D :: IsIn (const Point2d & p) const -{ - return ::CW(p, p1, p2) == ::CW(p, p2, p3) && - ::CW(p, p1, p2) == ::CW(p, p3, p1); -} - - - -int PTRIANGLE2D :: IsOn (const Point2d & p) const -{ - return IsOnLine (Line2d (*p1, *p2), p) || - IsOnLine (Line2d (*p1, *p3), p) || - IsOnLine (Line2d (*p2, *p3), p); -} - - -int PTRIANGLE2D :: IsIn (const Point2d & p) const -{ - return ::CW(p, *p1, *p2) == ::CW(p, *p2, *p3) && - ::CW(p, *p1, *p2) == ::CW(p, *p3, *p1); -} - -#endif - - - - - - -Polygon2d :: Polygon2d () -{ - ; -} - -Polygon2d :: ~Polygon2d () -{ - ; -} - -void Polygon2d :: AddPoint (const Point2d & p) -{ - points.Append(p); -} - - -double Polygon2d :: HArea () const -{ - int i; - double ar = 0; - for (i = 1; i <= points.Size(); i++) - { - const Point2d & p1 = points.Get(i); - const Point2d & p2 = points.Get(i%points.Size()+1); - ar += - (p2.X()-p1.X()) * p1.Y() - - (p2.Y()-p1.Y()) * p1.X(); - } - return ar/2; - /* - CURSOR c; - double ar = 0; - Point2d * p1, * p2, p0 = Point2d(0, 0); - Vec2d v1, v2 = Vec2d(1, 0); - - p2 = points[points.Last()]; - for (c = points.First(); c != points.Head(); c++) - { - p1 = p2; - p2 = points[c]; - ar += Cross ( (*p2-*p1), (*p1 - p0)); - } - return ar / 2; - */ -} - - -int Polygon2d :: IsOn (const Point2d & p) const -{ - int i; - for (i = 1; i <= points.Size(); i++) - { - const Point2d & p1 = points.Get(i); - const Point2d & p2 = points.Get(i%points.Size()+1); - if (IsOnLine (Line2d(p1, p2), p)) return 1; - } - return 0; - /* - CURSOR c; - Point2d * p1, * p2; - - p2 = points[points.Last()]; - for (c = points.First(); c != points.Head(); c++) - { - p1 = p2; - p2 = points[c]; - if (IsOnLine (Line2d(*p1, *p2), p)) return 1; - } - return 0; - */ -} - - -int Polygon2d :: IsIn (const Point2d & p) const -{ - int i; - double sum = 0, ang; - for (i = 1; i <= points.Size(); i++) - { - const Point2d & p1 = points.Get(i); - const Point2d & p2 = points.Get(i%points.Size()+1); - ang = Angle ( (p1 - p), (p2 - p) ); - if (ang > M_PI) ang -= 2 * M_PI; - sum += ang; - } - return fabs(sum) > M_PI; - /* - CURSOR c; - Point2d * p1, * p2; - double sum = 0, ang; - - p2 = points[points.Last()]; - for (c = points.First(); c != points.Head(); c++) - { - p1 = p2; - p2 = points[c]; - ang = Angle ( (*p1 - p), (*p2 - p) ); - if (ang > M_PI) ang -= 2 * M_PI; - sum += ang; - } - - return fabs(sum) > M_PI; - */ -} - -int Polygon2d :: IsConvex () const - { - /* - Point2d *p, *pold, *pnew; - char cw; - CURSOR c; - - if (points.Length() < 3) return 0; - - c = points.Last(); - p = points[c]; - c--; - pold = points[c]; - pnew = points[points.First()]; - cw = ::CW (*pold, *p, *pnew); - - for (c = points.First(); c != points.Head(); c++) - { - pnew = points[c]; - if (cw != ::CW (*pold, *p, *pnew)) - return 0; - pold = p; - p = pnew; - } - */ - return 0; - } - - -int Polygon2d :: IsStarPoint (const Point2d & p) const - { - /* - Point2d *pnew, *pold; - char cw; - CURSOR c; - - if (points.Length() < 3) return 0; - - pold = points[points.Last()]; - pnew = points[points.First()]; - - cw = ::CW (p, *pold, *pnew); - - for (c = points.First(); c != points.Head(); c++) - { - pnew = points[c]; - if (cw != ::CW (p, *pold, *pnew)) - return 0; - pold = pnew; - } - return 1; - */ - return 0; - } - - -Point2d Polygon2d :: Center () const - { - /* - double ai, a = 0, x = 0, y = 0; - Point2d * p, *p2; - Point2d p0 = Point2d(0, 0); - CURSOR c; - - p2 = points[points.Last()]; - - for (c = points.First(); c != points.Head(); c++) - { - p = points[c]; - ai = Cross (*p2 - p0, *p - p0); - x += ai / 3 * (p2->X() + p->X()); - y += ai / 3 * (p2->Y() + p->Y()); - a+= ai; - p2 = p; - } - if (a != 0) - return Point2d (x / a, y / a); - else - return Point2d (0, 0); - */ - return Point2d (0, 0); - } - - - -Point2d Polygon2d :: EqualAreaPoint () const - { - /* - double a11 = 0, a12 = 0, a21= 0, a22 = 0; - double b1 = 0, b2 = 0, dx, dy; - double det; - Point2d * p, *p2; - CURSOR c; - - p = points[points.Last()]; - - for (c = points.First(); c != points.Head(); c++) - { - p2 = p; - p = points[c]; - - dx = p->X() - p2->X(); - dy = p->Y() - p2->Y(); - - a11 += sqr (dy); - a12 -= dx * dy; - a21 -= dx * dy; - a22 += sqr (dx); - b1 -= dy * (p->X() * p2->Y() - p2->X() * p->Y()); - b2 -= dx * (p->Y() * p2->X() - p2->Y() * p->X()); - } - - det = a11 * a22 - a21 * a12; - - if (det != 0) - return Point2d ( (b1 * a22 - b2 * a12) / det, - (a11 * b2 - a21 * b1) / det); - else - return Point2d (0, 0); -*/ - return Point2d (0, 0); - } - - -} diff --git a/Netgen/libsrc/gprim/geom2d.hpp b/Netgen/libsrc/gprim/geom2d.hpp deleted file mode 100644 index 48b5eda71d..0000000000 --- a/Netgen/libsrc/gprim/geom2d.hpp +++ /dev/null @@ -1,870 +0,0 @@ -#ifndef FILE_GEOM2D -#define FILE_GEOM2D - -/* *************************************************************************/ -/* File: geom2d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 5. Aug. 95 */ -/* *************************************************************************/ - - - -/* Geometric Algorithms */ - -#define EPSGEOM 1E-5 - - -// extern void MyError (const char * ch); - -class Point2d; -class Vec2d; - -class LINE2D; -class Line2d; -class PLine2d; -class TRIANGLE2D; -class PTRIANGLE2D; - - -inline Vec2d operator- (const Point2d & p1, const Point2d & p2); -inline Point2d operator- (const Point2d & p1, const Vec2d & v); -inline Point2d operator+ (const Point2d & p1, const Vec2d & v); -inline Point2d Center (const Point2d & p1, const Point2d & p2); - -inline void PpSmV (const Point2d & p1, double s, const Vec2d & v, Point2d & p2); -inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v); -ostream & operator<<(ostream & s, const Point2d & p); -inline Vec2d operator- (const Point2d & p1, const Point2d & p2); -inline Point2d operator- (const Point2d & p1, const Vec2d & v); -inline Point2d operator+ (const Point2d & p1, const Vec2d & v); -inline Vec2d operator- (const Vec2d & p1, const Vec2d & v); -inline Vec2d operator+ (const Vec2d & p1, const Vec2d & v); -inline Vec2d operator* (double scal, const Vec2d & v); -double Angle (const Vec2d & v); -double FastAngle (const Vec2d & v); -double Angle (const Vec2d & v1, const Vec2d & v2); -double FastAngle (const Vec2d & v1, const Vec2d & v2); -ostream & operator<<(ostream & s, const Vec2d & v); -double Dist2(const Line2d & g, const Line2d & h ); // GH -int Near (const Point2d & p1, const Point2d & p2, const double eps); - -int Parallel (const Line2d & l1, const Line2d & l2, double peps = EPSGEOM); -int IsOnLine (const Line2d & l, const Point2d & p, double heps = EPSGEOM); -int IsOnLongLine (const Line2d & l, const Point2d & p); -int Hit (const Line2d & l1, const Line2d & l2, double heps = EPSGEOM); -ostream & operator<<(ostream & s, const Line2d & l); -Point2d CrossPoint (const PLine2d & l1, const PLine2d & l2); -int Parallel (const PLine2d & l1, const PLine2d & l2, double peps = EPSGEOM); -int IsOnLine (const PLine2d & l, const Point2d & p, double heps = EPSGEOM); -int IsOnLongLine (const PLine2d & l, const Point2d & p); -int Hit (const PLine2d & l1, const Line2d & l2, double heps = EPSGEOM); -ostream & operator<<(ostream & s, const Line2d & l); -ostream & operator<<(ostream & s, const TRIANGLE2D & t); -ostream & operator<<(ostream & s, const PTRIANGLE2D & t); - -/// -class Point2d -{ - /// - friend class Vec2d; - -protected: - /// - double px, py; - -public: - /// - Point2d() { /* px = py = 0; */ } - /// - Point2d(double ax, double ay) { px = ax; py = ay; } - /// - Point2d(const Point2d & p2) { px = p2.px; py = p2.py; } - - Point2d (const Point<2> & p2) - { - px = p2(0); - py = p2(1); - } - /// - Point2d & operator= (const Point2d & p2) - { px = p2.px; py = p2.py; return *this; } - - /// - int operator== (const Point2d & p2) const // GH - { return (px == p2.px && py == p2.py) ; } - - /// - double & X() { return px; } - /// - double & Y() { return py; } - /// - double X() const { return px; } - /// - double Y() const { return py; } - - operator Point<2> () const - { - return Point<2> (px, py); - } - - - /// - friend inline Vec2d operator- (const Point2d & p1, const Point2d & p2); - /// - friend inline Point2d operator- (const Point2d & p1, const Vec2d & v); - /// - friend inline Point2d operator+ (const Point2d & p1, const Vec2d & v); - - /// - friend inline Point2d Center (const Point2d & p1, const Point2d & p2); - - const Point2d & SetToMin (const Point2d & p2) - { - if (p2.px < px) px = p2.px; - if (p2.py < py) py = p2.py; - return *this; - } - - - /// - const Point2d & SetToMax (const Point2d & p2) - { - if (p2.px > px) px = p2.px; - if (p2.py > py) py = p2.py; - return *this; - } - - /// - friend double Dist (const Point2d & p1, const Point2d & p2) - { return sqrt ( (p1.px - p2.px) * (p1.px - p2.px) + - (p1.py - p2.py) * (p1.py - p2.py) ); } - // { return sqrt ( sqr (p1.X()-p2.X()) + sqr (p1.Y()-p2.Y()) ); } - - /// - friend double Dist2 (const Point2d & p1, const Point2d & p2) - { return ( (p1.px - p2.px) * (p1.px - p2.px) + - (p1.py - p2.py) * (p1.py - p2.py) ); } - // { return sqr (p1.X()-p2.X()) + sqr (p1.Y()-p2.Y()) ; } - - - /** - Points clock-wise ? - Are the points (p1, p2, p3) clock-wise ? - */ - friend inline int CW (const Point2d & p1, const Point2d & p2, const Point2d & p3) - { - // return Cross (p2 - p1, p3 - p2) < 0; - return - (p2.px - p1.px) * (p3.py - p2.py) - - (p2.py - p1.py) * (p3.px - p2.px) < 0; - } - /** - Points counter-clock-wise ? - Are the points (p1, p2, p3) counter-clock-wise ? - */ - friend inline int CCW (const Point2d & p1, const Point2d & p2, const Point2d & p3) - { - // return Cross (p2 - p1, p3 - p2) > 0; - return - (p2.px - p1.px) * (p3.py - p2.py) - - (p2.py - p1.py) * (p3.px - p2.px) > 0; - } - - /// - friend inline void PpSmV (const Point2d & p1, double s, const Vec2d & v, Point2d & p2); - /// - friend inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v); - - /// - friend ostream & operator<<(ostream & s, const Point2d & p); -}; - - -inline int Near (const Point2d & p1, const Point2d & p2, - const double eps = 1e-4 ) -{ - return Dist2(p1,p2) <= eps*eps; -} - - - - - - -/// -class Vec2d - { -protected: - /// - double vx, vy; - -public: - /// - Vec2d() { /* vx = vy = 0; */ } - /// - Vec2d(double ax, double ay) - { vx = ax; vy = ay; } - /// - Vec2d(const Vec2d & v2) { vx = v2.vx; vy = v2.vy; } - - /// - explicit Vec2d(const Vec<2> & v2) { vx = v2(0); vy = v2(1); } - - /// - Vec2d(const Point2d & p1, const Point2d & p2) - { vx = p2.px - p1.px; vy = p2.py - p1.py; } - - /// - Vec2d & operator= (const Vec2d & p2) - { vx = p2.vx; vy = p2.vy; return *this; } - - /// - double & X() { return vx; } - /// - double & Y() { return vy; } - /// - double X() const { return vx; } - /// - double Y() const { return vy; } - - /// - double Length() const { return sqrt (vx * vx + vy * vy); } - /// - double Length2() const { return vx * vx + vy * vy; } - - void GetNormal (Vec2d & n) const { n.vx=-vy; n.vy=vx; } // GH - - /// - inline Vec2d & operator+= (const Vec2d & v2); - /// - inline Vec2d & operator-= (const Vec2d & v2); - /// - inline Vec2d & operator*= (double s); - /// - inline Vec2d & operator/= (double s); - - /// - friend inline Vec2d operator- (const Point2d & p1, const Point2d & p2); - /// - friend inline Point2d operator- (const Point2d & p1, const Vec2d & v); - /// - friend inline Point2d operator+ (const Point2d & p1, const Vec2d & v); - /// - friend inline Vec2d operator- (const Vec2d & p1, const Vec2d & v); - /// - friend inline Vec2d operator+ (const Vec2d & p1, const Vec2d & v); - /// - friend inline Vec2d operator* (double scal, const Vec2d & v); - - /// - friend double operator* (const Vec2d & v1, const Vec2d & v2) - { return v1.X() * v2.X() + v1.Y() * v2.Y(); } - - - /// - friend double Cross (const Vec2d & v1, const Vec2d & v2) - { return double(v1.X()) * double(v2.Y()) - - double(v1.Y()) * double(v2.X()); } - - /// - friend inline void PpSmV (const Point2d & p1, double s, const Vec2d & v, Point2d & p2); - /// - friend inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v); - -/// Angle in [0,2*PI) - - /// - friend double Angle (const Vec2d & v); - /// - friend double FastAngle (const Vec2d & v); - /// - friend double Angle (const Vec2d & v1, const Vec2d & v2); - /// - friend double FastAngle (const Vec2d & v1, const Vec2d & v2); - - /// - friend ostream & operator<<(ostream & s, const Vec2d & v); - }; - - - -/// -class Line2d - { -protected: - /// - Point2d p1, p2; - -public: - /// - Line2d() : p1(), p2() { }; - /// - Line2d(const Point2d & ap1, const Point2d & ap2) - { p1 = ap1; p2 = ap2; } - - /// - Line2d & operator= (const Line2d & l2) - { p1 = l2.p1; p2 = l2.p2; return *this;} - - /// - Point2d & P1() { return p1; } - /// - Point2d & P2() { return p2; } - /// - const Point2d & P1() const { return p1; } - /// - const Point2d & P2() const { return p2; } - - /// - double XMax() const { return max2 (p1.X(), p2.X()); } - /// - double YMax() const { return max2 (p1.Y(), p2.Y()); } - /// - double XMin() const { return min2 (p1.X(), p2.X()); } - /// - double YMin() const { return min2 (p1.Y(), p2.Y()); } - - /// - Vec2d Delta () const { return Vec2d (p2.X()-p1.X(), p2.Y()-p1.Y()); } - /// - double Length () const { return Delta().Length(); } - /// - double Length2 () const - { return sqr (p1.X() - p2.X()) + - sqr (p1.Y() - p2.Y()); } - - void GetNormal (Line2d & n) const; // GH - Vec2d NormalDelta () const; // GH - - /// square of the distance between two 2d-lines. - friend double Dist2(const Line2d & g, const Line2d & h ); // GH - - /// - friend Point2d CrossPoint (const Line2d & l1, const Line2d & l2); - /// returns 1 iff parallel - friend int CrossPointBarycentric (const Line2d & l1, const Line2d & l2, - double & lam1, double & lam2); - - /// - friend int Parallel (const Line2d & l1, const Line2d & l2, double peps); - /// - friend int IsOnLine (const Line2d & l, const Point2d & p, double heps); - /// - friend int IsOnLongLine (const Line2d & l, const Point2d & p); - /// - friend int Hit (const Line2d & l1, const Line2d & l2, double heps); - - /// - friend ostream & operator<<(ostream & s, const Line2d & l); - }; - - -#ifdef NONE -/// -class PLine2d - { -protected: - /// - Point2d const * p1, *p2; - -public: - /// - PLine2d() { }; - /// - PLine2d(Point2d const * ap1, Point2d const * ap2) - { p1 = ap1; p2 = ap2; } - - /// - PLine2d & operator= (const PLine2d & l2) - { p1 = l2.p1; p2 = l2.p2; return *this;} - - /// - const Point2d *& P1() { return p1; } - /// - const Point2d *& P2() { return p2; } - /// - const Point2d & P1() const { return *p1; } - /// - const Point2d & P2() const { return *p2; } - - /// - double XMax() const { return max2 (p1->X(), p2->X()); } - /// - double YMax() const { return max2 (p1->Y(), p2->Y()); } - /// - double XMin() const { return min2 (p1->X(), p2->X()); } - /// - double YMin() const { return min2 (p1->Y(), p2->Y()); } - - - /// - Vec2d Delta () const { return Vec2d (p2->X()-p1->X(), p2->Y()-p1->Y()); } - /// - double Length () const { return Delta().Length(); } - /// - double Length2 () const - { return sqr (p1->X() - p2->X()) + - sqr (p1->Y() - p2->Y()); } - - - - /// - friend Point2d CrossPoint (const PLine2d & l1, const PLine2d & l2); - /// - friend int Parallel (const PLine2d & l1, const PLine2d & l2, double peps); - /// - friend int IsOnLine (const PLine2d & l, const Point2d & p, double heps); - /// - friend int IsOnLongLine (const PLine2d & l, const Point2d & p); - /// - friend int Hit (const PLine2d & l1, const Line2d & l2, double heps); - - /// - friend ostream & operator<<(ostream & s, const Line2d & l); - }; - - - -/// -class ILINE - { - /// - INDEX i[2]; - - public: - /// - ILINE() {}; - /// - ILINE(INDEX i1, INDEX i2) { i[0] = i1; i[1] = i2; } - /// - ILINE(const ILINE & l) { i[0] = l.i[0]; i[1] = l.i[1]; } - - /// - ILINE & operator= (const ILINE & l) - { i[0] = l.i[0]; i[1] = l.i[1]; return *this; } - - /// - const INDEX & I(int ai) const { return i[ai-1]; } - /// - const INDEX & X() const { return i[0]; } - /// - const INDEX & Y() const { return i[1]; } - /// - const INDEX & I1() const { return i[0]; } - /// - const INDEX & I2() const { return i[1]; } - - /// - INDEX & I(int ai) { return i[ai-1]; } - /// - INDEX & X() { return i[0]; } - /// - INDEX & Y() { return i[1]; } - /// - INDEX & I1() { return i[0]; } - /// - INDEX & I2() { return i[1]; } - }; - - - - -/// -class TRIANGLE2D - { -private: - /// - Point2d p1, p2, p3; - -public: - /// - TRIANGLE2D() { }; - /// - TRIANGLE2D (const Point2d & ap1, const Point2d & ap2, - const Point2d & ap3) - { p1 = ap1; p2 = ap2; p3 = ap3;} - - /// - TRIANGLE2D & operator= (const TRIANGLE2D & t2) - { p1 = t2.p1; p2 = t2.p2; p3 = t2.p3; return *this; } - - /// - Point2d & P1() { return p1; } - /// - Point2d & P2() { return p2; } - /// - Point2d & P3() { return p3; } - /// - const Point2d & P1() const { return p1; } - /// - const Point2d & P2() const { return p2; } - /// - const Point2d & P3() const { return p3; } - - /// - double XMax() const { return max3 (p1.X(), p2.X(), p3.X()); } - /// - double YMax() const { return max3 (p1.Y(), p2.Y(), p3.Y()); } - /// - double XMin() const { return min3 (p1.X(), p2.X(), p3.X()); } - /// - double YMin() const { return min3 (p1.Y(), p2.Y(), p3.Y()); } - - /// - inline Point2d Center () const - { return Point2d( (p1.X()+p2.X()+p3.X())/3, (p1.Y()+p2.Y()+p3.Y())/3); } - - /// - int Regular() const; - /// - int CW () const; - /// - int CCW () const; - - /// - int IsOn (const Point2d & p) const; - /// - int IsIn (const Point2d & p) const; - /// - friend ostream & operator<<(ostream & s, const TRIANGLE2D & t); - }; - - -/// -class PTRIANGLE2D - { -private: - /// - Point2d const *p1, *p2, *p3; - -public: - /// - PTRIANGLE2D() { }; - /// - PTRIANGLE2D (const Point2d * ap1, const Point2d * ap2, - const Point2d * ap3) - { p1 = ap1; p2 = ap2; p3 = ap3;} - - /// - PTRIANGLE2D & operator= (const PTRIANGLE2D & t2) - { p1 = t2.p1; p2 = t2.p2; p3 = t2.p3; return *this; } - - /// - const Point2d *& P1() { return p1; } - /// - const Point2d *& P2() { return p2; } - /// - const Point2d *& P3() { return p3; } - /// - const Point2d * P1() const { return p1; } - /// - const Point2d * P2() const { return p2; } - /// - const Point2d * P3() const { return p3; } - - /// - double XMax() const { return max3 (p1->X(), p2->X(), p3->X()); } - /// - double YMax() const { return max3 (p1->Y(), p2->Y(), p3->Y()); } - /// - double XMin() const { return min3 (p1->X(), p2->X(), p3->X()); } - /// - double YMin() const { return min3 (p1->Y(), p2->Y(), p3->Y()); } - - /// - Point2d Center () const - { return Point2d( (p1->X()+p2->X()+p3->X())/3, (p1->Y()+p2->Y()+p3->Y())/3); } - - - /// - int Regular() const; - /// - int CW () const; - /// - int CCW () const; - - /// - int IsOn (const Point2d & p) const; - /// - int IsIn (const Point2d & p) const; - /// - friend ostream & operator<<(ostream & s, const PTRIANGLE2D & t); - }; -#endif - - - -class Polygon2d -{ -protected: - ARRAY<Point2d> points; - -public: - Polygon2d (); - ~Polygon2d (); - - void AddPoint (const Point2d & p); - int GetNP() const { return points.Size(); } - void GetPoint (int i, Point2d & p) const - { p = points.Get(i); } - void GetLine (int i, Point2d & p1, Point2d & p2) const - { p1 = points.Get(i); p2 = points.Get(i%points.Size()+1); } - - double Area () const { return fabs (HArea()); } - int CW () const { return HArea() > 0; } - int CCW () const { return HArea() < 0; } - - int IsOn (const Point2d & p) const; - int IsIn (const Point2d & p) const; - - int IsConvex () const; - - int IsStarPoint (const Point2d & p) const; - Point2d Center() const; - Point2d EqualAreaPoint () const; -private: - double HArea () const; -}; - - -/** Cheap approximation to atan2. - A monotone function of atan2(x,y) is computed. - */ -extern double Fastatan2 (double x, double y); - - -inline Vec2d & Vec2d :: operator+= (const Vec2d & v2) - { - vx += v2.vx; - vy += v2.vy; - return *this; - } - -inline Vec2d & Vec2d :: operator-= (const Vec2d & v2) - { - vx -= v2.vx; - vy -= v2.vy; - return *this; - } - -inline Vec2d & Vec2d :: operator*= (double s) - { - vx *= s; - vy *= s; - return *this; - } - - -inline Vec2d & Vec2d :: operator/= (double s) -{ - if (s != 0) - { - vx /= s; - vy /= s; - } - else - { - MyError ("Vec2d::operator /=: Division by zero"); - } - return *this; -} - - - -inline Vec2d operator- (const Point2d & p1, const Point2d & p2) - { - return Vec2d (p1.X() - p2.X(), p1.Y() - p2.Y()); - } - - -inline Point2d operator- (const Point2d & p1, const Vec2d & v) - { - return Point2d (p1.X() - v.X(), p1.Y() - v.Y()); - } - - -inline Point2d operator+ (const Point2d & p1, const Vec2d & v) - { - return Point2d (p1.X() + v.X(), p1.Y() + v.Y()); - } - - -inline Point2d Center (const Point2d & p1, const Point2d & p2) - { - return Point2d ((p1.X() + p2.X()) / 2, (p1.Y() + p2.Y()) / 2); - } - - -inline Vec2d operator- (const Vec2d & v1, const Vec2d & v2) - { - return Vec2d (v1.X() - v2.X(), v1.Y() - v2.Y()); - } - - -inline Vec2d operator+ (const Vec2d & v1, const Vec2d & v2) - { - return Vec2d (v1.X() + v2.X(), v1.Y() + v2.Y()); - } - - -inline Vec2d operator* (double scal, const Vec2d & v) - { - return Vec2d (scal * v.X(), scal * v.Y()); - } - - -inline void PpSmV (const Point2d & p1, double s, - const Vec2d & v, Point2d & p2) - { - p2.X() = p1.X() + s * v.X(); - p2.Y() = p1.Y() + s * v.Y(); - } - - -inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v) - { - v.X() = p1.X() - p2.X(); - v.Y() = p1.Y() - p2.Y(); - } - - - - - -#ifdef none -inline int TRIANGLE2D :: Regular() const - { - return fabs(Cross ( p2 - p1, p3 - p2)) > EPSGEOM; - } - - -inline int TRIANGLE2D :: CW () const - { - return Cross ( p2 - p1, p3 - p2) < 0; - } - - -inline int TRIANGLE2D :: CCW () const - { - return Cross ( p2 - p1, p3 - p2) > 0; - } - - - - -inline int PTRIANGLE2D :: Regular() const - { - return fabs(Cross ( *p2 - *p1, *p3 - *p2)) > EPSGEOM; - } - - -inline int PTRIANGLE2D :: CW () const - { - return Cross ( *p2 - *p1, *p3 - *p2) < 0; - } - - -inline int PTRIANGLE2D :: CCW () const - { - return Cross ( *p2 - *p1, *p3 - *p2) > 0; - } - - -#endif - - -/// -class Mat2d -{ -protected: - /// - double coeff[4]; - -public: - /// - Mat2d() { coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0; } - /// - Mat2d(double a11, double a12, double a21, double a22) - { coeff[0] = a11; coeff[1] = a12; coeff[2] = a21; coeff[3] = a22; } - /// - Mat2d(const Mat2d & m2) - { for (int i = 0; i < 4; i++) coeff[i] = m2.Get(i); } - - /// - double & Elem (INDEX i, INDEX j) { return coeff[2*(i-1)+j-1]; } - /// - double & Elem (INDEX i) {return coeff[i]; } - /// - double Get (INDEX i, INDEX j) const { return coeff[2*(i-1)+j-1]; } - /// - double Get (INDEX i) const {return coeff[i]; } - - /// - double Det () const { return coeff[0] * coeff[3] - coeff[1] * coeff[2]; } - - /// - void Mult (const Vec2d & v, Vec2d & prod) const; - /// - void MultTrans (const Vec2d & v , Vec2d & prod) const; - /// - void Solve (const Vec2d & rhs, Vec2d & x) const; - /// Solves mat * x = rhs, but using a positive definite matrix instead of mat - void SolvePositiveDefinite (const Vec2d & rhs, Vec2d & x) const; - /// add a term \alpha * v * v^T - void AddDiadicProduct (double alpha, Vec2d & v); -}; - - - -inline void Mat2d :: Mult (const Vec2d & v, Vec2d & prod) const -{ - prod.X() = coeff[0] * v.X() + coeff[1] * v.Y(); - prod.Y() = coeff[2] * v.X() + coeff[3] * v.Y(); -} - - -inline void Mat2d :: MultTrans (const Vec2d & v, Vec2d & prod) const -{ - prod.X() = coeff[0] * v.X() + coeff[2] * v.Y(); - prod.Y() = coeff[1] * v.X() + coeff[3] * v.Y(); -} - - - -inline void Mat2d :: Solve (const Vec2d & rhs, Vec2d & x) const -{ - double det = Det(); - - if (det == 0) - MyError ("Mat2d::Solve: zero determinant"); - else - { - x.X() = (coeff[3] * rhs.X() - coeff[1] * rhs.Y()) / det; - x.Y() = (-coeff[2] * rhs.X() + coeff[0] * rhs.Y()) / det; - } -} - - -inline void Mat2d :: SolvePositiveDefinite (const Vec2d & rhs, Vec2d & x) const -{ - double a = max2(coeff[0], 1e-8); - double b = coeff[1] / a; - double c = coeff[2] / a; - double d = max2(coeff[3] - a *b * c, 1e-8); - - x.X() = (rhs.X() - b * rhs.Y()) / a; - x.Y() = rhs.Y() / d - c * x.X(); -} - - -inline void Mat2d :: AddDiadicProduct (double alpha, Vec2d & v) -{ - coeff[0] += alpha * v.X() * v.X(); - coeff[1] += alpha * v.X() * v.Y(); - coeff[2] += alpha * v.Y() * v.X(); - coeff[3] += alpha * v.Y() * v.Y(); -} - - - -#endif diff --git a/Netgen/libsrc/gprim/geom3d.cpp b/Netgen/libsrc/gprim/geom3d.cpp deleted file mode 100644 index eaee776778..0000000000 --- a/Netgen/libsrc/gprim/geom3d.cpp +++ /dev/null @@ -1,650 +0,0 @@ -#include <algorithm> -#include <mystdlib.h> - -#include <myadt.hpp> -#include <gprim.hpp> - -namespace netgen -{ -ostream & operator<<(ostream & s, const Point3d & p) - { - return s << "(" << p.x[0] << ", " << p.x[1] << ", " << p.x[2] << ")"; - } - -ostream & operator<<(ostream & s, const Vec3d & v) - { - return s << "(" << v.x[0] << ", " << v.x[1] << ", " << v.x[2] << ")"; - } - -double Angle (const Vec3d & v1, const Vec3d & v2) -{ - double co = (v1 * v2) / (v1.Length() * v2.Length()); - if (co > 1) co = 1; - if (co < -1) co = -1; - return acos ( co ); -} - - -void Vec3d :: GetNormal (Vec3d & n) const - { - if (fabs (X()) > fabs (Z())) - { - n.X() = -Y(); - n.Y() = X(); - n.Z() = 0; - } - else - { - n.X() = 0; - n.Y() = Z(); - n.Z() = -Y(); - } - double len = n.Length(); - if (len == 0) - { - n.X() = 1; - n.Y() = n.Z() = 0; - } - else - n /= len; - } - -/* -ostream & operator<<(ostream & s, const ROTDenseMatrix3D & r) - { - return s << "{ (" << r.txx << ", " << r.txy << ", " << r.txz << ") , (" - << r.tyx << ", " << r.tyy << ", " << r.tyz << ") , (" - << r.tzx << ", " << r.tzy << ", " << r.tzz << ") }"; - } -*/ - -/* -Vec3d operator- (const Point3d & p1, const Point3d & p2) - { - return Vec3d (p1.X() - p2.X(), p1.Y() - p2.Y(),p1.Z() - p2.Z()); - } - -Point3d operator- (const Point3d & p1, const Vec3d & v) - { - return Point3d (p1.X() - v.X(), p1.Y() - v.Y(),p1.Z() - v.Z()); - } - -Point3d operator+ (const Point3d & p1, const Vec3d & v) - { - return Point3d (p1.X() + v.X(), p1.Y() + v.Y(),p1.Z() + v.Z()); - } - -Vec3d operator- (const Vec3d & v1, const Vec3d & v2) - { - return Vec3d (v1.X() - v2.X(), v1.Y() - v2.Y(),v1.Z() - v2.Z()); - } - -Vec3d operator+ (const Vec3d & v1, const Vec3d & v2) - { - return Vec3d (v1.X() + v2.X(), v1.Y() + v2.Y(),v1.Z() + v2.Z()); - } - -Vec3d operator* (double scal, const Vec3d & v) - { - return Vec3d (scal * v.X(), scal * v.Y(), scal * v.Z()); - } -*/ -/* -double operator* (const Vec3d & v1, const Vec3d & v2) - { - return v1.X() * v2.X() + v1.Y() * v2.Y() + v1.Z() * v2.Z(); - } - -double Cross (const Vec3d & v1, const Vec3d & v2) - { - return v1.X() * v2.Y() - v1.Y() * v2.X(); - } -*/ - -/* -void ROTDenseMatrix3D :: CalcRotMat(double ag, double bg, double lg, double size2, Vec3d r) - { - size = size2; - txx=size * ( cos(bg) * cos(lg) ); - txy=size * ( cos(bg) * sin(lg) ); - txz=size * (-sin(bg) ); - - tyx=size * ( sin(ag) * sin(bg) * cos(lg) - cos(ag) * sin(lg) ); - tyy=size * ( sin(ag) * sin(bg) * sin(lg) + cos(ag) * cos(lg) ); - tyz=size * ( sin(ag) * cos(bg) ); - - tzx=size * ( cos(ag) * sin(bg) * cos(lg) + sin(ag) * sin(lg) ); - tzy=size * ( cos(ag) * sin(bg) * sin(lg) - sin(ag) * cos(lg) ); - tzz=size * ( cos(ag) * cos(bg) ); - - deltaR=r; - } -ROTDenseMatrix3D :: ROTDenseMatrix3D(double ag, double bg, double lg, double size2, Vec3d r) - {CalcRotMat(ag, bg, lg, size2, r); } - -ROTDenseMatrix3D :: ROTDenseMatrix3D(Vec3d rot2) - { - Vec3d r2(0,0,0); - CalcRotMat(rot2.X(), rot2.Y(), rot2.Z(), 1, r2); - } - -ROTDenseMatrix3D ROTDenseMatrix3D :: INV() - { - ROTDenseMatrix3D rinv(txx/sqr(size),tyx/sqr(size),tzx/sqr(size), - txy/sqr(size),tyy/sqr(size),tzy/sqr(size), - txz/sqr(size),tyz/sqr(size),tzz/sqr(size), - 1/size,deltaR); - return rinv; - } - -Vec3d operator* (const ROTDenseMatrix3D & r, const Vec3d & v) - { - return Vec3d (r.XX() * v.X() + r.XY() * v.Y() + r.XZ() * v.Z(), - r.YX() * v.X() + r.YY() * v.Y() + r.YZ() * v.Z(), - r.ZX() * v.X() + r.ZY() * v.Y() + r.ZZ() * v.Z() ); - } - -Point3d operator* (const ROTDenseMatrix3D & r, const Point3d & p) - { - return Point3d (r.XX() * p.X() + r.XY() * p.Y() + r.XZ() * p.Z(), - r.YX() * p.X() + r.YY() * p.Y() + r.YZ() * p.Z(), - r.ZX() * p.X() + r.ZY() * p.Y() + r.ZZ() * p.Z() ); - } -*/ - - - - - - - -Box3d :: Box3d ( double aminx, double amaxx, - double aminy, double amaxy, - double aminz, double amaxz ) -{ - minx[0] = aminx; maxx[0] = amaxx; - minx[1] = aminy; maxx[1] = amaxy; - minx[2] = aminz; maxx[2] = amaxz; -} - -Box3d :: Box3d ( const Box3d & b2 ) -{ - for (int i = 0; i < 3; i++) - { - minx[i] = b2.minx[i]; - maxx[i] = b2.maxx[i]; - } -} - -Box3d :: Box3d ( const Box<3> & b2 ) -{ - for (int i = 0; i < 3; i++) - { - minx[i] = b2.PMin()(i); - maxx[i] = b2.PMax()(i); - } -} - - -/* -int Box3d :: Intersect (const Box3d & box2) const -{ - int i; - for (i = 0; i <= 2; i++) - if (minx[i] > box2.maxx[i] || maxx[i] < box2.minx[i]) - return 0; - return 1; -} -*/ - -/* -void Box3d :: SetPoint (const Point3d & p) -{ - minx[0] = maxx[0] = p.X(); - minx[1] = maxx[1] = p.Y(); - minx[2] = maxx[2] = p.Z(); -} - -void Box3d :: AddPoint (const Point3d & p) -{ - if (p.X() < minx[0]) minx[0] = p.X(); - if (p.X() > maxx[0]) maxx[0] = p.X(); - if (p.Y() < minx[1]) minx[1] = p.Y(); - if (p.Y() > maxx[1]) maxx[1] = p.Y(); - if (p.Z() < minx[2]) minx[2] = p.Z(); - if (p.Z() > maxx[2]) maxx[2] = p.Z(); -} -*/ - -void Box3d :: GetPointNr (int i, Point3d & point) const -{ - i--; - point.X() = (i & 1) ? maxx[0] : minx[0]; - point.Y() = (i & 2) ? maxx[1] : minx[1]; - point.Z() = (i & 4) ? maxx[2] : minx[2]; -} - - -void Box3d :: Increase (double d) -{ - for (int i = 0; i <= 2; i++) - { - minx[i] -= d; - maxx[i] += d; - } -} - -void Box3d :: IncreaseRel (double /* rel */) -{ - for (int i = 0; i <= 2; i++) - { - double d = 0.5 * (maxx[i] - minx[i]); - minx[i] -= d; - maxx[i] += d; - } -} - - -Box3d :: Box3d (const Point3d& p1, const Point3d& p2) -{ - minx[0] = min2 (p1.X(), p2.X()); - minx[1] = min2 (p1.Y(), p2.Y()); - minx[2] = min2 (p1.Z(), p2.Z()); - maxx[0] = max2 (p1.X(), p2.X()); - maxx[1] = max2 (p1.Y(), p2.Y()); - maxx[2] = max2 (p1.Z(), p2.Z()); -} - -const Box3d& Box3d :: operator+=(const Box3d& b) -{ - minx[0] = min2 (minx[0], b.minx[0]); - minx[1] = min2 (minx[1], b.minx[1]); - minx[2] = min2 (minx[2], b.minx[2]); - maxx[0] = max2 (maxx[0], b.maxx[0]); - maxx[1] = max2 (maxx[1], b.maxx[1]); - maxx[2] = max2 (maxx[2], b.maxx[2]); - - return *this; -} - -Point3d Box3d :: MaxCoords() const -{ - return Point3d(maxx[0], maxx[1], maxx[2]); -} - -Point3d Box3d :: MinCoords() const -{ - return Point3d(minx[0], minx[1], minx[2]); -} - -/* -void Box3d :: CreateNegMinMaxBox() -{ - minx[0] = MAXDOUBLE; - minx[1] = MAXDOUBLE; - minx[2] = MAXDOUBLE; - maxx[0] = MINDOUBLE; - maxx[1] = MINDOUBLE; - maxx[2] = MINDOUBLE; - -} -*/ - -void Box3d :: WriteData(ofstream& fout) const -{ - for(int i = 0; i < 3; i++) - { - fout << minx[i] << " " << maxx[i] << " "; - } - fout << "\n"; -} - -void Box3d :: ReadData(ifstream& fin) -{ - for(int i = 0; i < 3; i++) - { - fin >> minx[i]; - fin >> maxx[i]; - } -} - - - - -Box3dSphere :: Box3dSphere ( double aminx, double amaxx, - double aminy, double amaxy, - double aminz, double amaxz ) - : Box3d (aminx, amaxx, aminy, amaxy, aminz, amaxz) -{ - CalcDiamCenter (); -} - - -void Box3dSphere :: CalcDiamCenter () -{ - diam = sqrt( sqr (maxx[0] - minx[0]) + - sqr (maxx[1] - minx[1]) + - sqr (maxx[2] - minx[2])); - - c.X() = 0.5 * (minx[0] + maxx[0]); - c.Y() = 0.5 * (minx[1] + maxx[1]); - c.Z() = 0.5 * (minx[2] + maxx[2]); - - inner = min2 ( min2 (maxx[0] - minx[0], maxx[1] - minx[1]), maxx[2] - minx[2]) / 2; -} - - -void Box3dSphere :: GetSubBox (int i, Box3dSphere & sbox) const -{ - i--; - if (i & 1) - { - sbox.minx[0] = c.X(); - sbox.maxx[0] = maxx[0]; - } - else - { - sbox.minx[0] = minx[0]; - sbox.maxx[0] = c.X(); - } - if (i & 2) - { - sbox.minx[1] = c.Y(); - sbox.maxx[1] = maxx[1]; - } - else - { - sbox.minx[1] = minx[1]; - sbox.maxx[1] = c.Y(); - } - if (i & 4) - { - sbox.minx[2] = c.Z(); - sbox.maxx[2] = maxx[2]; - } - else - { - sbox.minx[2] = minx[2]; - sbox.maxx[2] = c.Z(); - } - - // sbox.CalcDiamCenter (); - - sbox.c.X() = 0.5 * (sbox.minx[0] + sbox.maxx[0]); - sbox.c.Y() = 0.5 * (sbox.minx[1] + sbox.maxx[1]); - sbox.c.Z() = 0.5 * (sbox.minx[2] + sbox.maxx[2]); - sbox.diam = 0.5 * diam; - sbox.inner = 0.5 * inner; -} - - - - -/* -double Determinant (const Vec3d & col1, - const Vec3d & col2, - const Vec3d & col3) -{ - return - col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) + - col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) + - col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]); -} -*/ - -void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3) -{ - Swap (v1.Y(), v2.X()); - Swap (v1.Z(), v3.X()); - Swap (v2.Z(), v3.Y()); -} - - -int SolveLinearSystem (const Vec3d & col1, const Vec3d & col2, - const Vec3d & col3, const Vec3d & rhs, - Vec3d & sol) -{ - Vec3d cr; - Cross (col1, col2, cr); - double det = cr * col3; - - if (fabs (det) < 1e-40) - return 1; - - if (fabs(cr.Z()) > 1e-12) - { - // solve for 3. component - sol.Z() = (cr * rhs) / det; - - // 2x2 system for 1. and 2. component - double res1 = rhs.X() - sol.Z() * col3.X(); - double res2 = rhs.Y() - sol.Z() * col3.Y(); - - sol.X() = (col2.Y() * res1 - col2.X() * res2) / cr.Z(); - sol.Y() = (col1.X() * res2 - col1.Y() * res1) / cr.Z(); - - } - else - { - det = Determinant (col1, col2, col3); - if (fabs (det) < 1e-40) - return 1; - - sol.X() = Determinant (rhs, col2, col3) / det; - sol.Y() = Determinant (col1, rhs, col3) / det; - sol.Z() = Determinant (col1, col2, rhs) / det; - } - - return 0; -} - - -int SolveLinearSystemLS (const Vec3d & col1, - const Vec3d & col2, - const Vec2d & rhs, - Vec3d & sol) -{ - double a11 = col1 * col1; - double a12 = col1 * col2; - double a22 = col2 * col2; - - double det = a11 * a22 - a12 * a12; - - if (det*det <= 1e-24 * a11 * a22) - { - sol = Vec3d (0, 0, 0); - return 1; - } - - Vec2d invrhs; - invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det; - invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det; - - sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X(); - sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y(); - sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z(); - - return 0; - - /* - Vec3d inv1, inv2; - int err = - PseudoInverse (col1, col2, inv1, inv2); - - sol = rhs.X() * inv1 + rhs.Y() * inv2; - return err; - */ -} - -int SolveLinearSystemLS2 (const Vec3d & col1, - const Vec3d & col2, - const Vec2d & rhs, - Vec3d & sol, double & x, double & y) -{ - double a11 = col1 * col1; - double a12 = col1 * col2; - double a22 = col2 * col2; - - double det = a11 * a22 - a12 * a12; - - if (fabs (det) <= 1e-12 * col1.Length() * col2.Length() || - col1.Length2() == 0 || col2.Length2() == 0) - { - sol = Vec3d (0, 0, 0); - x = 0; y = 0; - return 1; - } - - Vec2d invrhs; - invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det; - invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det; - - sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X(); - sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y(); - sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z(); - - x = invrhs.X(); - y = invrhs.Y(); - - return 0; - - /* - Vec3d inv1, inv2; - int err = - PseudoInverse (col1, col2, inv1, inv2); - - sol = rhs.X() * inv1 + rhs.Y() * inv2; - return err; - */ -} - -int PseudoInverse (const Vec3d & col1, - const Vec3d & col2, - Vec3d & inv1, - Vec3d & inv2) -{ - double a11 = col1 * col1; - double a12 = col1 * col2; - double a22 = col2 * col2; - - double det = a11 * a22 - a12 * a12; - - if (fabs (det) < 1e-12 * col1.Length() * col2.Length()) - { - inv1 = Vec3d (0, 0, 0); - inv2 = Vec3d (0, 0, 0); - return 1; - } - - double ia11 = a22 / det; - double ia12 = -a12 / det; - double ia22 = a11 / det; - - inv1 = ia11 * col1 + ia12 * col2; - inv2 = ia12 * col1 + ia22 * col2; - - return 0; -} - - - - -QuadraticFunction3d :: -QuadraticFunction3d (const Point3d & p, const Vec3d & v) -{ - Vec3d hv(v); - hv /= (hv.Length() + 1e-12); - Vec3d t1, t2; - hv.GetNormal (t1); - Cross (hv, t1, t2); - - double t1p = t1.X() * p.X() + t1.Y() * p.Y() + t1.Z() * p.Z(); - double t2p = t2.X() * p.X() + t2.Y() * p.Y() + t2.Z() * p.Z(); - c0 = sqr (t1p) + sqr (t2p); - cx = -2 * (t1p * t1.X() + t2p * t2.X()); - cy = -2 * (t1p * t1.Y() + t2p * t2.Y()); - cz = -2 * (t1p * t1.Z() + t2p * t2.Z()); - - cxx = t1.X() * t1.X() + t2.X() * t2.X(); - cyy = t1.Y() * t1.Y() + t2.Y() * t2.Y(); - czz = t1.Z() * t1.Z() + t2.Z() * t2.Z(); - - cxy = 2 * t1.X() * t1.Y() + 2 * t2.X() * t2.Y(); - cxz = 2 * t1.X() * t1.Z() + 2 * t2.X() * t2.Z(); - cyz = 2 * t1.Y() * t1.Z() + 2 * t2.Y() * t2.Z(); - - /* - (*testout) << "c0 = " << c0 - << " clin = " << cx << " " << cy << " " << cz - << " cq = " << cxx << " " << cyy << " " << czz - << cxy << " " << cyz << " " << cyz << endl; - */ -} - -// QuadraticFunction3d gqf (Point3d (0,0,0), Vec3d (1, 0, 0)); - - - - - -void referencetransform :: Set (const Point3d & p1, const Point3d & p2, - const Point3d & p3, double ah) -{ - ex = p2 - p1; - ex /= ex.Length(); - ey = p3 - p1; - ey -= (ex * ey) * ex; - ey /= ey.Length(); - ez = Cross (ex, ey); - rp = p1; - h = ah; - - exh = ah * ex; - eyh = ah * ey; - ezh = ah * ez; - ah = 1 / ah; - ex_h = ah * ex; - ey_h = ah * ey; - ez_h = ah * ez; -} - -void referencetransform :: ToPlain (const Point3d & p, Point3d & pp) const -{ - Vec3d v; - v = p - rp; - pp.X() = (ex_h * v); - pp.Y() = (ey_h * v); - pp.Z() = (ez_h * v); -} - -void referencetransform :: ToPlain (const ARRAY<Point3d> & p, - ARRAY<Point3d> & pp) const -{ - Vec3d v; - int i; - - pp.SetSize (p.Size()); - for (i = 1; i <= p.Size(); i++) - { - v = p.Get(i) - rp; - pp.Elem(i).X() = (ex_h * v); - pp.Elem(i).Y() = (ey_h * v); - pp.Elem(i).Z() = (ez_h * v); - } -} - -void referencetransform :: FromPlain (const Point3d & pp, Point3d & p) const -{ - Vec3d v; - // v = (h * pp.X()) * ex + (h * pp.Y()) * ey + (h * pp.Z()) * ez; - // p = rp + v; - v.X() = pp.X() * exh.X() + pp.Y() * eyh.X() + pp.Z() * ezh.X(); - v.Y() = pp.X() * exh.Y() + pp.Y() * eyh.Y() + pp.Z() * ezh.Y(); - v.Z() = pp.X() * exh.Z() + pp.Y() * eyh.Z() + pp.Z() * ezh.Z(); - p.X() = rp.X() + v.X(); - p.Y() = rp.Y() + v.Y(); - p.Z() = rp.Z() + v.Z(); -} - - -} diff --git a/Netgen/libsrc/gprim/geom3d.hpp b/Netgen/libsrc/gprim/geom3d.hpp deleted file mode 100644 index 56bff4ad6b..0000000000 --- a/Netgen/libsrc/gprim/geom3d.hpp +++ /dev/null @@ -1,732 +0,0 @@ -#ifndef FILE_GEOM3D -#define FILE_GEOM3D - -/* *************************************************************************/ -/* File: geom3d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 5. Aug. 95 */ -/* *************************************************************************/ - - - - -extern void MyError (const char * ch); - -class Point3d; -class Vec3d; - -inline Vec3d operator- (const Point3d & p1, const Point3d & p2); -inline Point3d operator- (const Point3d & p1, const Vec3d & v); -inline Point3d operator+ (const Point3d & p1, const Vec3d & v); -Point3d & Add (double d, const Vec3d & v); -Point3d & Add2 (double d, const Vec3d & v, - double d2, const Vec3d & v2); -inline Point3d Center (const Point3d & p1, const Point3d & p2); -inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3); -inline Point3d Center (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4); -ostream & operator<<(ostream & s, const Point3d & p); -inline Vec3d operator- (const Vec3d & p1, const Vec3d & v); -inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v); -inline Vec3d operator* (double scal, const Vec3d & v); -inline double operator* (const Vec3d & v1, const Vec3d & v2); -inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2); -inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod); -double Angle (const Vec3d & v); -double FastAngle (const Vec3d & v); -double Angle (const Vec3d & v1, const Vec3d & v2); -double FastAngle (const Vec3d & v1, const Vec3d & v2); -ostream & operator<<(ostream & s, const Vec3d & v); -void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3); -int SolveLinearSystem (const Vec3d & col1, - const Vec3d & col2, - const Vec3d & col3, - const Vec3d & rhs, - Vec3d & sol); -int SolveLinearSystemLS (const Vec3d & col1, - const Vec3d & col2, - const Vec2d & rhs, - Vec3d & sol); -int SolveLinearSystemLS2 (const Vec3d & col1, - const Vec3d & col2, - const Vec2d & rhs, - Vec3d & sol, - double & x, double & y); -int PseudoInverse (const Vec3d & col1, - const Vec3d & col2, - Vec3d & inv1, - Vec3d & inv2); -double Determinant (const Vec3d & col1, - const Vec3d & col2, - const Vec3d & col3); - -/// Point in R3 -class Point3d -{ -protected: - /// - double x[3]; - -public: - /// - Point3d () { x[0] = x[1] = x[2] = 0; } - /// - Point3d(double ax, double ay, double az) - { x[0] = ax; x[1] = ay; x[2] = az; } - /// - Point3d(double ax[3]) - { x[0] = ax[0]; x[1] = ax[1]; x[2] = ax[2]; } - - /// - Point3d(const Point3d & p2) - { x[0] = p2.x[0]; x[1] = p2.x[1]; x[2] = p2.x[2]; } - - Point3d (const Point<3> & p2) - { - for (int i = 0; i < 3; i++) - x[i] = p2(i); - } - - /// - Point3d & operator= (const Point3d & p2) - { x[0] = p2.x[0]; x[1] = p2.x[1]; x[2] = p2.x[2]; return *this; } - - /// - int operator== (const Point3d& p) const - { return (x[0] == p.x[0] && x[1] == p.x[1] && x[2] == p.x[2]); } - - /// - double & X() { return x[0]; } - /// - double & Y() { return x[1]; } - /// - double & Z() { return x[2]; } - /// - double X() const { return x[0]; } - /// - double Y() const { return x[1]; } - /// - double Z() const { return x[2]; } - /// - double & X(int i) { return x[i-1]; } - /// - double X(int i) const { return x[i-1]; } - /// - const Point3d & SetToMin (const Point3d & p2) - { - if (p2.x[0] < x[0]) x[0] = p2.x[0]; - if (p2.x[1] < x[1]) x[1] = p2.x[1]; - if (p2.x[2] < x[2]) x[2] = p2.x[2]; - return *this; - } - - /// - const Point3d & SetToMax (const Point3d & p2) - { - if (p2.x[0] > x[0]) x[0] = p2.x[0]; - if (p2.x[1] > x[1]) x[1] = p2.x[1]; - if (p2.x[2] > x[2]) x[2] = p2.x[2]; - return *this; - } - - /// - friend inline Vec3d operator- (const Point3d & p1, const Point3d & p2); - /// - friend inline Point3d operator- (const Point3d & p1, const Vec3d & v); - /// - friend inline Point3d operator+ (const Point3d & p1, const Vec3d & v); - /// - inline Point3d & operator+= (const Vec3d & v); - inline Point3d & operator-= (const Vec3d & v); - /// - inline Point3d & Add (double d, const Vec3d & v); - /// - inline Point3d & Add2 (double d, const Vec3d & v, - double d2, const Vec3d & v2); - /// - friend inline double Dist (const Point3d & p1, const Point3d & p2) - { return sqrt ( (p1.x[0]-p2.x[0]) * (p1.x[0]-p2.x[0]) + - (p1.x[1]-p2.x[1]) * (p1.x[1]-p2.x[1]) + - (p1.x[2]-p2.x[2]) * (p1.x[2]-p2.x[2])); } - /// - inline friend double Dist2 (const Point3d & p1, const Point3d & p2) - { return ( (p1.x[0]-p2.x[0]) * (p1.x[0]-p2.x[0]) + - (p1.x[1]-p2.x[1]) * (p1.x[1]-p2.x[1]) + - (p1.x[2]-p2.x[2]) * (p1.x[2]-p2.x[2])); } - - /// - friend inline Point3d Center (const Point3d & p1, const Point3d & p2); - /// - friend inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3); - /// - friend inline Point3d Center (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4); - /// - friend ostream & operator<<(ostream & s, const Point3d & p); - - /// - friend class Vec3d; - /// - friend class Box3d; - - - operator Point<3> () const - { - return Point<3> (x[0], x[1], x[2]); - } -}; - - -/// -class Vec3d -{ -protected: - /// - double x[3]; - -public: - /// - inline Vec3d() { x[0] = x[1] = x[2] = 0; } - /// - inline Vec3d(double ax, double ay, double az) - { x[0] = ax; x[1] = ay; x[2] = az; } - /// - Vec3d(double ax[3]) - { x[0] = ax[0]; x[1] = ax[1]; x[2] = ax[2]; } - /// - inline Vec3d(const Vec3d & v2) - { x[0] = v2.x[0]; x[1] = v2.x[1]; x[2] = v2.x[2]; } - /// - inline Vec3d(const Point3d & p1, const Point3d & p2) - { - x[0] = p2.x[0] - p1.x[0]; - x[1] = p2.x[1] - p1.x[1]; - x[2] = p2.x[2] - p1.x[2]; - } - /// - inline Vec3d(const Point3d & p1) - { - x[0] = p1.x[0]; - x[1] = p1.x[1]; - x[2] = p1.x[2]; - } - - Vec3d (const Vec<3> & v2) - { - for (int i = 0; i < 3; i++) - x[i] = v2(i); - } - - operator Vec<3> () const - { - return Vec<3> (x[0], x[1], x[2]); - } - - - Vec3d & operator= (const Vec3d & v2) - { x[0] = v2.x[0]; x[1] = v2.x[1]; x[2] = v2.x[2]; return *this; } - /// - Vec3d & operator= (double val) - { x[0] = x[1] = x[2] = val; return *this; } - /// - double & X() { return x[0]; } - /// - double & Y() { return x[1]; } - /// - double & Z() { return x[2]; } - /// - double & X(int i) { return x[i-1]; } - - /// - double X() const { return x[0]; } - /// - double Y() const { return x[1]; } - /// - double Z() const { return x[2]; } - /// - double X(int i) const { return x[i-1]; } - - /// - double Length() const - { return sqrt (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); } - /// - double Length2() const - { return x[0] * x[0] + x[1] * x[1] + x[2] * x[2]; } - - /// - Vec3d & operator+= (const Vec3d & v2); - /// - Vec3d & operator-= (const Vec3d & v2); - /// - Vec3d & operator*= (double s); - /// - Vec3d & operator/= (double s); - /// - inline Vec3d & Add (double d, const Vec3d & v); - /// - inline Vec3d & Add2 (double d, const Vec3d & v, - double d2, const Vec3d & v2); - - /// - friend inline Vec3d operator- (const Point3d & p1, const Point3d & p2); - /// - friend inline Point3d operator- (const Point3d & p1, const Vec3d & v); - /// - friend inline Point3d operator+ (const Point3d & p1, const Vec3d & v); - /// - friend inline Vec3d operator- (const Vec3d & p1, const Vec3d & v); - /// - friend inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v); - /// - friend inline Vec3d operator* (double scal, const Vec3d & v); - - /// - friend inline double operator* (const Vec3d & v1, const Vec3d & v2); - /// - friend inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2); - /// - friend inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod); - - /// Returns one normal-vector to n - void GetNormal (Vec3d & n) const; - /// - friend double Angle (const Vec3d & v); - /// - friend double FastAngle (const Vec3d & v); - /// - friend double Angle (const Vec3d & v1, const Vec3d & v2); - /// - friend double FastAngle (const Vec3d & v1, const Vec3d & v2); - - void Normalize() - { - double len = (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); - if (len == 0) return; - len = sqrt (len); - x[0] /= len; x[1] /= len; x[2] /= len; - } - - /// - friend ostream & operator<<(ostream & s, const Vec3d & v); - - /// - friend class Point3d; - friend void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3); - friend int SolveLinearSystem (const Vec3d & col1, - const Vec3d & col2, - const Vec3d & col3, - const Vec3d & rhs, - Vec3d & sol); - friend int SolveLinearSystemLS (const Vec3d & col1, - const Vec3d & col2, - const Vec2d & rhs, - Vec3d & sol); - friend int SolveLinearSystemLS2 (const Vec3d & col1, - const Vec3d & col2, - const Vec2d & rhs, - Vec3d & sol, - double & x, double & y); - friend int PseudoInverse (const Vec3d & col1, - const Vec3d & col2, - Vec3d & inv1, - Vec3d & inv2); - friend double Determinant (const Vec3d & col1, - const Vec3d & col2, - const Vec3d & col3); -}; - - - - -class QuadraticFunction3d -{ - double c0, cx, cy, cz; - double cxx, cyy, czz, cxy, cxz, cyz; - -public: - QuadraticFunction3d (const Point3d & p, const Vec3d & v); - double Eval (const Point3d & p) - { - return - c0 - + p.X() * (cx + cxx * p.X() + cxy * p.Y() + cxz * p.Z()) - + p.Y() * (cy + cyy * p.Y() + cyz * p.Z()) - + p.Z() * (cz + czz * p.Z()); - } -}; - - - -inline Point3d Center (const Point3d & p1, const Point3d & p2) -{ - return Point3d (0.5 * (p1.x[0] + p2.x[0]), - 0.5 * (p1.x[1] + p2.x[1]), - 0.5 * (p1.x[2] + p2.x[2])); -} - - -inline Point3d Center (const Point3d & p1, const Point3d & p2, - const Point3d & p3) -{ - return Point3d (1.0/3.0 * (p1.x[0] + p2.x[0] + p3.x[0]), - 1.0/3.0 * (p1.x[1] + p2.x[1] + p3.x[1]), - 1.0/3.0 * (p1.x[2] + p2.x[2] + p3.x[2])); -} - -inline Point3d Center (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4) -{ - return Point3d (0.25 * (p1.x[0] + p2.x[0] + p3.x[0] + p4.x[0]), - 0.25 * (p1.x[1] + p2.x[1] + p3.x[1] + p4.x[1]), - 0.25 * (p1.x[2] + p2.x[2] + p3.x[2] + p4.x[2])); -} - - - -inline Vec3d & Vec3d :: operator+= (const Vec3d & v2) -{ - x[0] += v2.x[0]; - x[1] += v2.x[1]; - x[2] += v2.x[2]; - return *this; -} - -inline Vec3d & Vec3d :: operator-= (const Vec3d & v2) -{ - x[0] -= v2.x[0]; - x[1] -= v2.x[1]; - x[2] -= v2.x[2]; - return *this; -} - - -inline Vec3d & Vec3d :: operator*= (double s) -{ - x[0] *= s; - x[1] *= s; - x[2] *= s; - return *this; -} - - -inline Vec3d & Vec3d :: operator/= (double s) -{ - if (s != 0) - { - x[0] /= s; - x[1] /= s; - x[2] /= s; - } -#ifdef DEBUG - else - { - cerr << "Vec div by 0, v = " << (*this) << endl; - // MyError ("Vec3d::operator /=: Divisioin by zero"); - } -#endif - return *this; -} - -inline Vec3d & Vec3d::Add (double d, const Vec3d & v) -{ - x[0] += d * v.x[0]; - x[1] += d * v.x[1]; - x[2] += d * v.x[2]; - return *this; -} - -inline Vec3d & Vec3d::Add2 (double d, const Vec3d & v, - double d2, const Vec3d & v2) -{ - x[0] += d * v.x[0] + d2 * v2.x[0]; - x[1] += d * v.x[1] + d2 * v2.x[1]; - x[2] += d * v.x[2] + d2 * v2.x[2]; - return *this; -} - - - - - - - - -inline Vec3d operator- (const Point3d & p1, const Point3d & p2) -{ - return Vec3d (p1.x[0] - p2.x[0], p1.x[1] - p2.x[1],p1.x[2] - p2.x[2]); -} - - -inline Point3d operator- (const Point3d & p1, const Vec3d & v) -{ - return Point3d (p1.x[0] - v.x[0], p1.x[1] - v.x[1],p1.x[2] - v.x[2]); -} - - -inline Point3d operator+ (const Point3d & p1, const Vec3d & v) -{ - return Point3d (p1.x[0] + v.x[0], p1.x[1] + v.x[1],p1.x[2] + v.x[2]); -} - -inline Point3d & Point3d::operator+= (const Vec3d & v) -{ - x[0] += v.x[0]; - x[1] += v.x[1]; - x[2] += v.x[2]; - return *this; -} - -inline Point3d & Point3d::operator-= (const Vec3d & v) -{ - x[0] -= v.x[0]; - x[1] -= v.x[1]; - x[2] -= v.x[2]; - return *this; -} - -inline Point3d & Point3d::Add (double d, const Vec3d & v) -{ - x[0] += d * v.x[0]; - x[1] += d * v.x[1]; - x[2] += d * v.x[2]; - return *this; -} - -inline Point3d & Point3d::Add2 (double d, const Vec3d & v, - double d2, const Vec3d & v2) -{ - x[0] += d * v.x[0] + d2 * v2.x[0]; - x[1] += d * v.x[1] + d2 * v2.x[1]; - x[2] += d * v.x[2] + d2 * v2.x[2]; - return *this; -} - - -inline Vec3d operator- (const Vec3d & v1, const Vec3d & v2) -{ - return Vec3d (v1.x[0] - v2.x[0], v1.x[1] - v2.x[1],v1.x[2] - v2.x[2]); -} - - -inline Vec3d operator+ (const Vec3d & v1, const Vec3d & v2) -{ - return Vec3d (v1.x[0] + v2.x[0], v1.x[1] + v2.x[1],v1.x[2] + v2.x[2]); -} - - -inline Vec3d operator* (double scal, const Vec3d & v) -{ - return Vec3d (scal * v.x[0], scal * v.x[1], scal * v.x[2]); -} - - - -inline double operator* (const Vec3d & v1, const Vec3d & v2) -{ - return v1.x[0] * v2.x[0] + v1.x[1] * v2.x[1] + v1.x[2] * v2.x[2]; -} - - - -inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2) -{ - return Vec3d - ( v1.x[1] * v2.x[2] - v1.x[2] * v2.x[1], - v1.x[2] * v2.x[0] - v1.x[0] * v2.x[2], - v1.x[0] * v2.x[1] - v1.x[1] * v2.x[0]); -} - -inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod) -{ - prod.x[0] = v1.x[1] * v2.x[2] - v1.x[2] * v2.x[1]; - prod.x[1] = v1.x[2] * v2.x[0] - v1.x[0] * v2.x[2]; - prod.x[2] = v1.x[0] * v2.x[1] - v1.x[1] * v2.x[0]; -} - -inline double Determinant (const Vec3d & col1, - const Vec3d & col2, - const Vec3d & col3) -{ - return - col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) + - col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) + - col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]); -} - - -/// -class Box3d -{ -protected: - /// - double minx[3], maxx[3]; - -public: - /// - Box3d () { }; - /// - Box3d ( double aminx, double amaxx, - double aminy, double amaxy, - double aminz, double amaxz ); - /// - Box3d ( const Box3d & b2 ); - /// - Box3d (const Point3d& p1, const Point3d& p2); - /// - Box3d (const Box<3> & b2); - /// - double MinX () const { return minx[0]; } - /// - double MaxX () const { return maxx[0]; } - /// - double MinY () const { return minx[1]; } - /// - double MaxY () const { return maxx[1]; } - /// - double MinZ () const { return minx[2]; } - /// - double MaxZ () const { return maxx[2]; } - - /// - double Mini (int i) const { return minx[i-1]; } - /// - double Maxi (int i) const { return maxx[i-1]; } - - /// - Point3d PMin () const { return Point3d(minx[0], minx[1], minx[2]); } - /// - Point3d PMax () const { return Point3d(maxx[0], maxx[1], maxx[2]); } - - /// - void GetPointNr (int i, Point3d & point) const; - /// increase Box at each side with dist - void Increase (double dist); - /// increase Box by factor rel - void IncreaseRel (double rel); - /// return 1 if closures are intersecting - int Intersect (const Box3d & box2) const - { - if (minx[0] > box2.maxx[0] || maxx[0] < box2.minx[0] || - minx[1] > box2.maxx[1] || maxx[1] < box2.minx[1] || - minx[2] > box2.maxx[2] || maxx[2] < box2.minx[2]) - return 0; - return 1; - } - /// return 1 if point p in closure - int IsIn (const Point3d & p) const - { - if (minx[0] <= p.x[0] && maxx[0] >= p.x[0] && - minx[1] <= p.x[1] && maxx[1] >= p.x[1] && - minx[2] <= p.x[2] && maxx[2] >= p.x[2]) - return 1; - return 0; - } - /// - inline void SetPoint (const Point3d & p) - { - minx[0] = maxx[0] = p.X(); - minx[1] = maxx[1] = p.Y(); - minx[2] = maxx[2] = p.Z(); - } - - /// - inline void AddPoint (const Point3d & p) - { - if (p.x[0] < minx[0]) minx[0] = p.x[0]; - if (p.x[0] > maxx[0]) maxx[0] = p.x[0]; - if (p.x[1] < minx[1]) minx[1] = p.x[1]; - if (p.x[1] > maxx[1]) maxx[1] = p.x[1]; - if (p.x[2] < minx[2]) minx[2] = p.x[2]; - if (p.x[2] > maxx[2]) maxx[2] = p.x[2]; - } - - /// - const Box3d& operator+=(const Box3d& b); - - /// - Point3d MaxCoords() const; - /// - Point3d MinCoords() const; - - /// Make a negative sized box; - // void CreateNegMinMaxBox(); - - /// - Point3d CalcCenter () const { return Point3d(0.5*(minx[0] + maxx[0]), - 0.5*(minx[1] + maxx[1]), - 0.5*(minx[2] + maxx[2])); } - /// - double CalcDiam () const { return sqrt(sqr(maxx[0]-minx[0])+ - sqr(maxx[1]-minx[1])+ - sqr(maxx[2]-minx[2])); } - - /// - void WriteData(ofstream& fout) const; - /// - void ReadData(ifstream& fin); -}; - - -class Box3dSphere : public Box3d -{ -protected: - /// - double diam, inner; - /// - Point3d c; -public: - /// - Box3dSphere () { }; - /// - Box3dSphere ( double aminx, double amaxx, - double aminy, double amaxy, - double aminz, double amaxz); - /// - const Point3d & Center () const { return c; } - - /// - double Diam () const { return diam; } - /// - double Inner () const { return inner; } - /// - void GetSubBox (int i, Box3dSphere & sbox) const; - - // private: - /// - void CalcDiamCenter (); -}; - - - - -/// -class referencetransform -{ - /// - Vec3d ex, ey, ez; - /// - Vec3d exh, eyh, ezh; - /// - Vec3d ex_h, ey_h, ez_h; - /// - Point3d rp; - /// - double h; - -public: - - /// - void Set (const Point3d & p1, const Point3d & p2, - const Point3d & p3, double ah); - - /// - void ToPlain (const Point3d & p, Point3d & pp) const; - /// - void ToPlain (const ARRAY<Point3d> & p, ARRAY<Point3d> & pp) const; - /// - void FromPlain (const Point3d & pp, Point3d & p) const; -}; - - - -#endif diff --git a/Netgen/libsrc/gprim/geomfuncs.cpp b/Netgen/libsrc/gprim/geomfuncs.cpp deleted file mode 100644 index b2ac83824a..0000000000 --- a/Netgen/libsrc/gprim/geomfuncs.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <gprim.hpp> - -namespace netgen -{ - - /* - // template <> -inline void CalcInverse (const Mat<2,2> & m, Mat<2,2> & inv) -{ - double det = m(0,0) * m(1,1) - m(0,1) * m(1,0); - if (det == 0) - { - inv = 0; - return; - } - - double idet = 1.0 / det; - inv(0,0) = idet * m(1,1); - inv(0,1) = -idet * m(0,1); - inv(1,0) = -idet * m(1,0); - inv(1,1) = idet * m(0,0); -} - */ - - - - // template <> -void CalcInverse (const Mat<3,3> & m, Mat<3,3> & inv) -{ - double det = Det (m); - if (det == 0) - { - inv = 0; - return; - } - - double idet = 1.0 / det; - inv(0,0) = idet * (m(1,1) * m(2,2) - m(1,2) * m(2,1)); - inv(1,0) = -idet * (m(1,0) * m(2,2) - m(1,2) * m(2,0)); - inv(2,0) = idet * (m(1,0) * m(2,1) - m(1,1) * m(2,0)); - - inv(0,1) = -idet * (m(0,1) * m(2,2) - m(0,2) * m(2,1)); - inv(1,1) = idet * (m(0,0) * m(2,2) - m(0,2) * m(2,0)); - inv(2,1) = -idet * (m(0,0) * m(2,1) - m(0,1) * m(2,0)); - - inv(0,2) = idet * (m(0,1) * m(1,2) - m(0,2) * m(1,1)); - inv(1,2) = -idet * (m(0,0) * m(1,2) - m(0,2) * m(1,0)); - inv(2,2) = idet * (m(0,0) * m(1,1) - m(0,1) * m(1,0)); -} - -/* -// template <> -void CalcInverse (const Mat<2,3> & m, Mat<3,2> & inv) -{ - Mat<2,2> a = m * Trans (m); - Mat<2,2> ainv; - CalcInverse (a, ainv); - inv = Trans (m) * ainv; -} -*/ - - - -double Det (const Mat<2,2> & m) -{ - return m(0,0) * m(1,1) - m(0,1) * m(1,0); -} - -double Det (const Mat<3,3> & m) -{ - return - m(0,0) * m(1,1) * m(2,2) - + m(1,0) * m(2,1) * m(0,2) - + m(2,0) * m(0,1) * m(1,2) - - m(0,0) * m(2,1) * m(1,2) - - m(1,0) * m(0,1) * m(2,2) - - m(2,0) * m(1,1) * m(0,2); -} - - -void EigenValues (const Mat<3,3> & m, Vec<3> & ev) -{ - const double pi = 3.141592; - double a, b, c, d; - double p, q; - double arg; - - a = -1.; - b = m(0,0) + m(1,1) + m(2,2); - c = -( m(0,0)*m(2,2) + m(1,1)*m(2,2) + m(0,0)*m(1,1) - sqr(m(0,1)) - sqr(m(0,2)) - sqr(m(1,2)) ); - d = Det (m); - p = 3.*a*c - sqr(b); - q = 27.*sqr(a)*d - 9.*a*b*c + 2.*sqr(b)*b; - - - arg = acos((-q/2)/sqrt(-(p*p*p))); - - - ev(0) = (2. * sqrt(-p) * cos(arg/3.) - b) / 3.*a; - ev(1) = (-2. * sqrt(-p) * cos(arg/3.+pi/3) - b) / 3.*a; - ev(2) = (-2. * sqrt(-p) * cos(arg/3.-pi/3)- b) / 3.*a; - - - -} - - -} diff --git a/Netgen/libsrc/gprim/geomfuncs.hpp b/Netgen/libsrc/gprim/geomfuncs.hpp deleted file mode 100644 index b9228c8583..0000000000 --- a/Netgen/libsrc/gprim/geomfuncs.hpp +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef FILE_GEOMFUNCS -#define FILE_GEOMFUNCS - -/* *************************************************************************/ -/* File: geomfuncs.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Jul. 02 */ -/* *************************************************************************/ - - -template <int D> -inline double Abs (const Vec<D> & v) -{ - double sum = 0; - for (int i = 0; i < D; i++) - sum += v(i) * v(i); - return sqrt (sum); -} - - -template <int D> -inline double Abs2 (const Vec<D> & v) -{ - double sum = 0; - for (int i = 0; i < D; i++) - sum += v(i) * v(i); - return sum; -} - - - -template <int D> -inline double Dist (const Point<D> & a, const Point<D> & b) -{ - return Abs (a-b); -} - -template <int D> -inline double Dist2 (const Point<D> & a, const Point<D> & b) -{ - return Abs2 (a-b); -} - - -template <int D> -inline Point<D> Center (const Point<D> & a, const Point<D> & b) -{ - Point<D> res; - for (int i = 0; i < D; i++) - res(i) = 0.5 * (a(i) + b(i)); - return res; -} - -template <int D> -inline Point<D> Center (const Point<D> & a, const Point<D> & b, const Point<D> & c) -{ - Point<D> res; - for (int i = 0; i < D; i++) - res(i) = (1.0/3.0) * (a(i) + b(i) + c(i)); - return res; -} - - - -inline Vec<3> Cross (const Vec<3> & v1, const Vec<3> & v2) -{ - return Vec<3> - ( v1(1) * v2(2) - v1(2) * v2(1), - v1(2) * v2(0) - v1(0) * v2(2), - v1(0) * v2(1) - v1(1) * v2(0) ); -} - - -template <> -inline Vec<2> Vec<2> :: GetNormal () const -{ - return Vec<2> (-x[1], x[0]); -} - -template <> -inline Vec<3> Vec<3> :: GetNormal () const -{ - if (fabs (x[0]) > fabs (x[2])) - return Vec<3> (-x[1], x[0], 0); - else - return Vec<3> (0, x[2], -x[1]); -} - - - -// template <int H, int W> -inline void CalcInverse (const Mat<2,2> & m, Mat<2,2> & inv) -{ - double det = m(0,0) * m(1,1) - m(0,1) * m(1,0); - if (det == 0) - { - inv = 0; - return; - } - - double idet = 1.0 / det; - inv(0,0) = idet * m(1,1); - inv(0,1) = -idet * m(0,1); - inv(1,0) = -idet * m(1,0); - inv(1,1) = idet * m(0,0); -} - -void CalcInverse (const Mat<3,3> & m, Mat<3,3> & inv); - -inline void CalcInverse (const Mat<2,3> & m, Mat<3,2> & inv) -{ - Mat<2,2> a = m * Trans (m); - Mat<2,2> ainv; - CalcInverse (a, ainv); - inv = Trans (m) * ainv; -} - -void CalcInverse (const Mat<3,2> & m, Mat<2,3> & inv); - -inline void CalcInverse (const Mat<3,2> & m, Mat<2,3> & inv) -{ - Mat<2,2> a = Trans (m) * m; - Mat<2,2> ainv; - CalcInverse (a, ainv); - inv = ainv * Trans (m); -} - - -double Det (const Mat<2,2> & m); -double Det (const Mat<3,3> & m); - -// eigenvalues of a symmetric matrix -void EigenValues (const Mat<3,3> & m, Vec<3> & ev); -void EigenValues (const Mat<2,2> & m, Vec<3> & ev); - -#endif diff --git a/Netgen/libsrc/gprim/geomobjects.hpp b/Netgen/libsrc/gprim/geomobjects.hpp deleted file mode 100644 index 2db82cf9e9..0000000000 --- a/Netgen/libsrc/gprim/geomobjects.hpp +++ /dev/null @@ -1,346 +0,0 @@ -#ifndef FILE_OBJECTS -#define FILE_OBJECTS - -/* *************************************************************************/ -/* File: geomobjects.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Jul. 02 */ -/* *************************************************************************/ - - - -template <int D> class Vec; -template <int D> class Point; - - -template <int D> -class Point -{ - -protected: - double x[D]; - -public: - Point () { ; } - Point (double ax) { x[0] = ax; } - Point (double ax, double ay) { x[0] = ax; x[1] = ay; } - Point (double ax, double ay, double az) - { x[0] = ax; x[1] = ay; x[2] = az; } - Point (double ax, double ay, double az, double au) - { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au;} - - Point (const Point<D> & p2) - { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } - - explicit Point (const Vec<D> & v) - { for (int i = 0; i < D; i++) x[i] = v(i); } - - - Point & operator= (const Point<D> & p2) - { - for (int i = 0; i < D; i++) x[i] = p2.x[i]; - return *this; - } - - double & operator() (int i) { return x[i]; } - const double & operator() (int i) const { return x[i]; } - - operator const double* () const { return x; } -}; - - - - - -template <int D> -class Vec -{ - -protected: - double x[D]; - -public: - Vec () { ; } - Vec (double ax) { for (int i = 0; i < D; i++) x[i] = ax; } - Vec (double ax, double ay) { x[0] = ax; x[1] = ay; } - Vec (double ax, double ay, double az) - { x[0] = ax; x[1] = ay; x[2] = az; } - Vec (double ax, double ay, double az, double au) - { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au; } - - Vec (const Vec<D> & p2) - { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } - - explicit Vec (const Point<D> & p) - { for (int i = 0; i < D; i++) x[i] = p(i); } - - Vec (const Vec<D> & p1, const Vec<D> & p2) - { for(int i=0; i<D; i++) x[i] = p2(i)-p1(1); } - - - - Vec & operator= (const Vec<D> & p2) - { - for (int i = 0; i < D; i++) x[i] = p2.x[i]; - return *this; - } - - Vec & operator= (double s) - { - for (int i = 0; i < D; i++) x[i] = s; - return *this; - } - - double & operator() (int i) { return x[i]; } - const double & operator() (int i) const { return x[i]; } - - operator const double* () const { return x; } - - double Length () const - { - double l = 0; - for (int i = 0; i < D; i++) - l += x[i] * x[i]; - return sqrt (l); - } - - double Length2 () const - { - double l = 0; - for (int i = 0; i < D; i++) - l += x[i] * x[i]; - return l; - } - - const Vec<D> & Normalize () - { - double l = Length(); - if (l != 0) - for (int i = 0; i < D; i++) - x[i] /= l; - return *this; - } - - Vec<D> GetNormal () const; -}; - - - - - -template <int H, int W=H> -class Mat -{ - -protected: - double x[H*W]; - -public: - Mat () { ; } - Mat (const Mat & b) - { for (int i = 0; i < H*W; i++) x[i] = b.x[i]; } - - Mat & operator= (double s) - { - for (int i = 0; i < H*W; i++) x[i] = s; - return *this; - } - - Mat & operator= (const Mat & b) - { - for (int i = 0; i < H*W; i++) x[i] = b.x[i]; - return *this; - } - - double & operator() (int i, int j) { return x[i*W+j]; } - const double & operator() (int i, int j) const { return x[i*W+j]; } - double & operator() (int i) { return x[i]; } - const double & operator() (int i) const { return x[i]; } - - Vec<H> Col (int i) const - { - Vec<H> hv; - for (int j = 0; j < H; j++) - hv(j) = x[j*W+i]; - return hv; - } - - Vec<W> Row (int i) const - { - Vec<W> hv; - for (int j = 0; j < W; j++) - hv(j) = x[i*W+j]; - return hv; - } - - void Solve (const Vec<H> & rhs, Vec<W> & sol) const - { - Mat<W,H> inv; - CalcInverse (*this, inv); - sol = inv * rhs; - } -}; - - - - -template <int D> -class Box -{ -protected: - Point<D> pmin, pmax; -public: - Box () { ; } - Box ( const Point<D> & p1, const Point<D> & p2) - { - for (int i = 0; i < D; i++) - { - pmin(i) = min2(p1(i), p2(i)); - pmax(i) = max2(p1(i), p2(i)); - } - } - - const Point<D> & PMin () const { return pmin; } - const Point<D> & PMax () const { return pmax; } - - void Set (const Point<D> & p) - { pmin = pmax = p; } - - void Add (const Point<D> & p) - { - for (int i = 0; i < D; i++) - { - if (p(i) < pmin(i)) pmin(i) = p(i); - else if (p(i) > pmax(i)) pmax(i) = p(i); - } - } - - Point<D> Center () const - { - Point<D> c; - for (int i = 0; i < D; i++) - c(i) = 0.5 * (pmin(i)+pmax(i)); - return c; - } - double Diam () const { return Abs (pmax-pmin); } - - Point<D> GetPointNr (int nr) const - { - Point<D> p; - for (int i = 0; i < D; i++) - { - p(i) = (nr & 1) ? pmax(i) : pmin(i); - nr >>= 1; - } - return p; - } - - - bool Intersect (const Box<D> & box2) const - { - for (int i = 0; i < D; i++) - if (pmin(i) > box2.pmax(i) || - pmax(i) < box2.pmin(i)) return 0; - return 1; - } - - - bool IsIn (const Point<D> & p) const - { - for (int i = 0; i < D; i++) - if (p(i) < pmin(i) || p(i) > pmax(i)) return 0; - return 1; - } - - - void Increase (double dist) - { - for (int i = 0; i < D; i++) - { - pmin(i) -= dist; - pmax(i) += dist; - } - } -}; - - - - -template <int D> -class BoxSphere : public Box<D> -{ -protected: - /// - Point<D> c; - /// - double diam; - /// - double inner; -public: - /// - BoxSphere () { }; - /// - BoxSphere (const Box<D> & box) - : Box<D> (box) - { - CalcDiamCenter(); - }; - - /// - BoxSphere ( Point<D> pmin, Point<D> pmax ) - : Box<D> (pmin, pmax) - { - CalcDiamCenter(); - } - - /// - const Point<D> & Center () const { return c; } - /// - double Diam () const { return diam; } - /// - double Inner () const { return inner; } - - - /// - void GetSubBox (int nr, BoxSphere & sbox) const - { - for (int i = 0; i < D; i++) - { - if (nr & 1) - { - sbox.pmin(i) = c(i); - sbox.pmax(i) = this->pmax(i); - } - else - { - sbox.pmin(i) = this->pmin(i); - sbox.pmax(i) = c(i); - } - sbox.c(i) = 0.5 * (sbox.pmin(i) + sbox.pmax(i)); - nr >>= 1; - } - sbox.diam = 0.5 * diam; - sbox.inner = 0.5 * inner; - } - - - /// - void CalcDiamCenter () - { - c = Box<D>::Center (); - diam = Dist (this->pmin, this->pmax); - - inner = this->pmax(0) - this->pmin(0); - for (int i = 1; i < D; i++) - if (this->pmax(i) - this->pmin(i) < inner) - inner = this->pmax(i) - this->pmin(i); - } - -}; - - - - - - -#endif diff --git a/Netgen/libsrc/gprim/geomobjects2.hpp b/Netgen/libsrc/gprim/geomobjects2.hpp deleted file mode 100644 index 014a38525a..0000000000 --- a/Netgen/libsrc/gprim/geomobjects2.hpp +++ /dev/null @@ -1,366 +0,0 @@ -#ifndef FILE_OBJECTS -#define FILE_OBJECTS - -/* *************************************************************************/ -/* File: geomobjects.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Jul. 02 */ -/* *************************************************************************/ - -template <typename T> -class VecExpr -{ -public: - VecExpr () { ; } - double operator() (int i) const { return static_cast<const T&> (*this) (i); } -}; - - -template <int D> class Vec; -template <int D> class Point; - - -template <int D> -class Point : public VecExpr<Point<D> > -{ - -protected: - double x[D]; - -public: - Point () { ; } - Point (double ax) { x[0] = ax; } - Point (double ax, double ay) { x[0] = ax; x[1] = ay; } - Point (double ax, double ay, double az) - { x[0] = ax; x[1] = ay; x[2] = az; } - Point (double ax, double ay, double az, double au) - { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au;} - - Point (const Point<D> & p2) - { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } - - explicit Point (const Vec<D> & v) - { for (int i = 0; i < D; i++) x[i] = v(i); } - - - template <typename T> - explicit Point (const VecExpr<T> & expr) - { - for (int i = 0; i < D; i++) x[i] = expr(i); - } - - Point & operator= (const Point<D> & p2) - { - for (int i = 0; i < D; i++) x[i] = p2.x[i]; - return *this; - } - - template <typename T> - Point & operator= (const VecExpr<T> & expr) - { - for (int i = 0; i < D; i++) x[i] = expr(i); - return *this; - } - - double & operator() (int i) { return x[i]; } - const double & operator() (int i) const { return x[i]; } - - operator const double* () const { return x; } -}; - - - - - -template <int D> -class Vec : public VecExpr<Vec<D> > -{ - -protected: - double x[D]; - -public: - Vec () { ; } - Vec (double ax) { for (int i = 0; i < D; i++) x[i] = ax; } - Vec (double ax, double ay) { x[0] = ax; x[1] = ay; } - Vec (double ax, double ay, double az) - { x[0] = ax; x[1] = ay; x[2] = az; } - Vec (double ax, double ay, double az, double au) - { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au; } - - Vec (const Vec<D> & p2) - { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } - - explicit Vec (const Point<D> & p) - { for (int i = 0; i < D; i++) x[i] = p(i); } - - template <typename T> - explicit Vec (const VecExpr<T> & expr) - { - for (int i = 0; i < D; i++) x[i] = expr(i); - } - - - Vec & operator= (const Vec<D> & p2) - { - for (int i = 0; i < D; i++) x[i] = p2.x[i]; - return *this; - } - - template <typename T> - Vec & operator= (const VecExpr<T> & expr) - { - for (int i = 0; i < D; i++) x[i] = expr(i); - return *this; - } - - Vec & operator= (double s) - { - for (int i = 0; i < D; i++) x[i] = s; - return *this; - } - - double & operator() (int i) { return x[i]; } - const double & operator() (int i) const { return x[i]; } - - operator const double* () const { return x; } - - double Length () const - { - double l = 0; - for (int i = 0; i < D; i++) - l += x[i] * x[i]; - return sqrt (l); - } - - double Length2 () const - { - double l = 0; - for (int i = 0; i < D; i++) - l += x[i] * x[i]; - return l; - } - - const Vec<D> & Normalize () - { - double l = Length(); - if (l != 0) - for (int i = 0; i < D; i++) - x[i] /= l; - return *this; - } - - Vec<D> GetNormal () const; -}; - - - - - -template <int H, int W=H> -class Mat -{ - -protected: - double x[H*W]; - -public: - Mat () { ; } - Mat (const Mat & b) - { for (int i = 0; i < H*W; i++) x[i] = b.x[i]; } - - Mat & operator= (double s) - { - for (int i = 0; i < H*W; i++) x[i] = s; - return *this; - } - - Mat & operator= (const Mat & b) - { - for (int i = 0; i < H*W; i++) x[i] = b.x[i]; - return *this; - } - - double & operator() (int i, int j) { return x[i*W+j]; } - const double & operator() (int i, int j) const { return x[i*W+j]; } - - Vec<H> Col (int i) const - { - Vec<H> hv; - for (int j = 0; j < H; j++) - hv(j) = x[j*W+i]; - return hv; - } - - Vec<W> Row (int i) const - { - Vec<W> hv; - for (int j = 0; j < W; j++) - hv(j) = x[i*W+j]; - return hv; - } - - void Solve (const Vec<H> & rhs, Vec<W> & sol) const - { - Mat<W,H> inv; - CalcInverse (*this, inv); - sol = inv * rhs; - } -}; - - - - -template <int D> -class Box -{ -protected: - Point<D> pmin, pmax; -public: - Box () { ; } - Box ( const Point<D> & p1, const Point<D> & p2) - { - for (int i = 0; i < D; i++) - { - pmin(i) = min2(p1(i), p2(i)); - pmax(i) = max2(p1(i), p2(i)); - } - } - - const Point<D> & PMin () const { return pmin; } - const Point<D> & PMax () const { return pmax; } - - void Set (const Point<D> & p) - { pmin = pmax = p; } - - void Add (const Point<D> & p) - { - for (int i = 0; i < D; i++) - { - if (p(i) < pmin(i)) pmin(i) = p(i); - else if (p(i) > pmax(i)) pmax(i) = p(i); - } - } - - Point<D> Center () const - { - Point<D> c; - for (int i = 0; i < D; i++) - c(i) = 0.5 * (pmin(i)+pmax(i)); - return c; - } - double Diam () const { return Abs (pmax-pmin); } - - Point<D> GetPointNr (int nr) const - { - Point<D> p; - for (int i = 0; i < D; i++) - { - p(i) = (nr & 1) ? pmax(i) : pmin(i); - nr >>= 1; - } - return p; - } - - - bool Intersect (const Box<D> & box2) const - { - for (int i = 0; i < D; i++) - if (pmin(i) > box2.pmax(i) || - pmax(i) < box2.pmin(i)) return 0; - return 1; - } - - - bool IsIn (const Point<D> & p) const - { - for (int i = 0; i < D; i++) - if (p(i) < pmin(i) || p(i) > pmax(i)) return 0; - return 1; - } - - - void Increase (double dist) - { - for (int i = 0; i < D; i++) - { - pmin(i) -= dist; - pmax(i) += dist; - } - } -}; - - - - -template <int D> -class BoxSphere : public Box<D> -{ -protected: - /// - Point<D> c; - /// - double diam; - /// - double inner; -public: - /// - BoxSphere () { }; - /// - BoxSphere ( Point<D> pmin, Point<D> pmax ) - : Box<D> (pmin, pmax) - { - CalcDiamCenter(); - } - - /// - const Point<D> & Center () const { return c; } - /// - double Diam () const { return diam; } - /// - double Inner () const { return inner; } - - - /// - void GetSubBox (int nr, BoxSphere & sbox) const - { - for (int i = 0; i < D; i++) - { - if (nr & 1) - { - sbox.pmin(i) = c(i); - sbox.pmax(i) = this->pmax(i); - } - else - { - sbox.pmin(i) = this->pmin(i); - sbox.pmax(i) = c(i); - } - sbox.c(i) = 0.5 * (sbox.pmin(i) + sbox.pmax(i)); - nr >>= 1; - } - sbox.diam = 0.5 * diam; - sbox.inner = 0.5 * inner; - } - - - /// - void CalcDiamCenter () - { - c = Box<D>::Center (); - diam = Dist (this->pmin, this->pmax); - - inner = this->pmax(0) - this->pmin(0); - for (int i = 1; i < D; i++) - if (this->pmax(i) - this->pmin(i) < inner) - inner = this->pmax(i) - this->pmin(i); - } - -}; - - - - - - -#endif diff --git a/Netgen/libsrc/gprim/geomops.hpp b/Netgen/libsrc/gprim/geomops.hpp deleted file mode 100644 index 755f35a878..0000000000 --- a/Netgen/libsrc/gprim/geomops.hpp +++ /dev/null @@ -1,391 +0,0 @@ -#ifndef FILE_GEOMOPS -#define FILE_GEOMOPS - -/* *************************************************************************/ -/* File: geomops.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Jul. 02 */ -/* *************************************************************************/ - - -/* - -Point - Vector operations - - */ - - -template <int D> -inline Vec<D> operator+ (const Vec<D> & a, const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) + b(i); - return res; -} - - - -template <int D> -inline Point<D> operator+ (const Point<D> & a, const Vec<D> & b) -{ - Point<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) + b(i); - return res; -} - - - -template <int D> -inline Vec<D> operator- (const Point<D> & a, const Point<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) - b(i); - return res; -} - -template <int D> -inline Point<D> operator- (const Point<D> & a, const Vec<D> & b) -{ - Point<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) - b(i); - return res; -} - -template <int D> -inline Vec<D> operator- (const Vec<D> & a, const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) - b(i); - return res; -} - - - -template <int D> -inline Vec<D> operator* (double s, const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = s * b(i); - return res; -} - - -template <int D> -inline double operator* (const Vec<D> & a, const Vec<D> & b) -{ - double sum = 0; - for (int i = 0; i < D; i++) - sum += a(i) * b(i); - return sum; -} - - - -template <int D> -inline Vec<D> operator- (const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = -b(i); - return res; -} - - -template <int D> -inline Point<D> & operator+= (Point<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) += b(i); - return a; -} - -template <int D> -inline Vec<D> & operator+= (Vec<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) += b(i); - return a; -} - - -template <int D> -inline Point<D> & operator-= (Point<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) -= b(i); - return a; -} - -template <int D> -inline Vec<D> & operator-= (Vec<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) -= b(i); - return a; -} - - - -template <int D> -inline Vec<D> & operator*= (Vec<D> & a, double s) -{ - for (int i = 0; i < D; i++) - a(i) *= s; - return a; -} - - -template <int D> -inline Vec<D> & operator/= (Vec<D> & a, double s) -{ - for (int i = 0; i < D; i++) - a(i) /= s; - return a; -} - - - - -// Matrix - Vector operations - -/* -template <int H, int W> -inline Vec<H> operator* (const Mat<H,W> & m, const Vec<W> & v) -{ - Vec<H> res; - for (int i = 0; i < H; i++) - { - res(i) = 0; - for (int j = 0; j < W; j++) - res(i) += m(i,j) * v(j); - } - return res; -} -*/ - -// thanks to VC60 partial template specialization features !!! - -inline Vec<2> operator* (const Mat<2,2> & m, const Vec<2> & v) -{ - Vec<2> res; - for (int i = 0; i < 2; i++) - { - res(i) = 0; - for (int j = 0; j < 2; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - -inline Vec<2> operator* (const Mat<2,3> & m, const Vec<3> & v) -{ - Vec<2> res; - for (int i = 0; i < 2; i++) - { - res(i) = 0; - for (int j = 0; j < 3; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - - -inline Vec<3> operator* (const Mat<3,2> & m, const Vec<2> & v) -{ - Vec<3> res; - for (int i = 0; i < 3; i++) - { - res(i) = 0; - for (int j = 0; j < 2; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - - -inline Vec<3> operator* (const Mat<3,3> & m, const Vec<3> & v) -{ - Vec<3> res; - for (int i = 0; i < 3; i++) - { - res(i) = 0; - for (int j = 0; j < 3; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - - - - - - - -/* -template <int H1, int W1, int H2, int W2> -inline Mat<H1,W2> operator* (const Mat<H1,W1> & a, const Mat<H2,W2> & b) -{ - Mat<H1,W2> m; - for (int i = 0; i < H1; i++) - for (int j = 0; j < W2; j++) - { - double sum = 0; - for (int k = 0; k < W1; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} -*/ - -inline Mat<2,2> operator* (const Mat<2,2> & a, const Mat<2,2> & b) -{ - Mat<2,2> m; - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - { - double sum = 0; - for (int k = 0; k < 2; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - -inline Mat<2,2> operator* (const Mat<2,3> & a, const Mat<3,2> & b) -{ - Mat<2,2> m; - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - { - double sum = 0; - for (int k = 0; k < 3; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - - -inline Mat<3,2> operator* (const Mat<3,2> & a, const Mat<2,2> & b) -{ - Mat<3,2> m; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - { - double sum = 0; - for (int k = 0; k < 2; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - - - -inline Mat<2,3> operator* (const Mat<2,2> & a, const Mat<2,3> & b) -{ - Mat<2,3> m; - for (int i = 0; i < 2; i++) - for (int j = 0; j < 3; j++) - { - double sum = 0; - for (int k = 0; k < 2; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - - -inline Mat<3,3> operator* (const Mat<3,3> & a, const Mat<3,3> & b) -{ - Mat<3,3> m; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - { - double sum = 0; - for (int k = 0; k < 3; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - - - - - - - - -template <int H, int W> -inline Mat<W,H> Trans (const Mat<H,W> & m) -{ - Mat<W,H> res; - for (int i = 0; i < H; i++) - for (int j = 0; j < W; j++) - res(j,i) = m(i,j); - return res; -} - - - - - - - - - - - -template <int D> -inline ostream & operator<< (ostream & ost, const Vec<D> & a) -{ - ost << "("; - for (int i = 0; i < D-1; i++) - ost << a(i) << ", "; - ost << a(D-1) << ")"; - return ost; -} - -template <int D> -inline ostream & operator<< (ostream & ost, const Point<D> & a) -{ - ost << "("; - for (int i = 0; i < D-1; i++) - ost << a(i) << ", "; - ost << a(D-1) << ")"; - return ost; -} - -template <int D> -inline ostream & operator<< (ostream & ost, const Box<D> & b) -{ - ost << b.PMin() << " - " << b.PMax(); - return ost; -} - -template <int H, int W> -inline ostream & operator<< (ostream & ost, const Mat<H,W> & m) -{ - ost << "("; - for (int i = 0; i < H; i++) - { - for (int j = 0; j < W; j++) - ost << m(i,j) << " "; - ost << endl; - } - return ost; -} - - - - -#endif diff --git a/Netgen/libsrc/gprim/geomops2.hpp b/Netgen/libsrc/gprim/geomops2.hpp deleted file mode 100644 index c615da14ec..0000000000 --- a/Netgen/libsrc/gprim/geomops2.hpp +++ /dev/null @@ -1,428 +0,0 @@ -#ifndef FILE_GEOMOPS -#define FILE_GEOMOPS - -/* *************************************************************************/ -/* File: geomops.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Jul. 02 */ -/* *************************************************************************/ - - -/* - -Point - Vector operations - - */ - - - - -template <class TA, class TB> -class SumExpr : public VecExpr<SumExpr<TA, TB> > -{ - const TA a; - const TB b; -public: - SumExpr (const TA aa, const TB ab) : a(aa), b(ab) { ; } - double operator() (int i) const { return a(i) + b(i); } -}; - -template <typename TA, typename TB> -inline SumExpr<TA,TB> -operator+ (const VecExpr<TA> & a, const VecExpr<TB> & b) -{ - return SumExpr<TA,TB> (static_cast <const TA&> (a), static_cast <const TB&> (b)); -} - -/* -template <int D1, int D2> -inline SumExpr<const Vec<D1>&, const Vec<D2>&> -operator+ (const Vec<D1> & a, const Vec<D2> & b) -{ - return SumExpr<const Vec<D1>&, const Vec<D2>&> (a, b); -} -*/ - - - - - -/* -template <int D> -inline Vec<D> operator+ (const Vec<D> & a, const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) + b(i); - return res; -} -*/ - -template <int D> -inline Point<D> operator+ (const Point<D> & a, const Vec<D> & b) -{ - Point<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) + b(i); - return res; -} - - -template <int D> -inline Vec<D> operator- (const Point<D> & a, const Point<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) - b(i); - return res; -} - -template <int D> -inline Point<D> operator- (const Point<D> & a, const Vec<D> & b) -{ - Point<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) - b(i); - return res; -} - -template <int D> -inline Vec<D> operator- (const Vec<D> & a, const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = a(i) - b(i); - return res; -} - - -template <int D> -inline Vec<D> operator* (double s, const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = s * b(i); - return res; -} - - -template <int D> -inline double operator* (const Vec<D> & a, const Vec<D> & b) -{ - double sum = 0; - for (int i = 0; i < D; i++) - sum += a(i) * b(i); - return sum; -} - - - -template <int D> -inline Vec<D> operator- (const Vec<D> & b) -{ - Vec<D> res; - for (int i = 0; i < D; i++) - res(i) = -b(i); - return res; -} - - -template <int D> -inline Point<D> & operator+= (Point<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) += b(i); - return a; -} - - -template <int D, typename T> -inline Point<D> & operator+= (Point<D> & a, const VecExpr<T> & b) -{ - for (int i = 0; i < D; i++) - a(i) += b(i); - return a; -} - -template <int D> -inline Vec<D> & operator+= (Vec<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) += b(i); - return a; -} - - - - - -template <int D> -inline Point<D> & operator-= (Point<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) -= b(i); - return a; -} - -template <int D, typename T> -inline Point<D> & operator-= (Point<D> & a, const VecExpr<T> & b) -{ - for (int i = 0; i < D; i++) - a(i) -= b(i); - return a; -} - - - - - -template <int D> -inline Vec<D> & operator-= (Vec<D> & a, const Vec<D> & b) -{ - for (int i = 0; i < D; i++) - a(i) -= b(i); - return a; -} - - - -template <int D> -inline Vec<D> & operator*= (Vec<D> & a, double s) -{ - for (int i = 0; i < D; i++) - a(i) *= s; - return a; -} - - -template <int D> -inline Vec<D> & operator/= (Vec<D> & a, double s) -{ - for (int i = 0; i < D; i++) - a(i) /= s; - return a; -} - - - - -// Matrix - Vector operations - -/* -template <int H, int W> -inline Vec<H> operator* (const Mat<H,W> & m, const Vec<W> & v) -{ - Vec<H> res; - for (int i = 0; i < H; i++) - { - res(i) = 0; - for (int j = 0; j < W; j++) - res(i) += m(i,j) * v(j); - } - return res; -} -*/ - -// thanks to VC60 partial template specialization features !!! - -inline Vec<2> operator* (const Mat<2,2> & m, const Vec<2> & v) -{ - Vec<2> res; - for (int i = 0; i < 2; i++) - { - res(i) = 0; - for (int j = 0; j < 2; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - -inline Vec<2> operator* (const Mat<2,3> & m, const Vec<3> & v) -{ - Vec<2> res; - for (int i = 0; i < 2; i++) - { - res(i) = 0; - for (int j = 0; j < 3; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - - -inline Vec<3> operator* (const Mat<3,2> & m, const Vec<2> & v) -{ - Vec<3> res; - for (int i = 0; i < 3; i++) - { - res(i) = 0; - for (int j = 0; j < 2; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - - -inline Vec<3> operator* (const Mat<3,3> & m, const Vec<3> & v) -{ - Vec<3> res; - for (int i = 0; i < 3; i++) - { - res(i) = 0; - for (int j = 0; j < 3; j++) - res(i) += m(i,j) * v(j); - } - return res; -} - - - - - - - -/* -template <int H1, int W1, int H2, int W2> -inline Mat<H1,W2> operator* (const Mat<H1,W1> & a, const Mat<H2,W2> & b) -{ - Mat<H1,W2> m; - for (int i = 0; i < H1; i++) - for (int j = 0; j < W2; j++) - { - double sum = 0; - for (int k = 0; k < W1; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} -*/ - -inline Mat<2,2> operator* (const Mat<2,2> & a, const Mat<2,2> & b) -{ - Mat<2,2> m; - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - { - double sum = 0; - for (int k = 0; k < 2; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - -inline Mat<2,2> operator* (const Mat<2,3> & a, const Mat<3,2> & b) -{ - Mat<2,2> m; - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - { - double sum = 0; - for (int k = 0; k < 3; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - - -inline Mat<3,2> operator* (const Mat<3,2> & a, const Mat<2,2> & b) -{ - Mat<3,2> m; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - { - double sum = 0; - for (int k = 0; k < 2; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - -inline Mat<3,3> operator* (const Mat<3,3> & a, const Mat<3,3> & b) -{ - Mat<3,3> m; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - { - double sum = 0; - for (int k = 0; k < 3; k++) - sum += a(i,k) * b(k, j); - m(i,j) = sum; - } - return m; -} - - - - - - - - -template <int H, int W> -inline Mat<W,H> Trans (const Mat<H,W> & m) -{ - Mat<W,H> res; - for (int i = 0; i < H; i++) - for (int j = 0; j < W; j++) - res(j,i) = m(i,j); - return res; -} - - - - - - - - - - - -template <int D> -inline ostream & operator<< (ostream & ost, const Vec<D> & a) -{ - ost << "("; - for (int i = 0; i < D-1; i++) - ost << a(i) << ", "; - ost << a(D-1) << ")"; - return ost; -} - -template <int D> -inline ostream & operator<< (ostream & ost, const Point<D> & a) -{ - ost << "("; - for (int i = 0; i < D-1; i++) - ost << a(i) << ", "; - ost << a(D-1) << ")"; - return ost; -} - -template <int D> -inline ostream & operator<< (ostream & ost, const Box<D> & b) -{ - ost << b.PMin() << " - " << b.PMax(); - return ost; -} - -template <int H, int W> -inline ostream & operator<< (ostream & ost, const Mat<H,W> & m) -{ - ost << "("; - for (int i = 0; i < H; i++) - { - for (int j = 0; j < W; j++) - ost << m(i,j) << " "; - ost << endl; - } - return ost; -} - - - - -#endif diff --git a/Netgen/libsrc/gprim/geomtest3d.cpp b/Netgen/libsrc/gprim/geomtest3d.cpp deleted file mode 100644 index 14d1d58bd1..0000000000 --- a/Netgen/libsrc/gprim/geomtest3d.cpp +++ /dev/null @@ -1,1223 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <gprim.hpp> - -namespace netgen -{ -int -IntersectTriangleLine (const Point3d ** tri, const Point3d ** line) -{ - Vec3d vl(*line[0], *line[1]); - Vec3d vt1(*tri[0], *tri[1]); - Vec3d vt2(*tri[0], *tri[2]); - Vec3d vrs(*tri[0], *line[0]); - - static DenseMatrix a(3), ainv(3); - static Vector rs(3), lami(3); - int i; - - /* - (*testout) << "Tri-Line inters: " << endl - << "tri = " << *tri[0] << ", " << *tri[1] << ", " << *tri[2] << endl - << "line = " << *line[0] << ", " << *line[1] << endl; - */ - for (i = 1; i <= 3; i++) - { - a.Elem(i, 1) = -vl.X(i); - a.Elem(i, 2) = vt1.X(i); - a.Elem(i, 3) = vt2.X(i); - rs.Elem(i) = vrs.X(i); - } - - double det = a.Det(); - - double arel = vl.Length() * vt1.Length() * vt2.Length(); - /* - double amax = 0; - for (i = 1; i <= 9; i++) - if (fabs (a.Get(i)) > amax) - amax = fabs(a.Get(i)); - */ - // new !!!! - if (fabs (det) <= 1e-10 * arel) - { -#ifdef DEVELOP - // line parallel to triangle ! - // cout << "ERROR: IntersectTriangleLine degenerated" << endl; - // (*testout) << "WARNING: IntersectTriangleLine degenerated\n"; - /* - (*testout) << "lin-tri intersection: " << endl - << "line = " << *line[0] << " - " << *line[1] << endl - << "tri = " << *tri[0] << " - " << *tri[1] << " - " << *tri[2] << endl - << "lami = " << lami << endl - << "pc = " << ( *line[0] + lami.Get(1) * vl ) << endl - << " = " << ( *tri[0] + lami.Get(2) * vt1 + lami.Get(3) * vt2) << endl - << " a = " << a << endl - << " ainv = " << ainv << endl - << " det(a) = " << det << endl - << " rs = " << rs << endl; - */ -#endif - return 0; - } - - CalcInverse (a, ainv); - ainv.Mult (rs, lami); - - // (*testout) << "lami = " << lami << endl; - - double eps = 1e-6; - if ( - (lami.Get(1) >= -eps && lami.Get(1) <= 1+eps && - lami.Get(2) >= -eps && lami.Get(3) >= -eps && - lami.Get(2) + lami.Get(3) <= 1+eps) && ! - (lami.Get(1) >= eps && lami.Get(1) <= 1-eps && - lami.Get(2) >= eps && lami.Get(3) >= eps && - lami.Get(2) + lami.Get(3) <= 1-eps) ) - - - { -#ifdef DEVELOP - // cout << "WARNING: IntersectTriangleLine degenerated" << endl; - (*testout) << "WARNING: IntersectTriangleLine numerical inexact" << endl; - - (*testout) << "lin-tri intersection: " << endl - << "line = " << *line[0] << " - " << *line[1] << endl - << "tri = " << *tri[0] << " - " << *tri[1] << " - " << *tri[2] << endl - << "lami = " << lami << endl - << "pc = " << ( *line[0] + lami.Get(1) * vl ) << endl - << " = " << ( *tri[0] + lami.Get(2) * vt1 + lami.Get(3) * vt2) << endl - << " a = " << a << endl - << " ainv = " << ainv << endl - << " det(a) = " << det << endl - << " rs = " << rs << endl; -#endif - } - - - if (lami.Get(1) >= 0 && lami.Get(1) <= 1 && - lami.Get(2) >= 0 && lami.Get(3) >= 0 && lami.Get(2) + lami.Get(3) <= 1) - { - - return 1; - } - - return 0; -} - - - - - -int IntersectTetTriangle (const Point3d ** tet, const Point3d ** tri, - const int * tetpi, const int * tripi) -{ - int i, j; - double diam = Dist (*tri[0], *tri[1]); - double epsrel = 1e-8; - double eps = diam * epsrel; - -#ifdef MARK - MARK (inttettri1); -#endif - - double eps2 = eps * eps; - int loctripi[3], cnt = 0; - int loctetpi[4]; - - int tetp1 = -1, tetp2 = -1; - int trip1 = -1, trip2 = -1; - int tetp3, tetp4, trip3; - - /* - for (i = 0; i < 4; i++) - loctetpi[i] = -1; - */ - - - if (!tetpi) - { - for (i = 0; i <= 2; i++) - { - // loctripi[i] = -1; - for (j = 0; j <= 3; j++) - { - if (Dist2 (*tet[j], *tri[i]) < eps2) - { - // loctripi[i] = j; - // loctetpi[j] = i; - cnt++; - tetp2 = tetp1; - tetp1 = j; - trip2 = trip1; - trip1 = i; - break; - } - } - } - } - else - { - for (i = 0; i <= 2; i++) - { - // loctripi[i] = -1; - for (j = 0; j <= 3; j++) - { - if (tetpi[j] == tripi[i]) - { - // loctripi[i] = j; - // loctetpi[j] = i; - cnt++; - tetp2 = tetp1; - tetp1 = j; - trip2 = trip1; - trip1 = i; - break; - } - } - } - } - - // (*testout) << "cnt = " << cnt << endl; - -#ifdef MARK - MARK (inttettri2); -#endif - - - // (*testout) << "tet-trig inters, cnt = " << cnt << endl; - - // cnt .. number of common points - switch (cnt) - { - case 0: - { -#ifdef MARK - MARK (inttettric0); -#endif - - Vec3d no, n; - int inpi[3]; - - // check, if some trigpoint is in tet: - - for (j = 0; j < 3; j++) - inpi[j] = 1; - - for (i = 1; i <= 4; i++) - { - int pi1 = i % 4; - int pi2 = (i+1) % 4; - int pi3 = (i+2) % 4; - int pi4 = (i+3) % 4; - - Vec3d v1 (*tet[pi1], *tet[pi2]); - Vec3d v2 (*tet[pi1], *tet[pi3]); - Vec3d v3 (*tet[pi1], *tet[pi4]); - Cross (v1, v2, n); - - // n /= n.Length(); - double nl = n.Length(); - - if (v3 * n > 0) - n *= -1; - - int outeri = 1; - for (j = 0; j < 3; j++) - { - Vec3d v(*tet[pi1], *tri[j]); - if ( v * n < eps * nl) - outeri = 0; - else - inpi[j] = 0; - } - - if (outeri) - return 0; - } - - if (inpi[0] || inpi[1] || inpi[2]) - { - return 1; - } - - - // check, if some tet edge intersects triangle: - const Point3d * line[2], *tetf[3]; - for (i = 0; i <= 2; i++) - for (j = i+1; j <= 3; j++) - { - line[0] = tet[i]; - line[1] = tet[j]; - - if (IntersectTriangleLine (tri, &line[0])) - return 1; - } - - // check, if triangle line intersects tet face: - for (i = 0; i <= 3; i++) - { - for (j = 0; j <= 2; j++) - tetf[j] = tet[(i+j) % 4]; - - for (j = 0; j <= 2; j++) - { - line[0] = tri[j]; - line[1] = tri[(j+1) % 3]; - - if (IntersectTriangleLine (&tetf[0], &line[0])) - return 1; - } - } - - - return 0; -//GH break; - } - case 1: - { -#ifdef MARK - MARK (inttettric1); -#endif - - trip2 = 0; - while (trip2 == trip1) - trip2++; - trip3 = 3 - trip1 - trip2; - - tetp2 = 0; - while (tetp2 == tetp1) - tetp2++; - tetp3 = 0; - while (tetp3 == tetp1 || tetp3 == tetp2) - tetp3++; - tetp4 = 6 - tetp1 - tetp2 - tetp3; - - Vec3d vtri1 = *tri[trip2] - *tri[trip1]; - Vec3d vtri2 = *tri[trip3] - *tri[trip1]; - Vec3d ntri; - Cross (vtri1, vtri2, ntri); - - // tri durch tet ? - // fehlt noch - - - // test 3 tet-faces: - for (i = 1; i <= 3; i++) - { - Vec3d vtet1, vtet2; - switch (i) - { - case 1: - { - vtet1 = *tet[tetp2] - *tet[tetp1]; - vtet2 = *tet[tetp3] - *tet[tetp1]; - break; - } - case 2: - { - vtet1 = *tet[tetp3] - *tet[tetp1]; - vtet2 = *tet[tetp4] - *tet[tetp1]; - break; - } - case 3: - { - vtet1 = *tet[tetp4] - *tet[tetp1]; - vtet2 = *tet[tetp2] - *tet[tetp1]; - break; - } - } - - Vec3d ntet; - Cross (vtet1, vtet2, ntet); - - Vec3d crline = Cross (ntri, ntet); - - double lcrline = crline.Length(); - - if (lcrline < eps * eps * eps * eps) // new change ! - continue; - - if (vtri1 * crline + vtri2 * crline < 0) - crline *= -1; - - crline /= lcrline; - - double lam1, lam2, lam3, lam4; - LocalCoordinates (vtri1, vtri2, crline, lam1, lam2); - LocalCoordinates (vtet1, vtet2, crline, lam3, lam4); - - if (lam1 > -epsrel && lam2 > -epsrel && - lam3 > -epsrel && lam4 > -epsrel) - { - - /* - (*testout) << "lcrline = " << lcrline - << " eps = " << eps << " diam = " << diam << endl; - - (*testout) << "hit, cnt == 1 " - << "lam1,2,3,4 = " << lam1 << ", " - << lam2 << ", " << lam3 << ", " << lam4 - << "\n"; - */ - return 1; - } - } - return 0; -//GH break; - } - case 2: - { -#ifdef MARK - MARK (inttettric2); -#endif - - // common edge - tetp3 = 0; - while (tetp3 == tetp1 || tetp3 == tetp2) - tetp3++; - tetp4 = 6 - tetp1 - tetp2 - tetp3; - trip3 = 3 - trip1 - trip2; - - // (*testout) << "trip1,2,3 = " << trip1 << ", " << trip2 << ", " << trip3 << endl; - // (*testout) << "tetp1,2,3,4 = " << tetp1 << ", " << tetp2 - // << ", " << tetp3 << ", " << tetp4 << endl; - - Vec3d vtri = *tri[trip3] - *tri[trip1]; - Vec3d vtet1 = *tet[tetp3] - *tri[trip1]; - Vec3d vtet2 = *tet[tetp4] - *tri[trip1]; - - Vec3d n = *tri[trip2] - *tri[trip1]; - n /= n.Length(); - - vtet1 -= (n * vtet1) * n; - vtet2 -= (n * vtet2) * n; - - - double lam1, lam2; - LocalCoordinates (vtet1, vtet2, vtri, lam1, lam2); - - if (lam1 < -epsrel || lam2 < -epsrel) - return 0; - else - { - /* - - (*testout) << "vtet1 = " << vtet1 << endl; - (*testout) << "vtet2 = " << vtet2 << endl; - (*testout) << "vtri = " << vtri << endl; - (*testout) << "lam1 = " << lam1 << " lam2 = " << lam2 << endl; - (*testout) << (lam1 * (vtet1 * vtet1) + lam2 * (vtet1 * vtet2)) - << " = " << (vtet1 * vtri) << endl; - (*testout) << (lam1 * (vtet1 * vtet2) + lam2 * (vtet2 * vtet2)) - << " = " << (vtet2 * vtri) << endl; - - (*testout) << "tet = "; - for (j = 0; j < 4; j++) - (*testout) << (*tet[j]) << " "; - (*testout) << endl; - (*testout) << "tri = "; - for (j = 0; j < 3; j++) - (*testout) << (*tri[j]) << " "; - (*testout) << endl; - - (*testout) << "hit, cnt == 2" << endl; - */ - - return 1; - } - - break; - } - case 3: - { -#ifdef MARK - MARK (inttettric3); -#endif - - // common face - return 0; - } - } - - (*testout) << "hit, cnt = " << cnt << endl; - return 1; -} - - - - - -int IntersectTetTriangleRef (const Point3d ** tri, const int * tripi) -{ - int i, j; - double eps = 1e-8; - double eps2 = eps * eps; - - static Point3d rtetp1(0, 0, 0); - static Point3d rtetp2(1, 0, 0); - static Point3d rtetp3(0, 1, 0); - static Point3d rtetp4(0, 0, 1); - - static const Point3d * tet[] = { &rtetp1, &rtetp2, &rtetp3, &rtetp4 }; - static int tetpi[] = { 1, 2, 3, 4 }; - - - // return IntersectTetTriangle (tet, tri, tetpi, tripi); - - - int cnt = 0; - - int tetp1 = -1, tetp2 = -1; - int trip1 = -1, trip2 = -1; - int tetp3, tetp4, trip3; - - - if (!tetpi) - { - for (i = 0; i <= 2; i++) - { - for (j = 0; j <= 3; j++) - { - if (Dist2 (*tet[j], *tri[i]) < eps2) - { - cnt++; - tetp2 = tetp1; - tetp1 = j; - trip2 = trip1; - trip1 = i; - break; - } - } - } - } - else - { - for (i = 0; i <= 2; i++) - { - for (j = 0; j <= 3; j++) - { - if (tetpi[j] == tripi[i]) - { - cnt++; - tetp2 = tetp1; - tetp1 = j; - trip2 = trip1; - trip1 = i; - break; - } - } - } - } - - // (*testout) << "cnt = " << cnt << endl; - -#ifdef MARK - MARK (inttettriref2); -#endif - - - switch (cnt) - { - case 0: - { -#ifdef MARK - MARK (inttettric0ref); -#endif - - Vec3d no, n; - // int inpi[3]; - int pside[3][4]; - - for (j = 0; j < 3; j++) - { - pside[j][0] = (*tri[j]).X() > -eps; - pside[j][1] = (*tri[j]).Y() > -eps; - pside[j][2] = (*tri[j]).Z() > -eps; - pside[j][3] = (*tri[j]).X() + (*tri[j]).Y() + (*tri[j]).Z() < 1+eps; - } - - - for (j = 0; j < 4; j++) - { - if (!pside[0][j] && !pside[1][j] && !pside[2][j]) - return 0; - } - - for (j = 0; j < 3; j++) - { - if (pside[j][0] && pside[j][1] && pside[j][2] && pside[j][3]) - return 1; - } - - - const Point3d * line[2], *tetf[3]; - for (i = 0; i <= 2; i++) - for (j = i+1; j <= 3; j++) - { - line[0] = tet[i]; - line[1] = tet[j]; - - if (IntersectTriangleLine (tri, &line[0])) - return 1; - } - - for (i = 0; i <= 3; i++) - { - for (j = 0; j <= 2; j++) - tetf[j] = tet[(i+j) % 4]; - - for (j = 0; j <= 2; j++) - { - line[0] = tri[j]; - line[1] = tri[(j+1) % 3]; - - if (IntersectTriangleLine (&tetf[0], &line[0])) - return 1; - } - } - - - return 0; - break; - } - case 1: - { -#ifdef MARK - MARK (inttettric1ref); -#endif - - trip2 = 0; - if (trip2 == trip1) - trip2++; - trip3 = 3 - trip1 - trip2; - - tetp2 = 0; - while (tetp2 == tetp1) - tetp2++; - tetp3 = 0; - while (tetp3 == tetp1 || tetp3 == tetp2) - tetp3++; - tetp4 = 6 - tetp1 - tetp2 - tetp3; - - Vec3d vtri1 = *tri[trip2] - *tri[trip1]; - Vec3d vtri2 = *tri[trip3] - *tri[trip1]; - Vec3d ntri; - Cross (vtri1, vtri2, ntri); - - // tri durch tet ? - - /* - Vec3d vtet1(*tet[tetp1], *tet[tetp2]); - Vec3d vtet2(*tet[tetp1], *tet[tetp3]); - Vec3d vtet3(*tet[tetp1], *tet[tetp4]); - Vec3d sol; - - SolveLinearSystem (vtet1, vtet2, vtet3, vtri1, sol); - if (sol.X() > 0 && sol.Y() > 0 && sol.Z() > 0) - return 1; - - SolveLinearSystem (vtet1, vtet2, vtet3, vtri2, sol); - if (sol.X() > 0 && sol.Y() > 0 && sol.Z() > 0) - return 1; - */ - - // test 3 tet-faces: - for (i = 1; i <= 3; i++) - { - Vec3d vtet1, vtet2; - switch (i) - { - case 1: - { - vtet1 = *tet[tetp2] - *tet[tetp1]; - vtet2 = *tet[tetp3] - *tet[tetp1]; - break; - } - case 2: - { - vtet1 = *tet[tetp3] - *tet[tetp1]; - vtet2 = *tet[tetp4] - *tet[tetp1]; - break; - } - case 3: - { - vtet1 = *tet[tetp4] - *tet[tetp1]; - vtet2 = *tet[tetp2] - *tet[tetp1]; - break; - } - } - - Vec3d ntet; - Cross (vtet1, vtet2, ntet); - - Vec3d crline = Cross (ntri, ntet); - - double lcrline = crline.Length(); - if (lcrline < eps * eps) - continue; - - - if (vtri1 * crline + vtri2 * crline < 0) - crline *= -1; - - double lam1, lam2, lam3, lam4; - LocalCoordinates (vtri1, vtri2, crline, lam1, lam2); - LocalCoordinates (vtet1, vtet2, crline, lam3, lam4); - - if (lam1 > -eps && lam2 > -eps && - lam3 > -eps && lam4 > -eps) - { - // (*testout) << "hit, cnt == 1" << "\n"; - return 1; - } - } - - return 0; - break; - } - case 2: - { -#ifdef MARK - MARK (inttettric2ref); -#endif - - // common edge - tetp3 = 0; - while (tetp3 == tetp1 || tetp3 == tetp2) - tetp3++; - tetp4 = 6 - tetp1 - tetp2 - tetp3; - trip3 = 3 - trip1 - trip2; - - // (*testout) << "trip1,2,3 = " << trip1 << ", " << trip2 << ", " << trip3 << endl; - // (*testout) << "tetp1,2,3,4 = " << tetp1 << ", " << tetp2 - // << ", " << tetp3 << ", " << tetp4 << endl; - - Vec3d vtri = *tri[trip3] - *tri[trip1]; - Vec3d vtet1 = *tet[tetp3] - *tri[trip1]; - Vec3d vtet2 = *tet[tetp4] - *tri[trip1]; - - Vec3d n = *tri[trip2] - *tri[trip1]; - n /= n.Length(); - - vtet1 -= (n * vtet1) * n; - vtet2 -= (n * vtet2) * n; - - - double lam1, lam2; - LocalCoordinates (vtet1, vtet2, vtri, lam1, lam2); - - if (lam1 < -eps || lam2 < -eps) - return 0; - else - { - -// (*testout) << "vtet1 = " << vtet1 << endl; -// (*testout) << "vtet2 = " << vtet2 << endl; -// (*testout) << "vtri = " << vtri << endl; -// (*testout) << "lam1 = " << lam1 << " lam2 = " << lam2 << endl; - -// (*testout) << (lam1 * (vtet1 * vtet1) + lam2 * (vtet1 * vtet2)) -// << " = " << (vtet1 * vtri) << endl; -// (*testout) << (lam1 * (vtet1 * vtet2) + lam2 * (vtet2 * vtet2)) -// << " = " << (vtet2 * vtri) << endl; - -// (*testout) << "tet = "; -// for (j = 0; j < 4; j++) -// (*testout) << (*tet[j]) << " "; -// (*testout) << endl; -// (*testout) << "tri = "; -// for (j = 0; j < 3; j++) -// (*testout) << (*tri[j]) << " "; -// (*testout) << endl; - -// (*testout) << "hit, cnt == 2" << endl; - - return 1; - } - - break; - } - case 3: - { -#ifdef MARK - MARK (inttettric3ref); -#endif - - // common face - return 0; - } - } - - (*testout) << "hit, cnt = " << cnt << endl; - return 1; -} - - - - - - - - - - - -int IntersectTriangleTriangle (const Point3d ** tri1, const Point3d ** tri2) -{ - int i, j; - double diam = Dist (*tri1[0], *tri1[1]); - double epsrel = 1e-8; - double eps = diam * epsrel; - double eps2 = eps * eps; - - - - int cnt = 0; - /* - int tri1pi[3]; - int tri2pi[3]; - */ - - // int tri1p1 = -1; - /// int tri1p2 = -1; - // int tri2p1 = -1; - // int tri2p2 = -1; - // int tri1p3, tri2p3; - - /* - for (i = 0; i < 3; i++) - tri1pi[i] = -1; - */ - for (i = 0; i <= 2; i++) - { - // tri2pi[i] = -1; - for (j = 0; j <= 2; j++) - { - if (Dist2 (*tri1[j], *tri2[i]) < eps2) - { - // tri2pi[i] = j; - // tri1pi[j] = i; - cnt++; - // tri1p2 = tri1p1; - // tri1p1 = j; - // tri2p2 = tri2p1; - // tri2p1 = i; - break; - } - } - } - - switch (cnt) - { - case 0: - { - const Point3d * line[2]; - - for (i = 0; i <= 2; i++) - { - line[0] = tri2[i]; - line[1] = tri2[(i+1)%3]; - - if (IntersectTriangleLine (tri1, &line[0])) - { - (*testout) << "int1, line = " << *line[0] << " - " << *line[1] << endl; - return 1; - } - } - - for (i = 0; i <= 2; i++) - { - line[0] = tri1[i]; - line[1] = tri1[(i+1)%3]; - - if (IntersectTriangleLine (tri2, &line[0])) - { - (*testout) << "int2, line = " << *line[0] << " - " << *line[1] << endl; - return 1; - } - } - break; - } - default: - return 0; - } - - return 0; -} - - - -void -LocalCoordinates (const Vec3d & e1, const Vec3d & e2, - const Vec3d & v, double & lam1, double & lam2) -{ - double m11 = e1 * e1; - double m12 = e1 * e2; - double m22 = e2 * e2; - double rs1 = v * e1; - double rs2 = v * e2; - - double det = m11 * m22 - m12 * m12; - lam1 = (rs1 * m22 - rs2 * m12)/det; - lam2 = (m11 * rs2 - m12 * rs1)/det; -} - - - - - -int CalcSphereCenter (const Point3d ** pts, Point3d & c) -{ - /* - static DenseMatrix a(3), inva(3); - static Vector rs(3), sol(3); - int i; - double h = Dist(*pts[0], *pts[1]); - - for (i = 1; i <= 3; i++) - { - const Point3d & p1 = *pts[0]; - const Point3d & p2 = *pts[i]; - Vec3d v(p1, p2); - a.Elem(i,1) = v.X(); - a.Elem(i,2) = v.Y(); - a.Elem(i,3) = v.Z(); - - rs.Elem(i) = 0.5 * (v * v); - } - - if (fabs (a.Det()) <= 1e-12 * h * h * h) - { - (*testout) << "CalcSphereCenter: degenerated" << endl; - return 1; - } - - CalcInverse (a, inva); - inva.Mult (rs, sol); - - for (i = 1; i <= 3; i++) - c.X(i) = pts[0]->X(i) + sol.Elem(i); - */ - - Vec3d row1 (*pts[0], *pts[1]); - Vec3d row2 (*pts[0], *pts[2]); - Vec3d row3 (*pts[0], *pts[3]); - - Vec3d rhs(0.5 * (row1*row1), - 0.5 * (row2*row2), - 0.5 * (row3*row3)); - Transpose (row1, row2, row3); - - Vec3d sol; - if (SolveLinearSystem (row1, row2, row3, rhs, sol)) - { - (*testout) << "CalcSphereCenter: degenerated" << endl; - return 1; - } - - c = *pts[0] + sol; - return 0; -} - - - - - -int CalcTriangleCenter (const Point3d ** pts, Point3d & c) -{ - static DenseMatrix a(2), inva(2); - static Vector rs(2), sol(2); - double h = Dist(*pts[0], *pts[1]); - - Vec3d v1(*pts[0], *pts[1]); - Vec3d v2(*pts[0], *pts[2]); - - rs.Elem(1) = v1 * v1; - rs.Elem(2) = v2 * v2; - - a.Elem(1,1) = 2 * rs.Get(1); - a.Elem(1,2) = a.Elem(2,1) = 2 * (v1 * v2); - a.Elem(2,2) = 2 * rs.Get(2); - - if (fabs (a.Det()) <= 1e-12 * h * h) - { - (*testout) << "CalcTriangleCenter: degenerated" << endl; - return 1; - } - - CalcInverse (a, inva); - inva.Mult (rs, sol); - - c = *pts[0]; - v1 *= sol.Get(1); - v2 *= sol.Get(2); - - c += v1; - c += v2; - - return 0; -} - - - -double ComputeCylinderRadius (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Point3d & p4) -{ - Vec3d v12(p1, p2); - Vec3d v13(p1, p3); - Vec3d v14(p1, p4); - - Vec3d n1 = Cross (v12, v13); - Vec3d n2 = Cross (v14, v12); - - double n1l = n1.Length(); - double n2l = n2.Length(); - n1 /= n1l; - n2 /= n2l; - - double v12len = v12.Length(); - double h1 = n1l / v12len; - double h2 = n2l / v12len; - - /* - (*testout) << "n1 = " << n1 << " n2 = " << n2 - << "h1 = " << h1 << " h2 = " << h2 << endl; - */ - return ComputeCylinderRadius (n1, n2, h1, h2); -} - - - - -/* - Two triangles T1 and T2 have normals n1 and n2. - The height over the common edge is h1, and h2. - */ -double ComputeCylinderRadius (const Vec3d & n1, const Vec3d & n2, - double h1, double h2) -{ - Vec3d t1, t2; - double n11 = n1 * n1; - double n12 = n1 * n2; - double n22 = n2 * n2; - double det = n11 * n22 - n12 * n12; - - if (fabs (det) < 1e-14 * n11 * n22) - return 1e20; - - // a biorthogonal bases (ti * nj) = delta_ij: - t1 = (n22/det) * n1 + (-n12/det) * n2; - t2 = (-n12/det) * n1 + (n11/det) * n2; - - // normalize: - t1 /= t1.Length(); - t2 /= t2.Length(); - - /* - vector to center point has form - v = lam1 n1 + lam2 n2 - and fulfills - t2 v = h1/2 - t1 v = h2/2 - */ - - double lam1 = 0.5 * h2 / (n1 * t1); - double lam2 = 0.5 * h1 / (n2 * t2); - - double rad = (lam1 * n1 + lam2 * n2).Length(); - /* - (*testout) << "n1 = " << n1 - << " n2 = " << n2 - << " t1 = " << t1 - << " t2 = " << t2 - << " rad = " << rad << endl; - */ - return rad; -} - - - - - - -double MinDistLP2 (const Point2d & lp1, const Point2d & lp2, const Point2d & p) -{ - Vec2d v(lp1, lp2); - Vec2d vlp(lp1, p); - - // dist(lam) = \| vlp \|^2 - 2 lam (v1p, v) + lam^2 \| v \|^2 - - // lam = (v * vlp) / (v * v); - // if (lam < 0) lam = 0; - // if (lam > 1) lam = 1; - - double num = v*vlp; - double den = v*v; - - if (num <= 0) - return Dist2 (lp1, p); - - if (num >= den) - return Dist2 (lp2, p); - - if (den > 0) - { - return vlp.Length2() - num * num /den; - } - else - return vlp.Length2(); -} - - - - -double MinDistLP2 (const Point3d & lp1, const Point3d & lp2, const Point3d & p) -{ - Vec3d v(lp1, lp2); - Vec3d vlp(lp1, p); - - // dist(lam) = \| vlp \|^2 - 2 lam (v1p, v) + lam^2 \| v \|^2 - - // lam = (v * vlp) / (v * v); - // if (lam < 0) lam = 0; - // if (lam > 1) lam = 1; - - double num = v*vlp; - double den = v*v; - - if (num <= 0) - return Dist2 (lp1, p); - - if (num >= den) - return Dist2 (lp2, p); - - if (den > 0) - { - return vlp.Length2() - num * num /den; - } - else - return vlp.Length2(); -} - - - -double MinDistTP2 (const Point3d & tp1, const Point3d & tp2, - const Point3d & tp3, const Point3d & p) -{ - double lam1, lam2; - double res; - - LocalCoordinates (Vec3d (tp1, tp2), Vec3d (tp1, tp3), - Vec3d (tp1, p), lam1, lam2); - int in1 = lam1 >= 0; - int in2 = lam2 >= 0; - int in3 = lam1+lam2 <= 1; - - if (in1 && in2 && in3) - { - Point3d pp = tp1 + lam1 * Vec3d(tp1, tp2) + lam2 * Vec3d (tp1, tp3); - res = Dist2 (p, pp); - } - else - { - res = Dist2 (tp1, p); - if (!in1) - { - double hv = MinDistLP2 (tp1, tp3, p); - if (hv < res) res = hv; - } - if (!in2) - { - double hv = MinDistLP2 (tp1, tp2, p); - if (hv < res) res = hv; - } - if (!in3) - { - double hv = MinDistLP2 (tp2, tp3, p); - if (hv < res) res = hv; - } - /* - double d1 = MinDistLP2 (tp1, tp2, p); - double d2 = MinDistLP2 (tp1, tp3, p); - double d3 = MinDistLP2 (tp2, tp3, p); - res = min3 (d1, d2, d3); - */ - } - - return res; - - Vec3d pp1(tp1, p); - Vec3d v1(tp1, tp2), v2(tp1, tp3); - - double c = pp1.Length2(); - double cx = -2 * (pp1 * v1); - double cy = -2 * (pp1 * v2); - double cxx = v1.Length2(); - double cxy = 2 * (v1 * v2); - double cyy = v2.Length2(); - - QuadraticPolynomial2V pol (-c, -cx, -cy, -cxx, -cxy, -cyy); - double res2 = - pol.MaxUnitTriangle (); - - if (fabs (res - res2) > 1e-8) - cout << "res and res2 differ: " << res << " != " << res2 << endl; - return res2; -} - - -// 0 checks !!! -double MinDistLL2 (const Point3d & l1p1, const Point3d & l1p2, - const Point3d & l2p1, const Point3d & l2p2) -{ - // dist(lam1,lam2) = \| l2p1+lam2v2 - (l1p1+lam1 v1) \| - // min ! - - Vec3d l1l2 (l1p1, l2p1); - Vec3d v1 (l1p1, l1p2); - Vec3d v2 (l2p1, l2p2); - - double a11, a12, a22, rs1, rs2; - double lam1, lam2, det; - - a11 = v1*v1; - a12 = -(v1*v2); - a22 = v2*v2; - rs1 = l1l2 * v1; - rs2 = - (l1l2 * v2); - - det = a11 * a22 - a12 * a12; - if (det < 1e-14 * a11 * a22) - det = 1e-14 * a11 * a22; // regularization should be stable - - if (det < 1e-20) - det = 1e-20; - - - lam1 = (a22 * rs1 - a12 * rs2) / det; - lam2 = (-a12 * rs1 + a11 * rs2) / det; - - if (lam1 >= 0 && lam2 >= 0 && lam1 <= 1 && lam2 <= 1) - { - Vec3d v = l1l2 + (-lam1) * v1 + lam2 * v2; - return v.Length2(); - } - - double minv, hv; - minv = MinDistLP2 (l1p1, l1p2, l2p1); - hv = MinDistLP2 (l1p1, l1p2, l2p2); - if (hv < minv) minv = hv; - - hv = MinDistLP2 (l2p1, l2p2, l1p1); - if (hv < minv) minv = hv; - hv = MinDistLP2 (l2p1, l2p2, l1p2); - if (hv < minv) minv = hv; - - return minv; -} - -} diff --git a/Netgen/libsrc/gprim/geomtest3d.hpp b/Netgen/libsrc/gprim/geomtest3d.hpp deleted file mode 100644 index f801b8cdef..0000000000 --- a/Netgen/libsrc/gprim/geomtest3d.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef FILE_GEOMTEST3D -#define FILE_GEOMTEST3D - -/* *************************************************************************/ -/* File: geomtest3d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 13. Feb. 98 */ -/* *************************************************************************/ - - - -extern int -IntersectTriangleLine (const Point3d ** tri, const Point3d ** line); - - - -/** - Returns 0, iff - closure (tet) cup closure (tri) is empty, one corner point of tet, - one edge of tet or one face of tet - */ -extern int -IntersectTetTriangle (const Point3d ** tet, const Point3d ** tri, - const int * tetpi = NULL, const int * tripi = NULL); - -/** - Same test as above, but tet int reference position (0, ex, ey, ez), - tetpi = 1, 2, 4, 5 - */ -extern int -IntersectTetTriangleRef (const Point3d ** tri, const int * tripi = NULL); - - -// 1, iff not regular triangulation -extern int -IntersectTriangleTriangle (const Point3d ** tri1, const Point3d ** tri2); - - -extern void -LocalCoordinates (const Vec3d & e1, const Vec3d & e2, - const Vec3d & v, double & lam1, double & lam2); - -/// return 1 = degenerated sphere -extern int -CalcSphereCenter (const Point3d ** pts, Point3d & c); - -/// return 1 = degenerated triangle -extern int -CalcTriangleCenter (const Point3d ** pts, Point3d & c); - - - -/* - Compute radius of cylinder fitting 4 points. - cylinder axis is in the direction of p1-p2 -*/ -extern double ComputeCylinderRadius (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4); - -/* - Two triangles T1 and T2 have normals n1 and n2. - The height over the common edge is h1, and h2. - Radius of cylinder fitting both triangles -*/ -extern double ComputeCylinderRadius (const Vec3d & n1, const Vec3d & n2, - double h1, double h2); - - -extern double MinDistLP2 (const Point2d & lp1, const Point2d & lp2, const Point2d & p); - -extern double MinDistLP2 (const Point3d & lp1, const Point3d & lp2, const Point3d & p); - -extern double MinDistTP2 (const Point3d & tp1, const Point3d & tp2, - const Point3d & tp3, const Point3d & p); - -extern double MinDistLL2 (const Point3d & l1p1, const Point3d & l1p2, - const Point3d & l2p1, const Point3d & l2p2); - - -#endif diff --git a/Netgen/libsrc/gprim/gprim.hpp b/Netgen/libsrc/gprim/gprim.hpp deleted file mode 100644 index 0f57ebac86..0000000000 --- a/Netgen/libsrc/gprim/gprim.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef FILE_GPRIM -#define FILE_GPRIM - -/* *************************************************************************/ -/* File: gprim.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 14. Aug. 97 */ -/* *************************************************************************/ - - -namespace netgen -{ -#include "geomobjects.hpp" -#include "geomops.hpp" -#include "geomfuncs.hpp" - -#include "geom2d.hpp" -#include "geom3d.hpp" -#include "geomtest3d.hpp" -// #include "rot3d.hpp" -#include "transform3d.hpp" -// #include "reftrans.hpp" -#include "adtree.hpp" -} - -#endif diff --git a/Netgen/libsrc/gprim/testgeom.cpp b/Netgen/libsrc/gprim/testgeom.cpp deleted file mode 100644 index 8413f0f2b5..0000000000 --- a/Netgen/libsrc/gprim/testgeom.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <gprim.hpp> - - -Vec<2> func1 (const Point<2> & a, const Point<2> & b) -{ - return a-b; -} - -void func2 (Point<3> & a, Vec<3> & v) -{ - a += 3.4 * v; -} - -void func3 (const Mat<2,2> & m, const Vec<2> & vc, Vec<2> & res) -{ - res += Trans (m) * vc; -} diff --git a/Netgen/libsrc/gprim/transform3d.cpp b/Netgen/libsrc/gprim/transform3d.cpp deleted file mode 100644 index ea62fffe5a..0000000000 --- a/Netgen/libsrc/gprim/transform3d.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <gprim.hpp> -#include <linalg.hpp> - -namespace netgen -{ - -Transformation3d :: Transformation3d () -{ - int i, j; - for (i = 0; i < 3; i++) - { - offset[i] = 0; - for (j = 0; j < 3; j++) - lin[i][j] = 0; - } -} - -Transformation3d :: Transformation3d (const Vec3d & translate) -{ - int i, j; - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - lin[i][j] = 0; - for (i = 0; i < 3; i++) - { - offset[i] = translate.X(i+1); - lin[i][i] = 1; - } -} - - -Transformation3d :: -Transformation3d (const Point3d & c, double alpha, - double beta, double gamma) -{ - // total = T_c x Rot_0 x T_c^{-1} - // Use Euler angles, see many books from tech mech, e.g. - // Shabana "multibody systems" - - Transformation3d tc(c); - Transformation3d tcinv; - tc.CalcInverse (tcinv); - - Transformation3d r1, r2, r3, ht, ht2; - r1.SetAxisRotation (3, alpha); - r2.SetAxisRotation (1, beta); - r3.SetAxisRotation (3, gamma); - - ht.Combine (tc, r3); - ht2.Combine (ht, r2); - ht.Combine (ht2, r1); - Combine (ht, tcinv); - - cout << "Rotation - Transformation:" << (*this) << endl; - // (*testout) << "Rotation - Transformation:" << (*this) << endl; -} - - - - -Transformation3d :: Transformation3d (const Point3d ** pp) -{ - int i, j; - for (i = 1; i <= 3; i++) - { - offset[i-1] = (*pp[0]).X(i); - for (j = 1; j <= 3; j++) - lin[i-1][j-1] = (*pp[j]).X(i) - (*pp[0]).X(i); - } -} - -Transformation3d :: Transformation3d (const Point3d pp[]) -{ - int i, j; - for (i = 1; i <= 3; i++) - { - offset[i-1] = pp[0].X(i); - for (j = 1; j <= 3; j++) - lin[i-1][j-1] = pp[j].X(i) - pp[0].X(i); - } -} - - -void Transformation3d :: CalcInverse (Transformation3d & inv) const -{ - static DenseMatrix a(3), inva(3); - static Vector b(3), sol(3); - int i, j; - - for (i = 1; i <= 3; i++) - { - b.Elem(i) = offset[i-1]; - for (j = 1; j <= 3; j++) - a.Elem(i, j) = lin[i-1][j-1]; - } - - ::netgen::CalcInverse (a, inva); - inva.Mult (b, sol); - - for (i = 1; i <= 3; i++) - { - inv.offset[i-1] = -sol.Get(i); - for (j = 1; j <= 3; j++) - inv.lin[i-1][j-1] = inva.Elem(i, j); - } -} - - -void Transformation3d:: -Combine (const Transformation3d & ta, const Transformation3d & tb) -{ - int i, j, k; - - // o = o_a+ m_a o_b - // m = m_a m_b - - for (i = 0; i <= 2; i++) - { - offset[i] = ta.offset[i]; - for (j = 0; j <= 2; j++) - offset[i] += ta.lin[i][j] * tb.offset[j]; - } - - for (i = 0; i <= 2; i++) - for (j = 0; j <= 2; j++) - { - lin[i][j] = 0; - for (k = 0; k <= 2; k++) - lin[i][j] += ta.lin[i][k] * tb.lin[k][j]; - } -} -void Transformation3d :: SetAxisRotation (int dir, double alpha) -{ - double co = cos(alpha); - double si = sin(alpha); - dir--; - int pos1 = (dir+1) % 3; - int pos2 = (dir+2) % 3; - - int i, j; - for (i = 0; i <= 2; i++) - { - offset[i] = 0; - for (j = 0; j <= 2; j++) - lin[i][j] = 0; - } - - lin[dir][dir] = 1; - lin[pos1][pos1] = co; - lin[pos2][pos2] = co; - lin[pos1][pos2] = si; - lin[pos2][pos1] = -si; -} - -ostream & operator<< (ostream & ost, Transformation3d & trans) -{ - int i, j; - ost << "offset = "; - for (i = 0; i <= 2; i++) - ost << trans.offset[i] << " "; - ost << endl << "linear = " << endl; - for (i = 0; i <= 2; i++) - { - for (j = 0; j <= 2; j++) - ost << trans.lin[i][j] << " "; - ost << endl; - } - return ost; -} -} diff --git a/Netgen/libsrc/gprim/transform3d.hpp b/Netgen/libsrc/gprim/transform3d.hpp deleted file mode 100644 index 7472257297..0000000000 --- a/Netgen/libsrc/gprim/transform3d.hpp +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef FILE_TRANSFORM3D -#define FILE_TRANSFORM3D - -/* *************************************************************************/ -/* File: transform3d.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 22. Mar. 98 */ -/* *************************************************************************/ - -/* - Affine - Linear mapping in 3D space - */ - -class Transformation3d; -ostream & operator<< (ostream & ost, Transformation3d & trans); - -class Transformation3d -{ - double lin[3][3]; - double offset[3]; -public: - /// - Transformation3d (); - /// Unit tet is mapped to tet descibed by pp - Transformation3d (const Point3d ** pp); - /// Unit tet is mapped to tet descibed by pp - Transformation3d (const Point3d pp[]); - /// translation - Transformation3d (const Vec3d & translate); - /// rotation with ... - Transformation3d (const Point3d & c, double alpha, double beta, double gamma); - /// - void CalcInverse (Transformation3d & inv) const; - /// this = ta x tb - void Combine (const Transformation3d & ta, const Transformation3d & tb); - /// dir = 1..3 (== x..z) - void SetAxisRotation (int dir, double alpha); - /// - void Transform (const Point3d & from, Point3d & to) const - { - for (int i = 1; i <= 3; i++) - { - to.X(i) = offset[i-1] + lin[i-1][0] * from.X(1) + - lin[i-1][1] * from.X(2) + lin[i-1][2] * from.X(3); - } - } - /// transform vector, apply only linear part, not offset - void Transform (const Vec3d & from, Vec3d & to) const - { - for (int i = 1; i <= 3; i++) - { - to.X(i) = lin[i-1][0] * from.X(1) + - lin[i-1][1] * from.X(2) + lin[i-1][2] * from.X(3); - } - } - friend ostream & operator<< (ostream & ost, Transformation3d & trans); -}; - - - - - - - - - - - - - - -template <int D> -class Transformation -{ - Mat<D> m; - Vec<D> v; -public: - /// - Transformation () { m = 0; v = 0; } - - /// Unit tet is mapped to tet descibed by pp - Transformation (const Point<D> * pp); - - /// translation - Transformation (const Vec<D> & translate) - { - v = translate; - m = 0; - for (int i = 0; i < D; i++) - m(i,i) = 1; - } - - // rotation with ... - Transformation (const Point<D> & c, double alpha, double beta, double gamma) - { - // total = T_c x Rot_0 x T_c^{-1} - // Use Euler angles, see many books from tech mech, e.g. - // Shabana "multibody systems" - - Vec<D> vc(c); - Transformation<D> tc(vc); - Transformation<D> tcinv(-vc); - // tc.CalcInverse (tcinv); - - Transformation<D> r1, r2, r3, ht, ht2; - r1.SetAxisRotation (3, alpha); - r2.SetAxisRotation (1, beta); - r3.SetAxisRotation (3, gamma); - - ht.Combine (tc, r3); - ht2.Combine (ht, r2); - ht.Combine (ht2, r1); - Combine (ht, tcinv); - - // cout << "Rotation - Transformation:" << (*this) << endl; - // (*testout) << "Rotation - Transformation:" << (*this) << endl; - } - - /// - void CalcInverse (Transformation & inv) const; - - /// this = ta x tb - void Combine (const Transformation & ta, const Transformation & tb) - { - v = ta.v + ta.m * tb.v; - m = ta.m * tb.m; - } - - - - /// dir = 1..3 (== x..z) - void SetAxisRotation (int dir, double alpha) - { - double co = cos(alpha); - double si = sin(alpha); - dir--; - int pos1 = (dir+1) % 3; - int pos2 = (dir+2) % 3; - - int i, j; - for (i = 0; i <= 2; i++) - { - v(i) = 0; - for (j = 0; j <= 2; j++) - m(i,j) = 0; - } - - m(dir,dir) = 1; - m(pos1, pos1) = co; - m(pos2, pos2) = co; - m(pos1, pos2) = si; - m(pos2, pos1) = -si; - } - - /// - void Transform (const Point<D> & from, Point<D> & to) const - { - to = Point<D> (v + m * Vec<D>(from)); - } - - /// transform vector, apply only linear part, not offset - void Transform (const Vec<D> & from, Vec<D> & to) const - { - to = m * from; - } -}; - -template <int D> -ostream & operator<< (ostream & ost, Transformation<D> & trans); - - - - -#endif diff --git a/Netgen/libsrc/include/FlexLexer.h b/Netgen/libsrc/include/FlexLexer.h deleted file mode 100644 index 4b9b53cd13..0000000000 --- a/Netgen/libsrc/include/FlexLexer.h +++ /dev/null @@ -1,184 +0,0 @@ -// $Header: /cvsroot/gmsh/Netgen/libsrc/include/FlexLexer.h,v 1.2 2004-12-08 20:01:21 geuzaine Exp $ - -// FlexLexer.h -- define interfaces for lexical analyzer classes generated -// by flex - -// Copyright (c) 1993 The Regents of the University of California. -// All rights reserved. -// -// This code is derived from software contributed to Berkeley by -// Kent Williams and Tom Epperly. -// -// Redistribution and use in source and binary forms are permitted provided -// that: (1) source distributions retain this entire copyright notice and -// comment, and (2) distributions including binaries display the following -// acknowledgement: ``This product includes software developed by the -// University of California, Berkeley and its contributors'' in the -// documentation or other materials provided with the distribution and in -// all advertising materials mentioning features or use of this software. -// Neither the name of the University nor the names of its contributors may -// be used to endorse or promote products derived from this software without -// specific prior written permission. -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -// This file defines FlexLexer, an abstract class which specifies the -// external interface provided to flex C++ lexer objects, and yyFlexLexer, -// which defines a particular lexer class. -// -// If you want to create multiple lexer classes, you use the -P flag -// to rename each yyFlexLexer to some other xxFlexLexer. You then -// include <FlexLexer.h> in your other sources once per lexer class: -// -// #undef yyFlexLexer -// #define yyFlexLexer xxFlexLexer -// #include <FlexLexer.h> -// -// #undef yyFlexLexer -// #define yyFlexLexer zzFlexLexer -// #include <FlexLexer.h> -// ... - -#ifndef __FLEX_LEXER_H -// Never included before - need to define base class. -#define __FLEX_LEXER_H - - -extern "C++" { -struct yy_buffer_state; -typedef int yy_state_type; - -class FlexLexer { -public: - virtual ~FlexLexer() { } - - const char* YYText() { return yytext; } - int YYLeng() { return yyleng; } - - virtual void - yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; - virtual struct yy_buffer_state* - yy_create_buffer( istream* s, int size ) = 0; - virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; - virtual void yyrestart( istream* s ) = 0; - - virtual int yylex() = 0; - - // Call yylex with new input/output sources. - int yylex( istream* new_in, ostream* new_out = 0 ) - { - switch_streams( new_in, new_out ); - return yylex(); - } - - // Switch to new input/output streams. A nil stream pointer - // indicates "keep the current one". - virtual void switch_streams( istream* new_in = 0, - ostream* new_out = 0 ) = 0; - - int lineno() const { return yylineno; } - - int debug() const { return yy_flex_debug; } - void set_debug( int flag ) { yy_flex_debug = flag; } - -protected: - char* yytext; - int yyleng; - int yylineno; // only maintained if you use %option yylineno - int yy_flex_debug; // only has effect with -d or "%option debug" -}; - -} -#endif - -#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) -// Either this is the first time through (yyFlexLexerOnce not defined), -// or this is a repeated include to define a different flavor of -// yyFlexLexer, as discussed in the flex man page. -#define yyFlexLexerOnce - -class yyFlexLexer : public FlexLexer { -public: - // arg_yyin and arg_yyout default to the cin and cout, but we - // only make that assignment when initializing in yylex(). - yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 ); - - virtual ~yyFlexLexer(); - - void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); - struct yy_buffer_state* yy_create_buffer( istream* s, int size ); - void yy_delete_buffer( struct yy_buffer_state* b ); - void yyrestart( istream* s ); - - virtual int yylex(); - virtual void switch_streams( istream* new_in, ostream* new_out ); - -protected: - virtual int LexerInput( char* buf, int max_size ); - virtual void LexerOutput( const char* buf, int size ); - virtual void LexerError( const char* msg ); - - void yyunput( int c, char* buf_ptr ); - int yyinput(); - - void yy_load_buffer_state(); - void yy_init_buffer( struct yy_buffer_state* b, istream* s ); - void yy_flush_buffer( struct yy_buffer_state* b ); - - int yy_start_stack_ptr; - int yy_start_stack_depth; - int* yy_start_stack; - - void yy_push_state( int new_state ); - void yy_pop_state(); - int yy_top_state(); - - yy_state_type yy_get_previous_state(); - yy_state_type yy_try_NUL_trans( yy_state_type current_state ); - int yy_get_next_buffer(); - - istream* yyin; // input source for default LexerInput - ostream* yyout; // output sink for default LexerOutput - - struct yy_buffer_state* yy_current_buffer; - - // yy_hold_char holds the character lost when yytext is formed. - char yy_hold_char; - - // Number of characters read into yy_ch_buf. - int yy_n_chars; - - // Points to current character in buffer. - char* yy_c_buf_p; - - int yy_init; // whether we need to initialize - int yy_start; // start state number - - // Flag which is used to allow yywrap()'s to do buffer switches - // instead of setting up a fresh yyin. A bit of a hack ... - int yy_did_buffer_switch_on_eof; - - // The following are not always needed, but may be depending - // on use of certain flex features (like REJECT or yymore()). - - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - yy_state_type* yy_state_buf; - yy_state_type* yy_state_ptr; - - char* yy_full_match; - int* yy_full_state; - int yy_full_lp; - - int yy_lp; - int yy_looking_for_trail_begin; - - int yy_more_flag; - int yy_more_len; - int yy_more_offset; - int yy_prev_more_offset; -}; - -#endif diff --git a/Netgen/libsrc/include/csg.hpp b/Netgen/libsrc/include/csg.hpp deleted file mode 100644 index ffd45ef0bf..0000000000 --- a/Netgen/libsrc/include/csg.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../csg/csg.hpp" diff --git a/Netgen/libsrc/include/geometry2d.hpp b/Netgen/libsrc/include/geometry2d.hpp deleted file mode 100644 index bf0965c228..0000000000 --- a/Netgen/libsrc/include/geometry2d.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../geom2d/geometry2d.hpp" diff --git a/Netgen/libsrc/include/gprim.hpp b/Netgen/libsrc/include/gprim.hpp deleted file mode 100644 index 1e827aaf8c..0000000000 --- a/Netgen/libsrc/include/gprim.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../gprim/gprim.hpp" diff --git a/Netgen/libsrc/include/incvis.hpp b/Netgen/libsrc/include/incvis.hpp deleted file mode 100644 index a38e918698..0000000000 --- a/Netgen/libsrc/include/incvis.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// libraries for User interface: - -/* -#include <tcl8.3.h> -#include <tk8.3.h> - -#include <GL/gl.h> -#include <GL/glu.h> -#include "../togl/togl.h" - -#include <tix8.1.h> -*/ - - -#include <tcl.h> -#include <tk.h> - - -#if TK_MAJOR_VERSION==8 && TK_MINOR_VERSION==4 -#define tcl_const const -#else -#define tcl_const -#endif - - -#include <GL/gl.h> -#include <GL/glu.h> -#include "../../togl/togl.h" - - - -// Just the init-call -// #include <tix.h> diff --git a/Netgen/libsrc/include/linalg.hpp b/Netgen/libsrc/include/linalg.hpp deleted file mode 100644 index e96bd036c3..0000000000 --- a/Netgen/libsrc/include/linalg.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../linalg/linalg.hpp" diff --git a/Netgen/libsrc/include/meshing.hpp b/Netgen/libsrc/include/meshing.hpp deleted file mode 100644 index e41a88f9f2..0000000000 --- a/Netgen/libsrc/include/meshing.hpp +++ /dev/null @@ -1 +0,0 @@ -#include <../meshing/meshing.hpp> diff --git a/Netgen/libsrc/include/myadt.hpp b/Netgen/libsrc/include/myadt.hpp deleted file mode 100644 index d36bef05c1..0000000000 --- a/Netgen/libsrc/include/myadt.hpp +++ /dev/null @@ -1 +0,0 @@ -#include <../general/myadt.hpp> diff --git a/Netgen/libsrc/include/mydefs.hpp b/Netgen/libsrc/include/mydefs.hpp deleted file mode 100644 index c34ce56a8e..0000000000 --- a/Netgen/libsrc/include/mydefs.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef FILE_MYDEFS -#define FILE_MYDEFS - -/**************************************************************************/ -/* File: mydefs.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 10. Mar. 98 */ -/**************************************************************************/ - -/* - defines for graphics, testmodes, ... -*/ - - -// #define DEBUG - - -#define noDEMOVERSION -#define noDEVELOP -#define noSTEP -#define noSOLIDGEOM - -#define noDEMOAPP -#define noMODELLER - -#define noSTAT_STREAM -#define noLOG_STREAM - -#endif diff --git a/Netgen/libsrc/include/mystdlib.h b/Netgen/libsrc/include/mystdlib.h deleted file mode 100644 index 2249aea3a2..0000000000 --- a/Netgen/libsrc/include/mystdlib.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef FILE_MYSTDLIB -#define FILE_MYSTDLIB - - -#include <iostream> -#include <iomanip> -#include <fstream> -#include <sstream> - -#ifdef OLDCINCLUDE - -// e.g., CC compiler on SGI -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <malloc.h> -#include <ctype.h> -#include <time.h> - -#else - -// new standard -#include <cstdlib> -#include <cstdio> -#include <cmath> -#include <cctype> -#include <ctime> -#endif - - - -#include <new> -#include <string> -#include <typeinfo> - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - - -/*** Windows headers ***/ -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include <afxwin.h> -#include <afxmt.h> -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#include <winnt.h> -#endif /* WIN32 */ - - -/* -extern void* operator new(std::size_t) throw (std::bad_alloc); -extern void* operator new[](std::size_t) throw (std::bad_alloc); -extern void operator delete(void*) throw(); -extern void operator delete[](void*) throw(); -*/ - - -extern int mem_alloc; -extern int mem_total_alloc; -extern int mem_max_alloc; -extern int mem_total_alloc_array; -extern int mem_total_alloc_table; - - -using namespace std; - -#endif diff --git a/Netgen/libsrc/include/occgeom.hpp b/Netgen/libsrc/include/occgeom.hpp deleted file mode 100644 index af258e0df0..0000000000 --- a/Netgen/libsrc/include/occgeom.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../occ/occgeom.hpp" diff --git a/Netgen/libsrc/include/opti.hpp b/Netgen/libsrc/include/opti.hpp deleted file mode 100644 index 6b8a0b61c8..0000000000 --- a/Netgen/libsrc/include/opti.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../opti/opti.hpp" diff --git a/Netgen/libsrc/include/stepgeom.hpp b/Netgen/libsrc/include/stepgeom.hpp deleted file mode 100644 index d2c5c5e41e..0000000000 --- a/Netgen/libsrc/include/stepgeom.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "../stepgeom/geomanif.hh" -#include "../stepgeom/geopac2d.hh" -#include "../stepgeom/geopac3d.hh" -#include "../stepgeom/geosplinesurf.hh" -#include "../stepgeom/algprim.hh" -#include "../stepgeom/scenery.hh" -#include "../stepgeom/brep.hh" -#include "../stepgeom/adtcrit.hh" -#include "../stepgeom/STEPgeom.hh" -#include "../stepgeom/visapprox.hh" diff --git a/Netgen/libsrc/include/stepreader.hpp b/Netgen/libsrc/include/stepreader.hpp deleted file mode 100644 index 0214d58d9d..0000000000 --- a/Netgen/libsrc/include/stepreader.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../stepgeom/STEPread.hh" diff --git a/Netgen/libsrc/include/stlgeom.hpp b/Netgen/libsrc/include/stlgeom.hpp deleted file mode 100644 index f1eea264e1..0000000000 --- a/Netgen/libsrc/include/stlgeom.hpp +++ /dev/null @@ -1 +0,0 @@ -#include <../stlgeom/stlgeom.hpp> diff --git a/Netgen/libsrc/include/visual.hpp b/Netgen/libsrc/include/visual.hpp deleted file mode 100644 index f026f5a458..0000000000 --- a/Netgen/libsrc/include/visual.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "../visualization/visual.hpp" diff --git a/Netgen/libsrc/interface/Makefile b/Netgen/libsrc/interface/Makefile deleted file mode 100644 index c47dbe2c5a..0000000000 --- a/Netgen/libsrc/interface/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -src = nginterface.cpp writeuser.cpp writediffpack.cpp writeabaqus.cpp writefluent.cpp writepermas.cpp writetochnog.cpp writetecplot.cpp wuchemnitz.cpp writetochnog.cpp writefeap.cpp writeelmer.cpp writegmsh.cpp readuser.cpp importsolution.cpp -# -lib = nginterface -libpath = libsrc/interface -# -include ../makefile.inc -# diff --git a/Netgen/libsrc/interface/importsolution.cpp b/Netgen/libsrc/interface/importsolution.cpp deleted file mode 100644 index 3973d3927e..0000000000 --- a/Netgen/libsrc/interface/importsolution.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// -// Read solution file -// - - -#include <mystdlib.h> - - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -#include "nginterface.h" - -namespace netgen -{ -#include "writeuser.hpp" - - -void ImportSolution (const char * filename) -{ - ifstream inf (filename); - char buf[100], name[1000]; - int i, j, size, comps, order; - bool iscomplex; - const char * type; - Flags flags; - - while (1) - { - buf[0] = 0; - inf >> buf; - if (strcmp (buf, "solution") == 0) - { - inf >> name; - - inf >> buf[0]; - flags.DeleteFlags (); - while (buf[0] == '-') - { - inf >> buf[1]; - inf.putback (buf[1]); - if (!isalpha (buf[1])) - { - break; - } - inf >> (buf+1); - flags.SetCommandLineFlag (buf); - buf[0] = 0; - inf >> buf[0]; - } - inf.putback (buf[0]); - - (*testout) << "Flags: " << endl; - flags.PrintFlags (*testout); - (*testout) << "done" << endl; - - size = int(flags.GetNumFlag ("size", Ng_GetNP())); - comps = int(flags.GetNumFlag ("components", 1)); - type = flags.GetStringFlag ("type", "nodal"); - order = int(flags.GetNumFlag ("order", 1)); - iscomplex = flags.GetDefineFlag ("complex"); - - double * sol = new double[size*comps]; - - (*testout) << "import solution " << name << " size = " << size << " comps = " << comps << " order = " << order << endl; - - for (i = 0; i < size*comps; i++) - { - inf >> sol[i]; - // (*testout) << "sol: " << sol[i] << endl; - } - - Ng_SolutionData soldata; - Ng_InitSolutionData (&soldata); - soldata.name = name; - soldata.data = sol; - soldata.dist = comps; - soldata.components = comps; - soldata.order = order; - soldata.iscomplex = iscomplex; - soldata.soltype = NG_SOLUTION_NODAL; - if (strcmp (type, "element") == 0) - soldata.soltype = NG_SOLUTION_ELEMENT; - if (strcmp (type, "surfaceelement") == 0) - soldata.soltype = NG_SOLUTION_SURFACE_ELEMENT; - if (strcmp (type, "noncontinuous") == 0) - soldata.soltype = NG_SOLUTION_NONCONTINUOUS; - if (strcmp (type, "surfacenoncontinuous") == 0) - soldata.soltype = NG_SOLUTION_SURFACE_NONCONTINUOUS; - - Ng_SetSolutionData (&soldata); - } - else - { - // cout << "kw = (" << buf << ")" << endl; - (*testout) << "kw = (" << buf << ")" << endl; - break; - } - } - /* - struct Ng_SolutionData - { - char * name; // name of gridfunction - double * data; // solution values - int components; // used components in solution vector - int dist; // num of doubles per entry (alignment!) - Ng_SolutionType soltype; // type of solution function - }; - - // initialize solution data with default arguments - void Ng_InitSolutionData (Ng_SolutionData * soldata); - // set solution data - void Ng_SetSolutionData (Ng_SolutionData * soldata); - */ -} - - - -} diff --git a/Netgen/libsrc/interface/nginterface.cpp b/Netgen/libsrc/interface/nginterface.cpp deleted file mode 100644 index 784be18dc5..0000000000 --- a/Netgen/libsrc/interface/nginterface.cpp +++ /dev/null @@ -1,1476 +0,0 @@ -#include <mystdlib.h> - - -#include <meshing.hpp> -#include <csg.hpp> -#include <geometry2d.hpp> -#include <stlgeom.hpp> - -#ifdef OCCGEOMETRY -#include <occgeom.hpp> -#endif - - -#include <visual.hpp> - -#include "nginterface.h" -// #include <FlexLexer.h> - - -// #include <mystdlib.h> - - -namespace netgen -{ - extern AutoPtr<Mesh> mesh; - extern VisualSceneMesh vsmesh; - extern Tcl_Interp * tcl_interp; - - extern AutoPtr<SplineGeometry2d> geometry2d; - extern AutoPtr<CSGeometry> geometry; - extern STLGeometry * stlgeometry; -#ifdef OCCGEOMETRY - extern OCCGeometry * occgeometry; -#endif - -#ifdef OPENGL - extern VisualSceneSolution vssolution; -#endif - extern CSGeometry * ParseCSG (istream & istr); -} - - -using namespace netgen; - -/* - extern void * operator new (size_t s); - extern void * operator new [] (size_t s); - extern void operator delete (void * p); - extern void operator delete [] (void * p); -*/ - -// extern FlexLexer * lexer; - - - -void Ng_LoadGeometry (char * filename) -{ - ifstream infile (filename); - - geometry.Reset (); - geometry2d.Reset (); - -#ifdef OCCGEOMETRY - delete occgeometry; - occgeometry = 0; -#endif - - if ((strcmp (&filename[strlen(filename)-3], "geo") == 0) || - (strcmp (&filename[strlen(filename)-3], "GEO") == 0) || - (strcmp (&filename[strlen(filename)-3], "Geo") == 0)) - { - geometry.Reset (netgen::ParseCSG (infile)); - - if (!geometry) - { - geometry.Reset (new CSGeometry ()); - throw NgException ("input file not found"); - } - - geometry -> FindIdenticSurfaces(1e-6); - - double detail = atof (Tcl_GetVar (tcl_interp, "geooptions.detail", 0)); - double facets = atof (Tcl_GetVar (tcl_interp, "geooptions.facets", 0)); - Box<3> box (geometry->BoundingBox()); - - if (atoi (Tcl_GetVar (tcl_interp, "geooptions.drawcsg", 0))) - geometry->CalcTriangleApproximation(box, detail, facets); - - // geometry->CalcTriangleApproximation (box, 0.01, 10); - } - - else if (strcmp (&filename[strlen(filename)-4], "in2d") == 0) - { - geometry2d.Reset (new SplineGeometry2d()); - geometry2d -> Load (filename); - } - - else if ((strcmp (&filename[strlen(filename)-3], "stl") == 0) || - (strcmp (&filename[strlen(filename)-3], "STL") == 0) || - (strcmp (&filename[strlen(filename)-3], "Stl") == 0)) - { - ifstream infile(filename); - stlgeometry = STLGeometry :: Load (infile); - stlgeometry->edgesfound = 0; - Mesh meshdummy; - stlgeometry->Clear(); - stlgeometry->BuildEdges(); - stlgeometry->MakeAtlas(meshdummy); - stlgeometry->CalcFaceNums(); - stlgeometry->AddFaceEdges(); - stlgeometry->LinkEdges(); - } - -#ifdef OCCGEOMETRY - else if ((strcmp (&filename[strlen(filename)-4], "iges") == 0) || - (strcmp (&filename[strlen(filename)-3], "igs") == 0) || - (strcmp (&filename[strlen(filename)-3], "IGS") == 0) || - (strcmp (&filename[strlen(filename)-4], "IGES") == 0)) - { - PrintMessage (1, "Load IGES geometry file ", filename); - occgeometry = LoadOCC_IGES (filename); - } - else if ((strcmp (&filename[strlen(filename)-4], "step") == 0) || - (strcmp (&filename[strlen(filename)-3], "stp") == 0) || - (strcmp (&filename[strlen(filename)-3], "STP") == 0) || - (strcmp (&filename[strlen(filename)-4], "STEP") == 0)) - { - PrintMessage (1, "Load STEP geometry file ", filename); - occgeometry = LoadOCC_STEP (filename); - } -#endif - else - { - cerr << "Unknown geometry extension!!" << endl; - } -} - - -void Ng_LoadMesh (char * filename) -{ - mesh.Reset (new Mesh()); - mesh->Load (filename); -} - - - -int Ng_GetDimension () -{ - return mesh->GetDimension(); -} - -int Ng_GetNP () -{ - return mesh->GetNP(); -} - -int Ng_GetNV () -{ - return mesh->GetNV(); -} - -int Ng_GetNE () -{ - if (mesh->GetDimension() == 3) - return mesh->GetNE(); - else - return mesh->GetNSE(); -} - -int Ng_GetNSE () -{ - if (mesh->GetDimension() == 3) - return mesh->GetNSE(); - else - return mesh->GetNSeg(); -} - -void Ng_GetPoint (int pi, double * p) -{ - const Point3d & hp = mesh->Point (pi); - p[0] = hp.X(); - p[1] = hp.Y(); - if (mesh->GetDimension() == 3) - p[2] = hp.Z(); -} - - -NG_ELEMENT_TYPE Ng_GetElement (int ei, int * epi, int * np) -{ - if (mesh->GetDimension() == 3) - { - int i; - const Element & el = mesh->VolumeElement (ei); - for (i = 0; i < el.GetNP(); i++) - epi[i] = el.PNum(i+1); - - if (np) - *np = el.GetNP(); - - if (el.GetType() == PRISM) - { - // degenerated prism, (should be obsolete) - const int map1[] = { 3, 2, 5, 6, 1 }; - const int map2[] = { 1, 3, 6, 4, 2 }; - const int map3[] = { 2, 1, 4, 5, 3 }; - - const int * map = NULL; - int deg1 = 0, deg2 = 0, deg3 = 0; - int deg = 0; - if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; } - if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; } - if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; } - - switch (deg1+deg2+deg3) - { - { - case 1: - cout << "degenerated prism found, deg = 1" << endl; - for (i = 0; i < 5; i++) - epi[i] = el.PNum (map[i]); - - if (np) *np = 5; - return NG_PYRAMID; - break; - } - case 2: - { - cout << "degenerated prism found, deg = 2" << endl; - if (!deg1) epi[3] = el.PNum(4); - if (!deg2) epi[3] = el.PNum(5); - if (!deg3) epi[3] = el.PNum(6); - - if (np) *np = 4; - return NG_TET; - break; - } - default: - ; - } - - } - - return NG_ELEMENT_TYPE (el.GetType()); - } - else - { - int i; - const Element2d & el = mesh->SurfaceElement (ei); - for (i = 0; i < el.GetNP(); i++) - epi[i] = el.PNum(i+1); - - if (np) *np = el.GetNP(); - return NG_ELEMENT_TYPE (el.GetType()); - /* - switch (el.GetNP()) - { - case 3: return NG_TRIG; - case 4: return NG_QUAD; - case 6: return NG_TRIG6; - } - */ - } - - // should not occur - return NG_TET; -} - - -NG_ELEMENT_TYPE Ng_GetElementType (int ei) -{ - if (mesh->GetDimension() == 3) - { - return NG_ELEMENT_TYPE (mesh->VolumeElement (ei).GetType()); - } - else - { - int i; - const Element2d & el = mesh->SurfaceElement (ei); - switch (el.GetNP()) - { - case 3: return NG_TRIG; - case 4: return NG_QUAD; - case 6: return NG_TRIG6; - } - } - - // should not occur - return NG_TET; -} - - - -int Ng_GetElementIndex (int ei) -{ - if (mesh->GetDimension() == 3) - return mesh->VolumeElement(ei).GetIndex(); - else - { - int ind = mesh->SurfaceElement(ei).GetIndex(); - ind = mesh->GetFaceDescriptor(ind).BCProperty(); - return ind; - } -} - -char * Ng_GetElementMaterial (int ei) -{ - static char empty[] = ""; - if (mesh->GetDimension() == 3) - { - int ind = mesh->VolumeElement(ei).GetIndex(); - // cout << "ind = " << ind << endl; - const char * mat = mesh->GetMaterial (ind); - if (mat) - return const_cast<char*> (mat); - else - return empty; - } - return 0; -} - -NG_ELEMENT_TYPE Ng_GetSurfaceElement (int ei, int * epi, int * np) -{ - if (mesh->GetDimension() == 3) - { - const Element2d & el = mesh->SurfaceElement (ei); - for (int i = 0; i < el.GetNP(); i++) - epi[i] = el[i]; - - if (np) *np = el.GetNP(); - - return NG_ELEMENT_TYPE (el.GetType()); - } - else - { - const Segment & seg = mesh->LineSegment (ei); - - if (seg.pmid < 0) - { - epi[0] = seg.p1; - epi[1] = seg.p2; - - if (np) *np = 2; - return NG_SEGM; - } - else - { - epi[0] = seg.p1; - epi[1] = seg.p2; - epi[2] = seg.pmid; - - if (np) *np = 3; - return NG_SEGM3; - } - } - - return NG_TRIG; -} - -int Ng_GetSurfaceElementIndex (int ei) -{ - if (mesh->GetDimension() == 3) - return mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).BCProperty(); - else - return mesh->LineSegment(ei).si; -} - - -void Ng_GetNormalVector (int sei, int locpi, double * nv) -{ - nv[0] = 0; - nv[1] = 0; - nv[2] = 1; - - (*testout) << "Ng_GetNormalVector (sei = " << sei << ", locpi = " << locpi << ")" << endl; - - if (mesh->GetDimension() == 3) - { - Vec<3> n; - Point<3> p; - p = mesh->Point (mesh->SurfaceElement(sei).PNum(locpi)); - - int surfi = mesh->GetFaceDescriptor(mesh->SurfaceElement(sei).GetIndex()).SurfNr(); - - (*testout) << "surfi = " << surfi << endl; -#ifdef OCCGEOMETRY - if (occgeometry) - { - PointGeomInfo gi = mesh->SurfaceElement(sei).GeomInfoPi(locpi); - occgeometry->GetSurface (surfi).GetNormalVector(p, gi, n); - nv[0] = n(0); - nv[1] = n(1); - nv[2] = n(2); - } - else -#endif - if (geometry) - { - (*testout) << "geometry defined" << endl; - n = geometry->GetSurface (surfi) -> GetNormalVector(p); - (*testout) << "aus is" << endl; - nv[0] = n(0); - nv[1] = n(1); - nv[2] = n(2); - } - } -} - - -int Ng_FindElementOfPoint (double * p, double * lami, int build_searchtree, int index) -{ - if (mesh->GetDimension() == 3) - { - Point3d p3d(p[0], p[1], p[2]); - int ind = - mesh->GetElementOfPoint(p3d, lami, build_searchtree != 0, index); - return ind; - } - else - { - double lam3[3]; - Point3d p2d(p[0], p[1], 0); - int ind = - mesh->GetElementOfPoint(p2d, lam3, build_searchtree != 0, index); - lami[0] = lam3[0]; - lami[1] = lam3[1]; - return ind; - } -} - - - -void Ng_GetElementTransformation (int ei, const double * xi, - double * x, double * dxdxi) -{ - if (mesh->GetDimension() == 2) - { - Point<2> xl(xi[0], xi[1]); - Point<3> xg; - Mat<3,2> dx; - - mesh->GetCurvedElements().CalcSurfaceTransformation (xl, ei-1, xg, dx); - - if (x) - { - for (int i = 0; i < 2; i++) - x[i] = xg(i); - } - - if (dxdxi) - { - for (int i=0; i<2; i++) - { - dxdxi[2*i] = dx(i,0); - dxdxi[2*i+1] = dx(i,1); - } - } - } - else - { - Point<3> xl(xi[0], xi[1], xi[2]); - // (*testout) << "elnr = " << ei << ", eltrans, xl = " << xl << endl; - Point<3> xg; - Mat<3,3> dx; - - mesh->GetCurvedElements().CalcElementTransformation (xl, ei-1, xg, dx); - - // still 1-based arrays - if (x) - { - for (int i = 0; i < 3; i++) - x[i] = xg(i); - } - - if (dxdxi) - { - for (int i=0; i<3; i++) - { - dxdxi[3*i] = dx(i,0); - dxdxi[3*i+1] = dx(i,1); - dxdxi[3*i+2] = dx(i,2); - } - } - } -} - - -void Ng_GetSurfaceElementTransformation (int sei, const double * xi, - double * x, double * dxdxi) -{ - if (mesh->GetDimension() == 2) - { - Point<3> xg; - Vec<3> dx; - - // still 1-based arrays - mesh->GetCurvedElements().CalcSegmentTransformation (xi[0], sei-1, xg, dx); - - if (x) - for (int i = 0; i < 2; i++) - x[i] = xg(i); - - if (dxdxi) - for (int i=0; i<2; i++) - dxdxi[i] = dx(i); - - } - else - { - Point<2> xl(xi[0], xi[1]); - Point<3> xg; - Mat<3,2> dx; - - // still 1-based arrays - mesh->GetCurvedElements().CalcSurfaceTransformation (xl, sei-1, xg, dx); - - for (int i=0; i<3; i++) - { - if (x) - x[i] = xg(i); - if (dxdxi) - { - dxdxi[2*i] = dx(i,0); - dxdxi[2*i+1] = dx(i,1); - } - } - } -} - - - -void Ng_GetSurfaceElementNeighbouringDomains(const int selnr, int & in, int & out) -{ - in = mesh->GetFaceDescriptor((*mesh)[static_cast<SurfaceElementIndex>(selnr)].GetIndex()).DomainIn(); - out = mesh->GetFaceDescriptor((*mesh)[static_cast<SurfaceElementIndex>(selnr)].GetIndex()).DomainOut(); -} - - -void Ng_SetRefinementFlag (int ei, int flag) -{ - if (mesh->GetDimension() == 3) - mesh->VolumeElement(ei).SetRefinementFlag (flag != 0); - else - mesh->SurfaceElement(ei).SetRefinementFlag (flag != 0); -} - -void Ng_SetSurfaceRefinementFlag (int ei, int flag) -{ - if (mesh->GetDimension() == 3) - mesh->SurfaceElement(ei).SetRefinementFlag (flag != 0); -} - - -void Ng_Refine (NG_REFINEMENT_TYPE reftype) -{ - BisectionOptions biopt; - biopt.usemarkedelements = 1; - biopt.refine_p = 0; - biopt.refine_hp = 0; - if (reftype == NG_REFINE_P) - biopt.refine_p = 1; - if (reftype == NG_REFINE_HP) - biopt.refine_hp = 1; - Refinement * ref; - - if (geometry2d) - ref = new Refinement2d(*geometry2d); - else if (stlgeometry) - ref = new RefinementSTLGeometry(*stlgeometry); -#ifdef OCCGEOMETRY - else if (occgeometry) - ref = new OCCRefinementSurfaces (*occgeometry); -#endif - else if (geometry && mesh->GetDimension() == 3) - ref = new RefinementSurfaces(*geometry); - else - { - ref = new Refinement(); - } - - ref -> Bisect (*mesh, biopt); - - mesh -> UpdateTopology(); - // mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); - delete ref; -} - -void Ng_SecondOrder () -{ - if (stlgeometry) - { - RefinementSTLGeometry ref (*stlgeometry); - ref.MakeSecondOrder (*mesh); - } - - else if (geometry2d) - { - Refinement2d ref (*geometry2d); - ref.MakeSecondOrder (*mesh); - } - - else if (geometry && mesh->GetDimension() == 3) - - { - RefinementSurfaces ref (*geometry); - ref.MakeSecondOrder (*mesh); - } - else - { - cout << "no geom" << endl; - Refinement ref; - ref.MakeSecondOrder (*mesh); - } - - mesh -> UpdateTopology(); -} - -void Ng_HPRefinement (int levels) -{ - Refinement * ref; - - if (stlgeometry) - ref = new RefinementSTLGeometry (*stlgeometry); - else if (geometry2d) - ref = new Refinement2d (*geometry2d); - else - ref = new RefinementSurfaces (*geometry); - - - HPRefinement (*mesh, ref, levels); -} - - -void Ng_HighOrder (int order) -{ - Refinement * ref; - - if (stlgeometry) - ref = new RefinementSTLGeometry (*stlgeometry); -#ifdef OCCGEOMETRY - else if (occgeometry) - ref = new OCCRefinementSurfaces (*occgeometry); -#endif - else if (geometry2d) - ref = new Refinement2d (*geometry2d); - else - ref = new RefinementSurfaces (*geometry); - - // cout << "parameter 1: " << argv[1] << " (conversion to int = " << atoi(argv[1]) << ")" << endl; - - mesh -> GetCurvedElements().BuildCurvedElements (ref, order); - - delete ref; -} - - - - - - - - - - - - -int Ng_ME_GetNVertices (NG_ELEMENT_TYPE et) -{ - switch (et) - { - case NG_SEGM: - case NG_SEGM3: - return 2; - - case NG_TRIG: - case NG_TRIG6: - return 3; - - case NG_QUAD: - return 4; - - case NG_TET: - case NG_TET10: - return 4; - - case NG_PYRAMID: - return 5; - - case NG_PRISM: - case NG_PRISM12: - return 6; - - case NG_HEX: - return 8; - - default: - cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; - } - return 0; -} - -int Ng_ME_GetNEdges (NG_ELEMENT_TYPE et) -{ - switch (et) - { - case NG_SEGM: - case NG_SEGM3: - return 1; - - case NG_TRIG: - case NG_TRIG6: - return 3; - - case NG_QUAD: - return 4; - - case NG_TET: - case NG_TET10: - return 6; - - case NG_PYRAMID: - return 8; - - case NG_PRISM: - case NG_PRISM12: - return 9; - - case NG_HEX: - return 12; - - default: - cerr << "Ng_ME_GetNEdges, illegal element type " << et << endl; - } - return 0; -} - - -int Ng_ME_GetNFaces (NG_ELEMENT_TYPE et) -{ - switch (et) - { - case NG_SEGM: - case NG_SEGM3: - return 0; - - case NG_TRIG: - case NG_TRIG6: - return 1; - - case NG_QUAD: - case NG_QUAD6: - return 1; - - case NG_TET: - case NG_TET10: - return 4; - - case NG_PYRAMID: - return 5; - - case NG_PRISM: - case NG_PRISM12: - return 5; - - case NG_HEX: - return 6; - - default: - cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; - } - return 0; -} - - -const NG_POINT * Ng_ME_GetVertices (NG_ELEMENT_TYPE et) -{ - static double segm_points [][3] = - { { 1, 0, 0 }, - { 0, 0, 0 } }; - - static double trig_points [][3] = - { { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 0 } }; - - static double quad_points [][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 } }; - - static double tet_points [][3] = - { { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { 0, 0, 0 } }; - - static double pyramid_points [][3] = - { - { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 0, 1-1e-7 }, - }; - - static double prism_points[][3] = - { - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 0 }, - { 1, 0, 1 }, - { 0, 1, 1 }, - { 0, 0, 1 } - }; - - switch (et) - { - case NG_SEGM: - case NG_SEGM3: - return segm_points; - - case NG_TRIG: - case NG_TRIG6: - return trig_points; - - case NG_QUAD: - case NG_QUAD6: - return quad_points; - - case NG_TET: - case NG_TET10: - return tet_points; - - case NG_PYRAMID: - return pyramid_points; - - case NG_PRISM: - case NG_PRISM12: - return prism_points; - - case NG_HEX: - default: - cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; - } - return 0; -} - - - -const NG_EDGE * Ng_ME_GetEdges (NG_ELEMENT_TYPE et) -{ - static int segm_edges[1][2] = - { { 1, 2 }}; - - static int trig_edges[3][2] = - { { 3, 1 }, - { 3, 2 }, - { 1, 2 }}; - - static int quad_edges[4][2] = - { { 1, 2 }, - { 4, 3 }, - { 1, 4 }, - { 2, 3 }}; - - - static int tet_edges[6][2] = - { { 4, 1 }, - { 4, 2 }, - { 4, 3 }, - { 1, 2 }, - { 1, 3 }, - { 2, 3 }}; - - static int prism_edges[9][2] = - { { 3, 1 }, - { 1, 2 }, - { 3, 2 }, - { 6, 4 }, - { 4, 5 }, - { 6, 5 }, - { 3, 6 }, - { 1, 4 }, - { 2, 5 }}; - - static int pyramid_edges[8][2] = - { { 1, 2 }, - { 2, 3 }, - { 1, 4 }, - { 4, 3 }, - { 1, 5 }, - { 2, 5 }, - { 3, 5 }, - { 4, 5 }}; - - - - switch (et) - { - case NG_SEGM: - case NG_SEGM3: - return segm_edges; - - case NG_TRIG: - case NG_TRIG6: - return trig_edges; - - case NG_QUAD: - case NG_QUAD6: - return quad_edges; - - case NG_TET: - case NG_TET10: - return tet_edges; - - case NG_PYRAMID: - return pyramid_edges; - - case NG_PRISM: - case NG_PRISM12: - return prism_edges; - - case NG_HEX: - default: - cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; - } - return 0; -} - - -const NG_FACE * Ng_ME_GetFaces (NG_ELEMENT_TYPE et) -{ - static int tet_faces[4][4] = - { { 4, 2, 3, 0 }, - { 4, 1, 3, 0 }, - { 4, 1, 2, 0 }, - { 1, 2, 3, 0 } }; - - static int prism_faces[5][4] = - { - { 1, 2, 3, 0 }, - { 4, 5, 6, 0 }, - { 3, 1, 4, 6 }, - { 1, 2, 5, 4 }, - { 2, 3, 6, 5 } - }; - - static int pyramid_faces[5][4] = - { - { 1, 2, 5, 0 }, - { 2, 3, 5, 0 }, - { 3, 4, 5, 0 }, - { 4, 1, 5, 0 }, - { 1, 2, 3, 4 } - }; - - static int trig_faces[1][4] = - { - { 1, 2, 3, 0 }, - }; - - switch (et) - { - case NG_TET: - case NG_TET10: - return tet_faces; - - case NG_PRISM: - case NG_PRISM12: - return prism_faces; - - case NG_PYRAMID: - return pyramid_faces; - - - case NG_SEGM: - case NG_SEGM3: - - case NG_TRIG: - case NG_TRIG6: - return trig_faces; - case NG_QUAD: - - - case NG_HEX: - - default: - cerr << "Ng_ME_GetFaces, illegal element type " << et << endl; - } - return 0; -} - - -int Ng_GetNEdges() -{ - return mesh->GetTopology().GetNEdges(); -} -int Ng_GetNFaces() -{ - return mesh->GetTopology().GetNFaces(); -} - - - -int Ng_GetElement_Edges (int elnr, int * edges, int * orient) -{ - const MeshTopology & topology = mesh->GetTopology(); - if (mesh->GetDimension() == 3) - return topology.GetElementEdges (elnr, edges, orient); - else - return topology.GetSurfaceElementEdges (elnr, edges, orient); -} - -int Ng_GetElement_Faces (int elnr, int * faces, int * orient) -{ - const MeshTopology & topology = mesh->GetTopology(); - if (mesh->GetDimension() == 3) - return topology.GetElementFaces (elnr, faces, orient); - else - { - faces[0] = elnr; - if (orient) orient[0] = 0; - return 1; - } -} - -int Ng_GetSurfaceElement_Edges (int elnr, int * edges, int * orient) -{ - const MeshTopology & topology = mesh->GetTopology(); - if (mesh->GetDimension() == 3) - return topology.GetSurfaceElementEdges (elnr, edges, orient); - else - { - if (orient) - topology.GetSegmentEdge(elnr, edges[0], orient[0]); - else - edges[0] = topology.GetSegmentEdge(elnr); - } - return 1; - /* - int i, ned; - const MeshTopology & topology = mesh->GetTopology(); - ARRAY<int> ia; - topology.GetSurfaceElementEdges (elnr, ia); - ned = ia.Size(); - for (i = 1; i <= ned; i++) - edges[i-1] = ia.Get(i); - - if (orient) - { - topology.GetSurfaceElementEdgeOrientations (elnr, ia); - for (i = 1; i <= ned; i++) - orient[i-1] = ia.Get(i); - } - return ned; - */ -} - -int Ng_GetSurfaceElement_Face (int selnr, int * orient) -{ - if (mesh->GetDimension() == 3) - { - const MeshTopology & topology = mesh->GetTopology(); - if (orient) - *orient = topology.GetSurfaceElementFaceOrientation (selnr); - return topology.GetSurfaceElementFace (selnr); - } - return -1; -} - -int Ng_GetFace_Vertices (int fnr, int * vert) -{ - const MeshTopology & topology = mesh->GetTopology(); - ArrayMem<int,4> ia; - topology.GetFaceVertices (fnr, ia); - for (int i = 0; i < ia.Size(); i++) - vert[i] = ia[i]; - // cout << "face verts = " << ia << endl; - return ia.Size(); -} - - -int Ng_GetFace_Edges (int fnr, int * edge) -{ - const MeshTopology & topology = mesh->GetTopology(); - ArrayMem<int,4> ia; - topology.GetFaceEdges (fnr, ia); - for (int i = 0; i < ia.Size(); i++) - edge[i] = ia[i]; - return ia.Size(); -} - -void Ng_GetEdge_Vertices (int ednr, int * vert) -{ - const MeshTopology & topology = mesh->GetTopology(); - topology.GetEdgeVertices (ednr, vert[0], vert[1]); -} - - -int Ng_GetNVertexElements (int vnr) -{ - if (mesh->GetDimension() == 3) - return mesh->GetTopology().GetVertexElements(vnr).Size(); - else - return mesh->GetTopology().GetVertexSurfaceElements(vnr).Size(); -} - -void Ng_GetVertexElements (int vnr, int * els) -{ - FlatArray<int> ia(0,0); - if (mesh->GetDimension() == 3) - ia = mesh->GetTopology().GetVertexElements(vnr); - else - ia = mesh->GetTopology().GetVertexSurfaceElements(vnr); - for (int i = 0; i < ia.Size(); i++) - els[i] = ia[i]; -} - - -int Ng_GetElementOrder (int enr) -{ - if (mesh->GetDimension() == 3) - return mesh->VolumeElement(enr).GetOrder(); - else - return mesh->SurfaceElement(enr).GetOrder(); -} - - - -int Ng_GetNLevels () -{ - return mesh->mglevels; -} - - -void Ng_GetParentNodes (int ni, int * parents) -{ - if (ni <= mesh->mlbetweennodes.Size()) - { - parents[0] = mesh->mlbetweennodes.Get(ni).I1(); - parents[1] = mesh->mlbetweennodes.Get(ni).I2(); - } - else - parents[0] = parents[1] = 0; -} - - -int Ng_GetParentElement (int ei) -{ - if (mesh->GetDimension() == 3) - { - if (ei <= mesh->mlparentelement.Size()) - return mesh->mlparentelement.Get(ei); - } - else - { - if (ei <= mesh->mlparentsurfaceelement.Size()) - return mesh->mlparentsurfaceelement.Get(ei); - } - return 0; -} - - -int Ng_GetParentSElement (int ei) -{ - if (mesh->GetDimension() == 3) - { - if (ei <= mesh->mlparentsurfaceelement.Size()) - return mesh->mlparentsurfaceelement.Get(ei); - } - else - { - return 0; - } - return 0; -} - - - - - -int Ng_GetClusterRepVertex (int pi) -{ - return mesh->GetClusters().GetVertexRepresentant(pi); -} - -int Ng_GetClusterRepEdge (int pi) -{ - return mesh->GetClusters().GetEdgeRepresentant(pi); -} - -int Ng_GetClusterRepFace (int pi) -{ - return mesh->GetClusters().GetFaceRepresentant(pi); -} - -int Ng_GetClusterRepElement (int pi) -{ - return mesh->GetClusters().GetElementRepresentant(pi); -} - - - - - - -void Ng_InitSolutionData (Ng_SolutionData * soldata) -{ - soldata -> name = NULL; - soldata -> data = NULL; - soldata -> components = 1; - soldata -> dist = 1; - soldata -> order = 1; - soldata -> iscomplex = 0; - soldata -> draw_surface = 1; - soldata -> draw_volume = 1; - soldata -> soltype = NG_SOLUTION_NODAL; - soldata -> solclass = 0; -} - -void Ng_SetSolutionData (Ng_SolutionData * soldata) -{ -#ifdef OPENGL - // vssolution.ClearSolutionData (); - VisualSceneSolution::SolData * vss = new VisualSceneSolution::SolData; - - // cout << "Add solution " << soldata->name << ", type = " << soldata->soltype << endl; - - vss->name = new char[strlen (soldata->name)+1]; - strcpy (vss->name, soldata->name); - - vss->data = soldata->data; - vss->components = soldata->components; - vss->dist = soldata->dist; - vss->order = soldata->order; - vss->iscomplex = bool(soldata->iscomplex); - vss->draw_surface = soldata->draw_surface; - vss->draw_volume = soldata->draw_volume; - vss->soltype = VisualSceneSolution::SolType (soldata->soltype); - vss->solclass = soldata->solclass; - vssolution.AddSolutionData (vss); -#endif -} - -void Ng_ClearSolutionData () -{ - vssolution.ClearSolutionData(); -} - - - -void Ng_Redraw () -{ -#ifdef OPENGL - vssolution.UpdateSolutionTimeStamp(); - Render(); -#endif -} - - -void Ng_SetVisualizationParameter (const char * name, const char * value) -{ -#ifdef OPENGL - char buf[100]; - sprintf (buf, "visoptions.%s", name); - cout << "name = " << name << ", value = " << value << endl; - cout << "set tcl-variable " << buf << " to " << value << endl; - Tcl_SetVar (tcl_interp, buf, const_cast<char*> (value), 0); - Tcl_Eval (tcl_interp, "Ng_Vis_Set parameters;"); -#endif -} - - - - -int firsttime = 1; -int animcnt = 0; -void PlayAnimFile(const char* name, int speed, int maxcnt) -{ - //extern Mesh * mesh; - - /* - if (mesh.Ptr()) mesh->DeleteMesh(); - if (!mesh.Ptr()) mesh = new Mesh(); - */ - mesh.Reset (new Mesh()); - - int ne, np, i, ti; - - char str[80]; - char str2[80]; - - //int tend = 5000; - // for (ti = 1; ti <= tend; ti++) - //{ - int rti = (animcnt%(maxcnt-1)) + 1; - animcnt+=speed; - - sprintf(str2,"%05i.sol",rti); - strcpy(str,"mbssol/"); - strcat(str,name); - strcat(str,str2); - - cout << "read file '" << str << "'" << endl; - - ifstream infile(str); - infile >> ne; - for (i = 1; i <= ne; i++) - { - int j; - Element2d tri(TRIG); - tri.SetIndex(1); //faceind - - for (j = 1; j <= 3; j++) - infile >> tri.PNum(j); - - infile >> np; - for (i = 1; i <= np; i++) - { - Point3d p; - infile >> p.X() >> p.Y() >> p.Z(); - if (firsttime) - mesh->AddPoint (p); - else - mesh->Point(i)=p; - } - - //firsttime = 0; - Ng_Redraw(); - } -} - - -int Ng_GetNPeriodicVertices () -{ - ARRAY<INDEX_2> apairs; - mesh->GetIdentifications().GetPairs (0, apairs); - return apairs.Size(); -} - - -// pairs should be an integer array of 2*npairs -void Ng_GetPeriodicVertices (int * pairs) -{ - ARRAY<INDEX_2> apairs; - mesh->GetIdentifications().GetPairs (0, apairs); - for (int i = 0; i < apairs.Size(); i++) - { - pairs[2*i] = apairs[i].I1(); - pairs[2*i+1] = apairs[i].I2(); - } - -} - - - -int Ng_GetNPeriodicEdges () -{ - ARRAY<INDEX,PointIndex::BASE> map; - const MeshTopology & top = mesh->GetTopology(); - int nse = mesh->GetNSeg(); - - int cnt = 0; - // for (int id = 1; id <= mesh->GetIdentifications().GetMaxNr(); id++) - { - mesh->GetIdentifications().GetMap(0, map); - //(*testout) << "ident-map " << id << ":" << endl << map << endl; - - for (SegmentIndex si = 0; si < nse; si++) - { - PointIndex other1 = map[(*mesh)[si].p1]; - PointIndex other2 = map[(*mesh)[si].p2]; - // (*testout) << "seg = " << (*mesh)[si] << "; other = " - // << other1 << "-" << other2 << endl; - if (other1 && other2 && mesh->IsSegment (other1, other2)) - { - cnt++; - } - } - } - return cnt; -} - -void Ng_GetPeriodicEdges (int * pairs) -{ - ARRAY<INDEX,PointIndex::BASE> map; - const MeshTopology & top = mesh->GetTopology(); - int nse = mesh->GetNSeg(); - - int cnt = 0; - // for (int id = 1; id <= mesh->GetIdentifications().GetMaxNr(); id++) - { - mesh->GetIdentifications().GetMap(0, map); - - //(*testout) << "map = " << map << endl; - - for (SegmentIndex si = 0; si < nse; si++) - { - PointIndex other1 = map[(*mesh)[si].p1]; - PointIndex other2 = map[(*mesh)[si].p2]; - if (other1 && other2 && mesh->IsSegment (other1, other2)) - { - SegmentIndex otherseg = mesh->SegmentNr (other1, other2); - pairs[cnt++] = top.GetSegmentEdge (si+1); - pairs[cnt++] = top.GetSegmentEdge (otherseg+1); - } - } - } -} - - - -void Ng_PushStatus (const char * str) -{ - PushStatus (MyStr (str)); -} - -void Ng_PopStatus () -{ - PopStatus (); -} - -void Ng_SetThreadPercentage (double percent) -{ - SetThreadPercent (percent); -} - - -///// Added by Roman Stainko .... -int Ng_GetVertex_Elements( int vnr, int* elems ) -{ - const MeshTopology& topology = mesh->GetTopology(); - ArrayMem<int,4> indexArray; - topology.GetVertexElements( vnr, indexArray ); - - for( int i=0; i<indexArray.Size(); i++ ) - elems[i] = indexArray[i]; - - return indexArray.Size(); -} - -///// Added by Roman Stainko .... -int Ng_GetVertex_SurfaceElements( int vnr, int* elems ) -{ - const MeshTopology& topology = mesh->GetTopology(); - ArrayMem<int,4> indexArray; - topology.GetVertexSurfaceElements( vnr, indexArray ); - - for( int i=0; i<indexArray.Size(); i++ ) - elems[i] = indexArray[i]; - - return indexArray.Size(); -} - -///// Added by Roman Stainko .... -int Ng_GetVertex_NElements( int vnr ) -{ - const MeshTopology& topology = mesh->GetTopology(); - ArrayMem<int,4> indexArray; - topology.GetVertexElements( vnr, indexArray ); - - return indexArray.Size(); -} - -///// Added by Roman Stainko .... -int Ng_GetVertex_NSurfaceElements( int vnr ) -{ - const MeshTopology& topology = mesh->GetTopology(); - ArrayMem<int,4> indexArray; - topology.GetVertexSurfaceElements( vnr, indexArray ); - - return indexArray.Size(); -} - - - diff --git a/Netgen/libsrc/interface/nginterface.h b/Netgen/libsrc/interface/nginterface.h deleted file mode 100644 index dcb8ddd332..0000000000 --- a/Netgen/libsrc/interface/nginterface.h +++ /dev/null @@ -1,245 +0,0 @@ -#ifndef NGINTERFACE -#define NGINTERFACE - -/**************************************************************************/ -/* File: nginterface.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Nov. 99 */ -/**************************************************************************/ - -/* - - Application program interface to Netgen - - - */ - - -// max number of nodes per element -#define NG_ELEMENT_MAXPOINTS 12 - -// max number of nodes per surface element -#define NG_SURFACE_ELEMENT_MAXPOINTS 8 - - - -// implemented element types: -enum NG_ELEMENT_TYPE { - NG_SEGM = 1, NG_SEGM3 = 2, - NG_TRIG = 10, NG_QUAD=11, NG_TRIG6 = 12, NG_QUAD6 = 13, - NG_TET = 20, NG_TET10 = 21, - NG_PYRAMID = 22, NG_PRISM = 23, NG_PRISM12 = 24, - NG_HEX = 25 -}; - -typedef double NG_POINT[3]; // coordinates -typedef int NG_EDGE[2]; // initial point, end point -typedef int NG_FACE[4]; // points, last one is 0 for trig - - -#ifdef __cplusplus -extern "C" { -#endif - - // load geomtry from file - void Ng_LoadGeometry (char * filename); - - // load netgen mesh - void Ng_LoadMesh (char * filename); - - - // space dimension (2 or 3) - int Ng_GetDimension (); - - // number of mesh points - int Ng_GetNP (); - - // number of mesh vertices (differs from GetNP for 2nd order elements) - int Ng_GetNV (); - - // number of mesh elements - int Ng_GetNE (); - - // number of surface triangles - int Ng_GetNSE (); - - // Get Point coordintes, index from 1 .. np - void Ng_GetPoint (int pi, double * p); - - // Get Element Points - NG_ELEMENT_TYPE Ng_GetElement (int ei, int * epi, int * np = 0); - - // Get Element Type - NG_ELEMENT_TYPE Ng_GetElementType (int ei); - - // Get sub-domain of element ei - int Ng_GetElementIndex (int ei); - - // Get Material of element ei - char * Ng_GetElementMaterial (int ei); - - // Get Surface Element Points - NG_ELEMENT_TYPE Ng_GetSurfaceElement (int ei, int * epi, int * np = 0); - - // Get Surface Element Index - int Ng_GetSurfaceElementIndex (int ei); - - // Get normal vector of surface element node - void Ng_GetNormalVector (int sei, int locpi, double * nv); - - - // Find element of point, returns local coordinates - int Ng_FindElementOfPoint (double * p, double * lami, - int build_searchtrees = 0, int index = -1); - - - /// Curved Elemens: - /// xi..local coordinates - /// x ..global coordinates - /// dxdxi...D x D Jacobian matrix (row major storage) - void Ng_GetElementTransformation (int ei, const double * xi, - double * x, double * dxdxi); - - /// Curved Elemens: - /// xi..local coordinates - /// x ..global coordinates - /// dxdxi...D x D-1 Jacobian matrix (row major storage) - void Ng_GetSurfaceElementTransformation (int sei, const double * xi, double * x, double * dxdxi); - - - // Mark element for refinement - void Ng_SetRefinementFlag (int ei, int flag); - void Ng_SetSurfaceRefinementFlag (int sei, int flag); - - // Do local refinement - enum NG_REFINEMENT_TYPE { NG_REFINE_H = 0, NG_REFINE_P = 1, NG_REFINE_HP = 2 }; - void Ng_Refine (NG_REFINEMENT_TYPE reftype); - - // Use second order elements - void Ng_SecondOrder (); - void Ng_HighOrder (int order); - void Ng_HPRefinement (int levels); - - - // Topology and coordinate information of master element: - - int Ng_ME_GetNVertices (NG_ELEMENT_TYPE et); - int Ng_ME_GetNEdges (NG_ELEMENT_TYPE et); - int Ng_ME_GetNFaces (NG_ELEMENT_TYPE et); - - const NG_POINT * Ng_ME_GetVertices (NG_ELEMENT_TYPE et); - const NG_EDGE * Ng_ME_GetEdges (NG_ELEMENT_TYPE et); - const NG_FACE * Ng_ME_GetFaces (NG_ELEMENT_TYPE et); - - int Ng_GetNEdges(); - int Ng_GetNFaces(); - - - int Ng_GetElement_Edges (int elnr, int * edges, int * orient = 0); - int Ng_GetElement_Faces (int elnr, int * faces, int * orient = 0); - - int Ng_GetSurfaceElement_Edges (int selnr, int * edges, int * orient = 0); - int Ng_GetSurfaceElement_Face (int selnr, int * orient = 0); - - void Ng_GetSurfaceElementNeighbouringDomains(const int selnr, int & in, int & out); - - int Ng_GetFace_Vertices (int fnr, int * vert); - void Ng_GetEdge_Vertices (int ednr, int * vert); - int Ng_GetFace_Edges (int fnr, int * edge); - - int Ng_GetNVertexElements (int vnr); - void Ng_GetVertexElements (int vnr, int * els); - - int Ng_GetElementOrder (int enr); - - // Multilevel functions: - - // number of levels: - int Ng_GetNLevels (); - // get two parent nodes of node ni - void Ng_GetParentNodes (int ni, int * parents); - - // get parent element (first child has always same number) - int Ng_GetParentElement (int ei); - - // get parent surface element (first child has always same number) - int Ng_GetParentSElement (int ei); - - // representant of anisotropic cluster - int Ng_GetClusterRepVertex (int vi); - int Ng_GetClusterRepEdge (int edi); - int Ng_GetClusterRepFace (int fai); - int Ng_GetClusterRepElement (int eli); - - - void Ng_SurfaceElementTransformation (int eli, double x, double y, - double * p3d, double * jacobian); - -namespace netgen { -#include "../visualization/soldata.hpp" -} - - enum Ng_SolutionType - { NG_SOLUTION_NODAL = 1, - NG_SOLUTION_ELEMENT = 2, - NG_SOLUTION_SURFACE_ELEMENT = 3, - NG_SOLUTION_NONCONTINUOUS = 4, - NG_SOLUTION_SURFACE_NONCONTINUOUS = 5, - NG_SOLUTION_VIRTUAL_FUNCTION = 6, - NG_SOLUTION_MARKED_ELEMENTS = 10, - NG_SOLUTION_ELEMENT_ORDER = 11 - }; - - struct Ng_SolutionData - { - char * name; // name of gridfunction - double * data; // solution values - int components; // relevant (double) components in solution vector - int dist; // # doubles per entry alignment! - int iscomplex; // complex vector ? - bool draw_surface; - bool draw_volume; - int order; // order of elements, only partially supported - Ng_SolutionType soltype; // type of solution function - netgen::SolutionData * solclass; - }; - - // initialize solution data with default arguments - void Ng_InitSolutionData (Ng_SolutionData * soldata); - // set solution data - void Ng_SetSolutionData (Ng_SolutionData * soldata); - /// delete gridfunctions - void Ng_ClearSolutionData(); - // redraw - void Ng_Redraw(); - // - void Ng_SetVisualizationParameter (const char * name, - const char * value); - - - // number of periodic vertices - int Ng_GetNPeriodicVertices (); - // pairs should be an integer array of 2*npairs - void Ng_GetPeriodicVertices (int * pairs); - - // number of periodic edges - int Ng_GetNPeriodicEdges (); - // pairs should be an integer array of 2*npairs - void Ng_GetPeriodicEdges (int * pairs); - - - void Ng_PushStatus (const char * str); - void Ng_PopStatus (); - void Ng_SetThreadPercentage (double percent); - - //// added by Roman Stainko .... - int Ng_GetVertex_Elements( int vnr, int* elems); - int Ng_GetVertex_SurfaceElements( int vnr, int* elems ); - int Ng_GetVertex_NElements( int vnr ); - int Ng_GetVertex_NSurfaceElements( int vnr ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Netgen/libsrc/interface/nglib.cpp b/Netgen/libsrc/interface/nglib.cpp deleted file mode 100644 index d2e59f931e..0000000000 --- a/Netgen/libsrc/interface/nglib.cpp +++ /dev/null @@ -1,573 +0,0 @@ -/**************************************************************************/ -/* File: nglib.cc */ -/* Author: Joachim Schoeberl */ -/* Date: 7. May. 2000 */ -/**************************************************************************/ - -/* - - Interface to the netgen meshing kernel - -*/ - - -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> -#include <stlgeom.hpp> -#include <geometry2d.hpp> -#include <meshing.hpp> - - - -// #include <FlexLexer.h> - -namespace netgen { - extern void MeshFromSpline2D (SplineGeometry2d & geometry, - Mesh *& mesh, - MeshingParameters & mp); -} - - - - - - - -namespace nglib { -#include "nglib.h" -} - -using namespace netgen; - -// constants and types: - -namespace nglib -{ -// initialize, deconstruct Netgen library: -void Ng_Init () -{ - mycout = &cout; - myerr = &cerr; - testout = new ofstream ("test.out"); -} - -void Ng_Exit () -{ - ; -} - - - -Ng_Mesh * Ng_NewMesh () -{ - Mesh * mesh = new Mesh; - mesh->AddFaceDescriptor (FaceDescriptor (1, 1, 0, 1)); - return (Ng_Mesh*)(void*)mesh; -} - -void Ng_DeleteMesh (Ng_Mesh * mesh) -{ - delete (Mesh*)mesh; -} - - -// feeds points, surface elements and volume elements to the mesh -void Ng_AddPoint (Ng_Mesh * mesh, double * x) -{ - Mesh * m = (Mesh*)mesh; - m->AddPoint (Point3d (x[0], x[1], x[2])); -} - -void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et, - int * pi) -{ - Mesh * m = (Mesh*)mesh; - Element2d el (3); - el.SetIndex (1); - el.PNum(1) = pi[0]; - el.PNum(2) = pi[1]; - el.PNum(3) = pi[2]; - m->AddSurfaceElement (el); -} - -void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et, - int * pi) -{ - Mesh * m = (Mesh*)mesh; - Element el (4); - el.SetIndex (1); - el.PNum(1) = pi[0]; - el.PNum(2) = pi[1]; - el.PNum(3) = pi[2]; - el.PNum(4) = pi[3]; - m->AddVolumeElement (el); -} - -// ask for number of points, surface and volume elements -int Ng_GetNP (Ng_Mesh * mesh) -{ - return ((Mesh*)mesh) -> GetNP(); -} - -int Ng_GetNSE (Ng_Mesh * mesh) -{ - return ((Mesh*)mesh) -> GetNSE(); -} - -int Ng_GetNE (Ng_Mesh * mesh) -{ - return ((Mesh*)mesh) -> GetNE(); -} - - -// return point coordinates -void Ng_GetPoint (Ng_Mesh * mesh, int num, double * x) -{ - const Point3d & p = ((Mesh*)mesh)->Point(num); - x[0] = p.X(); - x[1] = p.Y(); - x[2] = p.Z(); -} - -// return surface and volume element in pi -Ng_Surface_Element_Type -Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi) -{ - const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num); - for (int i = 1; i <= el.GetNP(); i++) - pi[i-1] = el.PNum(i); - Ng_Surface_Element_Type et; - switch (el.GetNP()) - { - case 3: et = NG_TRIG; break; - case 4: et = NG_QUAD; break; - case 6: et = NG_TRIG6; break; - } - return et; -} - -Ng_Volume_Element_Type -Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi) -{ - const Element & el = ((Mesh*)mesh)->VolumeElement(num); - for (int i = 1; i <= el.GetNP(); i++) - pi[i-1] = el.PNum(i); - Ng_Volume_Element_Type et; - switch (el.GetNP()) - { - case 4: et = NG_TET; break; - case 5: et = NG_PYRAMID; break; - case 6: et = NG_PRISM; break; - case 10: et = NG_TET10; break; - } - return et; -} - - - -// generates volume mesh from surface mesh -Ng_Result Ng_GenerateVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp) -{ - Mesh * m = (Mesh*)mesh; - - - MeshingParameters mparam; - mparam.maxh = mp->maxh; - mparam.meshsizefilename = mp->meshsize_filename; - - m->CalcLocalH(); - - MeshVolume (mparam, *m); - RemoveIllegalElements (*m); - OptimizeVolume (mparam, *m); - - return NG_OK; -} - - - -// 2D Meshing Functions: - - - -void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x) -{ - Mesh * m = (Mesh*)mesh; - - m->AddPoint (Point3d (x[0], x[1], 0)); -} - -void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2) -{ - Mesh * m = (Mesh*)mesh; - - Segment seg; - seg.p1 = pi1; - seg.p2 = pi2; - m->AddSegment (seg); -} - - -int Ng_GetNP_2D (Ng_Mesh * mesh) -{ - Mesh * m = (Mesh*)mesh; - return m->GetNP(); -} - -int Ng_GetNE_2D (Ng_Mesh * mesh) -{ - Mesh * m = (Mesh*)mesh; - return m->GetNSE(); -} - -int Ng_GetNSeg_2D (Ng_Mesh * mesh) -{ - Mesh * m = (Mesh*)mesh; - return m->GetNSeg(); -} - -void Ng_GetPoint_2D (Ng_Mesh * mesh, int num, double * x) -{ - Mesh * m = (Mesh*)mesh; - - Point3d & p = m->Point(num); - x[0] = p.X(); - x[1] = p.Y(); -} - -void Ng_GetElement_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum) -{ - const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num); - for (int i = 1; i <= 3; i++) - pi[i-1] = el.PNum(i); - if (matnum) - *matnum = el.GetIndex(); -} - - -void Ng_GetSegment_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum) -{ - const Segment & seg = ((Mesh*)mesh)->LineSegment(num); - pi[0] = seg.p1; - pi[1] = seg.p2; - - if (matnum) - *matnum = seg.edgenr; -} - - - - -Ng_Geometry_2D * Ng_LoadGeometry_2D (const char * filename) -{ - SplineGeometry2d * geom = new SplineGeometry2d(); - geom -> Load (filename); - return (Ng_Geometry_2D *)geom; -} - -Ng_Result Ng_GenerateMesh_2D (Ng_Geometry_2D * geom, - Ng_Mesh ** mesh, - Ng_Meshing_Parameters * mp) -{ - // use global variable mparam - // MeshingParameters mparam; - mparam.maxh = mp->maxh; - mparam.meshsizefilename = mp->meshsize_filename; - mparam.quad = mp->quad_dominated; - - Mesh * m; - MeshFromSpline2D (*(SplineGeometry2d*)geom, m, mparam); - - cout << m->GetNSE() << " elements, " << m->GetNP() << " points" << endl; - - *mesh = (Ng_Mesh*)m; - return NG_OK; -} - - - -void Ng_HP_Refinement (Ng_Geometry_2D * geom, - Ng_Mesh * mesh, - int levels) -{ - Refinement2d ref(*(SplineGeometry2d*)geom); - HPRefinement (*(Mesh*)mesh, &ref, levels); -} - - - - - - - - - - - - - -ARRAY<STLReadTriangle> readtrias; //only before initstlgeometry -ARRAY<Point<3> > readedges; //only before init stlgeometry - -void Ng_SaveMesh(Ng_Mesh * mesh, const char* filename) -{ - ((Mesh*)mesh)->Save(filename); -} - -Ng_Mesh * Ng_LoadMesh(const char* filename) -{ - Mesh * mesh = new Mesh; - mesh->Load(filename); - return ( (Ng_Mesh*)mesh ); -} - -// loads geometry from STL file -Ng_STL_Geometry * Ng_STL_LoadGeometry (const char * filename, int binary) -{ - int i; - STLGeometry geom; - STLGeometry* geo; - ifstream ist(filename); - - if (binary) - { - geo = geom.LoadBinary(ist); - } - else - { - geo = geom.Load(ist); - } - - readtrias.SetSize(0); - readedges.SetSize(0); - - Point3d p; - Vec3d normal; - double p1[3]; - double p2[3]; - double p3[3]; - double n[3]; - - Ng_STL_Geometry * geo2 = Ng_STL_NewGeometry(); - - for (i = 1; i <= geo->GetNT(); i++) - { - const STLTriangle& t = geo->GetTriangle(i); - p = geo->GetPoint(t.PNum(1)); - p1[0] = p.X(); p1[1] = p.Y(); p1[2] = p.Z(); - p = geo->GetPoint(t.PNum(2)); - p2[0] = p.X(); p2[1] = p.Y(); p2[2] = p.Z(); - p = geo->GetPoint(t.PNum(3)); - p3[0] = p.X(); p3[1] = p.Y(); p3[2] = p.Z(); - normal = t.Normal(); - n[0] = normal.X(); n[1] = normal.Y(); n[2] = normal.Z(); - - Ng_STL_AddTriangle(geo2, p1, p2, p3, n); - } - - return geo2; -} - -// generate new STL Geometry -Ng_STL_Geometry * Ng_STL_NewGeometry () -{ - return (Ng_STL_Geometry*)(void*)new STLGeometry; -} - -// after adding triangles (and edges) initialize -Ng_Result Ng_STL_InitSTLGeometry (Ng_STL_Geometry * geom) -{ - STLGeometry* geo = (STLGeometry*)geom; - geo->InitSTLGeometry(readtrias); - readtrias.SetSize(0); - - if (readedges.Size() != 0) - { - int i; - /* - for (i = 1; i <= readedges.Size(); i+=2) - { - cout << "e(" << readedges.Get(i) << "," << readedges.Get(i+1) << ")" << endl; - } - */ - geo->AddEdges(readedges); - } - - if (geo->GetStatus() == STLTopology::STL_GOOD || geo->GetStatus() == STLTopology::STL_WARNING) return NG_OK; - return NG_SURFACE_INPUT_ERROR; -} - - // automatically generates edges: -Ng_Result Ng_STL_MakeEdges (Ng_STL_Geometry * geom, - Ng_Mesh* mesh, - Ng_Meshing_Parameters * mp) -{ - STLGeometry* stlgeometry = (STLGeometry*)geom; - Mesh* me = (Mesh*)mesh; - - MeshingParameters mparam; - - mparam.maxh = mp->maxh; - mparam.meshsizefilename = mp->meshsize_filename; - - me -> SetGlobalH (mparam.maxh); - me -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), - stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), - 0.3); - - me -> LoadLocalMeshSize (mp->meshsize_filename); - /* - if (mp->meshsize_filename) - { - ifstream infile (mp->meshsize_filename); - if (!infile.good()) return NG_FILE_NOT_FOUND; - me -> LoadLocalMeshSize (infile); - } - */ - - STLMeshing (*stlgeometry, *me); - - stlgeometry->edgesfound = 1; - stlgeometry->surfacemeshed = 0; - stlgeometry->surfaceoptimized = 0; - stlgeometry->volumemeshed = 0; - - return NG_OK; -} - - -// generates mesh, empty mesh be already created. -Ng_Result Ng_STL_GenerateSurfaceMesh (Ng_STL_Geometry * geom, - Ng_Mesh* mesh, - Ng_Meshing_Parameters * mp) -{ - STLGeometry* stlgeometry = (STLGeometry*)geom; - Mesh* me = (Mesh*)mesh; - - MeshingParameters mparam; - - mparam.maxh = mp->maxh; - mparam.meshsizefilename = mp->meshsize_filename; - - /* - me -> SetGlobalH (mparam.maxh); - me -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), - stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), - 0.3); - */ - /* - STLMeshing (*stlgeometry, *me); - - stlgeometry->edgesfound = 1; - stlgeometry->surfacemeshed = 0; - stlgeometry->surfaceoptimized = 0; - stlgeometry->volumemeshed = 0; - */ - int retval = STLSurfaceMeshing (*stlgeometry, *me); - if (retval == MESHING3_OK) - { - (*mycout) << "Success !!!!" << endl; - stlgeometry->surfacemeshed = 1; - stlgeometry->surfaceoptimized = 0; - stlgeometry->volumemeshed = 0; - } - else if (retval == MESHING3_OUTERSTEPSEXCEEDED) - { - (*mycout) << "ERROR: Give up because of too many trials. Meshing aborted!" << endl; - } - else if (retval == MESHING3_TERMINATE) - { - (*mycout) << "Meshing Stopped!" << endl; - } - else - { - (*mycout) << "ERROR: Surface meshing not successful. Meshing aborted!" << endl; - } - - - STLSurfaceOptimization (*stlgeometry, *me, mparam); - - return NG_OK; -} - - - // fills STL Geometry - // positive orientation - // normal vector may be null-pointer -void Ng_STL_AddTriangle (Ng_STL_Geometry * geom, - double * p1, double * p2, double * p3, double * nv) -{ - Point<3> apts[3]; - apts[0] = Point<3>(p1[0],p1[1],p1[2]); - apts[1] = Point<3>(p2[0],p2[1],p2[2]); - apts[2] = Point<3>(p3[0],p3[1],p3[2]); - - Vec<3> n; - if (!nv) - n = Cross (apts[0]-apts[1], apts[0]-apts[2]); - else - n = Vec<3>(nv[0],nv[1],nv[2]); - - readtrias.Append(STLReadTriangle(apts,n)); -} - - // add (optional) edges: -void Ng_STL_AddEdge (Ng_STL_Geometry * geom, - double * p1, double * p2) -{ - readedges.Append(Point3d(p1[0],p1[1],p1[2])); - readedges.Append(Point3d(p2[0],p2[1],p2[2])); -} - - - -Ng_Meshing_Parameters :: Ng_Meshing_Parameters() -{ - maxh = 1000; - fineness = 0.5; - secondorder = 0; - meshsize_filename = 0; - quad_dominated = 0; -} - - -} - - -// compatibility functions: - -namespace netgen -{ - - char geomfilename[255]; - -void MyError (const char * ch) -{ - cerr << ch; -} - -//Destination for messages, errors, ... -void Ng_PrintDest(const char * s) -{ - (*mycout) << s << flush; -} - -double GetTime () -{ - return 0; -} - -void ResetTime () -{ - ; -} - -void MyBeep (int i) -{ - ; -} - -} diff --git a/Netgen/libsrc/interface/nglib.h b/Netgen/libsrc/interface/nglib.h deleted file mode 100644 index 20d745d470..0000000000 --- a/Netgen/libsrc/interface/nglib.h +++ /dev/null @@ -1,208 +0,0 @@ -#ifndef NGLIB -#define NGLIB - -/**************************************************************************/ -/* File: nglib.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 7. May. 2000 */ -/**************************************************************************/ - -/* - - Interface to the netgen meshing kernel - -*/ - -/// Data type for NETGEN mesh -typedef void * Ng_Mesh; - -/// Data type for NETGEN CSG geomty -typedef void * Ng_CSG_Geometry; - -/// Data type for NETGEN 2D geomty -typedef void * Ng_Geometry_2D; - -/// Data type for NETGEN STL geomty -typedef void * Ng_STL_Geometry; - - - -// max number of nodes per element -#define NG_VOLUME_ELEMENT_MAXPOINTS 10 - -// implemented element types: -enum Ng_Volume_Element_Type { NG_TET = 1, NG_PYRAMID = 2, NG_PRISM = 3, - NG_TET10 = 4 }; - -// max number of nodes per surface element -#define NG_SURFACE_ELEMENT_MAXPOINTS 6 - -// implemented element types: -enum Ng_Surface_Element_Type { NG_TRIG = 1, NG_QUAD = 2, - NG_TRIG6 = 3 }; - - - -class Ng_Meshing_Parameters -{ - public: - - double maxh; - double fineness; // 0 .. coarse, 1 .. fine - int secondorder; - char * meshsize_filename; - int quad_dominated; - - Ng_Meshing_Parameters(); -}; - - -enum Ng_Result { NG_OK = 0, - NG_SURFACE_INPUT_ERROR = 1, - NG_VOLUME_FAILURE = 2, - NG_STL_INPUT_ERROR = 3, - NG_SURFACE_FAILURE = 4, - NG_FILE_NOT_FOUND = 5 }; - - - - - -// #ifdef __cplusplus -// extern "C" -// { -// #endif - - // initialize, deconstruct Netgen library: - void Ng_Init (); - void Ng_Exit (); - - - // Generates new mesh structure - Ng_Mesh * Ng_NewMesh (); - void Ng_DeleteMesh (Ng_Mesh * mesh); - - // feeds points, surface elements and volume elements to the mesh - void Ng_AddPoint (Ng_Mesh * mesh, double * x); - void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et, - int * pi); - void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et, - int * pi); - - // ask for number of points, surface and volume elements - int Ng_GetNP (Ng_Mesh * mesh); - int Ng_GetNSE (Ng_Mesh * mesh); - int Ng_GetNE (Ng_Mesh * mesh); - - - // return point coordinates - void Ng_GetPoint (Ng_Mesh * mesh, int num, double * x); - - // return surface and volume element in pi - Ng_Surface_Element_Type - Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi); - - Ng_Volume_Element_Type - Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi); - - - // Defines MeshSize Functions - void Ng_RestrictMeshSizeGlobal (Ng_Mesh * mesh, double h); - void Ng_RestrictMeshSizePoint (Ng_Mesh * mesh, double * p, double h); - void Ng_RestrictMeshSizeBox (Ng_Mesh * mesh, double * pmin, double * pmax, double h); - - // generates volume mesh from surface mesh - Ng_Result Ng_GenerateVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp); - - void Ng_SaveMesh(Ng_Mesh * mesh, const char* filename); - Ng_Mesh * Ng_LoadMesh(const char* filename); - - - - - - // ********************************************************** - // ** 2D Meshing ** - // ********************************************************** - - - // feeds points and boundary to mesh - - void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x); - void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2); - - // ask for number of points, elements and boundary segments - int Ng_GetNP_2D (Ng_Mesh * mesh); - int Ng_GetNE_2D (Ng_Mesh * mesh); - int Ng_GetNSeg_2D (Ng_Mesh * mesh); - - // return point coordinates - void Ng_GetPoint_2D (Ng_Mesh * mesh, int num, double * x); - - // return 2d triangles - void Ng_GetElement_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum = NULL); - - // return 2d boundary segment - void Ng_GetSegment_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum = NULL); - - - // load 2d netgen spline geometry - Ng_Geometry_2D * Ng_LoadGeometry_2D (const char * filename); - - // generate 2d mesh, mesh is allocated by function - Ng_Result Ng_GenerateMesh_2D (Ng_Geometry_2D * geom, - Ng_Mesh ** mesh, - Ng_Meshing_Parameters * mp); - - void Ng_HP_Refinement (Ng_Geometry_2D * geom, - Ng_Mesh * mesh, - int levels); - - - - - - // ********************************************************** - // ** STL Meshing ** - // ********************************************************** - - - // loads geometry from STL file - Ng_STL_Geometry * Ng_STL_LoadGeometry (const char * filename, int binary = 0); - - - // generate new STL Geometry - Ng_STL_Geometry * Ng_STL_NewGeometry (); - - - // fills STL Geometry - // positive orientation - // normal vector may be null-pointer - void Ng_STL_AddTriangle (Ng_STL_Geometry * geom, - double * p1, double * p2, double * p3, - double * nv = NULL); - - // add (optional) edges : - void Ng_STL_AddEdge (Ng_STL_Geometry * geom, - double * p1, double * p2); - - // after adding triangles (and edges) initialize - Ng_Result Ng_STL_InitSTLGeometry (Ng_STL_Geometry * geom); - - // automatically generates edges: - Ng_Result Ng_STL_MakeEdges (Ng_STL_Geometry * geom, - Ng_Mesh* mesh, - Ng_Meshing_Parameters * mp); - - - // generates mesh, empty mesh must be already created. - Ng_Result Ng_STL_GenerateSurfaceMesh (Ng_STL_Geometry * geom, - Ng_Mesh * mesh, - Ng_Meshing_Parameters * mp); - -// #ifdef __cplusplus -// } -// #endif - - -#endif diff --git a/Netgen/libsrc/interface/printdest.cpp b/Netgen/libsrc/interface/printdest.cpp deleted file mode 100644 index 0db654d94f..0000000000 --- a/Netgen/libsrc/interface/printdest.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -namespace netgen -{ - //Destination for messages, errors, ... - void Ng_PrintDest(const char * s) - { - (*mycout) << s << flush; - } -} diff --git a/Netgen/libsrc/interface/readuser.cpp b/Netgen/libsrc/interface/readuser.cpp deleted file mode 100644 index f7d4d1eae8..0000000000 --- a/Netgen/libsrc/interface/readuser.cpp +++ /dev/null @@ -1,394 +0,0 @@ -// -// Read user dependent output file -// - - -#include <mystdlib.h> - - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "writeuser.hpp" - -void ReadFile (Mesh & mesh, - const string & hfilename) -{ - cout << "Read User File" << endl; - - const char * filename = hfilename.c_str(); - - int i, j; - - char reco[100]; - int np, nbe; - - - - // ".surf" - mesh - - if ( (strlen (filename) > 5) && - strcmp (&filename[strlen (filename)-5], ".surf") == 0 ) - - { - cout << "Surface file" << endl; - - ifstream in (filename); - - in >> reco; - in >> np; - for (i = 1; i <= np; i++) - { - Point3d p; - in >> p.X() >> p.Y() >> p.Z(); - mesh.AddPoint (p); - } - - - in >> nbe; - // int invert = globflags.GetDefineFlag ("invertsurfacemesh"); - for (i = 1; i <= nbe; i++) - { - Element2d el; - int hi; - - el.SetIndex(1); - - for (j = 1; j <= 3; j++) - { - in >> el.PNum(j); - if (el.PNum(j) < PointIndex(1) || - el.PNum(j) > PointIndex(np)) - { - cerr << "Point Number " << el.PNum(j) << " out of range 1..." - << np << endl; - return; - } - } - - /* - if (invert) - swap (el.PNum(2), el.PNum(3)); - */ - - mesh.AddSurfaceElement (el); - } - - mesh.ClearFaceDescriptors(); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - - cout << "points: " << np << " faces: " << nbe << endl; - } - - - - - - // Universal mesh (AVL) - if ( (strlen (filename) > 4) && - strcmp (&filename[strlen (filename)-4], ".unv") == 0 ) - { - int i, j, k; - - double h; - char reco[100]; - int np, nbe; - int invert; - - - ifstream in(filename); - - invert = 0; // globflags.GetDefineFlag ("invertsurfacemesh"); - double scale = 1; // globflags.GetNumFlag ("scale", 1); - - - while (in.good()) - { - in >> reco; - if (strcmp (reco, "NODES") == 0) - { - cout << "nodes found" << endl; - for (j = 1; j <= 4; j++) - in >> reco; // read dummy - - while (1) - { - int pi, hi; - double x, y, z; - Point3d p; - - in >> pi; - if (pi == -1) - break; - - in >> hi >> hi >> hi; - in >> p.X() >> p.Y() >> p.Z(); - - p.X() *= scale; - p.Y() *= scale; - p.Z() *= scale; - - - mesh.AddPoint (p); - } - } - - if (strcmp (reco, "ELEMENTS") == 0) - { - cout << "elements found" << endl; - for (j = 1; j <= 4; j++) - in >> reco; // read dummy - - while (1) - { - int hi; - in >> hi; - if (hi == -1) break; - for (j = 1; j <= 7; j++) - in >> hi; - - Element2d el; - el.SetIndex(1); - in >> el.PNum(1) >> el.PNum(2) >> el.PNum(3); - - if (invert) - swap (el.PNum(2), el.PNum(3)); - mesh.AddSurfaceElement (el); - - for (j = 1; j <= 5; j++) - in >> hi; - } - } - } - - mesh.ClearFaceDescriptors(); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - - Point3d pmin, pmax; - mesh.GetBox (pmin, pmax); - cout << "bounding-box = " << pmin << "-" << pmax << endl; - } - - - - // fepp format2d: - - if ( (strlen (filename) > 7) && - strcmp (&filename[strlen (filename)-7], ".mesh2d") == 0 ) - { - cout << "Reading FEPP2D Mesh" << endl; - - char buf[100]; - int np, ne, nseg, i, j; - - ifstream in (filename); - - in >> buf; - - in >> nseg; - for (i = 1; i <= nseg; i++) - { - int bound, p1, p2; - in >> bound >> p1 >> p2; - // forget them - } - - in >> ne; - for (i = 1; i <= ne; i++) - { - int mat, nelp; - in >> mat >> nelp; - Element2d el (nelp == 3 ? TRIG : QUAD); - el.SetIndex (mat); - for (j = 1; j <= nelp; j++) - in >> el.PNum(j); - mesh.AddSurfaceElement (el); - } - - in >> np; - for (i = 1; i <= np; i++) - { - Point3d p(0,0,0); - in >> p.X() >> p.Y(); - mesh.AddPoint (p); - } - } - - - else if ( (strlen (filename) > 5) && - strcmp (&filename[strlen (filename)-5], ".mesh") == 0 ) - { - cout << "Reading Neutral Format" << endl; - - int np, ne, nse, i, j; - - ifstream in (filename); - - in >> np; - - if (in.good()) - { - // file starts with an integer - - for (i = 1; i <= np; i++) - { - Point3d p(0,0,0); - in >> p.X() >> p.Y() >> p.Z(); - mesh.AddPoint (p); - } - - in >> ne; - for (i = 1; i <= ne; i++) - { - int mat; - in >> mat; - Element el (4); - el.SetIndex (mat); - for (j = 1; j <= 4; j++) - in >> el.PNum(j); - mesh.AddVolumeElement (el); - } - - in >> nse; - for (i = 1; i <= nse; i++) - { - int mat, nelp; - in >> mat; - Element2d el (TRIG); - el.SetIndex (mat); - for (j = 1; j <= 3; j++) - in >> el.PNum(j); - mesh.AddSurfaceElement (el); - } - } - else - { - char buf[100]; - in.clear(); - do - { - in >> buf; - cout << "buf = " << buf << endl; - if (strcmp (buf, "points") == 0) - { - in >> np; - cout << "np = " << np << endl; - } - } - while (in.good()); - } - } - - - if ( (strlen (filename) > 4) && - strcmp (&filename[strlen (filename)-4], ".emt") == 0 ) - { - ifstream inemt (filename); - - string pktfile = filename; - int len = strlen (filename); - pktfile[len-3] = 'p'; - pktfile[len-2] = 'k'; - pktfile[len-1] = 't'; - cout << "pktfile = " << pktfile << endl; - - int np, nse, i; - int num, bcprop; - ifstream inpkt (pktfile.c_str()); - inpkt >> np; - ARRAY<double> values(np); - for (i = 1; i <= np; i++) - { - Point3d p(0,0,0); - inpkt >> p.X() >> p.Y() >> p.Z() - >> bcprop >> values.Elem(i); - mesh.AddPoint (p); - } - - mesh.ClearFaceDescriptors(); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - mesh.GetFaceDescriptor(1).SetBCProperty (1); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - mesh.GetFaceDescriptor(2).SetBCProperty (2); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - mesh.GetFaceDescriptor(3).SetBCProperty (3); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - mesh.GetFaceDescriptor(4).SetBCProperty (4); - mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); - mesh.GetFaceDescriptor(5).SetBCProperty (5); - - int p1, p2, p3; - double value; - inemt >> nse; - for (i = 1; i <= nse; i++) - { - inemt >> p1 >> p2 >> p3 >> bcprop >> value; - - if (bcprop < 1 || bcprop > 4) - cerr << "bcprop out of range, bcprop = " << bcprop << endl; - p1++; - p2++; - p3++; - if (p1 < 1 || p1 > np || p2 < 1 || p2 > np || p3 < 1 || p3 > np) - { - cout << "p1 = " << p1 << " p2 = " << p2 << " p3 = " << p3 << endl; - } - - if (i > 110354) Swap (p2, p3); - if (mesh.Point(p1).X() < 0.25) - Swap (p2,p3); - - Element2d el(TRIG); - - if (bcprop == 1) - { - if (values.Get(p1) < -69999) - el.SetIndex(1); - else - el.SetIndex(2); - } - else - el.SetIndex(3); - - - el.PNum(1) = p1; - el.PNum(2) = p2; - el.PNum(3) = p3; - mesh.AddSurfaceElement (el); - } - - - ifstream incyl ("ngusers/guenter/cylinder.surf"); - int npcyl, nsecyl; - incyl >> npcyl; - cout << "npcyl = " << npcyl << endl; - for (i = 1; i <= npcyl; i++) - { - Point3d p(0,0,0); - incyl >> p.X() >> p.Y() >> p.Z(); - mesh.AddPoint (p); - } - incyl >> nsecyl; - cout << "nsecyl = " << nsecyl << endl; - for (i = 1; i <= nsecyl; i++) - { - incyl >> p1 >> p2 >> p3; - p1 += np; - p2 += np; - p3 += np; - Element2d el(TRIG); - el.SetIndex(5); - el.PNum(1) = p1; - el.PNum(2) = p2; - el.PNum(3) = p3; - mesh.AddSurfaceElement (el); - } - } - -} - -} diff --git a/Netgen/libsrc/interface/writeabaqus.cpp b/Netgen/libsrc/interface/writeabaqus.cpp deleted file mode 100644 index e9308b1472..0000000000 --- a/Netgen/libsrc/interface/writeabaqus.cpp +++ /dev/null @@ -1,237 +0,0 @@ -// -// Write Abaqus file -// -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "writeuser.hpp" - - - - -void WriteAbaqusFormat (const Mesh & mesh, - const string & filename) - -{ - - cout << "\nWrite Abaqus Volume Mesh" << endl; - - ofstream outfile (filename.c_str()); - - outfile << "*Heading" << endl; - outfile << " " << filename << endl; - - outfile.precision(8); - - outfile << "*Node" << endl; - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int i, j, k; - - for (i = 1; i <= np; i++) - { - outfile << i << ", "; - outfile << mesh.Point(i).X() << ", "; - outfile << mesh.Point(i).Y() << ", "; - outfile << mesh.Point(i).Z() << "\n"; - } - - int elemcnt = 0; //element counter - int finished = 0; - int indcnt = 1; //index counter - - while (!finished) - { - int actcnt = 0; - const Element & el1 = mesh.VolumeElement(1); - int non = el1.GetNP(); - if (non == 4) - { - outfile << "*Element, type=C3D4, ELSET=PART" << indcnt << endl; - } - else if (non == 10) - { - outfile << "*Element, type=C3D10, ELSET=PART" << indcnt << endl; - } - else - { - cout << "unsupported Element type!!!" << endl; - } - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - - if (el.GetIndex() == indcnt) - { - actcnt++; - if (el.GetNP() != non) - { - cout << "different element-types in a subdomain are not possible!!!" << endl; - continue; - } - - elemcnt++; - outfile << elemcnt << ", "; - if (non == 4) - { - outfile << el.PNum(1) << ", "; - outfile << el.PNum(2) << ", "; - outfile << el.PNum(4) << ", "; - outfile << el.PNum(3) << "\n"; - } - else if (non == 10) - { - outfile << el.PNum(1) << ", "; - outfile << el.PNum(2) << ", "; - outfile << el.PNum(4) << ", "; - outfile << el.PNum(3) << ", "; - outfile << el.PNum(5) << ", "; - outfile << el.PNum(9) << ", "; - outfile << el.PNum(7) << ", " << "\n"; - outfile << el.PNum(6) << ", "; - outfile << el.PNum(8) << ", "; - outfile << el.PNum(10) << "\n"; - } - else - { - cout << "unsupported Element type!!!" << endl; - for (j = 1; j <= el.GetNP(); j++) - { - outfile << el.PNum(j); - if (j != el.GetNP()) outfile << ", "; - } - outfile << "\n"; - } - } - } - indcnt++; - if (elemcnt == ne) {finished = 1; cout << "all elements found by Index!" << endl;} - if (actcnt == 0) {finished = 1;} - } - - if (mesh.GetIdentifications().GetMaxNr()) - { - // periodic identification, implementation for - // Helmut J. Boehm, TU Vienna - - char cfilename[255]; - strcpy (cfilename, filename.c_str()); - - char mpcfilename[255]; - strcpy (mpcfilename, cfilename); - int len = strlen (cfilename); - if (len >= 4 && (strcmp (mpcfilename+len-4, ".inp") == 0)) - strcpy (mpcfilename+len-4, ".mpc"); - else - strcat (mpcfilename, ".mpc"); - - ofstream mpc (mpcfilename); - - int masternode; - - ARRAY<INDEX_2> pairs; - BitArray master(np), help(np); - master.Set(); - for (i = 1; i <= 3; i++) - { - mesh.GetIdentifications().GetPairs (i, pairs); - help.Clear(); - for (j = 1; j <= pairs.Size(); j++) - { - help.Set (pairs.Get(j).I1()); - } - master.And (help); - } - for (i = 1; i <= np; i++) - if (master.Test(i)) - masternode = i; - - cout << "masternode = " << masternode << " = " - << mesh.Point(masternode) << endl; - ARRAY<int> slaves(3); - for (i = 1; i <= 3; i++) - { - mesh.GetIdentifications().GetPairs (i, pairs); - for (j = 1; j <= pairs.Size(); j++) - { - if (pairs.Get(j).I1() == masternode) - slaves.Elem(i) = pairs.Get(j).I2(); - } - cout << "slave(" << i << ") = " << slaves.Get(i) - << " = " << mesh.Point(slaves.Get(i)) << endl; - } - - - outfile << "**\n" - << "*NSET,NSET=CTENODS\n" - << slaves.Get(1) << ", " - << slaves.Get(2) << ", " - << slaves.Get(3) << endl; - - - outfile << "**\n" - << "**POINT_fixed\n" - << "**\n" - << "*BOUNDARY, OP=NEW\n"; - for (j = 1; j <= 3; j++) - outfile << masternode << ", " << j << ",, 0.\n"; - - outfile << "**\n" - << "*BOUNDARY, OP=NEW\n"; - for (j = 1; j <= 3; j++) - { - Vec3d v(mesh.Point(masternode), mesh.Point(slaves.Get(j))); - double vlen = v.Length(); - int dir = 0; - if (fabs (v.X()) > 0.9 * vlen) dir = 2; - if (fabs (v.Y()) > 0.9 * vlen) dir = 3; - if (fabs (v.Z()) > 0.9 * vlen) dir = 1; - if (!dir) - cout << "ERROR: Problem with rigid body constraints" << endl; - outfile << slaves.Get(j) << ", " << dir << ",, 0.\n"; - } - - outfile << "**\n" - << "*EQUATION, INPUT=" << mpcfilename << endl; - - - BitArray eliminated(np); - eliminated.Clear(); - for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) - { - mesh.GetIdentifications().GetPairs (i, pairs); - if (!pairs.Size()) - continue; - - for (j = 1; j <= pairs.Size(); j++) - if (pairs.Get(j).I1() != masternode && - !eliminated.Test(pairs.Get(j).I2())) - { - eliminated.Set (pairs.Get(j).I2()); - for (k = 1; k <= 3; k++) - { - mpc << "4" << "\n"; - mpc << pairs.Get(j).I2() << "," << k << ", -1.0, "; - mpc << pairs.Get(j).I1() << "," << k << ", 1.0, "; - mpc << slaves.Get(i) << "," << k << ", 1.0, "; - mpc << masternode << "," << k << ", -1.0 \n"; - } - } - } - } - - - cout << "done" << endl; -} - -} diff --git a/Netgen/libsrc/interface/writediffpack.cpp b/Netgen/libsrc/interface/writediffpack.cpp deleted file mode 100644 index 25f9b2986f..0000000000 --- a/Netgen/libsrc/interface/writediffpack.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// -// Write diffpack file -// -// by -// Bartosz Sawicki <sawickib@ee.pw.edu.pl> -// extended by -// Jacques Lechelle <jacques.lechelle@wanadoo.fr> -// -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - - -namespace netgen -{ -#include "writeuser.hpp" - - -void WriteDiffPackFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - // double scale = globflags.GetNumFlag ("scale", 1); - double scale = 1; - - ofstream outfile(filename.c_str()); - - if (mesh.GetDimension() == 3) - - { - // Output compatible to Diffpack grid format - // Bartosz Sawicki <sawickib@ee.pw.edu.pl> - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - ARRAY <int> BIname; - ARRAY <int> BCsinpoint; - int i, j, k, l; - - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - const Element & eldummy = mesh.VolumeElement((int)1); - outfile << "\n\n" - "Finite element mesh (GridFE):\n\n" - " Number of space dim. = 3\n" - " Number of elements = " << ne << "\n" - " Number of nodes = " << np << "\n\n" - " All elements are of the same type : dpTRUE\n" - " Max number of nodes in an element: "<< eldummy.GetNP() << "\n" - " Only one subdomain : dpFALSE\n" - " Lattice data ? 0\n\n\n\n"; - - for (i = 1; i <= nse; i++) - { - int BI=mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex()).BCProperty(); - int nbi=BIname.Size(); - int found=0; - for (j = 1; j <= nbi; j++) - if(BI == BIname.Get(j)) found = 1; - if( ! found ) BIname.Append(BI); - } - - outfile << " " << BIname.Size() << " Boundary indicators: "; - for (i =1 ; i <= BIname.Size(); i++) - outfile << BIname.Get(i) << " "; - outfile << "\n\n\n"; - - outfile << " Nodal coordinates and nodal boundary indicators,\n" - " the columns contain:\n" - " - node number\n" - " - coordinates\n" - " - no of boundary indicators that are set (ON)\n" - " - the boundary indicators that are set (ON) if any.\n" - "#\n"; - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - - outfile.width(4); - outfile << i << " ("; - outfile.width(10); - outfile << p.X()/scale << ", "; - outfile.width(9); - outfile << p.Y()/scale << ", "; - outfile.width(9); - outfile << p.Z()/scale << ") "; - - if(mesh.PointType(i) != INNERPOINT) - { - BCsinpoint.DeleteAll(); - for (j = 1; j <= nse; j++) - { - for (k = 1; k <= mesh.SurfaceElement(j).GetNP(); k++) - { - if(mesh.SurfaceElement(j).PNum(k)==i) - { - int BC=mesh.GetFaceDescriptor(mesh.SurfaceElement(j).GetIndex()).BCProperty(); - int nbcsp=BCsinpoint.Size(); - int found = 0; - for (l = 1; l <= nbcsp; l++) - if(BC == BCsinpoint.Get(l)) found = 1; - if( ! found ) BCsinpoint.Append(BC); - } - } - } - int nbcsp = BCsinpoint.Size(); - outfile << "[" << nbcsp << "] "; - for (j = 1; j <= nbcsp; j++) - outfile << BCsinpoint.Get(j) << " "; - outfile << "\n"; - } - else outfile << "[0]\n"; - - } - - outfile << "\n" - " Element types and connectivity\n" - " the columns contain:\n" - " - element number\n" - " - element type\n" - " - subdomain number\n" - " - the global node numbers of the nodes in the element.\n" - "#\n"; - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - outfile.width(5); - if(el.GetNP()==4) - outfile << i << " ElmT4n3D "; - else - outfile << i << " ElmT10n3D "; - outfile.width(4); - outfile << el.GetIndex() << " "; - if(el.GetNP()==10) - { - outfile.width(8); - outfile << el.PNum(1); - outfile.width(8); - outfile << el.PNum(3); - outfile.width(8); - outfile << el.PNum(2); - outfile.width(8); - outfile << el.PNum(4); - outfile.width(8); - outfile << el.PNum(6); - outfile.width(8); - outfile << el.PNum(8); - outfile.width(8); - outfile << el.PNum(5); - outfile.width(8); - outfile << el.PNum(7); - outfile.width(8); - outfile << el.PNum(10); - outfile.width(8); - outfile << el.PNum(9); - } - else - { - outfile.width(8); - outfile << el.PNum(1); - outfile.width(8); - outfile << el.PNum(3); - outfile.width(8); - outfile << el.PNum(2); - outfile.width(8); - outfile << el.PNum(4); - } - outfile << "\n"; - } - } /* Diffpack */ - - else - - { - // Output compatible to Diffpack grid format 2D - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - ARRAY <int> BIname; - ARRAY <int> BCsinpoint; - int i, j, k, l; - - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - outfile << "\n\n" - "Finite element mesh (GridFE):\n\n" - " Number of space dim. = 2\n" - " Number of elements = " << nse << "\n" - " Number of nodes = " << np << "\n\n" - " All elements are of the same type : dpTRUE\n" - " Max number of nodes in an element: 3\n" - " Only one subdomain : dpFALSE\n" - " Lattice data ? 0\n\n\n\n"; - - for (i = 1; i <= nse; i++) - { - int BI=mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex()).BCProperty(); - int nbi=BIname.Size(); - int found=0; - for (j = 1; j <= nbi; j++) - if(BI == BIname.Get(j)) found = 1; - if( ! found ) BIname.Append(BI); - } - - outfile << " " << BIname.Size() << " Boundary indicators: "; - for (i =1 ; i <= BIname.Size(); i++) - outfile << BIname.Get(i) << " "; - outfile << "\n\n\n"; - - outfile << " Nodal coordinates and nodal boundary indicators,\n" - " the columns contain:\n" - " - node number\n" - " - coordinates\n" - " - no of boundary indicators that are set (ON)\n" - " - the boundary indicators that are set (ON) if any.\n" - "#\n"; - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - - outfile.width(4); - outfile << i << " ("; - outfile.width(10); - outfile << p.X()/scale << ", "; - outfile.width(9); - outfile << p.Y()/scale << ", "; - - if(mesh.PointType(i) != INNERPOINT) - { - BCsinpoint.DeleteAll(); - for (j = 1; j <= nse; j++) - { - for (k = 1; k <= 2; k++) - { - if(mesh.SurfaceElement(j).PNum(k)==i) - { - int BC=mesh.GetFaceDescriptor(mesh.SurfaceElement(j).GetIndex()).BCProperty(); - int nbcsp=BCsinpoint.Size(); - int found = 0; - for (l = 1; l <= nbcsp; l++) - if(BC == BCsinpoint.Get(l)) found = 1; - if( ! found ) BCsinpoint.Append(BC); - } - } - } - int nbcsp = BCsinpoint.Size(); - outfile << "[" << nbcsp << "] "; - for (j = 1; j <= nbcsp; j++) - outfile << BCsinpoint.Get(j) << " "; - outfile << "\n"; - } - else outfile << "[0]\n"; - - } - - outfile << "\n" - " Element types and connectivity\n" - " the columns contain:\n" - " - element number\n" - " - element type\n" - " - subdomain number\n" - " - the global node numbers of the nodes in the element.\n" - "#\n"; - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - outfile.width(5); - outfile << i << " ElmT3n2D "; - outfile.width(4); - outfile << el.GetIndex() << " "; - outfile.width(8); - outfile << el.PNum(1); - outfile.width(8); - outfile << el.PNum(3); - outfile.width(8); - outfile << el.PNum(2); - outfile << "\n"; - } - } -} -} diff --git a/Netgen/libsrc/interface/writeelmer.cpp b/Netgen/libsrc/interface/writeelmer.cpp deleted file mode 100644 index caf02e2c68..0000000000 --- a/Netgen/libsrc/interface/writeelmer.cpp +++ /dev/null @@ -1,127 +0,0 @@ - -// -// Write Elmer file -// -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "writeuser.hpp" - -#include <sys/stat.h> - - -void WriteElmerFormat (const Mesh &mesh, - const string &filename) -{ - cout << "write elmer mesh files" << endl; - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int i, j, rc; - char str[200]; - - int inverttets = mparam.inverttets; - int invertsurf = mparam.inverttrigs; - -#ifdef WIN32 - cerr << "not yet implemented for Windows platforms." << endl; - return; -#else - rc = mkdir(filename.c_str(), S_IRWXU|S_IRWXG); -#endif - sprintf( str, "%s/mesh.header", filename.c_str() ); - ofstream outfile_h(str); - sprintf( str, "%s/mesh.nodes", filename.c_str() ); - ofstream outfile_n(str); - sprintf( str, "%s/mesh.elements", filename.c_str() ); - ofstream outfile_e(str); - sprintf( str, "%s/mesh.boundary", filename.c_str() ); - ofstream outfile_b(str); - - // fill hashtable - - INDEX_3_HASHTABLE<int> face2volelement(ne); - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - INDEX_3 i3; - int k, l; - for (j = 1; j <= 4; j++) // loop over faces of tet - { - l = 0; - for (k = 1; k <= 4; k++) - if (k != j) - { - l++; - i3.I(l) = el.PNum(k); - } - i3.Sort(); - face2volelement.Set (i3, i); - } - } - -// outfile.precision(6); -// outfile.setf (ios::fixed, ios::floatfield); -// outfile.setf (ios::showpoint); - - outfile_h << np << " " << ne << " " << nse << "\n"; - outfile_h << "1" << "\n"; - outfile_h << "504 1" << "\n"; - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - - outfile_n << i << " -1 "; - outfile_n << p.X() << " "; - outfile_n << p.Y() << " "; - outfile_n << p.Z() << "\n"; - } - - for (i = 1; i <= ne; i++) - { - Element el = mesh.VolumeElement(i); - if (inverttets) el.Invert(); - sprintf( str, "5%02d", (int)el.GetNP() ); - outfile_e << i << " " << el.GetIndex() << " " << str << " "; - for (j = 1; j <= el.GetNP(); j++) - { - outfile_e << " "; - outfile_e << el.PNum(j); - } - outfile_e << "\n"; - } - - for (i = 1; i <= nse; i++) - { - Element2d el = mesh.SurfaceElement(i); - if (invertsurf) el.Invert(); - sprintf( str, "3%02d", (int)el.GetNP() ); - { - INDEX_3 i3; - for (j = 1; j <= 3; j++) i3.I(j) = el.PNum(j); - i3.Sort(); - - int elind = face2volelement.Get(i3); - outfile_b << i << " " << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << - " " << elind << " 0 " << str << " "; - } - for (j = 1; j <= el.GetNP(); j++) - { - outfile_b << " "; - outfile_b << el.PNum(j); - } - outfile_b << "\n"; - } -} - -} diff --git a/Netgen/libsrc/interface/writefeap.cpp b/Netgen/libsrc/interface/writefeap.cpp deleted file mode 100644 index 817ee7c538..0000000000 --- a/Netgen/libsrc/interface/writefeap.cpp +++ /dev/null @@ -1,220 +0,0 @@ -// -// Write FEAP file -// FEAP by Bob Taylor, Berkely -// -// contact Peter Wriggers or Albrecht Rieger, Hannover -// rieger@ibnm.uni-hannover.de -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ - -#include "writeuser.hpp" - - -void WriteFEAPFormat (const Mesh & mesh, - const string & filename) - -{ - // Feap format by A. Rieger - // rieger@ibnm.uni-hannover.de - - int inverttets = mparam.inverttets; - int invertsurf = mparam.inverttrigs; - - int i, j, zz, n; - - double scale = 1; // globflags.GetNumFlag ("scale", 1); - - ofstream outfile(filename.c_str()); - - outfile << "feap" << "\n"; - outfile << mesh.GetNP(); - outfile << ","; - outfile << mesh.GetNE(); - outfile << ","; - outfile << "1,3,3,4" << "\n" << "\n"; - outfile << "!numnp,numel,nummat,ndm,ndf,nen"; - outfile << "\n"; - - outfile << "\n" << "\n"; - outfile << "!node,, X Y Z" << "\n"; - outfile << "COOR" << "\n"; - outfile.precision(4); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - for (i = 1; i <= mesh.GetNP(); i++) - { - outfile.width(5); - outfile << i; - outfile << ",,"; - outfile.width(10); - outfile << mesh.Point(i).X()/scale << " "; - outfile.width(10); - outfile << mesh.Point(i).Y()/scale << " "; - outfile.width(10); - outfile << mesh.Point(i).Z()/scale << "\n"; - } - - outfile << "\n" << "\n"; - outfile << "!elm,,mat, n1 n2 n3 n4" << "\n"; - outfile << "ELEM" << "\n"; - - for (i = 1; i <= mesh.GetNE(); i++) - { - Element el = mesh.VolumeElement(i); - if (inverttets) - el.Invert(); - - - outfile.width(5); - outfile << i; - outfile << ",,"; - outfile << el.GetIndex(); - outfile << ","; - - - for (j = 1; j <= el.NP(); j++) - { - outfile.width(8); - outfile << el.PNum(j); - } - outfile << "\n"; - } - - outfile << "\n" << "\n"; - - - /* - - //outfile << "SLOA" << "\n"; - //outfile << "2,3,3" << "\n"; - //outfile << GetNSE() << "\n"; - outfile << "selm" << "\n" << GetNSE() << "\n"; - for (i = 1; i <= GetNSE(); i++) - { - if (SurfaceElement(i).GetIndex()) - { - outfile.width(8); - outfile << facedecoding.Get(SurfaceElement(i).GetIndex ()).surfnr; - //outfile.width(8); - //outfile << facedecoding.Get(SurfaceElement(i).GetIndex ()).domin; - //outfile.width(8); - //outfile << facedecoding.Get(SurfaceElement(i).GetIndex ()).domout; - } - else - outfile << " 0 0 0"; - - - Element2d sel = SurfaceElement(i); - if (invertsurf) - sel.Invert(); - //outfile.width(8); - //outfile << sel.GetNP(); - //if (facedecoding.Get(SurfaceElement(i).GetIndex ()).surfnr == 4) - //{ - for (j = 1; j <= sel.GetNP(); j++) - { - outfile.width(8); - outfile << sel.PNum(j); - } - //outfile.width(8); - //outfile << "0.0"; - //outfile.width(8); - //outfile << "0.0"; - //outfile.width(8); - //outfile << "1.0" << "\n"; - //} - outfile << "\n"; - //outfile << endl; - } - */ - - - - // BEGIN CONTACT OUTPUT - /* - int masterindex, slaveindex; - cout << "Master Surface index = "; - cin >> masterindex; - cout << "Slave Surface index = "; - cin >> slaveindex; - - - // CONTACT SURFACE 1 - outfile << "\n"; - outfile << "\n"; - outfile << "surface,1" << "\n";; - outfile.width(6); - outfile << "tria" << "\n";; - outfile.width(13); - outfile << "facet" << "\n";; - zz = 0; - for (i = 1; i <= mesh.GetNSE(); i++) - { - Element2d sel = mesh.SurfaceElement(i); - if (invertsurf) - sel.Invert(); - if (mesh.GetFaceDescriptor(sel.GetIndex ()).BCProperty() == masterindex) - { - zz++; - outfile.width(14); - outfile << zz; - outfile << ",,"; - for (j = 1; j <= sel.GetNP(); j++) - { - outfile << sel.PNum(j); - outfile << ","; - } - outfile << "\n"; - } - } - - - // CONTACT SURFACE 2 - outfile << "\n"; - outfile << "\n"; - outfile << "surface,2" << "\n";; - outfile.width(6); - outfile << "tria" << "\n";; - outfile.width(13); - outfile << "facet" << "\n";; - zz = 0; - for (i = 1; i <= mesh.GetNSE(); i++) - { - - Element2d sel = mesh.SurfaceElement(i); - if (invertsurf) - sel.Invert(); - if (mesh.GetFaceDescriptor(sel.GetIndex ()).BCProperty() == slaveindex) - { - zz++; - outfile.width(14); - outfile << zz; - outfile << ",,"; - for (j = 1; j <= sel.GetNP(); j++) - { - outfile << sel.PNum(j); - outfile << ","; - } - outfile << "\n"; - } - } - - outfile << "\n"; - outfile << "\n"; - */ - - // END CONTACT OUTPUT - - cout << "done" << endl; -} -} diff --git a/Netgen/libsrc/interface/writefluent.cpp b/Netgen/libsrc/interface/writefluent.cpp deleted file mode 100644 index 5c08d59857..0000000000 --- a/Netgen/libsrc/interface/writefluent.cpp +++ /dev/null @@ -1,193 +0,0 @@ -// -// Write Fluent file -// Johannes Gerstmayr, University Linz -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ - -#include "writeuser.hpp" - - - -void WriteFluentFormat (const Mesh & mesh, - const string & filename) - -{ - cout << "start writing fluent export" << endl; - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int i, j; - - ofstream outfile (filename.c_str()); - char str[100]; - - outfile.precision(6); - //outfile.setf (ios::fixed, ios::floatfield); - //outfile.setf (ios::showpoint); - - outfile << "(0 \"Exported file from NETGEN \")" << endl; - outfile << "(0 \"Dimension:\")" << endl; - outfile << "(2 3)" << endl << endl; - - outfile << "(0 \"Nodes:\")" << endl; - - //number of nodes: - sprintf(str,"(10 (0 1 %x 1))",np); //hexadecimal!!! - outfile << str << endl; - - //nodes of zone 1: - sprintf(str,"(10 (7 1 %x 1)(",np); //hexadecimal!!! - outfile << str << endl; - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - - //outfile.width(10); - outfile << p.X() << " "; - outfile << p.Y() << " "; - outfile << p.Z() << "\n"; - } - outfile << "))" << endl << endl; - - //write faces with elements - - outfile << "(0 \"Faces:\")" << endl; - - Element2d face, face2; - int i2, j2; - ARRAY<INDEX_3> surfaceelp; - ARRAY<int> surfaceeli; - ARRAY<int> locels; - - //no cells=no tets - //no faces=2*tets - - int noverbface = 2*ne-nse/2; - - sprintf(str,"(13 (0 1 %x 0))",(noverbface+nse)); //hexadecimal!!! - outfile << str << endl; - - sprintf(str,"(13 (4 1 %x 2 3)(",noverbface); //hexadecimal!!! - outfile << str << endl; - - const_cast<Mesh&> (mesh).BuildElementSearchTree(); - - for (i = 1; i <= ne; i++) - { - if (ne > 2000) - { - if (i%2000 == 0) - { - cout << (double)i/(double)ne*100. << "%" << endl; - } - } - - Element el = mesh.VolumeElement(i); - //if (inverttets) - // el.Invert(); - - //outfile << el.GetIndex() << " "; - if (el.GetNP() != 4) {cout << "only tet-meshes supported in write fluent!" << endl;} - - //faces: - - Box3d box; - el.GetBox(mesh.Points(), box); - box.IncreaseRel(1e-6); - - mesh.GetIntersectingVolEls(box.PMin(),box.PMax(),locels); - int nel = locels.Size(); - int locind; - - //cout << "nel=" << nel << endl; - - for (j = 1; j <= el.GetNFaces(); j++) - { - el.GetFace(j, face); - face.Invert(); - int eli2 = 0; - int stopsig = 0; - - for (i2 = 1; i2 <= nel; i2++) - { - locind = locels.Get(i2); - //cout << " locind=" << locind << endl; - - Element el2 = mesh.VolumeElement(locind); - //if (inverttets) - // el2.Invert(); - - for (j2 = 1; j2 <= el2.GetNFaces(); j2++) - { - el2.GetFace(j2, face2); - - if (face2.HasFace(face)) {eli2 = locind; stopsig = 1; break;} - } - if (stopsig) break; - } - - if (eli2==i) cout << "error in WRITE_FLUENT!!!" << endl; - - if (eli2 > i) //dont write faces two times! - { - //i: left cell, eli: right cell - outfile << hex << face.PNum(2) << " " - << hex << face.PNum(1) << " " - << hex << face.PNum(3) << " " - << hex << i << " " - << hex << eli2 << "\n"; - } - if (eli2 == 0) - { - surfaceelp.Append(INDEX_3(face.PNum(2),face.PNum(1),face.PNum(3))); - surfaceeli.Append(i); - } - } - } - outfile << "))" << endl; - - sprintf(str,"(13 (2 %x %x 3 3)(",(noverbface+1),noverbface+nse); //hexadecimal!!! - outfile << str << endl; - - for (i = 1; i <= surfaceelp.Size(); i++) - { - outfile << hex << surfaceelp.Get(i).I1() << " " - << hex << surfaceelp.Get(i).I2() << " " - << hex << surfaceelp.Get(i).I3() << " " - << hex << surfaceeli.Get(i) << " " << 0 << "\n"; - } - - outfile << "))" << endl << endl; - - outfile << "(0 \"Cells:\")" << endl; - - sprintf(str,"(12 (0 1 %x 0))",ne); //hexadecimal!!! - outfile << str << endl; - - sprintf(str,"(12 (1 1 %x 1 2))",ne); //hexadecimal!!! - outfile << str << endl << endl; - - - - - outfile << "(0 \"Zones:\")\n" - << "(45 (1 fluid fluid)())\n" - // << "(45 (2 velocity-inlet velocity_inlet.1)())\n" - // << "(45 (3 pressure-outlet pressure_outlet.2)())\n" - << "(45 (2 wall wall)())\n" - << "(45 (4 interior default-interior)())\n" << endl; - - cout << "done" << endl; -} - -} diff --git a/Netgen/libsrc/interface/writegmsh.cpp b/Netgen/libsrc/interface/writegmsh.cpp deleted file mode 100644 index 93def67783..0000000000 --- a/Netgen/libsrc/interface/writegmsh.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/************************************* - * Write Gmsh file - * First issue the 04/26/2004 by Paul CARRICO (paul.carrico@free.fr) - * At the moment, the GMSH format is available for - * linear tetrahedron elements i.e. in 3D - * (based on Neutral Format) - * - * Second issue the 05/05/2004 by Paul CARRICO - * Thanks to Joachim Schoeberl for the correction of a minor bug - * the 2 initial Gmsh Format (i.e. volume format and surface format) are group together) - * in only one file - **************************************/ - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "writeuser.hpp" - - - -/* - * GMSH mesh format - * points, elements, surface elements and physical entities - */ - -void WriteGmshFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - ofstream outfile (filename.c_str()); - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - int np = mesh.GetNP(); /// number of point - int ne = mesh.GetNE(); /// number of element - int nse = mesh.GetNSE(); /// number of surface element (BC) - int i, j, k, l; - - - /* - * 3D section : Linear volume elements (only tetrahedra) - */ - - if (ne > 0 && mesh.VolumeElement(1).GetNP() == 4) - { - cout << "Write GMSH Format \n"; - cout << "The GMSH format is available for linear tetrahedron elements only in 3D\n" << endl; - - int inverttets = mparam.inverttets; - int invertsurf = mparam.inverttrigs; - - - /// Write nodes - outfile << "$NOD\n"; - outfile << np << "\n"; - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - outfile << i << " "; /// node number - outfile << p.X() << " "; - outfile << p.Y() << " "; - outfile << p.Z() << "\n"; - } - outfile << "$ENDNOD\n"; - - /// write elements - outfile << "$ELM\n"; - outfile << ne + nse << "\n"; //// number of elements + number of surfaces BC - - for (i = 1; i <= nse; i++) - { - Element2d el = mesh.SurfaceElement(i); - if (invertsurf) el.Invert(); - outfile << i; - outfile << " "; - outfile << "2"; - outfile << " "; - outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; - /// that means that physical entity = elementary entity (arbitrary approach) - outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; - outfile << "3"; - outfile << " "; - for (j = 1; j <= el.GetNP(); j++) - { - outfile << " "; - outfile << el.PNum(j); - } - outfile << "\n"; - } - - - for (i = 1; i <= ne; i++) - { - Element el = mesh.VolumeElement(i); - if (inverttets) el.Invert(); - outfile << nse + i; /// element number - outfile << " "; - outfile << "4"; /// element type i.e. Tetraedron == 4 - outfile << " "; - outfile << 100000 + el.GetIndex(); - /// that means that physical entity = elementary entity (arbitrary approach) - outfile << " "; - outfile << 100000 + el.GetIndex(); /// volume number - outfile << " "; - outfile << "4"; /// number of nodes i.e. 4 for a tetrahedron - - for (j = 1; j <= el.GetNP(); j++) - { - outfile << " "; - outfile << el.PNum(j); - } - outfile << "\n"; - } - - - outfile << "$ENDELM\n"; - } - - /* - * End of 3D section - */ - - - - - - /* - * 2D section : available for triangles and quadrangles - */ - else if (ne == 0) /// means that there's no 3D element - { - cout << "\n Write Gmsh Surface Mesh (triangle and/or quadrangles)" << endl; - - /// Write nodes - outfile << "$NOD\n"; - outfile << np << "\n"; - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - outfile << i << " "; /// node number - outfile << p.X() << " "; - outfile << p.Y() << " "; - outfile << p.Z() << "\n"; - } - outfile << "$ENDNOD\n"; - - - /// write triangles & quadrangles - outfile << "$ELM\n"; - outfile << nse << "\n"; - - for (k = 1; k <= nse; k++) - { - const Element2d & el = mesh.SurfaceElement(k); - - - outfile << k; - outfile << " "; - outfile << (el.GetNP()-1); // 2 for a triangle and 3 for a quadrangle - outfile << " "; - outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; - /// that means that physical entity = elementary entity (arbitrary approach) - outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; - outfile << (el.GetNP()); // number of node per surfacic element - outfile << " "; - - for (l = 1; l <= el.GetNP(); l++) - { - outfile << " "; - outfile << el.PNum(l); - } - outfile << "\n"; - - } - outfile << "$ENDELM$ \n"; - } - - /* - * End of 2D section - */ - - else - { - cout << " Invalide element type for Gmsh volume Format !\n"; - } - - -} -} - - diff --git a/Netgen/libsrc/interface/writepermas.cpp b/Netgen/libsrc/interface/writepermas.cpp deleted file mode 100644 index 9dc7662458..0000000000 --- a/Netgen/libsrc/interface/writepermas.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// -// Write Permas file -// for Intes GmbH, Stuttgart -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -#include <string> - -using namespace std; - -namespace netgen -{ -#include "writeuser.hpp" - // Forward declarations (don't know, where to define them, sorry) - int addComponent(string &strComp, string &strSitu, ofstream &out); - - - // This should be the new function to export a PERMAS file - void WritePermasFormat (const Mesh &mesh, const string &filename, - string &strComp, string &strSitu) - { - ofstream outfile (filename.c_str()); - addComponent(strComp, strSitu, outfile); - WritePermasFormat ( mesh, filename); - } - - void WritePermasFormat (const Mesh &mesh, const string &filename) - { - string strComp, strSitu; - ofstream outfile (filename.c_str()); - - outfile.precision(8); - - strSitu = strComp = ""; - if (addComponent(strComp, strSitu, outfile) == 1) { - printf("Error while exporting PERMAS dat!\n"); - return; - } - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int i, j, k; - - if (ne == 0) - { - // pure surface mesh - cout << "\nWrite Permas Surface Mesh" << endl; - - int elnr = 0; - for (j = 1; j <= 2; j++) - { - int nelp; - switch (j) - { - case 1: - nelp = 3; - outfile << "$ELEMENT TYPE = TRIA3 ESET = ALLQUAD" << endl; - break; - case 2: - nelp = 4; - outfile << "$ELEMENT TYPE = QUAD4 ESET = ALLQUAD" << endl; - break; - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() != nelp) - continue; - - elnr++; - outfile << elnr << " "; - for (k = 1; k <= nelp; k++) - outfile << " " << el.PNum(k); - outfile << endl; - - } - } - } - else - { - cout << "\nWrite Permas Volume Mesh" << endl; - - int secondorder = (mesh.VolumeElement(1).GetNP() == 10); - - if (!secondorder) - { - outfile << "$ELEMENT TYPE = TET4 ESET = ALLTET" << endl; - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - outfile << i - << " " << el.PNum(1) - << " " << el.PNum(2) - << " " << el.PNum(3) - << " " << el.PNum(4) << endl; - } - } - else - { - outfile << "$ELEMENT TYPE = TET10 ESET = ALLTET" << endl; - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - outfile << i - << " " << el.PNum(1) - << " " << el.PNum(5) - << " " << el.PNum(2) - << " " << el.PNum(8) - << " " << el.PNum(3) - << " " << el.PNum(6) << endl << "& " - << " " << el.PNum(7) - << " " << el.PNum(9) - << " " << el.PNum(10) - << " " << el.PNum(4) << endl; - } - } - - outfile << endl << endl; - - - outfile << "$SURFACE GEO SURFID = 1 SFSET = ALLSUR" << endl; - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() == 3) - outfile << "STRIA3" - << " " << el.PNum(1) - << " " << el.PNum(2) - << " " << el.PNum(3) << endl; - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() == 4) - outfile << "SQUAD4" - << " " << el.PNum(1) - << " " << el.PNum(2) - << " " << el.PNum(3) - << " " << el.PNum(4) << endl; - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() == 6) - outfile << "STRIA6" - << " " << el.PNum(1) - << " " << el.PNum(4) - << " " << el.PNum(2) - << " " << el.PNum(5) - << " " << el.PNum(3) - << " " << el.PNum(6) << endl; - } - } - - - outfile << endl << endl; - - outfile << "$COOR NSET = ALLNODES" << endl; - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - for (i = 1; i <= np; i++) - { - outfile << i << " "; - outfile << mesh.Point(i).X() << " "; - outfile << mesh.Point(i).Y() << " "; - outfile << mesh.Point(i).Z() << "\n"; - } - } - ////////////////////////////////////////////////////////////////////////////////// - // \brief Writes PERMAS configuration header into export file - // Returns >0 in case of errors - // \par string &strComp : Reference to component description - // \par string &strComp : Reference to situation description - ////////////////////////////////////////////////////////////////////////////////// - int addComponent(string &strComp, string &strSitu, ofstream &out) - { - if (strComp.size() > 12 || strSitu > 12) - return 1; - - if (0 == strComp.size()) - strComp = "KOMPO1"; - - if (0 == strSitu.size()) - strSitu = "SIT1"; - - // Writing description header of configuration - out << "$ENTER COMPONENT NAME = " << strComp << " DOFTYPE = DISP MATH" << endl << endl; - out << " $SITUATION NAME = " << strSitu << endl; - out << " $END SITUATION" << endl << endl; - out << " $STRUCTURE" << endl; - - return 0; - } - -} diff --git a/Netgen/libsrc/interface/writepermas2.cpp b/Netgen/libsrc/interface/writepermas2.cpp deleted file mode 100644 index f78714c5a4..0000000000 --- a/Netgen/libsrc/interface/writepermas2.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// -// Write Permas file -// for Intes GmbH, Stuttgart -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "writeuser.hpp" - - - -void WritePermasFormat (const Mesh & mesh, - const string & filename) - -{ - - ofstream outfile (filename.c_str()); - - outfile.precision(8); - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int i, j, k; - - - if (ne == 0) - { - // pure surface mesh - - cout << "\nWrite Permas Surface Mesh" << endl; - - int elnr = 0; - for (j = 1; j <= 2; j++) - { - int nelp; - switch (j) - { - case 1: - nelp = 3; - outfile << "$ELEMENT TYPE = TRIA3 ESET = ALLQUAD" << endl; - break; - case 2: - nelp = 4; - outfile << "$ELEMENT TYPE = QUAD4 ESET = ALLQUAD" << endl; - break; - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() != nelp) - continue; - - elnr++; - outfile << elnr << " "; - for (k = 1; k <= nelp; k++) - outfile << " " << el.PNum(k); - outfile << endl; - - } - } - } - - else - - { - cout << "\nWrite Permas Volume Mesh" << endl; - - - int secondorder = (mesh.VolumeElement(1).GetNP() == 10); - - if (!secondorder) - { - outfile << "$ELEMENT TYPE = TET4 ESET = ALLTET" << endl; - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - outfile << i - << " " << el.PNum(1) - << " " << el.PNum(2) - << " " << el.PNum(3) - << " " << el.PNum(4) << endl; - } - } - else - { - outfile << "$ELEMENT TYPE = TET10 ESET = ALLTET" << endl; - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - outfile << i - << " " << el.PNum(1) - << " " << el.PNum(5) - << " " << el.PNum(2) - << " " << el.PNum(8) - << " " << el.PNum(3) - << " " << el.PNum(6) << endl << "& " - << " " << el.PNum(7) - << " " << el.PNum(9) - << " " << el.PNum(10) - << " " << el.PNum(4) << endl; - } - } - - outfile << endl << endl; - - - outfile << "$SURFACE GEO SURFID = 1 SFSET = ALLSUR" << endl; - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() == 3) - outfile << "STRIA3" - << " " << el.PNum(1) - << " " << el.PNum(2) - << " " << el.PNum(3) << endl; - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() == 4) - outfile << "SQUAD4" - << " " << el.PNum(1) - << " " << el.PNum(2) - << " " << el.PNum(3) - << " " << el.PNum(4) << endl; - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetNP() == 6) - outfile << "STRIA6" - << " " << el.PNum(1) - << " " << el.PNum(4) - << " " << el.PNum(2) - << " " << el.PNum(5) - << " " << el.PNum(3) - << " " << el.PNum(6) << endl; - } - } - - - outfile << endl << endl; - - - - outfile << "$COOR NSET = ALLNODES" << endl; - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - for (i = 1; i <= np; i++) - { - outfile << i << " "; - outfile << mesh.Point(i).X() << " "; - outfile << mesh.Point(i).Y() << " "; - outfile << mesh.Point(i).Z() << "\n"; - } -} - - -} diff --git a/Netgen/libsrc/interface/writetecplot.cpp b/Netgen/libsrc/interface/writetecplot.cpp deleted file mode 100644 index a3ddda3f9a..0000000000 --- a/Netgen/libsrc/interface/writetecplot.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// -// -// TECPLOT file by Jawor Georgiew -// -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - - - -namespace netgen -{ -#include "writeuser.hpp" - -void WriteTecPlotFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - INDEX i; - int j, k, e, z; - Vec<3> n; - - INDEX np = mesh.GetNP(); - INDEX ne = mesh.GetNE(); - INDEX nse = mesh.GetNSE(); - - ARRAY<int> sn(np); - ofstream outfile(filename.c_str()); - - outfile << "TITLE=\" " << filename << "\"" << endl; - - // fill hashtable - - INDEX_3_HASHTABLE<int> face2volelement(ne); - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - INDEX_3 i3; - int k, l; - for (j = 1; j <= 4; j++) // loop over faces of tet - { - l = 0; - for (k = 1; k <= 4; k++) - if (k != j) - { - l++; - i3.I(l) = el.PNum(k); - } - i3.Sort(); - face2volelement.Set (i3, i); - } - } - - - for (j = 1; j <= geom.GetNSurf(); j++) /* Flaeche Nummer j */ - { - for (i = 1; i <= np; i++) - sn.Elem(i) = 0; - - e = 0; - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (j == mesh.GetFaceDescriptor (el.GetIndex ()).SurfNr()) - { - for (k = 1; k <= 3; k++) - sn.Elem(el.PNum(k)) = 1; - e++; /* e= Anzahl der neuen Elemente */ - } - } - - z = 0; - for (i = 1; i <= np; i++) - if (sn.Elem(i) == 1) - sn.Elem(i) = ++z; - - outfile << "ZONE T=\" Surface " << j << " \", N=" << z - << ", E=" << e << ", ET=TRIANGLE, F=FEPOINT" << endl; - - for (i = 1; i <= np; i++) - if (sn.Elem(i) != 0) - { - n = geom.GetSurface(j) -> GetNormalVector ( mesh.Point(i) ); - - outfile << mesh.Point(i).X() << " " /* Knoten Koordinaten */ - << mesh.Point(i).Y() << " " - << mesh.Point(i).Z() << " " - << n(0) << " " - << n(1) << " " - << n(2) << " " - << i << endl; - } - - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (j == mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr()) - /* FlaechenKnoten (3) */ - outfile << sn.Get(el.PNum(1)) << " " - << sn.Get(el.PNum(2)) << " " - << sn.Get(el.PNum(3)) << endl; - - /// Hier soll noch die Ausgabe der Nummer des angrenzenden - /// Vol.elements erfolgen ! - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - INDEX_3 i3; - for (j = 1; j <= 3; j++) - i3.I(j) = el.PNum(j); - i3.Sort(); - - int elind = face2volelement.Get(i3); - } - } - } -} - - -} diff --git a/Netgen/libsrc/interface/writetochnog.cpp b/Netgen/libsrc/interface/writetochnog.cpp deleted file mode 100644 index 50546dc2d1..0000000000 --- a/Netgen/libsrc/interface/writetochnog.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// -// Write Tochnog file -// -// by -// -// Andreas Seltmann -// email: A.Seltmann@lsw.uni-heidelberg.de -// -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - - -namespace netgen -{ -#include "writeuser.hpp" - - -void WriteTochnogFormat (const Mesh & mesh, - const string & filename) -{ - cout << "\nWrite Tochnog Volume Mesh" << endl; - - ofstream outfile (filename.c_str()); - - outfile << "(Nodes and Elements generated with NETGEN" << endl; - outfile << " " << filename << ")" << endl; - - outfile.precision(8); - - outfile << "(Nodes)" << endl; - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int i, j, k; - - for (i = 1; i <= np; i++) - { - outfile << "node " << " " << i << " "; - outfile << mesh.Point(i).X() << " "; - outfile << mesh.Point(i).Y() << " "; - outfile << mesh.Point(i).Z() << "\n"; - } - - int elemcnt = 0; //element counter - int finished = 0; - int indcnt = 1; //index counter - - while (!finished) - { - int actcnt = 0; - const Element & el1 = mesh.VolumeElement(1); - int non = el1.GetNP(); - if (non == 4) - { - outfile << "(Elements, type=-tet4)" << endl; - } - else - { - cout << "unsupported Element type!!!" << endl; - } - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - - if (el.GetIndex() == indcnt) - { - actcnt++; - if (el.GetNP() != non) - { - cout << "different element-types in a subdomain are not possible!!!" << endl; - continue; - } - - elemcnt++; - outfile << "element " << elemcnt << " -tet4 "; - if (non == 4) - { - outfile << el.PNum(1) << " "; - outfile << el.PNum(2) << " "; - outfile << el.PNum(4) << " "; - outfile << el.PNum(3) << "\n"; - } - else - { - cout << "unsupported Element type!!!" << endl; - for (j = 1; j <= el.GetNP(); j++) - { - outfile << el.PNum(j); - if (j != el.GetNP()) outfile << ", "; - } - outfile << "\n"; - } - } - } - indcnt++; - if (elemcnt == ne) {finished = 1; cout << "all elements found by Index!" << endl;} - if (actcnt == 0) {finished = 1;} - } - - cout << "done" << endl; -} - -} diff --git a/Netgen/libsrc/interface/writeuser.cpp b/Netgen/libsrc/interface/writeuser.cpp deleted file mode 100644 index 83b9a050ce..0000000000 --- a/Netgen/libsrc/interface/writeuser.cpp +++ /dev/null @@ -1,899 +0,0 @@ -// -// Write user dependent output file -// - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <csg.hpp> -#include <geometry2d.hpp> -#include <meshing.hpp> - -namespace netgen -{ -#include "writeuser.hpp" - - -void RegisterUserFormats (ARRAY<const char*> & names) -{ - char *types[] = - { - "Neutral Format", - "Surface Mesh Format" , - "DIFFPACK Format", - "TecPlot Format", - "Tochnog Format", - "Abaqus Format", - "Fluent Format", - "Permas Format", - "FEAP Format", - "Elmer Format", - "STL Format", - "VRML Format", - "Gmsh Format", - // { "Chemnitz Format" }, - 0 - }; - - for (int i = 0; types[i]; i++) - names.Append (types[i]); -} - - - -bool WriteUserFormat (const string & format, - const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - PrintMessage (1, "Export mesh to file ", filename, - ", format is ", format); - - if (format == "Neutral Format") - WriteNeutralFormat (mesh, geom, filename); - - else if (format == "Surface Mesh Format") - WriteSurfaceFormat (mesh, filename); - - else if (format == "DIFFPACK Format") - WriteDiffPackFormat (mesh, geom, filename); - - else if (format == "Tochnog Format") - WriteTochnogFormat (mesh, filename); - - else if (format == "TecPlot Format") - cerr << "ERROR: TecPlot format currently out of order" << endl; - // WriteTecPlotFormat (mesh, geom, filename); - - else if (format == "Abaqus Format") - WriteAbaqusFormat (mesh, filename); - - else if (format == "Fluent Format") - WriteFluentFormat (mesh, filename); - - else if (format == "Permas Format") - WritePermasFormat (mesh, filename); - - else if (format == "FEAP Format") - WriteFEAPFormat (mesh, filename); - - else if (format == "Elmer Format") - WriteElmerFormat (mesh, filename); - - else if (format == "STL Format") - WriteSTLFormat (mesh, filename); - - else if (format == "VRML Format") - WriteVRMLFormat (mesh, 1, filename); - - else if (format == "Fepp Format") - WriteFEPPFormat (mesh, geom, filename); - - else if (format == "EdgeElement Format") - WriteEdgeElementFormat (mesh, geom, filename); - - else if (format == "Chemnitz Format") - WriteUserChemnitz (mesh, filename); - - else if (format == "Gmsh Format") - WriteGmshFormat (mesh, geom, filename); - - else - { - return 1; - } - - return 0; -} - - - - -/* - * Neutral mesh format - * points, elements, surface elements - */ - -void WriteNeutralFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - cout << "write neutral, new" << endl; - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int nseg = mesh.GetNSeg(); - int i, j; - - int inverttets = mparam.inverttets; - int invertsurf = mparam.inverttrigs; - - ofstream outfile (filename.c_str()); - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - outfile << np << "\n"; - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - - outfile.width(10); - outfile << p.X() << " "; - outfile.width(9); - outfile << p.Y() << " "; - if (mesh.GetDimension() == 3) - { - outfile.width(9); - outfile << p.Z(); - } - outfile << "\n"; - } - - if (mesh.GetDimension() == 3) - { - outfile << ne << "\n"; - for (i = 1; i <= ne; i++) - { - Element el = mesh.VolumeElement(i); - if (inverttets) - el.Invert(); - outfile.width(4); - outfile << el.GetIndex() << " "; - for (j = 1; j <= el.GetNP(); j++) - { - outfile << " "; - outfile.width(8); - outfile << el.PNum(j); - } - outfile << "\n"; - } - } - - outfile << nse << "\n"; - for (i = 1; i <= nse; i++) - { - Element2d el = mesh.SurfaceElement(i); - if (invertsurf) - el.Invert(); - outfile.width(4); - outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; - for (j = 1; j <= el.GetNP(); j++) - { - outfile << " "; - outfile.width(8); - outfile << el.PNum(j); - } - outfile << "\n"; - } - - - if (mesh.GetDimension() == 2) - { - outfile << nseg << "\n"; - for (i = 1; i <= nseg; i++) - { - const Segment & seg = mesh.LineSegment(i); - outfile.width(4); - outfile << seg.si << " "; - - outfile << " "; - outfile.width(8); - outfile << seg.p1; - outfile << " "; - outfile.width(8); - outfile << seg.p2; - - outfile << "\n"; - } - } -} - - - - - - - - - -void WriteSurfaceFormat (const Mesh & mesh, - const string & filename) -{ - // surface mesh - int i, j; - - cout << "Write Surface Mesh" << endl; - - ofstream outfile (filename.c_str()); - - outfile << "surfacemesh" << endl; - - outfile << mesh.GetNP() << endl; - for (i = 1; i <= mesh.GetNP(); i++) - { - for (j = 1; j <= 3; j++) - { - outfile.width(10); - outfile << mesh.Point(i).X(j) << " "; - } - outfile << endl; - } - outfile << mesh.GetNSE() << endl; - for (i = 1; i <= mesh.GetNSE(); i++) - { - for (j = 1; j <= 3; j++) - { - outfile.width(8); - outfile << mesh.SurfaceElement(i).PNum(j); - } - outfile << endl; - } -} - - - - - -/* - * save surface mesh as STL file - */ - -void WriteSTLFormat (const Mesh & mesh, - const string & filename) -{ - cout << "\nWrite STL Surface Mesh" << endl; - - ofstream outfile (filename.c_str()); - - int i, j, k; - - outfile.precision(10); - - outfile << "solid" << endl; - - for (i = 1; i <= mesh.GetNSE(); i++) - { - outfile << "facet normal "; - const Point3d& p1 = mesh.Point(mesh.SurfaceElement(i).PNum(1)); - const Point3d& p2 = mesh.Point(mesh.SurfaceElement(i).PNum(2)); - const Point3d& p3 = mesh.Point(mesh.SurfaceElement(i).PNum(3)); - - Vec3d normal = Cross(p2-p1,p3-p1); - if (normal.Length() != 0) - { - normal /= (normal.Length()); - } - - outfile << normal.X() << " " << normal.Y() << " " << normal.Z() << "\n"; - outfile << "outer loop\n"; - - outfile << "vertex " << p1.X() << " " << p1.Y() << " " << p1.Z() << "\n"; - outfile << "vertex " << p2.X() << " " << p2.Y() << " " << p2.Z() << "\n"; - outfile << "vertex " << p3.X() << " " << p3.Y() << " " << p3.Z() << "\n"; - - outfile << "endloop\n"; - outfile << "endfacet\n"; - } - outfile << "endsolid" << endl; -} - - - - - -/* - * - * write surface mesh as VRML file - * - */ - -void WriteVRMLFormat (const Mesh & mesh, - bool faces, - const string & filename) -{ - - if (faces) - - { - // Output in VRML, IndexedFaceSet is used - // Bartosz Sawicki <sawickib@ee.pw.edu.pl> - - int np = mesh.GetNP(); - int nse = mesh.GetNSE(); - int i, j, k, l; - - ofstream outfile (filename.c_str()); - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - outfile << "#VRML V2.0 utf8 \n" - "Background {\n" - " skyColor [1 1 1]\n" - " groundColor [1 1 1]\n" - "}\n" - "Group{ children [\n" - "Shape{ \n" - "appearance Appearance { material Material { }} \n" - "geometry IndexedFaceSet { \n" - "coord Coordinate { point [ \n"; - - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - outfile.width(10); - outfile << p.X() << " "; - outfile << p.Y() << " "; - outfile << p.Z() << " \n"; - } - - outfile << " ] } \n" - "coordIndex [ \n"; - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - for (j = 1; j <= 3; j++) - { - outfile.width(8); - outfile << el.PNum(j)-1; - } - outfile << " -1 \n"; - } - - outfile << " ] \n"; - - //define number and RGB definitions of colors - outfile << "color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0]} \n" - "colorIndex [\n"; - - for (i = 1; i <= nse; i++) - { - outfile << mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex ()).BCProperty(); - outfile << endl; - } - - outfile << " ] \n" - "colorPerVertex FALSE \n" - "creaseAngle 0 \n" - "solid FALSE \n" - "ccw FALSE \n" - "convex TRUE \n" - "} } # end of Shape\n" - "] }\n"; - - } /* end of VRMLFACES */ - - - else - - { - // Output in VRML, IndexedLineSet is used - // Bartosz Sawicki <sawickib@ee.pw.edu.pl> - - int np = mesh.GetNP(); - int nse = mesh.GetNSE(); - int i, j, k, l; - - ofstream outfile (filename.c_str()); - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - outfile << "#VRML V2.0 utf8 \n" - "Background {\n" - " skyColor [1 1 1]\n" - " groundColor [1 1 1]\n" - "}\n" - "Group{ children [\n" - "Shape{ \n" - "appearance Appearance { material Material { }} \n" - "geometry IndexedLineSet { \n" - "coord Coordinate { point [ \n"; - - - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - outfile.width(10); - outfile << p.X() << " "; - outfile << p.Y() << " "; - outfile << p.Z() << " \n"; - } - - outfile << " ] } \n" - "coordIndex [ \n"; - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - for (j = 1; j <= 3; j++) - { - outfile.width(8); - outfile << el.PNum(j)-1; - } - outfile.width(8); - outfile << el.PNum(1)-1; - outfile << " -1 \n"; - } - - outfile << " ] \n"; - -/* Uncomment if you want color mesh - outfile << "color Color { color [1 1 1, 0 1 0, 0 0 1, 1 1 0]} \n" - "colorIndex [\n"; - - for (i = 1; i <= nse; i++) - { - outfile << mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex ()).BCProperty(); - outfile << endl; - } - - outfile << " ] \n" -*/ - outfile << "colorPerVertex FALSE \n" - "} } #end of Shape\n" - "] } \n"; - - } - -} - - - - - - -/* - * FEPP .. a finite element package developed at University Linz, Austria - */ -void WriteFEPPFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - - ofstream outfile (filename.c_str()); - - if (mesh.GetDimension() == 3) - - { - - // output for FEPP - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int ns = mesh.GetNFD(); - int i, j; - - outfile.precision(5); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - outfile << "volumemesh4" << endl; - outfile << nse << endl; - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - // int facenr = mesh.facedecoding.Get(el.GetIndex()).surfnr; - outfile.width(4); - outfile << el.GetIndex() << " "; - outfile.width(4); - // outfile << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << " "; - outfile << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << " "; - outfile.width(4); - outfile << el.GetNP() << " "; - for (j = 1; j <= el.GetNP(); j++) - { - outfile.width(8); - outfile << el.PNum(j); - } - outfile << "\n"; - } - - - outfile << ne << "\n"; - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - outfile.width(4); - outfile << el.GetIndex() << " "; - outfile.width(4); - outfile << el.GetNP() << " "; - for (j = 1; j <= el.GetNP(); j++) - { - outfile.width(8); - outfile << el.PNum(j); - } - outfile << "\n"; - } - - outfile << np << "\n"; - for (i = 1; i <= np; i++) - { - const Point3d & p = mesh.Point(i); - - outfile.width(10); - outfile << p.X() << " "; - outfile.width(9); - outfile << p.Y() << " "; - outfile.width(9); - outfile << p.Z() << "\n"; - } - - /* - if (typ == WRITE_FEPPML) - { - int nbn = mesh.mlbetweennodes.Size(); - outfile << nbn << "\n"; - for (i = 1; i <= nbn; i++) - outfile << mesh.mlbetweennodes.Get(i).I1() << " " - << mesh.mlbetweennodes.Get(i).I2() << "\n"; - - - // int ncon = mesh.connectedtonode.Size(); - // outfile << ncon << "\n"; - // for (i = 1; i <= ncon; i++) - // outfile << i << " " << mesh.connectedtonode.Get(i) << endl; - } - */ - - - // write CSG surfaces - if (&geom && geom.GetNSurf() >= ns) - { - outfile << ns << endl; - for (i = 1; i <= ns; i++) - geom.GetSurface(mesh.GetFaceDescriptor(i).SurfNr())->Print(outfile); - } - else - outfile << "0" << endl; - } - - - else - - { // 2D fepp format - - ; - /* - extern SplineGeometry2d * geometry2d; - if (geometry2d) - Save2DMesh (mesh, &geometry2d->GetSplines(), outfile); - else - Save2DMesh (mesh, 0, outfile); - */ - } -} - - - - - - -/* - * Edge element mesh format - * points, elements, edges - */ - -void WriteEdgeElementFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename) -{ - cout << "write edge element format" << endl; - - const MeshTopology * top = &mesh.GetTopology(); - int npoints = mesh.GetNP(); - int nelements = mesh.GetNE(); - int nsurfelem = mesh.GetNSE(); - int nedges = top->GetNEdges(); - int i, j; - - int inverttets = mparam.inverttets; - int invertsurf = mparam.inverttrigs; - ARRAY<int> edges; - - ofstream outfile (filename.c_str()); - - outfile.precision(6); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - - // vertices with coordinates - outfile << npoints << "\n"; - for (i = 1; i <= npoints; i++) - { - const Point3d & p = mesh.Point(i); - - outfile.width(10); - outfile << p.X() << " "; - outfile.width(9); - outfile << p.Y() << " "; - outfile.width(9); - outfile << p.Z() << "\n"; - } - - // element - edge - list - outfile << nelements << " " << nedges << "\n"; - for (i = 1; i <= nelements; i++) - { - Element el = mesh.VolumeElement(i); - if (inverttets) - el.Invert(); - outfile.width(4); - outfile << el.GetIndex() << " "; - outfile.width(8); - outfile << el.GetNP(); - for (j = 1; j <= el.GetNP(); j++) - { - outfile << " "; - outfile.width(8); - outfile << el.PNum(j); - } - - top->GetElementEdges(i,edges); - outfile << endl << " "; - outfile.width(8); - outfile << edges.Size(); - for (j=1; j <= edges.Size(); j++) - { - outfile << " "; - outfile.width(8); - outfile << edges[j-1]; - } - outfile << "\n"; - - // orientation: - top->GetElementEdgeOrientations(i,edges); - outfile << " "; - for (j=1; j <= edges.Size(); j++) - { - outfile << " "; - outfile.width(8); - outfile << edges[j-1]; - } - outfile << "\n"; - } - - // surface element - edge - list (with boundary conditions) - outfile << nsurfelem << "\n"; - for (i = 1; i <= nsurfelem; i++) - { - Element2d el = mesh.SurfaceElement(i); - if (invertsurf) - el.Invert(); - outfile.width(4); - outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; - outfile.width(8); - outfile << el.GetNP(); - for (j = 1; j <= el.GetNP(); j++) - { - outfile << " "; - outfile.width(8); - outfile << el.PNum(j); - } - - top->GetSurfaceElementEdges(i,edges); - outfile << endl << " "; - outfile.width(8); - outfile << edges.Size(); - for (j=1; j <= edges.Size(); j++) - { - outfile << " "; - outfile.width(8); - outfile << edges[j-1]; - } - outfile << "\n"; - } - - - int v1, v2; - // edge - vertex - list - outfile << nedges << "\n"; - for (i=1; i <= nedges; i++) - { - top->GetEdgeVertices(i,v1,v2); - outfile.width(4); - outfile << v1; - outfile << " "; - outfile.width(8); - outfile << v2 << endl; - } -} - - - - - - - - - -#ifdef OLDSTYLE_WRITE - - -void WriteFile (int typ, - const Mesh & mesh, - const CSGeometry & geom, - const char * filename, - const char * geomfile, - double h) -{ - - - int inverttets = mparam.inverttets; - int invertsurf = mparam.inverttrigs; - - - - - - - - - if (typ == WRITE_EDGEELEMENT) - { - // write edge element file - // Peter Harscher, ETHZ - - cout << "Write Edge-Element Format" << endl; - - ofstream outfile (filename); - - int i, j; - int ned; - - // hash table representing edges; - INDEX_2_HASHTABLE<int> edgeht(mesh.GetNP()); - - // list of edges - ARRAY<INDEX_2> edgelist; - - // edge (point) on boundary ? - BitArray bedge, bpoint(mesh.GetNP()); - - static int eledges[6][2] = { { 1, 2 } , { 1, 3 } , { 1, 4 }, - { 2, 3 } , { 2, 4 } , { 3, 4 } }; - - // fill hashtable (point1, point2) ----> edgenr - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - INDEX_2 edge; - for (j = 1; j <= 6; j++) - { - edge.I1() = el.PNum (eledges[j-1][0]); - edge.I2() = el.PNum (eledges[j-1][1]); - edge.Sort(); - - if (!edgeht.Used (edge)) - { - edgelist.Append (edge); - edgeht.Set (edge, edgelist.Size()); - } - } - } - - - // set bedges, bpoints - bedge.SetSize (edgelist.Size()); - bedge.Clear(); - bpoint.Clear(); - - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & sel = mesh.SurfaceElement(i); - for (j = 1; j <= 3; j++) - { - bpoint.Set (sel.PNum(j)); - - INDEX_2 edge; - edge.I1() = sel.PNum(j); - edge.I2() = sel.PNum(j%3+1); - edge.Sort(); - - bedge.Set (edgeht.Get (edge)); - } - } - - - - outfile << mesh.GetNE() << endl; - // write element ---> point - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement(i); - - outfile.width(8); - outfile << i; - for (j = 1; j <= 4; j++) - { - outfile.width(8); - outfile << el.PNum(j); - } - outfile << endl; - } - - // write element ---> edge - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - INDEX_2 edge; - for (j = 1; j <= 6; j++) - { - edge.I1() = el.PNum (eledges[j-1][0]); - edge.I2() = el.PNum (eledges[j-1][1]); - edge.Sort(); - - outfile.width(8); - outfile << edgeht.Get (edge); - } - outfile << endl; - } - - // write points - outfile << mesh.GetNP() << endl; - outfile.precision (6); - for (i = 1; i <= mesh.GetNP(); i++) - { - const Point3d & p = mesh.Point(i); - - for (j = 1; j <= 3; j++) - { - outfile.width(8); - outfile << p.X(j); - } - outfile << " " - << (bpoint.Test(i) ? "1" : 0) << endl; - } - - // write edges - outfile << edgelist.Size() << endl; - for (i = 1; i <= edgelist.Size(); i++) - { - outfile.width(8); - outfile << edgelist.Get(i).I1(); - outfile.width(8); - outfile << edgelist.Get(i).I2(); - outfile << " " - << (bedge.Test(i) ? "1" : "0") << endl; - } - } - - - - -} -#endif -} diff --git a/Netgen/libsrc/interface/writeuser.hpp b/Netgen/libsrc/interface/writeuser.hpp deleted file mode 100644 index afb2a6d5e3..0000000000 --- a/Netgen/libsrc/interface/writeuser.hpp +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef WRITEUSER -#define WRITEUSER - -/**************************************************************************/ -/* File: writeuser.hh */ -/* Authors: many */ -/* Date: 10. Dec. 97 */ -/**************************************************************************/ - - -extern -void WriteFile (int typ, - const Mesh & mesh, - const CSGeometry & geom, - const char * filename, - const char * geomfile = NULL, - double h = 0); - - - -extern -void ReadFile (Mesh & mesh, - const string & filename); - -extern -void ImportSolution (const char * filename); - - - - - - - -extern -void WriteNeutralFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename); - -extern -void WriteSurfaceFormat (const Mesh & mesh, - const string & filename); - -extern -void WriteSTLFormat (const Mesh & mesh, - const string & filename); - -extern -void WriteVRMLFormat (const Mesh & mesh, - bool faces, - const string & filename); - -extern -void WriteFEPPFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename); - -extern -void WriteGmshFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename); - -extern -void WriteUserChemnitz (const Mesh & mesh, - const string & filename); - - -extern -void WriteDiffPackFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename); - -extern -void WriteTochnogFormat (const Mesh & mesh, - const string & filename); - -extern -void WriteTecPlotFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename); - -extern -void WriteAbaqusFormat (const Mesh & mesh, - const string & filename); - -extern -void WriteFluentFormat (const Mesh & mesh, - const string & filename); - -extern -void WritePermasFormat (const Mesh & mesh, - const string & filename); - -extern -void WriteFEAPFormat (const Mesh & mesh, - const string & filename); - -extern -void WriteElmerFormat (const Mesh & mesh, - const string & filename); - - -extern -void WriteEdgeElementFormat (const Mesh & mesh, - const CSGeometry & geom, - const string & filename); - - - -extern void RegisterUserFormats (ARRAY<const char*> & names); -extern bool WriteUserFormat (const string & format, - const Mesh & mesh, - const CSGeometry & geom, - const string & filename); -#endif diff --git a/Netgen/libsrc/interface/wuchemnitz.cpp b/Netgen/libsrc/interface/wuchemnitz.cpp deleted file mode 100644 index 82a513d1ca..0000000000 --- a/Netgen/libsrc/interface/wuchemnitz.cpp +++ /dev/null @@ -1,309 +0,0 @@ -// Write Chemnitz file format - - -#include <mystdlib.h> - -#include <myadt.hpp> - -#include <linalg.hpp> -#include <csg.hpp> -#include <meshing.hpp> - -namespace netgen -{ - -class POINT3D - { - public: - POINT3D () { }; - double x, y, z; - }; - -class VOLELEMENT - { - public: - VOLELEMENT () {}; - int domnr, p1, p2, p3, p4; - int faces[4]; - }; - -class SURFELEMENT - { - public: - SURFELEMENT () { }; - int snr, p1, p2, p3; - }; - - -class FACE - { - public: - FACE () { }; - int p1, p2, p3; - int edges[3]; - }; - -class EDGE - { - public: - EDGE () { }; - int p1, p2; - }; - -static ARRAY<POINT3D> points; -static ARRAY<VOLELEMENT> volelements; -static ARRAY<SURFELEMENT> surfelements; - -static ARRAY<FACE> faces; -static ARRAY<EDGE> edges; - - -void ReadFile (char * filename) - { - int i, n; - ifstream infile(filename); - char reco[100]; - - - infile >> reco; // file format recognition - - infile >> n; // number of surface elements - cout << n << " Surface elements" << endl; - - for (i = 1; i <= n; i++) - { - SURFELEMENT sel; - infile >> sel.snr >> sel.p1 >> sel.p2 >> sel.p3; - surfelements.Append (sel); - } - - infile >> n; // number of volume elements - cout << n << " Volume elements" << endl; - - for (i = 1; i <= n; i++) - { - VOLELEMENT el; - infile >> el.p1 >> el.p2 >> el.p3 >> el.p4; - volelements.Append (el); - } - - infile >> n; // number of points - cout << n << " Points" << endl; - - for (i = 1; i <= n; i++) - { - POINT3D p; - infile >> p.x >> p.y >> p.z; - points.Append (p); - } - } - - - -void ReadFileMesh (const Mesh & mesh) -{ - int i, n; - - n = mesh.GetNSE(); // number of surface elements - cout << n << " Surface elements" << endl; - - for (i = 1; i <= n; i++) - { - SURFELEMENT sel; - const Element2d & el = mesh.SurfaceElement(i); - sel.snr = el.GetIndex(); - sel.p1 = el.PNum(1); - sel.p2 = el.PNum(2); - sel.p3 = el.PNum(3); - surfelements.Append (sel); - } - - n = mesh.GetNE(); // number of volume elements - cout << n << " Volume elements" << endl; - - for (i = 1; i <= n; i++) - { - VOLELEMENT el; - const Element & nel = mesh.VolumeElement(i); - el.p1 = nel.PNum(1); - el.p2 = nel.PNum(2); - el.p3 = nel.PNum(3); - el.p4 = nel.PNum(4); - // infile >> el.p1 >> el.p2 >> el.p3 >> el.p4; - volelements.Append (el); - } - - n = mesh.GetNP(); // number of points - cout << n << " Points" << endl; - - for (i = 1; i <= n; i++) - { - POINT3D p; - Point3d mp = mesh.Point(i); - p.x = mp.X(); - p.y = mp.Y(); - p.z = mp.Z(); - // infile >> p.x >> p.y >> p.z; - points.Append (p); - } - } - - - - -void Convert () - { - int i, j, facei, edgei; - INDEX_3 i3; - INDEX_2 i2; - - INDEX_3_HASHTABLE<int> faceindex(volelements.Size()/5 + 1); - INDEX_2_HASHTABLE<int> edgeindex(volelements.Size()/5 + 1); - - for (i = 1; i <= volelements.Size(); i++) - { - for (j = 1; j <= 4; j++) - { - switch (j) - { - case 1: - i3.I1() = volelements.Get(i).p2; - i3.I2() = volelements.Get(i).p3; - i3.I3() = volelements.Get(i).p4; - break; - case 2: - i3.I1() = volelements.Get(i).p1; - i3.I2() = volelements.Get(i).p3; - i3.I3() = volelements.Get(i).p4; - break; - case 3: - i3.I1() = volelements.Get(i).p1; - i3.I2() = volelements.Get(i).p2; - i3.I3() = volelements.Get(i).p4; - break; - case 4: - i3.I1() = volelements.Get(i).p1; - i3.I2() = volelements.Get(i).p2; - i3.I3() = volelements.Get(i).p3; - break; - } - i3.Sort(); - if (faceindex.Used (i3)) - facei = faceindex.Get(i3); - else - { - FACE fa; - fa.p1 = i3.I1(); - fa.p2 = i3.I2(); - fa.p3 = i3.I3(); - facei = faces.Append (fa); - faceindex.Set (i3, facei); - } - - volelements.Elem(i).faces[j-1] = facei; - } - - } - - - for (i = 1; i <= faces.Size(); i++) - { - for (j = 1; j <= 3; j++) - { - switch (j) - { - case 1: - i2.I1() = faces.Get(i).p2; - i2.I2() = faces.Get(i).p3; - break; - case 2: - i2.I1() = faces.Get(i).p1; - i2.I2() = faces.Get(i).p3; - break; - case 3: - i2.I1() = faces.Get(i).p1; - i2.I2() = faces.Get(i).p2; - break; - } - if (i2.I1() > i2.I2()) swap (i2.I1(), i2.I2()); - if (edgeindex.Used (i2)) - edgei = edgeindex.Get(i2); - else - { - EDGE ed; - ed.p1 = i2.I1(); - ed.p2 = i2.I2(); - edgei = edges.Append (ed); - edgeindex.Set (i2, edgei); - } - - faces.Elem(i).edges[j-1] = edgei; - } - - } - - } - - -void WriteFile (ostream & outfile) - { - int i; - - outfile - << "#VERSION: 1.0" << endl - << "#PROGRAM: NETGEN" << endl - << "#EQN_TYPE: POISSON" << endl - << "#DIMENSION: 3D" << endl - << "#DEG_OF_FREE: 1" << endl - << "#DESCRIPTION: I don't know" << endl - << "##RENUM: not done" << endl - << "#USER: Kleinzen" << endl - << "DATE: 10.06.1996" << endl; - - outfile << "#HEADER: 8" << endl - << points.Size() << " " << edges.Size() << " " - << faces.Size() << " " << volelements.Size() << " 0 0 0 0" << endl; - - outfile << "#VERTEX: " << points.Size() << endl; - for (i = 1; i <= points.Size(); i++) - outfile << " " << i << " " << points.Get(i).x << " " << points.Get(i).y - << " " << points.Get(i).z << endl; - - outfile << "#EDGE: " << edges.Size() << endl; - for (i = 1; i <= edges.Size(); i++) - outfile << " " << i << " 1 " - << edges.Get(i).p1 << " " - << edges.Get(i).p2 - << " 0" << endl; - - outfile << "#FACE: " << faces.Size() << endl; - for (i = 1; i <= faces.Size(); i++) - outfile << " " << i << " 1 3 " - << faces.Get(i).edges[0] << " " - << faces.Get(i).edges[1] << " " - << faces.Get(i).edges[2] << endl; - - outfile << "#SOLID: " << volelements.Size() << endl; - for (i = 1; i <= volelements.Size(); i++) - outfile << " " << i << " 1 4 " - << volelements.Get(i).faces[0] << " " - << volelements.Get(i).faces[1] << " " - << volelements.Get(i).faces[2] << " " - << volelements.Get(i).faces[3] << endl; - - outfile << "#END_OF_DATA" << endl; - } - - -void WriteUserChemnitz (const Mesh & mesh, - const string & filename) -{ - ofstream outfile (filename.c_str()); - - ReadFileMesh (mesh); - Convert (); - - WriteFile (outfile); - cout << "Wrote Chemnitz standard file" << endl; -} -} diff --git a/Netgen/libsrc/linalg/Makefile b/Netgen/libsrc/linalg/Makefile deleted file mode 100644 index 0cb19b0932..0000000000 --- a/Netgen/libsrc/linalg/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for linear algebra library -# -src = basemat.cpp densemat.cpp vector.cpp sparsmat.cpp polynomial.cpp -# -lib = la -libpath = libsrc/linalg -# -# -include ../makefile.inc -# - - diff --git a/Netgen/libsrc/linalg/basemat.cpp b/Netgen/libsrc/linalg/basemat.cpp deleted file mode 100644 index 889d79d668..0000000000 --- a/Netgen/libsrc/linalg/basemat.cpp +++ /dev/null @@ -1,472 +0,0 @@ -#ifdef ABC - -#include <mystdlib.h> -#include <linalg.hpp> - - -// ofstream (*myerr) ("error.out"); -// ofstream (*myerr) ("NUL"); - - -namespace netgen -{ - -double BaseMatrix :: shit = 0; - - -BaseMatrix :: BaseMatrix () - { - height = width = 0; - symmetric = 0; - } - -BaseMatrix :: BaseMatrix (INDEX h, INDEX w) - { - if (!w) w = h; - height = h; - width = w; - symmetric = 0; - } - -void BaseMatrix :: SetSize (INDEX h, INDEX w) - { - if (!w) w = h; - height = h; - width = w; - } - -void BaseMatrix :: SetSymmetric (int sym) - { - symmetric = sym; - } - -double & BaseMatrix :: operator() (INDEX, INDEX) - { - (*myerr) << "BaseMatrix: operator() called" << endl; - return shit; - } - -double BaseMatrix :: operator() (INDEX, INDEX) const - { - (*myerr) << "BaseMatrix: operator() called" << endl; - return 0; - } - - - -ostream & operator<<(ostream & s, const BaseMatrix & m) - { - return m.Print (s); - } - -ostream & BaseMatrix :: Print (ostream & s) const - { - if (Symmetric()) s << "Symmetric" << endl; - for (INDEX i = 1; i <= Height(); i++) - { - for (INDEX j = 1; j < Width(); j++) - s << (*this)(i, j) << " "; - s << (*this)(i, Width()) << endl; - } - - return s; - } - - - /* -TempVector BaseMatrix :: operator* (const Vector & v) const - { - Vector * prod = new Vector(Height()); - - if (Width() != v.Length()) - { - (*myerr) << "\nMatrix and Vector don't fit 1" << endl; - } - else if (Height() != prod->Length()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else - { - Mult (v, *prod); - } - - return *prod; - } - */ - - -DenseMatrix operator* (const BaseMatrix & m1, const BaseMatrix & m2) - { - DenseMatrix temp (m1.Height(), m2.Width()); - double sum; - - if (m1.Width() != m2.Height()) - { - (*myerr) << "BaseMatrix :: operator*: Matrix Size does not fit" << endl; - } - else if (temp.Height() != m1.Height()) - { - (*myerr) << "BaseMatrix :: operator*: temp not allocated" << endl; - } - else - { - for (INDEX i = 1; i <= m1.Height(); i++) - for (INDEX j = 1; j <= m2.Width(); j++) - { - sum = 0; - for (INDEX k = 1; k <= m1.Width(); k++) - sum += m1(i, k) * m2(k, j); - temp(i, j) = sum; - } - } - return temp; - } - - -DenseMatrix operator+ (const BaseMatrix & m1, const BaseMatrix & m2) - { - DenseMatrix temp (m1.Height(), m1.Width()); - INDEX i, j; - - if (m1.Width() != m2.Width() || m1.Height() != m2.Height()) - { - (*myerr) << "BaseMatrix :: operator+: Matrix Size does not fit" << endl; - } - else if (temp.Height() != m1.Height()) - { - (*myerr) << "BaseMatrix :: operator+: temp not allocated" << endl; - } - else - { - for (i = 1; i <= m1.Height(); i++) - for (j = 1; j <= m1.Width(); j++) - { - temp(i, j) = m1(i, j) + m2(i, j); - } - } - return temp; - } - - -void BaseMatrix :: Mult (const FlatVector & /* v */, - FlatVector & /* prod */) const - { - (*myerr) << "BaseMatrix :: Mult called" << endl; - double * x = 0; - *x = 1; - assert (1); - } - -void BaseMatrix :: MultTrans (const Vector & v, - Vector & prod) const - { - if (Symmetric()) - Mult (v, prod); - else - (*myerr) << "BaseMatrix :: MultTrans called for non symmetric matrix" << endl; - } - -void BaseMatrix :: Residuum (const Vector & x, - const Vector & b, Vector & res) const - { - Mult (x, res); - res *= -1; - res.Add (1, b); - } - -void BaseMatrix :: ResiduumTrans (const Vector & x, - const Vector & b, Vector & res) const - { - MultTrans (x, res); - res *= -1; - res.Add (1, b); - } - -BaseMatrix * BaseMatrix :: Copy () const - { - (*myerr) << "BaseMatrix :: Copy called" << endl; - return NULL; - } - - -Vector * BaseMatrix :: CreateVector () const - { - return new Vector (Height()); - } - - - -/* -void BaseMatrix :: Mult (const Vector & v, Vector & prod) const - { - double sum; - - prod.SetLength (Height()); - - if (Width() != v.Length()) - { - (*myerr) << "\nMatrix and Vector don't fit 2" << endl; - } - else if (Height() != prod.Length()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else - { - for (INDEX i = 1; i <= Height(); i++) - { - sum = 0; - - for (INDEX j = 1; j <= Width(); j++) - sum += (*this)(i,j) * v.Get(j); - - prod.Set (i, sum); - } - } - } - - -void BaseMatrix :: MultTrans (const Vector & v, Vector & prod) const - { - double sum; - - prod.SetLength (Width()); - - if (Height() != v.Length()) - { - (*myerr) << "\nMatrix and Vector don't fit 3" << endl; - } - else if (Width() != prod.Length()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else - { - for (INDEX i = 1; i <= Width(); i++) - { - sum = 0; - - for (INDEX j = 1; j <= Height(); j++) - sum += (*this)(j, i) * v.Get(j); - - prod.Set (i, sum); - } - } - } - - -void BaseMatrix :: Residuum (const Vector & x, const Vector & b, Vector & res) const - { - double sum; - - res.SetLength (Height()); - - if (Width() != x.Length() || Height() != b.Length()) - { - (*myerr) << "\nMatrix and Vector don't fit 4" << endl; - } - else if (Height() != res.Length()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else - { - for (INDEX i = 1; i <= Height(); i++) - { - sum = b.Get(i); - - for (INDEX j = 1; j <= Width(); j++) - sum -= (*this)(i,j) * x.Get(j); - - res.Set (i, sum); - } - } - } -*/ - - - - - - - -void BaseMatrix :: SolveDestroy (const Vector & v, Vector & sol) - { - INDEX i, j, k; - double q; - - if (Width() != Height()) - { - (*myerr) << "SolveDestroy: Matrix not square"; - return; - } - if (Width() != v.Size()) - { - (*myerr) << "SolveDestroy: Matrix and Vector don't fit"; - return; - } - - sol = v; - if (Height() != sol.Size()) - { - (*myerr) << "SolveDestroy: Solution Vector not ok"; - return; - } - - for (i = 1; i <= Height(); i++) - { - for (j = i+1; j <= Height(); j++) - { - q=(*this)(j,i) / (*this)(i,i); - for (k = i+1; k <= Height(); k++) - { - (*this)(j, k) -= q * (*this)(i,k); - } - sol.Elem(j) -= q * sol.Get(i); - } - } - - for (i = Height(); i >= 1; i--) - { - q = sol.Elem(i); - for (j = i+1; j <= Height(); j++) - { - q -= (*this)(i,j) * sol.Get(j); - } - sol.Elem(i) = q / (*this)(i,i); - } - } - -void BaseMatrix :: Solve (const Vector & v, Vector & sol) const - { - BaseMatrix * temp = Copy(); - - if (temp->Height() != Height()) - { - (*myerr) << "Solve: Matrix temp not allocated" << endl; - return; - } - - temp->SolveDestroy (v, sol); - - delete temp; - } - - - /* -Vector BaseMatrix :: SolveDestroyFunc (const Vector & b) const -{ - return Vector(0); -} -*/ - - -Vector BaseMatrix :: Solve (const Vector & v) const - { - Vector sol (v.Size()); - - if (Width() != Height()) - { - (*myerr) << "Solve: Matrix not square"; - return v; - } - if (Width() != v.Size()) - { - (*myerr) << "Solve: Matrix and Vector don't fit"; - return v; - } - if (Width() != sol.Size()) - { - (*myerr) << "Solve: Vector sol not allocated" << endl; - } - - Solve (v, sol); - - return sol; - } - - - - - - - -void BaseMatrix :: LU_Decomposition (DenseMatrix & l, DenseMatrix & u) const - { - INDEX i, j ,k; - double sum; - l.SetSize (Width()); - u.SetSize (Width()); - - for (i = 1; i <= Width(); i++) - for (j = 1; j <= Width(); j++) - l(i, j) = u(i, j) = 0; - - for (i = 1; i <= Width(); i++) - { - for (k = 1; k < i; k++) - { - sum = (*this)(i, k); - for (j = 1; j < k; j++) - sum -= l(i, j) * u(j, k); - l(i, k) = sum / u(k, k); - } - l(i, i) = 1; - - for (k = i; k <= Width(); k++) - { - sum = (*this)(i, k); - for (j = 1; j < i; j++) - sum -= l(i, j) * u(j, k); - u(i, k) = sum; - } - } - } - - - -void Transpose (const BaseMatrix & m1, DenseMatrix & m2) - { - m2.SetSize (m1.Width(), m1.Height()); - INDEX i, j; - - for (i = 1; i <= m1.Height(); i++) - for (j = 1; j <= m1.Width(); j++) - m2(j, i) = m1(i, j); - } - - - -DenseMatrix * BaseMatrix :: MakeDenseMatrix () const -{ - DenseMatrix * dmat = new DenseMatrix (Height(), Width()); - dmat -> SetSymmetric(Symmetric()); - - Vector x(Width()), y(Height()); - INDEX i, j; - - for (i = 1; i <= Width(); i++) - { - x = 0; - x.Elem(i) = 1; - Mult (x, y); - - for (j = 1; j <= Height(); j++) - dmat->Elem(j, i) = y.Get(j); - } - - return dmat; -} - - -BaseMatrix * BaseMatrix :: InverseMatrix (const BitArray * /* inner */) const -{ - (*mycout) << "called basematrix::inversemarix" << endl; - return NULL; -} - - - -} -#endif diff --git a/Netgen/libsrc/linalg/basemat.hpp b/Netgen/libsrc/linalg/basemat.hpp deleted file mode 100644 index d47abe790d..0000000000 --- a/Netgen/libsrc/linalg/basemat.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifdef NONE - -#ifndef FILE_BASEMAT -#define FILE_BASEMAT - -/**************************************************************************/ -/* File: basemat.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Oct. 94 */ -/**************************************************************************/ - -/* - Base type for linear operator -*/ - -class DenseMatrix; - -/// -class BaseMatrix -{ -protected: - /// - INDEX height, width; - /// - int symmetric; - /// - static double shit; - -public: - /// - BaseMatrix (); - /// - BaseMatrix (INDEX h, INDEX w = 0); - /// - virtual ~BaseMatrix () { }; - - /// - INDEX Width () const { return width; } - /// - INDEX Height () const { return height; } - /// - int Symmetric () const { return symmetric; } - - /// - virtual void SetSize (INDEX h, INDEX w = 0); - /// - virtual void SetSymmetric (int sym = 1); - - /// - virtual double & operator() (INDEX i, INDEX j); - /// - virtual double operator() (INDEX i, INDEX j) const; - - /// - friend ostream & operator<<(ostream & s, const BaseMatrix & m); - /// - virtual ostream & Print (ostream & s) const; - - /// - // TempVector operator* (const Vector & v) const; - - - /// - virtual void Mult (const FlatVector & v, FlatVector & prod) const; - /// - virtual void MultTrans (const Vector & v, Vector & prod) const; - /// - virtual void Residuum (const Vector & x, const Vector & b, Vector & res) const; - /// - virtual void ResiduumTrans (const Vector & x, const Vector & b, Vector & res) const; - // virtual double EvaluateBilinearform (const Vector & x); - - virtual BaseMatrix * Copy () const; - /// - virtual Vector * CreateVector () const; - - /// - virtual void AddElementMatrix (const ARRAY<INDEX> & /* pnum */, - const BaseMatrix & /* elemmat */) { }; - /// - virtual void MultElementMatrix (const ARRAY<INDEX> & /* pnum */, - const Vector & /* x */, Vector & /* y */) { }; - /// - virtual void MultTransElementMatrix (const ARRAY<INDEX> & /* pnum */, - const Vector & /* x */, Vector & /* y */) { }; - - - /// - virtual DenseMatrix * MakeDenseMatrix () const; - /// - virtual BaseMatrix * InverseMatrix (const class BitArray * inner = NULL) - const; - - /// - virtual void SolveDestroy (const Vector & b, Vector & x); - /// - void Solve (const Vector & b, Vector & x) const; - /// - // virtual Vector SolveDestroyFunc (const Vector & b) const; - /// - Vector Solve (const Vector & b) const; - /// - virtual void LU_Decomposition (DenseMatrix & l, DenseMatrix & u) const; -}; - - -#endif - -#endif diff --git a/Netgen/libsrc/linalg/densemat.cpp b/Netgen/libsrc/linalg/densemat.cpp deleted file mode 100644 index d15c123e0d..0000000000 --- a/Netgen/libsrc/linalg/densemat.cpp +++ /dev/null @@ -1,1443 +0,0 @@ -#include <mystdlib.h> - -#include <linalg.hpp> - - -namespace netgen -{ - DenseMatrix :: DenseMatrix () - { - data = NULL; - height = 0; - width = 0; - } - - DenseMatrix :: DenseMatrix (int h, int w) - { - if (!w) w = h; - width = w; - height = h; - if (h*w) - data = new double[h*w]; - else - data = 0; - - for (int i = 0 ; i < (h * w); i++) - data[i] = 0; - } - - /* - DenseMatrix :: DenseMatrix (int h, int w, const double * d) - : BaseMatrix (h, w) - { - int size = h * w; - int i; - - if (size) - { - data = new double[size]; - for (i = 0; i < size; i++) - data[i] = d[i]; - } - else - data = NULL; - } - */ - - DenseMatrix :: DenseMatrix (const DenseMatrix & m2) - { - data = NULL; - SetSize (m2.Height(), m2.Width()); - memcpy (data, m2.data, sizeof(double) * Height() * Width()); - } - - DenseMatrix :: ~DenseMatrix () - { - delete [] data; - } - - - void DenseMatrix :: SetSize (int h, int w) - { - if (!w) w = h; - if (height == h && width == w) return; - - height = h; - width = w; - - delete[] data; - - if (h*w) - data = new double[h*w]; - else - data = NULL; - } - - - /* -DenseMatrix & DenseMatrix :: operator= (const BaseMatrix & m2) - { - int i, j; - - SetSize (m2.Height(), m2.Width()); - - if (data) - for (i = 1; i <= Height(); i++) - for (j = 1; j <= Width(); j++) - Set (i, j, m2(i, j)); - else - (*myerr) << "DenseMatrix::Operator=: Matrix not allocated" << endl; - - return *this; - } - */ - - - DenseMatrix & DenseMatrix :: operator= (const DenseMatrix & m2) - { - SetSize (m2.Height(), m2.Width()); - - if (data) memcpy (data, m2.data, sizeof(double) * m2.Height() * m2.Width()); - return *this; - } - - - DenseMatrix & DenseMatrix :: operator+= (const DenseMatrix & m2) - { - int i; - double * p, * q; - - if (Height() != m2.Height() || Width() != m2.Width()) - { - (*myerr) << "DenseMatrix::Operator+=: Sizes don't fit" << endl; - return *this; - } - - if (data) - { - p = data; - q = m2.data; - for (i = Width() * Height(); i > 0; i--) - { - *p += *q; - p++; - q++; - } - } - else - (*myerr) << "DenseMatrix::Operator+=: Matrix not allocated" << endl; - - return *this; - } - - -DenseMatrix & DenseMatrix :: operator-= (const DenseMatrix & m2) - { - int i; - double * p, * q; - - if (Height() != m2.Height() || Width() != m2.Width()) - { - (*myerr) << "DenseMatrix::Operator-=: Sizes don't fit" << endl; - return *this; - } - - if (data) - { - p = data; - q = m2.data; - for (i = Width() * Height(); i > 0; i--) - { - *p -= *q; - p++; - q++; - } - } - else - (*myerr) << "DenseMatrix::Operator-=: Matrix not allocated" << endl; - - return *this; - } - - - - - /* -double & DenseMatrix :: operator() (int i, int j) -{ - if (i >= 1 && j >= 1 && i <= height && j <= width) - return Elem(i,j); - else (*myerr) << "DenseMatrix: index (" << i << "," << j << ") out of range (1.." - << height << ",1.." << width << ")\n"; - static double dummy = 0; - return dummy; -} - - double DenseMatrix :: operator() (int i, int j) const - { - if (i >= 1 && j >= 1 && i <= height && j <= width) - return Get(i,j); - else (*myerr) << "DenseMatrix: index (" << i << "," << j << ") out of range (1.." - << height << ",1.." << width << ")\n"; - - static double dummy = 0; - return dummy; - } - */ - -DenseMatrix & DenseMatrix :: operator= (double v) - { - int i; - double * p = data; - - if (data) - for (i = width*height; i > 0; i--, p++) - *p = v; - - return *this; - } - - - -DenseMatrix & DenseMatrix :: operator*= (double v) - { - int i; - double * p = data; - - if (data) - for (i = width*height; i > 0; i--, p++) - *p *= v; - - return *this; - } - - -double DenseMatrix :: Det () const - { - if (width != height) - { - (*myerr) << "DenseMatrix :: Det: width != height" << endl; - return 0; - } - - switch (width) - { - case 1: return Get(1, 1); - case 2: return Get(1) * Get(4) - Get(2) * Get(3); - - case 3: return Get(1) * Get(5) * Get(9) - + Get(2) * Get(6) * Get(7) - + Get(3) * Get(4) * Get(8) - - Get(1) * Get(6) * Get(8) - - Get(2) * Get(4) * Get(9) - - Get(3) * Get(5) * Get(7); - default: - { - (*myerr) << "Matrix :: Det: general size not implemented (size=" << width << ")" << endl; - return 0; - } - } - } - - -void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2) - { - // int i, j, k, n; - double det; - // DenseMatrix m1 = hm1; - - if (m1.width != m1.height) - { - (*myerr) << "CalcInverse: matrix not symmetric" << endl; - return; - } - if (m1.width != m2.width || m1.height != m2.height) - { - (*myerr) << "CalcInverse: dim(m2) != dim(m1)" << endl; - return; - } - - - if (m1.Width() <= 3) - { - det = m1.Det(); - if (det == 0) - { - (*myerr) << "CalcInverse: Matrix singular" << endl; - return; - } - - det = 1e0 / det; - switch (m1.width) - { - case 1: - { - m2.Set(1, 1, det); - return; - } - case 2: - { - m2.Set(1, 1, det * m1.Get(4)); - m2.Set(2, 2, det * m1.Get(1)); - m2.Set(1, 2, - det * m1.Get(2)); - m2.Set(2, 1, - det * m1.Get(3)); - return; - } - case 3: - { - m2.Set(1, 1, det * (m1.Get(5) * m1.Get(9) - m1.Get(6) * m1.Get(8))); - m2.Set(2, 1, -det * (m1.Get(4) * m1.Get(9) - m1.Get(6) * m1.Get(7))); - m2.Set(3, 1, det * (m1.Get(4) * m1.Get(8) - m1.Get(5) * m1.Get(7))); - - m2.Set(1, 2, -det * (m1.Get(2) * m1.Get(9) - m1.Get(3) * m1.Get(8))); - m2.Set(2, 2, det * (m1.Get(1) * m1.Get(9) - m1.Get(3) * m1.Get(7))); - m2.Set(3, 2, -det * (m1.Get(1) * m1.Get(8) - m1.Get(2) * m1.Get(7))); - - m2.Set(1, 3, det * (m1.Get(2) * m1.Get(6) - m1.Get(3) * m1.Get(5))); - m2.Set(2, 3, -det * (m1.Get(1) * m1.Get(6) - m1.Get(3) * m1.Get(4))); - m2.Set(3, 3, det * (m1.Get(1) * m1.Get(5) - m1.Get(2) * m1.Get(4))); - return; - } - } - } - - else - { - int i, j, k, n; - n = m1.Height(); - - -#ifdef CHOL - int dots = (n > 200); - - // Cholesky - - double x; - Vector p(n); - - m2 = m1; - /* - m2.SetSymmetric(); - if (!m2.Symmetric()) - cerr << "m should be symmetric for Cholesky" << endl; - */ - - for (i = 1; i <= n; i++) - for (j = 1; j < i; j++) - m2.Elem(j, i) = m2.Get(i, j); - - for (i = 1; i <= n; i++) - { - if (dots && i % 10 == 0) - (*mycout) << "." << flush; - - for (j = i; j <= n; j++) - { - x = m2.Get(i, j); - - const double * pik = &m2.Get(i, 1); - const double * pjk = &m2.Get(j, 1); - - for (k = i-2; k >= 0; --k, ++pik, ++pjk) - x -= (*pik) * (*pjk); - - // for (k = i-1; k >= 1; --k) - // x -= m2.Get(j, k) * m2.Get(i, k); - - if (i == j) - { - if (x <= 0) - { - cerr << "Matrix indefinite 1" << endl; - return; - } - - p.Elem(i) = 1 / sqrt(x); - } - else - { - m2.Elem(j, i) = x * p.Get(i); - } - } - } - - for (i = 1; i <= n; i++) - m2.Elem(i, i) = 1 / p.Get(i); - - // check: A = L L^t - -// for (i = 1; i <= n; i++) -// for (j = 1; j <= n; j++) -// { -// x = 0; -// for (k = 1; k <= i && k <= j; k++) -// x += m2.Get(i, k) * m2.Get(j, k); -// (*testout) << "err " << i << "," << j << " = " << (m1.Get(i, j) - x) << endl; -// } - - - - // calc L^{-1}, store upper triangle - - // DenseMatrix hm(n); - // hm = m2; - - for (i = 1; i <= n; i++) - { - if (dots && i % 10 == 0) - (*mycout) << "+" << flush; - - for (j = i; j <= n; j++) - { - x = 0; - if (j == i) x = 1; - - const double * pjk = &m2.Get(j, i); - const double * pik = &m2.Get(i, i); - for (k = i; k < j; k++, ++pjk, ++pik) - x -= *pik * *pjk; - - // for (k = i; k < j; k++) - // x -= m2.Get(j, k) * m2.Get(i, k); - - m2.Elem(i, j) = x / m2.Get(j, j); - } - } - -// (*testout) << "check L^-1" << endl; -// for (i = 1; i <= n; i++) -// for (j = 1; j <= n; j++) -// { -// x = 0; -// for (k = j; k <= i; k++) -// x += hm.Get(i, k) * m2.Get(j, k); -// (*testout) << "i, j = " << i << "," << j << " x = " << x << endl; -// } - - - // calc A^-1 = L^-T * L^-1 - - for (i = 1; i <= n; i++) - { - if (dots && i % 10 == 0) - (*mycout) << "-" << flush; - - for (j = 1; j <= i; j++) - { - x = 0; - k = i; - if (j > i) k = j; - - const double * pik = &m2.Get(i, k); - const double * pjk = &m2.Get(j, k); - - for ( ; k <= n; ++k, ++pik, ++pjk) - x += *pik * *pjk; - // for ( ; k <= n; k++) - // x += m2.Get(i, k) * m2.Get(j, k); - - m2.Elem(i, j) = x; - } - } - - for (i = 1; i <= n; i++) - for (j = 1; j < i; j++) - m2.Elem(j, i) = m2.Get(i, j); - - if (dots) (*mycout) << endl; -#endif - - - - // Gauss - Jordan - algorithm - - int r, hi; - double max, hr; - - - ARRAY<int> p(n); // pivot-permutation - Vector hv(n); - - - m2 = m1; - - /* - if (m2.Symmetric()) - for (i = 1; i <= n; i++) - for (j = 1; j < i; j++) - m2.Elem(j, i) = m2.Get(i, j); - */ - - // Algorithm of Stoer, Einf. i. d. Num. Math, S 145 - - for (j = 1; j <= n; j++) - p.Set(j, j); - - for (j = 1; j <= n; j++) - { - // pivot search - - max = fabs(m2.Get(j, j)); - r = j; - - for (i = j+1; i <= n ;i++) - if (fabs (m2.Get(i, j)) > max) - { - r = i; - max = fabs (m2.Get(i, j)); - } - - if (max < 1e-20) - { - cerr << "Inverse matrix: matrix singular" << endl; - return; - } - - r = j; - - // exchange rows - if (r > j) - { - for (k = 1; k <= n; k++) - { - hr = m2.Get(j, k); - m2.Elem(j, k) = m2.Get(r, k); - m2.Elem(r, k) = hr; - } - hi = p.Get(j); - p.Elem(j) = p.Get(r); - p.Elem(r) = hi; - } - - - // transformation - - hr = 1 / m2.Get(j, j); - for (i = 1; i <= n; i++) - m2.Elem(i, j) *= hr; - m2.Elem(j, j) = hr; - - for (k = 1; k <= n; k++) - if (k != j) - { - for (i = 1; i <= n; i++) - if (i != j) - m2.Elem(i, k) -= m2.Elem(i, j) * m2.Elem(j, k); - m2.Elem(j, k) *= -hr; - } - } - - // col exchange - - for (i = 1; i <= n; i++) - { - for (k = 1; k <= n; k++) - hv.Elem(p.Get(k)) = m2.Get(i, k); - for (k = 1; k <= n; k++) - m2.Elem(i, k) = hv.Get(k); - } - - - - /* - if (m1.Symmetric()) - for (i = 1; i <= n; i++) - for (j = 1; j < i; j++) - m1.Elem(j, i) = m1.Get(i, j); - - m2 = 0; - - for (i = 1; i <= n; i++) - m2.Elem(i, i) = 1; - - for (i = 1; i <= n; i++) - { - // (*mycout) << '.' << flush; - q = m1.Get(i, i); - for (k = 1; k <= n; k++) - { - m1.Elem(i, k) /= q; - m2.Elem(i, k) /= q; - } - - for (j = i+1; j <= n; j++) - { - q = m1.Elem(j, i); - - double * m1pi = &m1.Elem(i, i); - double * m1pj = &m1.Elem(j, i); - - for (k = n; k >= i; --k, ++m1pi, ++m1pj) - *m1pj -= q * (*m1pi); - - double * m2pi = &m2.Elem(i, 1); - double * m2pj = &m2.Elem(j, 1); - - for (k = i; k > 0; --k, ++m2pi, ++m2pj) - *m2pj -= q * (*m2pi); - - // for (k = 1; k <= n; k++) - // { - // m1.Elem(j, k) -= q * m1.Elem(i, k); - // m2.Elem(j, k) -= q * m2.Elem(i, k); - // } - - } - } - - for (i = n; i >= 1; i--) - { - // (*mycout) << "+" << flush; - for (j = 1; j < i; j++) - { - q = m1.Elem(j, i); - - double * m2pi = &m2.Elem(i, 1); - double * m2pj = &m2.Elem(j, 1); - - for (k = n; k > 0; --k, ++m2pi, ++m2pj) - *m2pj -= q * (*m2pi); - - - // for (k = 1; k <= n; k++) - // { - // m1.Elem(j, k) -= q * m1.Elem(i, k); - // m2.Elem(j, k) -= q * m2.Elem(i, k); - // } - } - } - - if (m2.Symmetric()) - { - for (i = 1; i <= n; i++) - for (j = 1; j < i; j++) - m2.Elem(i, j) = m2.Elem(j, i); - } -*/ - } - } - - -void CalcAAt (const DenseMatrix & a, DenseMatrix & m2) - { - int n1 = a.Height(); - int n2 = a.Width(); - int i, j, k; - double sum; - const double *p, *q, *p0; - - if (m2.Height() != n1 || m2.Width() != n1) - { - (*myerr) << "CalcAAt: sizes don't fit" << endl; - return; - } - - for (i = 1; i <= n1; i++) - { - sum = 0; - p = &a.ConstElem(i, 1); - for (k = 1; k <= n2; k++) - { - sum += *p * *p; - p++; - } - m2.Set(i, i, sum); - - p0 = &a.ConstElem(i, 1); - q = a.data; - for (j = 1; j < i; j++) - { - sum = 0; - p = p0; - - for (k = 1; k <= n2; k++) - { - sum += *p * *q; - p++; - q++; - } - m2.Set(i, j, sum); - m2.Set(j, i, sum); - } - } - } - - - -#ifdef ABC -BaseMatrix * DenseMatrix :: InverseMatrix (const BitArray * /* inner */) const -{ - if (Height() != Width()) - { - (*myerr) << "BaseMatrix::InverseMatrix(): Matrix not symmetric" << endl; - return new DenseMatrix(1); - } - else - { - if (Symmetric()) - { - (*mycout) << "Invmat not available" << endl; - BaseMatrix * invmat = NULL; - return invmat; - } - - DenseMatrix * invmat = new DenseMatrix (Height()); - - CalcInverse (*this, *invmat); - return invmat; - } -} -#endif - - - -void CalcAtA (const DenseMatrix & a, DenseMatrix & m2) - { - int n1 = a.Height(); - int n2 = a.Width(); - int i, j, k; - double sum; - - if (m2.Height() != n2 || m2.Width() != n2) - { - (*myerr) << "CalcAtA: sizes don't fit" << endl; - return; - } - - for (i = 1; i <= n2; i++) - for (j = 1; j <= n2; j++) - { - sum = 0; - for (k = 1; k <= n1; k++) - sum += a.Get(k, i) * a.Get(k, j); - m2.Elem(i, j) = sum; - } - } - - - - - - -void CalcABt (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2) - { - int n1 = a.Height(); - int n2 = a.Width(); - int n3 = b.Height(); - int i, j, k; - double sum; - - if (m2.Height() != n1 || m2.Width() != n3 || b.Width() != n2) - { - (*myerr) << "CalcABt: sizes don't fit" << endl; - return; - } - - double * pm2 = &m2.Elem(1, 1); - const double * pa1 = &a.Get(1, 1); - - for (i = 1; i <= n1; i++) - { - const double * pb = &b.Get(1, 1); - for (j = 1; j <= n3; j++) - { - sum = 0; - const double * pa = pa1; - - for (k = 1; k <= n2; k++) - { - sum += *pa * *pb; - pa++; pb++; - } - - *pm2 = sum; - pm2++; - } - pa1 += n2; - } - } - - -void CalcAtB (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2) - { - int n1 = a.Height(); - int n2 = a.Width(); - int n3 = b.Width(); - int i, j, k; - - if (m2.Height() != n2 || m2.Width() != n3 || b.Height() != n1) - { - (*myerr) << "CalcAtB: sizes don't fit" << endl; - return; - } - - for (i = 1; i <= n2 * n3; i++) - m2.data[i-1] = 0; - - for (i = 1; i <= n1; i++) - for (j = 1; j <= n2; j++) - { - const double va = a.Get(i, j); - double * pm2 = &m2.Elem(j, 1); - const double * pb = &b.Get(i, 1); - - for (k = 1; k <= n3; ++k, ++pm2, ++pb) - *pm2 += va * *pb; - // for (k = 1; k <= n3; k++) - // m2.Elem(j, k) += va * b.Get(i, k); - } - /* - for (i = 1; i <= n2; i++) - for (j = 1; j <= n3; j++) - { - sum = 0; - for (k = 1; k <= n1; k++) - sum += a.Get(k, i) * b.Get(k, j); - m2.Elem(i, j) = sum; - } - */ - } - - - - - - - -DenseMatrix operator* (const DenseMatrix & m1, const DenseMatrix & m2) - { - DenseMatrix temp (m1.Height(), m2.Width()); - - if (m1.Width() != m2.Height()) - { - (*myerr) << "DenseMatrix :: operator*: Matrix Size does not fit" << endl; - } - else if (temp.Height() != m1.Height()) - { - (*myerr) << "DenseMatrix :: operator*: temp not allocated" << endl; - } - else - { - Mult (m1, m2, temp); - } - return temp; - } - - -void Mult (const DenseMatrix & m1, const DenseMatrix & m2, DenseMatrix & m3) - { - double sum; - double *p1, *p1s, *p1sn, *p1snn, *p2, *p2s, *p2sn, *p3; - - if (m1.Width() != m2.Height() || m1.Height() != m3.Height() || - m2.Width() != m3.Width() ) - { - (*myerr) << "DenseMatrix :: Mult: Matrix Size does not fit" << endl; - (*myerr) << "m1: " << m1.Height() << " x " << m1.Width() << endl; - (*myerr) << "m2: " << m2.Height() << " x " << m2.Width() << endl; - (*myerr) << "m3: " << m3.Height() << " x " << m3.Width() << endl; - return; - } - /* - else if (m1.Symmetric() || m2.Symmetric() || m3.Symmetric()) - { - (*myerr) << "DenseMatrix :: Mult: not implemented for symmetric matrices" << endl; - return; - } - */ - else - { - // int i, j, k; - int n1 = m1.Height(); - int n2 = m2.Width(); - int n3 = m1.Width(); - - /* - for (i = n1 * n2-1; i >= 0; --i) - m3.data[i] = 0; - - const double * pm1 = &m1.Get(1, 1); - for (i = 1; i <= n1; i++) - { - const double * pm2 = &m2.Get(1, 1); - double * pm3i = &m3.Elem(i, 1); - - for (j = 1; j <= n3; j++) - { - const double vm1 = *pm1; - ++pm1; - // const double vm1 = m1.Get(i, j); - double * pm3 = pm3i; - // const double * pm2 = &m2.Get(j, 1); - - for (k = 0; k < n2; k++) - { - *pm3 += vm1 * *pm2; - ++pm2; - ++pm3; - } - - // for (k = 1; k <= n2; k++) - // m3.Elem(i, k) += m1.Get(i, j) * m2.Get(j, k); - } - } - */ - - /* - for (i = 1; i <= n1; i++) - for (j = 1; j <= n2; j++) - { - sum = 0; - for (k = 1; k <= n3; k++) - sum += m1.Get(i, k) * m2.Get(k, j); - m3.Set(i, j, sum); - } - */ - - - /* - for (i = 1; i <= n1; i++) - { - const double pm1i = &m1.Get(i, 1); - const double pm2j = &m2.Get(1, 1); - - for (j = 1; j <= n2; j++) - { - double sum = 0; - const double * pm1 = pm1i; - const double * pm2 = pm2j; - pm2j++; - - for (k = 1; k <= n3; k++) - { - sum += *pm1 * *pm2; - ++pm1; - pm2 += n2; - } - - m3.Set (i, j, sum); - } - } - */ - - - p3 = m3.data; - p1s = m1.data; - p2sn = m2.data + n2; - p1snn = p1s + n1 * n3; - - while (p1s != p1snn) - { - p1sn = p1s + n3; - p2s = m2.data; - - while (p2s != p2sn) - { - sum = 0; - p1 = p1s; - p2 = p2s; - p2s++; - - while (p1 != p1sn) - { - sum += *p1 * *p2; - p1++; - p2 += n2; - } - *p3++ = sum; - } - p1s = p1sn; - } - } - } - - - -DenseMatrix operator+ (const DenseMatrix & m1, const DenseMatrix & m2) - { - DenseMatrix temp (m1.Height(), m1.Width()); - int i, j; - - if (m1.Width() != m2.Width() || m1.Height() != m2.Height()) - { - (*myerr) << "BaseMatrix :: operator+: Matrix Size does not fit" << endl; - } - else if (temp.Height() != m1.Height()) - { - (*myerr) << "BaseMatrix :: operator+: temp not allocated" << endl; - } - else - { - for (i = 1; i <= m1.Height(); i++) - for (j = 1; j <= m1.Width(); j++) - { - temp.Set(i, j, m1.Get(i, j) + m2.Get(i, j)); - } - } - return temp; - } - - - - -void Transpose (const DenseMatrix & m1, DenseMatrix & m2) -{ - int w = m1.Width(); - int h = m1.Height(); - int i, j; - - m2.SetSize (w, h); - - double * pm2 = &m2.Elem(1, 1); - for (j = 1; j <= w; j++) - { - const double * pm1 = &m1.Get(1, j); - for (i = 1; i <= h; i++) - { - *pm2 = *pm1; - pm2 ++; - pm1 += w; - } - } -} - - -/* -void DenseMatrix :: Mult (const Vector & v, Vector & prod) const - { - double sum, val; - const double * mp, * sp; - double * dp; - // const Vector & v = bv.CastToVector(); - // Vector & prod = bprod.CastToVector(); - - - int n = Height(); - int m = Width(); - - if (prod.Size() != n) - prod.SetSize (n); - -#ifdef DEVELOP - if (!n) - { - cout << "DenseMatrix::Mult mheight = 0" << endl; - } - if (!m) - { - cout << "DenseMatrix::Mult mwidth = 0" << endl; - } - - if (m != v.Size()) - { - (*myerr) << "\nMatrix and Vector don't fit" << endl; - } - else if (Height() != prod.Size()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else -#endif - { - if (Symmetric()) - { - int i, j; - - - for (i = 1; i <= n; i++) - { - sp = &v.Get(1); - dp = &prod.Elem(1); - mp = &Get(i, 1); - - val = v.Get(i); - sum = Get(i, i) * val; - - for (j = 1; j < i; ++j, ++mp, ++sp, ++dp) - { - sum += *mp * *sp; - *dp += val * *mp; - } - - prod.Elem(i) = sum; - } - } - else - { - mp = data; - dp = &prod.Elem(1); - for (int i = 1; i <= n; i++) - { - sum = 0; - sp = &v.Get(1); - - for (int j = 1; j <= m; j++) - { - // sum += Get(i,j) * v.Get(j); - sum += *mp * *sp; - mp++; - sp++; - } - - // prod.Set (i, sum); - *dp = sum; - dp++; - } - } - } - } -*/ - -void DenseMatrix :: MultTrans (const Vector & v, Vector & prod) const -{ - // const Vector & v = (const Vector&)bv; // .CastToVector(); - // Vector & prod = (Vector & )bprod; // .CastToVector(); - - /* - if (Height() != v.Size()) - { - (*myerr) << "\nMatrix and Vector don't fit" << endl; - } - else if (Width() != prod.Size()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else - */ - { - int i, j; - int w = Width(), h = Height(); - if (prod.Size() != w) - prod.SetSize (w); - - const double * pmat = &Get(1, 1); - const double * pv = &v.Get(1); - - prod = 0; - - for (i = 1; i <= h; i++) - { - double val = *pv; - ++pv; - - double * pprod = &prod.Elem(1); - - for (j = w-1; j >= 0; --j, ++pmat, ++pprod) - { - *pprod += val * *pmat; - } - } - - /* - double sum; - - for (i = 1; i <= Width(); i++) - { - sum = 0; - - for (int j = 1; j <= Height(); j++) - sum += Get(j, i) * v.Get(j); - - prod.Set (i, sum); - } - */ - } - } - - -void DenseMatrix :: Residuum (const Vector & x, const Vector & b, - Vector & res) const - { - double sum; - // const Vector & x = bx.CastToVector(); - // const Vector & b = bb.CastToVector(); - // Vector & res = bres.CastToVector(); - - res.SetSize (Height()); - - if (Width() != x.Size() || Height() != b.Size()) - { - (*myerr) << "\nMatrix and Vector don't fit" << endl; - } - else if (Height() != res.Size()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else - { - int i, j; - int h = Height(); - int w = Width(); - const double * mp = &Get(1, 1); - - for (i = 1; i <= h; i++) - { - sum = b.Get(i); - const double * xp = &x.Get(1); - - for (j = 1; j <= w; ++j, ++mp, ++xp) - sum -= *mp * *xp; - - res.Elem(i) = sum; - } - } - } - -#ifdef ABC -double DenseMatrix :: EvaluateBilinearform (const Vector & hx) const - { - double sum = 0, hsum; - // const Vector & hx = x.CastToVector(); - int i, j; - - if (Width() != hx.Size() || Height() != hx.Size()) - { - (*myerr) << "Matrix::EvaluateBilinearForm: sizes don't fit" << endl; - } - else - { - for (i = 1; i <= Height(); i++) - { - hsum = 0; - for (j = 1; j <= Height(); j++) - { - hsum += Get(i, j) * hx.Get(j); - } - sum += hsum * hx.Get(i); - } - } - -// testout << "sum = " << sum << endl; - return sum; - } - - -void DenseMatrix :: MultElementMatrix (const ARRAY<int> & pnum, - const Vector & hx, Vector & hy) - { - int i, j; - // const Vector & hx = x.CastToVector(); - // Vector & hy = y.CastToVector(); - - if (Symmetric()) - { - for (i = 1; i <= Height(); i++) - { - for (j = 1; j < i; j++) - { - hy.Elem(pnum.Get(i)) += Get(i, j) * hx.Get(pnum.Get(j)); - hy.Elem(pnum.Get(j)) += Get(i, j) * hx.Get(pnum.Get(i)); - } - hy.Elem(pnum.Get(j)) += Get(i, i) * hx.Get(pnum.Get(i)); - } - } - else - for (i = 1; i <= Height(); i++) - for (j = 1; j <= Width(); j++) - hy.Elem(pnum.Get(i)) += Get(i, j) * hx.Get(pnum.Get(j)); - - } - -void DenseMatrix :: MultTransElementMatrix (const ARRAY<int> & pnum, - const Vector & hx, Vector & hy) - { - int i, j; - // const Vector & hx = x.CastToVector(); - // Vector & hy = y.CastToVector(); - - if (Symmetric()) - MultElementMatrix (pnum, hx, hy); - else - for (i = 1; i <= Height(); i++) - for (j = 1; j <= Width(); j++) - hy.Elem(pnum.Get(i)) += Get(j, i) * hx.Get(pnum.Get(j)); - } -#endif - - -void DenseMatrix :: Solve (const Vector & v, Vector & sol) const -{ - DenseMatrix temp (*this); - temp.SolveDestroy (v, sol); -} - - -void DenseMatrix :: SolveDestroy (const Vector & v, Vector & sol) - { - double q; - - if (Width() != Height()) - { - (*myerr) << "SolveDestroy: Matrix not square"; - return; - } - if (Width() != v.Size()) - { - (*myerr) << "SolveDestroy: Matrix and Vector don't fit"; - return; - } - - sol = v; - if (Height() != sol.Size()) - { - (*myerr) << "SolveDestroy: Solution Vector not ok"; - return; - } - - - if (0 /* Symmetric() */) - { - - // Cholesky factorization - - int i, j, k, n; - n = Height(); - - // Cholesky - - double x; - Vector p(n); - - for (i = 1; i <= n; i++) - for (j = 1; j < i; j++) - Elem(j, i) = Get(i, j); - - for (i = 1; i <= n; i++) - { - // (*mycout) << "." << flush; - for (j = i; j <= n; j++) - { - x = Get(i, j); - - const double * pik = &Get(i, 1); - const double * pjk = &Get(j, 1); - - for (k = i-2; k >= 0; --k, ++pik, ++pjk) - x -= (*pik) * (*pjk); - - // for (k = i-1; k >= 1; --k) - // x -= Get(j, k) * Get(i, k); - - if (i == j) - { - if (x <= 0) - { - cerr << "Matrix indefinite" << endl; - return; - } - - p.Elem(i) = 1 / sqrt(x); - } - else - { - Elem(j, i) = x * p.Get(i); - } - } - } - - for (i = 1; i <= n; i++) - Elem(i, i) = 1 / p.Get(i); - - // A = L L^t - // L stored in left-lower triangle - - - sol = v; - - // Solve L sol = sol - - for (i = 1; i <= n; i++) - { - double val = sol.Get(i); - - const double * pij = &Get(i, 1); - const double * solj = &sol.Get(1); - - for (j = 1; j < i; j++, ++pij, ++solj) - val -= *pij * *solj; - // for (j = 1; j < i; j++) - // val -= Get(i, j) * sol.Get(j); - - sol.Elem(i) = val / Get(i, i); - } - - // Solve L^t sol = sol - - for (i = n; i >= 1; i--) - { - double val = sol.Get(i) / Get(i, i); - sol.Elem(i) = val; - - double * solj = &sol.Elem(1); - const double * pij = &Get(i, 1); - - for (j = 1; j < i; ++j, ++pij, ++solj) - *solj -= val * *pij; - // for (j = 1; j < i; j++) - // sol.Elem(j) -= Get(i, j) * val; - } - - - } - else - { - // (*mycout) << "gauss" << endl; - int i, j, k, n = Height(); - for (i = 1; i <= n; i++) - { - for (j = i+1; j <= n; j++) - { - q = Get(j,i) / Get(i,i); - if (q) - { - const double * pik = &Get(i, i+1); - double * pjk = &Elem(j, i+1); - - for (k = i+1; k <= n; ++k, ++pik, ++pjk) - *pjk -= q * *pik; - - // for (k = i+1; k <= Height(); k++) - // Elem(j, k) -= q * Get(i,k); - - - sol.Elem(j) -= q * sol.Get(i); - } - } - } - - for (i = n; i >= 1; i--) - { - q = sol.Get(i); - for (j = i+1; j <= n; j++) - q -= Get(i,j) * sol.Get(j); - - sol.Elem(i) = q / Get(i,i); - } - } - } - - -/* -BaseMatrix * DenseMatrix :: Copy () const - { - return new DenseMatrix (*this); - } -*/ - - - - -ostream & operator<< (ostream & ost, const DenseMatrix & m) -{ - for (int i = 0; i < m.Height(); i++) - { - for (int j = 0; j < m.Width(); j++) - ost << m.Get(i+1,j+1) << " "; - ost << endl; - } - return ost; -} - - - -} diff --git a/Netgen/libsrc/linalg/densemat.hpp b/Netgen/libsrc/linalg/densemat.hpp deleted file mode 100644 index fadb128d6a..0000000000 --- a/Netgen/libsrc/linalg/densemat.hpp +++ /dev/null @@ -1,260 +0,0 @@ -#ifndef FILE_DENSEMAT -#define FILE_DENSEMAT - -/**************************************************************************/ -/* File: densemat.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Oct. 94 */ -/**************************************************************************/ - -/** - Data type dense matrix -*/ - - -#include <assert.h> - -class DenseMatrix -{ -protected: - int height; - int width; - double * data; - -public: - /// - DenseMatrix (); - /// - DenseMatrix (int h, int w = 0); - /// - DenseMatrix (const DenseMatrix & m2); - /// - ~DenseMatrix (); - - /// - void SetSize (int h, int w = 0); - - int Height() const { return height; } - int Width() const { return width; } - - double & operator() (int i, int j) { return data[i*width+j]; } - double operator() (int i, int j) const { return data[i*width+j]; } - double & operator() (int i) { return data[i]; } - double operator() (int i) const { return data[i]; } - - /// - DenseMatrix & operator= (const DenseMatrix & m2); - /// - DenseMatrix & operator+= (const DenseMatrix & m2); - /// - DenseMatrix & operator-= (const DenseMatrix & m2); - - /// - DenseMatrix & operator= (double v); - /// - DenseMatrix & operator*= (double v); - - /// - void Mult (const FlatVector & v, FlatVector & prod) const - { - double sum; - const double * mp, * sp; - double * dp; - -#ifdef DEBUG - if (prod.Size() != height) - { - cerr << "Mult: wrong vector size " << endl; - assert (1); - // prod.SetSize (height); - } - - - if (!height) - { - cout << "DenseMatrix::Mult height = 0" << endl; - } - if (!width) - { - cout << "DenseMatrix::Mult width = 0" << endl; - } - - if (width != v.Size()) - { - (*myerr) << "\nMatrix and Vector don't fit" << endl; - } - else if (Height() != prod.Size()) - { - (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; - } - else -#endif - { - mp = data; - dp = &prod.Elem(1); - for (int i = 1; i <= height; i++) - { - sum = 0; - sp = &v.Get(1); - - for (INDEX j = 1; j <= width; j++) - { - // sum += Get(i,j) * v.Get(j); - sum += *mp * *sp; - mp++; - sp++; - } - - *dp = sum; - dp++; - } - } - } - - /// - void MultTrans (const Vector & v, Vector & prod) const; - /// - void Residuum (const Vector & x, const Vector & b, Vector & res) const; - /// - double Det () const; - - /// - friend DenseMatrix operator* (const DenseMatrix & m1, const DenseMatrix & m2); - /// - friend DenseMatrix operator+ (const DenseMatrix & m1, const DenseMatrix & m2); - - /// - friend void Transpose (const DenseMatrix & m1, DenseMatrix & m2); - /// - friend void Mult (const DenseMatrix & m1, const DenseMatrix & m2, DenseMatrix & m3); - /// - friend void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2); - /// - friend void CalcAAt (const DenseMatrix & a, DenseMatrix & m2); - /// - friend void CalcAtA (const DenseMatrix & a, DenseMatrix & m2); - /// - friend void CalcABt (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2); - /// - friend void CalcAtB (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2); - /// - void Solve (const Vector & b, Vector & x) const; - /// - void SolveDestroy (const Vector & b, Vector & x); - /// - const double & Get(INDEX i, INDEX j) const { return data[(i-1)*width+j-1]; } - /// - const double & Get(INDEX i) const { return data[i-1]; } - /// - void Set(INDEX i, INDEX j, double v) { data[(i-1)*width+j-1] = v; } - /// - double & Elem(INDEX i, INDEX j) { return data[(i-1)*width+j-1]; } - /// - const double & ConstElem(INDEX i, INDEX j) const { return data[(i-1)*width+j-1]; } -}; - - -extern ostream & operator<< (ostream & ost, const DenseMatrix & m); - - - -template <int WIDTH> -class MatrixFixWidth -{ -protected: - int height; - double * data; - -public: - /// - MatrixFixWidth () - { height = 0; data = 0; } - /// - MatrixFixWidth (int h) - { height = h; data = new double[WIDTH*height]; } - /// - ~MatrixFixWidth () - { delete [] data; } - - void SetSize (int h) - { - if (h != height) - { - delete data; - height = h; - data = new double[WIDTH*height]; - } - } - - /// - int Height() const { return height; } - - /// - int Width() const { return WIDTH; } - - /// - MatrixFixWidth & operator= (double v) - { - for (int i = 0; i < height*WIDTH; i++) - data[i] = v; - return *this; - } - - /// - void Mult (const FlatVector & v, FlatVector & prod) const - { - double sum; - const double * mp, * sp; - double * dp; - - /* - if (prod.Size() != height) - { - cerr << "MatrixFixWidth::Mult: wrong vector size " << endl; - assert (1); - } - */ - - mp = data; - dp = &prod[0]; - for (int i = 0; i < height; i++) - { - sum = 0; - sp = &v[0]; - - for (int j = 0; j < WIDTH; j++) - { - sum += *mp * *sp; - mp++; - sp++; - } - - *dp = sum; - dp++; - } - } - - double & operator() (int i, int j) - { return data[i*WIDTH+j]; } - - const double & operator() (int i, int j) const - { return data[i*WIDTH+j]; } - - - - const double & Get(int i, int j) const { return data[(i-1)*WIDTH+j-1]; } - /// - const double & Get(int i) const { return data[i-1]; } - /// - void Set(int i, int j, double v) { data[(i-1)*WIDTH+j-1] = v; } - /// - double & Elem(int i, int j) { return data[(i-1)*WIDTH+j-1]; } - /// - const double & ConstElem(int i, int j) const { return data[(i-1)*WIDTH+j-1]; } -}; - - - - - -#endif diff --git a/Netgen/libsrc/linalg/linalg.hpp b/Netgen/libsrc/linalg/linalg.hpp deleted file mode 100644 index 4599fad48d..0000000000 --- a/Netgen/libsrc/linalg/linalg.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef FILE_LINALG -#define FILE_LINALG - -/* *************************************************************************/ -/* File: linalg.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Oct. 94 */ -/* *************************************************************************/ - -/* - - Data types for basic linear algebra - more data types are found in linalgl.hpp - - The basic concepts include the data types - - Vector - SparseMatrix - DenseMatrix - -*/ - - -#include <myadt.hpp> -namespace netgen -{ -#include "vector.hpp" - // #include "basemat.hpp" -#include "densemat.hpp" - // #include "sparsmat.hpp" -#include "polynomial.hpp" -} -#endif - - diff --git a/Netgen/libsrc/linalg/polynomial.cpp b/Netgen/libsrc/linalg/polynomial.cpp deleted file mode 100644 index 964dab9674..0000000000 --- a/Netgen/libsrc/linalg/polynomial.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include <mystdlib.h> -#include <linalg.hpp> - -namespace netgen -{ - -QuadraticPolynomial1V :: -QuadraticPolynomial1V (double ac, double acx, double acxx) -{ - c = ac; - cx = acx; - cxx = acxx; -} - -double QuadraticPolynomial1V :: -Value (double x) -{ - return c + cx * x + cxx * x * x; -} - -double QuadraticPolynomial1V :: MaxUnitInterval () -{ - // inner max - if (cxx < 0 && cx > 0 && cx < -2 * cxx) - { - return c - 0.25 * cx * cx / cxx; - } - - - if (cx + cxx > 0) // right edge - return c + cx + cxx; - - // left end - return c; -} - - - - -LinearPolynomial2V :: -LinearPolynomial2V (double ac, double acx, double acy) -{ - c = ac; - cx = acx; - cy = acy; -} - - -QuadraticPolynomial2V :: -QuadraticPolynomial2V () -{ - ; -} - - -QuadraticPolynomial2V :: -QuadraticPolynomial2V (double ac, double acx, double acy, - double acxx, double acxy, double acyy) -{ - c = ac; - cx = acx; - cy = acy; - cxx = acxx; - cxy = acxy; - cyy = acyy; -} - -void QuadraticPolynomial2V :: -Square (const LinearPolynomial2V & lp) -{ - c = lp.c * lp.c; - cx = 2 * lp.c * lp.cx; - cy = 2 * lp.c * lp.cy; - - cxx = lp.cx * lp.cx; - cxy = 2 * lp.cx * lp.cy; - cyy = lp.cy * lp.cy; -} - -void QuadraticPolynomial2V :: -Add (double lam, const QuadraticPolynomial2V & qp2) -{ - c += lam * qp2.c; - cx += lam * qp2.cx; - cy += lam * qp2.cy; - cxx += lam * qp2.cxx; - cxy += lam * qp2.cxy; - cyy += lam * qp2.cyy; -} - -double QuadraticPolynomial2V :: -Value (double x, double y) -{ - return c + cx * x + cy * y + cxx * x * x + cxy * x * y + cyy * y * y; -} - -/* -double QuadraticPolynomial2V :: -MinUnitSquare () -{ - double x, y; - double minv = 1e8; - double val; - for (x = 0; x <= 1; x += 0.1) - for (y = 0; y <= 1; y += 0.1) - { - val = Value (x, y); - if (val < minv) - minv = val; - } - return minv; -}; -*/ - -double QuadraticPolynomial2V :: -MaxUnitSquare () -{ - // find critical point - - double maxv = c; - double hv; - - double det, x0, y0; - det = 4 * cxx * cyy - cxy * cxy; - - if (det > 0) - { - // definite surface - - x0 = (-2 * cyy * cx + cxy * cy) / det; - y0 = (cxy * cx -2 * cxx * cy) / det; - - if (x0 >= 0 && x0 <= 1 && y0 >= 0 && y0 <= 1) - { - hv = Value (x0, y0); - if (hv > maxv) maxv = hv; - } - } - - QuadraticPolynomial1V e1(c, cx, cxx); - QuadraticPolynomial1V e2(c, cy, cyy); - QuadraticPolynomial1V e3(c+cy+cyy, cx+cxy, cxx); - QuadraticPolynomial1V e4(c+cx+cxx, cy+cxy, cyy); - - hv = e1.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - hv = e2.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - hv = e3.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - hv = e4.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - - return maxv; - - // (*testout) << "maxv = " << maxv << " =~= "; - - /* - double x, y; - maxv = -1e8; - double val; - for (x = 0; x <= 1.01; x += 0.1) - for (y = 0; y <= 1.01; y += 0.1) - { - val = Value (x, y); - if (val > maxv) - maxv = val; - } - - // (*testout) << maxv << endl; - return maxv; - */ -} - - - - -double QuadraticPolynomial2V :: -MaxUnitTriangle () -{ - // find critical point - - double maxv = c; - double hv; - - double det, x0, y0; - det = 4 * cxx * cyy - cxy * cxy; - - if (cxx < 0 && det > 0) - { - // definite surface - - x0 = (-2 * cyy * cx + cxy * cy) / det; - y0 = (cxy * cx -2 * cxx * cy) / det; - - if (x0 >= 0 && y0 >= 0 && x0+y0 <= 1) - { - return Value (x0, y0); - } - } - - - QuadraticPolynomial1V e1(c, cx, cxx); - QuadraticPolynomial1V e2(c, cy, cyy); - QuadraticPolynomial1V e3(c+cy+cyy, cx-cy+cxy-2*cyy, cxx-cxy+cyy); - - hv = e1.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - hv = e2.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - hv = e3.MaxUnitInterval(); - if (hv > maxv) maxv = hv; - - return maxv; -} -} diff --git a/Netgen/libsrc/linalg/polynomial.hpp b/Netgen/libsrc/linalg/polynomial.hpp deleted file mode 100644 index 3108d4dd72..0000000000 --- a/Netgen/libsrc/linalg/polynomial.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef FILE_POLYNOMIAL -#define FILE_POLYNOMIAL - -/* *************************************************************************/ -/* File: polynomial.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 25. Nov. 99 */ -/* *************************************************************************/ - - -class QuadraticPolynomial1V -{ - double c, cx, cxx; -public: - QuadraticPolynomial1V (double ac, double acx, double acxx); - double Value (double x); - double MaxUnitInterval (); -}; - -class LinearPolynomial2V -{ - double c, cx, cy; -public: - LinearPolynomial2V (double ac, double acx, double acy); - friend class QuadraticPolynomial2V; -}; - - -class QuadraticPolynomial2V -{ - double c, cx, cy, cxx, cxy, cyy; -public: - QuadraticPolynomial2V (); - QuadraticPolynomial2V (double ac, double acx, double acy, - double acxx, double acxy, double acyy); - void Square (const LinearPolynomial2V & lp); - void Add (double lam, const QuadraticPolynomial2V & qp); - - double Value (double x, double y); - // double MinUnitSquare (); - double MaxUnitSquare (); - double MaxUnitTriangle (); -}; - -#endif diff --git a/Netgen/libsrc/linalg/sparsmat.cpp b/Netgen/libsrc/linalg/sparsmat.cpp deleted file mode 100644 index f3249f82e6..0000000000 --- a/Netgen/libsrc/linalg/sparsmat.cpp +++ /dev/null @@ -1,1707 +0,0 @@ -//#include <algorithm> -#ifdef ABC - -#include <mystdlib.h> - -#include <linalg.hpp> - - -namespace netgen -{ -MatrixGraph :: MatrixGraph (int size, int aincrement) -{ - int i; - increment = aincrement; - - lines.SetSize (size); - for (i = 1;i <= size; i++) - { - lines.Elem(i).allocsize = increment; - lines.Elem(i).size = 1; - lines.Elem(i).diag = 1; - lines.Elem(i).col = new INDEX[increment]; - lines.Elem(i).col[0] = i; - } -} - -MatrixGraph :: MatrixGraph (const ARRAY<int> & linesize) -{ - INDEX i; - INDEX n = linesize.Size(); - INDEX sum = 0; - INDEX * cola; - - lines.SetSize (n); - increment = 0; - - for (i = 1; i <= n; i++) - sum += linesize.Get(i); - - cola = new INDEX[sum]; - - sum = 0; - for (i = 1; i <= n; i++) - { - lines.Elem(i).allocsize=linesize.Get(i); - lines.Elem(i).size = 1; - lines.Elem(i).diag = 1; - lines.Elem(i).col = &cola[sum]; - cola[sum] = i; - sum += linesize.Get(i); - } -} - -int MatrixGraph :: GetPosition (INDEX i, INDEX j) const -{ - int k; - - INDEX * ip = lines.Get(i).col; - INDEX n = lines.Get(i).size; - for (k = 1; k <= n; k++, ip++) - { - if (j == *ip) return k; - } - - return 0; - - /* - // quick search: - - const INDEX * ip = lines.Get(i).col; - int max = lines.Get(i).size; - - int l = 0, k = 1, newind; - - while (k < max) - k <<= 1; - - while (k > 0) - { - k >>= 1; - newind = k+l; - if (newind >= max) continue; - if (ip[newind] <= j) - l += k; - } - - if (l < max && ip[l] == j) - return l+1; - - return 0; - */ -} - - - -int MatrixGraph :: CreatePosition (INDEX i, INDEX j) - { - int k; - MatrixGraph::linestruct * lin = &lines.Elem(i); - - - - for (k = 1; k <= lin->size; k++) - { - if (lin->col[k-1] == j) - return 0; - if (lin->col[k-1] > j) - break; - } - - // k ... position to enter new element - - if (lin->size == lin->allocsize) - { - INDEX * tmpcol = new INDEX[lin->size + increment]; - memcpy (tmpcol, lin->col, sizeof(INDEX) * lin->size); - delete lin->col; - lin->col = tmpcol; - lin->allocsize+=increment; - } - - if (k <= lin->size) - memmove (&lin->col[k], &lin->col[k-1], - sizeof(INDEX) * (lin->size + 1 - k)); - - lin->col[k-1] = j; - lin->size++; - if (j < i) lin->diag++; - - return 1; - } - - - -double & SparseMatrix :: operator() (INDEX i, INDEX j) -{ - if (i >= 1 && i <= height && j >= 1 && j <= width) - return Elem(i, j); - else - { - (*myerr) << "SparseMatirx::operator(): out of range" << endl; - return shit; - } -} - -double SparseMatrix :: operator() (INDEX i, INDEX j) const -{ - if (i >= 1 && i <= height && j >= 1 && j <= width) - return Get(i, j); - else - { - (*myerr) << "SparseMatirx::operator(): out of range" << endl; - return shit; - } -} - - - - - - -SparseMatrix :: SparseMatrix (INDEX h, INDEX w) - : BaseMatrix (h, w) -{ - ; -} - - - - -void SparseMatrix :: Mult (const Vector & v, Vector & prod) const - { - double sum, vi; - INDEX i, j, n; - - const INDEX * col; - const double * valp; - - // const Vector & v = bv.CastToVector(); - // Vector & prod = bprod.CastToVector(); - - prod.SetSize (Height()); - - /* - if (prod.Size() != Height() || v.Size() != Width()) - { - (*myerr) << "SparseMatrix::Mult: Dimensions don't fit" << endl; - return; - } - */ - - if (!Symmetric()) - { - n = Height(); - INDEX w = Width(); - - /* - const MatrixGraph::linestruct * linep = &graph->lines.Get(1); - - for (i = 1; i <= n; i++) - { - sum = 0; - col = linep->col; - valp = data.Get(i); - - for (j = 0; j < linep->size; j++, valp++, col++) - sum += *valp * v.Get(*col); - - linep++; - prod.Set (i, sum); - } - */ - - const MatrixGraph::linestruct * linep = &graph->lines.Get(1); - const double * vp = &v.Get(1); - vp--; - - for (i = 1; i <= n; i++) - { - sum = 0; - col = linep->col; - valp = data.Get(i); - const int ls = linep->size; - - if (i <= w) - for (j = 0; j < ls; j++) - sum += valp[j] * vp[col[j]]; - else - // decrement one, because of diagonal element outside - for (j = 0; j < ls-1; j++) - sum += valp[j] * vp[col[j]]; - - - linep++; - prod.Elem(i) = sum; - } - - } - else - { - prod = 0; - n = Height(); - - const MatrixGraph::linestruct * linep = &graph->lines.Get(1); - - for (i = 1; i <= n; i++) - { - sum = 0; - // col = graph->lines.Get(i).col; - col = linep->col; - valp = data.Get(i); - vi = v.Get(i); - - for (j = linep->diag-1; j > 0; j--, col++, valp++) - { - sum += (*valp) * v.Get(*col); - prod.Elem(*col) += (*valp) * vi; - } - - linep++; - sum += (*valp) * v.Get(*col); - prod.Elem(i) += sum; - } - } - } - -void SparseMatrix :: MultTrans (const Vector & v, Vector & prod) const - { - INDEX i, j, n, coln; - // const Vector & v = bv.CastToVector(); - // Vector & prod = bprod.CastToVector(); - const INDEX * col; - const double * valp; - double val; - - prod.SetSize (Width()); - - if (prod.Size() != Width() || v.Size() != Height()) - { - (*myerr) << "SparseMatrix::Mult: Dimensions don't fit" << endl; - return; - } - - if (!Symmetric()) - { - n = Height(); - prod = 0; - - for (i = 1; i <= n; i++) - { - col = graph->lines.Get(i).col; - valp = data.Get(i); - coln = graph->lines.Get(i).size; - val = v.Get(i); - - // lin = &lins.Get(i); - // col = lin->col; - // val = v.Get(i); - - for (j = 1; j <= coln; j++, col++, valp++) - prod.Elem(*col) += (*valp) * val; - } - } - else - { - Mult (v, prod); - } - } - - - - -void SparseMatrix :: Residuum (const Vector & bx, const Vector & bb, - Vector & bres) const - { - BaseMatrix :: Residuum (bx, bb, bres); - /* - double sum, xi; - INDEX i, j, n; - colstruct * col; - const linestruct * lin; - const Vector & x = bx.CastToVector(); - const Vector & b = bb.CastToVector(); - Vector & res = bres.CastToVector(); - - res.SetSize (b.Size()); - - if (res.Size() != b.Size() || b.Size() != Height() || - x.Size() != Width()) - { - (*myerr) << "SparseMatrix::Residuum: Dimensions don't fit" << endl; - return; - } - - n = Height(); - if (!Symmetric()) - { - for (i = 1; i <= Height(); i++) - { - lin = &lins.Get(i); - sum = b.Get(i); - col = lin->col; - - for (j = lin->size; j > 0; j--, col++) - sum -= col->data * x.Get(col->colnr); - - res.Set (i, sum); - } - } - else - { - res = b; - for (i = 1; i <= n; i++) - { - lin = &lins.Get(i); - sum = 0; - col = lin->col; - xi = x.Get(i); - - for (j = lin->size; j > 0; j--, col++) - { - sum -= col->data * x.Get(col->colnr); - if (col->colnr != i) - res.Elem(col->colnr) -= col->data * xi; - } - - res.Elem(i) += sum; - } - } - */ - } - - -void SparseMatrix :: ResiduumTrans (const Vector & /* bx */, - const Vector & /* bb */, - Vector & /* bres */) const - { - cerr << "SparseMastrix :: Residuumtrans called, but not implemented" << endl; - - /* - INDEX i, j, n; - colstruct * col; - const linestruct * lin; - const Vector & x = bx.CastToVector(); - const Vector & b = bb.CastToVector(); - Vector & res = bres.CastToVector(); - - - res.SetSize (Width()); - - if (res.Size() != b.Size() || b.Size() != Width() || - x.Size() != Height()) - { - (*myerr) << "SparseMatrix::ResiduumTrans: Dimensions don't fit" << endl; - return; - } - - if (!Symmetric()) - { - n = Height(); - - res = b; - - for (i = 1; i <= n; i++) - { - lin = &lins.Get(i); - col = lin->col; - - for (j = lin->size; j > 0; j--, col++) - res.Elem(col->colnr) -= col->data * x.Get(i); - } - } - else - { - Residuum (bx, bb, bres); - } - */ - } - - - -ostream & SparseMatrix :: Print (ostream & s) const - { - INDEX i, j; - - if (Symmetric()) s << "Lower half of matrix:" << endl; - - for (i = 1; i <= Height(); i++) - { - s << "Line " << i << " "; - - if (Symmetric()) - { - for (j = 1 ; j <= GetDiagPos (i); j++) - s << "(" << GetColIndex (i, j) << ": " << GetData (i, j) << ") "; - } - else - { - for (j = 1 ; j <= ElementsInLine (i); j++) - s << "(" << GetColIndex (i, j) << ": " << GetData (i, j) << ") "; - } - - s << endl; - } - return s; - } - - - - - - -void SparseMatrix :: AddElementMatrix (const ARRAY<INDEX> & pnum, - const BaseMatrix & elemmat) -{ - int i, j, i1, i2, n; - - n = pnum.Size(); - static ARRAY<int> spnum, map; - spnum.SetSize (n); - map.SetSize (n); - - for (i = 1; i <= n; i++) - spnum.Elem(i) = pnum.Get(i); - - for (i = 1; i <= n; i++) - for (j = 1; j <= n-1; j++) - if (spnum.Elem(j) > spnum.Elem(j+1)) - swap (spnum.Elem(j), spnum.Elem(j+1)); - - for (i = 1; i <= n; i++) - for (j = 1; j <= n; j++) - if (pnum.Get(i) == spnum.Get(j)) - map.Elem(j) = i; - - - const DenseMatrix & delemmat = (const DenseMatrix&)elemmat; - if (Symmetric()) - { - for (i1 = 1; i1 <= n; i1++) - { - INDEX ii1 = spnum.Get(i1); - const INDEX * coli = graph->lines.Get(ii1).col; - double * val = data.Get(ii1); - int ncol = graph->lines.Get(ii1).size; - - int hi = 0; - for (i2 = 1; i2 <= i1; i2++) - { - while (coli[hi] < spnum.Get(i2)) - hi++; - val[hi] += delemmat.Get(map.Get(i1), map.Get(i2)); - } - } - - /* - for (i1 = 1; i1 <= pnum.Size(); i1++) - for (i2 = 1; i2 <= i1; i2++) - Elem(pnum.Get(i1), pnum.Get(i2)) += delemmat.Get(i1, i2); - */ - } - else - { - for (i1 = 1; i1 <= n; i1++) - { - INDEX ii1 = spnum.Get(i1); - const INDEX * coli = graph->lines.Get(ii1).col; - double * val = data.Get(ii1); - int ncol = graph->lines.Get(ii1).size; - - int hi = 0; - for (i2 = 1; i2 <= n; i2++) - { - while (coli[hi] < spnum.Get(i2)) - hi++; - val[hi] += delemmat.Get(map.Get(i1), map.Get(i2)); - } - } - - /* - for (i1 = 1; i1 <= pnum.Size(); i1++) - for (i2 = 1; i2 <= pnum.Size(); i2++) - Elem(pnum.Get(i1), pnum.Get(i2)) += delemmat.Get(i1, i2); - */ - } -} - - - - -double SparseMatrix :: RowTimesVector (INDEX i, const Vector & v) const - { - const double * valp; - const INDEX * col; - int coln; - double sum; - int j; - - /* - if (Width() > v.Size()) - { - cerr << "SparseMatrix::RowTimesVector: Size doesn't fit" << endl; - return 0; - } - */ - - col = graph->lines.Get(i).col; - valp = data.Get(i); - sum = 0; - coln = Symmetric() ? graph->lines.Get(i).diag : graph->lines.Get(i).size; - - for (j = 1; j <= coln; ++j, ++col, ++valp) - sum += (*valp) * v.Get(*col); - - return sum; - - /* - col = graph->lines.Get(i).col; - valp = data.Get(i); - coln = graph->lines.Get(i).size; - val = v.Get(i); - - // lin = &lins.Get(i); - // col = lin->col; - // val = v.Get(i); - - for (j = 1; j <= coln; j++, col++, valp++) - prod.Elem(*col) += (*valp) * val; - */ - - - } - - - -void SparseMatrix :: AddRowToVector (INDEX i, double s, Vector & v) const -{ - const double * valp; - const INDEX * col; - double * vp; - int coln, j; - -#ifdef debug - if (Width() > v.Size()) - { - cerr << "SparseMatrix::AddRowToVector: Size doesn't fit" - << "w = " << Width() << " len = " << v.Size() << endl; - return; - } -#endif - - vp = &v.Elem(1) - 1; - valp = data.Get(i); - col = graph->lines.Get(i).col; - coln = Symmetric() ? graph->lines.Get(i).diag : graph->lines.Get(i).size; - - // for (j = 0; j < coln; j++) - // vp[col[j]] += s * valp[j]; - - for (j = coln-1; j >= 0; --j, ++valp, ++col) - vp[*col] += s * (*valp); -} - - - - - - -char SparseMatrix :: Used (INDEX i, INDEX j) const - { - return (graph->GetPosition(i, j) != 0); - } - - - -double SparseMatrix :: Get(INDEX i, INDEX j) const - { - if (Symmetric() && (j > i)) swap (i, j); - - int pos = graph->GetPosition(i, j); - if (pos) - return data.Get(i)[pos-1]; - else - return 0; - } - - -/* - quick search: - - const colstruct * col = lins.Get(i).col; - INDEX max = lins.Get(i).size; - - int l = 0, k = 1, newind; - - while (k < max) - k <<= 1; - - - while (k > 0) - { - k >>= 1; - newind = k+l; - if (newind >= max) continue; - if (col[newind].colnr <= j) - l += k; - } - - if (l < max && col[l].colnr == j) return col[l].data; - - return 0; - */ - - - -void SparseMatrix :: Set(INDEX i, INDEX j, double v) - { - Elem (i, j) = v; - } - - - -double & SparseMatrix :: Elem(INDEX i, INDEX j) - { - if (Symmetric() && j > i) swap (i, j); - - int pos = graph->GetPosition (i, j); - if (!pos) - { - CreatePosition (i, j); - pos = graph->GetPosition (i, j); - } - - return data.Elem(i)[pos-1]; - } - - - - - - - - -SparseMatrixFlex :: SparseMatrixFlex (INDEX h, INDEX w) - : SparseMatrix (h, w) -{ - INDEX i; - graph = - mygraph = new MatrixGraph (h); - - data.SetSize (h); - for (i = 1; i <= graph->Size(); i++) - { - data.Elem(i) = new double[graph->lines.Get(i).allocsize]; - data.Elem(i)[0] = 0; - } -} - -SparseMatrixFlex :: ~SparseMatrixFlex () -{ - ; -} - - -void SparseMatrixFlex :: SetSize (INDEX /* h */, INDEX /* w */) -{ - cerr << "SparseMatrixFlex :: SetSize() not implemented" << endl; -} - -void SparseMatrixFlex :: SetSymmetric (int sym) -{ - BaseMatrix::SetSymmetric (sym); -} - -void SparseMatrixFlex :: ChangeSize (INDEX /* h */, INDEX /* w */) -{ - cerr << "SparseMatrixFlex :: ChangeSize() not implemented" << endl; -} - - -void SparseMatrixFlex :: DeleteElements () -{ - ; -} - -BaseMatrix * SparseMatrixFlex :: Copy () const -{ - return (SparseMatrixFlex*)this; -} - - -int SparseMatrixFlex :: CreatePosition (INDEX i, INDEX j) -{ - int oldlinesize = graph->lines.Get(i).allocsize; - if (mygraph->CreatePosition(i, j)) - { - int newlinesize = graph->lines.Get(i).allocsize; - if (oldlinesize != newlinesize) - { - double * hdp = new double[newlinesize]; - memcpy (hdp, data.Elem(i), sizeof(double) * oldlinesize); - delete data.Elem(i); - data.Elem(i) = hdp; - } - - int pos = graph->GetPosition (i, j); - int size = graph->lines.Get(i).size; - - memmove (&data.Elem(i)[pos], &data.Elem(i)[pos-1], - sizeof(double) * (size-pos)); - data.Elem(i)[pos-1] = 0; - } - - return 0; -} - - - - -SparseMatrixFix :: SparseMatrixFix (const MatrixGraph & agraph, - int asymmetric) - : SparseMatrix (agraph.Size()) -{ - graph = &agraph; - SetSymmetric (asymmetric); - - data.SetSize (graph->Size()); - - int i, nne; - double * block; - - nne = 0; - for (i = 1; i <= graph->Size(); i++) - { - if (Symmetric()) - nne += graph->lines.Get(i).diag; - else - nne += graph->lines.Get(i).size; - } - - block = new double[nne]; - - for (i = 0; i < nne; i++) - block[i] = 0; - - nne = 0; - for (i = 1; i <= graph->Size(); i++) - { - data.Elem(i) = &block[nne]; - if (Symmetric()) - nne += graph->lines.Get(i).diag; - else - nne += graph->lines.Get(i).size; - } - -} - - -SparseMatrixFix :: ~SparseMatrixFix () -{ - ; -} - -int SparseMatrixFix :: CreatePosition (INDEX i, INDEX j) -{ - (*myerr) << "SparseMatrixFix cannot change graph, requested: " - << i << "-" << j << endl; - return 0; -} - -#ifdef nothing - - -SparseMatrix :: SparseMatrix () : BaseMatrix (), lins() - { - }; - -SparseMatrix :: SparseMatrix (INDEX h, INDEX w) : BaseMatrix (h, w), lins (h) - { - if (!w) w = h; - - for (INDEX i = 1; i <= h; i++) - { - lins[i].size = 0; - lins[i].maxsize = 0; - lins[i].col = NULL; - } - } - -SparseMatrix :: SparseMatrix (const SparseMatrix & m2) : BaseMatrix(), lins() - { - (*this) = m2; - } - - -SparseMatrix :: ~SparseMatrix () - { - DeleteElements (); - } - - - -void SparseMatrix :: SetSize (INDEX h, INDEX w) - { - if (!w) w = h; - DeleteElements (); - - if (height == h && width == w) return; - - height = h; - width = w; - lins.SetSize (height); - - if (lins.Size () == height) - { - for (INDEX i = 1; i <= h; i++) - { - lins[i].size = 0; - lins[i].maxsize = 0; - lins[i].col = NULL; - } - } - else - { - height = width = 0; - (*myerr) << "SparseMatrix::SetSize: Out of memory" << endl; - } - } - - -void SparseMatrix :: ChangeSize (INDEX h, INDEX w) - { - INDEX i; - - if (!w) w = h; - if (height == h && width == w) return; - - lins.SetSize (h); - - if (lins.Size () == h) - { - for (i = height+1; i <= h; i++) - { - lins[i].size = 0; - lins[i].maxsize = 0; - lins[i].col = NULL; - } - for (i = h+1; i <= height; i++) - { - if (lins[i].col) - { - DeleteColStruct (lins[i].col, lins[i].maxsize); - - lins[i].col = NULL; - lins[i].size = 0; - lins[i].maxsize = 0; - } - } - - height = h; - width = w; - } - else - { - height = width = 0; - (*myerr) << "SparseMatrix::SetSize: Out of memory" << endl; - } - } - - -void SparseMatrix :: SetSymmetric (int sym) - { - INDEX i, j; - int nr; - - if (sym != Symmetric()) - { - BaseMatrix :: SetSymmetric (sym); - - if (!sym) - { - for (i = 1; i <= Height(); i++) - for (nr = 1; nr <= ElementsInLine (i); nr++) - { - j = GetIndex (i, nr); - if (j < i) - Elem (j, i) = GetData (i, nr); - } - } - else - { - DeleteElements(); - } - } - } - - -void SparseMatrix :: DeleteElements () - { - for (INDEX i = 1; i <= lins.Size(); i++) - { - if (lins[i].col) - { - DeleteColStruct (lins[i].col, lins[i].maxsize); - - lins[i].col = NULL; - lins[i].size = 0; - lins[i].maxsize = 0; - } - } - } - - - -double & SparseMatrix::operator() (INDEX i, INDEX j) -{ - if (i >= 1 && j >= 1 && i <= height && j <= width) - { - return Elem(i, j); - } - else (*myerr) << "\nindex (" << i << "," << j << ") out of range (1.." - << height << ",1.." << width << ")\n"; - return shit; -} - -double SparseMatrix::operator() (INDEX i, INDEX j) const -{ - if (i >= 1 && j >= 1 && i <= height && j <= width) - { - return Get(i, j); - } - else (*myerr) << "\nindex (" << i << "," << j << ") out of range (1.." - << height << ",1.." << width << ")\n"; - return 0; -} - -SparseMatrix & SparseMatrix :: operator= (const SparseMatrix & m2) - { - INDEX i, j; - - SetSize (m2.Height(), m2.Width()); - SetSymmetric (m2.Symmetric()); - - for (i = 1; i <= m2.Height(); i++) - for (j = 1; j <= m2.ElementsInLine(i); j++) - (*this).Elem(i, m2.GetIndex(i, j)) = m2.GetData(i, j); - return *this; - } - - -SparseMatrix & SparseMatrix :: operator*= (double v) - { - INDEX i, j; - - for (i = 1; i <= Height(); i++) - for (j = 1; j <= ElementsInLine(i); j++) - GetDataRef(i, j) *= v; - return *this; - } - - - -char SparseMatrix :: Used (INDEX i, INDEX j) const - { - if (Symmetric() && j > i) swap (i, j); - - if (i < 1 || i > height) return 0; - - const colstruct * col = lins.Get(i).col; - INDEX max = lins.Get(i).size; - - for (int k = 0; k < max; k++, col++) - if (col->colnr == j) return 1; - - return 0; - } - - - -double SparseMatrix :: Get(INDEX i, INDEX j) const - { - if (Symmetric() && j > i) swap (i, j); - - const colstruct * col = lins.Get(i).col; - INDEX max = lins.Get(i).size; - - int l = 0, k = 1, newind; - - while (k < max) - k <<= 1; - - - while (k > 0) - { - k >>= 1; - newind = k+l; - if (newind >= max) continue; - if (col[newind].colnr <= j) - l += k; - } - - if (l < max && col[l].colnr == j) return col[l].data; - - return 0; - - /* - for (INDEX k = 0; k < max; k++, col++) - if (col->colnr == j) - { - if (l != k) cerr << "Set: ind not ok" << endl; - else cerr << "is ok" << endl; - return col->data; - } - - return 0; - */ - } - - -void SparseMatrix :: Set(INDEX i, INDEX j, double v) - { - Elem (i, j) = v; - } - - - -double & SparseMatrix :: Elem(INDEX i, INDEX j) - { - if (Symmetric() && j > i) swap (i, j); - - linestruct * lin = &lins.Elem(i); - colstruct * col, *ncol; - - int size = lin->size; - int pos; - - if (size) - { - - // bereits Elemente in der Liste - - if (j > lin->col[size-1].colnr) - { - - // neues Element an letzter Position einfuegen - - if (lin->maxsize > size) - { - lin->size++; - lin->col[size].colnr = j; - return lin->col[size].data = 0; - } - - if ( (ncol = NewColStruct(lin->maxsize+4)/* new colstruct[lin->maxsize+4] */) != NULL) - { - memcpy (ncol, lin->col, sizeof(colstruct) * size); - - DeleteColStruct (lin->col, lin->maxsize); - - lin->maxsize += 4; - lin->col = ncol; - lin->size++; - ncol[size].colnr = j; - return ncol[size].data = 0; - } - else - { - (*myerr) << "SparseMatrix::Elem: Out of memory 1" << endl; - return shit; - } - - } - else - { - - for (col = lin->col; col->colnr < j; col++); - // Zeilenliste durchsuchen - - if (col->colnr == j) return col->data; - // Element exisitiert bereits - - if (lin->maxsize > size) - { - memmove (col+1, col, size_t((char*)&lin->col[size] - (char*)col)); - - lin->size++; - col->colnr = j; - return col->data = 0; - } - - pos = size_t (col - lin->col); - - if ( (ncol = NewColStruct(lin->maxsize+4) ) != NULL) - { - - if (pos) memcpy (ncol, lin->col, sizeof(colstruct) * pos); - memcpy (ncol+(pos+1), col, sizeof(colstruct) * (size-pos)); - - DeleteColStruct (lin->col, lin->maxsize); -// delete lin->col; - - lin->maxsize += 4; - lin->col = ncol; - lin->size++; - ncol[pos].colnr = j; - return ncol[pos].data = 0; - } - else - { - (*myerr) << "SparseMatrix::Elem: Out of memory 2" << endl; - return shit; - } - } - } - else - { - // kein Element in der Liste - - if (lin->maxsize) - { - // Liste bereits angelegt - - lin->size = 1; - lin->col->colnr = j; - return lin->col->data = 0; - } - else - { - if ( (lin->col = NewColStruct(6) ) != NULL ) - { - lin->maxsize = 6; - lin->size = 1; - lin->col->colnr = j; - return lin->col->data = 0; - } - else - { - (*myerr) << "SparseMatrix::Elem: Out of memory 3" << endl; - return shit; - } - } - } - } - - - -void SparseMatrix :: Delete (INDEX i, int nr) - { - colstruct * col = lins[i].col; - - nr--; - while (nr < lins[i].size-1) - { - col[nr].data = col[nr+1].data; - col[nr].colnr = col[nr+1].colnr; - nr++; - } - lins[i].size--; - } - -void SparseMatrix :: DeleteElem (INDEX i, INDEX j) - { - int nr; - int dec = 0; - - if (Symmetric() && j > i) swap (i, j); - - colstruct * col = lins[i].col; - - for (nr = 0; nr < lins[i].size; nr++) - { - if (dec) - { - col[nr-1].data = col[nr].data; - col[nr-1].colnr = col[nr].colnr; - } - if (col[nr].colnr == j) dec = 1; - } - if (dec) - lins[i].size--; - } - - -void SparseMatrix :: SetLineAllocSize (INDEX i, int j) - { - colstruct * ncol; - - - if (lins[i].maxsize < j) - { - if ( (ncol = NewColStruct(j)) != NULL) - { - memcpy (ncol, lins[i].col, sizeof(colstruct) * lins[i].size); - - if (lins[i].maxsize) - DeleteColStruct (lins[i].col, lins[i].maxsize); - - lins[i].maxsize = j; - lins[i].col = ncol; - } - else - (*myerr) << "SPARSE_MATIRX :: SetLineAllocSize: Out of Memory" << endl; - } - } - - - - - - - - - - - - - - -SparseMatrix operator* (const SparseMatrix & m1, - const SparseMatrix & m2) - { - SparseMatrix m(m1.Height(), m2.Width()); - INDEX i, j, k, nr; - - if (!m1.Symmetric() && !m2.Symmetric()) - { - for (i = 1; i <= m1.Height(); i++) - { - for (j = 1; j <= m1.ElementsInLine(i); j++) - { - nr = m1.GetIndex (i, j); - for (k = 1; k <= m2.ElementsInLine(nr); k++) - { - m(i, m2.GetIndex(nr, k)) += m1.GetData(i, j) * m2.GetData(nr, k); - } - } - } - } - else - { - (*myerr) << "SparseMatrix :: operator* not implemented for symmetric case" << endl; - } - return m; - } - - -SparseMatrix & SparseMatrix :: operator+= (const SparseMatrix & m2) - { - INDEX i, k; - int j; - - if (Symmetric() == m2.Symmetric()) - { - for (i = 1; i <= Height(); i++) - for (j = 1; j <= m2.ElementsInLine (i); j++) - { - k = m2.GetIndex (i, j); - Elem(i, k) += m2.GetData (i, j); - } - } - else - { - (*myerr) << "SparseMatrix :: operator+= not implemented for different cases" << endl; - } - return *this; - } - - - -SparseMatrix & SparseMatrix :: operator*= (const SparseMatrix & m2) - { - INDEX i, k; - int j, l; - colstruct * cs; - int ms, s; - - if (!Symmetric() && !m2.Symmetric()) - { - for (i = 1; i <= Height(); i++) - { - cs = lins[i].col; - s = lins[i].size; - ms = lins[i].maxsize; - - lins[i].col = NULL; - lins[i].size = 0; - lins[i].maxsize = 0; - - - for (j = 0; j < s; j++) - { - k = cs[j].colnr; - - for (l = 1; l <= m2.ElementsInLine (k); l++) - Elem(i, m2.GetIndex(k, l)) += cs[j].data * m2.GetData(k, l); - } - - DeleteColStruct (cs, ms); - } - } - else - { - (*myerr) << "SparseMatrix :: operator*= not implemented for Symmetric matrices" << endl; - } - - return *this; - } - - -void SparseMatrix :: Solve (const Vector & v, Vector & sol) const - { - SparseMatrix temp = *this; - INDEX i, j, nr, k; - double q; - - sol = v; - - - if (!Symmetric()) - { - for (i = 1; i <= Height(); i++) - { - if (temp.ElementsInLine(i) < 1 || temp.GetIndex(i, 1) != i) - { - (*myerr) << "i = " << i << endl; - (*myerr) << "Solve: Matrix singular" << endl; - char ch; - cin >> ch; - } - for (j = 2; j <= temp.ElementsInLine(i); j++) - { - nr = temp.GetIndex(i, j); - if (temp.GetIndex(nr, 1) != i) - { - (*myerr) << temp << endl; - (*myerr) << "i = " << i << "j = " << j << "nr = " << nr << endl; - (*myerr) << "Solve: Graph not symmetrix" << endl; - char ch; - cin >> ch; - } - - q = temp.GetData (nr, 1) / temp.GetData(i, 1); - temp.Delete (nr, 1); - - for (k = 2; k <= temp.ElementsInLine (i); k++) - temp.Elem(nr, temp.GetIndex(i, k)) -= q * temp.GetData(i, k); - - sol(nr) -= q * sol(i); - } - } - - for (i = temp.Height(); i >= 1; i--) - { - for (j = 2; j <= temp.ElementsInLine(i); j++) - { - sol(i) -= temp.GetData(i, j) * sol(temp.GetIndex(i, j)); - } - sol(i) /= temp.GetData(i, 1); - } - } - else - (*myerr) << "SparseMatrix :: Solve not implemented for symmetic case" << endl; - } - - - - - -void Transpose (const SparseMatrix & m1, SparseMatrix & m2) - { - INDEX i, j; - - m2.SetSize(m1.Width(), m1.Height()); - m2.SetSymmetric(m1.Symmetric()); - - if (!m1.Symmetric()) - { - for (i = 1; i <= m1.Height(); i++) - for (j = 1; j <= m1.ElementsInLine(i); j++) - m2(m1.GetIndex(i, j), i) = m1.GetData(i, j); - } - else - m2 = m1; - } - - - -BaseMatrix * SparseMatrix :: Copy () const - { - return new SparseMatrix (*this); - } - - - - - - - -void SparseMatrix :: AddRowMatrix (INDEX row, const SparseMatrix & m2) - { - int i1, i2, i; - colstruct * cs1, * cs2, * ncs; - int s1, s2, s; - - s1 = lins[row].size; - s2 = m2.lins[1].size; - cs1 = lins[row].col; - cs2 = m2.lins[1].col; - - i1 = 0; - i2 = 0; - i = 0; - - - if (Symmetric()) - { - while (s2 && cs2[s2-1].colnr > row) s2--; - } - - - while (i1 < s1 && i2 < s2) - { - if (cs1[i1].colnr < cs2[i2].colnr) i1++; - else if (cs1[i1].colnr > cs2[i2].colnr) i2++; - else { i1++; i2++; } - i++; - } - - i += (s1 - i1); - i += (s2 - i2); - - s = i; - - if (s > s1) - { - ncs = NewColStruct (s); - - i1 = 0; - i2 = 0; - i = 0; - - while (i1 < s1 && i2 < s2) - { - if (cs1[i1].colnr < cs2[i2].colnr) - { - ncs[i].colnr = cs1[i1].colnr; - ncs[i].data = cs1[i1].data; - i1++; - } - else if (cs1[i1].colnr > cs2[i2].colnr) - { - ncs[i].colnr = cs2[i2].colnr; - ncs[i].data = cs2[i2].data; - i2++; - } - else - { - ncs[i].colnr = cs1[i1].colnr; - ncs[i].data = cs1[i1].data + cs2[i2].data; - i1++; - i2++; - } - i++; - } - - while (i1 < s1) - { - ncs[i].colnr = cs1[i1].colnr; - ncs[i].data = cs1[i1].data; - i1++; - i++; - } - - while (i2 < s2) - { - ncs[i].colnr = cs2[i2].colnr; - ncs[i].data = cs2[i2].data; - i2++; - i++; - } - - if (lins[row].maxsize) - DeleteColStruct (cs1, lins[row].maxsize); - - lins[row].col = ncs; - lins[row].size = s; - lins[row].maxsize = s; - } - - - else - { - i1 = 0; - i2 = 0; - - while (i2 < s2) - { - if (cs1[i1].colnr == cs2[i2].colnr) - { - cs1[i1].data += cs2[i2].data; - i2++; - } - i1++; - } - } - } - - -double SparseMatrix :: RowTimesVector (INDEX i, const Vector & v) const - { - const linestruct * lin; - const colstruct * col; - double sum; - int j; - - if (Width() > v.Size()) - { - cerr << "SparseMatrix::RowTimesVector: Size doesn't fit" << endl; - return 0; - } - - lin = &lins.Get(i); - sum = 0; - col = lin->col; - - for (j = lin->size; j > 0; j--, col++) - sum += col->data * v.Get(col->colnr); - - return sum; - } - -void SparseMatrix :: AddRowToVector (INDEX i, double s, Vector & v) const - { - const linestruct * lin; - const colstruct * col; - int j; - - if (Width() > v.Size()) - { - cerr << "SparseMatrix::AddRowToVector: Size doesn't fit" - << "w = " << Width() << " len = " << v.Size() << endl; - return; - } - - lin = &lins.Get(i); - col = lin->col; - - for (j = lin->size; j > 0; j--, col++) - v.Elem(col->colnr) += s * col->data; - } - - -static ARRAY<void*> poolarray; -static ARRAY<int> poolsizes; - - -SparseMatrix::colstruct * SparseMatrix :: NewColStruct (int s) - { -// return new colstruct[s]; - - - int i, j; - void * p; - colstruct * cs; - - if (s > 20) return new colstruct[s]; - - for (i = 1; i <= poolsizes.Size(); i++) - if (poolsizes.Get(i) == s) break; - - if (i > poolsizes.Size()) - { - poolsizes.Append(s); - poolarray.Append((void*)NULL); - i = poolsizes.Size(); - } - - p = poolarray.Get(i); - if (!p) - { - poolarray.Elem(i) = p = cs = new colstruct[10 * s]; - for (j = 0; j < 9; j++) - *(void**)(void*)(&cs[s * j]) = &cs[s * (j+1)]; - *(void**)(void*)(&cs[s * 9]) = NULL; - } - - poolarray.Elem(i) = *(void**)p; - return (colstruct*)p; - } - -void SparseMatrix :: DeleteColStruct (colstruct * cs, int s) - { -// delete cs; -// return; - - int i; - - if (s > 20) - { - delete cs; - return; - } - - for (i = 1; i <= poolsizes.Size(); i++) - if (poolsizes.Get(i) == s) break; - - - if (i > poolsizes.Size()) - { - (*myerr) << "SparseMatrix :: DeleteColStruct: Size not found" << endl; - return; - } - - - *(void**)(void*)cs = poolarray.Get(i); - poolarray.Elem(i) = cs; - } - -void SparseMatrix :: SetGraph (const class TABLE<INDEX> & graph) - { - int i, j, es, ad, nne; - colstruct * block; - - nne = 0; - for (i = 1; i <= graph.Size(); i++) - { - if (Symmetric()) - { - es = 0; - for (j = 1; j <= graph.EntrySize(i); j++) - if (graph.Get(i, j) <= i) - es++; - } - else - es = graph.EntrySize(i); - nne += es; - } - - oneblock = 1; - block = new colstruct[nne]; - - ad = 0; - for (i = 1; i <= graph.Size(); i++) - { - if (Symmetric()) - { - es = 0; - for (j = 1; j <= graph.EntrySize(i); j++) - if (graph.Get(i, j) <= i) - es++; - } - else - es = graph.EntrySize(i); - - lins.Elem(i).size = 0; - lins.Elem(i).maxsize = es; - lins.Elem(i).col = &block[ad]; - ad += es; - } - } - - - - -#endif -} -#endif diff --git a/Netgen/libsrc/linalg/sparsmat.hpp b/Netgen/libsrc/linalg/sparsmat.hpp deleted file mode 100644 index 74aaa3134e..0000000000 --- a/Netgen/libsrc/linalg/sparsmat.hpp +++ /dev/null @@ -1,265 +0,0 @@ -#ifdef NONE - -#ifndef FILE_SPARSMAT -#define FILE_SPARSMAT - -/* *************************************************************************/ -/* File: sparsmat.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Oct. 94 */ -/* *************************************************************************/ - - -class SparseMatrix; - -/** - The graph of a sparse matrix. - The graph is stored for a non-symmetric matrix -*/ -class MatrixGraph -{ - /// data structure for one row of matrix - struct linestruct - { - /// allocated size - int allocsize; - /// used size - int size; - /// diag element (always allocated) - int diag; - /// colume numbers - INDEX* col; - }; - - /// graph of matrix - ARRAY<linestruct> lines; - /// increment of allocated line-memory on overflow - int increment; - -public: - //@{ @name Constructors, Destructor - - /// Height of matrix, increment value for line-overflow - MatrixGraph (int size, int aincrement = 5); - /// Allocates graph with elements per row given in ARRAY linesize - MatrixGraph (const ARRAY<int> & linesize); - //@} - - - /// returns position of Element (i, j), 0 for unused - int GetPosition (INDEX i, INDEX j) const; - - /// returns position of new element - int CreatePosition (INDEX i, INDEX j); - - /// Returns height of matrix - int Size() const { return lines.Size(); } - - - friend class SparseMatrix; - friend class SparseMatrixFlex; - friend class SparseMatrixFix; - friend class PointJacobiPrecond; -}; - - - - - - -/** - Base class for sparse matrix. - Matrix to work with in most applications - */ -class SparseMatrix : public BaseMatrix -{ -protected: - /// graph of matrix - const MatrixGraph * graph; - /// pointer to matrix values in each row - ARRAY<double*> data; - -public: - - /// returns reference, fail save but slow - virtual double & operator() (INDEX i, INDEX j); - /// returns value, fail save but slow - virtual double operator() (INDEX i, INDEX j) const; - - - /// prod = matrix x v - virtual void Mult (const Vector & v, Vector & prod) const; - /// prod = matrix^T x v - virtual void MultTrans (const Vector & v, Vector & prod) const; - /// res = b - mat x x - virtual void Residuum (const Vector & x, const Vector & b, - Vector & res) const; - /// res = b - mat^T x x - virtual void ResiduumTrans (const Vector & x, const Vector & b, - Vector & res) const; - - - /** - Add element matrix to sparse matrix. - The graph of the element-matrix must be symmetric. - Global point numbers are given in pnum. - */ - virtual void AddElementMatrix (const ARRAY<INDEX> & pnum, const BaseMatrix & elemmat); - - /// for multigrid-extension, should be removed from here - void GSStepToInner (const Vector & b, Vector & x, double dump, - const BitArray & inner) const; - - /// for multigrid-extension, should be removed from here - void GSStepBackToInner (const Vector & b, Vector & x, double dump, - const BitArray & inner) const; - - /// - virtual ostream & Print (ostream & s) const; - - /** Scalar product of i-th row times vector. - For symmetric matrices only lower left block - (including diagonal) is used. - */ - double RowTimesVector (INDEX i, const Vector & v) const; - /** Adds s times the i-th row of matrix to vector v. - For symmetric matrices only lower left block - (including diagonal) is used. - */ - void AddRowToVector (INDEX i, double s, Vector & v) const; - - /** Number of elements in line. - For symmetric matrices GetDiagPos must be used for - most purposes. - */ - int ElementsInLine (INDEX i) const - { return graph->lines.Get(i).size; } - - /** Columne index of nr-th non-zero element in row i */ - INDEX GetColIndex (INDEX i, int nr) const - { return graph->lines.Get(i).col[nr-1]; } - - /** Referece to columne index of nr-th non-zero - element in row i */ - const INDEX & GetColIndexRef (INDEX i, int nr) const - { return graph->lines.Get(i).col[nr-1]; } - - /** Value of nr-th non-zero element in row i */ - double GetData (INDEX i, int nr) const - { return data.Get(i)[nr-1]; } - - /** Reference to value of nr-th non-zero element in row i */ - const double & GetDataRef (INDEX i, int nr) const - { return data.Get(i)[nr-1]; } - - /** Returns value of diagonal element in row i */ - double GetDiag (INDEX i) const - { return data.Get(i)[graph->lines.Get(i).diag-1]; } - - /** Which position has diagonal element in row i ? */ - int GetDiagPos (INDEX i) const - { return graph->lines.Get(i).diag; } - - /** Returns matrix value of row i, col j. - For symmetric matrices the indices will be sorted in - this function */ - double Get(INDEX i, INDEX j) const; - - /** Set value of element (i, j) to v. - For symmetric matrices element (j, i) is set. */ - void Set(INDEX i, INDEX j, double v); - - /** Returns reference to element (i, j). - For symmetric matrices a reference to (j, i) is returned */ - double & Elem(INDEX i, INDEX j); - - /** Is element (i, j) used ? */ - char Used (INDEX i, INDEX j) const; - -protected: - /// A sparse matrix must not be constructed - SparseMatrix (INDEX h, INDEX w = 0); - /// Allocates matrix position - virtual int CreatePosition (INDEX i, INDEX j) = 0; - -private: - /// - friend class ScalarBlockJacobiPrecond; - friend class PointJacobiPrecond; -}; - - - - -/** Sparse matrix with flexible graph. - On demand, a matrix position is allocated */ -class SparseMatrixFlex : public SparseMatrix -{ - /// non-const pointer to graph. - MatrixGraph * mygraph; - -public: - /// - SparseMatrixFlex (); - /// - SparseMatrixFlex (INDEX h, INDEX w = 0); - /// - SparseMatrixFlex (const SparseMatrix & m2); - /// - virtual ~SparseMatrixFlex (); - - /// - virtual void SetSize (INDEX h, INDEX w = 0); - /// - virtual void SetSymmetric (int sym = 1); - /// - virtual void ChangeSize (INDEX h, INDEX w = 0); - /// - void DeleteElements (); - - - /// - SparseMatrix & operator= (const SparseMatrix & m2); - /// - SparseMatrix & operator*= (double v); - - - /// - virtual BaseMatrix * Copy () const; - /// - void Delete (INDEX i, int nr); - /// - void DeleteElem (INDEX i, INDEX j); - - /// - void SetLineAllocSize (INDEX i, int j); - -protected: - /// - virtual int CreatePosition (INDEX i, INDEX j); - -}; - - - - -/** Sparse matrix with fixed graph. - After construction of the matrix, the graph - must not be changed. */ -class SparseMatrixFix : public SparseMatrix -{ -public: - /// - SparseMatrixFix (const MatrixGraph & agraph, int asymmetric = 0); - /// - virtual ~SparseMatrixFix (); - -protected: - /// CreatePosition is not allowed for SparseMatrixFix -> error - virtual int CreatePosition (INDEX i, INDEX j); -}; - - -#endif - -#endif diff --git a/Netgen/libsrc/linalg/vector.cpp b/Netgen/libsrc/linalg/vector.cpp deleted file mode 100644 index 05b5a0a71e..0000000000 --- a/Netgen/libsrc/linalg/vector.cpp +++ /dev/null @@ -1,787 +0,0 @@ -#ifdef abc -#include <mystdlib.h> -#include <linalg.hpp> -#include <algorithm> - -namespace netgen -{ - -double BaseVector :: shit = 0; - -// %FD Constructs a vector of length zero -BaseVector :: BaseVector () - { - length = 0; - } - -// %FD Constructs a vector of given length -BaseVector :: BaseVector ( - INDEX alength // length of the vector - ) - { - length = alength; - } - -// %FD Sets length of the vector, old vector will be destroyed -void -BaseVector :: SetLength ( - INDEX alength // new length of the vector - ) - { - length = alength; - } - -// %FD Changes length of the vector, old values stay valid -void -BaseVector :: ChangeLength ( - INDEX alength // new length of the vector - ) - { - length = alength; - } - - - -// %FD { Write a vector with the help of the '<<' operator onto a stream } -ostream & // stream for further use -operator<< ( - ostream & s, // stream to write vector onto - const BaseVector & v // vector to write - ) - { - return v.Print (s); - } - - -// %FD{ Divides every component of the vector by the scalar c. -// The function checks for division by zero } -BaseVector & // result vector -BaseVector :: operator/= ( - double c // scalar to divide by - ) - { - if (c) - return (*this) *= (1/c); - else - { - (*myerr) << "operator/=: division by zero" << endl; - return *this; - } - } - - -// %FD Creates a copy of the object -BaseVector * // pointer to the new vector -BaseVector :: Copy () const - { - cerr << "Base_vector::Copy called" << endl << flush; - return NULL; - } - - - - -void BaseVector :: GetElementVector (const ARRAY<INDEX> & pnum, - BaseVector & elvec) const -{ - int i; - for (i = 1; i <= pnum.Size(); i++) - elvec(i) = (*this)(pnum.Get(i)); -} - -void BaseVector :: SetElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec) -{ - int i; - for (i = 1; i <= pnum.Size(); i++) - (*this)(pnum.Get(i)) = elvec(i); -} - - -void BaseVector :: AddElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec) -{ - int i; - for (i = 1; i <= pnum.Size(); i++) - (*this)(pnum.Get(i)) += elvec(i); -} - - - - - - - - - - - -TempVector :: ~TempVector () - { - delete vec; - } - -TempVector BaseVector :: operator+ (const BaseVector & v2) const - { - return (*Copy()) += v2; - } - -TempVector BaseVector :: operator- (const BaseVector & v2) const - { - return (*Copy()) -= v2; - } - -TempVector BaseVector :: operator- () const - { - return (*Copy()) *= -1; - } - - -TempVector operator* (const BaseVector & v1, double scal) - { - return (*v1.Copy()) *= scal; - } - -TempVector operator/ (const BaseVector & v1, double scal) - { - return (*v1.Copy()) /= scal; - } - - -TempVector operator* (double scal, const BaseVector & v1) - { - return v1 * scal; - } - - - - - -BaseVector * TempVector :: Copy () const - { - return vec->Copy(); - } - - - - - - - - - - -double Vector :: shit = 0; - -class clVecpool -{ -public: - ARRAY<double *> vecs; - ARRAY<INDEX> veclens; - - ~clVecpool(); -}; - -clVecpool :: ~clVecpool() -{ - int i; - for (i = 1; i <= vecs.Size(); i++) - delete vecs.Elem(i); -} - -static clVecpool vecpool; - - - -static double * NewDouble (INDEX len) -{ - if (len < 10) - return new double[len]; - else - { - int i; - for (i = 1; i <= vecpool.veclens.Size(); i++) - if (vecpool.veclens.Get(i) == len) - { - double * hvec = vecpool.vecs.Get(i); - vecpool.vecs.DeleteElement(i); - vecpool.veclens.DeleteElement(i); - return hvec; - } - - return new double[len]; - } -} - -static void DeleteDouble (INDEX len, double * dp) -{ - if (len < 10) - delete [] dp; - else - { - vecpool.vecs.Append (dp); - vecpool.veclens.Append (len); - } -} - - - -Vector :: Vector () : BaseVector() - { - data = NULL; - } - -Vector :: Vector (INDEX alength) : BaseVector (alength) - { - if (length) - { - // data = new double[length]; - data = NewDouble (length); - - if (!data) - { - length = 0; - (*myerr) << "Vector not allocated" << endl; - } - } - else - data = NULL; - } - - -Vector :: Vector (const Vector & v2) - { - length = v2.length; - - if (length) - { - // data = new double[length]; - data = NewDouble (length); - - if (data) - { - memcpy (data, v2.data, length * sizeof (double)); - } - else - { - length = 0; - (*myerr) << "Vector::Vector : Vector not allocated" << endl; - } - } - else - data = NULL; - } - - -Vector :: ~Vector () -{ - // veclenfile << "~Vector delete: " << length << endl; - if (data) - { - DeleteDouble (length, data); - // delete [] data; - } - -} - -void Vector :: SetLength (INDEX alength) - { - if (length == alength) return; - - if (data) - { - DeleteDouble (length, data); - // delete [] data; - } - data = NULL; - length = alength; - - if (length == 0) return; - // data = new double[length]; - data = NewDouble (length); - - if (!data) - { - length = 0; - (*myerr) << "Vector::SetLength: Vector not allocated" << endl; - } - } - -void Vector :: ChangeLength (INDEX alength) -{ - (*mycout) << "Vector::ChangeLength called" << endl; - if (length == alength) return; - - if (alength == 0) - { - // delete [] data; - DeleteDouble (length, data); - length = 0; - return; - } - - double * olddata = data; - - data = NewDouble (alength); - // data = new double[alength]; - if (!data) - { - length = 0; - (*myerr) << "Vector::SetLength: Vector not allocated" << endl; - delete [] olddata; - } - - memcpy (data, olddata, min2(alength, length)); - - delete [] olddata; - length = alength; - } - -/// NEW RM -void Vector::SetBlockLength (INDEX /* blength */) -{ - MyError("BaseVector::SetBlockLength was called for a Vector"); -} - - -double & Vector :: operator() (INDEX i) - { - if (i >= 1 && i <= length) return Elem(i); - else (*myerr) << "\nindex " << i << " out of range (" - << 1 << "," << Length() << ")\n"; - return shit; - } - -double Vector :: operator() (INDEX i) const - { - if (i >= 1 && i <= length) return Get(i); - else (*myerr) << "\nindex " << i << " out of range (" - << 1 << "," << Length() << ")\n" << flush; - return shit; - } - - - -double Vector :: SupNorm () const - { - double sup = 0; - - for (INDEX i = 1; i <= Length(); i++) - if (fabs (Get(i)) > sup) - sup = fabs(Get(i)); - - return sup; - } - -double Vector :: L2Norm () const - { - double sum = 0; - - for (INDEX i = 1; i <= Length(); i++) - sum += Get(i) * Get(i); - - return sqrt (sum); - } - -double Vector :: L1Norm () const - { - double sum = 0; - - for (INDEX i = 1; i <= Length(); i++) - sum += fabs (Get(i)); - - return sum; - } - -double Vector :: Max () const - { - if (!Length()) return 0; - double m = Get(1); - for (INDEX i = 2; i <= Length(); i++) - if (Get(i) > m) m = Get(i); - return m; - } - -double Vector :: Min () const - { - if (!Length()) return 0; - double m = Get(1); - for (INDEX i = 2; i <= Length(); i++) - if (Get(i) < m) m = Get(i); - return m; - } - - -/* -ostream & operator<<(ostream & s, const Vector & v) - { - int w = s.width(); - if (v.Length()) - { - s.width(0); - s << '('; - for (INDEX i = 1; i < v.Length(); i++) - { - s.width(w); - s << v.Get(i) << ","; - if (i % 8 == 0) s << endl << ' '; - } - s.width(w); - s << v.Get(v.Length()) << ')'; - } - else - s << "(Vector not allocated)"; - - return s; - } -*/ - -ostream & Vector :: Print (ostream & s) const - { - int w = s.width(); - if (Length()) - { - s.width(0); - s << '('; - for (INDEX i = 1; i < Length(); i++) - { - s.width(w); - s << Get(i) << ","; - if (i % 8 == 0) s << endl << ' '; - } - s.width(w); - s << Get(Length()) << ')'; - } - else - s << "(Vector not allocated)"; - - return s; - } - - - -BaseVector & Vector :: operator+= (const BaseVector & v2) - { - const Vector & hv2 = v2.CastToVector(); - - if (Length() == hv2.Length()) - for (INDEX i = 1; i <= Length(); i++) - Elem (i) += hv2.Get(i); - else - (*myerr) << "operator+= illegal dimension" << endl; - return *this; - } - -BaseVector & Vector :: operator-= (const BaseVector & v2) - { - const Vector & hv2 = v2.CastToVector(); - - if (Length() == hv2.Length()) - for (INDEX i = 1; i <= Length(); i++) - Elem (i) -= hv2.Get(i); - else - (*myerr) << "operator-= illegal dimension" << endl; - return *this; - } - -BaseVector & Vector :: operator*= (double c) - { - for (INDEX i = 1; i <= Length(); i++) - Elem(i) *= c; - return *this; - } - - - -BaseVector & Vector :: Add (double scal, const BaseVector & v2) - { - const Vector & hv2 = v2.CastToVector(); - - if (Length() == hv2.Length()) - { - double * p1 = data; - double * p2 = hv2.data; - - for (INDEX i = Length(); i > 0; i--) - { - (*p1) += scal * (*p2); - p1++; p2++; - } - } - else - (*myerr) << "Vector::Add: illegal dimension" << endl; - return *this; - } - -BaseVector & Vector :: Add2 (double scal, const BaseVector & v2, - double scal3, const BaseVector & v3) - { - const Vector & hv2 = v2.CastToVector(); - const Vector & hv3 = v3.CastToVector(); - - if (Length() == hv2.Length()) - { - double * p1 = data; - double * p2 = hv2.data; - double * p3 = hv3.data; - - for (INDEX i = Length(); i > 0; i--) - { - (*p1) += (scal * (*p2) + scal3 * (*p3)); - p1++; p2++; p3++; - } - } - else - (*myerr) << "Vector::Add: illegal dimension" << endl; - return *this; - } - -BaseVector & Vector :: Set (double scal, const BaseVector & v2) - { - const Vector & hv2 = v2.CastToVector(); - - if (Length() == hv2.Length()) - { - double * p1 = data; - double * p2 = hv2.data; - - for (INDEX i = Length(); i > 0; i--) - { - (*p1) = scal * (*p2); - p1++; p2++; - } - } - else - (*myerr) << "Vector::Set: illegal dimension" << endl; - return *this; - } - - -BaseVector & Vector :: Set2 (double scal , const BaseVector & v2, - double scal3, const BaseVector & v3) - { - const Vector & hv2 = v2.CastToVector(); - const Vector & hv3 = v3.CastToVector(); - - - if (Length() == hv2.Length()) - { - double * p1 = data; - double * p2 = hv2.data; - double * p3 = hv3.data; - - for (INDEX i = Length(); i > 0; i--) - { - (*p1) = scal * (*p2) + scal3 * (*p3); - p1++; p2++; p3++; - } - } - else - (*myerr) << "Vector::Set: illegal dimension" << endl; - return *this; - } - - -void Vector :: GetPart (int startpos, BaseVector & v2) const -{ - Vector & hv2 = v2.CastToVector(); - - if (Length() >= startpos + v2.Length() - 1) - { - const double * p1 = &Get(startpos); - double * p2 = &hv2.Elem(1); - - memcpy (p2, p1, hv2.Length() * sizeof(double)); - } - else - MyError ("Vector::GetPart: Vector to short"); -} - - -// NEW RM -void Vector :: SetPart (int startpos, const BaseVector & v2) -{ - const Vector & hv2 = v2.CastToVector(); - INDEX i; - INDEX n = v2.Length(); - - if (Length() >= startpos + n - 1) - { - double * p1 = &Elem(startpos); - const double * p2 = &hv2.Get(1); - - for (i = 1; i <= n; i++) - { - (*p1) = (*p2); - p1++; - p2++; - } - } - else - MyError ("Vector::SetPart: Vector to short"); -} - -void Vector :: AddPart (int startpos, double val, const BaseVector & v2) -{ - const Vector & hv2 = v2.CastToVector(); - INDEX i; - INDEX n = v2.Length(); - - if (Length() >= startpos + n - 1) - { - double * p1 = &Elem(startpos); - const double * p2 = &hv2.Get(1); - - for (i = 1; i <= n; i++) - { - (*p1) += val * (*p2); - p1++; - p2++; - } - } - else - MyError ("Vector::AddPart: Vector to short"); -} - - - - -double Vector :: operator* (const BaseVector & v2) const - { - const Vector & hv2 = v2.CastToVector(); - - double sum = 0; - double * p1 = data; - double * p2 = hv2.data; - - if (Length() == hv2.Length()) - { - for (INDEX i = Length(); i > 0; i--) - { - sum += (*p1) * (*p2); - p1++; p2++; - } - } - else - (*myerr) << "Scalarproduct illegal dimension" << endl; - return sum; - } - -void Vector :: SetRandom () - { - INDEX i; - for (i = 1; i <= Length(); i++) - Elem(i) = rand (); - - double l2 = L2Norm(); - if (l2 > 0) - (*this) /= l2; - // Elem(i) = 1.0 / double(i); - // Elem(i) = drand48(); - } - - -/* -TempVector Vector :: operator- () const - { - Vector & sum = *(Vector*)Copy(); - - if (sum.Length () == Length()) - { - for (INDEX i = 1; i <= Length(); i++) - sum.Set (i, Get(i)); - } - else - (*myerr) << "operator+ (Vector, Vector): sum.Length() not ok" << endl; - return sum; - } -*/ - -BaseVector & Vector::operator= (const Vector & v2) - { - SetLength (v2.Length()); - - if (data == v2.data) return *this; - - if (v2.Length() == Length()) - memcpy (data, v2.data, sizeof (double) * Length()); - else - (*myerr) << "Vector::operator=: not allocated" << endl; - - return *this; - } - -BaseVector & Vector::operator= (const BaseVector & v2) - { - const Vector & hv2 = v2.CastToVector(); - - SetLength (hv2.Length()); - - if (data == hv2.data) return *this; - - if (hv2.Length() == Length()) - memcpy (data, hv2.data, sizeof (double) * Length()); - else - (*myerr) << "Vector::operator=: not allocated" << endl; - - return *this; - } - - -BaseVector & Vector::operator= (double scal) - { - if (!Length()) (*myerr) << "Vector::operator= (double) : data not allocated" - << endl; - - for (INDEX i = 1; i <= Length(); i++) - Set (i, scal); - - return *this; - } - - -BaseVector * Vector :: Copy () const - { - return new Vector (*this); - } - - -void Vector :: Swap (BaseVector & v2) - { - Vector & hv2 = v2.CastToVector(); - swap (length, hv2.length); - swap (data, hv2.data); - } - - - - -void Vector :: GetElementVector (const ARRAY<INDEX> & pnum, - BaseVector & elvec) const -{ - int i; - Vector & helvec = elvec.CastToVector(); - for (i = 1; i <= pnum.Size(); i++) - helvec.Elem(i) = Get(pnum.Get(i)); -} - -void Vector :: SetElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec) -{ - int i; - const Vector & helvec = elvec.CastToVector(); - for (i = 1; i <= pnum.Size(); i++) - Elem(pnum.Get(i)) = helvec.Get(i); -} - - -void Vector :: AddElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec) -{ - int i; - const Vector & helvec = elvec.CastToVector(); - for (i = 1; i <= pnum.Size(); i++) - Elem(pnum.Get(i)) += helvec.Get(i); -} -} -#endif diff --git a/Netgen/libsrc/linalg/vector.hpp b/Netgen/libsrc/linalg/vector.hpp deleted file mode 100644 index acba491792..0000000000 --- a/Netgen/libsrc/linalg/vector.hpp +++ /dev/null @@ -1,485 +0,0 @@ -#ifndef FILE_VECTOR -#define FILE_VECTOR - -/* *************************************************************************/ -/* File: vector.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Oct. 94 */ -/* *************************************************************************/ - - -class FlatVector -{ -protected: - int s; - double *data; -public: - FlatVector () { ; } - FlatVector (int as, double * adata) - { s = as; data = adata; } - - int Size () const - { return s; } - - FlatVector & operator= (const FlatVector & v) - { memcpy (data, v.data, s*sizeof(double)); return *this; } - - FlatVector & operator= (double scal) - { - for (int i = 0; i < s; i++) data[i] = scal; - return *this; - } - - double & operator[] (int i) { return data[i]; } - const double & operator[] (int i) const { return data[i]; } - double & operator() (int i) { return data[i]; } - const double & operator() (int i) const { return data[i]; } - - double & Elem (int i) { return data[i-1]; } - const double & Get (int i) const { return data[i-1]; } - void Set (int i, double val) { data[i-1] = val; } - - FlatVector & operator*= (double scal) - { - for (int i = 0; i < s; i++) data[i] *= scal; - return *this; - } - - FlatVector & Add (double scal, const FlatVector & v2) - { - for (int i = 0; i < s; i++) - data[i] += scal * v2.data[i]; - return *this; - } - - FlatVector & Set (double scal, const FlatVector & v2) - { - for (int i = 0; i < s; i++) - data[i] = scal * v2.data[i]; - return *this; - } - - FlatVector & Set2 (double scal1, const FlatVector & v1, - double scal2, const FlatVector & v2) - { - for (int i = 0; i < s; i++) - data[i] = scal1 * v1.data[i] + scal2 * v2.data[i]; - return *this; - } - - double L2Norm() const - { - double sum = 0; - for (int i = 0; i < s; i++) - sum += data[i] * data[i]; - return sqrt (sum); - } - - friend double operator* (const FlatVector & v1, const FlatVector & v2); -}; - - - -class Vector : public FlatVector -{ - -public: - Vector () - { s = 0; data = 0; } - Vector (int as) - { s = as; data = new double[s]; } - ~Vector () - { delete [] data; } - - Vector & operator= (const FlatVector & v) - { memcpy (data, &v.Get(1), s*sizeof(double)); return *this; } - - Vector & operator= (double scal) - { - for (int i = 0; i < s; i++) data[i] = scal; - return *this; - } - - void SetSize (int as) - { - if (s != as) - { - s = as; - delete [] data; - data = new double [s]; - } - } - -}; - - -inline double operator* (const FlatVector & v1, const FlatVector & v2) -{ - double sum = 0; - for (int i = 0; i < v1.s; i++) - sum += v1.data[i] * v2.data[i]; - return sum; -} - - - - -inline ostream & operator<< (ostream & ost, const FlatVector & v) -{ - for (int i = 0; i < v.Size(); i++) - ost << " " << setw(7) << v[i]; - return ost; -} - - - - - - - - - - -#ifdef OLDVEC - -class TempVector; -class Vector; -class BlockVector; - -/** Data types for vectors. - - Every Vector data structure is derived from a BaseVector class. - A BaseVector provides virtual functions for the scalar-vector - and vector-vector operations. - If the return value of a function is a vector, then there should - be used a TempVector class. This avoids one additional constructor/ - destructor call. - Finally, a Vector - class contains the data of a Vector in dense - form. - - Vector - Operations: - - Vector ( x ) Constructor empty, with given length or - given vector to copy - - SetLength () - ChangeLength() Change vector-length with/without destroing the vector - Length() return vector-length - - Copy() Construct a vector of same type and contents - - operator() Save vector access - Set, Get, Elem: Fast vector access for setting, receiving and reference - - +, -, *, =, +=, -=, *=, /= - virtual vector operations - - SupNorm, L2Norm, L1Norm, Min, Max - Vector operations - - Set (s, v), Add (s, v) - Fast scalar-vector operations - - Print () stream output of a vector - -*/ - -class BaseVector -{ -protected: - /// - INDEX length; - /// - static double shit; - -public: - /// - BaseVector (); - /// - BaseVector (INDEX alength); - /// - virtual ~BaseVector () { }; - /// - virtual void SetSize (INDEX asize) { SetLength(asize); } - /// - virtual void SetLength (INDEX alength); - /// - virtual void ChangeLength (INDEX alength); - /// Size should be prefered !!! - INDEX Length () const { return length; } - /// - INDEX Size() const { return length; } - - // NEW RM ---> in BlockVector - // rtual void SetBlockLength (INDEX blength) = 0; - - /// - virtual BaseVector & operator= (const BaseVector & /* v2 */) { return *this; } - /// - virtual BaseVector & operator= (double /* scal */) { return *this; } - - /// - virtual double & operator() (INDEX /* i */) { return shit; } - /// - virtual double operator() (INDEX /* i */) const { return 0; } - - /// - virtual double SupNorm () const = 0; - /// - virtual double L2Norm () const = 0; - /// - virtual double L1Norm () const = 0; - /// - virtual double Min () const = 0; - /// - virtual double Max () const = 0; - - /// - virtual BaseVector & operator+= (const BaseVector & v2) = 0; - /// - virtual BaseVector & operator-= (const BaseVector & v2) = 0; - /// - virtual BaseVector & operator*= (double scal) = 0; - /// - virtual BaseVector & operator/= (double scal); - - /// - virtual TempVector operator+ (const BaseVector & v2) const; - /// - virtual TempVector operator- (const BaseVector & v2) const; - /// - virtual TempVector operator- () const; - /// - virtual double operator* (const BaseVector & v2) const = 0; - /// - friend TempVector operator* (const BaseVector & v1, double scal); - /// - friend TempVector operator/ (const BaseVector & v1, double scal); - /// - friend TempVector operator* (double scal, const BaseVector & v1); - - /// - virtual BaseVector & Add (double /* scal */, const BaseVector & /* v2 */) { return *this; } - /// - virtual BaseVector & Add2 (double /* scal */, const BaseVector & /* v2 */, - double /* scal3 */, const BaseVector & /* v3 */) { return *this; } - /// - virtual BaseVector & Set (double /* scal */, const BaseVector & /* v2 */) { return *this; } - /// - virtual BaseVector & Set2 (double /* scal */, const BaseVector & /* v2 */, - double /* scal3 */, const BaseVector & /* v3 */) { return *this; } - - /// - virtual void SetRandom () { }; - - - /// - virtual void GetPart (int /* startpos */, - BaseVector & /* v2*/ ) const { }; - /// - virtual void SetPart (int /* startpos */, - const BaseVector & /* v2 */) { }; - /// - virtual void AddPart (int /* startpos */, double /* val */, - const BaseVector & /* v2 */) { }; - - /// - virtual void GetElementVector (const ARRAY<INDEX> & pnum, - BaseVector & elvec) const; - /// - virtual void SetElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec); - /// - virtual void AddElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec); - - /// - friend ostream & operator<<(ostream & s, const BaseVector & v); - /// - virtual ostream & Print (ostream & s) const { return s; } - - /// - virtual BaseVector * Copy () const; - /// - virtual int IsVector () const { return 0; } - /// - virtual int IsBlockVector () const { return 0; } - /// - virtual Vector & CastToVector () { return *(Vector*)this; } - /// - virtual const Vector & CastToVector () const { return *(Vector*)this; } - /// - virtual BlockVector & CastToBlockVector () { return *(BlockVector*)this; } - /// - virtual const BlockVector & CastToBlockVector () const { return *(BlockVector*)this; } - }; - - -/// -class TempVector : public BaseVector -{ - /// - BaseVector * vec; - - public: - /// - TempVector (BaseVector & v1) { vec = & v1; } - /// - ~TempVector (); - /// - virtual Vector & CastToVector () - { return vec->CastToVector(); } - /// - virtual const Vector & CastToVector () const - { return vec->CastToVector(); } - /// - virtual BlockVector & CastToBlockVector () - { return vec->CastToBlockVector(); } - /// - virtual const BlockVector & CastToBlockVector () const - { return vec->CastToBlockVector(); } - - - /// - virtual BaseVector & operator+= (const BaseVector & /* v2 */) { return *this; } - /// - virtual BaseVector & operator-= (const BaseVector & /* v2 */) { return *this; } - /// - virtual BaseVector & operator*= (double /* scal */) { return *this; } - /// - virtual double operator* (const BaseVector & /* v2 */) const { return 0; } - - /// - virtual double SupNorm () const { return vec->SupNorm(); } - /// - virtual double L2Norm () const { return vec->L2Norm(); } - /// - virtual double L1Norm () const { return vec->L1Norm(); } - /// - virtual double Min () const { return vec->Min(); } - /// - virtual double Max () const { return vec->Max(); } - - /// - virtual void Swap (BaseVector &) { }; - /// - virtual BaseVector * Copy () const; - - - }; - - -/// -class Vector : public BaseVector -{ - /// - double * data; - /// - static double shit; - -public: - /// - Vector (); - /// - Vector (INDEX alength); - /// - Vector (const Vector & v2); - /// - virtual ~Vector (); - - /// - virtual void SetLength (INDEX alength); - /// - virtual void ChangeLength (INDEX alength); - /// NEW RM - virtual void SetBlockLength (INDEX blength); - - /// - virtual BaseVector & operator= (const BaseVector & v2); - /// - virtual BaseVector & operator= (const Vector & v2); - /// - virtual BaseVector & operator= (double scal); - - /// - double & operator() (INDEX i); - /// - double operator() (INDEX i) const; - - /// - virtual double SupNorm () const; - /// - virtual double L2Norm () const; - /// - virtual double L1Norm () const; - /// - virtual double Min () const; - /// - virtual double Max () const; - - /// - virtual BaseVector & operator+= (const BaseVector & v2); - /// - virtual BaseVector & operator-= (const BaseVector & v2); - /// - virtual BaseVector & operator*= (double scal); - - /// - virtual double operator* (const BaseVector & v2) const; - - - /// - virtual BaseVector & Add (double scal, const BaseVector & v2); - /// - virtual BaseVector & Add2 (double scal, const BaseVector & v2, - double scal3, const BaseVector & v3); - /// - virtual BaseVector & Set (double scal, const BaseVector & v2); - /// - virtual BaseVector & Set2 (double scal , const BaseVector & v2, - double scal3, const BaseVector & v3); - - /// - virtual void GetPart (int startpos, BaseVector & v2) const; - /// - virtual void SetPart (int startpos, const BaseVector & v2); - /// - virtual void AddPart (int startpos, double val, const BaseVector & v2); - - /// - virtual void SetRandom (); - - /// - virtual ostream & Print (ostream & s) const; - /// - virtual BaseVector * Copy () const; - /// - virtual void Swap (BaseVector &); - - /// - const double & Get (INDEX i) const { return data[i-1]; } - /// - void Set (INDEX i, double v) { data[i-1] = v; } - /// - double & Elem (INDEX i) { return data[i-1]; } - - /// - virtual int IsVector () const { return 1; } - - - /// - virtual void GetElementVector (const ARRAY<INDEX> & pnum, - BaseVector & elvec) const; - /// - virtual void SetElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec); - /// - virtual void AddElementVector (const ARRAY<INDEX> & pnum, - const BaseVector & elvec); - }; - -#endif - -#endif - - diff --git a/Netgen/libsrc/makefile.inc b/Netgen/libsrc/makefile.inc deleted file mode 100644 index 76369d5fb6..0000000000 --- a/Netgen/libsrc/makefile.inc +++ /dev/null @@ -1,48 +0,0 @@ -# -# -# Make-Include-File for library -# Joachim Schoeberl, 17.04.96 -# -# -CPP_DIR=../.. -LIBSRC_DIR=$(CPP_DIR)/libsrc -LIB_DIR=$(CPP_DIR)/lib/$(MACHINE) - -OCC_DIR=../../occ -OCCINC_DIR=$(OCC_DIR)/inc -OCCLIB_DIR=$(OCC_DIR)/lib -# -include $(LIBSRC_DIR)/makefile.mach.$(MACHINE) -# -CPLUSPLUSFLAGS1 = -c -I$(LIBSRC_DIR)/include -I$(OCCINC_DIR) -# -ARFLAGS = r -# -LIBB=$(LIB_DIR)/lib$(lib).a -# -.PRECIOUS: .cpp .c -.SUFFIXES: .cpp .c .o -# -.cpp.o: - $(CPLUSPLUS) $(CPLUSPLUSFLAGS1) $(CPLUSPLUSFLAGS2) $(CPLUSPLUSFLAGSLIBRARY) $< -.c.o: - $(CPLUSPLUS) $(CPLUSPLUSFLAGS1) $(CPLUSPLUSFLAGS2) $(CPLUSPLUSFLAGSLIBRARY) $< -# -# -$(LIBB):: $(LIB_DIR) -# -# make lib from sources: -# -$(LIBB):: $(src) - $(CPLUSPLUS) $(CPLUSPLUSFLAGS1) $(CPLUSPLUSFLAGS2) $(CPLUSPLUSFLAGSLIBRARY) $? - @$(AR) $(ARFLAGS) $@ *.o - -@$(RM) *.o - -@$(RANLIB) $@ -# -# -# -$(LIB_DIR) : - -@mkdir $(CPP_DIR)/lib - @mkdir $(LIB_DIR) -# -# diff --git a/Netgen/libsrc/makefile.mach.FREEBSD b/Netgen/libsrc/makefile.mach.FREEBSD deleted file mode 100644 index 6f903d4e60..0000000000 --- a/Netgen/libsrc/makefile.mach.FREEBSD +++ /dev/null @@ -1,26 +0,0 @@ -# -# Machine dependent make include file for gcc -# -# -#CC=gcc -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -#MAKE=make -RM=rm -RANLIB=ranlib -# -# Machine dependent flags: -# -include $(LOCALBASE)/lib/tixConfig.sh -include $(LOCALBASE)/lib/tcl$(TCL_VER)/tclConfig.sh -include $(LOCALBASE)/lib/tk$(TK_VER)/tkConfig.sh -tcltklib = `echo $(TIX_BUILD_LIB_SPEC)` `echo $(TK_LIB_SPEC)` `echo $(TCL_LIB_FLAG)` - -CFLAGS2 = -CPLUSPLUSFLAGS2 = $(CXXFLAGS) -I$(X11BASE)/include -DLINUX -DOPENGL -CPLUSPLUSFLAGS3 = -I$(LIBSRC_DIR)/step `echo $(TCL_INCLUDE_SPEC)` `echo -I$(TK_PREFIX)`/include/tk`echo $(TK_VERSION)` -# -LINKFLAGS2 = -L$(LOCALBASE)/lib -L$(X11BASE)/lib - -SYSLIB2 = -lstdc++ diff --git a/Netgen/libsrc/makefile.mach.INTEL b/Netgen/libsrc/makefile.mach.INTEL deleted file mode 100644 index deef5b091c..0000000000 --- a/Netgen/libsrc/makefile.mach.INTEL +++ /dev/null @@ -1,34 +0,0 @@ -# -# Machine dependent make include file -# -CC=icc -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -MAKE=make -RM=rm -RANLIB=ranlib -# -# Machine dependent flags: -# -CFLAGS2 = -CPLUSPLUSFLAGS2 = -O2 -wd1572 -Ob2 -DLINUX -DOPENGL -DNGSOLVE \ - -Qoption,c,-ip_ninl_max_stats=1000 \ - -Qoption,c,-ip_ninl_min_stats=50 \ - -Qoption,c,-ip_ninl_max_total_stats=1000 \ - -gcc-name=/usr/bin/g++ -# -LINKFLAGS2 = -L/usr/openwin/lib -L/usr/X11R6/lib -L/usr/lib/GL3.5 \ - -gcc-name=/usr/bin/g++ -# -# SYSLIB2 = /opt/experimental/lib/libstdc++.a -# SYSLIB2 = -lstdc++ -# -lgcc_s -# SYSLIB2 = -L/usr/lib/lapack -lblas -lstdc++ - -# goalngs = goalngs - - -goalngs=goalngs - -appngs = lib/$(MACHINE)/*.o -lngsolvebasic \ No newline at end of file diff --git a/Netgen/libsrc/makefile.mach.LINUX b/Netgen/libsrc/makefile.mach.LINUX deleted file mode 100644 index f5df356167..0000000000 --- a/Netgen/libsrc/makefile.mach.LINUX +++ /dev/null @@ -1,31 +0,0 @@ -# -# Machine dependent make include file -# -# -# CC=/opt/gcc-dev/bin/gcc -# CC=/usr/local/bin/gcc -CC=gcc -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -MAKE=make -RM=rm -RANLIB=ranlib -# -# Machine dependent flags: -# -CFLAGS2 = - -CPLUSPLUSFLAGS2 = -O2 -I/usr/include/GL3.5 -DLINUX -DOPENGL \ - -ftemplate-depth-99 -finline-limit=20000 \ - -funroll-loops -DNGSOLVE - -LINKFLAGS2 = -L/usr/openwin/lib -L/usr/X11R6/lib -L/usr/lib/GL3.5 -lstdc++ - - -goalngs=goalngs - -# lapack = -llapack -lblas -lgmp -lg2c - - -appngs = lib/$(MACHINE)/*.o -lngsolvebasic \ No newline at end of file diff --git a/Netgen/libsrc/makefile.mach.LINUXGCC33 b/Netgen/libsrc/makefile.mach.LINUXGCC33 deleted file mode 100644 index 0a6ee84afb..0000000000 --- a/Netgen/libsrc/makefile.mach.LINUXGCC33 +++ /dev/null @@ -1,33 +0,0 @@ -# -# Machine dependent make include file -# -# -# CC=/opt/gcc33/bin/gcc -# CC=/usr/local/bin/gcc -CC=gcc -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -MAKE=make -RM=rm -RANLIB=ranlib -# -# -CFLAGS2 = -CPLUSPLUSFLAGS2 = -O2 -DLINUX -DOPENGL \ - -ftemplate-depth-99 -finline-limit=20000 \ - -mcpu=pentium4 -fforce-addr -funroll-loops \ - -DnoTRAFO -DNGSOLVE -DnoADDON -DnoPML -DnoLAPACK \ - -DnoOCCGEOMETRY -I/usr/include/g++/backward -I./occ/inc -DnoDEBUG -# -# -# -LINKFLAGS2 = -L/usr/openwin/lib -L/usr/X11R6/lib -L/usr/lib/GL3.5 - -SYSLIB2 = -lstdc++ - -goalngs = goalngs - -appngs = lib/$(MACHINE)/*.o -lngsolvebasic - -# occlib = -L$(OCCLIB_DIR) -lTKIGES -lTKBRep -lTKSTEP -lTKSTL \ No newline at end of file diff --git a/Netgen/libsrc/makefile.mach.SGI b/Netgen/libsrc/makefile.mach.SGI deleted file mode 100644 index b75920ce26..0000000000 --- a/Netgen/libsrc/makefile.mach.SGI +++ /dev/null @@ -1,19 +0,0 @@ -# -# Machine dependent make include file -# -CC=CC -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -MAKE=make -k -RM=rm -RANLIB=echo -# -CFLAGS2 = -# -CPLUSPLUSFLAGS2 = -O2 -LANG:std -OPT:Olimit=0 -I/usr/X11R6/include -I/usr/local/include -I/nfs/home/joachim/tcltk/include -DOPENGL -woff 1174 -woff 1682 -woff 1681 -woff 1552 -DOLDCINCLUDE -# -woff 3262,3203,1174,1110 -# -# -I/usr/freeware/include -LINKFLAGS2 = -LANG:std -L/usr/openwin/lib -L/usr/freeware/lib32 -L/usr/X11R6/lib -L/usr/local/lib -w -L/nfs/home/joachim/tcltk/lib - diff --git a/Netgen/libsrc/makefile.mach.SGIGCC b/Netgen/libsrc/makefile.mach.SGIGCC deleted file mode 100644 index c43363c5e7..0000000000 --- a/Netgen/libsrc/makefile.mach.SGIGCC +++ /dev/null @@ -1,53 +0,0 @@ -# -# Machine dependent make include file -# -# -# CC=/opt/experimental/bin/gcc -CC=/usr/freeware/bin/gcc -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -MAKE=make -RM=rm -RANLIB=ranlib -# -# Machine dependent flags: -# -CFLAGS2 = -# I/opt/experimental/include/g++-v3 -CPLUSPLUSFLAGS2 = -O2 -save-temps -fverbose-asm -I/usr/local/include -I/usr/freeware/include -I/usr/freeware/include/tcl -I/usr/freeware/include/tk -I/usr/include/GL3.5 -DLINUX -DOPENGL -I../lapack/\ - -ftemplate-depth-99 -# -finline-limit=10000 -# -mcpu=pentiumpro -fforce-addr -Wdisabled-optimization -funroll-loops -# -funroll-all-loops -# -dr -dt -df -# -fforce-addr \ -# -fssa -fdce -fschedule-insns2 -fstrict-aliasing -frename-registers \ -# -freg-struct-return -# -fargument-noalias-global -fargument-noalias \ -# --param max-gcse-memory=100000000 \ -# --param max-delay-slot-live-search=100000 \ -# --param max-pending-list-length=10000 \ -# -fssa \ -# -fomit-frame-pointer -fno-enforce-eh-specs -fno-defer-pop \ -# -fforce-mem -fstrict-aliasing \ -# -fno-implement-inlines \ -# -foptimize-sibling-calls \ -# -frerun-cse-after-loop -fcse-follow-jumps -fexpensive-optimizations \ -# -fstrength-reduce -frerun-loop-opt -fcse-skip-blocks -fgcse \ -# -pedantic \ -# -fno-implicit-templates -# -# -I/usr/local/intel/mkl/INCLUDE -# -fsyntax-only -# -fomit-frame-pointer -# -funroll-loops -# -LINKFLAGS2 = -L/usr/local/lib -L/usr/openwin/lib -L/usr/X11R6/lib -L/usr/lib/GL3.5 -L/usr/freeware/lib32 -L/usr/X11R6/lib -L/usr/local/lib - -# SYSLIB2 = libstdc++. -# SYSLIB2 = -lstdc++ -# -lgcc_s -# SYSLIB2 = -L/usr/lib/lapack -lblas -lstdc++ - - diff --git a/Netgen/libsrc/makefile.mach.SUN b/Netgen/libsrc/makefile.mach.SUN deleted file mode 100644 index f927ae06f1..0000000000 --- a/Netgen/libsrc/makefile.mach.SUN +++ /dev/null @@ -1,16 +0,0 @@ -# -# Machine dependent make include file -# -CC=CC -CPLUSPLUS=$(CC) -AR=ar -LINK=$(CC) -MAKE=make -k -RM=rm -RANLIB=ranlib -# -CFLAGS2 = -# -CPLUSPLUSFLAGS2 = -fast -O2 -I/usr/openwin/share/include -LINKFLAGS2 = -L/usr/openwin/lib - diff --git a/Netgen/libsrc/meshing/Makefile b/Netgen/libsrc/meshing/Makefile deleted file mode 100644 index c0f17db986..0000000000 --- a/Netgen/libsrc/meshing/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -src = adfront2.cpp adfront3.cpp geomsearch.cpp global.cpp \ - meshtool.cpp \ - netrule2.cpp netrule3.cpp parser2.cpp parser3.cpp ruler2.cpp ruler3.cpp \ - meshtype.cpp meshclass.cpp improve2.cpp smoothing2.cpp improve3.cpp smoothing3.cpp \ - improve2gen.cpp meshing2.cpp meshing3.cpp \ - localh.cpp delaunay.cpp topology.cpp clusters.cpp \ - tetrarls.cpp triarls.cpp quadrls.cpp meshfunc.cpp meshfunc2d.cpp \ - refine.cpp bisect.cpp zrefine.cpp secondorder.cpp hprefinement.cpp \ - boundarylayer.cpp specials.cpp msghandler.cpp \ - pyramidrls.cpp pyramid2rls.cpp prism2rls.cpp curvedelems.cpp curvedelems2.cpp -# -lib = mesh -libpath = libsrc/meshing -# -include ../makefile.inc -# diff --git a/Netgen/libsrc/meshing/adfront2.cpp b/Netgen/libsrc/meshing/adfront2.cpp deleted file mode 100644 index 01b591f477..0000000000 --- a/Netgen/libsrc/meshing/adfront2.cpp +++ /dev/null @@ -1,526 +0,0 @@ -/* - Advancing front class for surfaces -*/ - -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ - - /* -AdFront2::FrontPoint2 :: FrontPoint2 () -{ - globalindex = 0; - nlinetopoint = 0; - frontnr = INT_MAX-10; // attention: overflow on calculating INT_MAX + 1 - mgi = NULL; -} - */ - -AdFront2::FrontPoint2 :: FrontPoint2 (const Point3d & ap, PointIndex agi, - MultiPointGeomInfo * amgi) -{ - p = ap; - globalindex = agi; - nlinetopoint = 0; - frontnr = INT_MAX-10; - - if (amgi) - { - mgi = new MultiPointGeomInfo (*amgi); - for (int i = 1; i <= mgi->GetNPGI(); i++) - if (mgi->GetPGI(i).trignum <= 0) - cout << "Add FrontPoint2, illegal geominfo = " << mgi->GetPGI(i).trignum << endl; - } - else - mgi = NULL; -} - -/* -AdFront2::FrontPoint2 :: ~FrontPoint2 () -{ -// if (mgi) delete mgi; -} -*/ - - -AdFront2::FrontLine :: FrontLine () -{ - lineclass = 1; -} - -AdFront2::FrontLine :: FrontLine (const INDEX_2 & al) -{ - l = al; - lineclass = 1; -} - - - - - - -AdFront2 :: AdFront2 (const Box3d & aboundingbox) - : boundingbox(aboundingbox), - linesearchtree(boundingbox.PMin(), boundingbox.PMax()), - cpointsearchtree(boundingbox.PMin(), boundingbox.PMax()) -{ - nfl = 0; - // allflines = new INDEX_2_HASHTABLE<int> (100000); - allflines = 0; - - minval = 0; - starti = 1; -} - -AdFront2 :: ~AdFront2 () -{ - delete allflines; -} - - -void AdFront2 :: PrintOpenSegments (ostream & ost) const -{ - if (nfl > 0) - { - int i; - ost << nfl << " open front segments left:" << endl; - for (i = 1; i <= lines.Size(); i++) - if (lines.Get(i).Valid()) - ost << GetGlobalIndex (lines.Get(i).L().I1()) << "-" - << GetGlobalIndex (lines.Get(i).L().I2()) << endl; - - } -} - - -void AdFront2 :: GetPoints (ARRAY<Point3d> & apoints) const -{ - for (int i = 0; i < points.Size(); i++) - apoints.Append (points[i].P()); -} - - - - - -INDEX AdFront2 :: AddPoint (const Point3d & p, PointIndex globind, - MultiPointGeomInfo * mgi) -{ - // inserts at empty position or resizes array - int pi; - - if (delpointl.Size() != 0) - { - pi = delpointl.Last(); - delpointl.DeleteLast (); - - points.Elem(pi) = FrontPoint2 (p, globind, mgi); - } - else - { - pi = points.Append (FrontPoint2 (p, globind, mgi)); - } - - if (mgi) - { - cpointsearchtree.Insert (p, pi); - } - - return pi; -} - - -INDEX AdFront2 :: AddLine (INDEX pi1, INDEX pi2, - const PointGeomInfo & gi1, const PointGeomInfo & gi2) -{ - int minfn; - INDEX li; - - FrontPoint2 & p1 = points.Elem(pi1); - FrontPoint2 & p2 = points.Elem(pi2); - - - - nfl++; - - p1.AddLine(); - p2.AddLine(); - - minfn = min2 (p1.FrontNr(), p2.FrontNr()); - p1.DecFrontNr (minfn+1); - p2.DecFrontNr (minfn+1); - - if (dellinel.Size() != 0) - { - li = dellinel.Last(); - dellinel.DeleteLast (); - - lines.Elem(li) = FrontLine (INDEX_2(pi1, pi2)); - } - else - { - li = lines.Append(FrontLine (INDEX_2(pi1, pi2))); - } - - - if (!gi1.trignum || !gi2.trignum) - { - cout << "ERROR: in AdFront::AddLine, illegal geominfo" << endl; - } - - lines.Elem(li).SetGeomInfo (gi1, gi2); - - Box3d lbox; - lbox.SetPoint(p1.P()); - lbox.AddPoint(p2.P()); - - linesearchtree.Insert (lbox.PMin(), lbox.PMax(), li); - - /* - (*testout) << "add front line: " << p1.P() << " - " << p2.P() - << " Dist = " << Dist (p1.P(), p2.P()) << endl; - */ - - if (allflines) - { - if (allflines->Used (INDEX_2 (GetGlobalIndex (pi1), - GetGlobalIndex (pi2)))) - { - cerr << "ERROR Adfront2::AddLine: line exists" << endl; - (*testout) << "ERROR Adfront2::AddLine: line exists" << endl; - } - - allflines->Set (INDEX_2 (GetGlobalIndex (pi1), - GetGlobalIndex (pi2)), 1); - } - - return li; -} - - -void AdFront2 :: DeleteLine (INDEX li) -{ - int i; - INDEX pi; - - nfl--; - - for (i = 1; i <= 2; i++) - { - pi = lines.Get(li).L().I(i); - points.Elem(pi).RemoveLine(); - - if (!points.Get(pi).Valid()) - { - delpointl.Append (pi); - if (points.Elem(pi).mgi) - { - cpointsearchtree.DeleteElement (pi); - delete points.Elem(pi).mgi; - points.Elem(pi).mgi = NULL; - } - } - } - - if (allflines) - { - allflines->Set (INDEX_2 (GetGlobalIndex (lines.Get(li).L().I1()), - GetGlobalIndex (lines.Get(li).L().I2())), 2); - } - - lines.Elem(li).Invalidate(); - linesearchtree.DeleteElement (li); - - - - dellinel.Append (li); -} - - -int AdFront2 :: ExistsLine (int pi1, int pi2) -{ - if (!allflines) - return 0; - if (allflines->Used (INDEX_2(pi1, pi2))) - return allflines->Get (INDEX_2 (pi1, pi2)); - else - return 0; -} - - - -void AdFront2 :: IncrementClass (INDEX li) -{ - lines.Elem(li).IncrementClass(); -} - - -void AdFront2 :: ResetClass (INDEX li) -{ - lines.Elem(li).ResetClass(); -} - - - -int AdFront2 :: SelectBaseLine (Point3d & p1, Point3d & p2, - const PointGeomInfo *& geominfo1, - const PointGeomInfo *& geominfo2, - int & qualclass) -{ - int i, hi; - - /* - int minval; - int baselineindex; - minval = INT_MAX; - for (i = 1; i <= lines.Size(); i++) - if (lines.Get(i).Valid()) - { - hi = lines.Get(i).LineClass() + - points.Get(lines.Get(i).L().I1()).FrontNr() + - points.Get(lines.Get(i).L().I2()).FrontNr(); - - if (hi < minval) - { - minval = hi; - baselineindex = i; - } - } - */ - - /* - static int minval = 0; - static int starti = 1; - */ - int baselineindex = 0; - - for (i = starti; i <= lines.Size(); i++) - { - if (lines.Get(i).Valid()) - // const ILINE * lp = &lines.Get(i).l; - // if (lp->I1() >= 0) - { - hi = lines.Get(i).LineClass() + - points.Get(lines.Get(i).L().I1()).FrontNr() + - points.Get(lines.Get(i).L().I2()).FrontNr(); - - if (hi <= minval) - { - minval = hi; - baselineindex = i; - break; - } - } - } - - if (!baselineindex) - { - // (*testotu) << "nfl = " << nfl << " tot l = " << lines.Size() << endl; - minval = INT_MAX; - for (i = 1; i <= lines.Size(); i++) - if (lines.Get(i).Valid()) - { - hi = lines.Get(i).LineClass() + - points.Get(lines.Get(i).L().I1()).FrontNr() + - points.Get(lines.Get(i).L().I2()).FrontNr(); - - if (hi < minval) - { - minval = hi; - baselineindex = i; - } - } - } - starti = baselineindex+1; - - - - p1 = points.Get(lines.Get(baselineindex).L().I1()).P(); - p2 = points.Get(lines.Get(baselineindex).L().I2()).P(); - geominfo1 = &lines.Get(baselineindex).GetGeomInfo(1); - geominfo2 = &lines.Get(baselineindex).GetGeomInfo(2); - - qualclass = lines.Get(baselineindex).LineClass(); - - return baselineindex; -} - - - - -int AdFront2 :: GetLocals (int baselineindex, - ARRAY<Point3d> & locpoints, - ARRAY<MultiPointGeomInfo> & pgeominfo, - ARRAY<INDEX_2> & loclines, // local index - ARRAY<INDEX> & pindex, - ARRAY<INDEX> & lindex, - double xh) -{ - int i, j, ii; - int pstind; - int pi; - Point3d midp, p0; - - pstind = lines.Get(baselineindex).L().I1(); - p0 = points.Get(pstind).P(); - - loclines.Append(lines.Get(baselineindex).L()); - lindex.Append(baselineindex); - - static ARRAY<int> nearlines; - - nearlines.SetSize(0); - - linesearchtree.GetIntersecting (p0 - Vec3d(xh, xh, xh), - p0 + Vec3d(xh, xh, xh), - nearlines); - - for (ii = 1; ii <= nearlines.Size(); ii++) - { - i = nearlines.Get(ii); - - if (lines.Get(i).Valid() && i != baselineindex) - { - // const Point3d & p1 = points.Get(lines.Get(i).L().I1()).P(); - // const Point3d & p2 = points.Get(lines.Get(i).L().I2()).P(); - - // midp = Center (p1, p2); - // if (Dist (midp, p0) <= xh + 0.5 * Dist (p1, p2)) - { - loclines.Append(lines.Get(i).L()); - lindex.Append(i); - } - } - } - - static ARRAY<int> invpindex; - - invpindex.SetSize (points.Size()); - for (i = 1; i <= loclines.Size(); i++) - { - invpindex.Elem(loclines.Get(i).I1()) = 0; - invpindex.Elem(loclines.Get(i).I2()) = 0; - } - - for (i = 1; i <= loclines.Size(); i++) - { - for (j = 1; j <= 2; j++) - { - pi = loclines.Get(i).I(j); - if (invpindex.Get(pi) == 0) - { - pindex.Append (pi); - invpindex.Elem(pi) = pindex.Size(); - loclines.Elem(i).I(j) = locpoints.Append (points.Get(pi).P()); - } - else - loclines.Elem(i).I(j) = invpindex.Get(pi); - } - } - - pgeominfo.SetSize (locpoints.Size()); - for (i = 1; i <= pgeominfo.Size(); i++) - pgeominfo.Elem(i).Init(); - - - for (i = 1; i <= loclines.Size(); i++) - for (j = 1; j <= 2; j++) - { - int lpi = loclines.Get(i).I(j); - - const PointGeomInfo & gi = - lines.Get(lindex.Get(i)).GetGeomInfo (j); - pgeominfo.Elem(lpi).AddPointGeomInfo (gi); - - /* - if (pgeominfo.Elem(lpi).cnt == MULTIPOINTGEOMINFO_MAX) - break; - - const PointGeomInfo & gi = - lines.Get(lindex.Get(i)).GetGeomInfo (j); - - PointGeomInfo * pgi = pgeominfo.Elem(lpi).mgi; - - int found = 0; - for (k = 0; k < pgeominfo.Elem(lpi).cnt; k++) - if (pgi[k].trignum == gi.trignum) - found = 1; - - if (!found) - { - pgi[pgeominfo.Elem(lpi).cnt] = gi; - pgeominfo.Elem(lpi).cnt++; - } - */ - } - - for (i = 1; i <= locpoints.Size(); i++) - { - int pi = pindex.Get(i); - - if (points.Get(pi).mgi) - for (j = 1; j <= points.Get(pi).mgi->GetNPGI(); j++) - pgeominfo.Elem(i).AddPointGeomInfo (points.Get(pi).mgi->GetPGI(j)); - } - - - - /* - for (i = 1; i <= points.Size(); i++) - if (points.Get(i).Valid() && - Dist (points.Get(i).P(), p0) <= xh && - invpindex.Get(i) == 0) - { - invpindex.Elem(i) = - locpoints.Append (points.Get(pi).P()); - } - */ - - if (loclines.Size() == 1) - { - cout << "loclines.Size = 1" << endl; - (*testout) << "loclines.size = 1" << endl - << " h = " << xh << endl - << " nearline.size = " << nearlines.Size() << endl - << " p0 = " << p0 << endl; - } - - return lines.Get(baselineindex).LineClass(); -} - - - -void AdFront2 :: SetStartFront () -{ - INDEX i; - int j; - - for (i = 1; i <= lines.Size(); i++) - if (lines.Get(i).Valid()) - for (j = 1; j <= 2; j++) - points.Elem(lines.Get(i).L().I(j)).DecFrontNr(0); -} - - - - -void AdFront2 :: Print (ostream & ost) const -{ - INDEX i; - - ost << points.Size() << " Points: " << endl; - for (i = 1; i <= points.Size(); i++) - if (points.Get(i).Valid()) - ost << i << " " << points.Get(i).P() << endl; - - ost << nfl << " Lines: " << endl; - for (i = 1; i <= lines.Size(); i++) - if (lines.Get(i).Valid()) - ost << lines.Get(i).L().I1() << " - " << lines.Get(i).L().I2() << endl; - - ost << flush; -} -} diff --git a/Netgen/libsrc/meshing/adfront2.hpp b/Netgen/libsrc/meshing/adfront2.hpp deleted file mode 100644 index 4e72c087fb..0000000000 --- a/Netgen/libsrc/meshing/adfront2.hpp +++ /dev/null @@ -1,337 +0,0 @@ -#ifndef FILE_ADFRONT2 -#define FILE_ADFRONT2 - -/**************************************************************************/ -/* File: adfront2.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - -/* - Advancing front class for surfaces -*/ - - -/* -#define FRONTLINE_GEOMINFO_SIZE 8 -#define FRONTPOINT_GEOMINFO_SIZE 4 -*/ - -/// -class AdFront2 -{ - - /// - class FrontPoint2 - { - /// coordinates - Point3d p; - /// global node index - PointIndex globalindex; - /// number of front lines connected to point - int nlinetopoint; - /// distance to original boundary - int frontnr; - // char geominfo[FRONTLINE_GEOMINFO_SIZE]; - public: - /// - MultiPointGeomInfo * mgi; - - /// - FrontPoint2 () - { - globalindex = -1; - nlinetopoint = 0; - frontnr = INT_MAX-10; // attention: overflow on calculating INT_MAX + 1 - mgi = NULL; - } - - /// - FrontPoint2 (const Point3d & ap, PointIndex agi, - MultiPointGeomInfo * amgi); - /// - ~FrontPoint2 () { ; } - - /// - const Point3d & P () const { return p; } - /// - PointIndex GlobalIndex () const { return globalindex; } - - /// - void AddLine () { nlinetopoint++; } - /// - void RemoveLine () - { - nlinetopoint--; - if (nlinetopoint == 0) - nlinetopoint = -1; - } - - /// - bool Valid () const - { return nlinetopoint >= 0; } - - /// - void DecFrontNr (int afrontnr) - { - if (frontnr > afrontnr) frontnr = afrontnr; - } - - /// - int FrontNr () const { return frontnr; } - }; - - - /// - class FrontLine - { - private: - /// Point Indizes - INDEX_2 l; - /// quality class - int lineclass; - /// geometry specific data - // char geominfo[FRONTLINE_GEOMINFO_SIZE]; - PointGeomInfo geominfo[2]; - public: - - FrontLine (); - /// - FrontLine (const INDEX_2 & al); - - /// - const INDEX_2 & L () const - { - return l; - } - - /// - int LineClass() const - { - return lineclass; - } - - /// - void IncrementClass () - { - lineclass++; - } - /// - void ResetClass () - { - lineclass = 1; - } - - /// - bool Valid () const - { - return l.I1() != -1; - } - /// - void Invalidate () - { - l.I1() = -1; - l.I2() = -1; - lineclass = 1000; - } - - void SetGeomInfo (const PointGeomInfo & gi1, const PointGeomInfo & gi2) - { - geominfo[0] = gi1; - geominfo[1] = gi2; - } - - const PointGeomInfo * GetGeomInfo () const - { return geominfo; } - - const PointGeomInfo & GetGeomInfo (int endp) const - { return geominfo[endp-1]; } - - friend class AdFront2; - }; - - - - /// - ARRAY<FrontPoint2> points; /// front points - ARRAY<FrontLine> lines; /// front lines - - Box3d boundingbox; - Box3dTree linesearchtree; /// search tree for lines - Point3dTree cpointsearchtree; /// search tree for cone points - - ARRAY<INDEX> delpointl; /// list of deleted front points - ARRAY<INDEX> dellinel; /// list of deleted front lines - - INDEX nfl; /// number of front lines; - INDEX_2_HASHTABLE<int> * allflines; /// all front lines ever have been - - - int minval; - int starti; - -public: - /// - // AdFront2 (); - AdFront2 (const Box3d & aboundingbox); - /// - ~AdFront2 (); - - /// - void GetPoints (ARRAY<Point3d> & apoints) const; - /// - void Print (ostream & ost) const; - - /// - bool Empty () const - { - return nfl == 0; - } - /// - int GetNFL () const { return nfl; } - /// - int SelectBaseLine (Point3d & p1, Point3d & p2, - const PointGeomInfo *& geominfo1, - const PointGeomInfo *& geominfo2, - int & qualclass); - - /// - int GetLocals (int baseline, - ARRAY<Point3d> & locpoints, - ARRAY<MultiPointGeomInfo> & pgeominfo, - ARRAY<INDEX_2> & loclines, // local index - ARRAY<INDEX> & pindex, - ARRAY<INDEX> & lindex, - double xh); - - /// - void DeleteLine (INDEX li); - /// - INDEX AddPoint (const Point3d & p, PointIndex globind, - MultiPointGeomInfo * mgi = NULL); - /// - INDEX AddLine (INDEX pi1, INDEX pi2, - const PointGeomInfo & gi1, const PointGeomInfo & gi2); - /// - int ExistsLine (int gpi1, int gpi2); - /// - void IncrementClass (INDEX li); - /// - void ResetClass (INDEX li); - - /// - const PointGeomInfo & GetLineGeomInfo (int li, int lend) const - { return lines.Get(li).GetGeomInfo (lend); } - /// - - PointIndex GetGlobalIndex (int pi) const - { - return points.Get(pi).GlobalIndex(); - } - /// - void SetStartFront (); - /// - void PrintOpenSegments (ostream & ost) const; -}; - - - - - - -/* -inline int AdFront2::FrontPoint2 :: Valid () const -{ - return nlinetopoint >= 0; -} -*/ -/* -inline const Point3d & AdFront2::FrontPoint2 :: P () const -{ - return p; -} - -inline PointIndex AdFront2::FrontPoint2 :: GlobalIndex () const -{ - return globalindex; -} - -inline void AdFront2::FrontPoint2 :: AddLine () -{ - nlinetopoint++; -} - -inline void AdFront2::FrontPoint2 :: RemoveLine () -{ - nlinetopoint--; - if (nlinetopoint == 0) - nlinetopoint = -1; -} - -inline int AdFront2::FrontPoint2 :: FrontNr () const -{ - return frontnr; -} - -inline void AdFront2::FrontPoint2 :: DecFrontNr (int afrontnr) -{ - if (frontnr > afrontnr) frontnr = afrontnr; -} -*/ - - - - - - - - -/* -inline int AdFront2::FrontLine :: Valid () const -{ - return l.I1() != 0; -} - -inline void AdFront2::FrontLine :: Invalidate () -{ - l.I1() = 0; - l.I2() = 0; - lineclass = 1000; -} - -inline const INDEX_2 & AdFront2::FrontLine :: L () const -{ - return l; -} - -inline int AdFront2::FrontLine :: LineClass () const -{ - return lineclass; -} - - -inline void AdFront2::FrontLine :: IncrementClass () -{ - lineclass++; -} - -inline void AdFront2::FrontLine :: ResetClass () -{ - lineclass = 1; -} - - -inline int AdFront2 :: Empty () const -{ - return nfl == 0; -} - -inline INDEX AdFront2 :: GetGlobalIndex (INDEX pi) const -{ - return points.Get(pi).GlobalIndex(); -} -*/ -#endif - - - diff --git a/Netgen/libsrc/meshing/adfront3.cpp b/Netgen/libsrc/meshing/adfront3.cpp deleted file mode 100644 index 1bf686e103..0000000000 --- a/Netgen/libsrc/meshing/adfront3.cpp +++ /dev/null @@ -1,883 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -/* ********************** FrontPoint ********************** */ - -namespace netgen -{ - -FrontPoint3 :: FrontPoint3 () -{ - globalindex = -1; - nfacetopoint = 0; - frontnr = 1000; - cluster = 0; -} - - -FrontPoint3 :: FrontPoint3 (const Point3d & ap, PointIndex agi) -{ - p = ap; - globalindex = agi; - nfacetopoint = 0; - frontnr = 1000; - cluster = 0; -} - - - -/* ********************** FrontFace ********************** */ - -FrontFace :: FrontFace () -{ - qualclass = 1; - oldfront = 0; - hashvalue = 0; - cluster = 0; -} - -FrontFace :: FrontFace (const Element2d & af) -{ - f = af; - oldfront = 0; - qualclass = 1; - hashvalue = 0; -} - -void FrontFace :: Invalidate () -{ - f.Delete(); - oldfront = 0; - qualclass = 1000; -} - - - - -/* ********************** AddFront ********************** */ - - -AdFront3 :: AdFront3 () -{ - nff = 0; - nff4 = 0; - vol = 0; - - hashon = 1; - hashcreated = 0; - if (hashon) - hashtable.Init(&points, &faces); - - facetree = NULL; - connectedpairs = NULL; - - rebuildcounter = -1; - lasti = 0; - minval = -1; -} - - -AdFront3 :: ~AdFront3 () -{ - delete facetree; - delete connectedpairs; -} - -void AdFront3 :: GetPoints (ARRAY<Point3d> & apoints) const -{ - for (PointIndex pi = PointIndex::BASE; - pi < points.Size()+PointIndex::BASE; pi++) - - apoints.Append (points[pi].P()); -} - - -PointIndex AdFront3 :: AddPoint (const Point3d & p, PointIndex globind) -{ - if (delpointl.Size()) - { - PointIndex pi = delpointl.Last(); - delpointl.DeleteLast (); - - points[pi] = FrontPoint3 (p, globind); - return pi; - } - else - { - points.Append (FrontPoint3 (p, globind)); - return points.Size()-1+PointIndex::BASE; - } -} - - -INDEX AdFront3 :: AddFace (const Element2d & aface) -{ - int i, minfn; - - nff++; - - for (i = 0; i < aface.GetNP(); i++) - points[aface[i]].AddFace(); - - const Point3d & p1 = points[aface[0]].P(); - const Point3d & p2 = points[aface[1]].P(); - const Point3d & p3 = points[aface[2]].P(); - - vol += 1.0/6.0 * (p1.X() + p2.X() + p3.X()) * - ( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) - - (p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) ); - - if (aface.GetNP() == 4) - { - nff4++; - const Point3d & p4 = points[aface[3]].P(); - vol += 1.0/6.0 * (p1.X() + p3.X() + p4.X()) * - ( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) - - (p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) ); - } - - - minfn = 1000; - for (i = 0; i < aface.GetNP(); i++) - { - int fpn = points[aface[i]].FrontNr(); - if (i == 0 || fpn < minfn) - minfn = fpn; - } - - - int cluster = 0; - for (i = 1; i <= aface.GetNP(); i++) - { - if (points[aface.PNum(i)].cluster) - cluster = points[aface.PNum(i)].cluster; - } - for (i = 1; i <= aface.GetNP(); i++) - points[aface.PNum(i)].cluster = cluster; - - - for (i = 1; i <= aface.GetNP(); i++) - points[aface.PNum(i)].DecFrontNr (minfn+1); - - int nfn = faces.Append(FrontFace (aface)); - faces.Elem(nfn).cluster = cluster; - - if (hashon && hashcreated) - hashtable.AddElem(aface, nfn); - - return nfn; -} - - - -void AdFront3 :: DeleteFace (INDEX fi) -{ - nff--; - - for (int i = 1; i <= faces.Get(fi).Face().GetNP(); i++) - { - PointIndex pi = faces.Get(fi).Face().PNum(i); - points[pi].RemoveFace(); - if (!points[pi].Valid()) - delpointl.Append (pi); - } - - const Element2d & face = faces.Get(fi).Face(); - const Point3d & p1 = points[face.PNum(1)].P(); - const Point3d & p2 = points[face.PNum(2)].P(); - const Point3d & p3 = points[face.PNum(3)].P(); - - vol -= 1.0/6.0 * (p1.X() + p2.X() + p3.X()) * - ( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) - - (p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) ); - - if (face.GetNP() == 4) - { - const Point3d & p4 = points[face.PNum(4)].P(); - vol -= 1.0/6.0 * (p1.X() + p3.X() + p4.X()) * - ( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) - - (p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) ); - - nff4--; - } - - faces.Elem(fi).Invalidate(); -} - - -INDEX AdFront3 :: AddConnectedPair (const INDEX_2 & apair) -{ - if (!connectedpairs) - connectedpairs = new TABLE<int, PointIndex::BASE> (GetNP()); - - connectedpairs->Add (apair.I1(), apair.I2()); - connectedpairs->Add (apair.I2(), apair.I1()); - - return 0; -} - - - -void AdFront3 :: IncrementClass (INDEX fi) -{ - faces.Elem(fi).IncrementQualClass(); -} - - -void AdFront3 :: ResetClass (INDEX fi) -{ - faces.Elem(fi).ResetQualClass(); -} - - - -void AdFront3 :: CreateTrees () -{ - int i, j; - PointIndex pi; - Point3d pmin, pmax; - - for (pi = PointIndex::BASE; - pi < GetNP()+PointIndex::BASE; pi++) - { - const Point3d & p = GetPoint(pi); - if (pi == PointIndex::BASE) - { - pmin = p; - pmax = p; - } - else - { - pmin.SetToMin (p); - pmax.SetToMax (p); - } - } - - pmax = pmax + 0.5 * (pmax - pmin); - pmin = pmin + 0.5 * (pmin - pmax); - - delete facetree; - facetree = new Box3dTree (pmin, pmax); - - for (i = 1; i <= GetNF(); i++) - { - const Element2d & el = GetFace(i); - pmin = GetPoint (el[0]); - pmax = pmin; - for (j = 1; j < 3; j++) - { - const Point3d & p = GetPoint (el[j]); - pmin.SetToMin (p); - pmax.SetToMax (p); - } - pmax = pmax + 0.01 * (pmax - pmin); - pmin = pmin + 0.01 * (pmin - pmax); - // (*testout) << "insert " << i << ": " << pmin << " - " << pmax << "\n"; - facetree -> Insert (pmin, pmax, i); - } -} - - -void AdFront3 :: GetIntersectingFaces (const Point3d & pmin, const Point3d & pmax, - ARRAY<int> & ifaces) const -{ - facetree -> GetIntersecting (pmin, pmax, ifaces); -} - -void AdFront3 :: GetFaceBoundingBox (int i, Box3d & box) const -{ - const FrontFace & face = faces.Get(i); - box.SetPoint (points[face.f[0]].p); - box.AddPoint (points[face.f[1]].p); - box.AddPoint (points[face.f[2]].p); -} - -void AdFront3 :: RebuildInternalTables () -{ - int i, j, hi; - - hi = 0; - for (i = 1; i <= faces.Size(); i++) - if (faces.Get(i).Valid()) - { - hi++; - if (hi < i) - faces.Elem(hi) = faces.Get(i); - } - - faces.SetSize (nff); - - int np = points.Size(); - - for (i = PointIndex::BASE; - i < np+PointIndex::BASE; i++) - points[i].cluster = i; - - int change; - do - { - change = 0; - for (i = 1; i <= faces.Size(); i++) - { - const Element2d & el = faces.Get(i).Face(); - - int mini = points[el.PNum(1)].cluster; - int maxi = mini; - - for (j = 2; j <= 3; j++) - { - int ci = points[el.PNum(j)].cluster; - if (ci < mini) mini = ci; - if (ci > maxi) maxi = ci; - } - - if (mini < maxi) - { - change = 1; - for (j = 1; j <= 3; j++) - points[el.PNum(j)].cluster = mini; - } - } - } - while (change); - - BitArrayChar<PointIndex::BASE> usecl(np); - usecl.Clear(); - for (i = 1; i <= faces.Size(); i++) - { - usecl.Set (points[faces.Get(i).Face().PNum(1)].cluster); - faces.Elem(i).cluster = - points[faces.Get(i).Face().PNum(1)].cluster; - } - int cntcl = 0; - for (i = PointIndex::BASE; - i < np+PointIndex::BASE; i++) - if (usecl.Test(i)) - cntcl++; - - ARRAY<double, PointIndex::BASE> clvol (np); - clvol = 0.0; - - for (i = 1; i <= faces.Size(); i++) - { - const Element2d & face = faces.Get(i).Face(); - - const Point3d & p1 = points[face.PNum(1)].P(); - const Point3d & p2 = points[face.PNum(2)].P(); - const Point3d & p3 = points[face.PNum(3)].P(); - - double vi = 1.0/6.0 * (p1.X() + p2.X() + p3.X()) * - ( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) - - (p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) ); - - if (face.GetNP() == 4) - { - const Point3d & p4 = points[face.PNum(4)].P(); - vi += 1.0/6.0 * (p1.X() + p3.X() + p4.X()) * - ( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) - - (p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) ); - } - - clvol[faces.Get(i).cluster] += vi; - } - - - int negvol = 0; - for (i = PointIndex::BASE; - i < clvol.Size()+PointIndex::BASE; i++) - { - if (clvol[i] < 0) - negvol = 1; - } - - if (negvol) - { - for (i = 1; i <= faces.Size(); i++) - faces.Elem(i).cluster = 1; - for (i = PointIndex::BASE; - i < points.Size()+PointIndex::BASE; i++) - points[i].cluster = 1; - } - - if (hashon) - hashtable.Create(); -} - - - -int AdFront3 :: SelectBaseElement () -{ - int i, hi, fstind; - - /* - static int minval = -1; - static int lasti = 0; - static int counter = 0; - */ - if (rebuildcounter <= 0) - { - RebuildInternalTables(); - rebuildcounter = nff / 10 + 1; - - lasti = 0; - } - rebuildcounter--; - - /* - if (faces.Size() > 2 * nff) - { - // compress facelist - - RebuildInternalTables (); - lasti = 0; - } - */ - - fstind = 0; - - for (i = lasti+1; i <= faces.Size() && !fstind; i++) - if (faces.Elem(i).Valid()) - { - hi = faces.Get(i).QualClass() + - points[faces.Get(i).Face().PNum(1)].FrontNr() + - points[faces.Get(i).Face().PNum(2)].FrontNr() + - points[faces.Get(i).Face().PNum(3)].FrontNr(); - - if (hi <= minval) - { - minval = hi; - fstind = i; - lasti = fstind; - } - } - - if (!fstind) - { - minval = INT_MAX; - for (i = 1; i <= faces.Size(); i++) - if (faces.Elem(i).Valid()) - { - hi = faces.Get(i).QualClass() + - points[faces.Get(i).Face().PNum(1)].FrontNr() + - points[faces.Get(i).Face().PNum(2)].FrontNr() + - points[faces.Get(i).Face().PNum(3)].FrontNr(); - - if (hi <= minval) - { - minval = hi; - fstind = i; - lasti = 0; - } - } - } - - - return fstind; -} - - - -int AdFront3 :: GetLocals (int fstind, - ARRAY<Point3d> & locpoints, - ARRAY<Element2d> & locfaces, // local index - ARRAY<PointIndex> & pindex, - ARRAY<INDEX> & findex, - INDEX_2_HASHTABLE<int> & getconnectedpairs, - float xh, - float relh, - INDEX& facesplit) -{ - if (hashon && faces.Size() < 500) { hashon=0; } - if (hashon && !hashcreated) - { - hashtable.Create(); - hashcreated=1; - } - - INDEX i, j; - PointIndex pstind; - INDEX pi; - Point3d midp, p0; - - static ARRAY<int, PointIndex::BASE> invpindex; - - static ARRAY<Element2d> locfaces2; //all local faces in radius xh - static ARRAY<int> locfaces3; // all faces in outer radius relh - static ARRAY<INDEX> findex2; - - locfaces2.SetSize(0); - locfaces3.SetSize(0); - findex2.SetSize(0); - - int cluster = faces.Get(fstind).cluster; - - pstind = faces.Get(fstind).Face().PNum(1); - p0 = points[pstind].P(); - - locfaces2.Append(faces.Get(fstind).Face()); - findex2.Append(fstind); - - - Box3d b1 (p0 - Vec3d(xh, xh, xh), p0 + Vec3d (xh, xh, xh)); - - if (hashon) - { - hashtable.GetLocals(locfaces2, findex2, fstind, p0, xh); - } - else - { - for (i = 1; i <= faces.Size(); i++) - { - const Element2d & face = faces.Get(i).Face(); - if (faces.Get(i).cluster == cluster && faces.Get(i).Valid() && i != fstind) - { - const Point3d & p1 = points[face.PNum(1)].P(); - const Point3d & p2 = points[face.PNum(2)].P(); - const Point3d & p3 = points[face.PNum(3)].P(); - - Box3d b2; - b2.SetPoint (p1); - b2.AddPoint (p2); - b2.AddPoint (p3); - - /* - midp = Center (p1, p2, p3); - - if (Dist2 (midp, p0) <= xh*xh) - { - locfaces2.Append(faces.Get(i).Face()); - findex2.Append(i); - } - */ - if (b1.Intersect (b2)) - { - locfaces2.Append(faces.Get(i).Face()); - findex2.Append(i); - } - } - } - } - - //local faces for inner radius: - for (i = 1; i <= locfaces2.Size(); i++) - { - const Element2d & face = locfaces2.Get(i); - const Point3d & p1 = points[face.PNum(1)].P(); - const Point3d & p2 = points[face.PNum(2)].P(); - const Point3d & p3 = points[face.PNum(3)].P(); - - midp = Center (p1, p2, p3); - - if (Dist2 (midp, p0) <= relh * relh || i == 1) - { - locfaces.Append(locfaces2.Get(i)); - findex.Append(findex2.Get(i)); - } - else - locfaces3.Append (i); - } - - facesplit=locfaces.Size(); - - - //local faces for outer radius: - for (i = 1; i <= locfaces3.Size(); i++) - { - locfaces.Append (locfaces2.Get(locfaces3.Get(i))); - findex.Append (findex2.Get(locfaces3.Get(i))); - } - - - invpindex.SetSize (points.Size()); - for (i = 1; i <= locfaces.Size(); i++) - for (j = 1; j <= locfaces.Get(i).GetNP(); j++) - { - pi = locfaces.Get(i).PNum(j); - invpindex[pi] = -1; - } - - for (i = 1; i <= locfaces.Size(); i++) - { - for (j = 1; j <= locfaces.Get(i).GetNP(); j++) - { - pi = locfaces.Get(i).PNum(j); - if (invpindex[pi] == -1) - { - pindex.Append (pi); - invpindex[pi] = pindex.Size(); // -1+PointIndex::BASE; - locfaces.Elem(i).PNum(j) = locpoints.Append (points[pi].P()); - } - else - locfaces.Elem(i).PNum(j) = invpindex[pi]; - - } - } - - - - if (connectedpairs) - { - for (i = 1; i <= locpoints.Size(); i++) - { - int pi = pindex.Get(i); - if (pi >= 1 && pi <= connectedpairs->Size ()) - { - for (j = 1; j <= connectedpairs->EntrySize(pi); j++) - { - int oi = connectedpairs->Get(pi, j); - int other = invpindex.Get(oi); - if (other >= 1 && other <= pindex.Size() && - pindex.Get(other) == oi) - { - INDEX_2 coned(i, other); - coned.Sort(); - // (*testout) << "connected: " << locpoints.Get(i) << "-" << locpoints.Get(other) << endl; - getconnectedpairs.Set (coned, 1); - } - } - } - } - } - - - - - /* - for (i = 1; i <= points.Size(); i++) - if (points.Elem(i).Valid() && Dist (points.Elem(i).P(), p0) <= xh) - { - if (!invpindex.Get(i)) - { - locpoints.Append (points.Get(i).P()); - pindex.Append (i); - invpindex.Elem(i) = pindex.Size(); - } - } - */ - return faces.Get(fstind).QualClass(); -} - - -// returns all points connected with fi -void AdFront3 :: GetGroup (int fi, - ARRAY<MeshPoint> & grouppoints, - ARRAY<Element2d> & groupelements, - ARRAY<PointIndex> & pindex, - ARRAY<INDEX> & findex - ) const -{ - static ARRAY<char> pingroup; - INDEX i; - int j, changed, fused; - - pingroup.SetSize(points.Size()); - - for (i = 1; i <= pingroup.Size(); i++) - pingroup.Elem(i) = 0; - for (j = 1; j <= 3; j++) - pingroup.Elem (faces.Get(fi).Face().PNum(j)) = 1; - - do - { - changed = 0; - - for (i = 1; i <= faces.Size(); i++) - if (faces.Get(i).Valid()) - { - const Element2d & face = faces.Get(i).Face(); - - - fused = 0; - for (j = 1; j <= 3; j++) - if (pingroup.Elem(face.PNum(j))) - fused++; - - if (fused >= 2) - for (j = 1; j <= 3; j++) - if (!pingroup.Elem(face.PNum(j))) - { - pingroup.Elem(face.PNum(j)) = 1; - changed = 1; - } - } - - } - while (changed); - - - static ARRAY<int> invpindex; - invpindex.SetSize (points.Size()); - - - for (i = 1; i <= points.Size(); i++) - if (points.Get(i).Valid()) - { - grouppoints.Append (points.Get(i).P()); - pindex.Append (i); - invpindex.Elem(i) = pindex.Size(); - } - - for (i = 1; i <= faces.Size(); i++) - if (faces.Get(i).Valid()) - { - fused = 0; - for (j = 1; j <= 3; j++) - if (pingroup.Get(faces.Get(i).Face().PNum(j))) - fused++; - - if (fused >= 2) - { - groupelements.Append (faces.Get(i).Face()); - findex.Append (i); - } - } - - for (i = 1; i <= groupelements.Size(); i++) - for (j = 1; j <= 3; j++) - { - groupelements.Elem(i).PNum(j) = - invpindex.Get(groupelements.Elem(i).PNum(j)); - } - - /* - for (i = 1; i <= groupelements.Size(); i++) - for (j = 1; j <= 3; j++) - for (k = 1; k <= grouppoints.Size(); k++) - if (pindex.Get(k) == groupelements.Get(i).PNum(j)) - { - groupelements.Elem(i).PNum(j) = k; - break; - } - */ -} - - -void AdFront3 :: SetStartFront (int /* baseelnp */) -{ - INDEX i; - int j; - - for (i = 1; i <= faces.Size(); i++) - if (faces.Get(i).Valid()) - { - const Element2d & face = faces.Get(i).Face(); - for (j = 1; j <= 3; j++) - points[face.PNum(j)].DecFrontNr(0); - } - - /* - if (baseelnp) - { - for (i = 1; i <= faces.Size(); i++) - if (faces.Get(i).Valid() && faces.Get(i).Face().GetNP() != baseelnp) - faces.Elem(i).qualclass = 1000; - } - */ -} - - -int AdFront3 :: Inside (const Point3d & p) const -{ - int i, cnt; - Vec3d n, v1, v2; - DenseMatrix a(3), ainv(3); - Vector b(3), u(3); - - // random numbers: - n.X() = 0.123871; - n.Y() = 0.15432; - n.Z() = -0.43989; - - cnt = 0; - for (i = 1; i <= faces.Size(); i++) - if (faces.Get(i).Valid()) - { - const Point3d & p1 = points[faces.Get(i).Face().PNum(1)].P(); - const Point3d & p2 = points[faces.Get(i).Face().PNum(2)].P(); - const Point3d & p3 = points[faces.Get(i).Face().PNum(3)].P(); - - v1 = p2 - p1; - v2 = p3 - p1; - - a.Elem(1, 1) = v1.X(); - a.Elem(2, 1) = v1.Y(); - a.Elem(3, 1) = v1.Z(); - a.Elem(1, 2) = v2.X(); - a.Elem(2, 2) = v2.Y(); - a.Elem(3, 2) = v2.Z(); - a.Elem(1, 3) = -n.X(); - a.Elem(2, 3) = -n.Y(); - a.Elem(3, 3) = -n.Z(); - - b.Elem(1) = p.X() - p1.X(); - b.Elem(2) = p.Y() - p1.Y(); - b.Elem(3) = p.Z() - p1.Z(); - - CalcInverse (a, ainv); - ainv.Mult (b, u); - - if (u.Elem(1) >= 0 && u.Elem(2) >= 0 && u.Elem(1)+u.Elem(2) <= 1 && - u.Elem(3) > 0) - { - cnt++; - } - } - - return (cnt % 2); -} - - - - - -int AdFront3 :: SameSide (const Point3d & lp1, const Point3d & lp2, - const ARRAY<int> * testfaces) const -{ - int i, ii, cnt; - - const Point3d *line[2]; - line[0] = &lp1; - line[1] = &lp2; - - - cnt = 0; - - Point3d pmin(lp1); - Point3d pmax(lp1); - pmin.SetToMin (lp2); - pmax.SetToMax (lp2); - - static ARRAY<int> aprif; - aprif.SetSize(0); - - if (!testfaces) - facetree->GetIntersecting (pmin, pmax, aprif); - else - { - for (i = 1; i <= testfaces->Size(); i++) - aprif.Append (testfaces->Get(i)); - } - - // (*testout) << "test ss, p1,p2 = " << lp1 << lp2 << ", inters = " << aprif.Size() << endl; - // for (i = 1; i <= faces.Size(); i++) - for (ii = 1; ii <= aprif.Size(); ii++) - { - i = aprif.Get(ii); - - if (faces.Get(i).Valid()) - { - const Point3d *tri[3]; - tri[0] = &points[faces.Get(i).Face().PNum(1)].P(); - tri[1] = &points[faces.Get(i).Face().PNum(2)].P(); - tri[2] = &points[faces.Get(i).Face().PNum(3)].P(); - - if (IntersectTriangleLine (&tri[0], &line[0])) - cnt++; - - } - } - - return ((cnt+1) % 2); -} -} diff --git a/Netgen/libsrc/meshing/adfront3.hpp b/Netgen/libsrc/meshing/adfront3.hpp deleted file mode 100644 index 2c43f9334b..0000000000 --- a/Netgen/libsrc/meshing/adfront3.hpp +++ /dev/null @@ -1,276 +0,0 @@ -#ifndef FILE_ADFRONT3 -#define FILE_ADFRONT3 - -/**************************************************************************/ -/* File: adfront3.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - -/* - Advancing front class for volume meshing -*/ - - - -/// Point in advancing front -class FrontPoint3 -{ - /// coordinates - Point3d p; - /// global node index - PointIndex globalindex; - /// number of faces connected to point - int nfacetopoint; - /// distance to original boundary - int frontnr; - /// - int cluster; -public: - /// - FrontPoint3 (); - /// - FrontPoint3 (const Point3d & ap, PointIndex agi); - - /// - const Point3d & P () const - { return p; } - /// - PointIndex GlobalIndex () const - { return globalindex; } - - /// - void AddFace () - { nfacetopoint++; } - - /// - void RemoveFace() - { - nfacetopoint--; - if (nfacetopoint == 0) nfacetopoint = -1; - } - - /// - int Valid () const - { return nfacetopoint >= 0; } - - /// - void DecFrontNr (int afrontnr) - { - if (frontnr > afrontnr) frontnr = afrontnr; - } - - /// - int FrontNr () const - { return frontnr; } - - /// - friend class AdFront3; -}; - -/// Face in advancing front -class FrontFace -{ - /// - Element2d f; - /// - int qualclass; - /// - char oldfront; - /// - int hashvalue; - /// - int cluster; - -public: - /// - FrontFace (); - /// - FrontFace (const Element2d & af); - /// - const Element2d & Face () const - { return f; } - - /// - int QualClass () const - { return qualclass; } - - /// - void IncrementQualClass () - { qualclass++; } - - /// - void ResetQualClass () - { - if (qualclass > 1) - { - qualclass = 1; - oldfront = 0; - } - } - - /// - bool Valid () const - { return !f.IsDeleted(); } - - /// - void Invalidate (); - - /// - int HashValue() const - { return hashvalue; } - - /// - void SetHashValue(int hv) - { hashvalue = hv; } - - /// - friend class AdFront3; - - int Cluster () const { return cluster; } -}; - - - - -/// Advancing front, 3D. -class AdFront3 -{ - /// - ARRAY<FrontPoint3, PointIndex::BASE> points; - /// - ARRAY<FrontFace> faces; - /// - ARRAY<PointIndex> delpointl; - - /// which points are connected to pi ? - TABLE<int, PointIndex::BASE> * connectedpairs; - - /// number of total front faces; - int nff; - /// number of quads in front - int nff4; - - /// - double vol; - - /// - GeomSearch3d hashtable; - - /// - int hashon; - - /// - int hashcreated; - - /// counter for rebuilding internal tables - int rebuildcounter; - /// last base element - int lasti; - /// minimal selection-value of baseelements - int minval; - - /// - class Box3dTree * facetree; -public: - - /// - AdFront3 (); - /// - ~AdFront3 (); - /// - void GetPoints (ARRAY<Point3d> & apoints) const; - /// - int GetNP() const - { return points.Size(); } - /// - const Point3d & GetPoint (PointIndex pi) const - { return points[pi].P(); } - /// - int GetNF() const - { return nff; } - /// - const Element2d & GetFace (int i) const - { return faces.Get(i).Face(); } - /// - void Print () const; - /// - bool Empty () const - { return nff == 0; } - /// - bool Empty (int elnp) const - { - if (elnp == 4) - return (nff4 == 0); - return (nff - nff4 == 0); - } - /// - int SelectBaseElement (); - - /// - void CreateTrees (); - - /// - void GetIntersectingFaces (const Point3d & pmin, const Point3d & pmax, - ARRAY<int> & ifaces) const; - - /// - void GetFaceBoundingBox (int i, Box3d & box) const; - - /// - int GetLocals (int baseelement, - ARRAY<Point3d> & locpoints, - ARRAY<Element2d> & locfaces, // local index - ARRAY<PointIndex> & pindex, - ARRAY<INDEX> & findex, - INDEX_2_HASHTABLE<int> & connectedpairs, - float xh, - float relh, - INDEX& facesplit); - - /// - void GetGroup (int fi, - ARRAY<MeshPoint> & grouppoints, - ARRAY<Element2d> & groupelements, - ARRAY<PointIndex> & pindex, - ARRAY<INDEX> & findex - ) const; - - /// - void DeleteFace (INDEX fi); - /// - PointIndex AddPoint (const Point3d & p, PointIndex globind); - /// - INDEX AddFace (const Element2d & e); - /// - INDEX AddConnectedPair (const INDEX_2 & pair); - /// - void IncrementClass (INDEX fi); - /// - void ResetClass (INDEX fi); - /// - void SetStartFront (int baseelnp = 0); - - /// is Point p inside Surface ? - int Inside (const Point3d & p) const; - /// both points on same side ? - int SameSide (const Point3d & lp1, const Point3d & lp2, - const ARRAY<int> * testfaces = NULL) const; - - - /// - PointIndex GetGlobalIndex (PointIndex pi) const - { return points[pi].GlobalIndex(); } - /// - double Volume () const - { return vol; } - - -private: - void RebuildInternalTables(); -}; - - - - -#endif diff --git a/Netgen/libsrc/meshing/bisect.cpp b/Netgen/libsrc/meshing/bisect.cpp deleted file mode 100644 index c95a2f1421..0000000000 --- a/Netgen/libsrc/meshing/bisect.cpp +++ /dev/null @@ -1,2371 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ -//#include "../interface/writeuser.hpp" - - class MarkedTet; - class MarkedPrism; - class MarkedTri; - class MarkedQuad; - - typedef MoveableArray<MarkedTet> T_MTETS; - typedef MoveableArray<MarkedPrism> T_MPRISMS; - typedef MoveableArray<MarkedTri> T_MTRIS; - typedef MoveableArray<MarkedQuad> T_MQUADS; - -class MarkedTet -{ -public: - /// pnums of tet - PointIndex pnums[4]; - /// material number - int matindex; - /// element marked for refinement - /// marked = 1: marked by element marker, marked = 2 due to closure - unsigned int marked:2; - /// flag of Arnold-Mukherjee algorithm - unsigned int flagged:1; - /// tetedge (local coordinates 0..3) - unsigned int tetedge1:3; - unsigned int tetedge2:3; - /// marked edge of faces - /// face_j : face without node j, - /// mark_k : edge without node k - unsigned char faceedges[4]; - - bool incorder; - unsigned int order:6; - - friend ostream & operator<< (ostream & ost, const MarkedTet & mt); -}; - -class MarkedPrism -{ -public: - /// 6 point numbers - PointIndex pnums[6]; - /// material number - int matindex; - /// marked for refinement - int marked; - /// edge without node k (0,1,2) - int markededge; - - bool incorder; - unsigned int order:6; -}; - -class MarkedTri -{ -public: - /// three point numbers - PointIndex pnums[3]; - /// three geominfos - PointGeomInfo pgeominfo[3]; - /// marked for refinement - int marked; - /// edge without node k - int markededge; - /// surface id - int surfid; - - bool incorder; - unsigned int order:6; -}; - -class MarkedQuad -{ -public: - /// point numbers - PointIndex pnums[4]; - /// - PointGeomInfo pgeominfo[4]; - /// marked for refinement - int marked; - /// surface id - int surfid; - - bool incorder; - unsigned int order:6; -}; - - - - - -ostream & operator<< (ostream & ost, const MarkedTet & mt) -{ - int k; - ost << "MT: " << mt.pnums[0] << " - " << mt.pnums[1] << " - " - << mt.pnums[2] << " - " << mt.pnums[3] << endl - << "marked edge: " << mt.tetedge1 << " - " << mt.tetedge2 - << ", order = " << mt.order << endl; - for (k = 0; k < 4; k++) - ost << mt.faceedges[k] << " "; - ost << endl; - return ost; -} - - - - -void BTSortEdges (const Mesh & mesh, - INDEX_2_CLOSED_HASHTABLE<int> & edgenumber) -{ - cout << "sorting ... " << flush; - - // if (mesh.PureTetMesh()) - if (1) - { - // new, fast version - - ARRAY<INDEX_2> edges; - ARRAY<int> eclasses; - - int i, j, k; - int cntedges = 0; - int goon; - int ned; - - // enumerate edges: - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - static int tetedges[6][2] = - { { 1, 2 }, - { 1, 3 }, - { 1, 4 }, - { 2, 3 }, - { 2, 4 }, - { 3, 4 } } ; - static int prismedges[9][2] = - { { 1, 2 }, - { 1, 3 }, - { 2, 3 }, - { 4, 5 }, - { 4, 6 }, - { 5, 6 }, - { 1, 4 }, - { 2, 5 }, - { 3, 6 } }; - int pyramidedges[6][2] = - { { 1, 2 }, - { 3, 4 }, - { 1, 5 }, - { 2, 5 }, - { 3, 5 }, - { 4, 5 } }; - - int (*tip)[2]; - - switch (el.GetType()) - { - case TET: - case TET10: - { - tip = tetedges; - ned = 6; - break; - } - case PRISM: - case PRISM12: - { - tip = prismedges; - ned = 6; - break; - } - case PYRAMID: - { - tip = pyramidedges; - ned = 6; - break; - } - } - - for (j = 0; j < ned; j++) - { - INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1])); - i2.Sort(); - if (!edgenumber.Used(i2)) - { - cntedges++; - edges.Append (i2); - edgenumber.Set(i2, cntedges); - } - } - } - - // additional surface edges: - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement (i); - static int trigedges[3][2] = - { { 1, 2 }, - { 2, 3 }, - { 3, 1 } }; - - static int quadedges[4][2] = - { { 1, 2 }, - { 2, 3 }, - { 3, 4 }, - { 4, 1 } }; - - - int (*tip)[2]; - - switch (el.GetType()) - { - case TRIG: - case TRIG6: - { - tip = trigedges; - ned = 3; - break; - } - case QUAD: - case QUAD6: - { - tip = quadedges; - ned = 4; - break; - } - default: - { - cerr << "Error: Sort for Bisect, SE has " << el.GetNP() << " points" << endl; - ned = 0; - } - } - - for (j = 0; j < ned; j++) - { - INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1])); - i2.Sort(); - if (!edgenumber.Used(i2)) - { - cntedges++; - edges.Append (i2); - edgenumber.Set(i2, cntedges); - } - } - } - - - - - - eclasses.SetSize (cntedges); - for (i = 1; i <= cntedges; i++) - eclasses.Elem(i) = i; - - - // identify edges in element stack - do - { - goon = 0; - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - - if (el.GetType() != PRISM && - el.GetType() != PRISM12 && - el.GetType() != PYRAMID) - continue; - - int prismpairs[3][4] = - { { 1, 2, 4, 5 }, - { 2, 3, 5, 6 }, - { 1, 3, 4, 6 } }; - - int pyramidpairs[3][4] = - { { 1, 2, 4, 3 }, - { 1, 5, 4, 5 }, - { 2, 5, 3, 5 } }; - - int (*pairs)[4]; - switch (el.GetType()) - { - case PRISM: - case PRISM12: - { - pairs = prismpairs; - break; - } - case PYRAMID: - { - pairs = pyramidpairs; - break; - } - } - - for (j = 0; j < 3; j++) - { - INDEX_2 e1 (el.PNum(pairs[j][0]), - el.PNum(pairs[j][1])); - INDEX_2 e2 (el.PNum(pairs[j][2]), - el.PNum(pairs[j][3])); - e1.Sort(); - e2.Sort(); - - int eclass1 = edgenumber.Get (e1); - int eclass2 = edgenumber.Get (e2); - - // (*testout) << "identify edges " << eclass1 << "-" << eclass2 << endl; - - if (eclasses.Get(eclass1) > - eclasses.Get(eclass2)) - { - eclasses.Elem(eclass1) = - eclasses.Get(eclass2); - goon = 1; - } - if (eclasses.Get(eclass2) > - eclasses.Get(eclass1)) - { - eclasses.Elem(eclass2) = - eclasses.Get(eclass1); - goon = 1; - } - } - } - } - while (goon); - - /* - for (i = 1; i <= cntedges; i++) - { - (*testout) << "edge " << i << ": " - << edges.Get(i).I1() << "-" << edges.Get(i).I2() - << ", class = " << eclasses.Get(i) << endl; - } - */ - // compute classlength: - ARRAY<double> edgelength(cntedges); - for (i = 1; i <= cntedges; i++) - edgelength.Elem(i) = 1e20; - - for (i = 1; i <= cntedges; i++) - { - INDEX_2 edge = edges.Get(i); - double elen = Dist (mesh.Point(edge.I1()), - mesh.Point(edge.I2())); - edgelength.Elem (i) = elen; - } - - /* - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - - if (el.GetType() == TET) - { - for (j = 1; j <= 3; j++) - for (k = j+1; k <= 4; k++) - { - INDEX_2 i2(el.PNum(j), el.PNum(k)); - i2.Sort(); - - int enr = edgenumber.Get(i2); - double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); - if (elen < edgelength.Get(enr)) - edgelength.Set (enr, elen); - } - } - else if (el.GetType() == PRISM) - { - for (j = 1; j <= 3; j++) - { - k = (j % 3) + 1; - - INDEX_2 i2(el.PNum(j), el.PNum(k)); - i2.Sort(); - - int enr = edgenumber.Get(i2); - double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); - if (elen < edgelength.Get(enr)) - edgelength.Set (enr, elen); - - i2 = INDEX_2(el.PNum(j+3), el.PNum(k+3)); - i2.Sort(); - - enr = edgenumber.Get(i2); - elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); - if (elen < edgelength.Get(enr)) - edgelength.Set (enr, elen); - - if (!edgenumber.Used(i2)) - { - cntedges++; - edgenumber.Set(i2, cntedges); - } - i2 = INDEX_2(el.PNum(j), el.PNum(j+3)); - i2.Sort(); - - enr = edgenumber.Get(i2); - elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); - if (elen < edgelength.Get(enr)) - edgelength.Set (enr, elen); - } - } - } - */ - - - for (i = 1; i <= cntedges; i++) - { - if (eclasses.Get(i) != i) - { - if (edgelength.Get(i) < edgelength.Get(eclasses.Get(i))) - edgelength.Elem(eclasses.Get(i)) = edgelength.Get(i); - edgelength.Elem(i) = 1e20; - } - } - - - TABLE<int> eclasstab(cntedges); - for (i = 1; i <= cntedges; i++) - eclasstab.Add1 (eclasses.Get(i), i); - - - // sort edges: - ARRAY<int> sorted(cntedges); - - QickSort (edgelength, sorted); - - int cnt = 0; - for (i = 1; i <= cntedges; i++) - { - int ii = sorted.Get(i); - for (j = 1; j <= eclasstab.EntrySize(ii); j++) - { - cnt++; - edgenumber.Set (edges.Get(eclasstab.Get(ii, j)), cnt); - } - } - } - - else - - { - // old version - - int i, j, k; - int cnt = 0; - int found; - double len2, maxlen2; - INDEX_2 ep; - - // sort edges by length, parallel edges (on prisms) - // are added in blocks - - do - { - found = 0; - maxlen2 = 1e30; - - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - int ned; - int tetedges[6][2] = - { { 1, 2 }, - { 1, 3 }, - { 1, 4 }, - { 2, 3 }, - { 2, 4 }, - { 3, 4 } }; - int prismedges[6][2] = - { { 1, 2 }, - { 1, 3 }, - { 2, 4 }, - { 4, 5 }, - { 4, 6 }, - { 5, 6 } }; - int pyramidedges[6][2] = - { { 1, 2 }, - { 3, 4 }, - { 1, 5 }, - { 2, 5 }, - { 3, 5 }, - { 4, 5 } }; - - int (*tip)[2]; - - switch (el.GetType()) - { - case TET: - { - tip = tetedges; - ned = 6; - break; - } - case PRISM: - { - tip = prismedges; - ned = 6; - break; - } - case PYRAMID: - { - tip = pyramidedges; - ned = 6; - break; - } - } - - for (j = 0; j < ned; j++) - { - INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1])); - i2.Sort(); - if (!edgenumber.Used(i2)) - { - len2 = Dist (mesh.Point (i2.I1()), - mesh.Point (i2.I2())); - if (len2 < maxlen2) - { - maxlen2 = len2; - ep = i2; - found = 1; - } - } - } - } - if (found) - { - cnt++; - edgenumber.Set (ep, cnt); - - - // find connected edges: - int goon = 0; - do - { - goon = 0; - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement (i); - if (el.GetNP() != 6) continue; - - int prismpairs[3][4] = - { { 1, 2, 4, 5 }, - { 2, 3, 5, 6 }, - { 1, 3, 4, 6 } }; - - int pyramidpairs[3][4] = - { { 1, 2, 4, 3 }, - { 1, 5, 4, 5 }, - { 2, 5, 3, 5 } }; - - int (*pairs)[4]; - switch (el.GetType()) - { - case PRISM: - { - pairs = prismpairs; - break; - } - case PYRAMID: - { - pairs = pyramidpairs; - break; - } - } - - for (j = 0; j < 3; j++) - { - INDEX_2 e1 (el.PNum(pairs[j][0]), - el.PNum(pairs[j][1])); - INDEX_2 e2 (el.PNum(pairs[j][2]), - el.PNum(pairs[j][3])); - e1.Sort(); - e2.Sort(); - - int used1 = edgenumber.Used (e1); - int used2 = edgenumber.Used (e2); - - if (used1 && !used2) - { - cnt++; - edgenumber.Set (e2, cnt); - goon = 1; - } - if (used2 && !used1) - { - cnt++; - edgenumber.Set (e1, cnt); - goon = 1; - } - } - } - } - while (goon); - } - } - while (found); - } -} - - - - -void BTDefineMarkedTet (const Element & el, - INDEX_2_CLOSED_HASHTABLE<int> & edgenumber, - MarkedTet & mt) -{ - int i, j, k; - for (i = 0; i < 4; i++) - mt.pnums[i] = el[i]; - - mt.marked = 0; - mt.flagged = 0; - - mt.incorder = 0; - mt.order = 1; - - int val = 0; - // find marked edge of tet: - for (i = 0; i < 3; i++) - for (j = i+1; j < 4; j++) - { - INDEX_2 i2(mt.pnums[i], mt.pnums[j]); - i2.Sort(); - int hval = edgenumber.Get(i2); - if (hval > val) - { - val = hval; - mt.tetedge1 = i; - mt.tetedge2 = j; - } - } - - - // find marked edges of faces: - for (k = 0; k < 4; k++) - { - val = 0; - for (i = 0; i < 3; i++) - for (j = i+1; j < 4; j++) - if (i != k && j != k) - { - INDEX_2 i2(mt.pnums[i], mt.pnums[j]); - i2.Sort(); - int hval = edgenumber.Get(i2); - if (hval > val) - { - val = hval; - mt.faceedges[k] = 6 - k - i - j; - } - } - } -} - - - - -void BTDefineMarkedPrism (const Element & el, - INDEX_2_CLOSED_HASHTABLE<int> & edgenumber, - MarkedPrism & mp) -{ - int i, j, k; - - if (el.GetType() == PRISM || - el.GetType() == PRISM12) - { - for (i = 0; i < 6; i++) - mp.pnums[i] = el[i]; - } - else if (el.GetType() == PYRAMID) - { - static int map[6] = - { 1, 2, 5, 4, 3, 5 }; - for (i = 0; i < 6; i++) - mp.pnums[i] = el.PNum(map[i]); - } - else if (el.GetType() == TET || - el.GetType() == TET10) - { - static int map[6] = - { 1, 4, 3, 2, 4, 3 }; - for (i = 0; i < 6; i++) - mp.pnums[i] = el.PNum(map[i]); - - } - else - { - PrintSysError ("Define marked prism called for non-prism and non-pyramid"); - } - - - - mp.marked = 0; - - mp.incorder = 0; - mp.order = 1; - - int val = 0; - for (i = 0; i < 2; i++) - for (j = i+1; j < 3; j++) - { - INDEX_2 i2(mp.pnums[i], mp.pnums[j]); - i2.Sort(); - int hval = edgenumber.Get(i2); - if (hval > val) - { - val = hval; - mp.markededge = 3 - i - j; - } - } -} - - - - - - -void BTDefineMarkedTri (const Element2d & el, - INDEX_2_CLOSED_HASHTABLE<int> & edgenumber, - MarkedTri & mt) -{ - int i, j, k; - for (i = 0; i < 3; i++) - { - mt.pnums[i] = el[i]; - mt.pgeominfo[i] = el.GeomInfoPi (i+1); - } - - mt.marked = 0; - mt.surfid = el.GetIndex(); - - mt.incorder = 0; - mt.order = 1; - - int val = 0; - for (i = 0; i < 2; i++) - for (j = i+1; j < 3; j++) - { - INDEX_2 i2(mt.pnums[i], mt.pnums[j]); - i2.Sort(); - int hval = edgenumber.Get(i2); - if (hval > val) - { - val = hval; - mt.markededge = 3 - i - j; - } - } -} - - - - - -void BTDefineMarkedQuad (const Element2d & el, - INDEX_2_CLOSED_HASHTABLE<int> & edgenumber, - MarkedQuad & mq) -{ - int i, j, k; - for (i = 0; i < 4; i++) - mq.pnums[i] = el[i]; - Swap (mq.pnums[2], mq.pnums[3]); - - mq.marked = 0; - mq.surfid = el.GetIndex(); -} - - - - -// mark elements due to local h -int BTMarkTets (T_MTETS & mtets, - T_MPRISMS & mprisms, - const Mesh & mesh) -{ - int i, j, k; - int step; - - int marked = 0; - - int np = mesh.GetNP(); - Vector hv(np); - for (i = 1; i <= np; i++) - hv.Elem(i) = mesh.GetH (mesh.Point(i)); - - double hfac = 1; - - for (step = 1; step <= 2; step++) - { - for (i = 1; i <= mtets.Size(); i++) - { - double h = 0; - - for (j = 0; j < 3; j++) - for (k = j+1; k < 4; k++) - { - const Point3d & p1 = mesh.Point (mtets.Get(i).pnums[j]); - const Point3d & p2 = mesh.Point (mtets.Get(i).pnums[k]); - double hh = Dist2 (p1, p2); - if (hh > h) h = hh; - } - h = sqrt (h); - - double hshould = 1e10; - for (j = 0; j < 4; j++) - { - double hi = hv.Get (mtets.Get(i).pnums[j]); - if (hi < hshould) - hshould = hi; - } - - - if (step == 1) - { - if (h / hshould > hfac) - hfac = h / hshould; - } - else - { - if (h > hshould * hfac) - { - mtets.Elem(i).marked = 1; - marked = 1; - } - else - mtets.Elem(i).marked = 0; - } - - } - for (i = 1; i <= mprisms.Size(); i++) - { - double h = 0; - - for (j = 0; j < 2; j++) - for (k = j+1; k < 3; k++) - { - const Point3d & p1 = mesh.Point (mprisms.Get(i).pnums[j]); - const Point3d & p2 = mesh.Point (mprisms.Get(i).pnums[k]); - double hh = Dist2 (p1, p2); - if (hh > h) h = hh; - } - h = sqrt (h); - - double hshould = 1e10; - for (j = 0; j < 6; j++) - { - double hi = hv.Get (mprisms.Get(i).pnums[j]); - if (hi < hshould) - hshould = hi; - } - - - if (step == 1) - { - if (h / hshould > hfac) - hfac = h / hshould; - } - else - { - if (h > hshould * hfac) - { - mprisms.Elem(i).marked = 1; - marked = 1; - } - else - mprisms.Elem(i).marked = 0; - } - - } - - - - if (step == 1) - { - if (hfac > 2) - hfac /= 2; - else - hfac = 1; - } - - } - return marked; -} - - - - - - - - - - - - - - -void BTBisectTet (const MarkedTet & oldtet, int newp, - MarkedTet & newtet1, MarkedTet & newtet2) -{ - int i, j, k; - - - // points vis a vis from tet-edge - int vis1, vis2; - vis1 = 0; - while (vis1 == oldtet.tetedge1 || vis1 == oldtet.tetedge2) - vis1++; - vis2 = 6 - vis1 - oldtet.tetedge1 - oldtet.tetedge2; - - - // is tet of type P ? - int istypep = 0; - for (i = 0; i < 4; i++) - { - int cnt = 0; - for (j = 0; j < 4; j++) - if (oldtet.faceedges[j] == i) - cnt++; - if (cnt == 3) - istypep = 1; - } - - - - for (i = 0; i < 4; i++) - { - newtet1.pnums[i] = oldtet.pnums[i]; - newtet2.pnums[i] = oldtet.pnums[i]; - } - newtet1.flagged = istypep && !oldtet.flagged; - newtet2.flagged = istypep && !oldtet.flagged; - - int nm = oldtet.marked - 1; - if (nm < 0) nm = 0; - newtet1.marked = nm; - newtet2.marked = nm; - - - for (i = 0; i < 4; i++) - { - if (i == oldtet.tetedge1) - { - newtet2.pnums[i] = newp; - newtet2.faceedges[i] = oldtet.faceedges[i]; // inherited face - newtet2.faceedges[vis1] = i; // cut faces - newtet2.faceedges[vis2] = i; - - j = 0; - while (j == i || j == oldtet.faceedges[i]) - j++; - k = 6 - i - oldtet.faceedges[i] - j; - newtet2.tetedge1 = j; // tet-edge - newtet2.tetedge2 = k; - - // new face: - if (istypep && oldtet.flagged) - newtet2.faceedges[oldtet.tetedge2] = - 6 - oldtet.tetedge1 - j - k; - else - newtet2.faceedges[oldtet.tetedge2] = oldtet.tetedge1; - } - - if (i == oldtet.tetedge2) - { - newtet1.pnums[i] = newp; - newtet1.faceedges[i] = oldtet.faceedges[i]; // inherited face - newtet1.faceedges[vis1] = i; - newtet1.faceedges[vis2] = i; - j = 0; - while (j == i || j == oldtet.faceedges[i]) - j++; - k = 6 - i - oldtet.faceedges[i] - j; - newtet1.tetedge1 = j; - newtet1.tetedge2 = k; - - // new face: - if (istypep && oldtet.flagged) - newtet1.faceedges[oldtet.tetedge1] = - 6 - oldtet.tetedge2 - j - k; - else - newtet1.faceedges[oldtet.tetedge1] = oldtet.tetedge2; - } - } - - newtet1.matindex = oldtet.matindex; - newtet2.matindex = oldtet.matindex; - newtet1.incorder = 0; - newtet1.order = oldtet.order; - newtet2.incorder = 0; - newtet2.order = oldtet.order; -} - - - - -void BTBisectPrism (const MarkedPrism & oldprism, int newp1, int newp2, - MarkedPrism & newprism1, MarkedPrism & newprism2) -{ - int i, j, k; - - for (i = 0; i < 6; i++) - { - newprism1.pnums[i] = oldprism.pnums[i]; - newprism2.pnums[i] = oldprism.pnums[i]; - } - - int pe1, pe2; - pe1 = 0; - if (pe1 == oldprism.markededge) - pe1++; - pe2 = 3 - oldprism.markededge - pe1; - - newprism1.pnums[pe2] = newp1; - newprism1.pnums[pe2+3] = newp2; - newprism1.markededge = pe2; - newprism2.pnums[pe1] = newp1; - newprism2.pnums[pe1+3] = newp2; - newprism2.markededge = pe1; - - newprism1.matindex = oldprism.matindex; - newprism2.matindex = oldprism.matindex; - - int nm = oldprism.marked - 1; - if (nm < 0) nm = 0; - newprism1.marked = nm; - newprism2.marked = nm; - - newprism1.incorder = 0; - newprism1.order = oldprism.order; - newprism2.incorder = 0; - newprism2.order = oldprism.order; -} - - - -void BTBisectTri (const MarkedTri & oldtri, int newp, const PointGeomInfo & newpgi, - MarkedTri & newtri1, MarkedTri & newtri2) -{ - int i, j, k; - - for (i = 0; i < 3; i++) - { - newtri1.pnums[i] = oldtri.pnums[i]; - newtri1.pgeominfo[i] = oldtri.pgeominfo[i]; - newtri2.pnums[i] = oldtri.pnums[i]; - newtri2.pgeominfo[i] = oldtri.pgeominfo[i]; - } - - int pe1, pe2; - pe1 = 0; - if (pe1 == oldtri.markededge) - pe1++; - pe2 = 3 - oldtri.markededge - pe1; - - newtri1.pnums[pe2] = newp; - newtri1.pgeominfo[pe2] = newpgi; - newtri1.markededge = pe2; - - newtri2.pnums[pe1] = newp; - newtri2.pgeominfo[pe1] = newpgi; - newtri2.markededge = pe1; - - newtri1.surfid = oldtri.surfid; - newtri2.surfid = oldtri.surfid; - - int nm = oldtri.marked - 1; - if (nm < 0) nm = 0; - newtri1.marked = nm; - newtri2.marked = nm; - - newtri1.incorder = 0; - newtri1.order = oldtri.order; - newtri2.incorder = 0; - newtri2.order = oldtri.order; -} - - -void BTBisectQuad (const MarkedQuad & oldquad, - int newp1, const PointGeomInfo & npgi1, - int newp2, const PointGeomInfo & npgi2, - MarkedQuad & newquad1, MarkedQuad & newquad2) -{ - int i, j, k; - - for (i = 0; i < 4; i++) - { - newquad1.pnums[i] = oldquad.pnums[i]; - newquad1.pgeominfo[i] = oldquad.pgeominfo[i]; - newquad2.pnums[i] = oldquad.pnums[i]; - newquad2.pgeominfo[i] = oldquad.pgeominfo[i]; - } - - newquad1.pnums[1] = newp1; - newquad1.pgeominfo[1] = npgi1; - newquad1.pnums[3] = newp2; - newquad1.pgeominfo[3] = npgi2; - - newquad2.pnums[0] = newp1; - newquad2.pgeominfo[0] = npgi1; - newquad2.pnums[2] = newp2; - newquad2.pgeominfo[2] = npgi2; - - newquad1.surfid = oldquad.surfid; - newquad2.surfid = oldquad.surfid; - - - int nm = oldquad.marked - 1; - if (nm < 0) nm = 0; - - newquad1.marked = nm; - newquad2.marked = nm; -} - - - - -int MarkHangingTets (T_MTETS & mtets, - const INDEX_2_CLOSED_HASHTABLE<int> & cutedges) -{ - int i, j, k; - - int hanging = 0; - for (i = 1; i <= mtets.Size(); i++) - { - MarkedTet & teti = mtets.Elem(i); - - if (teti.marked) - { - hanging = 1; - continue; - } - - for (j = 0; j < 3; j++) - for (k = j+1; k < 4; k++) - { - INDEX_2 edge(teti.pnums[j], - teti.pnums[k]); - edge.Sort(); - if (cutedges.Used (edge)) - { - teti.marked = 1; - hanging = 1; - } - } - } - return hanging; -} - - - -int MarkHangingPrisms (T_MPRISMS & mprisms, - const INDEX_2_CLOSED_HASHTABLE<int> & cutedges) -{ - int i, j, k; - - int hanging = 0; - for (i = 1; i <= mprisms.Size(); i++) - { - if (mprisms.Elem(i).marked) - { - hanging = 1; - continue; - } - - for (j = 0; j < 2; j++) - for (k = j+1; k < 3; k++) - { - INDEX_2 edge1(mprisms.Get(i).pnums[j], - mprisms.Get(i).pnums[k]); - INDEX_2 edge2(mprisms.Get(i).pnums[j+3], - mprisms.Get(i).pnums[k+3]); - edge1.Sort(); - edge2.Sort(); - if (cutedges.Used (edge1) || - cutedges.Used (edge2)) - { - mprisms.Elem(i).marked = 1; - hanging = 1; - } - } - } - return hanging; -} - - - -int MarkHangingTris (T_MTRIS & mtris, - const INDEX_2_CLOSED_HASHTABLE<int> & cutedges) -{ - int i, j, k; - - int hanging = 0; - for (i = 1; i <= mtris.Size(); i++) - { - if (mtris.Get(i).marked) - { - hanging = 1; - continue; - } - for (j = 0; j < 2; j++) - for (k = j+1; k < 3; k++) - { - INDEX_2 edge(mtris.Get(i).pnums[j], - mtris.Get(i).pnums[k]); - edge.Sort(); - if (cutedges.Used (edge)) - { - mtris.Elem(i).marked = 1; - hanging = 1; - } - } - } - return hanging; -} - - - -int MarkHangingQuads (T_MQUADS & mquads, - const INDEX_2_CLOSED_HASHTABLE<int> & cutedges) -{ - int i; - - int hanging = 0; - for (i = 1; i <= mquads.Size(); i++) - { - if (mquads.Elem(i).marked) - { - hanging = 1; - continue; - } - - INDEX_2 edge1(mquads.Get(i).pnums[0], - mquads.Get(i).pnums[1]); - INDEX_2 edge2(mquads.Get(i).pnums[2], - mquads.Get(i).pnums[3]); - edge1.Sort(); - edge2.Sort(); - if (cutedges.Used (edge1) || - cutedges.Used (edge2)) - { - mquads.Elem(i).marked = 1; - hanging = 1; - } - - } - return hanging; -} - - - -void ConnectToNodeRec (int node, int tonode, - const TABLE<int> & conto, ARRAY<int> & connecttonode) -{ - int i, n2; - // (*testout) << "connect " << node << " to " << tonode << endl; - for (i = 1; i <= conto.EntrySize(node); i++) - { - n2 = conto.Get(node, i); - if (!connecttonode.Get(n2)) - { - connecttonode.Elem(n2) = tonode; - ConnectToNodeRec (n2, tonode, conto, connecttonode); - } - } -} - - - - -T_MTETS mtets; -T_MPRISMS mprisms; -T_MTRIS mtris; -T_MQUADS mquads; - - - -void BisectTetsCopyMesh (Mesh & mesh, const class CSGeometry *, - BisectionOptions & opt) -{ - mtets.SetName ("bisection, tets"); - mprisms.SetName ("bisection, prisms"); - mtris.SetName ("bisection, trigs"); - mquads.SetName ("bisection, quads"); - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int i, j, k, l, m; - - /* - if (mtets.Size() + mprisms.Size() == mesh.GetNE()) - return; - */ - - mtets.SetSize(0); - mprisms.SetSize(0); - mtris.SetSize(0); - mquads.SetSize(0); - - - INDEX_2_HASHTABLE<int> shortedges(100); - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - if (el.GetType() == PRISM || - el.GetType() == PRISM12) - { - for (j = 1; j <= 3; j++) - { - INDEX_2 se(el.PNum(j), el.PNum(j+3)); - se.Sort(); - shortedges.Set (se, 1); - } - } - } - - - - // INDEX_2_HASHTABLE<int> edgenumber(np); - INDEX_2_CLOSED_HASHTABLE<int> edgenumber(9*ne+4*nse); - - BTSortEdges (mesh, edgenumber); - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - - switch (el.GetType()) - { - case TET: - case TET10: - { - // if tet has short edge, it is handled as degenerated prism - - int foundse = 0; - for (j = 1; j <= 3; j++) - for (k = j+1; k <= 4; k++) - { - INDEX_2 se(el.PNum(j), el.PNum(k)); - se.Sort(); - if (shortedges.Used (se)) - { - // cout << "tet converted to prism" << endl; - - foundse = 1; - int p3 = 1; - while (p3 == j || p3 == k) - p3++; - int p4 = 10 - j - k - p3; - - // even permutation ? - int pi[4]; - pi[0] = j; - pi[1] = k; - pi[2] = p3; - pi[3] = p4; - int cnt = 0; - for (l = 1; l <= 4; l++) - for (m = 0; m < 3; m++) - if (pi[m] > pi[m+1]) - { - Swap (pi[m], pi[m+1]); - cnt++; - } - if (cnt % 2) - Swap (p3, p4); - - Element hel = el; - hel.PNum(1) = el.PNum(j); - hel.PNum(2) = el.PNum(k); - hel.PNum(3) = el.PNum(p3); - hel.PNum(4) = el.PNum(p4); - - MarkedPrism mp; - BTDefineMarkedPrism (hel, edgenumber, mp); - mp.matindex = el.GetIndex(); - mprisms.Append (mp); - } - } - if (!foundse) - { - MarkedTet mt; - BTDefineMarkedTet (el, edgenumber, mt); - mt.matindex = el.GetIndex(); - mtets.Append (mt); - } - break; - } - case PYRAMID: - { - // eventually rotate - MarkedPrism mp; - - INDEX_2 se(el.PNum(1), el.PNum(2)); - se.Sort(); - if (shortedges.Used (se)) - { - Element hel = el; - hel.PNum(1) = el.PNum(2); - hel.PNum(2) = el.PNum(3); - hel.PNum(3) = el.PNum(4); - hel.PNum(4) = el.PNum(1); - BTDefineMarkedPrism (hel, edgenumber, mp); - } - else - { - BTDefineMarkedPrism (el, edgenumber, mp); - } - - mp.matindex = el.GetIndex(); - mprisms.Append (mp); - break; - } - case PRISM: - case PRISM12: - { - MarkedPrism mp; - BTDefineMarkedPrism (el, edgenumber, mp); - mp.matindex = el.GetIndex(); - mprisms.Append (mp); - break; - } - } - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (el.GetType() == TRIG || - el.GetType() == TRIG6) - { - MarkedTri mt; - BTDefineMarkedTri (el, edgenumber, mt); - mtris.Append (mt); - } - else - { - MarkedQuad mq; - BTDefineMarkedQuad (el, edgenumber, mq); - mquads.Append (mq); - } - } - - - - mesh.mlparentelement.SetSize(ne); - for (i = 1; i <= ne; i++) - mesh.mlparentelement.Elem(i) = 0; - mesh.mlparentsurfaceelement.SetSize(nse); - for (i = 1; i <= nse; i++) - mesh.mlparentsurfaceelement.Elem(i) = 0; - - - cout << "copied " << mtets.Size() << " tets, " << mtris.Size() << " trigs" << endl; -} - - -void Refinement :: Bisect (Mesh & mesh, - BisectionOptions & opt) -{ - cout << "Mesh bisection" << endl; - - if (mesh.mglevels == 1) - BisectTetsCopyMesh(mesh, NULL, opt); - - mesh.ComputeNVertices(); - - int np = mesh.GetNV(); - mesh.SetNP(np); - - // int ne = mesh.GetNE(); - // int nse = mesh.GetNSE(); - int i, j, l; - - // int initnp = np; - // int maxsteps = 3; - - mesh.mglevels++; - - /* - if (opt.refinementfilename || opt.usemarkedelements) - maxsteps = 3; - */ - - - - if (opt.refine_p) - { - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int ii = 0; - for (ElementIndex ei = 0; ei < ne; ei++) - if (mesh[ei].TestRefinementFlag()) - mesh[ei].SetOrder (mesh[ei].GetOrder()+1); - - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - if (mesh[sei].TestRefinementFlag()) - mesh[sei].SetOrder (mesh[sei].GetOrder()+1); - - - ARRAY<int,PointIndex::BASE> v_order (mesh.GetNP()); - v_order = 0; - - for (ElementIndex ei = 0; ei < ne; ei++) - for (j = 0; j < mesh[ei].GetNP(); j++) - if (mesh[ei].GetOrder() > v_order[mesh[ei][j]]) - v_order[mesh[ei][j]] = mesh[ei].GetOrder(); - - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - for (j = 0; j < mesh[sei].GetNP(); j++) - if (mesh[sei].GetOrder() > v_order[mesh[sei][j]]) - v_order[mesh[sei][j]] = mesh[sei].GetOrder(); - - for (ElementIndex ei = 0; ei < ne; ei++) - for (j = 0; j < mesh[ei].GetNP(); j++) - if (mesh[ei].GetOrder() < v_order[mesh[ei][j]]-1) - mesh[ei].SetOrder(v_order[mesh[ei][j]]-1); - - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - for (j = 0; j < mesh[sei].GetNP(); j++) - if (mesh[sei].GetOrder() < v_order[mesh[sei][j]]-1) - mesh[sei].SetOrder(v_order[mesh[sei][j]]-1); - - return; - } - - - - // INDEX_2_HASHTABLE<int> cutedges(10 + 5 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size())); - INDEX_2_CLOSED_HASHTABLE<int> cutedges(10 + 9 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size())); - - - for (l = 1; l <= 1; l++) - { - int marked = 0; - if (opt.refinementfilename) - { - ifstream inf(opt.refinementfilename); - cout << "load refinementinfo from file " << opt.refinementfilename << endl; - char ch; - for (i = 1; i <= mtets.Size(); i++) - { - inf >> ch; - mtets.Elem(i).marked = (ch == '1'); - } - marked = 1; - } - - else if (opt.usemarkedelements) - { - int cntm = 0; - - // all in one ! - if (mprisms.Size()) - { - int cnttet = 0; - int cntprism = 0; - for (i = 1; i <= mesh.GetNE(); i++) - { - if (mesh.VolumeElement(i).GetType() == TET || - mesh.VolumeElement(i).GetType() == TET10) - { - cnttet++; - mtets.Elem(cnttet).marked = - 3 * mesh.VolumeElement(i).TestRefinementFlag(); - if (mtets.Elem(cnttet).marked) - cntm++; - } - else - { - cntprism++; - mprisms.Elem(cntprism).marked = - 2 * mesh.VolumeElement(i).TestRefinementFlag(); - if (mprisms.Elem(cntprism).marked) - cntm++; - } - - } - } - else - for (i = 1; i <= mtets.Size(); i++) - { - mtets.Elem(i).marked = - 3 * mesh.VolumeElement(i).TestRefinementFlag(); - if (mtets.Elem(i).marked) - cntm++; - } - - // (*testout) << "mtets = " << mtets << endl; - - /* - for (i = 1; i <= mtris.Size(); i++) - mtris.Elem(i).marked = 0; - for (i = 1; i <= mquads.Size(); i++) - mquads.Elem(i).marked = 0; - */ - - cout << "marked elements: " << cntm << endl; - - int cnttrig = 0; - int cntquad = 0; - for (i = 1; i <= mesh.GetNSE(); i++) - { - if (mesh.SurfaceElement(i).GetType() == TRIG || - mesh.SurfaceElement(i).GetType() == TRIG6) - { - cnttrig++; - mtris.Elem(cnttrig).marked = - mesh.SurfaceElement(i).TestRefinementFlag() ? 2 : 0; - // mtris.Elem(cnttrig).marked = 0; - if (mtris.Elem(cnttrig).marked) - cntm++; - } - else - { - cntquad++; - mquads.Elem(cntquad).marked = - mesh.SurfaceElement(i).TestRefinementFlag(); - // mquads.Elem(cntquad).marked = 0; - if (mquads.Elem(cntquad).marked) - cntm++; - } - } - - cout << "with surface-elements: " << cntm << endl; - - if (mesh.GetDimension() == 2) - { - cntm = 0; - for (i = 1; i <= mtris.Size(); i++) - { - mtris.Elem(i).marked = - 2 * mesh.SurfaceElement(i).TestRefinementFlag(); - // mtris.Elem(i).marked = 2; - if (mtris.Elem(i).marked) - cntm++; - } - - if (!cntm) - { - for (i = 1; i <= mtris.Size(); i++) - { - mtris.Elem(i).marked = 2; - cntm++; - } - } - cout << "trigs: " << mtris.Size() << " "; - cout << "marked: " << cntm << endl; - } - - marked = (cntm > 0); - } - else - { - marked = BTMarkTets (mtets, mprisms, mesh); - } - - if (!marked) break; - - - if (opt.refine_p) - { - cout << "refine p" << endl; - - for (i = 1; i <= mtets.Size(); i++) - mtets.Elem(i).incorder = mtets.Elem(i).marked ? 1 : 0; - - for (i = 1; i <= mtets.Size(); i++) - if (mtets.Elem(i).incorder) - mtets.Elem(i).marked = 0; - - - for (i = 1; i <= mprisms.Size(); i++) - mprisms.Elem(i).incorder = mprisms.Elem(i).marked ? 1 : 0; - - for (i = 1; i <= mprisms.Size(); i++) - if (mprisms.Elem(i).incorder) - mprisms.Elem(i).marked = 0; - - - for (i = 1; i <= mtris.Size(); i++) - mtris.Elem(i).incorder = mtris.Elem(i).marked ? 1 : 0; - - for (i = 1; i <= mtris.Size(); i++) - { - if (mtris.Elem(i).incorder) - mtris.Elem(i).marked = 0; - } - } - - if (opt.refine_hp) - { - cout << "refine hp" << endl; - BitArray singv(np); - singv.Clear(); - - if (mesh.GetDimension() == 3) - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - singv.Set (seg.p1); - singv.Set (seg.p2); - } - else - { - // vertices with 2 different bnds - ARRAY<int> bndind(np); - bndind = 0; - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - for (int j = 0; j < 2; j++) - { - int pi = (j == 0) ? seg.p1 : seg.p2; - if (bndind.Elem(pi) == 0) - bndind.Elem(pi) = seg.edgenr; - else if (bndind.Elem(pi) != seg.edgenr) - singv.Set (pi); - } - } - } - - - - for (i = 1; i <= mtets.Size(); i++) - mtets.Elem(i).incorder = 1; - for (i = 1; i <= mtets.Size(); i++) - { - if (!mtets.Elem(i).marked) - mtets.Elem(i).incorder = 0; - for (j = 0; j < 4; j++) - if (singv.Test (mtets.Elem(i).pnums[j])) - mtets.Elem(i).incorder = 0; - } - for (i = 1; i <= mtets.Size(); i++) - if (mtets.Elem(i).incorder) - mtets.Elem(i).marked = 0; - - - for (i = 1; i <= mprisms.Size(); i++) - mprisms.Elem(i).incorder = 1; - for (i = 1; i <= mprisms.Size(); i++) - { - if (!mprisms.Elem(i).marked) - mprisms.Elem(i).incorder = 0; - for (j = 0; j < 6; j++) - if (singv.Test (mprisms.Elem(i).pnums[j])) - mprisms.Elem(i).incorder = 0; - } - for (i = 1; i <= mprisms.Size(); i++) - if (mprisms.Elem(i).incorder) - mprisms.Elem(i).marked = 0; - - - for (i = 1; i <= mtris.Size(); i++) - mtris.Elem(i).incorder = 1; - for (i = 1; i <= mtris.Size(); i++) - { - if (!mtris.Elem(i).marked) - mtris.Elem(i).incorder = 0; - for (j = 0; j < 3; j++) - if (singv.Test (mtris.Elem(i).pnums[j])) - mtris.Elem(i).incorder = 0; - } - for (i = 1; i <= mtris.Size(); i++) - { - if (mtris.Elem(i).incorder) - mtris.Elem(i).marked = 0; - } - } - - - - - - int hangingvol, hangingsurf, hangingedge; - - do - { - // refine volume elements - - int nel = mtets.Size(); - for (i = 1; i <= nel; i++) - if (mtets.Elem(i).marked) - { - MarkedTet oldtet; - MarkedTet newtet1, newtet2; - int newp; - - - oldtet = mtets.Get(i); - INDEX_2 edge(oldtet.pnums[oldtet.tetedge1], - oldtet.pnums[oldtet.tetedge2]); - edge.Sort(); - if (cutedges.Used (edge)) - { - newp = cutedges.Get(edge); - } - else - { - Point3d np = Center (mesh.Point (edge.I1()), - mesh.Point (edge.I2())); - newp = mesh.AddPoint (np); - cutedges.Set (edge, newp); - } - - BTBisectTet (oldtet, newp, newtet1, newtet2); - mtets.Elem(i) = newtet1; - mtets.Append (newtet2); - } - - int npr = mprisms.Size(); - for (i = 1; i <= npr; i++) - if (mprisms.Elem(i).marked) - { - MarkedPrism oldprism; - MarkedPrism newprism1, newprism2; - int newp1, newp2; - - oldprism = mprisms.Get(i); - int pi1 = 0; - if (pi1 == oldprism.markededge) - pi1++; - int pi2 = 3-pi1-oldprism.markededge; - - INDEX_2 edge1(oldprism.pnums[pi1], - oldprism.pnums[pi2]); - INDEX_2 edge2(oldprism.pnums[pi1+3], - oldprism.pnums[pi2+3]); - edge1.Sort(); - edge2.Sort(); - - if (cutedges.Used (edge1)) - newp1 = cutedges.Get(edge1); - else - { - Point3d np = Center (mesh.Point (edge1.I1()), - mesh.Point (edge1.I2())); - newp1 = mesh.AddPoint (np); - cutedges.Set (edge1, newp1); - } - if (cutedges.Used (edge2)) - newp2 = cutedges.Get(edge2); - else - { - Point3d np = Center (mesh.Point (edge2.I1()), - mesh.Point (edge2.I2())); - newp2 = mesh.AddPoint (np); - cutedges.Set (edge2, newp2); - } - - - BTBisectPrism (oldprism, newp1, newp2, newprism1, newprism2); - mprisms.Elem(i) = newprism1; - mprisms.Append (newprism2); - } - - - hangingvol = - MarkHangingTets (mtets, cutedges) + - MarkHangingPrisms (mprisms, cutedges); - - - int nsel = mtris.Size(); - - for (i = 1; i <= nsel; i++) - if (mtris.Elem(i).marked) - { - MarkedTri oldtri; - MarkedTri newtri1, newtri2; - int newp; - - oldtri = mtris.Get(i); - int oldpi1 = oldtri.pnums[(oldtri.markededge+1)%3]; - int oldpi2 = oldtri.pnums[(oldtri.markededge+2)%3]; - INDEX_2 edge(oldpi1, oldpi2); - edge.Sort(); - - // cerr << "edge = " << edge.I1() << "-" << edge.I2() << endl; - - if (cutedges.Used (edge)) - { - newp = cutedges.Get(edge); - } - else - { - Point3d np = Center (mesh.Point (edge.I1()), - mesh.Point (edge.I2())); - newp = mesh.AddPoint (np); - cutedges.Set (edge, newp); - } - // newp = cutedges.Get(edge); - - int si = mesh.GetFaceDescriptor (oldtri.surfid).SurfNr(); - // geom->GetSurface(si)->Project (mesh.Point(newp)); - PointGeomInfo npgi; - - if (mesh.PointType(newp) != EDGEPOINT) - PointBetween (mesh.Point (oldpi1), mesh.Point (oldpi2), - 0.5, si, - oldtri.pgeominfo[(oldtri.markededge+1)%3], - oldtri.pgeominfo[(oldtri.markededge+2)%3], - mesh.Point (newp), npgi); - - BTBisectTri (oldtri, newp, npgi, newtri1, newtri2); - - - mtris.Elem(i) = newtri1; - mtris.Append (newtri2); - mesh.mlparentsurfaceelement.Append (i); - } - - int nquad = mquads.Size(); - for (i = 1; i <= nquad; i++) - if (mquads.Elem(i).marked) - { - MarkedQuad oldquad; - MarkedQuad newquad1, newquad2; - int newp1, newp2; - - oldquad = mquads.Get(i); - INDEX_2 edge1(oldquad.pnums[0], - oldquad.pnums[1]); - INDEX_2 edge2(oldquad.pnums[2], - oldquad.pnums[3]); - edge1.Sort(); - edge2.Sort(); - - if (cutedges.Used (edge1)) - { - newp1 = cutedges.Get(edge1); - } - else - { - Point3d np = Center (mesh.Point (edge1.I1()), - mesh.Point (edge1.I2())); - newp1 = mesh.AddPoint (np); - cutedges.Set (edge1, newp1); - } - - if (cutedges.Used (edge2)) - { - newp2 = cutedges.Get(edge2); - } - else - { - Point3d np = Center (mesh.Point (edge2.I1()), - mesh.Point (edge2.I2())); - newp2 = mesh.AddPoint (np); - cutedges.Set (edge2, newp2); - } - - PointGeomInfo npgi1, npgi2; - - int si = mesh.GetFaceDescriptor (oldquad.surfid).SurfNr(); - // geom->GetSurface(si)->Project (mesh.Point(newp1)); - // geom->GetSurface(si)->Project (mesh.Point(newp2)); - - (*testout) << "project point " << newp1 << " old: " << mesh.Point(newp1); - PointBetween (mesh.Point (edge1.I1()), mesh.Point (edge1.I2()), - 0.5, si, - oldquad.pgeominfo[0], - oldquad.pgeominfo[1], - mesh.Point (newp1), npgi1); - (*testout) << " new: " << mesh.Point(newp1) << endl; - - - PointBetween (mesh.Point (edge2.I1()), mesh.Point (edge2.I2()), - 0.5, si, - oldquad.pgeominfo[2], - oldquad.pgeominfo[3], - mesh.Point (newp2), npgi2); - - - BTBisectQuad (oldquad, newp1, npgi1, newp2, npgi2, - newquad1, newquad2); - mquads.Elem(i) = newquad1; - mquads.Append (newquad2); - } - - - hangingsurf = - MarkHangingTris (mtris, cutedges) + - MarkHangingQuads (mquads, cutedges); - - hangingedge = 0; - - int nseg = mesh.GetNSeg (); - for (i = 1; i <= nseg; i++) - { - Segment & seg = mesh.LineSegment (i); - INDEX_2 edge(seg.p1, seg.p2); - edge.Sort(); - if (cutedges.Used (edge)) - { - hangingedge = 1; - Segment nseg1 = seg; - Segment nseg2 = seg; - - int newpi = cutedges.Get(edge); - - nseg1.p2 = newpi; - nseg2.p1 = newpi; - - EdgePointGeomInfo newepgi; - - // (*testout) << "move edgepoint " << newpi << " from " << mesh.Point(newpi); - PointBetween (mesh.Point (seg.p1), mesh.Point (seg.p2), - 0.5, seg.surfnr1, seg.surfnr2, - seg.epgeominfo[0], seg.epgeominfo[1], - mesh.Point (newpi), newepgi); - // (*testout) << " to " << mesh.Point (newpi) << endl; - nseg1.epgeominfo[1] = newepgi; - nseg2.epgeominfo[0] = newepgi; - - mesh.LineSegment (i) = nseg1; - mesh.AddSegment (nseg2); - } - } - - } - while (hangingvol || hangingsurf || hangingedge); - - - cout << mtets.Size() << " tets" << endl; - cout << mtris.Size() << " trigs" << endl; - if (mprisms.Size()) - { - cout << mprisms.Size() << " prisms" << endl; - cout << mquads.Size() << " quads" << endl; - } - cout << mesh.GetNP() << " points" << endl; - } - - /* - cout << "mem in mtets: " << endl; - mtets.PrintMemInfo(cout); - cout << "cutedges" << endl; - cutedges.PrintMemInfo(cout); - */ - - // (*testout) << "mtets = " << mtets << endl; - - if (opt.refine_hp) - { - // - ARRAY<int> v_order (mesh.GetNP()); - v_order = 0; - if (mesh.GetDimension() == 3) - { - for (i = 1; i <= mtets.Size(); i++) - if (mtets.Elem(i).incorder) - mtets.Elem(i).order++; - - for (i = 0; i < mtets.Size(); i++) - for (j = 0; j < 4; j++) - if (mtets[i].order > v_order.Elem(mtets[i].pnums[j])) - v_order.Elem(mtets[i].pnums[j]) = mtets[i].order; - for (i = 0; i < mtets.Size(); i++) - for (j = 0; j < 4; j++) - if (mtets[i].order < v_order.Elem(mtets[i].pnums[j])-1) - mtets[i].order = v_order.Elem(mtets[i].pnums[j])-1; - } - else - { - for (i = 1; i <= mtris.Size(); i++) - if (mtris.Elem(i).incorder) - { - mtris.Elem(i).order++; - } - - for (i = 0; i < mtris.Size(); i++) - for (j = 0; j < 3; j++) - if (mtris[i].order > v_order.Elem(mtris[i].pnums[j])) - v_order.Elem(mtris[i].pnums[j]) = mtris[i].order; - for (i = 0; i < mtris.Size(); i++) - { - for (j = 0; j < 3; j++) - if (mtris[i].order < v_order.Elem(mtris[i].pnums[j])-1) - mtris[i].order = v_order.Elem(mtris[i].pnums[j])-1; - } - } - } - - mtets.SetAllocSize (mtets.Size()); - mprisms.SetAllocSize (mprisms.Size()); - mtris.SetAllocSize (mtris.Size()); - mquads.SetAllocSize (mquads.Size()); - - - mesh.ClearVolumeElements(); - mesh.VolumeElements().SetAllocSize (mtets.Size()+mprisms.Size()); - for (i = 1; i <= mtets.Size(); i++) - { - Element el(TET); - el.SetIndex (mtets.Get(i).matindex); - for (j = 1; j <= 4; j++) - el.PNum(j) = mtets.Get(i).pnums[j-1]; - el.SetOrder (mtets.Get(i).order); - mesh.AddVolumeElement (el); - } - for (i = 1; i <= mprisms.Size(); i++) - { - Element el(PRISM); - el.SetIndex (mprisms.Get(i).matindex); - for (j = 1; j <= 6; j++) - el.PNum(j) = mprisms.Get(i).pnums[j-1]; - el.SetOrder (mprisms.Get(i).order); - - // degenerated prism ? - static const int map1[] = { 3, 2, 5, 6, 1 }; - static const int map2[] = { 1, 3, 6, 4, 2 }; - static const int map3[] = { 2, 1, 4, 5, 3 }; - - - const int * map = NULL; - int deg1 = 0, deg2 = 0, deg3 = 0; - // int deg = 0; - if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; } - if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; } - if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; } - - switch (deg1+deg2+deg3) - { - case 1: - { - for (j = 1; j <= 5; j++) - el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1]; - - el.SetType (PYRAMID); - break; - } - case 2: - { - static const int tetmap1[] = { 1, 2, 3, 4 }; - static const int tetmap2[] = { 2, 3, 1, 5 }; - static const int tetmap3[] = { 3, 1, 2, 6 }; - if (!deg1) map = tetmap1; - if (!deg2) map = tetmap2; - if (!deg3) map = tetmap3; - for (j = 1; j <= 4; j++) - el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1]; - /* - if (!deg1) el.PNum(4) = el.PNum(4); - if (!deg2) el.PNum(4) = el.PNum(5); - if (!deg3) el.PNum(4) = el.PNum(6); - */ - el.SetType(TET); - break; - } - default: - ; - } - mesh.AddVolumeElement (el); - } - - mesh.ClearSurfaceElements(); - for (i = 1; i <= mtris.Size(); i++) - { - Element2d el(TRIG); - el.SetIndex (mtris.Get(i).surfid); - el.SetOrder (mtris.Get(i).order); - for (j = 1; j <= 3; j++) - { - el.PNum(j) = mtris.Get(i).pnums[j-1]; - el.GeomInfoPi(j) = mtris.Get(i).pgeominfo[j-1]; - } - mesh.AddSurfaceElement (el); - } - for (i = 1; i <= mquads.Size(); i++) - { - Element2d el(QUAD); - el.SetIndex (mquads.Get(i).surfid); - for (j = 1; j <= 4; j++) - el.PNum(j) = mquads.Get(i).pnums[j-1]; - Swap (el.PNum(3), el.PNum(4)); - mesh.AddSurfaceElement (el); - } - - - - // write multilevel hierarchy to mesh: - np = mesh.GetNP(); - mesh.mlbetweennodes.SetSize(np); - if (mesh.mglevels <= 2) - for (i = 1; i <= np; i++) - { - mesh.mlbetweennodes.Elem(i).I1() = 0; - mesh.mlbetweennodes.Elem(i).I2() = 0; - } - - /* - for (i = 1; i <= cutedges.GetNBags(); i++) - for (j = 1; j <= cutedges.GetBagSize(i); j++) - { - INDEX_2 edge; - int newpi; - cutedges.GetData (i, j, edge, newpi); - mesh.mlbetweennodes.Elem(newpi) = edge; - } - */ - for (i = 1; i <= cutedges.Size(); i++) - if (cutedges.UsedPos(i)) - { - INDEX_2 edge; - int newpi; - cutedges.GetData (i, edge, newpi); - mesh.mlbetweennodes.Elem(newpi) = edge; - } - - - /* - mesh.PrintMemInfo (cout); - cout << "tets "; - mtets.PrintMemInfo (cout); - cout << "prims "; - mprisms.PrintMemInfo (cout); - cout << "tris "; - mtris.PrintMemInfo (cout); - cout << "quads "; - mquads.PrintMemInfo (cout); - cout << "cutedges "; - cutedges.PrintMemInfo (cout); - */ - - - /* - - // find connected nodes (close nodes) - TABLE<int> conto(np); - for (i = 1; i <= mprisms.Size(); i++) - for (j = 1; j <= 6; j++) - { - int n1 = mprisms.Get(i).pnums[j-1]; - int n2 = mprisms.Get(i).pnums[(j+2)%6]; - // if (n1 != n2) - { - int found = 0; - for (k = 1; k <= conto.EntrySize(n1); k++) - if (conto.Get(n1, k) == n2) - { - found = 1; - break; - } - if (!found) - conto.Add (n1, n2); - } - } - mesh.connectedtonode.SetSize(np); - for (i = 1; i <= np; i++) - mesh.connectedtonode.Elem(i) = 0; - - -// (*testout) << "connection table: " << endl; -// for (i = 1; i <= np; i++) -// { -// (*testout) << "node " << i << ": "; -// for (j = 1; j <= conto.EntrySize(i); j++) -// (*testout) << conto.Get(i, j) << " "; -// (*testout) << endl; -// } - - - for (i = 1; i <= np; i++) - if (mesh.connectedtonode.Elem(i) == 0) - { - mesh.connectedtonode.Elem(i) = i; - ConnectToNodeRec (i, i, conto, mesh.connectedtonode); - } -*/ - - // mesh.BuildConnectedNodes(); - - mesh.ComputeNVertices(); - mesh.UpdateTopology(); - - // update identification tables - for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) - { - ARRAY<int,PointIndex::BASE> identmap; - mesh.GetIdentifications().GetMap (i, identmap); - - - /* - for (j = 1; j <= cutedges.GetNBags(); j++) - for (k = 1; k <= cutedges.GetBagSize(j); k++) - { - INDEX_2 i2; - int newpi; - cutedges.GetData (j, k, i2, newpi); - INDEX_2 oi2(identmap.Get(i2.I1()), - identmap.Get(i2.I2())); - oi2.Sort(); - if (cutedges.Used (oi2)) - { - int onewpi = cutedges.Get(oi2); - mesh.GetIdentifications().Add (newpi, onewpi, i); - } - } - */ - - for (j = 1; j <= cutedges.Size(); j++) - if (cutedges.UsedPos(j)) - { - INDEX_2 i2; - int newpi; - cutedges.GetData (j, i2, newpi); - INDEX_2 oi2(identmap.Get(i2.I1()), - identmap.Get(i2.I2())); - oi2.Sort(); - if (cutedges.Used (oi2)) - { - int onewpi = cutedges.Get(oi2); - mesh.GetIdentifications().Add (newpi, onewpi, i); - } - } - - } - PrintMessage (5, "Bisection done"); -} - - - - -BisectionOptions :: BisectionOptions () -{ - outfilename = NULL; - mlfilename = NULL; - refinementfilename = NULL; - femcode = NULL; - maxlevel = 50; - usemarkedelements = 0; - refine_hp = 0; - refine_p = 0; -} - - - -void Refinement :: PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi) -{ - newp = p1+secpoint*(p2-p1); -} - -void Refinement :: PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi) -{ - newp = p1+secpoint*(p2-p1); -} - -void Refinement :: ProjectToSurface (Point<3> & p, int surfi) -{ - cout << "Refinement :: ProjectToSurface ERROR: no geometry set" << endl; -} - - -} diff --git a/Netgen/libsrc/meshing/bisect.hpp b/Netgen/libsrc/meshing/bisect.hpp deleted file mode 100644 index 8a1e836116..0000000000 --- a/Netgen/libsrc/meshing/bisect.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef BISECT -#define BISECT - -class BisectionOptions -{ -public: - const char * outfilename; - const char * mlfilename; - const char * refinementfilename; - const char * femcode; - int maxlevel; - int usemarkedelements; - bool refine_hp; - bool refine_p; - BisectionOptions (); -}; - -class ZRefinementOptions -{ -public: - int minref; - ZRefinementOptions(); -}; - - -/* -extern void BisectTets (Mesh &, const CSGeometry *, - BisectionOptions & opt); -*/ - -extern void BisectTetsCopyMesh (Mesh &, const class CSGeometry *, - BisectionOptions & opt); - -extern void ZRefinement (Mesh &, const CSGeometry *, - ZRefinementOptions & opt); - - - - - -class Refinement -{ -public: - Refinement (); - virtual ~Refinement (); - - void Refine (Mesh & mesh); - void Bisect (Mesh & mesh, class BisectionOptions & opt); - void MakeSecondOrder (Mesh & mesh); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi); - - virtual void ProjectToSurface (Point<3> & p, int surfi); - - virtual void ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & /* gi */) - { - ProjectToSurface (p, surfi); - } - - - void ValidateSecondOrder (Mesh & mesh); - void ValidateRefinedMesh (Mesh & mesh, - ARRAY<INDEX_2> & parents); - -}; - -#endif diff --git a/Netgen/libsrc/meshing/boundarylayer.cpp b/Netgen/libsrc/meshing/boundarylayer.cpp deleted file mode 100644 index 6f564586b6..0000000000 --- a/Netgen/libsrc/meshing/boundarylayer.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - -void InsertVirtualBoundaryLayer (Mesh & mesh) -{ - cout << "Insert virt. b.l." << endl; - - int surfid; - - cout << "Boundary Nr:"; - cin >> surfid; - - int i, j; - int np = mesh.GetNP(); - - cout << "Old NP: " << mesh.GetNP() << endl; - cout << "Trigs: " << mesh.GetNSE() << endl; - - BitArray bndnodes(np); - ARRAY<int> mapto(np); - - bndnodes.Clear(); - for (i = 1; i <= mesh.GetNSeg(); i++) - { - int snr = mesh.LineSegment(i).edgenr; - cout << "snr = " << snr << endl; - if (snr == surfid) - { - bndnodes.Set (mesh.LineSegment(i).p1); - bndnodes.Set (mesh.LineSegment(i).p2); - } - } - for (i = 1; i <= mesh.GetNSeg(); i++) - { - int snr = mesh.LineSegment(i).edgenr; - if (snr != surfid) - { - bndnodes.Clear (mesh.LineSegment(i).p1); - bndnodes.Clear (mesh.LineSegment(i).p2); - } - } - - for (i = 1; i <= np; i++) - { - if (bndnodes.Test(i)) - mapto.Elem(i) = mesh.AddPoint (mesh.Point (i)); - else - mapto.Elem(i) = 0; - } - - for (i = 1; i <= mesh.GetNSE(); i++) - { - Element2d & el = mesh.SurfaceElement(i); - for (j = 1; j <= el.GetNP(); j++) - if (mapto.Get(el.PNum(j))) - el.PNum(j) = mapto.Get(el.PNum(j)); - } - - - int nq = 0; - for (i = 1; i <= mesh.GetNSeg(); i++) - { - int snr = mesh.LineSegment(i).edgenr; - if (snr == surfid) - { - int p1 = mesh.LineSegment(i).p1; - int p2 = mesh.LineSegment(i).p2; - int p3 = mapto.Get (p1); - if (!p3) p3 = p1; - int p4 = mapto.Get (p2); - if (!p4) p4 = p2; - - Element2d el(4); - el.PNum(1) = p1; - el.PNum(2) = p2; - el.PNum(3) = p3; - el.PNum(4) = p4; - el.SetIndex (2); - mesh.AddSurfaceElement (el); - nq++; - } - } - - cout << "New NP: " << mesh.GetNP() << endl; - cout << "Quads: " << nq << endl; -} - -} diff --git a/Netgen/libsrc/meshing/boundarylayer.hpp b/Netgen/libsrc/meshing/boundarylayer.hpp deleted file mode 100644 index e5a047b6bb..0000000000 --- a/Netgen/libsrc/meshing/boundarylayer.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef FILE_BOUNDARYLAYER -#define FILE_BOUNDARYLAYER - - -/// -extern void InsertVirtualBoundaryLayer (Mesh & mesh); - - -#endif diff --git a/Netgen/libsrc/meshing/clusters.cpp b/Netgen/libsrc/meshing/clusters.cpp deleted file mode 100644 index 5eef2078e7..0000000000 --- a/Netgen/libsrc/meshing/clusters.cpp +++ /dev/null @@ -1,260 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - -namespace netgen -{ - -AnisotropicClusters :: AnisotropicClusters (const Mesh & amesh) - : mesh(amesh) -{ - ; -} - -AnisotropicClusters :: ~AnisotropicClusters () -{ - ; -} - -void AnisotropicClusters :: Update() -{ - int i, j, k; - - const MeshTopology & top = mesh.GetTopology(); - if (!top.HasEdges()) - return; - - PrintMessage (3, "Update Clusters"); - - nv = mesh.GetNV(); - ned = top.GetNEdges(); - nfa = top.GetNFaces(); - ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - - cluster_reps.SetSize (nv+ned+nfa+ne); - - ARRAY<int> nnums, ednums, fanums; - int changed; - - for (i = 1; i <= cluster_reps.Size(); i++) - cluster_reps.Elem(i) = i; - - for (i = 1; i <= cluster_reps.Size(); i++) - cluster_reps.Elem(i) = -1; - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - ELEMENT_TYPE typ = el.GetType(); - - top.GetElementEdges (i, ednums); - top.GetElementFaces (i, fanums); - - int elnv = top.GetNVertices (typ); - int elned = ednums.Size(); - int elnfa = fanums.Size(); - - nnums.SetSize(elnv+elned+elnfa+1); - for (j = 1; j <= elnv; j++) - nnums.Elem(j) = el.PNum(j); - for (j = 1; j <= elned; j++) - nnums.Elem(elnv+j) = nv+ednums.Elem(j); - for (j = 1; j <= elnfa; j++) - nnums.Elem(elnv+elned+j) = nv+ned+fanums.Elem(j); - nnums.Elem(elnv+elned+elnfa+1) = nv+ned+nfa+i; - - for (j = 0; j < nnums.Size(); j++) - cluster_reps.Elem(nnums[j]) = nnums[j]; - } - - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - ELEMENT_TYPE typ = el.GetType(); - - top.GetSurfaceElementEdges (i, ednums); - int fanum = top.GetSurfaceElementFace (i); - - int elnv = top.GetNVertices (typ); - int elned = ednums.Size(); - - nnums.SetSize(elnv+elned+1); - for (j = 1; j <= elnv; j++) - nnums.Elem(j) = el.PNum(j); - for (j = 1; j <= elned; j++) - nnums.Elem(elnv+j) = nv+ednums.Elem(j); - nnums.Elem(elnv+elned+1) = fanum; - - for (j = 0; j < nnums.Size(); j++) - cluster_reps.Elem(nnums[j]) = nnums[j]; - } - - static const int hex_cluster[] = - { - 1, 2, 3, 4, 1, 2, 3, 4, - 5, 6, 7, 8, 5, 6, 7, 8, 1, 2, 3, 4, - 9, 9, 5, 8, 6, 7, - 9 - }; - - static const int prism_cluster[] = - { - 1, 2, 3, 1, 2, 3, - 4, 5, 6, 4, 5, 6, 3, 1, 2, - 7, 7, 4, 5, 6, - 7 - }; - static const int pyramid_cluster[] = - { - 1, 2, 2, 1, 3, - 4, 2, 1, 4, 6, 5, 5, 6, - 7, 5, 7, 6, 4, - 7 - }; - static const int tet_cluster14[] = - { 1, 2, 3, 1, 1, 4, 5, 4, 5, 6, 7, 5, 4, 7, 7 }; - - static const int tet_cluster12[] = - { 1, 1, 2, 3, 4, 4, 5, 1, 6, 6, 7, 7, 4, 6, 7 }; - - static const int tet_cluster13[] = - { 1, 2, 1, 3, 4, 6, 4, 5, 1, 5, 7, 4, 7, 5, 7 }; - - static const int tet_cluster23[] = - { 2, 1, 1, 3, 6, 5, 5, 4, 4, 1, 5, 7, 7, 4, 7 }; - - static const int tet_cluster24[] = - { 2, 1, 3, 1, 4, 1, 5, 4, 6, 5, 5, 7, 4, 7, 7 }; - - static const int tet_cluster34[] = - { 2, 3, 1, 1, 4, 5, 1, 6, 4, 5, 5, 4, 7, 7, 7 }; - - int cnt = 0; - do - { - cnt++; - changed = 0; - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - ELEMENT_TYPE typ = el.GetType(); - - top.GetElementEdges (i, ednums); - top.GetElementFaces (i, fanums); - - int elnv = top.GetNVertices (typ); - int elned = ednums.Size(); - int elnfa = fanums.Size(); - - nnums.SetSize(elnv+elned+elnfa+1); - for (j = 1; j <= elnv; j++) - nnums.Elem(j) = el.PNum(j); - for (j = 1; j <= elned; j++) - nnums.Elem(elnv+j) = nv+ednums.Elem(j); - for (j = 1; j <= elnfa; j++) - nnums.Elem(elnv+elned+j) = nv+ned+fanums.Elem(j); - nnums.Elem(elnv+elned+elnfa+1) = nv+ned+nfa+i; - - - const int * clustertab = NULL; - switch (typ) - { - case PRISM: - case PRISM12: - clustertab = prism_cluster; - break; - case HEX: - clustertab = hex_cluster; - break; - case PYRAMID: - clustertab = pyramid_cluster; - break; - case TET: - case TET10: - if (cluster_reps.Get(el.PNum(1)) == - cluster_reps.Get(el.PNum(2))) - clustertab = tet_cluster12; - else if (cluster_reps.Get(el.PNum(1)) == - cluster_reps.Get(el.PNum(3))) - clustertab = tet_cluster13; - else if (cluster_reps.Get(el.PNum(1)) == - cluster_reps.Get(el.PNum(4))) - clustertab = tet_cluster14; - else if (cluster_reps.Get(el.PNum(2)) == - cluster_reps.Get(el.PNum(3))) - clustertab = tet_cluster23; - else if (cluster_reps.Get(el.PNum(2)) == - cluster_reps.Get(el.PNum(4))) - clustertab = tet_cluster24; - else if (cluster_reps.Get(el.PNum(3)) == - cluster_reps.Get(el.PNum(4))) - clustertab = tet_cluster34; - else - clustertab = NULL; - break; - default: - clustertab = NULL; - } - - if (clustertab) - for (j = 0; j < nnums.Size(); j++) - for (k = 0; k < j; k++) - if (clustertab[j] == clustertab[k]) - { - int jj = nnums[j]; - int kk = nnums[k]; - if (cluster_reps.Get(jj) < cluster_reps.Get(kk)) - { - cluster_reps.Elem(kk) = cluster_reps.Get(jj); - changed = 1; - } - else if (cluster_reps.Get(kk) < cluster_reps.Get(jj)) - { - cluster_reps.Elem(jj) = cluster_reps.Get(kk); - changed = 1; - } - } - - /* - if (clustertab) - { - if (typ == PYRAMID) - (*testout) << "pyramid"; - else if (typ == PRISM || typ == PRISM12) - (*testout) << "prism"; - else if (typ == TET || typ == TET10) - (*testout) << "tet"; - else - (*testout) << "unknown type" << endl; - - (*testout) << ", nnums = "; - for (j = 0; j < nnums.Size(); j++) - (*testout) << "node " << j << " = " << nnums[j] << ", rep = " - << cluster_reps.Get(nnums[j]) << endl; - } - */ - } - } - while (changed); - - /* - (*testout) << "cluster reps:" << endl; - for (i = 1; i <= cluster_reps.Size(); i++) - { - (*testout) << i << ": "; - if (i <= nv) - (*testout) << "v" << i << " "; - else if (i <= nv+ned) - (*testout) << "e" << i-nv << " "; - else if (i <= nv+ned+nfa) - (*testout) << "f" << i-nv-ned << " "; - else - (*testout) << "c" << i-nv-ned-nfa << " "; - (*testout) << cluster_reps.Get(i) << endl; - } - */ -} -} diff --git a/Netgen/libsrc/meshing/clusters.hpp b/Netgen/libsrc/meshing/clusters.hpp deleted file mode 100644 index b0eea1b5e0..0000000000 --- a/Netgen/libsrc/meshing/clusters.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef CLUSTERS -#define CLUSTERS - -/**************************************************************************/ -/* File: clusers.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 28. Apr. 01 */ -/**************************************************************************/ - -/* - Anisotropic clusters - - nodes, edges, faces, elements -*/ - - -class AnisotropicClusters -{ - const Mesh & mesh; - - int nv, ned, nfa, ne; - - // connected nodes, nodes = vertices, edges, faces, elements - ARRAY<int> cluster_reps; - -public: - AnisotropicClusters (const Mesh & amesh); - ~AnisotropicClusters(); - - void Update(); - - int GetVertexRepresentant (int vnr) const - { return cluster_reps.Get(vnr); } - int GetEdgeRepresentant (int ednr) const - { return cluster_reps.Get(nv+ednr); } - int GetFaceRepresentant (int fnr) const - { return cluster_reps.Get(nv+ned+fnr); } - int GetElementRepresentant (int enr) const - { return cluster_reps.Get(nv+ned+nfa+enr); } -}; - -#endif diff --git a/Netgen/libsrc/meshing/curvedelems.cpp b/Netgen/libsrc/meshing/curvedelems.cpp deleted file mode 100644 index 50fea32f55..0000000000 --- a/Netgen/libsrc/meshing/curvedelems.cpp +++ /dev/null @@ -1,2037 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - -namespace netgen -{ - - - // computes Gaussean integration formula on (0,1) with n points - // in: Numerical algs in C (or, was it the Fortran book ?) - void ComputeGaussRule (int n, ARRAY<double> & xi, ARRAY<double> & wi) - { - xi.SetSize (n); - wi.SetSize (n); - - int m = (n+1)/2; - double p1, p2, p3; - double pp, z, z1; - for (int i = 1; i <= m; i++) - { - z = cos ( M_PI * (i - 0.25) / (n + 0.5)); - while(1) - { - p1 = 1; p2 = 0; - for (int j = 1; j <= n; j++) - { - p3 = p2; p2 = p1; - p1 = ((2 * j - 1) * z * p2 - (j - 1) * p3) / j; - } - // p1 is legendre polynomial - - pp = n * (z*p1-p2) / (z*z - 1); - z1 = z; - z = z1-p1/pp; - - if (fabs (z - z1) < 1e-14) break; - } - - xi[i-1] = 0.5 * (1 - z); - xi[n-i] = 0.5 * (1 + z); - wi[i-1] = wi[n-i] = 1.0 / ( (1 - z * z) * pp * pp); - } - } - - - -// ---------------------------------------------------------------------------- -// PolynomialBasis -// ---------------------------------------------------------------------------- - - - void PolynomialBasis :: CalcLegendrePolynomials (double x) - { - double p1 = 1.0, p2 = 0.0, p3; - - lp[0] = 1.0; - - for (int j=1; j<=order; j++) - { - p3=p2; p2=p1; - p1=((2.0*j-1.0)*(2*x-1)*p2-(j-1.0)*p3)/j; - lp[j] = p1; - } - } - - - void PolynomialBasis :: CalcDLegendrePolynomials (double x) - { - double p1 = 0., p2 = 0., p3; - - dlp[0] = 0.; - - for (int j = 1; j <= order-1; j++) - { - p3=p2; p2=p1; - p1=((2.*j-1.)*(2*lp[j-1]+(2*x-1)*p2)-(j-1.)*p3)/j; - dlp[j] = p1; - } - } - - - void PolynomialBasis :: CalcF (double x) - { - CalcLegendrePolynomials (x); - - for (int j = 0; j<=order-2; j++) - f[j] = (lp[j+2]-lp[j])/(2.0*(j+1)+1)/2.0; - } - - - void PolynomialBasis :: CalcDf (double x) - { - CalcLegendrePolynomials (x); - - for (int j = 0; j <= order-2; j++) - df[j] = lp[j+1]; - } - - - void PolynomialBasis :: CalcFDf (double x) - { - CalcLegendrePolynomials (x); - - for (int j = 0; j<=order-2; j++) - { - f[j] = (lp[j+2]-lp[j])/(2.0*(j+1)+1)/2.0; - df[j] = lp[j+1]; - } - } - - - void PolynomialBasis :: CalcDDf (double x) - { - CalcLegendrePolynomials (x); - CalcDLegendrePolynomials (x); - - for (int j = 0; j <= order-2; j++) ddf[j] = dlp[j+1]; - } - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement1D -// ---------------------------------------------------------------------------- - - - void BaseFiniteElement1D :: CalcVertexShapes () - { - vshape[0] = xi(0); - vshape[1] = 1-xi(0); - - vdshape[0] = 1; - vdshape[1] = -1; - - /* - if (edgeorient == -1) - { - Swap (vshape[0], vshape[1]); - Swap (vdshape[0], vdshape[1]); - } - */ - - } - - - void BaseFiniteElement1D :: CalcEdgeShapes () - { - b.SetOrder (edgeorder); - if (edgeorient == 1) - b.CalcFDf( 1-xi(0) ); - else - b.CalcFDf( xi(0) ); - - for (int k = 2; k <= edgeorder; k++) - { - eshape[k-2] = b.GetF(k); - edshape[k-2] = -b.GetDf(k); - } - } - - - void BaseFiniteElement1D :: CalcEdgeLaplaceShapes () - { - b.SetOrder (edgeorder); - if (edgeorient == 1) - b.CalcDDf( 1-xi(0) ); - else - b.CalcDDf( xi(0) ); - - for (int k = 2; k <= edgeorder; k++) - eddshape[k-2] = b.GetDDf(k); - } - - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement2D -// ---------------------------------------------------------------------------- - - - void BaseFiniteElement2D :: SetElementNumber (int aelnr) - { - int locmaxedgeorder = -1; - - BaseFiniteElement<2> :: SetElementNumber (aelnr); - const Element2d & elem = mesh[(SurfaceElementIndex) (elnr-1)]; - top.GetSurfaceElementEdges (elnr, &(edgenr[0]), &(edgeorient[0])); - facenr = top.GetSurfaceElementFace (elnr); - faceorient = top.GetSurfaceElementFaceOrientation (elnr); - - for (int v = 0; v < nvertices; v++) - vertexnr[v] = elem[v]; - - for (int e = 0; e < nedges; e++) - { - edgeorder[e] = curv.GetEdgeOrder (edgenr[e]-1); // 1-based - locmaxedgeorder = max2 (edgeorder[e], locmaxedgeorder); - } - - faceorder = curv.GetFaceOrder (facenr-1); // 1-based - CalcNFaceShapes (); - - if (locmaxedgeorder > maxedgeorder) - { - maxedgeorder = locmaxedgeorder; - eshape.SetSize(nedges * (maxedgeorder-1)); - edshape.SetSize(nedges * (maxedgeorder-1)); - } - - if (faceorder > maxfaceorder) - { - maxfaceorder = faceorder; - fshape.SetSize( nfaceshapes ); // number of face shape functions - fdshape.SetSize( nfaceshapes ); - fddshape.SetSize ( nfaceshapes ); - } - } - - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement3D -// ---------------------------------------------------------------------------- - - - void BaseFiniteElement3D :: SetElementNumber (int aelnr) - { - int locmaxedgeorder = -1; - int locmaxfaceorder = -1; - int v, f, e; - - BaseFiniteElement<3> :: SetElementNumber (aelnr); - Element elem = mesh[(ElementIndex) (elnr-1)]; - top.GetElementEdges (elnr, &(edgenr[0]), &(edgeorient[0])); - top.GetElementFaces (elnr, &(facenr[0]), &(faceorient[0])); - - for (v = 0; v < nvertices; v++) - vertexnr[v] = elem[v]; - - for (f = 0; f < nfaces; f++) - { - surfacenr[f] = top.GetFace2SurfaceElement (facenr[f]); - // surfaceorient[f] = top.GetSurfaceElementFaceOrientation (surfacenr[f]); - } - - for (e = 0; e < nedges; e++) - { - edgeorder[e] = curv.GetEdgeOrder (edgenr[e]-1); // 1-based - locmaxedgeorder = max (edgeorder[e], locmaxedgeorder); - } - - for (f = 0; f < nfaces; f++) - { - faceorder[f] = curv.GetFaceOrder (facenr[f]-1); // 1-based - locmaxfaceorder = max (faceorder[f], locmaxfaceorder); - } - - CalcNFaceShapes (); - - if (locmaxedgeorder > maxedgeorder) - { - maxedgeorder = locmaxedgeorder; - eshape.SetSize(nedges * (maxedgeorder-1)); - edshape.SetSize(nedges * (maxedgeorder-1)); - } - - if (locmaxfaceorder > maxfaceorder) - { - maxfaceorder = locmaxfaceorder; - fshape.SetSize( nfaces * (maxfaceorder-1) * (maxfaceorder-1)); // number of face shape functions - fdshape.SetSize( nfaces * (maxfaceorder-1) * (maxfaceorder-1)); - } - } - - - - -// ---------------------------------------------------------------------------- -// FETrig -// ---------------------------------------------------------------------------- - - - void FETrig :: SetReferencePoint (Point<2> axi) - { - BaseFiniteElement2D :: SetReferencePoint (axi); - lambda(0) = xi(0); - lambda(1) = xi(1); - lambda(2) = 1-xi(0)-xi(1); - - dlambda(0,0) = 1; dlambda(0,1) = 0; - dlambda(1,0) = 0; dlambda(1,1) = 1; - dlambda(2,0) = -1; dlambda(2,1) = -1; - } - - - void FETrig :: SetVertexSingularity (int v, int exponent) - { - int i; - if (1-lambda(v) < EPSILON) return; - - Point<3> lamold = lambda; - - Vec<2> dfac; - - double fac = pow(1-lambda(v),exponent-1); - - for (i = 0; i < 2; i++) - { - dfac(i) = -(exponent-1)*pow(1-lambda(v),exponent-2)*dlambda(v,i); - dlambda(v,i) *= exponent * pow(1-lambda(v),exponent-1); - } - - lambda(v) = 1-pow(1-lambda(v),exponent); - - for (i = 0; i < nvertices; i++) - { - if (i == v) continue; - for (int j = 0; j < 2; j++) - dlambda(i,j) = dlambda(i,j) * fac + lamold(i) * dfac(j); - - lambda(i) *= fac; - } - } - - - - void FETrig :: CalcVertexShapes () - { - for (int v = 0; v < nvertices; v++) - { - vshape[v] = lambda(v); - vdshape[v](0) = dlambda(v,0); - vdshape[v](1) = dlambda(v,1); - } - } - - - void FETrig :: CalcEdgeShapes () - { - int index = 0; - for (int e = 0; e < nedges; e++) - { - if (edgeorder[e] <= 1) continue; - - int i0 = eledge[e][0]-1; - int i1 = eledge[e][1]-1; - - double arg = lambda(i0) + lambda(i1); // = 1-lambda[i2]; - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 2; k <= edgeorder[e]; k++) - { - eshape[index] = 0; - edshape[index] = Vec<2>(0,0); - index++; - } - continue; - } - - if (edgeorient[e] == -1) Swap (i0, i1); // reverse orientation - - double xi = lambda(i1)/arg; - - b1.SetOrder (edgeorder[e]); - b1.CalcFDf (xi); - - double decay = arg; - double ddecay; - - double l0 = lambda(i0); - double l0x = dlambda(i0,0); - double l0y = dlambda(i0,1); - - double l1 = lambda(i1); - double l1x = dlambda(i1,0); - double l1y = dlambda(i1,1); - - for (int k = 2; k <= edgeorder[e]; k++) - { - ddecay = k*decay; - decay *= arg; - - eshape[index] = b1.GetF (k) * decay; - edshape[index] = Vec<2> - (b1.GetDf(k) * (l1x*arg - l1*(l0x+l1x)) * - decay / (arg * arg) + b1.GetF(k) * ddecay * (l0x+l1x), - b1.GetDf(k) * (l1y*arg - l1*(l0y+l1y)) * - decay / (arg * arg) + b1.GetF(k) * ddecay * (l0y+l1y)); - index++; - } - } - // (*testout) << "eshape = " << eshape << ", edshape = " << edshape << endl; - - - /* - index = 0; - for (int e = 0; e < nedges; e++) - { - int i0 = eledge[e][0]-1; - int i1 = eledge[e][1]-1; - - if (edgeorient[e] == -1) Swap (i0, i1); // reverse orientation - - double x = lambda(i1)-lambda(i0); - double y = 1-lambda(i0)-lambda(i1); - double fy = (1-y)*(1-y); - - // double p3 = 0, p3x = 0, p3y = 0; - // double p2 = -1, p2x = 0, p2y = 0; - // double p1 = x, p1x = 1, p1y = 0; - - double p3 = 0, p3x = 0, p3y = 0; - double p2 = -0.5, p2x = 0, p2y = 0; - double p1 = 0.5*x, p1x = 0.5, p1y = 0; - - for (int j=2; j<= edgeorder[e]; j++) - { - p3=p2; p3x = p2x; p3y = p2y; - p2=p1; p2x = p1x; p2y = p1y; - double c1 = (2.0*j-3) / j; - double c2 = (j-3.0) / j; - - p1 = c1 * x * p2 - c2 * fy * p3; - p1x = c1 * p2 + c1 * x * p2x - c2 * fy * p3x; - p1y = c1 * x * p2y - (c2 * 2 * (y-1) * p3 + c2 * fy * p3y); - eshape[index] = p1; - // edshape[index] = Vec<2> (p1x, p1y); - edshape[index](0) = -2*p1x; - edshape[index](1) = p1y-p1x; - index++; - } - - } - // (*testout) << "eshape = " << eshape << ", edshape = " << edshape << endl; - */ - } - - - void FETrig :: CalcFaceShapes () - { - int index = 0; - - int i0 = elface[0][0]-1; - int i1 = elface[0][1]-1; - int i2 = elface[0][2]-1; - - // sort lambda_i's by the corresponing vertex numbers - - if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1); - if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2); - if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2); - - double arg = lambda(i1) + lambda(i2); - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 0; k < nfaceshapes; k++) - { - fshape[index] = 0; - fdshape[index] = Vec<2>(0,0); - index++; - } - return; - } - - b1.SetOrder (faceorder); - b2.SetOrder (faceorder); - - b1.CalcFDf (lambda(i0)); - b2.CalcFDf (lambda(i2)/arg); - - double decay = 1; - double ddecay; - - double l0 = lambda(i0); - double l1 = lambda(i1); - double l2 = lambda(i2); - double dl0x = dlambda(i0,0); - double dl0y = dlambda(i0,1); - double dl1x = dlambda(i1,0); - double dl1y = dlambda(i1,1); - double dl2x = dlambda(i2,0); - double dl2y = dlambda(i2,1); - - double dargx = dl1x + dl2x; - double dargy = dl1y + dl2y; - - for (int n1 = 2; n1 < faceorder; n1++) - { - ddecay = (n1-1)*decay; - decay *= arg; - - for (int n0 = 2; n0 < faceorder-n1+2; n0++) - { - fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay; - fdshape[index] = Vec<2> - (b1.GetDf(n0) * dl0x * b2.GetF(n1) * decay + - b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx, - b1.GetDf(n0) * dl0y * b2.GetF(n1) * decay + - b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy); - index++; - } - } - } - - - - void FETrig :: CalcFaceLaplaceShapes () - { - int index = 0; - - int i0 = elface[0][0]-1; - int i1 = elface[0][1]-1; - int i2 = elface[0][2]-1; - - if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1); - if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2); - if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2); - - double arg = lambda(i1) + lambda(i2); - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 0; k < nfaceshapes; k++) - fddshape[k] = 0; - return; - } - - b1.SetOrder (faceorder); - b2.SetOrder (faceorder); - - b1.CalcFDf (lambda(i0)); - b1.CalcDDf (lambda(i0)); - b2.CalcFDf (lambda(i2)/arg); - b2.CalcDDf (lambda(i2)/arg); - - double decay = 1; - double ddecay = 0; - double dddecay; - - double l0 = lambda(i0); - double l1 = lambda(i1); - double l2 = lambda(i2); - double dl0x = dlambda(i0,0); - double dl0y = dlambda(i0,1); - double dl1x = dlambda(i1,0); - double dl1y = dlambda(i1,1); - double dl2x = dlambda(i2,0); - double dl2y = dlambda(i2,1); - - double dargx = dl1x + dl2x; - double dargy = dl1y + dl2y; - - for (int n1 = 2; n1 < faceorder; n1++) - { - dddecay = (n1-1)*ddecay; - ddecay = (n1-1)*decay; - decay *= arg; - - for (int n0 = 2; n0 < faceorder-n1+2; n0++) - { - fddshape[index] = - - // b1.GetDf(n0) * dl0x * b2.GetF(n1) * decay .... derived - - b1.GetDDf(n0) * dl0x * dl0x * b2.GetF(n1) * decay + - b1.GetDf(n0) * dl0x * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay + - b1.GetDf(n0) * dl0x * b2.GetF(n1) * ddecay * dargx + - - - // b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay ... derived - - b1.GetDf(n0) * dl0x * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay + - b1.GetF(n0) * b2.GetDDf(n1) * pow((dl2x * arg - l2 * dargx)/(arg*arg),2) * decay + - b1.GetF(n0) * b2.GetDf(n1) * (-2*dargx/arg) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay + - b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * ddecay * dargx + - - - // b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx ... derived - - b1.GetDf(n0) * dl0x * b2.GetF(n1) * ddecay * dargx + - b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * ddecay * dargx + - b1.GetF(n0) * b2.GetF(n1) * dddecay * dargx * dargx + - - - // b1.GetDf(n0) * dl0y * b2.GetF(n1) * decay ... derived - - b1.GetDDf(n0) * dl0y * dl0y * b2.GetF(n1) * decay + - b1.GetDf(n0) * dl0y * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay + - b1.GetDf(n0) * dl0y * b2.GetF(n1) * ddecay * dargy + - - - // b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay ... derived - - b1.GetDf(n0) * dl0y * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay + - b1.GetF(n0) * b2.GetDDf(n1) * pow((dl2y * arg - l2 * dargy)/(arg*arg),2) * decay + - b1.GetF(n0) * b2.GetDf(n1) * (-2*dargy/arg) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay + - b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * ddecay * dargy + - - - // b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy ... derived - - b1.GetDf(n0) * dl0y * b2.GetF(n1) * ddecay * dargy + - b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * ddecay * dargy + - b1.GetF(n0) * b2.GetF(n1) * dddecay * dargy * dargy; - - index++; - } - } - } - - - -// ---------------------------------------------------------------------------- -// FEQuad -// ---------------------------------------------------------------------------- - - - void FEQuad :: CalcVertexShapes () - { - vshape[0] = (1-xi(0)) * (1-xi(1)); - vshape[1] = ( xi(0)) * (1-xi(1)); - vshape[2] = ( xi(0)) * ( xi(1)); - vshape[3] = (1-xi(0)) * ( xi(1)); - - vdshape[0] = Vec<2> ( -(1-xi(1)), -(1-xi(0)) ); - vdshape[1] = Vec<2> ( (1-xi(1)), -( xi(0)) ); - vdshape[2] = Vec<2> ( ( xi(1)), ( xi(0)) ); - vdshape[3] = Vec<2> ( -( xi(1)), (1-xi(0)) ); - } - - - void FEQuad :: CalcEdgeShapes () - { - int index = 0; - - double arg0[4] = { xi(0), 1-xi(0), 1-xi(1), xi(1) }; - double arg1[4] = { 1-xi(1), xi(1), 1-xi(0), xi(0) }; - double darg0[4] = { 1, -1, -1, 1 }; - double darg1[4] = { -1, 1, -1, 1 }; - - for (int e = 0; e < nedges; e++) - { - b1.SetOrder (edgeorder[e]); - b1.CalcFDf (edgeorient[e] == 1 ? arg0[e] : 1-arg0[e]); - - double decay = arg1[e]; - double ddecay; - - for (int k = 2; k <= edgeorder[e]; k++, index++) - { - ddecay = k*decay; - decay *= arg1[e]; -// linear decay - eshape[index] = b1.GetF(k) * arg1[e]; - - if (e < 2) - edshape[index] = Vec<2> - (darg0[e] * edgeorient[e] * b1.GetDf(k) * arg1[e], - b1.GetF(k) * darg1[e]); - else - edshape[index] = Vec<2> - (b1.GetF(k) * darg1[e], - darg0[e] * edgeorient[e] * b1.GetDf(k) * arg1[e]); - -// exponential decay -/* eshape[index] = b1.GetF(k) * decay; - - if (e < 2) - edshape[index] = Vec<2> - (darg0[e] * edgeorient[e] * b1.GetDf(k) * decay, - b1.GetF(k) * ddecay * darg1[e]); - else - edshape[index] = Vec<2> - (b1.GetF(k) * ddecay * darg1[e], - darg0[e] * edgeorient[e] * b1.GetDf(k) * decay); -*/ - } - } - } - - - void FEQuad :: CalcFaceShapes () - { - int index = 0; - - // find index of point with smallest number - - int i0 = 0; - for (int i = 1; i < 4; i++) - if (vertexnr[elface[0][i]-1] < vertexnr[elface[0][i0]-1]) i0 = i; - - double x; - double y; - double dxx; - double dxy; - double dyx; - double dyy; - - switch (i0) - { - case 0: - x = xi(0); y = xi(1); - dxx = 1; dxy = 0; - dyx = 0; dyy = 1; - break; - case 1: - x = xi(1); y = 1-xi(0); - dxx = 0; dxy = 1; - dyx = -1; dyy = 0; - break; - case 2: - x = 1-xi(0); y = 1-xi(1); - dxx = -1; dxy = 0; - dyx = 0; dyy = -1; - break; - case 3: - x = 1-xi(1); y = xi(0); - dxx = 0; dxy =-1; - dyx = 1; dyy = 0; - break; - } - - if (vertexnr[elface[0][(i0+1) % 4]-1] > vertexnr[elface[0][(i0+3) % 4]-1]) - { - Swap (x,y); - Swap (dxx, dyx); - Swap (dxy, dyy); - } - - b1.SetOrder (faceorder); - b2.SetOrder (faceorder); - - b1.CalcFDf (x); - b2.CalcFDf (y); - - for (int n0 = 2; n0 <= faceorder; n0++) - for (int n1 = 2; n1 <= faceorder; n1++) - { - fshape[index] = b1.GetF(n0) * b2.GetF(n1); - fdshape[index] = Vec<2> (b1.GetDf(n0) * dxx * b2.GetF(n1) + b1.GetF(n0) * b2.GetDf(n1) * dyx, - b1.GetDf(n0) * dxy * b2.GetF(n1) + b1.GetF(n0) * b2.GetDf(n1) * dyy); - index++; - } - } - - - void FEQuad :: CalcFaceLaplaceShapes () - { - int index = 0; - - // find index of point with smallest number - - int i0 = 0; - for (int i = 1; i < 4; i++) - if (vertexnr[elface[0][i]-1] < vertexnr[elface[0][i0]-1]) i0 = i; - - double x; - double y; - double dxx; - double dxy; - double dyx; - double dyy; - - switch (i0) - { - case 0: - x = xi(0); y = xi(1); - dxx = 1; dxy = 0; - dyx = 0; dyy = 1; - break; - case 1: - x = xi(1); y = 1-xi(0); - dxx = 0; dxy = 1; - dyx = -1; dyy = 0; - break; - case 2: - x = 1-xi(0); y = 1-xi(1); - dxx = -1; dxy = 0; - dyx = 0; dyy = -1; - break; - case 3: - x = 1-xi(1); y = xi(0); - dxx = 0; dxy =-1; - dyx = 1; dyy = 0; - break; - } - - if (vertexnr[elface[0][(i0+1) % 4]-1] > vertexnr[elface[0][(i0+3) % 4]-1]) - { - Swap (x,y); - Swap (dxx, dyx); - Swap (dxy, dyy); - } - - b1.SetOrder (faceorder); - b2.SetOrder (faceorder); - - b1.CalcFDf (x); - b1.CalcDDf (x); - b2.CalcFDf (y); - b2.CalcDDf (y); - - for (int n0 = 2; n0 <= faceorder; n0++) - for (int n1 = 2; n1 <= faceorder; n1++) - { - fddshape[index] = - b1.GetDDf(n0) * dxx * dxx * b2.GetF(n1) + - 2* b1.GetDf(n0) * dxx * b2.GetDf(n1) * dyx + - b1.GetF(n0) * b2.GetDDf(n1) * dyx * dyx + - - b1.GetDDf(n0) * dxy * dxy * b2.GetF(n1) + - 2* b1.GetDf(n0) * dxy * b2.GetDf(n1) * dyy + - b1.GetF(n0) * b2.GetDDf(n1) * dyy * dyy; - - index++; - } - } - - - -// ---------------------------------------------------------------------------- -// FETet -// ---------------------------------------------------------------------------- - - - void FETet :: SetReferencePoint (Point<3> axi) - { - BaseFiniteElement3D :: SetReferencePoint (axi); - - lambda(0) = xi(0); - lambda(1) = xi(1); - lambda(2) = xi(2); - lambda(3) = 1-xi(0)-xi(1)-xi(2); - - dlambda(0,0) = 1; dlambda(0,1) = 0; dlambda(0,2) = 0; - dlambda(1,0) = 0; dlambda(1,1) = 1; dlambda(1,2) = 0; - dlambda(2,0) = 0; dlambda(2,1) = 0; dlambda(2,2) = 1; - dlambda(3,0) = -1; dlambda(3,1) = -1; dlambda(3,2) = -1; - } - - - void FETet :: CalcVertexShapes () - { - for (int v = 0; v < nvertices; v++) - { - vshape[v] = lambda(v); - vdshape[v](0) = dlambda(v,0); - vdshape[v](1) = dlambda(v,1); - vdshape[v](2) = dlambda(v,2); - } - } - - - void FETet :: CalcEdgeShapes () - { - int index = 0; - - for (int e = 0; e < nedges; e++) - { - int i0 = eledge[e][0]-1; - int i1 = eledge[e][1]-1; - - double arg = lambda(i0)+lambda(i1); - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 2; k <= edgeorder[e]; k++) - { - eshape[index] = 0; - edshape[index] = Vec<3>(0,0,0); - index++; - } - continue; - } - - if (edgeorient[e] == -1) Swap (i0, i1); - - double xi = lambda[i1]/arg; - - b1.SetOrder (edgeorder[e]); - b1.CalcFDf (xi); - - double decay = arg; - double ddecay; - - double l0 = lambda(i0); - double dl0x = dlambda(i0,0); - double dl0y = dlambda(i0,1); - double dl0z = dlambda(i0,2); - - double l1 = lambda(i1); - double dl1x = dlambda(i1,0); - double dl1y = dlambda(i1,1); - double dl1z = dlambda(i1,2); - - double dargx = dl0x + dl1x; - double dargy = dl0y + dl1y; - double dargz = dl0z + dl1z; - - for (int k = 2; k <= edgeorder[e]; k++) - { - ddecay = k*decay; - decay *= arg; - - eshape[index] = b1.GetF (k) * decay; - edshape[index] = Vec<3> - (b1.GetDf(k) * (dl1x*arg - l1*dargx) * - decay / (arg * arg) + b1.GetF(k) * ddecay * dargx, - b1.GetDf(k) * (dl1y*arg - l1*dargy) * - decay / (arg * arg) + b1.GetF(k) * ddecay * dargy, - b1.GetDf(k) * (dl1z*arg - l1*dargz) * - decay / (arg * arg) + b1.GetF(k) * ddecay * dargz); - - index++; - } - } - } - - - void FETet :: CalcFaceShapes () - { - int index = 0; - - for (int f = 0; f < nfaces; f++) - { - if (faceorder[f] <= 2) continue; - - int i0 = elface[f][0]-1; - int i1 = elface[f][1]-1; - int i2 = elface[f][2]-1; - - if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1); - if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2); - if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2); - - double arg = lambda(i1) + lambda(i2); - double arg2 = lambda(i0) + lambda(i1) + lambda(i2); - - if (fabs(arg) < EPSILON || fabs(arg2) < EPSILON) // division by 0 - { - for (int k = 0; k < nfaceshapes[f]; k++) - { - fshape[index] = 0; - fdshape[index] = Vec<3>(0,0,0); - index++; - } - continue; - } - - b1.SetOrder (faceorder[f]); - b2.SetOrder (faceorder[f]); - - b1.CalcFDf (lambda(i0)/arg2); - b2.CalcFDf (lambda(i2)/arg); - - double decay = 1; - double ddecay; - - double l0 = lambda(i0); - double l1 = lambda(i1); - double l2 = lambda(i2); - double dl0x = dlambda(i0,0); - double dl0y = dlambda(i0,1); - double dl0z = dlambda(i0,2); - double dl1x = dlambda(i1,0); - double dl1y = dlambda(i1,1); - double dl1z = dlambda(i1,2); - double dl2x = dlambda(i2,0); - double dl2y = dlambda(i2,1); - double dl2z = dlambda(i2,2); - - double dargx = dl1x + dl2x; - double dargy = dl1y + dl2y; - double dargz = dl1z + dl2z; - double darg2x = dl0x + dl1x + dl2x; - double darg2y = dl0y + dl1y + dl2y; - double darg2z = dl0z + dl1z + dl2z; - - for (int n1 = 2; n1 < faceorder[f]; n1++) - { - ddecay = (n1-1)*decay; - decay *= arg; - - double decay2 = arg2; - double ddecay2; - - for (int n0 = 2; n0 < faceorder[f]-n1+2; n0++) - { - ddecay2 = n0*decay2; - decay2 *= arg2; - - fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay * decay2; - fdshape[index] = Vec<3> - (b1.GetDf(n0) * (dl0x * arg2 - l0 * darg2x)/(arg2*arg2) * b2.GetF(n1) * decay * decay2 + - b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay * decay2 + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx * decay2 + - b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2x, - - b1.GetDf(n0) * (dl0y * arg2 - l0 * darg2y)/(arg2*arg2) * b2.GetF(n1) * decay * decay2 + - b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay * decay2 + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy * decay2 + - b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2y, - - b1.GetDf(n0) * (dl0z * arg2 - l0 * darg2z)/(arg2*arg2) * b2.GetF(n1) * decay * decay2 + - b1.GetF(n0) * b2.GetDf(n1) * (dl2z * arg - l2 * dargz)/(arg*arg) * decay * decay2 + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargz * decay2 + - b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2z); - - index++; - } - } - } - } - - - - -// ---------------------------------------------------------------------------- -// FEPrism -// ---------------------------------------------------------------------------- - - - void FEPrism :: SetReferencePoint (Point<3> axi) - { - BaseFiniteElement3D :: SetReferencePoint (axi); - - lambda(0) = xi(0); - lambda(1) = xi(1); - lambda(2) = 1-xi(0)-xi(1); - lambda(3) = xi(2); - - dlambda(0,0) = 1; dlambda(0,1) = 0; dlambda(0,2) = 0; - dlambda(1,0) = 0; dlambda(1,1) = 1; dlambda(1,2) = 0; - dlambda(2,0) = -1; dlambda(2,1) = -1; dlambda(2,2) = 0; - dlambda(3,0) = 0; dlambda(3,1) = 0; dlambda(3,2) = 1; - } - - - void FEPrism :: CalcVertexShapes () - { - double zcomp = 1-lambda(3); - - for (int v = 0; v < nvertices; v++) - { - if (v == 3) zcomp = 1-zcomp; - - vshape[v] = lambda(v % 3) * zcomp; - vdshape[v](0) = dlambda(v % 3,0) * zcomp; - vdshape[v](1) = dlambda(v % 3,1) * zcomp; - vdshape[v](2) = lambda(v % 3) * (-dlambda(3,2)); - - if (v >= 3) vdshape[v](2) *= -1; - } - } - - - void FEPrism :: CalcEdgeShapes () - { - int index = 0; - int e; - // triangle edge shapes - - for (e = 0; e < 6; e++) - { - int i0 = (eledge[e][0]-1) % 3; - int i1 = (eledge[e][1]-1) % 3; - - double arg = lambda[i0]+lambda[i1]; - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 2; k <= edgeorder[e]; k++) - { - eshape[index] = 0; - edshape[index] = Vec<3>(0,0,0); - index++; - } - continue; - } - - if (edgeorient[e] == -1) Swap (i0, i1); - - double xi = lambda[i1]/arg; - - b1.SetOrder (edgeorder[e]); - b1.CalcFDf (xi); - - double decay = arg; - double ddecay; - - double zarg = e < 3 ? (1-lambda(3)) : lambda(3); - double zcomp = zarg; - double dzcomp; - - double l0 = lambda(i0); - double dl0x = dlambda(i0,0); - double dl0y = dlambda(i0,1); - - double l1 = lambda(i1); - double dl1x = dlambda(i1,0); - double dl1y = dlambda(i1,1); - - double dargx = dl0x + dl1x; - double dargy = dl0y + dl1y; - - for (int k = 2; k <= edgeorder[e]; k++) - { - ddecay = k*decay; - decay *= arg; - - dzcomp = k*zcomp; - zcomp *= zarg; - - eshape[index] = b1.GetF (k) * decay * zcomp; - edshape[index] = Vec<3> - ((b1.GetDf(k) * (dl1x*arg - l1*dargx) * - decay / (arg * arg) + b1.GetF(k) * ddecay * dargx) * zcomp, - (b1.GetDf(k) * (dl1y*arg - l1*dargy) * - decay / (arg * arg) + b1.GetF(k) * ddecay * dargy) * zcomp, - b1.GetF(k) * decay * dzcomp * (e < 3 ? -1 : 1)); - index++; - } - } - - // rectangle edge shapes - - for (e = 6; e < nedges; e++) - { - int i0 = eledge[e][0]-1; - - double arg = lambda[i0]; - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 2; k <= edgeorder[e]; k++) - { - eshape[index] = 0.; - edshape[index] = Vec<3>(0.,0.,0.); - index++; - } - continue; - } - - double xi = lambda[3]; - - if (edgeorient[e] == -1) xi = 1-xi; - - b1.SetOrder (edgeorder[e]); - b1.CalcFDf (xi); - - double decay = arg; - double ddecay; - - double l0 = lambda(i0); - double l0x = dlambda(i0,0); - double l0y = dlambda(i0,1); - - for (int k = 2; k <= edgeorder[e]; k++) - { - ddecay = k*decay; - decay *= arg; - - eshape[index] = b1.GetF (k) * decay; - edshape[index] = Vec<3> - (b1.GetF(k) * ddecay * l0x, - b1.GetF(k) * ddecay * l0y, - b1.GetDf(k) * edgeorient[e] * decay); - index++; - } - } - } - - - void FEPrism :: CalcFaceShapes () - { - int index = 0; - int f; - - // triangle face parts - - for (f = 0; f < 2; f++) - { - int i0 = elface[f][0]-1; - int i1 = elface[f][1]-1; - int i2 = elface[f][2]-1; - - if (vertexnr[i1] < vertexnr[i0]) Swap (i0, i1); - if (vertexnr[i2] < vertexnr[i0]) Swap (i0, i2); - if (vertexnr[i2] < vertexnr[i1]) Swap (i1, i2); - - i0 = i0 % 3; - i1 = i1 % 3; - i2 = i2 % 3; - - double arg = lambda(i1) + lambda(i2); - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 0; k < nfaceshapes[f]; k++) - { - fshape[index] = 0; - fdshape[index] = Vec<3>(0,0,0); - index++; - } - continue; - } - - b1.SetOrder (faceorder[f]); - b2.SetOrder (faceorder[f]); - - b1.CalcFDf (lambda(i0)); - b2.CalcFDf (lambda(i2)/arg); - - double decay = 1; - double ddecay; - - double l0 = lambda(i0); - double l1 = lambda(i1); - double l2 = lambda(i2); - double dl0x = dlambda(i0,0); - double dl0y = dlambda(i0,1); - double dl0z = dlambda(i0,2); - double dl1x = dlambda(i1,0); - double dl1y = dlambda(i1,1); - double dl1z = dlambda(i1,2); - double dl2x = dlambda(i2,0); - double dl2y = dlambda(i2,1); - double dl2z = dlambda(i2,2); - - double dargx = dl1x + dl2x; - double dargy = dl1y + dl2y; - double dargz = dl1z + dl2z; - - double arg2 = f == 0 ? 1-xi(2) : xi(2); - double darg2z = f == 0 ? -1 : 1; - - for (int n1 = 2; n1 < faceorder[f]; n1++) - { - ddecay = (n1-1)*decay; - decay *= arg; - - double decay2 = arg2; - double ddecay2; - - for (int n0 = 2; n0 < faceorder[f]-n1+2; n0++) - { - ddecay2 = n0*decay2; - decay2 *= arg2; - - fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay * decay2; - fdshape[index] = Vec<3> - (b1.GetDf(n0) * dl0x * b2.GetF(n1) * decay * decay2 + - b1.GetF(n0) * b2.GetDf(n1) * (dl2x * arg - l2 * dargx)/(arg*arg) * decay * decay2 + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx * decay2, - - b1.GetDf(n0) * dl0y * b2.GetF(n1) * decay * decay2 + - b1.GetF(n0) * b2.GetDf(n1) * (dl2y * arg - l2 * dargy)/(arg*arg) * decay * decay2 + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy * decay2, - - b1.GetDf(n0) * dl0z * b2.GetF(n1) * decay * decay2 + - b1.GetF(n0) * b2.GetDf(n1) * (dl2z * arg - l2 * dargz)/(arg*arg) * decay * decay2 + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargz * decay2 + - b1.GetF(n0) * b2.GetF(n1) * decay * ddecay2 * darg2z); - - index++; - } - } - } - - - // quad parts - - for (f = 2; f < nfaces; f++) - { - // find index of point with smallest number - - int i, i0 = 0; - for (i = 1; i < 4; i++) - if (vertexnr[elface[f][i]-1] < vertexnr[elface[f][i0]-1]) i0 = i; - - double arg = 0; - double dargx = 0; - double dargy = 0; - double dargz = 0; - for (i = 0; i < 4; i++) - { - arg += lambda((elface[f][i]-1) % 3)/2.0; - dargx += dlambda((elface[f][i]-1) % 3,0)/2.0; - dargy += dlambda((elface[f][i]-1) % 3,1)/2.0; - dargz += dlambda((elface[f][i]-1) % 3,2)/2.0; - } - - if (fabs(arg) < EPSILON) // division by 0 - { - for (int k = 0; k < nfaceshapes[f]; k++) - { - fshape[index] = 0; - fdshape[index] = Vec<3>(0,0,0); - index++; - } - continue; - } - - int i1 = (i0+3) % 4; - int j = (elface[f][i0]-1) % 3; - - double lam = lambda(j)/arg; - double dlamx = (dlambda(j,0)*arg-lambda(j)*dargx)/(arg*arg); - double dlamy = (dlambda(j,1)*arg-lambda(j)*dargy)/(arg*arg); - double dlamz = (dlambda(j,2)*arg-lambda(j)*dargz)/(arg*arg); - - double x; - double z; - double dxx; - double dxy; - double dxz; - double dzx; - double dzy; - double dzz; - - int ratvar; - /* - switch (i0) - { - case 0: - x = xi(2); z = lam; - - dxx = 0; dxy = 0; dxz = 1; - dzx = dlamx; dzy = dlamy; dzz = dlamz; - ratvar = 1; - break; - case 1: - x = 1-lam; z = xi(2); - dxx = -dlamx; dxy = -dlamy; dxz = -dlamz; - dzx = 0; dzy = 0; dzz = 1; - ratvar = 0; - break; - case 2: - x = 1-xi(2); z = 1-lam; - dxx = 0; dxy = 0; dxz = -1; - dzx = -dlamx; dzy = -dlamy; dzz = -dlamz; - ratvar = 1; - break; - case 3: - x = lam; z = 1-xi(2); - dxx = dlamx; dxy = dlamy; dxz = dlamz; - dzx = 0; dzy = 0; dzz = -1; - ratvar = 0; - break; - } - */ - - ratvar = 0; - x = 1-lam; - dxx = -dlamx; dxy = -dlamy; dxz = -dlamz; - if (i0 == 0 || i0 == 1) - { - z = xi(2); - dzx = 0; dzy = 0; dzz = 1; - } - else - { - z = 1-xi(2); - dzx = 0; dzy = 0; dzz = -1; - } - - int ix = i0 ^ 1; - int iz = 3-i0; - - if (vertexnr[elface[f][ix]-1] > vertexnr[elface[f][iz]-1]) - { - Swap (x,z); - Swap (dxx, dzx); - Swap (dxy, dzy); - Swap (dxz, dzz); - ratvar = 1-ratvar; - } - - b1.SetOrder (faceorder[f]); - b2.SetOrder (faceorder[f]); - - b1.CalcFDf (x); - b2.CalcFDf (z); - - double decay = arg; - double ddecay; - - for (int n0 = 2; n0 <= faceorder[f]; n0++) - { - ddecay = n0*decay; - decay *= arg; - - if (ratvar == 1) decay = arg; - - for (int n1 = 2; n1 <= faceorder[f]; n1++) - { - if (ratvar == 1) - { - ddecay = n1*decay; - decay *= arg; - } - - fshape[index] = b1.GetF(n0) * b2.GetF(n1) * decay; - fdshape[index] = Vec<3> - (b1.GetDf(n0) * dxx * b2.GetF(n1) * decay + - b1.GetF(n0) * b2.GetDf(n1) * dzx * decay + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargx, - - b1.GetDf(n0) * dxy * b2.GetF(n1) * decay + - b1.GetF(n0) * b2.GetDf(n1) * dzy * decay + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargy, - - b1.GetDf(n0) * dxz * b2.GetF(n1) * decay + - b1.GetF(n0) * b2.GetDf(n1) * dzz * decay + - b1.GetF(n0) * b2.GetF(n1) * ddecay * dargz); - - index++; - } - } - } - } - - - -// ---------------------------------------------------------------------------- -// FEPyramid -// ---------------------------------------------------------------------------- - - - void FEPyramid :: SetReferencePoint (Point<3> axi) - { - BaseFiniteElement3D :: SetReferencePoint (axi); - } - - - void FEPyramid :: CalcVertexShapes () - { - double x = xi(0); - double y = xi(1); - double z = xi(2); - - if (z == 1.) z = 1-1e-10; - vshape[0] = (1-z-x)*(1-z-y) / (1-z); - vshape[1] = x*(1-z-y) / (1-z); - vshape[2] = x*y / (1-z); - vshape[3] = (1-z-x)*y / (1-z); - vshape[4] = z; - - double z1 = 1-z; - double z2 = z1*z1; - - vdshape[0] = Vec<3>( -(z1-y)/z1, -(z1-x)/z1, ((x+y+2*z-2)*z1+(z1-y)*(z1-x))/z2 ); - vdshape[1] = Vec<3>( (z1-y)/z1, -x/z1, (-x*z1+x*(z1-y))/z2 ); - vdshape[2] = Vec<3>( y/z1, x/z1, x*y/z2 ); - vdshape[3] = Vec<3>( -y/z1, (z1-x)/z1, (-y*z1+y*(z1-x))/z2 ); - vdshape[4] = Vec<3>( 0, 0, 1 ); - } - - - void FEPyramid :: CalcEdgeShapes () - { - int index = 0; - - for (int e = 0; e < GetNEdges(); e++) - { - for (int k = 2; k <= edgeorder[e]; k++) - { - eshape[index] = 0; - edshape[index] = Vec<3>(0,0,0); - index++; - } - } - } - - - void FEPyramid :: CalcFaceShapes () - { - int index = 0; - - for (int f = 0; f < GetNFaces(); f++) - { - for (int k = 0; k < nfaceshapes[f]; k++) - { - fshape[index] = 0; - fdshape[index] = Vec<3>(0,0,0); - index++; - } - } - } - - - - - -// ---------------------------------------------------------------------------- -// FEHex -// ---------------------------------------------------------------------------- - - - void FEHex :: SetReferencePoint (Point<3> axi) - { - BaseFiniteElement3D :: SetReferencePoint (axi); - } - - - void FEHex :: CalcVertexShapes () - { - double x = xi(0); - double y = xi(1); - double z = xi(2); - - vshape[0] = (1-x)*(1-y)*(1-z); - vshape[1] = x *(1-y)*(1-z); - vshape[2] = x * y *(1-z); - vshape[3] = (1-x)* y *(1-z); - vshape[4] = (1-x)*(1-y)* z; - vshape[5] = x *(1-y)* z; - vshape[6] = x * y * z; - vshape[7] = (1-x)* y * z; - - vdshape[0] = Vec<3>(-(1-y)*(1-z), -(1-x)*(1-z), -(1-x)*(1-y)); - vdshape[1] = Vec<3>( (1-y)*(1-z), -x *(1-z), -x *(1-y)); - vdshape[2] = Vec<3>( y *(1-z), x *(1-z), -x * y); - vdshape[3] = Vec<3>( -y *(1-z), (1-x)*(1-z), -(1-x)*y); - vdshape[4] = Vec<3>(-(1-y)* z, -(1-x)* z, (1-x)*(1-y)); - vdshape[5] = Vec<3>( (1-y)* z, -x * z, x *(1-y)); - vdshape[6] = Vec<3>( y * z, x * z, x * y); - vdshape[7] = Vec<3>( -y * z, (1-x)* z, (1-x)*y); - - } - - - void FEHex :: CalcEdgeShapes () - { - int index = 0; - - for (int e = 0; e < GetNEdges(); e++) - { - for (int k = 2; k <= edgeorder[e]; k++) - { - eshape[index] = 0; - edshape[index] = Vec<3>(0,0,0); - index++; - } - } - } - - - void FEHex :: CalcFaceShapes () - { - int index = 0; - - for (int f = 0; f < GetNFaces(); f++) - { - for (int k = 0; k < nfaceshapes[f]; k++) - { - fshape[index] = 0; - fdshape[index] = Vec<3>(0,0,0); - index++; - } - } - } - - - - - - - - - - int CurvedElements :: IsSurfaceElementCurved (int elnr) const - { - if (mesh.coarsemesh) - { - const HPRefElement & hpref_el = - (*mesh.hpelements) [ mesh[(SurfaceElementIndex) elnr].hp_elnr]; - - return mesh.coarsemesh->GetCurvedElements().IsSurfaceElementCurved (hpref_el.coarse_elnr); - } - - - - - Element2d elem = mesh[(SurfaceElementIndex) elnr]; - - switch (elem.GetType()) - { - case TRIG: - { - FETrig fe2d(*this); - fe2d.SetElementNumber (elnr+1); - return (fe2d.IsCurved()); - break; - } - - case QUAD: - { - FEQuad fe2d(*this); - fe2d.SetElementNumber (elnr+1); - return (fe2d.IsCurved()); - break; - } - - } - return 0; - } - - - - int CurvedElements :: IsElementCurved (int elnr) const - { - if (mesh.coarsemesh) - { - const HPRefElement & hpref_el = - (*mesh.hpelements) [ mesh[(ElementIndex) elnr].hp_elnr]; - - return mesh.coarsemesh->GetCurvedElements().IsElementCurved (hpref_el.coarse_elnr); - } - - - - Element elem = mesh[(ElementIndex) elnr]; - - switch (elem.GetType()) - { - case TET: - { - FETet fe3d(*this); - fe3d.SetElementNumber (elnr+1); - return (fe3d.IsCurved()); - break; - } - - case PRISM: - { - FEPrism fe3d(*this); - fe3d.SetElementNumber (elnr+1); - return (fe3d.IsCurved()); - break; - } - - case PYRAMID: - { - FEPyramid fe3d(*this); - fe3d.SetElementNumber (elnr+1); - return (fe3d.IsCurved()); - break; - } - - case HEX: - { - FEHex fe3d(*this); - fe3d.SetElementNumber (elnr+1); - return (fe3d.IsCurved()); - break; - } - - } - - return 0; - } - - - void CurvedElements :: CalcSegmentTransformation (double xi, int segnr, - Point<3> * x, Vec<3> * dxdxi) - { - FESegm segm (*this); - segm.SetElementNumber (segnr+1); - segm.SetReferencePoint (Point<1>(xi)); - -// segm.CalcVertexShapes (x != NULL, dxdxi != NULL); - segm.CalcVertexShapes (); - - if (x) - { - (*x) = Point<3>(0,0,0); - for (int v = 0; v < 2; v++) - (*x) = (*x) + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v)); - } - - if (dxdxi) - { - (*dxdxi) = Vec<3>(0,0,0); - for (int v = 0; v < 2; v++) - (*dxdxi) = (*dxdxi) + segm.GetVertexDShape(v) * mesh.Point(segm.GetVertexNr(v)); - } - - if (segm.GetEdgeOrder() > 1) - { -// segm.CalcEdgeShapes (x != NULL, dxdxi != NULL); - segm.CalcEdgeShapes (); - - if (x) - { - int gindex = edgecoeffsindex[segm.GetEdgeNr()-1]; - for (int k = 2; k <= segm.GetEdgeOrder(); k++, gindex++) - (*x) = (*x) + segm.GetEdgeShape(k-2) * edgecoeffs[gindex]; - } - - if (dxdxi) - { - int gindex = edgecoeffsindex[segm.GetEdgeNr()-1]; - for (int k = 2; k <= segm.GetEdgeOrder(); k++, gindex++) - (*dxdxi) = (*dxdxi) + segm.GetEdgeDShape(k-2) * edgecoeffs[gindex]; - } - } - } - - - - void CurvedElements :: CalcSurfaceTransformation (Point<2> xi, int elnr, - Point<3> * x, Mat<3,2> * dxdxi) - { - - if (mesh.coarsemesh) - { - const HPRefElement & hpref_el = - (*mesh.hpelements) [ mesh[(SurfaceElementIndex) elnr].hp_elnr]; - - // xi umrechnen - double lami[4]; - switch (mesh[(SurfaceElementIndex) elnr].GetType()) - { - case TRIG: - { - lami[0] = xi(0); - lami[1] = xi(1); - lami[2] = 1-xi(0)-xi(1); - lami[3] = 0; - break; - } - case QUAD: - { - lami[0] = (1-xi(0))*(1-xi(1)); - lami[1] = xi(0) * (1-xi(1)); - lami[2] = xi(0) * xi(1); - lami[3] = (1-xi(0))*xi(1); - break; - } - } - Point<2> coarse_xi(0,0); - for (int i = 0; i < 4; i++) - { - coarse_xi(0) += hpref_el.param[i][0] * lami[i]; - coarse_xi(1) += hpref_el.param[i][1] * lami[i]; - } - mesh.coarsemesh->GetCurvedElements().CalcSurfaceTransformation (coarse_xi, hpref_el.coarse_elnr, x, dxdxi); - - return; - } - - - - - const Element2d & elem = mesh[(SurfaceElementIndex) elnr]; - - BaseFiniteElement2D * fe2d; - - // char locmem[max2(sizeof(FEQuad), sizeof(FETrig))]; - char locmemtrig[sizeof(FETrig)]; - char locmemquad[sizeof(FEQuad)]; - switch (elem.GetType()) - { - case TRIG: fe2d = new (locmemtrig) FETrig (*this); break; - case QUAD: fe2d = new (locmemquad) FEQuad (*this); break; - } - - fe2d->SetElementNumber (elnr+1); - fe2d->SetReferencePoint (xi); - - /* - for (int v = 0; v < fe2d->GetNVertices(); v++) - { - // if (fe2d->GetVertexNr(v) == 1) - fe2d->SetVertexSingularity (v, 2); - } - */ - /* - int imin = 0, imax = 0; - if (fe2d->GetVertexNr(1) < fe2d->GetVertexNr(0)) imin = 1; - if (fe2d->GetVertexNr(2) < fe2d->GetVertexNr(imin)) imin = 2; - if (fe2d->GetVertexNr(1) > fe2d->GetVertexNr(0)) imax = 1; - if (fe2d->GetVertexNr(2) > fe2d->GetVertexNr(imax)) imax = 2; - - fe2d->SetVertexSingularity (imin, 3); - fe2d->SetVertexSingularity (3-imin-imax, 3); - fe2d->SetVertexSingularity (imax, 3); - */ - fe2d->CalcVertexShapes (); - - if (x) - { - (*x) = Point<3>(0,0,0); - for (int v = 0; v < fe2d->GetNVertices(); v++) - (*x) = (*x) + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v)); - } - - if (dxdxi) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - (*dxdxi)(i,j) = 0; - - for (int v = 0; v < elem.GetNV(); v++) - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - (*dxdxi)(i,j) += fe2d->GetVertexDShape(v)(j) * mesh.Point(fe2d->GetVertexNr(v)).X(i+1); - } - - if (IsHighOrder()) - { -// fe2d->CalcEdgeShapes (x != NULL, dxdxi != NULL); - fe2d->CalcEdgeShapes (); - if (x) - { - int index = 0; - for (int e = 0; e < fe2d->GetNEdges(); e++) - { - int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1]; - - for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++) - (*x) = (*x) + fe2d->GetEdgeShape(index) * edgecoeffs[gindex]; - } - } - - if (dxdxi) - { - int index = 0; - for (int e = 0; e < fe2d->GetNEdges(); e++) - { - int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1]; - for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++) - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - (*dxdxi)(i,j) += fe2d->GetEdgeDShape(index)(j) * edgecoeffs[gindex](i); - } - } - - if (mesh.GetDimension() == 3) - { -// fe2d->CalcFaceShapes (x != NULL, dxdxi != NULL); - fe2d->CalcFaceShapes (); - - if (x) - { - int gindex = facecoeffsindex[fe2d->GetFaceNr()-1]; - for (int index = 0; index < fe2d->GetNFaceShapes(); index++, gindex++) - { - (*x) = (*x) + fe2d->GetFaceShape(index) * facecoeffs[gindex]; - } - } - - if (dxdxi) - { - int gindex = facecoeffsindex[fe2d->GetFaceNr()-1]; - for (int index = 0; index < fe2d->GetNFaceShapes(); index++, gindex++) - for (int i = 0; i < 3; i++) - for (int j = 0; j < 2; j++) - (*dxdxi)(i,j) += fe2d->GetFaceDShape(index)(j) * facecoeffs[gindex](i); - } - } - } - - fe2d -> ~BaseFiniteElement2D(); - } - - - - - void CurvedElements :: CalcElementTransformation (Point<3> xi, int elnr, - Point<3> * x, Mat<3,3> * dxdxi) - { - - if (mesh.coarsemesh) - { - const HPRefElement & hpref_el = - (*mesh.hpelements) [ mesh[(ElementIndex) elnr].hp_elnr]; - - - double lami[8]; - FlatVector vlami(8, lami); - vlami = 0; - mesh[(ElementIndex) elnr] . GetShapeNew (xi, vlami); - - Point<3> coarse_xi(0,0,0); - for (int i = 0; i < 8; i++) - for (int l = 0; l < 3; l++) - coarse_xi(l) += hpref_el.param[i][l] * lami[i]; - - Mat<3,3> trans, dxdxic; - if (dxdxi) - { - MatrixFixWidth<3> dlami(8); - dlami = 0; - mesh[(ElementIndex) elnr] . GetDShapeNew (xi, dlami); - - trans = 0; - for (int k = 0; k < 3; k++) - for (int l = 0; l < 3; l++) - { - double sum = 0; - for (int i = 0; i < 8; i++) - sum += hpref_el.param[i][l] * dlami(i, k); - trans(l,k) = sum; - } - } - - mesh.coarsemesh->GetCurvedElements().CalcElementTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic); - - if (dxdxi) - *dxdxi = dxdxic * trans; - return; - } - - - - - - - - - - Element elem = mesh[(ElementIndex) elnr]; - BaseFiniteElement3D * fe3d; - - // char locmem[max2(sizeof(FETet), sizeof(FEPrism))]; - char locmemtet[sizeof(FETet)]; - char locmemprism[sizeof(FEPrism)]; - char locmempyramid[sizeof(FEPyramid)]; - char locmemhex[sizeof(FEHex)]; - switch (elem.GetType()) - { - case TET: fe3d = new (locmemtet) FETet (*this); break; - case PRISM: fe3d = new (locmemprism) FEPrism (*this); break; - case PYRAMID: fe3d = new (locmempyramid) FEPyramid (*this); break; - case HEX: fe3d = new (locmemhex) FEHex (*this); break; - } - - fe3d->SetElementNumber (elnr+1); - fe3d->SetReferencePoint (xi); - - fe3d->CalcVertexShapes (); -// fe3d->CalcVertexShapes (x != NULL, dxdxi != NULL); - - if (x) - { - (*x) = Point<3>(0,0,0); - for (int v = 0; v < fe3d->GetNVertices(); v++) - (*x) += fe3d->GetVertexShape(v) * Vec<3> (mesh.Point(fe3d->GetVertexNr(v))); - } - - if (dxdxi) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - (*dxdxi)(i,j) = 0; - - for (int v = 0; v < fe3d->GetNVertices(); v++) - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - (*dxdxi)(i,j) += fe3d->GetVertexDShape(v)(j) * mesh.Point(fe3d->GetVertexNr(v)).X(i+1); - } - - if (IsHighOrder()) - { -// fe3d->CalcEdgeShapes (x != NULL, dxdxi != NULL); - fe3d->CalcEdgeShapes (); - - if (x) - { - int index = 0; - for (int e = 0; e < fe3d->GetNEdges(); e++) - { - int gindex = edgecoeffsindex[fe3d->GetEdgeNr(e)-1]; - for (int k = 2; k <= fe3d->GetEdgeOrder(e); k++, index++, gindex++) - (*x) += fe3d->GetEdgeShape(index) * edgecoeffs[gindex]; - } - } - - if (dxdxi) - { - int index = 0; - for (int e = 0; e < fe3d->GetNEdges(); e++) - { - int gindex = edgecoeffsindex[fe3d->GetEdgeNr(e)-1]; - for (int k = 2; k <= fe3d->GetEdgeOrder(e); k++, index++, gindex++) - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - (*dxdxi)(i,j) += fe3d->GetEdgeDShape(index)(j) * edgecoeffs[gindex](i); - } - } - - if (mesh.GetDimension() == 3) - { - fe3d->CalcFaceShapes (); -// fe3d->CalcFaceShapes (x != NULL, dxdxi != NULL); - - if (x) - { - int index = 0; - for (int f = 0; f < fe3d->GetNFaces(); f++) - { - int gindex = facecoeffsindex[fe3d->GetFaceNr(f)-1]; - for (int k = 0; k < fe3d->GetNFaceShapes(f); k++, index++, gindex++) - (*x) += fe3d->GetFaceShape(index) * facecoeffs[gindex]; - } - } - - if (dxdxi) - { - int index = 0; - for (int f = 0; f < fe3d->GetNFaces(); f++) - { - int gindex = facecoeffsindex[fe3d->GetFaceNr(f)-1]; - for (int k = 0; k < fe3d->GetNFaceShapes(f); k++, index++, gindex++) - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - (*dxdxi)(i,j) += fe3d->GetFaceDShape(index)(j) * facecoeffs[gindex](i); - } - } - } - } - - fe3d -> ~BaseFiniteElement3D(); - } - - -} // namespace netgen - - diff --git a/Netgen/libsrc/meshing/curvedelems.hpp b/Netgen/libsrc/meshing/curvedelems.hpp deleted file mode 100644 index dd11eef051..0000000000 --- a/Netgen/libsrc/meshing/curvedelems.hpp +++ /dev/null @@ -1,837 +0,0 @@ -#ifndef CURVEDELEMS -#define CURVEDELEMS - -/**************************************************************************/ -/* File: curvedelems.hpp */ -/* Author: Robert Gaisbauer */ -/* Date: 27. Sep. 02 (second version: 30. Jan. 03) */ -/**************************************************************************/ - -#include "bisect.hpp" -#include <iostream> - -#define EPSILON 1e-20 - - - -void ComputeGaussRule (int n, ARRAY<double> & xi, ARRAY<double> & wi); - - - - - -// ---------------------------------------------------------------------------- -// CurvedElements -// ---------------------------------------------------------------------------- - -class CurvedElements -{ - const Mesh & mesh; - const MeshTopology & top; - - bool isHighOrder; - int nvisualsubsecs; - int nIntegrationPoints; - - ARRAY<int> edgeorder; - ARRAY<int> faceorder; - - /* - - ARRAY< Vec<3> > edgecoeffs; - ARRAY< Vec<3> > facecoeffs; - - ARRAY<int> edgecoeffsindex; - ARRAY<int> facecoeffsindex; - - */ - - inline Vec<3> GetEdgeCoeff (int edgenr, int k); - inline Vec<3> GetFaceCoeff (int facenr, int k); - - - void CalcSegmentTransformation (double xi, int segnr, - Point<3> * x = NULL, Vec<3> * dxdxi = NULL); - - void CalcSurfaceTransformation (Point<2> xi, int elnr, - Point<3> * x = NULL, Mat<3,2> * dxdxi = NULL); - - void CalcElementTransformation (Point<3> xi, int elnr, - Point<3> * x = NULL, Mat<3,3> * dxdxi = NULL); - -public: - - Refinement * refinement; - - ARRAY< Vec<3> > edgecoeffs; - ARRAY< Vec<3> > facecoeffs; - - ARRAY<int> edgecoeffsindex; - ARRAY<int> facecoeffsindex; - - - - - - CurvedElements (const Mesh & amesh); - ~CurvedElements(); - - bool IsHighOrder() const - { return isHighOrder; }; - void SetHighOrder () { isHighOrder = 1; } - - - int GetNVisualSubsecs() const - { return nvisualsubsecs; }; - - const class Mesh & GetMesh() const - { return mesh; }; - - void BuildCurvedElements(Refinement * ref, int polydeg); - - int GetEdgeOrder (int edgenr) const - { return edgeorder[edgenr]; }; - - int GetFaceOrder (int facenr) const - { return faceorder[facenr]; }; - - int IsEdgeCurved (int edgenr) const; - - int IsFaceCurved (int facenr) const; - - int IsSurfaceElementCurved (int elnr) const; - - int IsElementCurved (int elnr) const; - - - void CalcSegmentTransformation (double xi, int segnr, - Point<3> & x) - { CalcSegmentTransformation (xi, segnr, &x, NULL); }; - - void CalcSegmentTransformation (double xi, int segnr, - Vec<3> & dxdxi) - { CalcSegmentTransformation (xi, segnr, NULL, &dxdxi); }; - - void CalcSegmentTransformation (double xi, int segnr, - Point<3> & x, Vec<3> & dxdxi) - { CalcSegmentTransformation (xi, segnr, &x, &dxdxi); }; - - - void CalcSurfaceTransformation (Point<2> & xi, int elnr, - Point<3> & x) - { CalcSurfaceTransformation (xi, elnr, &x, NULL); }; - - void CalcSurfaceTransformation (Point<2> & xi, int elnr, - Mat<3,2> & dxdxi) - { CalcSurfaceTransformation (xi, elnr, NULL, &dxdxi); }; - - void CalcSurfaceTransformation (Point<2> & xi, int elnr, - Point<3> & x, Mat<3,2> & dxdxi) - { CalcSurfaceTransformation (xi, elnr, &x, &dxdxi); }; - - - void CalcElementTransformation (Point<3> xi, int elnr, - Point<3> & x) - { CalcElementTransformation (xi, elnr, &x, NULL); }; - - void CalcElementTransformation (Point<3> xi, int elnr, - Mat<3,3> & dxdxi) - { CalcElementTransformation (xi, elnr, NULL, &dxdxi); }; - - void CalcElementTransformation (Point<3> xi, int elnr, - Point<3> & x, Mat<3,3> & dxdxi) - { CalcElementTransformation (xi, elnr, &x, &dxdxi); }; - -}; - - - -// ---------------------------------------------------------------------------- -// PolynomialBasis -// ---------------------------------------------------------------------------- - -class PolynomialBasis -{ - int order; - int maxorder; - ArrayMem<double,20> f; - ArrayMem<double,20> df; - ArrayMem<double,20> ddf; - - ArrayMem<double,20> lp; - ArrayMem<double,20> dlp; - - inline void CalcLegendrePolynomials (double x); - inline void CalcDLegendrePolynomials (double x); - -public: - - PolynomialBasis () - { maxorder = -1; }; - - ~PolynomialBasis () - {}; - - void SetOrder (int aorder) - { - order = aorder; - if (order > maxorder) - { - maxorder = order; - f.SetSize(order-1); - df.SetSize(order-1); - ddf.SetSize(order-1); - lp.SetSize(order+1); - dlp.SetSize(order); - }; - }; - - inline void CalcF (double x); - inline void CalcDf (double x); - inline void CalcDDf (double x); - - inline void CalcFDf (double x); - - double GetF (int p) { return f[p-2]; }; - double GetDf (int p) { return df[p-2]; }; - double GetDDf (int p) { return ddf[p-2]; }; -}; - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement -// ---------------------------------------------------------------------------- - -template <int DIM> -class BaseFiniteElement -{ -protected: - - Point<DIM> xi; - int elnr; - const CurvedElements & curv; - const Mesh & mesh; - const MeshTopology & top; - -public: - - BaseFiniteElement(const CurvedElements & acurv) - : curv(acurv), mesh(curv.GetMesh()), top(mesh.GetTopology()) - {}; - - virtual ~BaseFiniteElement() - {}; - - void SetElementNumber (int aelnr) - { elnr = aelnr; }; // 1-based arrays in netgen - - virtual void SetReferencePoint (Point<DIM> axi) - { xi = axi; }; -}; - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement1D -// ---------------------------------------------------------------------------- - -class BaseFiniteElement1D : public BaseFiniteElement<1> -{ -protected: - PolynomialBasis b; - - int vertexnr[2]; - int edgenr; - int edgeorient; - int edgeorder; - - int maxedgeorder; - - double vshape[2]; - double vdshape[2]; - ArrayMem<double,20> eshape; - ArrayMem<double,20> edshape; - ArrayMem<double,20> eddshape; - -public: - - BaseFiniteElement1D (const CurvedElements & acurv) : BaseFiniteElement<1>(acurv) - { maxedgeorder = 1; }; - - virtual ~BaseFiniteElement1D() - {}; - - int GetVertexNr (int v) - { return vertexnr[v]; }; - - int GetEdgeNr () - { return edgenr; }; - - int GetEdgeOrder () - { return edgeorder; }; - - int GetEdgeOrientation () - { return edgeorient; }; - - void CalcVertexShapes(); - void CalcEdgeShapes(); - void CalcEdgeLaplaceShapes(); - - double GetVertexShape (int v) - { return vshape[v]; }; - - double GetEdgeShape (int index) - { return eshape[index]; }; - - double GetVertexDShape (int v) - { return vdshape[v]; }; - - double GetEdgeDShape (int index) - { return edshape[index]; }; - - double GetEdgeLaplaceShape (int index) - { return eddshape[index]; }; - -}; - - - - -// ---------------------------------------------------------------------------- -// FESegm -// ---------------------------------------------------------------------------- - -class FESegm : public BaseFiniteElement1D -{ - -public: - - FESegm(const CurvedElements & acurv) : BaseFiniteElement1D(acurv) - {}; - - virtual ~FESegm() - {}; - - void SetElementNumber (int aelnr) - { - BaseFiniteElement<1> :: SetElementNumber (aelnr); - Segment s = mesh.LineSegment(elnr); - vertexnr[0] = s.p1; - vertexnr[1] = s.p2; - edgenr = top.GetSegmentEdge(elnr); - edgeorient = top.GetSegmentEdgeOrientation(elnr); - edgeorder = curv.GetEdgeOrder(edgenr-1); // 1-based arrays in netgen - - if (edgeorder > maxedgeorder) - { - maxedgeorder = edgeorder; - eshape.SetSize(maxedgeorder-1); - edshape.SetSize(maxedgeorder-1); - eddshape.SetSize(maxedgeorder-1); - } - }; - -}; - - - -// ---------------------------------------------------------------------------- -// FEEdge -// ---------------------------------------------------------------------------- - -class FEEdge : public BaseFiniteElement1D -{ - -public: - - FEEdge(const CurvedElements & acurv) : BaseFiniteElement1D(acurv) - {}; - - virtual ~FEEdge() - {}; - - void SetElementNumber (int aelnr) - { - BaseFiniteElement<1> :: SetElementNumber (aelnr); - top.GetEdgeVertices (elnr, vertexnr[0], vertexnr[1]); - edgenr = elnr; - edgeorient = 1; - edgeorder = curv.GetEdgeOrder(edgenr-1); // 1-based arrays in netgen - - if (edgeorder > maxedgeorder) - { - maxedgeorder = edgeorder; - eshape.SetSize(maxedgeorder-1); - edshape.SetSize(maxedgeorder-1); - eddshape.SetSize(maxedgeorder-1); - } - }; - -}; - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement2D -// ---------------------------------------------------------------------------- - -class BaseFiniteElement2D : public BaseFiniteElement<2> -{ -protected: - - int nvertices; - int nedges; - - int vertexnr[4]; - int edgenr[4]; - int edgeorient[4]; - int edgeorder[4]; - int facenr; - int faceorient; - int faceorder; - - int nfaceshapes; - - int maxedgeorder; - int maxfaceorder; - - PolynomialBasis b1, b2; - - double vshape[4]; - Vec<2> vdshape[4]; - ArrayMem<double,80> eshape; - ArrayMem< Vec<2>,80> edshape; - ArrayMem<double,400> fshape; - ArrayMem<Vec<2>,400> fdshape; - ArrayMem<double,400> fddshape; - - virtual void CalcNFaceShapes () = 0; - -public: - - BaseFiniteElement2D (const CurvedElements & acurv) : BaseFiniteElement<2>(acurv) - { maxedgeorder = maxfaceorder = -1; }; - - virtual ~BaseFiniteElement2D() - {}; - - void SetElementNumber (int aelnr); - - virtual void SetVertexSingularity (int v, int exponent) = 0; - - int GetVertexNr (int v) - { return vertexnr[v]; }; - - int GetEdgeNr (int e) - { return edgenr[e]; }; - - int GetFaceNr () - { return facenr; }; - - int GetEdgeOrder (int e) - { return edgeorder[e]; }; - - int GetFaceOrder () - { return faceorder; } - - int GetNVertices () - { return nvertices; }; - - int GetNEdges () - { return nedges; }; - - int GetNFaceShapes () - { return nfaceshapes; }; - - int IsCurved () - { - bool iscurved = 0; - int e; - - for (e = 0; e < GetNEdges(); e++) - iscurved = iscurved || (GetEdgeOrder(e) > 1); - - return iscurved || (GetFaceOrder() > 1); - } - - virtual void CalcVertexShapes() = 0; - virtual void CalcEdgeShapes() = 0; - virtual void CalcFaceShapes() = 0; - - virtual void CalcFaceLaplaceShapes() = 0; - - double GetVertexShape (int v) - { return vshape[v]; }; - - double GetEdgeShape (int index) - { return eshape[index]; }; - - double GetFaceShape (int index) - { return fshape[index]; }; - - Vec<2> GetVertexDShape (int v) - { return vdshape[v]; }; - - Vec<2> GetEdgeDShape (int index) - { return edshape[index]; }; - - Vec<2> GetFaceDShape (int index) - { return fdshape[index]; }; - - double GetFaceLaplaceShape (int index) - { return fddshape[index]; }; -}; - - - -// ---------------------------------------------------------------------------- -// FETrig -// ---------------------------------------------------------------------------- - -class FETrig : public BaseFiniteElement2D -{ - Point<3> lambda; - Mat<3,2> dlambda; - - const ELEMENT_EDGE * eledge; - const ELEMENT_FACE * elface; - - virtual void CalcNFaceShapes () - { nfaceshapes = ((faceorder-1)*(faceorder-2))/2; }; - -public: - - FETrig (const CurvedElements & acurv) : BaseFiniteElement2D(acurv) - { - nvertices = 3; - nedges = 3; - eledge = MeshTopology :: GetEdges (TRIG); - elface = MeshTopology :: GetFaces (TRIG); - }; - - virtual ~FETrig() - {}; - - virtual void SetReferencePoint (Point<2> axi); - - virtual void SetVertexSingularity (int v, int exponent); - - virtual void CalcVertexShapes(); - virtual void CalcEdgeShapes(); - virtual void CalcFaceShapes(); - - virtual void CalcFaceLaplaceShapes(); -}; - - - -// ---------------------------------------------------------------------------- -// FEQuad -// ---------------------------------------------------------------------------- - -class FEQuad : public BaseFiniteElement2D -{ - const ELEMENT_FACE * elface; - - virtual void CalcNFaceShapes () - { nfaceshapes = (faceorder-1)*(faceorder-1); }; - -public: - - FEQuad (const CurvedElements & acurv) : BaseFiniteElement2D(acurv) - { - nvertices = 4; - nedges = 4; - elface = MeshTopology :: GetFaces (QUAD); - }; - - virtual ~FEQuad() - {}; - - virtual void SetVertexSingularity (int /* v */, int /* exponent */) - {}; - - virtual void CalcVertexShapes(); - virtual void CalcEdgeShapes(); - virtual void CalcFaceShapes(); - - virtual void CalcFaceLaplaceShapes(); -}; - - - - -// ---------------------------------------------------------------------------- -// BaseFiniteElement3D -// ---------------------------------------------------------------------------- - -class BaseFiniteElement3D : public BaseFiniteElement<3> -{ -protected: - - int nvertices; - int nedges; - int nfaces; - - int vertexnr[8]; - int edgenr[12]; - int edgeorient[12]; - int edgeorder[12]; - int facenr[6]; - int faceorient[6]; - int faceorder[6]; - int surfacenr[6]; - // int surfaceorient[6]; - - int nfaceshapes[6]; - - int maxedgeorder; - int maxfaceorder; - - PolynomialBasis b1, b2; - - double vshape[8]; - Vec<3> vdshape[8]; - ArrayMem<double,120> eshape; - ArrayMem<Vec<3>,120> edshape; - ArrayMem<double,2000> fshape; - ArrayMem<Vec<3>,2000> fdshape; - - virtual void CalcNFaceShapes () = 0; - -public: - - int locmaxedgeorder; - int locmaxfaceorder; - - BaseFiniteElement3D (const CurvedElements & acurv) : BaseFiniteElement<3>(acurv) - { maxedgeorder = maxfaceorder = -1; }; - - void SetElementNumber (int aelnr); - - int GetVertexNr (int v) - { return vertexnr[v]; }; - - int GetEdgeNr (int e) - { return edgenr[e]; }; - - int GetFaceNr (int f) - { return facenr[f]; }; - - int GetNFaceShapes (int f) - { return nfaceshapes[f]; }; - - int GetEdgeOrder (int e) - { return edgeorder[e]; }; - - int GetFaceOrder (int f) - { return faceorder[f]; }; - - int GetNVertices () - { return nvertices; }; - - int GetNEdges () - { return nedges; }; - - int GetNFaces () - { return nfaces; }; - - int IsCurved () - { - bool iscurved = 0; - int e, f; - - for (e = 0; e < GetNEdges(); e++) - iscurved = iscurved || (GetEdgeOrder(e) > 1); - - for (f = 0; f < GetNFaces(); f++) - iscurved = iscurved || (GetFaceOrder(f) > 1); - - return iscurved; - } - - virtual void CalcVertexShapes() = 0; - virtual void CalcEdgeShapes() = 0; - virtual void CalcFaceShapes() = 0; - - double GetVertexShape (int v) - { return vshape[v]; }; - - double GetEdgeShape (int index) - { return eshape[index]; }; - - double GetFaceShape (int index) - { return fshape[index]; }; - - Vec<3> GetVertexDShape (int v) - { return vdshape[v]; }; - - Vec<3> GetEdgeDShape (int index) - { return edshape[index]; }; - - Vec<3> GetFaceDShape (int index) - { return fdshape[index]; }; -}; - - - -// ---------------------------------------------------------------------------- -// FETet -// ---------------------------------------------------------------------------- - -class FETet : public BaseFiniteElement3D -{ - Point<4> lambda; - Mat<4,3> dlambda; - - const ELEMENT_EDGE * eledge; - const ELEMENT_FACE * elface; - - virtual void CalcNFaceShapes () - { - for (int f = 0; f < nfaces; f++) - nfaceshapes[f] = ((faceorder[f]-1)*(faceorder[f]-2))/2; - }; - -public: - - FETet (const CurvedElements & acurv) : BaseFiniteElement3D(acurv) - { - nvertices = 4; - nedges = 6; - nfaces = 4; - eledge = MeshTopology :: GetEdges (TET); - elface = MeshTopology :: GetFaces (TET); - }; - - void SetReferencePoint (Point<3> axi); - - virtual void CalcVertexShapes(); - virtual void CalcEdgeShapes(); - virtual void CalcFaceShapes(); -}; - - - -// ---------------------------------------------------------------------------- -// FEPrism -// ---------------------------------------------------------------------------- - -class FEPrism : public BaseFiniteElement3D -{ - Point<4> lambda; // mixed barycentric coordinates - Mat<4,3> dlambda; - - const ELEMENT_EDGE * eledge; - const ELEMENT_FACE * elface; - - virtual void CalcNFaceShapes () - { - int f; - for (f = 0; f < 2; f++) - nfaceshapes[f] = ((faceorder[f]-1)*(faceorder[f]-2))/2; - for (f = 2; f < nfaces; f++) - nfaceshapes[f] = (faceorder[f]-1)*(faceorder[f]-1); - }; - -public: - - FEPrism (const CurvedElements & acurv) : BaseFiniteElement3D(acurv) - { - nvertices = 6; - nedges = 9; - nfaces = 5; - eledge = MeshTopology :: GetEdges (PRISM); - elface = MeshTopology :: GetFaces (PRISM); - }; - - void SetReferencePoint (Point<3> axi); - - virtual void CalcVertexShapes(); - virtual void CalcEdgeShapes(); - virtual void CalcFaceShapes(); -}; - - - - -// ---------------------------------------------------------------------------- -// FEPyramid -// ---------------------------------------------------------------------------- - -class FEPyramid : public BaseFiniteElement3D -{ - - const ELEMENT_EDGE * eledge; - const ELEMENT_FACE * elface; - - virtual void CalcNFaceShapes () - { - int f; - for (f = 0; f < 4; f++) - nfaceshapes[f] = ((faceorder[f]-1)*(faceorder[f]-2))/2; - for (f = 4; f < nfaces; f++) - nfaceshapes[f] = (faceorder[f]-1)*(faceorder[f]-1); - }; - -public: - - FEPyramid (const CurvedElements & acurv) : BaseFiniteElement3D(acurv) - { - nvertices = 5; - nedges = 8; - nfaces = 5; - eledge = MeshTopology :: GetEdges (PYRAMID); - elface = MeshTopology :: GetFaces (PYRAMID); - }; - - void SetReferencePoint (Point<3> axi); - - virtual void CalcVertexShapes(); - virtual void CalcEdgeShapes(); - virtual void CalcFaceShapes(); -}; - - - - -// ---------------------------------------------------------------------------- -// FEHex -// ---------------------------------------------------------------------------- - -class FEHex : public BaseFiniteElement3D -{ - - const ELEMENT_EDGE * eledge; - const ELEMENT_FACE * elface; - - virtual void CalcNFaceShapes () - { - int f; - for (f = 0; f < 6; f++) - nfaceshapes[f] = (faceorder[f]-1)*(faceorder[f]-1); - }; - -public: - - FEHex (const CurvedElements & acurv) : BaseFiniteElement3D(acurv) - { - nvertices = 8; - nedges = 12; - nfaces = 6; - eledge = MeshTopology :: GetEdges (HEX); - elface = MeshTopology :: GetFaces (HEX); - }; - - void SetReferencePoint (Point<3> axi); - - virtual void CalcVertexShapes(); - virtual void CalcEdgeShapes(); - virtual void CalcFaceShapes(); -}; - - - - -#endif diff --git a/Netgen/libsrc/meshing/curvedelems2.cpp b/Netgen/libsrc/meshing/curvedelems2.cpp deleted file mode 100644 index 6b79ee5fe9..0000000000 --- a/Netgen/libsrc/meshing/curvedelems2.cpp +++ /dev/null @@ -1,752 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - -namespace netgen -{ - - -// ---------------------------------------------------------------------------- -// CurvedElements -// ---------------------------------------------------------------------------- - - CurvedElements :: CurvedElements (const Mesh & amesh) - : mesh(amesh), top(mesh.GetTopology()) - { - isHighOrder = 0; - nvisualsubsecs = 2; - nIntegrationPoints = 10; - } - - - CurvedElements :: ~CurvedElements () - { - ; - } - - - void CurvedElements :: BuildCurvedElements(Refinement * ref, int polydeg) - { - if (mesh.coarsemesh) - { - mesh.coarsemesh->GetCurvedElements().BuildCurvedElements (ref, polydeg); - SetHighOrder(); - return; - } - - PrintMessage (2, "Build curved elements, order = ", polydeg); - - NgLock lock(const_cast<Mesh&>(mesh).Mutex(), 1); - isHighOrder = 0; - lock.UnLock(); - - const_cast<Mesh &>(mesh).UpdateTopology(); - - // set order of edges and faces - - BaseFiniteElement2D * fe2d; - - FEEdge edge (*this); - FESegm segm (*this); - FETrig trig (*this); - FEQuad quad (*this); - - int i, k, e, f; - - ARRAY<bool> edgedone; - - edgedone.SetSize (top.GetNEdges()); - - edgeorder.SetSize (top.GetNEdges()); - faceorder.SetSize (top.GetNFaces()); - - int nedgestocurve = mesh.GetNSeg(); - - edgedone = 0; - edgeorder = 1; - faceorder = 1; - - /* - for (e = 0; e < top.GetNEdges(); e++) - { - edgedone = 0; - edgeorder[e] = 1; - } - - for (f = 0; f < top.GetNFaces(); f++) - faceorder[f] = 1; - */ - - for (i = 1; i <= mesh.GetNSeg(); i++) - edgeorder[top.GetSegmentEdge(i)-1] = polydeg; - - - if (mesh.GetDimension() == 3) - { - for (i = 1; i <= mesh.GetNSE(); i++) - { - faceorder[top.GetSurfaceElementFace(i)-1] = polydeg; - - Element2d elem = mesh[(SurfaceElementIndex) (i-1)]; - - ARRAY<int> edgenrs; - top.GetSurfaceElementEdges(i, edgenrs); - - nedgestocurve += top.GetNEdges(elem.GetType()); - - for (int e = 0; e < top.GetNEdges(elem.GetType()); e++) - edgeorder[edgenrs[e]-1] = polydeg; - } - } - - if (polydeg == 1) - { - isHighOrder = 0; - return; - } - - PrintMessage (1, "Building curved elements, order = ", polydeg); - PushStatusF ("curving edges"); - - - - // set edgecoeffs and facecoeffs arrays index and size - - edgecoeffsindex.SetSize (top.GetNEdges()+1); - facecoeffsindex.SetSize (top.GetNFaces()+1); - - edgecoeffsindex[0] = 0; - for (e = 2; e <= top.GetNEdges()+1; e++) - edgecoeffsindex[e-1] = edgecoeffsindex[e-2] + edgeorder[e-2]-1; - - facecoeffsindex[0] = 0; - for (f = 2; f <= top.GetNFaces()+1; f++) - { - switch (top.GetFaceType (f-1)) - { - case TRIG: - facecoeffsindex[f-1] = facecoeffsindex[f-2] + - (faceorder[f-2]-1)*(faceorder[f-2]-2)/2; - break; - case QUAD: - facecoeffsindex[f-1] = facecoeffsindex[f-2] + - (faceorder[f-2]-1)*(faceorder[f-2]-1); - break; - } - } - - edgecoeffs.SetSize(edgecoeffsindex[top.GetNEdges()]); - facecoeffs.SetSize(facecoeffsindex[top.GetNFaces()]); - - - - // evaluate edge points - - PointGeomInfo newgi; // dummy variable, only needed for function call - EdgePointGeomInfo newepgi; // dummy variable, only needed for function call - Point3d xexact; // new point to be stored in ARRAY edgepts - - ARRAY<double> xi, wi; - ComputeGaussRule(nIntegrationPoints, xi, wi); - - for (i=0; i<edgecoeffsindex[top.GetNEdges()]; i++) - edgecoeffs[i] = Vec<3>(0.,0.,0.); - - - - - // all edges belonging to segments - - for (i=0; i<mesh.GetNSeg(); i++) - { - if (multithread.terminate) return; - - SetThreadPercent( double(100*i/nedgestocurve) ); - - int edgenr = top.GetSegmentEdge(i+1); - - if (edgedone[edgenr-1]) continue; - - edgedone[edgenr-1] = 1; - - Segment s = mesh.LineSegment(i+1); - - segm.SetElementNumber (i+1); - - for (k = 2; k <= segm.GetEdgeOrder(); k++) - edgecoeffs[edgecoeffsindex[edgenr-1]+k-2] = Vec<3>(0.,0.,0.); - - for (int l = 0; l < nIntegrationPoints; l++) - { - segm.SetReferencePoint (Point<1>(xi[l])); - segm.CalcVertexShapes (); - segm.CalcEdgeLaplaceShapes (); - - Point<3> xv(0,0,0); - - for (int v = 0; v < 2; v++) - xv = xv + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v)); - - double secpoint = xi[l]; - - ref->PointBetween (mesh.Point(segm.GetVertexNr(1)), - mesh.Point(segm.GetVertexNr(0)), secpoint, - s.surfnr2, s.surfnr1, - s.epgeominfo[1], s.epgeominfo[0], - xexact, newepgi); - - for (int k = 2; k <= segm.GetEdgeOrder(); k++) - edgecoeffs[edgecoeffsindex[edgenr-1]+k-2] -= - wi[l] * segm.GetEdgeLaplaceShape(k-2) * Vec<3>(xexact - xv); - - } - - for (k = 2; k <= segm.GetEdgeOrder(); k++) - edgecoeffs[edgecoeffsindex[edgenr-1]+k-2] = - (2.0*(k-1.0)+1.0)*edgecoeffs[edgecoeffsindex[edgenr-1]+k-2]; - - } - - - - - - // all edges belonging to surface elements - - if (mesh.GetDimension() == 3) - { - int nedgescurved = mesh.GetNSeg(); - for (int i=0; i<mesh.GetNSE(); i++) - { - if (multithread.terminate) return; - - // SetThreadPercent( double(100*(mesh.GetNSeg()+i)/nedgestocurve) ); - Element2d elem = mesh[(SurfaceElementIndex) i]; - const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(elem.GetType()); - - ARRAY<int> edgenrs; - ARRAY<int> orient; - top.GetSurfaceElementEdges(i+1, edgenrs); - top.GetSurfaceElementEdgeOrientations(i+1, orient); - - for (int e = 0; e < top.GetNEdges(elem.GetType()); e++) - { -// cout << "e = " << e << "/" << top.GetNEdges(elem.GetType()) << endl; - - nedgescurved++; - - if (edgedone[edgenrs[e]-1]) continue; - - edgedone[edgenrs[e]-1] = 1; - - SetThreadPercent( double(100*(nedgescurved)/nedgestocurve) ); - - edge.SetElementNumber (edgenrs[e]); - - for (k = 2; k <= edge.GetEdgeOrder(); k++) - edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2] = Vec<3>(0.,0.,0.); - - for (int l = 0; l < nIntegrationPoints; l++) - { -// cout << "." << flush; - edge.SetReferencePoint (Point<1>(xi[l])); - edge.CalcVertexShapes (); - edge.CalcEdgeLaplaceShapes (); - - Point<3> xv(0,0,0); - for (int v = 0; v < 2; v++) - xv = xv + edge.GetVertexShape(v) * mesh.Point(edge.GetVertexNr(v)); - - double secpoint = xi[l]; - - if (orient[e] == 1) - ref->PointBetween (mesh.Point(edge.GetVertexNr(1)), - mesh.Point(edge.GetVertexNr(0)), secpoint, - mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(), - elem.GeomInfoPi(eledges[e][1]), - elem.GeomInfoPi(eledges[e][0]), - xexact, newgi); - else - ref->PointBetween (mesh.Point(edge.GetVertexNr(1)), - mesh.Point(edge.GetVertexNr(0)), secpoint, - mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(), - elem.GeomInfoPi(eledges[e][0]), - elem.GeomInfoPi(eledges[e][1]), - xexact, newgi); - - for (k = 2; k <= edge.GetEdgeOrder(); k++) - edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2] -= - wi[l] * edge.GetEdgeLaplaceShape(k-2) * Vec<3>(xexact - xv); - } -// cout << endl; - for (k = 2; k <= edge.GetEdgeOrder(); k++) - edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2] = - (2.0*(k-1.0)+1.0)*edgecoeffs[edgecoeffsindex[edgenrs[e]-1]+k-2]; - - } - } - } - - - - -/* - - // L2-Projection for edges - - - cout << "WARNING: L2-Projection for edges" << endl; - - if (mesh.GetDimension() == 3) - { - for (int i=0; i<mesh.GetNSE(); i++) - { - Element2d elem = mesh[(SurfaceElementIndex) i]; - const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(elem.GetType()); - - ARRAY<int> edgenrs; - ARRAY<int> orient; - top.GetSurfaceElementEdges(i+1, edgenrs); - top.GetSurfaceElementEdgeOrientations(i+1, orient); - - for (int e = 0; e < top.GetNEdges(elem.GetType()); e++) - { - edge.SetElementNumber (edgenrs[e]); - - int npoints = edge.GetEdgeOrder()-1; - - if (npoints == 0) continue; - - DenseMatrix mat(npoints); - DenseMatrix inv(npoints); - Vector vec[3]; - - for (int k = 0; k < 3; k++) - { - vec[k].SetSize(npoints); - for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.); - } - - for (int l = 0; l < nIntegrationPoints; l++) - { - double w = wi[l]; - - edge.SetReferencePoint (Point<1>(xi[l])); - edge.CalcVertexShapes (); - edge.CalcEdgeShapes (); - - for (int n = 0; n < npoints; n++) - for (int m = 0; m < npoints; m++) - mat.Set(n+1, m+1, mat.Get(n+1,m+1) + - edge.GetEdgeShape(n) * edge.GetEdgeShape(m) * w); - - Point<3> xv(0,0,0); - for (int v = 0; v < 2; v++) - xv = xv + edge.GetVertexShape(v) * mesh.Point(edge.GetVertexNr(v)); - - double secpoint = xi[l]; - - ref->PointBetween (mesh.Point(edge.GetVertexNr(1)), - mesh.Point(edge.GetVertexNr(0)), secpoint, - mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(), - elem.GeomInfoPi(eledges[e][1]), - elem.GeomInfoPi(eledges[e][0]), - xexact, newgi); - - for (int k = 2; k <= edge.GetEdgeOrder(); k++) - { - vec[0].Set(k-1, vec[0].Get(k-1) + Vec<3>(xexact - xv)(0)*edge.GetEdgeShape(k-2)*w ); - vec[1].Set(k-1, vec[1].Get(k-1) + Vec<3>(xexact - xv)(1)*edge.GetEdgeShape(k-2)*w ); - vec[2].Set(k-1, vec[2].Get(k-1) + Vec<3>(xexact - xv)(2)*edge.GetEdgeShape(k-2)*w ); - } - - } - - - CalcInverse(mat,inv); - - Vector a0, a1, a2; - - a0 = inv*vec[0]; - a1 = inv*vec[1]; - a2 = inv*vec[2]; - - int index = edgecoeffsindex[edge.GetEdgeNr()-1]; - - for (int n = 0; n < npoints; n++, index++) - edgecoeffs[index] = Vec<3>(a0(n+1), a1(n+1), a2(n+1)); - } - } - } - - - for (int i=0; i<mesh.GetNSeg(); i++) - { - int edgenr = top.GetSegmentEdge(i+1); - - Segment s = mesh.LineSegment(i+1); - - segm.SetElementNumber (i+1); - - int npoints = segm.GetEdgeOrder()-1; - - if (npoints == 0) continue; - - DenseMatrix mat(npoints); - DenseMatrix inv(npoints); - Vector vec[3]; - - for (int k = 0; k < 3; k++) - { - vec[k].SetSize(npoints); - for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.); - } - - for (int l = 0; l < nIntegrationPoints; l++) - { - double w = wi[l]; - - segm.SetReferencePoint (Point<1>(xi[l])); - segm.CalcVertexShapes (); - segm.CalcEdgeShapes (); - - for (int n = 0; n < npoints; n++) - for (int m = 0; m < npoints; m++) - mat.Set(n+1, m+1, mat.Get(n+1,m+1) + - segm.GetEdgeShape(n) * segm.GetEdgeShape(m) * w); - - Point<3> xv(0,0,0); - for (int v = 0; v < 2; v++) - xv = xv + segm.GetVertexShape(v) * mesh.Point(segm.GetVertexNr(v)); - - double secpoint = xi[l]; - - if (segm.GetEdgeOrientation() == -1) secpoint = 1. - secpoint; // reverse orientation - - ref->PointBetween (mesh.Point(segm.GetVertexNr(1)), - mesh.Point(segm.GetVertexNr(0)), secpoint, - s.surfnr2, s.surfnr1, - s.epgeominfo[1], s.epgeominfo[0], - xexact, newepgi); - - for (int k = 2; k <= segm.GetEdgeOrder(); k++) - { - vec[0].Set(k-1, vec[0].Get(k-1) + Vec<3>(xexact - xv)(0)*segm.GetEdgeShape(k-2)*w ); - vec[1].Set(k-1, vec[1].Get(k-1) + Vec<3>(xexact - xv)(1)*segm.GetEdgeShape(k-2)*w ); - vec[2].Set(k-1, vec[2].Get(k-1) + Vec<3>(xexact - xv)(2)*segm.GetEdgeShape(k-2)*w ); - } - - } - - - CalcInverse(mat,inv); - - Vector a0, a1, a2; - - a0 = inv*vec[0]; - a1 = inv*vec[1]; - a2 = inv*vec[2]; - - int index = edgecoeffsindex[segm.GetEdgeNr()-1]; - - for (int n = 0; n < npoints; n++, index++) - edgecoeffs[index] = Vec<3>(a0(n+1), a1(n+1), a2(n+1)); - - - - } - -*/ - - - - - - // evaluate face points - - if (mesh.GetDimension() == 3) - { - PopStatus (); - PushStatusF ("curving faces"); - - for (int j=0; j<facecoeffsindex[top.GetNFaces()]; j++) - facecoeffs[j] = Vec<3>(0.,0.,0.); - - for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) // for all surface elements - { - if (multithread.terminate) return; - - SetThreadPercent( double(100*i/mesh.GetNSE()) ); - - Element2d elem = mesh[i]; - - if (elem.GetType() == TRIG) - fe2d = &trig; - else - fe2d = &quad; - - fe2d->SetElementNumber (i+1); - - int npoints = fe2d->GetNFaceShapes(); - - if (npoints == 0) continue; - - DenseMatrix mat(npoints); - DenseMatrix inv(npoints); - Vector vec[3]; - - for (int k = 0; k < 3; k++) - { - vec[k].SetSize(npoints); - for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.); - } - - for (int j = 0; j < nIntegrationPoints; j++) - { - for (int k = 0; k < nIntegrationPoints; k++) - { - double w; - Point<2> xr; - - if (elem.GetType() == TRIG) - { - w = wi[j]*wi[k]*(1-xi[j]); - xr = Point<2> (xi[j], xi[k]*(1-xi[j])); - } - else - { - w = wi[j]*wi[k]; - xr = Point<2> (xi[j], xi[k]); - } - - fe2d->SetReferencePoint (xr); - fe2d->CalcFaceShapes (); - fe2d->CalcVertexShapes (); - fe2d->CalcEdgeShapes (); - fe2d->CalcFaceLaplaceShapes (); - - // integration over the product of the gradients of the face shapes - - for (int n = 0; n < npoints; n++) - for (int m = 0; m < npoints; m++) - mat.Set(n+1, m+1, - mat.Get(n+1,m+1) + - fe2d->GetFaceDShape(n)*fe2d->GetFaceDShape(m)*w); - - // integration over the difference between the exact geometry and the one - // defined by vertex and edge shape functions times face shape - - // double giu = 0, giv = 0; - PointGeomInfo gi; - gi.trignum = elem.GeomInfoPi(1).trignum; - gi.u = 0.0; - gi.v = 0.0; - Point<3> xve(0.,0.,0.); - - // vertex shape functions - for (int v = 0; v < fe2d->GetNVertices(); v++) - { - xve = xve + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v)); - gi.u += fe2d->GetVertexShape(v) * elem.GeomInfoPi(v+1).u; - gi.v += fe2d->GetVertexShape(v) * elem.GeomInfoPi(v+1).v; - } - - // edge shape functions - int index = 0; - for (int e = 0; e < fe2d->GetNEdges(); e++) - { - int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1]; - for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++) - xve = xve + fe2d->GetEdgeShape(index) * edgecoeffs[gindex]; - } - - // exact point - - Point<3> xexact = xve; - ref->ProjectToSurface (xexact, mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr(), gi); - - Vec<3> v2 = w*(Vec<3>(xexact)-Vec<3>(xve)); - - for (int k = 0; k < 3; k++) - for (int n = 0; n < npoints; n++) - vec[k].Set(n+1, vec[k].Get(n+1) - fe2d->GetFaceLaplaceShape(n)*v2(k)); - } - } - - CalcInverse(mat,inv); - - Vector a0(npoints), a1(npoints), a2(npoints); - - /* - a0 = inv*vec[0]; - a1 = inv*vec[1]; - a2 = inv*vec[2]; - */ - inv.Mult (vec[0], a0); - inv.Mult (vec[1], a1); - inv.Mult (vec[2], a2); - - int index = facecoeffsindex[fe2d->GetFaceNr()-1]; - - for (int n = 0; n < npoints; n++, index++) - facecoeffs[index] = Vec<3>(a0.Elem(n+1), a1.Elem(n+1), a2.Elem(n+1)); - } - } - - - - -/* - cout << "WARNING: L2-Projection for faces" << endl; - - // evaluate face points - - if (mesh.GetDimension() == 3) - { - for (int i=0; i<facecoeffsindex[top.GetNFaces()]; i++) - facecoeffs[i] = Vec<3>(0.,0.,0.); - - for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) // for all surface elements - { - Element2d elem = mesh[i]; - - if (elem.GetType() == TRIG) - fe2d = &trig; - else - fe2d = &quad; - - fe2d->SetElementNumber (i+1); - - int npoints = fe2d->GetNFaceShapes(); - - if (npoints == 0) continue; - - DenseMatrix mat(npoints); - DenseMatrix inv(npoints); - Vector vec[3]; - - for (int k = 0; k < 3; k++) - { - vec[k].SetSize(npoints); - for (int n = 1; n <= npoints; n++) vec[k].Set(n, 0.); - } - - for (int j = 0; j < nIntegrationPoints; j++) - { - for (int k = 0; k < nIntegrationPoints; k++) - { - double w; - Point<2> xr; - - if (elem.GetType() == TRIG) - { - w = wi[j]*wi[k]*(1-xi[j]); - xr = Point<2> (xi[j], xi[k]*(1-xi[j])); - } - else - { - w = wi[j]*wi[k]; - xr = Point<2> (xi[j], xi[k]); - } - - fe2d->SetReferencePoint (xr); -// fe2d->CalcFaceDShape (false, true); - fe2d->CalcFaceShapes (); - - // integration over the product of the gradients of the face shapes - - for (int n = 0; n < npoints; n++) - for (int m = 0; m < npoints; m++) - mat.Set(n+1, m+1, mat.Get(n+1,m+1) + - fe2d->GetFaceShape(n)*fe2d->GetFaceShape(m)*w); - - // integration over the difference between the exact geometry and the one - // defined by vertex and edge shape functions times face shape - - Point<3> xve(0.,0.,0.); - - // vertex shape functions - fe2d->CalcVertexShapes (); -// fe2d->CalcVertexShape (true, false); - for (int v = 0; v < fe2d->GetNVertices(); v++) - xve = xve + fe2d->GetVertexShape(v) * mesh.Point(fe2d->GetVertexNr(v)); - - // edge shape functions -// fe2d->CalcEdgeShape (true, false); - fe2d->CalcEdgeShapes (); - - int index = 0; - for (int e = 0; e < fe2d->GetNEdges(); e++) - { - int gindex = edgecoeffsindex[fe2d->GetEdgeNr(e)-1]; - - for (int k = 2; k <= fe2d->GetEdgeOrder(e); k++, index++, gindex++) - xve = xve + fe2d->GetEdgeShape(index) * edgecoeffs[gindex]; - } - - // exact point - - Point<3> xexact = xve; - ref->ProjectToSurface (xexact, mesh.GetFaceDescriptor(elem.GetIndex()).SurfNr()); - - Vec<3> v = w*(Vec<3>(xexact)-Vec<3>(xve)); - - fe2d->CalcFaceLaplaceShapes (); - - for (int k = 0; k < 3; k++) - for (int n = 0; n < npoints; n++) - vec[k].Set(n+1, vec[k].Get(n+1) + fe2d->GetFaceShape(n)*v(k)); - } - } - - CalcInverse(mat,inv); - - Vector a0, a1, a2; - - a0 = inv*vec[0]; - a1 = inv*vec[1]; - a2 = inv*vec[2]; - - int index = facecoeffsindex[fe2d->GetFaceNr()-1]; - - for (int n = 0; n < npoints; n++, index++) - facecoeffs[index] = Vec<3>(a0(n+1), a1(n+1), a2(n+1)); - } - } -*/ - - - PrintMessage (5, "reducing order"); - - for (e = 0; e < top.GetNEdges(); e++) - if (edgeorder[e] > 1) - { - int i; - double maxcoeff = 0.; - - for (i = edgecoeffsindex[e]; i < edgecoeffsindex[e+1]; i++) - maxcoeff = max2 (maxcoeff, edgecoeffs[i].Length()); - - if (maxcoeff < 1e-12) edgeorder[e] = 1; - } - - for (f = 0; f < top.GetNFaces(); f++) - if (faceorder[f] > 1) - { - int i; - double maxcoeff = 0.; - - for (i = facecoeffsindex[f]; i < facecoeffsindex[f+1]; i++) - maxcoeff = max (maxcoeff, facecoeffs[i].Length()); - - if (maxcoeff < 1e-12) faceorder[f] = 1; - } - - isHighOrder = 1; // true - - PrintMessage(1, "done"); - PopStatus(); - // cout << "finished" << endl; - } - -} // namespace netgen diff --git a/Netgen/libsrc/meshing/delaunay.cpp b/Netgen/libsrc/meshing/delaunay.cpp deleted file mode 100644 index 505a8c193f..0000000000 --- a/Netgen/libsrc/meshing/delaunay.cpp +++ /dev/null @@ -1,1683 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - - -namespace netgen -{ - - - static const int deltetfaces[][3] = - { { 1, 2, 3 }, - { 2, 0, 3 }, - { 0, 1, 3 }, - { 1, 0, 2 } }; - - - class DelaunayTet - { - PointIndex pnums[4]; - int nb[4]; - - public: - DelaunayTet () { ; } - - DelaunayTet (const DelaunayTet & el) - { - for (int i = 0; i < 4; i++) - pnums[i] = el[i]; - } - - DelaunayTet (const Element & el) - { - for (int i = 0; i < 4; i++) - pnums[i] = el[i]; - } - - PointIndex & operator[] (int i) { return pnums[i]; } - PointIndex operator[] (int i) const { return pnums[i]; } - - int & NB1(int i) { return nb[i-1]; } - int NB1(int i) const { return nb[i-1]; } - - int & NB(int i) { return nb[i]; } - int NB(int i) const { return nb[i]; } - - - int FaceNr (INDEX_3 & face) const // which face nr is it ? - { - for (int i = 0; i < 3; i++) - if (pnums[i] != face.I1() && - pnums[i] != face.I2() && - pnums[i] != face.I3()) - return i; - return 3; - } - - void GetFace1 (int i, INDEX_3 & face) const - { - face.I(1) = pnums[deltetfaces[i-1][0]]; - face.I(2) = pnums[deltetfaces[i-1][1]]; - face.I(3) = pnums[deltetfaces[i-1][2]]; - } - - void GetFace (int i, INDEX_3 & face) const - { - face.I(1) = pnums[deltetfaces[i][0]]; - face.I(2) = pnums[deltetfaces[i][1]]; - face.I(3) = pnums[deltetfaces[i][2]]; - } - - INDEX_3 GetFace1 (int i) const - { - return INDEX_3 (pnums[deltetfaces[i-1][0]], - pnums[deltetfaces[i-1][1]], - pnums[deltetfaces[i-1][2]]); - } - - INDEX_3 GetFace (int i) const - { - return INDEX_3 (pnums[deltetfaces[i][0]], - pnums[deltetfaces[i][1]], - pnums[deltetfaces[i][2]]); - } - - void GetFace1 (int i, Element2d & face) const - { - // face.SetType(TRIG); - face[0] = pnums[deltetfaces[i-1][0]]; - face[1] = pnums[deltetfaces[i-1][1]]; - face[2] = pnums[deltetfaces[i-1][2]]; - } - }; - - - - - - - - - - /* - Table to maintain neighbour elements - */ - class MeshNB - { - // face nodes -> one element - INDEX_3_CLOSED_HASHTABLE<int> faces; - - // - ARRAY<DelaunayTet> & tets; - - public: - - // estimated number of points - MeshNB (ARRAY<DelaunayTet> & atets, int np) - : faces(200), tets(atets) - { ; } - - // add element with 4 nodes - void Add (int elnr); - - // delete element with 4 nodes - void Delete (int elnr) - { - DelaunayTet & el = tets.Elem(elnr); - for (int i = 0; i < 4; i++) - faces.Set (el.GetFace(i).Sort(), el.NB(i)); - } - - // get neighbour of element elnr in direction fnr - int GetNB (int elnr, int fnr) - { - return tets.Get(elnr).NB1(fnr); - } - - // - void ResetFaceHT (int size) - { - faces.SetSize (size); - } - }; - - - - void MeshNB :: Add (int elnr) - { - DelaunayTet & el = tets.Elem(elnr); - - for (int i = 0; i < 4; i++) - { - INDEX_3 i3 = INDEX_3::Sort (el.GetFace(i)); - - int posnr; - - if (!faces.PositionCreate (i3, posnr)) - { - // face already in use - int othertet = faces.GetData (posnr); - - el.NB(i) = othertet; - if (othertet) - { - int fnr = tets.Get(othertet).FaceNr (i3); - tets.Elem(othertet).NB(fnr) = elnr; - } - } - else - { - faces.SetData (posnr, elnr); - el.NB(i) = 0; - } - } - } - - - - - - - /* - connected lists of cosphereical elements - */ - class SphereList - { - ARRAY<int> links; - public: - SphereList () - { ; } - - void AddElement (int elnr) - { - if (elnr > links.Size()) - links.Append (1); - links.Elem(elnr) = elnr; - } - - void DeleteElement (int elnr) - { - links.Elem(elnr) = 0; - } - - void ConnectElement (int eli, int toi) - { - links.Elem (eli) = links.Get (toi); - links.Elem (toi) = eli; - } - - void GetList (int eli, ARRAY<int> & linked) const; - }; - - - void SphereList :: GetList (int eli, ARRAY<int> & linked) const - { - linked.SetSize (0); - int pi = eli; - - do - { - if (pi <= 0 || pi > links.Size()) - { - cerr << "link, error " << endl; - cerr << "pi = " << pi << " linked.s = " << linked.Size() << endl; - exit(1); - } - if (linked.Size() > links.Size()) - { - cerr << "links have loop" << endl; - exit(1); - } - - linked.Append (pi); - pi = links.Get(pi); - } - while (pi != eli); - } - - - - - - void AddDelaunayPoint (PointIndex newpi, const Point3d & newp, - ARRAY<DelaunayTet> & tempels, - Mesh & mesh, - Box3dTree & tettree, - MeshNB & meshnb, - ARRAY<Point3d> & centers, ARRAY<double> & radi2, - ARRAY<int> & connected, ARRAY<int> & treesearch, - ARRAY<int> & freelist, SphereList & list, - IndexSet & insphere, IndexSet & closesphere) - { - int i, j, k, l; - - /* - find any sphere, such that newp is contained in - */ - - DelaunayTet el; - int cfelind = -1; - - const Point3d * pp[4]; - Point3d pc; - double r2; - Point3d tpmin, tpmax; - - tettree.GetIntersecting (newp, newp, treesearch); - for (j = 0; j < treesearch.Size(); j++) - { - int jjj = treesearch[j]; - if (Dist2 (centers.Get(jjj), newp) < radi2.Get(jjj)) - { - el = tempels.Get(jjj); - cfelind = jjj; - break; - } - } - - /* - if (!felind) - { - cerr << "not in any sphere, 1" << endl; - // old, non tree search - - double mindist = 1e10; - for (j = 1; j <= tempels.Size(); j++) - { - if (tempels.Get(j).PNum(1)) - { - double toofar = - Dist2 (centers.Get(j), newp) - radi2.Get(j); - if (toofar < mindist || toofar < 1e-7) - { - mindist = toofar; - cout << " dist2 = " << Dist2 (centers.Get(j), newp) - << " radi2 = " << radi2.Get(j) << endl; - } - if (toofar < 0) - { - el = tempels.Get(j); - felind = j; - cout << "sphere found !" << endl; - break; - } - } - } - cout << "point is too far from sheres: " << mindist << endl; - } - */ - - if (cfelind == -1) - { - PrintWarning ("Delaunay, point not in any sphere"); - return; - } - - - /* - insphere: point is in sphere -> delete element - closesphere: point is close to sphere -> considered for same center - */ - - // save overestimate - insphere.SetMaxIndex (2 * tempels.Size() + 5 * mesh.GetNP()); - closesphere.SetMaxIndex (2 * tempels.Size() + 5 * mesh.GetNP()); - - insphere.Clear(); - closesphere.Clear(); - - - insphere.Add (cfelind); - - int changed = 1; - int nstarti = 1, starti; - while (changed) - { - changed = 0; - starti = nstarti; - nstarti = insphere.Array().Size()+1; - - // if point in sphere, then it is also closesphere - for (j = starti; j < nstarti; j++) - { - int helind = insphere.Array().Get(j); - if (!closesphere.IsIn (helind)) - closesphere.Add (helind); - } - - // add connected spheres to insphere - list - for (j = starti; j < nstarti; j++) - { - list.GetList (insphere.Array().Get(j), connected); - for (k = 1; k <= connected.Size(); k++) - { - int celind = connected.Get(k); - - if (tempels.Get(celind)[0] != -1 && - !insphere.IsIn (celind)) - { - changed = 1; - insphere.Add (celind); - } - } - } - - // check neighbour-tets - for (j = starti; j < nstarti; j++) - for (k = 1; k <= 4; k++) - { - int helind = insphere.Array().Get(j); - int nbind = meshnb.GetNB (helind, k); - - if (nbind && !insphere.IsIn (nbind) ) - { - if (Dist2 (centers.Get(nbind), newp) - < radi2.Get(nbind) * (1+1e-8) ) - { - closesphere.Add (nbind); - } - - if (Dist2 (centers.Get(nbind), newp) - < radi2.Get(nbind) * (1 + 1e-12)) - { - // point is in sphere -> remove tet - insphere.Add (nbind); - changed = 1; - } - else - { - /* - Element2d face; - tempels.Get(helind).GetFace (k, face); - - const Point3d & p1 = mesh.Point (face.PNum(1)); - const Point3d & p2 = mesh.Point (face[1]); - const Point3d & p3 = mesh.Point (face[2]); - */ - - INDEX_3 i3 = tempels.Get(helind).GetFace (k-1); - - const Point3d & p1 = mesh.Point ( PointIndex (i3.I1())); - const Point3d & p2 = mesh.Point ( PointIndex (i3.I2())); - const Point3d & p3 = mesh.Point ( PointIndex (i3.I3())); - - - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d n = Cross (v1, v2); - n /= n.Length(); - - if (n * Vec3d (p1, mesh.Point (tempels.Get(helind)[k-1])) > 0) - n *= -1; - - double dist = n * Vec3d (p1, newp); - - - if (dist > -1e-10) // 1e-10 - { - insphere.Add (nbind); - changed = 1; - } - - - } - } - } - } // while (changed) - - // (*testout) << "newels: " << endl; - ARRAY<Element> newels; - - Element2d face(TRIG); - for (j = 1; j <= insphere.Array().Size(); j++) - for (k = 1; k <= 4; k++) - { - // int elind = insphere.Array().Get(j); - int celind = insphere.Array().Get(j); - int nbind = meshnb.GetNB (celind, k); - - if (!nbind || !insphere.IsIn (nbind)) - { - tempels.Get (celind).GetFace1 (k, face); - - Element newel(TET); - for (l = 1; l <= 3; l++) - newel.PNum(l) = face.PNum(l); - newel[3] = newpi; - - newels.Append (newel); - - Vec3d v1(mesh.Point (face[0]), mesh.Point (face[1])); - Vec3d v2(mesh.Point (face[0]), mesh.Point (face[2])); - Vec3d n = Cross (v1, v2); - n /= n.Length(); - if (n * Vec3d(mesh.Point (face[0]), - mesh.Point (tempels.Get(insphere.Array().Get(j))[k-1])) - > 0) - n *= -1; - - double hval = n * Vec3d (mesh.Point (face[0]), newp); - - if (hval > -1e-12) - { - cerr << "vec to outer" << endl; - (*testout) << "vec to outer, hval = " << hval << endl; - (*testout) << "v1 x v2 = " << Cross (v1, v2) << endl; - (*testout) << "facep: " - << mesh.Point (face[0]) << " " - << mesh.Point (face[1]) << " " - << mesh.Point (face[2]) << endl; - } - } - } - - meshnb.ResetFaceHT (10*insphere.Array().Size()+1); - - for (j = 1; j <= insphere.Array().Size(); j++) - { - // int elind = - int celind = insphere.Array().Get(j); - - meshnb.Delete (celind); - list.DeleteElement (celind); - - for (k = 0; k < 4; k++) - tempels.Elem(celind)[k] = -1; - - ((ADTree6&)tettree.Tree()).DeleteElement (celind); - freelist.Append (celind); - } - - - int hasclose = 0; - for (j = 1; j <= closesphere.Array().Size(); j++) - { - int ind = closesphere.Array().Get(j); - if (!insphere.IsIn(ind) && - fabs (Dist2 (centers.Get (ind), newp) - radi2.Get(ind)) < 1e-8 ) - hasclose = 1; - } - - for (j = 1; j <= newels.Size(); j++) - { - int nelind; - - if (!freelist.Size()) - { - tempels.Append (newels.Get(j)); - nelind = tempels.Size(); - } - else - { - nelind = freelist.Last(); - freelist.DeleteLast(); - - tempels.Elem(nelind) = newels.Get(j); - } - - meshnb.Add (nelind); - list.AddElement (nelind); - - for (k = 1; k <= 4; k++) - pp[k-1] = &mesh.Point (newels.Get(j).PNum(k)); - - if (CalcSphereCenter (&pp[0], pc) ) - { - PrintSysError ("Delaunay: New tet is flat"); - - (*testout) << "new tet is flat" << endl; - for (k = 1; k <= 4; k++) - (*testout) << newels.Get(j).PNum(k) << " "; - (*testout) << endl; - for (k = 1; k <= 4; k++) - (*testout) << *pp[k-1] << " "; - (*testout) << endl; - } - - r2 = Dist2 (*pp[0], pc); - if (hasclose) - for (k = 1; k <= closesphere.Array().Size(); k++) - { - int csameind = closesphere.Array().Get(k); - if (!insphere.IsIn(csameind) && - fabs (r2 - radi2.Get(csameind)) < 1e-10 && - Dist (pc, centers.Get(csameind)) < 1e-10) - { - pc = centers.Get(csameind); - r2 = radi2.Get(csameind); - list.ConnectElement (nelind, csameind); - break; - } - } - - if (centers.Size() < nelind) - { - centers.Append (pc); - radi2.Append (r2); - } - else - { - centers.Elem(nelind) = pc; - radi2.Elem(nelind) = r2; - } - - closesphere.Add (nelind); - - tpmax = tpmin = *pp[0]; - for (k = 1; k <= 3; k++) - { - tpmin.SetToMin (*pp[k]); - tpmax.SetToMax (*pp[k]); - } - tpmax = tpmax + 0.01 * (tpmax - tpmin); - tettree.Insert (tpmin, tpmax, nelind); - } - } - - - - - - - void Delaunay1 (Mesh & mesh, const MeshingParameters & mp, AdFront3 * adfront, - ARRAY<DelaunayTet> & tempels, - int oldnp, DelaunayTet & startel, Point3d & pmin, Point3d & pmax) - { - int i, j, k, l; - const Point3d * pp[4]; - - ARRAY<Point3d> centers; - ARRAY<double> radi2; - - Point3d tpmin, tpmax; - - - // new: local box - mesh.GetBox (pmax, pmin); // lower bound for pmax, upper for pmin - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & face = adfront->GetFace(i); - for (j = 0; j < face.GetNP(); j++) - { - pmin.SetToMin (mesh.Point (face[j])); - pmax.SetToMax (mesh.Point (face[j])); - } - } - - for (i = 0; i < mesh.LockedPoints().Size(); i++) - { - pmin.SetToMin (mesh.Point (mesh.LockedPoints()[i])); - pmax.SetToMax (mesh.Point (mesh.LockedPoints()[i])); - } - - - - Vec3d vdiag(pmin, pmax); - // double r1 = vdiag.Length(); - double r1 = sqrt (3.0) * max3(vdiag.X(), vdiag.Y(), vdiag.Z()); - vdiag = Vec3d (r1, r1, r1); - double r2; - - Point3d pmin2 = pmin - 8 * vdiag; - Point3d pmax2 = pmax + 8 * vdiag; - - Point3d cp1(pmin2), cp2(pmax2), cp3(pmax2), cp4(pmax2); - cp2.X() = pmin2.X(); - cp3.Y() = pmin2.Y(); - cp4.Z() = pmin2.Z(); - - - - - int np = mesh.GetNP(); - - startel[0] = mesh.AddPoint (cp1); - startel[1] = mesh.AddPoint (cp2); - startel[2] = mesh.AddPoint (cp3); - startel[3] = mesh.AddPoint (cp4); - - // flag points to use for Delaunay: - BitArrayChar<PointIndex::BASE> usep(np); - usep.Clear(); - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & face = adfront->GetFace(i); - for (j = 0; j < face.GetNP(); j++) - usep.Set (face[j]); - } - - for (i = oldnp + PointIndex::BASE; - i < np + PointIndex::BASE; i++) - usep.Set (i); - - for (i = 0; i < mesh.LockedPoints().Size(); i++) - usep.Set (mesh.LockedPoints()[i]); - - - ARRAY<int> freelist; - - - int cntp = 0; - - MeshNB meshnb (tempels, mesh.GetNP() + 5); - SphereList list; - - pmin2 = pmin2 + 0.1 * (pmin2 - pmax2); - pmax2 = pmax2 + 0.1 * (pmax2 - pmin2); - - Box3dTree tettree(pmin2, pmax2); - - - tempels.Append (startel); - meshnb.Add (1); - list.AddElement (1); - ARRAY<int> connected, treesearch; - - - tpmin = tpmax = mesh.Point(startel[0]); - for (k = 1; k < 4; k++) - { - tpmin.SetToMin (mesh.Point (startel[k])); - tpmax.SetToMax (mesh.Point (startel[k])); - } - tpmax = tpmax + 0.01 * (tpmax - tpmin); - tettree.Insert (tpmin, tpmax, 1); - - - Point3d pc; - - for (k = 0; k < 4; k++) - pp[k] = &mesh.Point (startel[k]); - - CalcSphereCenter (&pp[0], pc); - - centers.Append (pc); - radi2.Append (Dist2 (*pp[0], pc)); - - - IndexSet insphere(mesh.GetNP()); - IndexSet closesphere(mesh.GetNP()); - - - -#ifdef MARK - MARK (delaunay1); -#endif - - - // "random" reordering of points (speeds a factor 3 - 5 !!!) - - ARRAY<int> mixed(np); - int prims[] = { 11, 13, 17, 19, 23, 29, 31, 37 }; - int prim; - - i = 0; - while (np % prims[i] == 0) i++; - prim = prims[i]; - - for (i = 1; i <= np; i++) - mixed.Elem(i) = (prim * i) % np + PointIndex::BASE; - - for (i = 1; i <= np; i++) - { - if (i % 100 == 0) - PrintDot ('+'); - - multithread.percent = 100.0 * i / np; - if (multithread.terminate) - break; - - PointIndex newpi = mixed.Get(i); - - if (!usep.Test(newpi)) - continue; - - cntp++; - - const Point3d & newp = mesh.Point(newpi); - - AddDelaunayPoint (newpi, newp, tempels, mesh, - tettree, meshnb, centers, radi2, - connected, treesearch, freelist, list, insphere, closesphere); - } - -#ifdef MARK - MARK (delaunay3); -#endif - - - - for (i = tempels.Size(); i >= 1; i--) - if (tempels.Get(i)[0] <= 0) - tempels.DeleteElement (i); - - PrintDot ('\n'); - - PrintMessage (3, "Points: ", cntp); - PrintMessage (3, "Elements: ", tempels.Size()); - // (*mycout) << cntp << " / " << tempels.Size() << " points/elements" << endl; - - /* - cout << "tempels: "; - tempels.PrintMemInfo(cout); - cout << "Searchtree: "; - tettree.Tree().PrintMemInfo(cout); - cout << "MeshNB: "; - meshnb.PrintMemInfo(cout); - */ - } - - - - - - - void Meshing3 :: Delaunay (Mesh & mesh, const MeshingParameters & mp) - { - PointIndex pi; - int i, j, k, l; - int ii; - int np, ne; - - PrintMessage (1, "Delaunay meshing"); - PrintMessage (3, "number of points: ", mesh.GetNP()); - PushStatus ("Delaunay meshing"); - - - - ARRAY<DelaunayTet> tempels; - - Point3d pmin, pmax; - Point3d tpmin, tpmax; - const Point3d * pp[4]; - - - DelaunayTet startel; - - int oldnp = mesh.GetNP(); - if (mp.blockfill) - { - BlockFillLocalH (mesh, mp); - PrintMessage (3, "number of points: ", mesh.GetNP()); - } - - np = mesh.GetNP(); - - Delaunay1 (mesh, mp, adfront, tempels, oldnp, startel, pmin, pmax); - - - { - // improve delaunay - mesh by swapping !!!! - - Mesh tempmesh; - for (pi = PointIndex::BASE; pi < mesh.GetNP()+PointIndex::BASE; pi++) - tempmesh.AddPoint (mesh[pi]); - - for (i = 1; i <= tempels.Size(); i++) - { - Element el(4); - for (j = 0; j < 4; j++) - el[j] = tempels.Elem(i)[j]; - - el.SetIndex (1); - - const Point3d & lp1 = mesh.Point (el[0]); - const Point3d & lp2 = mesh.Point (el[1]); - const Point3d & lp3 = mesh.Point (el[2]); - const Point3d & lp4 = mesh.Point (el[3]); - Vec3d v1(lp1, lp2); - Vec3d v2(lp1, lp3); - Vec3d v3(lp1, lp4); - Vec3d n = Cross (v1, v2); - double vol = n * v3; - - if (vol > 0) - swap (el[2], el[3]); - - tempmesh.AddVolumeElement (el); - } - - - MeshQuality3d (tempmesh); - - for (i = 1; i <= mesh.GetNOpenElements(); i++) - { - Element2d sel = mesh.OpenElement(i); - sel.SetIndex(1); - tempmesh.AddSurfaceElement (sel); - swap (sel[1], sel[2]); - tempmesh.AddSurfaceElement (sel); - } - - - for (i = 1; i <= 4; i++) - { - Element2d self(TRIG); - self.SetIndex (1); - startel.GetFace1 (i, self); - tempmesh.AddSurfaceElement (self); - } - - - tempmesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); - tempmesh.AddFaceDescriptor (FaceDescriptor (2, 1, 0, 0)); - - - // for (i = mesh.GetNP() - 3; i <= mesh.GetNP(); i++) - // tempmesh.AddLockedPoint (i); - for (pi = PointIndex::BASE; - pi < tempmesh.GetNP() + PointIndex::BASE; pi++) - tempmesh.AddLockedPoint (pi); - - // tempmesh.PrintMemInfo(cout); - // tempmesh.Save ("tempmesh.vol"); - - for (i = 1; i <= 2; i++) - { - tempmesh.FindOpenElements (); - - PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); - tempmesh.CalcSurfacesOfNode (); - - tempmesh.FreeOpenElementsEnvironment (1); - - MeshOptimize3d meshopt; - meshopt.SwapImprove(tempmesh, OPT_CONFORM); - } - - -#ifdef STAT_STREAM - tempmesh.FindOpenElements (); - PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); - (*statout) << tempmesh.GetNOpenElements() << " & " << endl; -#endif - - MeshQuality3d (tempmesh); - - tempels.SetSize(0); - for (i = 1; i <= tempmesh.GetNE(); i++) - tempels.Append (tempmesh.VolumeElement(i)); - } - - - - // remove degenerated - - BitArray badnode(mesh.GetNP()); - badnode.Clear(); - int ndeg = 0; - for (i = 1; i <= tempels.Size(); i++) - { - Element el(4); - for (j = 0; j < 4; j++) - el[j] = tempels.Elem(i)[j]; - // Element & el = tempels.Elem(i); - const Point3d & lp1 = mesh.Point (el[0]); - const Point3d & lp2 = mesh.Point (el[1]); - const Point3d & lp3 = mesh.Point (el[2]); - const Point3d & lp4 = mesh.Point (el[3]); - Vec3d v1(lp1, lp2); - Vec3d v2(lp1, lp3); - Vec3d v3(lp1, lp4); - Vec3d n = Cross (v1, v2); - double vol = n * v3; - - double h = v1.Length() + v2.Length() + v3.Length(); - if (fabs (vol) < 1e-8 * (h * h * h) && - (el[0] <= np && el[1] <= np && - el[2] <= np && el[3] <= np) ) // old: 1e-12 - { - badnode.Set(el[0]); - badnode.Set(el[1]); - badnode.Set(el[2]); - badnode.Set(el[3]); - ndeg++; - (*testout) << "vol = " << vol << " h = " << h << endl; - } - - if (vol > 0) - Swap (el[2], el[3]); - } - - ne = tempels.Size(); - for (i = ne; i >= 1; i--) - { - const DelaunayTet & el = tempels.Get(i); - if (badnode.Test(el[0]) || - badnode.Test(el[1]) || - badnode.Test(el[2]) || - badnode.Test(el[3]) ) - tempels.DeleteElement(i); - } - - - PrintMessage (3, ndeg, " degenerated elements removed"); - - // find surface triangles which are no face of any tet - - INDEX_3_HASHTABLE<int> openeltab(mesh.GetNOpenElements()+3); - ARRAY<int> openels; - for (i = 1; i <= mesh.GetNOpenElements(); i++) - { - const Element2d & tri = mesh.OpenElement(i); - INDEX_3 i3(tri[0], tri[1], tri[2]); - i3.Sort(); - openeltab.Set (i3, i); - } - - for (i = 1; i <= tempels.Size(); i++) - { - for (j = 0; j < 4; j++) - { - INDEX_3 i3 = tempels.Get(i).GetFace (j); - i3.Sort(); - if (openeltab.Used(i3)) - openeltab.Set (i3, 0); - } - } - - // and store them in openels - for (i = 1; i <= openeltab.GetNBags(); i++) - for (j = 1; j <= openeltab.GetBagSize(i); j++) - { - INDEX_3 i3; - int fnr; - openeltab.GetData (i, j, i3, fnr); - if (fnr) - openels.Append (fnr); - } - - - - - - // find open triangle with close edge (from halfening of surface squares) - - INDEX_2_HASHTABLE<INDEX_2> twotrias(mesh.GetNOpenElements()+5); - // for (i = 1; i <= mesh.GetNOpenElements(); i++) - for (ii = 1; ii <= openels.Size(); ii++) - { - i = openels.Get(ii); - const Element2d & el = mesh.OpenElement(i); - for (j = 1; j <= 3; j++) - { - INDEX_2 hi2 (el.PNumMod (j), el.PNumMod(j+1)); - hi2.Sort(); - if (twotrias.Used(hi2)) - { - INDEX_2 hi3; - hi3 = twotrias.Get (hi2); - hi3.I2() = el.PNumMod (j+2); - twotrias.Set (hi2, hi3); - } - else - { - INDEX_2 hi3(el.PNumMod (j+2), 0); - twotrias.Set (hi2, hi3); - } - } - } - - INDEX_2_HASHTABLE<int> tetedges(tempels.Size() + 5); - for (i = 1; i <= tempels.Size(); i++) - { - const DelaunayTet & el = tempels.Get(i); - INDEX_2 i2; - for (j = 1; j <= 6; j++) - { - switch (j) - { - case 1: i2 = INDEX_2(el[0], el[1]); break; - case 2: i2 = INDEX_2(el[0], el[2]); break; - case 3: i2 = INDEX_2(el[0], el[3]); break; - case 4: i2 = INDEX_2(el[1], el[2]); break; - case 5: i2 = INDEX_2(el[1], el[3]); break; - case 6: i2 = INDEX_2(el[2], el[3]); break; - } - i2.Sort(); - tetedges.Set (i2, 1); - } - } - // cout << "tetedges:"; - // tetedges.PrintMemInfo (cout); - - - for (INDEX_2_HASHTABLE<INDEX_2>::Iterator it = twotrias.Begin(); - it != twotrias.End(); it++) - { - INDEX_2 hi2, hi3; - twotrias.GetData (it, hi2, hi3); - hi3.Sort(); - if (tetedges.Used (hi3)) - { - const Point3d & p1 = mesh.Point ( PointIndex (hi2.I1())); - const Point3d & p2 = mesh.Point ( PointIndex (hi2.I2())); - const Point3d & p3 = mesh.Point ( PointIndex (hi3.I1())); - const Point3d & p4 = mesh.Point ( PointIndex (hi3.I2())); - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d v3(p1, p4); - Vec3d n = Cross (v1, v2); - double vol = n * v3; - - double h = v1.Length() + v2.Length() + v3.Length(); - if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 - { - badnode.Set(hi3.I1()); - badnode.Set(hi3.I2()); - } - } - } - - /* - for (i = 1; i <= twotrias.GetNBags(); i++) - for (j = 1; j <= twotrias.GetBagSize (i); j++) - { - INDEX_2 hi2, hi3; - twotrias.GetData (i, j, hi2, hi3); - hi3.Sort(); - if (tetedges.Used (hi3)) - { - const Point3d & p1 = mesh.Point (hi2.I1()); - const Point3d & p2 = mesh.Point (hi2.I2()); - const Point3d & p3 = mesh.Point (hi3.I1()); - const Point3d & p4 = mesh.Point (hi3.I2()); - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d v3(p1, p4); - Vec3d n = Cross (v1, v2); - double vol = n * v3; - - double h = v1.Length() + v2.Length() + v3.Length(); - if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 - { - badnode.Set(hi3.I1()); - badnode.Set(hi3.I2()); - } - } - } - */ - - ne = tempels.Size(); - for (i = ne; i >= 1; i--) - { - const DelaunayTet & el = tempels.Get(i); - if (badnode.Test(el[0]) || - badnode.Test(el[1]) || - badnode.Test(el[2]) || - badnode.Test(el[3]) ) - tempels.DeleteElement(i); - } - - - - - // find intersecting: - PrintMessage (3, "Remove intersecting"); - if (openels.Size()) - { - Box3dTree setree(pmin, pmax); - - /* - cout << "open elements in search tree: " << openels.Size() << endl; - cout << "pmin, pmax = " << pmin << " - " << pmax << endl; - */ - - for (i = 1; i <= openels.Size(); i++) - { - int fnr; - fnr = openels.Get(i); - if (fnr) - { - const Element2d & tri = mesh.OpenElement(fnr); - - Point3d ltpmin (mesh.Point(tri[0])); - Point3d ltpmax (tpmin); - - for (k = 2; k <= 3; k++) - { - ltpmin.SetToMin (mesh.Point (tri.PNum(k))); - ltpmax.SetToMax (mesh.Point (tri.PNum(k))); - } - setree.Insert (ltpmin, ltpmax, fnr); - } - } - - ARRAY<int> neartrias; - for (i = 1; i <= tempels.Size(); i++) - { - // const Point3d *pp[4]; - int tetpi[4]; - DelaunayTet & el = tempels.Elem(i); - - int intersect = 0; - - for (j = 0; j < 4; j++) - { - pp[j] = &mesh.Point(el[j]); - tetpi[j] = el[j]; - } - - Point3d tetpmin(*pp[0]); - Point3d tetpmax(tetpmin); - for (j = 1; j < 4; j++) - { - tetpmin.SetToMin (*pp[j]); - tetpmax.SetToMax (*pp[j]); - } - tetpmin = tetpmin + 0.01 * (tetpmin - tetpmax); - tetpmax = tetpmax + 0.01 * (tetpmax - tetpmin); - - setree.GetIntersecting (tetpmin, tetpmax, neartrias); - - - // for (j = 1; j <= mesh.GetNSE(); j++) - // { - for (int jj = 1; jj <= neartrias.Size(); jj++) - { - j = neartrias.Get(jj); - - const Element2d & tri = mesh.OpenElement(j); - const Point3d *tripp[3]; - int tripi[3]; - - for (k = 1; k <= 3; k++) - { - tripp[k-1] = &mesh.Point (tri.PNum(k)); - tripi[k-1] = tri.PNum(k); - } - - if (IntersectTetTriangle (&pp[0], &tripp[0], tetpi, tripi)) - { - /* - int il1, il2; - (*testout) << "intersect !" << endl; - (*testout) << "triind: "; - for (il1 = 0; il1 < 3; il1++) - (*testout) << " " << tripi[il1]; - (*testout) << endl; - (*testout) << "tetind: "; - for (il2 = 0; il2 < 4; il2++) - (*testout) << " " << tetpi[il2]; - (*testout) << endl; - - (*testout) << "trip: "; - for (il1 = 0; il1 < 3; il1++) - (*testout) << " " << *tripp[il1]; - (*testout) << endl; - (*testout) << "tetp: "; - for (il2 = 0; il2 < 4; il2++) - (*testout) << " " << *pp[il2]; - (*testout) << endl; - */ - - - intersect = 1; - break; - } - } - - - if (intersect) - { - tempels.DeleteElement(i); - i--; - } - } - } - - -#ifdef MARK - MARK (delaunay4); -#endif - - - - - - - - - PrintMessage (3, "Remove outer"); - - // find connected tets (with no face between, and no hole due - // to removed intersecting tets. - // INDEX_3_HASHTABLE<INDEX_2> innerfaces(np); - - - INDEX_3_HASHTABLE<int> boundaryfaces(mesh.GetNOpenElements()/3+1); - for (i = 1; i <= mesh.GetNOpenElements(); i++) - { - const Element2d & tri = mesh.OpenElement(i); - INDEX_3 i3 (tri[0], tri[1], tri[2]); - i3.Sort(); - boundaryfaces.PrepareSet (i3); - } - boundaryfaces.AllocateElements(); - for (i = 1; i <= mesh.GetNOpenElements(); i++) - { - const Element2d & tri = mesh.OpenElement(i); - INDEX_3 i3 (tri[0], tri[1], tri[2]); - i3.Sort(); - boundaryfaces.Set (i3, 1); - } - - for (i = 0; i < tempels.Size(); i++) - for (j = 0; j < 4; j++) - tempels[i].NB(j) = 0; - - TABLE<int,PointIndex::BASE> elsonpoint(mesh.GetNP()); - for (i = 0; i < tempels.Size(); i++) - { - const DelaunayTet & el = tempels[i]; - INDEX_4 i4(el[0], el[1], el[2], el[3]); - i4.Sort(); - elsonpoint.IncSizePrepare (i4.I1()); - elsonpoint.IncSizePrepare (i4.I2()); - } - - elsonpoint.AllocateElementsOneBlock(); - - for (i = 0; i < tempels.Size(); i++) - { - const DelaunayTet & el = tempels[i]; - INDEX_4 i4(el[0], el[1], el[2], el[3]); - i4.Sort(); - elsonpoint.Add (i4.I1(), i+1); - elsonpoint.Add (i4.I2(), i+1); - } - - // cout << "elsonpoint mem: "; - // elsonpoint.PrintMemInfo(cout); - - INDEX_3_CLOSED_HASHTABLE<INDEX_2> faceht(100); - - Element2d hel(TRIG); - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - faceht.SetSize (4 * elsonpoint[pi].Size()); - for (ii = 0; ii < elsonpoint[pi].Size(); ii++) - { - i = elsonpoint[pi][ii]; - const DelaunayTet & el = tempels.Get(i); - - for (j = 1; j <= 4; j++) - { - el.GetFace1 (j, hel); - hel.Invert(); - hel.NormalizeNumbering(); - - if (hel[0] == pi) - { - INDEX_3 i3(hel[0], hel[1], hel[2]); - - if (!boundaryfaces.Used (i3)) - { - if (faceht.Used (i3)) - { - INDEX_2 i2 = faceht.Get(i3); - - tempels.Elem(i).NB1(j) = i2.I1(); - tempels.Elem(i2.I1()).NB1(i2.I2()) = i; - } - else - { - hel.Invert(); - hel.NormalizeNumbering(); - INDEX_3 i3(hel[0], hel[1], hel[2]); - INDEX_2 i2(i, j); - faceht.Set (i3, i2); - } - } - } - } - } - } - - /* - for (i = 1; i <= tempels.Size(); i++) - { - const DelaunayTet & el = tempels.Get(i); - for (j = 1; j <= 4; j++) - { - INDEX_3 i3; - Element2d face; - el.GetFace1 (j, face); - for (int kk = 1; kk <= 3; kk++) - i3.I(kk) = face.PNum(kk); - - i3.Sort(); - if (!boundaryfaces.Used (i3)) - { - if (innerfaces.Used(i3)) - { - INDEX_2 i2; - i2 = innerfaces.Get(i3); - i2.I2() = i; - innerfaces.Set (i3, i2); - } - else - { - INDEX_2 i2; - i2.I1() = i; - i2.I2() = 0; - innerfaces.Set (i3, i2); - } - } - } - } - */ - - /* - (*testout) << "nb elements:" << endl; - for (i = 1; i <= tempels.Size(); i++) - { - (*testout) << i << " "; - for (j = 1; j <= 4; j++) - (*testout) << tempels.Get(i).NB1(j) << " "; - (*testout) << endl; - } - - (*testout) << "pairs:" << endl; - for (i = 1; i <= innerfaces.GetNBags(); i++) - for (j = 1; j <= innerfaces.GetBagSize(i); j++) - { - INDEX_3 i3; - INDEX_2 i2; - innerfaces.GetData (i, j, i3, i2); - (*testout) << i2 << endl; - } - */ - - - - - - - - /* - cout << "innerfaces: "; - innerfaces.PrintMemInfo (cout); - */ - - // cout << "boundaryfaces: "; - // boundaryfaces.PrintMemInfo (cout); - - - PrintMessage (5, "tables filled"); - - - ne = tempels.Size(); - BitArray inner(ne), outer(ne); - inner.Clear(); - outer.Clear(); - ARRAY<int> elstack; - - /* - int starti = 0; - for (i = 1; i <= ne; i++) - { - const Element & el = tempels.Get(i); - for (j = 1; j <= 4; j++) - for (k = 1; k <= 4; k++) - if (el.PNum(j) == startel.PNum(k)) - { - outer.Set(i); - starti = i; - } - } - */ - - while (1) - { - int inside; - bool done = 1; - - for (i = 1; i <= ne; i++) - if (!inner.Test(i) && !outer.Test(i)) - { - done = 0; - break; - } - - if (done) break; - - const DelaunayTet & el = tempels.Get(i); - const Point3d & p1 = mesh.Point (el[0]); - const Point3d & p2 = mesh.Point (el[1]); - const Point3d & p3 = mesh.Point (el[2]); - const Point3d & p4 = mesh.Point (el[3]); - - Point3d ci = Center (p1, p2, p3, p4); - - inside = adfront->Inside (ci); - - /* - cout << "startel: " << i << endl; - cout << "inside = " << inside << endl; - cout << "ins2 = " << adfront->Inside (Center (ci, p1)) << endl; - cout << "ins3 = " << adfront->Inside (Center (ci, p2)) << endl; - */ - - elstack.SetSize(0); - elstack.Append (i); - - while (elstack.Size()) - { - int ei = elstack.Last(); - elstack.DeleteLast(); - - if (!inner.Test(ei) && !outer.Test(ei)) - { - if (inside) - inner.Set(ei); - else - outer.Set(ei); - - - for (j = 1; j <= 4; j++) - { - INDEX_3 i3 = tempels.Get(ei).GetFace1(j); - /* - Element2d face; - tempels.Get(ei).GetFace(j, face); - for (int kk = 1; kk <= 3; kk++) - i3.I(kk) = face.PNum(kk); - */ - i3.Sort(); - - - if (tempels.Get(ei).NB1(j)) - elstack.Append (tempels.Get(ei).NB1(j)); - - /* - if (innerfaces.Used(i3)) - { - INDEX_2 i2 = innerfaces.Get(i3); - int other = i2.I1() + i2.I2() - ei; - - if (other != tempels.Get(ei).NB1(j)) - cerr << "different1 !!" << endl; - - if (other) - { - elstack.Append (other); - } - } - else - if (tempels.Get(ei).NB1(j)) - cerr << "different2 !!" << endl; - */ - - } - } - } - } - - - - // check outer elements - if (debugparam.slowchecks) - { - for (i = 1; i <= ne; i++) - { - const DelaunayTet & el = tempels.Get(i); - const Point3d & p1 = mesh.Point (el[0]); - const Point3d & p2 = mesh.Point (el[1]); - const Point3d & p3 = mesh.Point (el[2]); - const Point3d & p4 = mesh.Point (el[3]); - - Point3d ci = Center (p1, p2, p3, p4); - - // if (adfront->Inside (ci) != adfront->Inside (Center (ci, p1))) - // cout << "ERROR: outer test unclear !!!" << endl; - - if (inner.Test(i) != adfront->Inside (ci)) - { - /* - cout << "ERROR: outer test wrong !!!" - << "inner = " << int(inner.Test(i)) - << "outer = " << int(outer.Test(i)) - << endl; - - cout << "Vol = " << Determinant(Vec3d(p1, p2), - Vec3d(p1, p3), - Vec3d(p1, p4)) << endl; - - */ - for (j = 1; j <= 4; j++) - { - Point3d hp; - switch (j) - { - case 1: hp = Center (ci, p1); break; - case 2: hp = Center (ci, p2); break; - case 3: hp = Center (ci, p3); break; - case 4: hp = Center (ci, p4); break; - } - // cout << "inside(" << hp << ") = " << adfront->Inside(hp) << endl; - } - - } - - if (adfront->Inside(ci)) - outer.Clear(i); - else - outer.Set(i); - } - } - - - /* - - // find bug in innerfaces - - tempmesh.DeleteVolumeElements(); - - for (i = 1; i <= innerfaces.GetNBags(); i++) - for (j = 1; j <= innerfaces.GetBagSize(i); j++) - { - INDEX_3 i3; - INDEX_2 i2; - innerfaces.GetData (i, j, i3, i2); - if (i2.I2()) - { - if (outer.Test(i2.I1()) != outer.Test(i2.I2())) - { - tempmesh.AddVolumeElement (tempels.Get(i2.I1())); - tempmesh.AddVolumeElement (tempels.Get(i2.I2())); - cerr << "outer flag different for connected els" << endl; - } - } - } - - - cout << "Check intersectiong once more" << endl; - - for (i = 1; i <= openels.Size(); i++) - { - tempmesh.SurfaceElement(2*openels.Get(i)).SetIndex(2); - tempmesh.SurfaceElement(2*openels.Get(i)-1).SetIndex(2); - } - - // for (i = 1; i <= tempmesh.GetNE(); i++) - // for (j = 1; j <= tempmesh.GetNSE(); j++) - i = 6; j = 403; - if (i <= tempmesh.GetNE() && j <= tempmesh.GetNSE()) - if (tempmesh.SurfaceElement(j).GetIndex()==2) - { - const Element & el = tempmesh.VolumeElement(i); - const Element2d & sel = tempmesh.SurfaceElement(j); - - const Point3d *tripp[3]; - const Point3d *pp[4]; - int tetpi[4], tripi[3]; - - for (k = 1; k <= 4; k++) - { - pp[k-1] = &tempmesh.Point(el.PNum(k)); - tetpi[k-1] = el.PNum(k); - } - - for (k = 1; k <= 3; k++) - { - tripp[k-1] = &tempmesh.Point (sel.PNum(k)); - tripi[k-1] = sel.PNum(k); - } - - (*testout) << "Check Triangle " << j << ":"; - for (k = 1; k <= 3; k++) - (*testout) << " " << sel.PNum(k); - for (k = 1; k <= 3; k++) - (*testout) << " " << tempmesh.Point(sel.PNum(k)); - (*testout) << endl; - - (*testout) << "Check Tet " << i << ":"; - for (k = 1; k <= 4; k++) - (*testout) << " " << el.PNum(k); - for (k = 1; k <= 4; k++) - (*testout) << " " << tempmesh.Point(el.PNum(k)); - (*testout) << endl; - - if (IntersectTetTriangle (&pp[0], &tripp[0], tetpi, tripi)) - { - cout << "Intesection detected !!" << endl; - } - } - - tempmesh.Save ("temp.vol"); - - // end bug search - */ - - - for (i = ne; i >= 1; i--) - { - if (outer.Test(i)) - tempels.DeleteElement(i); - } - - - // (*mycout) << "done" << endl; - - - // mesh.points.SetSize(mesh.points.Size()-4); - - for (i = 1; i <= tempels.Size(); i++) - { - Element el(4); - for (j = 0; j < 4; j++) - el[j] = tempels.Elem(i)[j]; - mesh.AddVolumeElement (el); - } - - PrintMessage (5, "outer removed"); - - mesh.FindOpenElements(); - - mesh.Compress(); - - PopStatus (); - } -} diff --git a/Netgen/libsrc/meshing/findip.cpp b/Netgen/libsrc/meshing/findip.cpp deleted file mode 100644 index 7be0ee913d..0000000000 --- a/Netgen/libsrc/meshing/findip.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// find inner point - -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - - -template <typename POINTARRAY, typename FACEARRAY> -int FindInnerPoint (POINTARRAY & points, - FACEARRAY & faces, - Point3d & p) -{ - int i, j; - ARRAY<Vec3d> a; - ARRAY<double> c; - Point3d p1, pmin; - int i1, i2, i3, i4; - int nf; - DenseMatrix m(3), inv(3); - Vector rs(3), x(3); - double f, fmin, hd, hmax; - - nf = faces.Size(); - - // testout << "#faces = " << faces.Size() << endl; - // testout << "#points = " << points.Size() << endl; - - a.SetSize (nf); - c.SetSize (nf); - - for (i = 1; i <= nf; i++) - { - p1 = points.Get(faces.Get(i).PNum(1)); - a.Elem(i) = Cross (points.Get(faces.Get(i).PNum(2)) - points.Get(faces.Get(i).PNum(1)), - points.Get(faces.Get(i).PNum(3)) - points.Get(faces.Get(i).PNum(1))); - a.Elem(i) /= a.Get(i).Length(); - c.Elem(i) = - (a.Get(i).X() * p1.X() + a.Get(i).Y() * p1.Y() + a.Get(i).Z() * p1.Z()); - } - - - hmax = 0; - for (i = 1; i <= nf; i++) - { - const Element2d & el = faces.Get(i); - for (j = 1; j <= 3; j++) - { - double hi = Dist (points.Get(el.PNumMod(j)), - points.Get(el.PNumMod(j+1))); - if (hi > hmax) hmax = hi; - } - } - - - fmin = 100; - pmin = Point3d (0, 0, 0); - - for (i1 = 1; i1 <= nf; i1++) - for (i2 = i1+1; i2 <= nf; i2++) - for (i3 = i2+1; i3 <= nf; i3++) - for (i4 = i3+1; i4 <= nf; i4++) - { - m.Elem(1, 1) = a.Get(i1).X() - a.Get(i2).X(); - m.Elem(1, 2) = a.Get(i1).Y() - a.Get(i2).Y(); - m.Elem(1, 3) = a.Get(i1).Z() - a.Get(i2).Z(); - rs.Elem(1) = c.Get(i2) - c.Get(i1); - - m.Elem(2, 1) = a.Get(i1).X() - a.Get(i3).X(); - m.Elem(2, 2) = a.Get(i1).Y() - a.Get(i3).Y(); - m.Elem(2, 3) = a.Get(i1).Z() - a.Get(i3).Z(); - rs.Elem(2) = c.Get(i3) - c.Get(i1); - - m.Elem(3, 1) = a.Get(i1).X() - a.Get(i4).X(); - m.Elem(3, 2) = a.Get(i1).Y() - a.Get(i4).Y(); - m.Elem(3, 3) = a.Get(i1).Z() - a.Get(i4).Z(); - rs.Elem(3) = c.Get(i4) - c.Get(i1); - - - if (fabs (m.Det()) > 1e-10) - { - CalcInverse (m, inv); - inv.Mult (rs, x); - - // testout << "x = " << x << endl; - - - f = -1e10; - for (i = 1; i <= nf; i++) - { - hd = x.Elem(1) * a.Get(i).X() - + x.Elem(2) * a.Get(i).Y() - + x.Elem(3) * a.Get(i).Z() - + c.Get(i); - if (hd > f) f = hd; - } - - if (f < fmin) - { - fmin = f; - pmin.X() = x.Elem(1); - pmin.Y() = x.Elem(2); - pmin.Z() = x.Elem(3); - } - } - } - - // testout << "fmin = " << fmin << endl; - // testout << "pmin = " << pmin << endl; - - p = pmin; - return (fmin < -1e-3 * hmax) ? 1 : 0; - // return (fmin < 0) ? 1 : 0; -} -} diff --git a/Netgen/libsrc/meshing/findip.hpp b/Netgen/libsrc/meshing/findip.hpp deleted file mode 100644 index a0aed91b6c..0000000000 --- a/Netgen/libsrc/meshing/findip.hpp +++ /dev/null @@ -1,108 +0,0 @@ -// find inner point - -template <typename POINTARRAY, typename FACEARRAY> -inline int FindInnerPoint (POINTARRAY & points, - FACEARRAY & faces, - Point3d & p) -{ - int i, j; - ARRAY<Vec3d> a; - ARRAY<double> c; - Point3d p1, pmin; - int i1, i2, i3, i4; - int nf; - DenseMatrix m(3), inv(3); - Vector rs(3), x(3); - double f, fmin, hd, hmax; - - nf = faces.Size(); - - // testout << "#faces = " << faces.Size() << endl; - // testout << "#points = " << points.Size() << endl; - - a.SetSize (nf); - c.SetSize (nf); - - for (i = 1; i <= nf; i++) - { - p1 = points.Get(faces.Get(i).PNum(1)); - a.Elem(i) = Cross (points.Get(faces.Get(i).PNum(2)) - points.Get(faces.Get(i).PNum(1)), - points.Get(faces.Get(i).PNum(3)) - points.Get(faces.Get(i).PNum(1))); - a.Elem(i) /= a.Get(i).Length(); - c.Elem(i) = - (a.Get(i).X() * p1.X() + a.Get(i).Y() * p1.Y() + a.Get(i).Z() * p1.Z()); - } - - - hmax = 0; - for (i = 1; i <= nf; i++) - { - const Element2d & el = faces.Get(i); - for (j = 1; j <= 3; j++) - { - double hi = Dist (points.Get(el.PNumMod(j)), - points.Get(el.PNumMod(j+1))); - if (hi > hmax) hmax = hi; - } - } - - - fmin = 100; - pmin = Point3d (0, 0, 0); - - for (i1 = 1; i1 <= nf; i1++) - for (i2 = i1+1; i2 <= nf; i2++) - for (i3 = i2+1; i3 <= nf; i3++) - for (i4 = i3+1; i4 <= nf; i4++) - { - m.Elem(1, 1) = a.Get(i1).X() - a.Get(i2).X(); - m.Elem(1, 2) = a.Get(i1).Y() - a.Get(i2).Y(); - m.Elem(1, 3) = a.Get(i1).Z() - a.Get(i2).Z(); - rs.Elem(1) = c.Get(i2) - c.Get(i1); - - m.Elem(2, 1) = a.Get(i1).X() - a.Get(i3).X(); - m.Elem(2, 2) = a.Get(i1).Y() - a.Get(i3).Y(); - m.Elem(2, 3) = a.Get(i1).Z() - a.Get(i3).Z(); - rs.Elem(2) = c.Get(i3) - c.Get(i1); - - m.Elem(3, 1) = a.Get(i1).X() - a.Get(i4).X(); - m.Elem(3, 2) = a.Get(i1).Y() - a.Get(i4).Y(); - m.Elem(3, 3) = a.Get(i1).Z() - a.Get(i4).Z(); - rs.Elem(3) = c.Get(i4) - c.Get(i1); - - - if (fabs (m.Det()) > 1e-10) - { - CalcInverse (m, inv); - inv.Mult (rs, x); - - // testout << "x = " << x << endl; - - - f = -1e10; - for (i = 1; i <= nf; i++) - { - hd = x.Elem(1) * a.Get(i).X() - + x.Elem(2) * a.Get(i).Y() - + x.Elem(3) * a.Get(i).Z() - + c.Get(i); - if (hd > f) f = hd; - } - - if (f < fmin) - { - fmin = f; - pmin.X() = x.Elem(1); - pmin.Y() = x.Elem(2); - pmin.Z() = x.Elem(3); - } - } - } - - // testout << "fmin = " << fmin << endl; - // testout << "pmin = " << pmin << endl; - - p = pmin; - return (fmin < -1e-3 * hmax) ? 1 : 0; - // return (fmin < 0) ? 1 : 0; -} - diff --git a/Netgen/libsrc/meshing/geomsearch.cpp b/Netgen/libsrc/meshing/geomsearch.cpp deleted file mode 100644 index 1c37637816..0000000000 --- a/Netgen/libsrc/meshing/geomsearch.cpp +++ /dev/null @@ -1,263 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ - GeomSearch3d :: GeomSearch3d() - { - size.i1 = 0; size.i2 = 0; size.i3 = 0; - } - - GeomSearch3d :: ~GeomSearch3d() - { - //delete old Hashtable: - if (size.i1 != 0) - { - for (int i = 0; i < size.i1*size.i2*size.i3; i++) - delete hashtable[i]; - } - } - - void GeomSearch3d :: Init (ARRAY <FrontPoint3,PointIndex::BASE> *pointsi, ARRAY <FrontFace> *facesi) - { - points = pointsi; - faces = facesi; - size.i1 = 0; size.i2 = 0; size.i3 = 0; - reset = 1; - hashcount = 1; - } - - void GeomSearch3d :: ElemMaxExt(Point3d& minp, Point3d& maxp, const Element2d& elem) - { - maxp.X()=(*points)[elem.PNum(1)].P().X(); - maxp.Y()=(*points)[elem.PNum(1)].P().Y(); - maxp.Z()=(*points)[elem.PNum(1)].P().Z(); - minp.X()=(*points)[elem.PNum(1)].P().X(); - minp.Y()=(*points)[elem.PNum(1)].P().Y(); - minp.Z()=(*points)[elem.PNum(1)].P().Z(); - - for (int i=2; i <= 3; i++) - { - maxp.X()=max2((*points)[elem.PNum(i)].P().X(),maxp.X()); - maxp.Y()=max2((*points)[elem.PNum(i)].P().Y(),maxp.Y()); - maxp.Z()=max2((*points)[elem.PNum(i)].P().Z(),maxp.Z()); - minp.X()=min2((*points)[elem.PNum(i)].P().X(),minp.X()); - minp.Y()=min2((*points)[elem.PNum(i)].P().Y(),minp.Y()); - minp.Z()=min2((*points)[elem.PNum(i)].P().Z(),minp.Z()); - } - } - - void GeomSearch3d :: MinCoords(const Point3d& p1, Point3d& p2) - { - p2.X()=min2(p1.X(),p2.X()); - p2.Y()=min2(p1.Y(),p2.Y()); - p2.Z()=min2(p1.Z(),p2.Z()); - } - - void GeomSearch3d :: MaxCoords(const Point3d& p1, Point3d& p2) - { - p2.X()=max2(p1.X(),p2.X()); - p2.Y()=max2(p1.Y(),p2.Y()); - p2.Z()=max2(p1.Z(),p2.Z()); - } - - void GeomSearch3d :: Create() - { - INDEX i,j,k; - if (reset) - { - const double hashelemsizefactor = 4; - reset = 0; - /* - minext=Point3d(MAXDOUBLE, MAXDOUBLE, MAXDOUBLE); - maxext=Point3d(MINDOUBLE, MINDOUBLE, MINDOUBLE); - */ - ElemMaxExt(minext, maxext, faces->Get(1).Face()); - Point3d maxp, minp; - Vec3d midext(0,0,0); - - //get max Extension of Frontfaces - for (i = 1; i <= faces->Size(); i++) - { - ElemMaxExt(minp, maxp, faces->Get(i).Face()); - MinCoords(minp, minext); - MaxCoords(maxp, maxext); - midext+=maxp-minp; - } - - - maxextreal = maxext; - maxext = maxext + 1e-4 * (maxext - minext); - - midext*=1./faces->Size(); - Vec3d boxext = maxext - minext; - - //delete old Hashtable: - if (size.i1 != 0) - { - for (i = 1; i <= size.i1*size.i2*size.i3; i++) - { - delete hashtable.Get(i); - } - } - - size.i1 = int (boxext.X()/midext.X()/hashelemsizefactor+1); - size.i2 = int (boxext.Y()/midext.Y()/hashelemsizefactor+1); - size.i3 = int (boxext.Z()/midext.Z()/hashelemsizefactor+1); - PrintMessage (5, "hashsizes = ", size.i1, ", ", size.i2, ", ", size.i3); - - elemsize.X()=boxext.X()/size.i1; - elemsize.Y()=boxext.Y()/size.i2; - elemsize.Z()=boxext.Z()/size.i3; - - //create Hasharrays: - hashtable.SetSize(size.i1*size.i2*size.i3); - for (i = 1; i <= size.i1; i++) - { - for (j = 1; j <= size.i2; j++) - { - for (k = 1; k <= size.i3; k++) - { - INDEX ind=i+(j-1)*size.i1+(k-1)*size.i2*size.i1; - hashtable.Elem(ind) = new ARRAY <int> (); - } - } - } - } - else - { - //Clear all Hash-Arrays - for (i = 1; i <= size.i1; i++) - { - for (j = 1; j <= size.i2; j++) - { - for (k = 1; k <= size.i3; k++) - { - INDEX ind=i+(j-1)*size.i1+(k-1)*size.i2*size.i1; - hashtable.Elem(ind)->SetSize(0); - } - } - } - } - - //Faces in Hashtable einfuegen: - for (i = 1; i <= faces->Size(); i++) - { - AddElem(faces->Get(i).Face(),i); - } - - } - - void GeomSearch3d :: AddElem(const Element2d& elem, INDEX elemnum) - { - Point3d minp, maxp; - ElemMaxExt(minp, maxp, elem); - int sx = int ((minp.X()-minext.X())/elemsize.X()+1.); - int ex = int ((maxp.X()-minext.X())/elemsize.X()+1.); - int sy = int ((minp.Y()-minext.Y())/elemsize.Y()+1.); - int ey = int ((maxp.Y()-minext.Y())/elemsize.Y()+1.); - int sz = int ((minp.Z()-minext.Z())/elemsize.Z()+1.); - int ez = int ((maxp.Z()-minext.Z())/elemsize.Z()+1.); - int ix,iy,iz; - - for (ix = sx; ix <= ex; ix++) - { - for (iy = sy; iy <= ey; iy++) - { - for (iz = sz; iz <= ez; iz++) - { - INDEX ind=ix+(iy-1)*size.i1+(iz-1)*size.i2*size.i1; - if (ind < 1 || ind > size.i1 * size.i2 * size.i3) - { - cerr << "Illegal hash-position"; - cerr << "Position: " << ix << "," << iy << "," << iz << endl; - } - hashtable.Elem(ind)->Append(elemnum); - } - } - } - } - - void GeomSearch3d :: GetLocals(ARRAY<Element2d> & locfaces, ARRAY<INDEX> & findex, - INDEX fstind, const Point3d& p0, double xh) - { - hashcount++; - - Point3d minp, maxp, midp; - - minp=p0-Vec3d(xh,xh,xh); //lay cube over sphere - maxp=p0+Vec3d(xh,xh,xh); - - MaxCoords(minext,minp); //cube may not be out of hash-region - MinCoords(maxextreal,maxp); - - - int cluster = faces->Get(fstind).Cluster(); - - int sx = int((minp.X()-minext.X())/elemsize.X()+1.); - int ex = int((maxp.X()-minext.X())/elemsize.X()+1.); - int sy = int((minp.Y()-minext.Y())/elemsize.Y()+1.); - int ey = int((maxp.Y()-minext.Y())/elemsize.Y()+1.); - int sz = int((minp.Z()-minext.Z())/elemsize.Z()+1.); - int ez = int((maxp.Z()-minext.Z())/elemsize.Z()+1.); - int ix,iy,iz,i,k; - - int cnt1 = 0; // test, how efficient hashtable is - int cnt2 = 0; - int cnt3 = 0; - - for (ix = sx; ix <= ex; ix++) - { - for (iy = sy; iy <= ey; iy++) - { - for (iz = sz; iz <= ez; iz++) - { - INDEX ind=ix+(iy-1)*size.i1+(iz-1)*size.i2*size.i1; - - //go through all elements in one hash area - const ARRAY <int> & area = *hashtable.Elem(ind); - for (k = 1; k <= area.Size(); k++) - { - cnt2++; - i = area.Get(k); - if (faces->Get(i).Cluster() == cluster && - faces->Get(i).Valid() && - faces->Get(i).HashValue() != hashcount && - i != fstind) - { - cnt1++; - const Element2d & face = faces->Get(i).Face(); - - const Point3d & p1 = (*points)[face.PNum(1)].P(); - const Point3d & p2 = (*points)[face.PNum(2)].P(); - const Point3d & p3 = (*points)[face.PNum(3)].P(); - - midp = Center (p1, p2, p3); - - if (Dist2 (midp, p0) <= xh*xh) - { - cnt3++; - locfaces.Append(faces->Get(i).Face()); - findex.Append(i); - faces->Elem(i).SetHashValue(hashcount); - } - } - } - } - } - } - /* - if (faces->Size() != 0 && hashcount % 200 == 0) - { - (*mycout) << "n.o.f= " << faces->Size(); - (*mycout) << ", n.o.lf= " << locfaces.Size(); - (*mycout) << ", hashf= " << (double)cnt2/(double)faces->Size(); - (*mycout) << " (" << (double)cnt1/(double)faces->Size(); - (*mycout) << ", " << (double)cnt3/(double)faces->Size() << ")" << endl; - } - */ - - } - -} diff --git a/Netgen/libsrc/meshing/geomsearch.hpp b/Netgen/libsrc/meshing/geomsearch.hpp deleted file mode 100644 index 5364c24f8d..0000000000 --- a/Netgen/libsrc/meshing/geomsearch.hpp +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef FILE_GEOMSEARCH -#define FILE_GEOMSEARCH - -/**************************************************************************/ -/* File: geomsearch.hh */ -/* Author: Johannes Gerstmayr */ -/* Date: 19. Nov. 97 */ -/**************************************************************************/ - -class FrontPoint3; -class FrontFace; - - /// class for quick access of 3D-elements; class cannot delete elements, but only append -class GeomSearch3d -{ - -public: - /// - GeomSearch3d(); - /// - virtual ~GeomSearch3d(); - - /// - void Init (ARRAY <FrontPoint3,PointIndex::BASE> *pointsi, ARRAY <FrontFace> *facesi); - - ///get elements max extension - void ElemMaxExt(Point3d& minp, Point3d& maxp, const Element2d& elem); - - ///get minimum coordinates of two points ->p2 - void MinCoords(const Point3d& p1, Point3d& p2); - - ///get minimum coordinates of two points ->p2 - void MaxCoords(const Point3d& p1, Point3d& p2); - - ///create a hashtable from an existing array of triangles - ///sizei = number of pieces in one direction - void Create(); - - ///add new element to Hashtable - void AddElem(const Element2d& elem, INDEX elemnum); - - ///GetLocal faces in sphere with radius xh and middlepoint p - void GetLocals(ARRAY<Element2d> & locfaces, ARRAY<INDEX> & findex, - INDEX fstind, const Point3d& p0, double xh); - -private: - - ARRAY <FrontFace> *faces; // Pointers to Arrays in Adfront - ARRAY <FrontPoint3,PointIndex::BASE> *points; - - ARRAY <ARRAY <int>*> hashtable; - - Point3d minext; //extension of Hashdomain - Point3d maxext; - Point3d maxextreal; - Vec3d elemsize; //size of one Hash-Element - - threeint size; // size of Hashtable in each direction - int reset; - int hashcount; -}; - -#endif - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Netgen/libsrc/meshing/global.cpp b/Netgen/libsrc/meshing/global.cpp deleted file mode 100644 index 60a1fbe51d..0000000000 --- a/Netgen/libsrc/meshing/global.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - ostream * testout = &cout; - - ostream * mycout = &cout; - ostream * myerr = &cerr; - - - // Flags globflags; // not used anymoure - Flags parameters; - - - int silentflag = 0; - int testmode = 0; - - MeshingParameters mparam; - volatile multithreadt multithread; - - string ngdir = "."; - - ARRAY<int> tets_in_qualclass; - - - multithreadt :: multithreadt() - { - pause =0; - testmode = 0; - redraw = 0; - drawing = 0; - terminate = 0; - running = 0; - percent = 0; - task = ""; - } - - DebugParameters debugparam; - bool verbose = 0; - - int timestamp = 0; - int GetTimeStamp() - { - return timestamp; - } - - int NextTimeStamp() - { - timestamp++; - return timestamp; - } -} diff --git a/Netgen/libsrc/meshing/global.hpp b/Netgen/libsrc/meshing/global.hpp deleted file mode 100644 index 843231d0c5..0000000000 --- a/Netgen/libsrc/meshing/global.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef FILE_GLOBAL -#define FILE_GLOBAL - - -/**************************************************************************/ -/* File: global.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - -/* - global functions and variables -*/ - -/// -extern double GetTime (); -extern void ResetTime (); - -/// -extern int testmode; - -// extern ostream * testout; -// extern AutoPtr<ostream> testout; - -/// calling parameters -extern Flags parameters; - -extern MeshingParameters mparam; - -extern ARRAY<int> tets_in_qualclass; - - -class multithreadt -{ -public: - int pause; - int testmode; - int redraw; - int drawing; - int terminate; - int running; - double percent; - char * task; - bool demorunning; - multithreadt(); -}; - -extern volatile multithreadt multithread; - -extern string ngdir; -extern DebugParameters debugparam; -extern bool verbose; - -#endif diff --git a/Netgen/libsrc/meshing/hpref_prism.hpp b/Netgen/libsrc/meshing/hpref_prism.hpp deleted file mode 100644 index ffbf2d2873..0000000000 --- a/Netgen/libsrc/meshing/hpref_prism.hpp +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - // HP_PRISM ... no refinement - int refprism_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_newelstypes[] = - { - HP_PRISM, - HP_NONE, - }; - int refprism_newels[][8] = - { - { 1, 2, 3, 4, 5, 6 } - }; - HPRef_Struct refprism = - { - HP_PRISM, - refprism_splitedges, - 0, 0, - refprism_newelstypes, - refprism_newels - }; - - - - // HP_PRISM_SINGEDGE ... vertical edge 1-4 is singular - int refprism_singedge_splitedges[][3] = - { - { 1, 2, 7 }, - { 1, 3, 8 }, - { 4, 5, 9 }, - { 4, 6, 10 }, - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_singedge_newelstypes[] = - { - HP_PRISM_SINGEDGE, - HP_HEX, - HP_NONE, - }; - int refprism_singedge_newels[][8] = - { - { 1, 7, 8, 4, 9, 10 }, - { 3, 8, 7, 2, 6, 10, 9, 5 } - }; - HPRef_Struct refprism_singedge = - { - HP_PRISM, - refprism_singedge_splitedges, - 0, 0, - refprism_singedge_newelstypes, - refprism_singedge_newels - }; - - - - - - - // HP_PRISM_SINGEDGE_V12 vertical edges 1-4 and 2-5 are singular - int refprism_singedge_v12_splitedges[][3] = - { - { 1, 2, 7 }, - { 1, 3, 8 }, - { 2, 1, 9 }, - { 2, 3, 10 }, - { 4, 5, 11 }, - { 4, 6, 12 }, - { 5, 4, 13 }, - { 5, 6, 14}, - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_singedge_v12_newelstypes[] = - { - HP_HEX, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_NONE, - }; - int refprism_singedge_v12_newels[][8] = - { - { 7, 9, 10, 8, 11, 13, 14, 12 }, - { 1, 7, 8, 4, 11, 12 }, - { 2, 10, 9, 5, 14, 13 }, - { 3, 8, 10, 6, 12, 14 }, - }; - HPRef_Struct refprism_singedge_v12 = - { - HP_PRISM, - refprism_singedge_v12_splitedges, - 0, 0, - refprism_singedge_v12_newelstypes, - refprism_singedge_v12_newels - }; - - - - - - - // HP_PRISM_SINGEDGE_H12 - int refprism_singedge_h12_splitedges[][3] = - { - { 1, 3, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 3, 1, 10 }, - - { 4, 6, 12 }, - { 5, 4, 13 }, - { 5, 6, 14 }, - { 6, 4, 15 }, - - { 0, 0, 0 } - }; - - int refprism_singedge_h12_splitfaces[][4] = - { - { 2, 1, 3, 11 }, - { 5, 4, 6, 16 }, - { 0, 0, 0, 0 }, - }; - - HPREF_ELEMENT_TYPE refprism_singedge_h12_newelstypes[] = - { - HP_HEX, - HP_HEX, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_NONE, - }; - int refprism_singedge_h12_newels[][8] = - { - { 1, 8, 11, 7, 4, 13, 16, 12 }, - { 9, 3, 10, 11, 14, 6, 15, 16 }, - { 7, 11, 10, 12, 16, 15 }, - { 2, 9, 11, 5, 14, 16 }, - { 8, 2, 11, 13, 5, 16 } - }; - HPRef_Struct refprism_singedge_h12 = - { - HP_PRISM, - refprism_singedge_h12_splitedges, - refprism_singedge_h12_splitfaces, - 0, - refprism_singedge_h12_newelstypes, - refprism_singedge_h12_newels - }; - - - - - - - // HP_PRISM_SINGEDGE_H1 - int refprism_singedge_h1_splitedges[][3] = - { - { 1, 3, 7 }, - { 2, 3, 8 }, - { 4, 6, 9 }, - { 5, 6, 10 }, - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_singedge_h1_newelstypes[] = - { - HP_HEX, - HP_PRISM, - HP_NONE, - }; - int refprism_singedge_h1_newels[][8] = - { - { 1, 2, 8, 7, 4, 5, 10, 9 }, - { 3, 7, 8, 6, 9, 10 } - }; - HPRef_Struct refprism_singedge_h1 = - { - HP_PRISM, - refprism_singedge_h1_splitedges, - 0, 0, - refprism_singedge_h1_newelstypes, - refprism_singedge_h1_newels - }; - - - - - - - -// HP_PRISM_1FA_0E_0V - int refprism_1fa_0e_0v_splitedges[][3] = - { - { 1, 4, 7 }, - { 2, 5, 8 }, - { 3, 6, 9 }, - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_1fa_0e_0v_newelstypes[] = - { - HP_PRISM_1FA_0E_0V, - HP_PRISM, - HP_NONE, - }; - int refprism_1fa_0e_0v_newels[][8] = - { - { 1, 2, 3, 7, 8, 9 }, - { 7, 8, 9, 4, 5, 6 } - }; - HPRef_Struct refprism_1fa_0e_0v = - { - HP_PRISM, - refprism_1fa_0e_0v_splitedges, - 0, 0, - refprism_1fa_0e_0v_newelstypes, - refprism_1fa_0e_0v_newels - }; - - - - - - -// HP_PRISM_1FB_0E_0V ... quad face 1-2-4-5 - int refprism_1fb_0e_0v_splitedges[][3] = - { - { 1, 3, 7 }, - { 2, 3, 8 }, - { 4, 6, 9 }, - { 5, 6, 10 }, - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_1fb_0e_0v_newelstypes[] = - { - HP_HEX_1F_0E_0V, - HP_PRISM, - HP_NONE, - }; - int refprism_1fb_0e_0v_newels[][8] = - { - { 1, 4, 5, 2, 7, 9, 10, 8 }, - { 7, 8, 3, 9, 10, 6 } - }; - HPRef_Struct refprism_1fb_0e_0v = - { - HP_PRISM, - refprism_1fb_0e_0v_splitedges, - 0, 0, - refprism_1fb_0e_0v_newelstypes, - refprism_1fb_0e_0v_newels - }; - - - - - - -// HP_PRISM_1FB_1EA_0V ... quad face 1-2-4-5 - int refprism_1fb_1ea_0v_splitedges[][3] = - { - { 1, 3, 7 }, - { 2, 3, 8 }, - { 4, 6, 9 }, - { 5, 6, 10 }, - { 1, 2, 11 }, - { 4, 5, 12 }, - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refprism_1fb_1ea_0v_newelstypes[] = - { - HP_HEX_1F_0E_0V, - HP_PRISM_1FB_1EA_0V, - HP_PRISM, - HP_NONE, - }; - int refprism_1fb_1ea_0v_newels[][8] = - { - { 11, 12, 5, 2, 7, 9, 10, 8 }, - { 1, 11, 7, 4, 12, 9 }, - { 7, 8, 3, 9, 10, 6 } - }; - HPRef_Struct refprism_1fb_1ea_0v = - { - HP_PRISM, - refprism_1fb_1ea_0v_splitedges, - 0, 0, - refprism_1fb_1ea_0v_newelstypes, - refprism_1fb_1ea_0v_newels - }; - - - - - diff --git a/Netgen/libsrc/meshing/hpref_quad.hpp b/Netgen/libsrc/meshing/hpref_quad.hpp deleted file mode 100644 index 8802d4539e..0000000000 --- a/Netgen/libsrc/meshing/hpref_quad.hpp +++ /dev/null @@ -1,2129 +0,0 @@ - - - - -// HP_QUAD -int refquad_splitedges[][3] = -{ - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_newelstypes[] = -{ - HP_QUAD, - HP_NONE, -}; -int refquad_newels[][8] = -{ - { 1, 2, 3, 4 }, -}; -HPRef_Struct refquad = -{ - HP_QUAD, - refquad_splitedges, - 0, 0, - refquad_newelstypes, - refquad_newels -}; - - - - - - - -// HP_QUAD_SINGCORNER -int refquad_singcorner_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_singcorner_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_TRIG, - HP_NONE, -}; -int refquad_singcorner_newels[][8] = -{ - { 1, 5, 6 }, - { 2, 4, 6, 5 }, - { 2, 3, 4 }, -}; -HPRef_Struct refquad_singcorner = -{ - HP_QUAD, - refquad_singcorner_splitedges, - 0, 0, - refquad_singcorner_newelstypes, - refquad_singcorner_newels -}; - - - - - -// HP_DUMMY_QUAD_SINGCORNER -int refdummyquad_singcorner_splitedges[][3] = -{ - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refdummyquad_singcorner_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_TRIG, - HP_NONE, -}; -int refdummyquad_singcorner_newels[][8] = -{ - { 1, 2, 4 }, - { 4, 2, 3 }, -}; -HPRef_Struct refdummyquad_singcorner = -{ - HP_QUAD, - refdummyquad_singcorner_splitedges, - 0, 0, - refdummyquad_singcorner_newelstypes, - refdummyquad_singcorner_newels -}; - - - - - - - -// HP_QUAD_SINGEDGE -int refquad_singedge_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_singedge_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_singedge_newels[][8] = -{ - { 1, 2, 6, 5 }, - { 5, 6, 3, 4 }, -}; -HPRef_Struct refquad_singedge = -{ - HP_QUAD, - refquad_singedge_splitedges, - 0, 0, - refquad_singedge_newelstypes, - refquad_singedge_newels -}; - - - - - - -// HP_QUAD_0E_2VA -int refquad_0e_2va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_0e_2va_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int refquad_0e_2va_newels[][8] = -{ - { 1, 5, 6 }, - { 2, 8, 7 }, - { 5, 7, 8, 6 }, - { 6, 8, 3, 4 }, -}; -HPRef_Struct refquad_0e_2va = -{ - HP_QUAD, - refquad_0e_2va_splitedges, - 0, 0, - refquad_0e_2va_newelstypes, - refquad_0e_2va_newels -}; - - - -// HP_QUAD_0E_2VB -int refquad_0e_2vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 3, 4, 7 }, - { 3, 2, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_0e_2vb_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int refquad_0e_2vb_newels[][8] = -{ - { 1, 5, 6 }, - { 3, 7, 8 }, - { 5, 2, 4, 6 }, - { 2, 8, 7, 4 }, -}; -HPRef_Struct refquad_0e_2vb = -{ - HP_QUAD, - refquad_0e_2vb_splitedges, - 0, 0, - refquad_0e_2vb_newelstypes, - refquad_0e_2vb_newels -}; - - - - -// HP_QUAD_0E_3V -int refquad_0e_3v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 2, 9 }, - { 3, 4, 10 }, - { 0, 0, 0 } -}; - -int refquad_0e_3v_splitfaces[][4] = -{ - { 2, 3, 1, 14 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_0e_3v_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int refquad_0e_3v_newels[][8] = -{ - { 1, 5, 6 }, - { 2, 8, 14, 7 }, - { 3, 10, 9 }, - { 5, 7, 14, 6 }, - { 8, 9, 10, 14 }, - { 6, 14, 10, 4 }, -}; -HPRef_Struct refquad_0e_3v = -{ - HP_QUAD, - refquad_0e_3v_splitedges, - refquad_0e_3v_splitfaces, - 0, - refquad_0e_3v_newelstypes, - refquad_0e_3v_newels -}; - - - - -// HP_QUAD_0E_4V -int refquad_0e_4v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 2, 9 }, - { 3, 4, 10 }, - { 4, 1, 11 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; - -int refquad_0e_4v_splitfaces[][4] = -{ - { 1, 2, 4, 13 }, - { 2, 3, 1, 14 }, - { 3, 4, 2, 15 }, - { 4, 1, 3, 16 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_0e_4v_newelstypes[] = -{ - HP_DUMMY_QUAD_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - - HP_QUAD, - HP_QUAD, - HP_QUAD, - HP_QUAD, - - HP_QUAD, - HP_NONE, -}; -int refquad_0e_4v_newels[][8] = -{ - { 1, 5, 13, 6 }, - { 2, 8, 14, 7 }, - { 3, 10, 15, 9 }, - { 4, 11, 16, 12 }, - { 5, 7, 14, 13 }, - { 8, 9, 15, 14 }, - { 10, 12, 16, 15 }, - { 11, 6, 13, 16 }, - { 13, 14, 15, 16 } -}; -HPRef_Struct refquad_0e_4v = -{ - HP_QUAD, - refquad_0e_4v_splitedges, - refquad_0e_4v_splitfaces, - 0, - refquad_0e_4v_newelstypes, - refquad_0e_4v_newels -}; - - - - - - - - -// HP_QUAD_1E_1VA -int refquad_1e_1va_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_1va_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGEDGECORNER1, - HP_NONE, -}; -int refquad_1e_1va_newels[][8] = -{ - { 7, 2, 6, 5 }, - { 5, 6, 3, 4 }, - { 1, 7, 5 }, -}; -HPRef_Struct refquad_1e_1va = -{ - HP_QUAD, - refquad_1e_1va_splitedges, - 0, 0, - refquad_1e_1va_newelstypes, - refquad_1e_1va_newels -}; - - - - -// HP_QUAD_1E_1VB -int refquad_1e_1vb_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 2, 1, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_1vb_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGEDGECORNER2, - HP_NONE, -}; -int refquad_1e_1vb_newels[][8] = -{ - { 1, 7, 6, 5 }, - { 5, 6, 3, 4 }, - { 7, 2, 6 }, -}; -HPRef_Struct refquad_1e_1vb = -{ - HP_QUAD, - refquad_1e_1vb_splitedges, - 0, 0, - refquad_1e_1vb_newelstypes, - refquad_1e_1vb_newels -}; - - - -// HP_QUAD_1E_1VC -int refquad_1e_1vc_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 3, 4, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_1vc_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_1vc_newels[][8] = -{ - { 1, 2, 6, 5 }, - { 5, 6, 4 }, - { 4, 6, 7, 8 }, - { 3, 8, 7 } -}; -HPRef_Struct refquad_1e_1vc = -{ - HP_QUAD, - refquad_1e_1vc_splitedges, - 0, 0, - refquad_1e_1vc_newelstypes, - refquad_1e_1vc_newels -}; - - - -// HP_QUAD_1E_1VD -int refquad_1e_1vd_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 4, 1, 7 }, - { 4, 3, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_1vd_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_1vd_newels[][8] = -{ - { 1, 2, 6, 5 }, - { 5, 6, 3 }, - { 5, 3, 8, 7 }, - { 4, 7, 8 } -}; -HPRef_Struct refquad_1e_1vd = -{ - HP_QUAD, - refquad_1e_1vd_splitedges, - 0, 0, - refquad_1e_1vd_newelstypes, - refquad_1e_1vd_newels -}; - - - - - - - -// HP_QUAD_1E_2VA -int refquad_1e_2va_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 2, 1, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_2va_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_NONE, -}; -int refquad_1e_2va_newels[][8] = -{ - { 7, 8, 6, 5 }, - { 5, 6, 3, 4 }, - { 1, 7, 5 }, - { 8, 2, 6 } -}; -HPRef_Struct refquad_1e_2va = -{ - HP_QUAD, - refquad_1e_2va_splitedges, - 0, 0, - refquad_1e_2va_newelstypes, - refquad_1e_2va_newels -}; - - - - -// HP_QUAD_1E_2VB -int refquad_1e_2vb_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 3, 2, 8 }, - { 3, 4, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_2vb_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_2vb_newels[][8] = -{ - { 7, 2, 6, 5 }, - { 1, 7, 5 }, - { 5, 6, 4 }, - { 4, 6, 8, 9 }, - { 3, 9, 8 } -}; -HPRef_Struct refquad_1e_2vb = -{ - HP_QUAD, - refquad_1e_2vb_splitedges, - 0, 0, - refquad_1e_2vb_newelstypes, - refquad_1e_2vb_newels -}; - - - - -// HP_QUAD_1E_2VC -int refquad_1e_2vc_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 4, 1, 8 }, - { 4, 3, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_2vc_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_2vc_newels[][8] = -{ - { 7, 2, 6, 5 }, - { 1, 7, 5 }, - { 5, 6, 3 }, - { 5, 3, 9, 8 }, - { 4, 8, 9 } -}; -HPRef_Struct refquad_1e_2vc = -{ - HP_QUAD, - refquad_1e_2vc_splitedges, - 0, 0, - refquad_1e_2vc_newelstypes, - refquad_1e_2vc_newels -}; - - - - -// HP_QUAD_1E_2VD -int refquad_1e_2vd_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 2, 1, 7 }, - { 3, 2, 8 }, - { 3, 4, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_2vd_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_2vd_newels[][8] = -{ - { 1, 7, 6, 5 }, - { 7, 2, 6 }, - { 5, 6, 4 }, - { 4, 6, 8, 9 }, - { 3, 9, 8 } -}; -HPRef_Struct refquad_1e_2vd = -{ - HP_QUAD, - refquad_1e_2vd_splitedges, - 0, 0, - refquad_1e_2vd_newelstypes, - refquad_1e_2vd_newels -}; - - - - - -// HP_QUAD_1E_2VE -int refquad_1e_2ve_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 2, 1, 7 }, - { 4, 1, 8 }, - { 4, 3, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_2ve_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_2ve_newels[][8] = -{ - { 1, 7, 6, 5 }, - { 7, 2, 6 }, - { 5, 6, 3 }, - { 5, 3, 9, 8 }, - { 4, 8, 9 } -}; -HPRef_Struct refquad_1e_2ve = -{ - HP_QUAD, - refquad_1e_2ve_splitedges, - 0, 0, - refquad_1e_2ve_newelstypes, - refquad_1e_2ve_newels -}; - - - - - - -// HP_QUAD_1E_2VF -int refquad_1e_2vf_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 4, 1, 7 }, - { 4, 3, 8 }, - { 3, 2, 9 }, - { 3, 4, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_2vf_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_1e_2vf_newels[][8] = -{ - { 1, 2, 6, 5 }, - { 5, 6, 9, 7 }, - { 7, 9, 10, 8 }, - { 4, 7, 8 }, - { 3, 10, 9 }, -}; -HPRef_Struct refquad_1e_2vf = -{ - HP_QUAD, - refquad_1e_2vf_splitedges, - 0, 0, - refquad_1e_2vf_newelstypes, - refquad_1e_2vf_newels -}; - - - - - -// HP_QUAD_1E_3VA -int refquad_1e_3va_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 2, 1, 8 }, - { 3, 2, 9 }, - { 3, 4, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_3va_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGCORNER, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG, - HP_NONE, -}; -int refquad_1e_3va_newels[][8] = -{ - { 1, 7, 5 }, - { 8, 2, 6 }, - { 3, 10, 9 }, - { 7, 8, 6, 5 }, - { 4, 6, 9, 10 }, - { 5, 6, 4 } -}; -HPRef_Struct refquad_1e_3va = -{ - HP_QUAD, - refquad_1e_3va_splitedges, - 0, 0, - refquad_1e_3va_newelstypes, - refquad_1e_3va_newels -}; - - - - - -// HP_QUAD_1E_3VB -int refquad_1e_3vb_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 2, 1, 8 }, - { 4, 1, 9 }, - { 4, 3, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_3vb_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGCORNER, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG, - HP_NONE, -}; -int refquad_1e_3vb_newels[][8] = -{ - { 1, 7, 5 }, - { 8, 2, 6 }, - { 4, 9, 10 }, - { 7, 8, 6, 5 }, - { 5, 3, 10, 9 }, - { 5, 6, 3 } -}; -HPRef_Struct refquad_1e_3vb = -{ - HP_QUAD, - refquad_1e_3vb_splitedges, - 0, 0, - refquad_1e_3vb_newelstypes, - refquad_1e_3vb_newels -}; - - - - - -// HP_QUAD_1E_3VC -int refquad_1e_3vc_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 3, 2, 8 }, - { 3, 4, 9 }, - { 4, 3, 10 }, - { 4, 1, 11 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_3vc_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int refquad_1e_3vc_newels[][8] = -{ - { 1, 7, 5 }, - { 3, 9, 8 }, - { 4, 11, 10 }, - { 7, 2, 6, 5 }, - { 5, 6, 8, 11 }, - { 11, 8, 9, 10 } -}; -HPRef_Struct refquad_1e_3vc = -{ - HP_QUAD, - refquad_1e_3vc_splitedges, - 0, 0, - refquad_1e_3vc_newelstypes, - refquad_1e_3vc_newels -}; - - - - -// HP_QUAD_1E_3VD -int refquad_1e_3vd_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 2, 1, 7 }, - { 3, 2, 8 }, - { 3, 4, 9 }, - { 4, 3, 10 }, - { 4, 1, 11 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_3vd_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int refquad_1e_3vd_newels[][8] = -{ - { 7, 2, 6 }, - { 3, 9, 8 }, - { 4, 11, 10 }, - { 1, 7, 6, 5 }, - { 5, 6, 8, 11 }, - { 11, 8, 9, 10 } -}; -HPRef_Struct refquad_1e_3vd = -{ - HP_QUAD, - refquad_1e_3vd_splitedges, - 0, 0, - refquad_1e_3vd_newelstypes, - refquad_1e_3vd_newels -}; - - - - - - -// HP_QUAD_1E_4V -int refquad_1e_4v_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 2, 1, 8 }, - { 4, 1, 9 }, - { 3, 2, 10 }, - { 4, 3, 11 }, - { 3, 4, 12 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_1e_4v_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int refquad_1e_4v_newels[][8] = -{ - { 1, 7, 5 }, - { 8, 2, 6 }, - { 3, 12, 10 }, - { 4, 9, 11 }, - { 7, 8, 6, 5 }, - { 5, 6, 10, 9 }, - { 9, 10, 12, 11 } -}; -HPRef_Struct refquad_1e_4v = -{ - HP_QUAD, - refquad_1e_4v_splitedges, - 0, 0, - refquad_1e_4v_newelstypes, - refquad_1e_4v_newels -}; - - - - -//////////////////////////////////////////////////////////////////////////////// - - - -// HP_QUAD_2E -int refquad_2e_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 3, 8 }, - { 0, 0, 0 } -}; -int refquad_2e_splitfaces[][4] = -{ - { 1, 2, 4, 9 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_2e_newels[][8] = -{ - { 1, 5, 9 }, - { 6, 1, 9 }, - { 5, 2, 7, 9 }, - { 4, 6, 9, 8 }, - { 9, 7, 3, 8 }, -}; -HPRef_Struct refquad_2e = -{ - HP_QUAD, - refquad_2e_splitedges, - refquad_2e_splitfaces, - 0, - refquad_2e_newelstypes, - refquad_2e_newels -}; - - - - - - - -// HP_QUAD_2E_1VA -int refquad_2e_1va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 3, 8 }, - { 2, 1, 10 }, - { 0, 0, 0 } -}; -int refquad_2e_1va_splitfaces[][4] = -{ - { 1, 2, 4, 9 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_1va_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGEDGECORNER2, - HP_NONE, -}; -int refquad_2e_1va_newels[][8] = -{ - { 1, 5, 9 }, - { 6, 1, 9 }, - { 5, 10, 7, 9 }, - { 4, 6, 9, 8 }, - { 9, 7, 3, 8 }, - { 10, 2, 7 }, -}; -HPRef_Struct refquad_2e_1va = -{ - HP_QUAD, - refquad_2e_1va_splitedges, - refquad_2e_1va_splitfaces, - 0, - refquad_2e_1va_newelstypes, - refquad_2e_1va_newels -}; - - - - - - -// HP_QUAD_2E_1VB -int refquad_2e_1vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 3, 8 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 0, 0, 0 } -}; -int refquad_2e_1vb_splitfaces[][4] = -{ - { 1, 2, 4, 9 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_1vb_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int refquad_2e_1vb_newels[][8] = -{ - { 1, 5, 9 }, - { 6, 1, 9 }, - { 5, 2, 7, 9 }, - { 4, 6, 9, 8 }, - { 7, 8, 9 }, - { 8, 7, 10, 11 }, - { 3, 11, 10 } -}; -HPRef_Struct refquad_2e_1vb = -{ - HP_QUAD, - refquad_2e_1vb_splitedges, - refquad_2e_1vb_splitfaces, - 0, - refquad_2e_1vb_newelstypes, - refquad_2e_1vb_newels -}; - - - - - -// HP_QUAD_2E_1VC -int refquad_2e_1vc_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 1, 8 }, - { 4, 3, 9 }, - { 0, 0, 0 } -}; -int refquad_2e_1vc_splitfaces[][4] = -{ - { 1, 2, 4, 10 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_1vc_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_2e_1vc_newels[][8] = -{ - { 1, 5, 10 }, - { 6, 1, 10 }, - { 4, 8, 9 }, - { 5, 2, 7, 10 }, - { 8, 6, 10, 9 }, - { 10, 7, 3, 9 }, -}; -HPRef_Struct refquad_2e_1vc = -{ - HP_QUAD, - refquad_2e_1vc_splitedges, - refquad_2e_1vc_splitfaces, - 0, - refquad_2e_1vc_newelstypes, - refquad_2e_1vc_newels -}; - - - - - - - - - - -// HP_QUAD_2E -int refquad_2e_2va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 3, 8 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 2, 1, 12 }, - { 0, 0, 0 } -}; -int refquad_2e_2va_splitfaces[][4] = -{ - { 1, 2, 4, 9 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_2va_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGEDGECORNER2, - HP_NONE, -}; -int refquad_2e_2va_newels[][8] = -{ - { 1, 5, 9 }, - { 6, 1, 9 }, - { 5, 12, 7, 9 }, - { 4, 6, 9, 8 }, - { 7, 8, 9 }, - { 8, 7, 10, 11 }, - { 3, 11, 10 }, - { 12, 2, 7 } -}; -HPRef_Struct refquad_2e_2va = -{ - HP_QUAD, - refquad_2e_2va_splitedges, - refquad_2e_2va_splitfaces, - 0, - refquad_2e_2va_newelstypes, - refquad_2e_2va_newels -}; - - - - - - -// HP_QUAD_2E_2VB -int refquad_2e_2vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 4, 1, 9 }, - { 4, 3, 10 }, - { 0, 0, 0 } -}; -int refquad_2e_2vb_splitfaces[][4] = -{ - { 1, 2, 4, 11 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_2vb_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_2e_2vb_newels[][8] = -{ - { 1, 5, 11 }, - { 6, 1, 11 }, - { 4, 9, 10 }, - { 7, 2, 8 }, - { 5, 7, 8, 11 }, - { 9, 6, 11, 10 }, - { 3, 10, 11, 8 }, -}; -HPRef_Struct refquad_2e_2vb = -{ - HP_QUAD, - refquad_2e_2vb_splitedges, - refquad_2e_2vb_splitfaces, - 0, - refquad_2e_2vb_newelstypes, - refquad_2e_2vb_newels -}; - - - - - - - - - - -// HP_QUAD_2E -int refquad_2e_2vc_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 3, 8 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 4, 1, 12 }, - { 0, 0, 0 } -}; -int refquad_2e_2vc_splitfaces[][4] = -{ - { 1, 2, 4, 9 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_2vc_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGEDGECORNER2, - HP_NONE, -}; -int refquad_2e_2vc_newels[][8] = -{ - { 1, 5, 9 }, - { 6, 1, 9 }, - { 5, 2, 7, 9 }, - { 12, 6, 9, 8 }, - { 7, 8, 9 }, - { 8, 7, 10, 11 }, - { 3, 11, 10 }, - { 4, 12, 8 } -}; -HPRef_Struct refquad_2e_2vc = -{ - HP_QUAD, - refquad_2e_2vc_splitedges, - refquad_2e_2vc_splitfaces, - 0, - refquad_2e_2vc_newelstypes, - refquad_2e_2vc_newels -}; - - - - - - - - - - - - - - -// HP_QUAD_2E -int refquad_2e_3v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 4, 3, 8 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 2, 1, 12 }, - { 4, 1, 13 }, - { 0, 0, 0 } -}; -int refquad_2e_3v_splitfaces[][4] = -{ - { 1, 2, 4, 9 }, - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2e_3v_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - HP_NONE, -}; -int refquad_2e_3v_newels[][8] = -{ - { 1, 5, 9 }, - { 6, 1, 9 }, - { 5, 12, 7, 9 }, - { 13, 6, 9, 8 }, - { 7, 8, 9 }, - { 8, 7, 10, 11 }, - { 3, 11, 10 }, - { 12, 2, 7 }, - { 4, 13, 8 } -}; -HPRef_Struct refquad_2e_3v = -{ - HP_QUAD, - refquad_2e_3v_splitedges, - refquad_2e_3v_splitfaces, - 0, - refquad_2e_3v_newelstypes, - refquad_2e_3v_newels -}; - - - - - - - - - - -// HP_QUAD_2EB_0V -int refquad_2eb_0v_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 0, 0, 0 } -}; -int refquad_2eb_0v_splitfaces[][4] = -{ - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2eb_0v_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_0v_newels[][8] = -{ - { 1, 2, 6, 5 }, - { 3, 4, 8, 7 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_0v = -{ - HP_QUAD, - refquad_2eb_0v_splitedges, - refquad_2eb_0v_splitfaces, - 0, - refquad_2eb_0v_newelstypes, - refquad_2eb_0v_newels -}; - - - - - - - - -// HP_QUAD_2EB_1VA -int refquad_2eb_1va_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 1, 2, 9 }, - { 0, 0, 0 } -}; -int refquad_2eb_1va_splitfaces[][4] = -{ - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2eb_1va_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_1va_newels[][8] = -{ - { 9, 2, 6, 5 }, - { 3, 4, 8, 7 }, - { 1, 9, 5 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_1va = -{ - HP_QUAD, - refquad_2eb_1va_splitedges, - refquad_2eb_1va_splitfaces, - 0, - refquad_2eb_1va_newelstypes, - refquad_2eb_1va_newels -}; - - - - -// HP_QUAD_2EB_1VB -int refquad_2eb_1vb_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 2, 1, 9 }, - { 0, 0, 0 } -}; -int refquad_2eb_1vb_splitfaces[][4] = -{ - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2eb_1vb_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_1vb_newels[][8] = -{ - { 1, 9, 6, 5 }, - { 3, 4, 8, 7 }, - { 9, 2, 6 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_1vb = -{ - HP_QUAD, - refquad_2eb_1vb_splitedges, - refquad_2eb_1vb_splitfaces, - 0, - refquad_2eb_1vb_newelstypes, - refquad_2eb_1vb_newels -}; - - - - - - -// HP_QUAD_2EB_2VA -int refquad_2eb_2va_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 1, 2, 9 }, - { 2, 1, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_2eb_2va_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_2va_newels[][8] = -{ - { 9, 10, 6, 5 }, - { 3, 4, 8, 7 }, - { 1, 9, 5 }, - { 10, 2, 6 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_2va = -{ - HP_QUAD, - refquad_2eb_2va_splitedges, - 0, 0, - refquad_2eb_2va_newelstypes, - refquad_2eb_2va_newels -}; - - - -// HP_QUAD_2EB_2VB -int refquad_2eb_2vb_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 1, 2, 9 }, - { 3, 4, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_2eb_2vb_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER1, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_2vb_newels[][8] = -{ - { 9, 2, 6, 5 }, - { 10, 4, 8, 7 }, - { 1, 9, 5 }, - { 3, 10, 7 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_2vb = -{ - HP_QUAD, - refquad_2eb_2vb_splitedges, - 0, 0, - refquad_2eb_2vb_newelstypes, - refquad_2eb_2vb_newels -}; - - - -// HP_QUAD_2EB_2VC -int refquad_2eb_2vc_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 1, 2, 9 }, - { 4, 3, 10 }, - { 0, 0, 0 } -}; -int refquad_2eb_2vc_splitfaces[][4] = -{ - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2eb_2vc_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_2vc_newels[][8] = -{ - { 9, 2, 6, 5 }, - { 3, 10, 8, 7 }, - { 1, 9, 5 }, - { 10, 4, 8 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_2vc = -{ - HP_QUAD, - refquad_2eb_2vc_splitedges, - refquad_2eb_2vc_splitfaces, - 0, - refquad_2eb_2vc_newelstypes, - refquad_2eb_2vc_newels -}; - - - - -// HP_QUAD_2EB_2VD -int refquad_2eb_2vd_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 2, 1, 9 }, - { 4, 3, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_2eb_2vd_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_2vd_newels[][8] = -{ - { 1, 9, 6, 5 }, - { 3, 10, 8, 7 }, - { 9, 2, 6 }, - { 10, 4, 8 }, - { 5, 6, 7, 8 } -}; -HPRef_Struct refquad_2eb_2vd = -{ - HP_QUAD, - refquad_2eb_2vd_splitedges, - 0, 0, - refquad_2eb_2vd_newelstypes, - refquad_2eb_2vd_newels -}; - - - - - - - -// HP_QUAD_2EB_3VA -int refquad_2eb_3va_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 2, 1, 8 }, - { 3, 2, 9 }, - { 4, 1, 10 }, - { 3, 4, 11 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_2eb_3va_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_3va_newels[][8] = -{ - { 1, 7, 5 }, - { 8, 2, 6 }, - { 3, 11, 9}, - { 7, 8, 6, 5 }, - { 11, 4, 10, 9 }, - { 5, 6, 9, 10 } -}; -HPRef_Struct refquad_2eb_3va = -{ - HP_QUAD, - refquad_2eb_3va_splitedges, - 0, 0, - refquad_2eb_3va_newelstypes, - refquad_2eb_3va_newels -}; - - - - - -// HP_QUAD_2EB_3VB -int refquad_2eb_3vb_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 1, 2, 7 }, - { 2, 1, 8 }, - { 3, 2, 9 }, - { 4, 1, 10 }, - { 4, 3, 11 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE refquad_2eb_3vb_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_NONE, -}; -int refquad_2eb_3vb_newels[][8] = -{ - { 1, 7, 5 }, - { 8, 2, 6 }, - { 11, 4, 10 }, - { 7, 8, 6, 5 }, - { 3, 11, 10, 9 }, - { 5, 6, 9, 10 } -}; -HPRef_Struct refquad_2eb_3vb = -{ - HP_QUAD, - refquad_2eb_3vb_splitedges, - 0, 0, - refquad_2eb_3vb_newelstypes, - refquad_2eb_3vb_newels -}; - - - - - - -// HP_QUAD_2EB_4V -int refquad_2eb_4v_splitedges[][3] = -{ - { 1, 4, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 4, 1, 8 }, - { 1, 2, 9 }, - { 2, 1, 10 }, - { 3, 4, 11 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; -int refquad_2eb_4v_splitfaces[][4] = -{ - { 0, 0, 0, 0 }, -}; -HPREF_ELEMENT_TYPE refquad_2eb_4v_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_NONE, -}; -int refquad_2eb_4v_newels[][8] = -{ - { 9, 10, 6, 5 }, - { 11, 12, 8, 7 }, - { 5, 6, 7, 8 }, - { 1, 9, 5 }, - { 10, 2, 6 }, - { 3, 11, 7 }, - { 12, 4, 8 }, -}; -HPRef_Struct refquad_2eb_4v = -{ - HP_QUAD, - refquad_2eb_4v_splitedges, - refquad_2eb_4v_splitfaces, - 0, - refquad_2eb_4v_newelstypes, - refquad_2eb_4v_newels -}; - - - - - - - -// HP_QUAD_3E -int refquad_3e_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 4, 10 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; - -int refquad_3e_splitfaces[][4] = -{ - { 1, 2, 4, 13 }, - { 2, 3, 1, 14 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_3e_newelstypes[] = -{ - HP_QUAD_2E, - HP_QUAD_2E, -// HP_TRIG_SINGEDGECORNER1, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER1, - - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - - HP_QUAD, - HP_NONE, -}; -int refquad_3e_newels[][8] = -{ -// { 1, 5, 13 }, -// { 6, 1, 13 }, -// { 7, 2, 14 }, -// { 2, 8, 14 }, - { 1, 5, 13, 6 }, - { 2, 8, 14, 7 }, - { 5, 7, 14, 13 }, - { 8, 3, 10, 14 }, - { 4, 6, 13, 12 }, - { 13, 14, 10, 12 } -}; -HPRef_Struct refquad_3e = -{ - HP_QUAD, - refquad_3e_splitedges, - refquad_3e_splitfaces, - 0, - refquad_3e_newelstypes, - refquad_3e_newels -}; - - - - - - - -// HP_QUAD_3E_3VA -int refquad_3e_3va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 4, 10 }, - { 3, 2, 11 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; - -int refquad_3e_3va_splitfaces[][4] = -{ - { 1, 2, 4, 13 }, - { 2, 3, 1, 14 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_3e_3va_newelstypes[] = -{ - HP_QUAD_2E, - HP_QUAD_2E, - -// HP_TRIG_SINGEDGECORNER1, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - - HP_QUAD, - HP_NONE, -}; -int refquad_3e_3va_newels[][8] = -{ -// { 1, 5, 13 }, -// { 6, 1, 13 }, -// { 7, 2, 14 }, -// { 2, 8, 14 }, - { 1, 5, 13, 6 }, - { 2, 8, 14, 7 }, - { 11, 3, 10 }, - { 5, 7, 14, 13 }, - { 8, 11, 10, 14 }, - { 4, 6, 13, 12 }, - { 13, 14, 10, 12 } -}; -HPRef_Struct refquad_3e_3va = -{ - HP_QUAD, - refquad_3e_3va_splitedges, - refquad_3e_3va_splitfaces, - 0, - refquad_3e_3va_newelstypes, - refquad_3e_3va_newels -}; - - - - - - - - - - -// HP_QUAD_3E_3VB -int refquad_3e_3vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 4, 10 }, - { 4, 1, 11 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; - -int refquad_3e_3vb_splitfaces[][4] = -{ - { 1, 2, 4, 13 }, - { 2, 3, 1, 14 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_3e_3vb_newelstypes[] = -{ - HP_QUAD_2E, - HP_QUAD_2E, - -// HP_TRIG_SINGEDGECORNER1, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER1, - - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - - HP_QUAD, - HP_NONE, -}; -int refquad_3e_3vb_newels[][8] = -{ -// { 1, 5, 13 }, -// { 6, 1, 13 }, -// { 7, 2, 14 }, -// { 2, 8, 14 }, - { 1, 5, 13, 6 }, - { 2, 8, 14, 7 }, - { 4, 11, 12 }, - { 5, 7, 14, 13 }, - { 8, 3, 10, 14 }, - { 11, 6, 13, 12 }, - { 13, 14, 10, 12 } -}; -HPRef_Struct refquad_3e_3vb = -{ - HP_QUAD, - refquad_3e_3vb_splitedges, - refquad_3e_3vb_splitfaces, - 0, - refquad_3e_3vb_newelstypes, - refquad_3e_3vb_newels -}; - - - - - - - - - -// HP_QUAD_3E_4V -int refquad_3e_4v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 4, 10 }, - { 3, 2, 11 }, - { 4, 3, 12 }, - { 4, 1, 15 }, - { 0, 0, 0 } -}; - -int refquad_3e_4v_splitfaces[][4] = -{ - { 1, 2, 4, 13 }, - { 2, 3, 1, 14 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_3e_4v_newelstypes[] = -{ - HP_QUAD_2E, - HP_QUAD_2E, - -// HP_TRIG_SINGEDGECORNER1, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER2, -// HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - - HP_QUAD, - HP_NONE, -}; -int refquad_3e_4v_newels[][8] = -{ -// { 1, 5, 13 }, -// { 6, 1, 13 }, -// { 7, 2, 14 }, -// { 2, 8, 14 }, - { 1, 5, 13, 6 }, - { 2, 8, 14, 7 }, - { 11, 3, 10 }, - { 4, 15, 12 }, - { 5, 7, 14, 13 }, - { 8, 11, 10, 14 }, - { 15, 6, 13, 12 }, - { 13, 14, 10, 12 } -}; -HPRef_Struct refquad_3e_4v = -{ - HP_QUAD, - refquad_3e_4v_splitedges, - refquad_3e_4v_splitfaces, - 0, - refquad_3e_4v_newelstypes, - refquad_3e_4v_newels -}; - - - - - - - - - -// HP_QUAD_4E -int refquad_4e_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 3, 2, 9 }, - { 3, 4, 10 }, - { 4, 1, 11 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; - -int refquad_4e_splitfaces[][4] = -{ - { 1, 2, 4, 13 }, - { 2, 3, 1, 14 }, - { 3, 4, 2, 15 }, - { 4, 1, 3, 16 }, - { 0, 0, 0, 0 }, -}; - -HPREF_ELEMENT_TYPE refquad_4e_newelstypes[] = -{ - HP_QUAD_2E, - HP_QUAD_2E, - HP_QUAD_2E, - HP_QUAD_2E, - - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - - HP_QUAD, - HP_NONE, -}; -int refquad_4e_newels[][8] = -{ - { 1, 5, 13, 6 }, - { 2, 8, 14, 7 }, - { 3, 10, 15, 9 }, - { 4, 11, 16, 12 }, - { 5, 7, 14, 13 }, - { 8, 9, 15, 14 }, - { 10, 12, 16, 15 }, - { 11, 6, 13, 16 }, - { 13, 14, 15, 16 } -}; -HPRef_Struct refquad_4e = -{ - HP_QUAD, - refquad_4e_splitedges, - refquad_4e_splitfaces, - 0, - refquad_4e_newelstypes, - refquad_4e_newels -}; - - diff --git a/Netgen/libsrc/meshing/hpref_tet.hpp b/Netgen/libsrc/meshing/hpref_tet.hpp deleted file mode 100644 index b071269ec8..0000000000 --- a/Netgen/libsrc/meshing/hpref_tet.hpp +++ /dev/null @@ -1,2842 +0,0 @@ - - -// HP_TET -int reftet_splitedges[][3] = -{ - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_newelstypes[] = -{ - HP_TET, - HP_NONE, -}; -int reftet_newels[][8] = -{ - { 1, 2, 3, 4 }, -}; -HPRef_Struct reftet = -{ - HP_TET, - reftet_splitedges, - 0, 0, - reftet_newelstypes, - reftet_newels -}; - - - -/* *********** Tet - Refinement - 0 edges *************** */ - -// HP_TET_0E_1V -int reftet_0e_1v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_0e_1v_newelstypes[] = -{ - HP_TET_0E_1V, - HP_PRISM, - HP_NONE, -}; -int reftet_0e_1v_newels[][8] = -{ - { 1, 5, 6, 7 }, - { 5, 6, 7, 2, 3, 4 } -}; -HPRef_Struct reftet_0e_1v = -{ - HP_TET, - reftet_0e_1v_splitedges, - 0, 0, - reftet_0e_1v_newelstypes, - reftet_0e_1v_newels -}; - - - -// HP_TET_0E_2V -int reftet_0e_2v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_0e_2v_newelstypes[] = -{ - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_PRISM, - HP_PRISM, - HP_NONE, -}; -int reftet_0e_2v_newels[][8] = -{ - { 1, 5, 6, 7 }, - { 2, 10, 9, 8 }, - { 5, 6, 7, 8, 9, 10 }, - { 4, 10, 7, 3, 9, 6 }, -}; -HPRef_Struct reftet_0e_2v = -{ - HP_TET, - reftet_0e_2v_splitedges, - 0, 0, - reftet_0e_2v_newelstypes, - reftet_0e_2v_newels -}; - - - - - -// HP_TET_0E_3V -int reftet_0e_3v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 0, 0, 0 } -}; -int reftet_0e_3v_splitfaces[][4] = - { - { 1, 2, 3, 14 }, - { 2, 3, 1, 15 }, - { 3, 1, 2, 16 }, - { 0, 0, 0, 0 }, - }; -HPREF_ELEMENT_TYPE reftet_0e_3v_newelstypes[] = -{ - HP_PYRAMID_0E_1V, - HP_PYRAMID_0E_1V, - HP_PYRAMID_0E_1V, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, -}; -int reftet_0e_3v_newels[][8] = -{ - { 1, 5, 14, 6, 7 }, - { 2, 9, 15, 8, 10 }, - { 3, 11, 16, 12, 13 }, - { 5, 14, 7, 8, 15, 10 }, - { 9, 15, 10, 12, 16, 13 }, - { 6, 7, 14, 11, 13, 16 }, - { 14, 15, 16, 7, 10, 13 }, - { 7, 10, 13, 4 } -}; -HPRef_Struct reftet_0e_3v = -{ - HP_TET, - reftet_0e_3v_splitedges, - reftet_0e_3v_splitfaces, - 0, - reftet_0e_3v_newelstypes, - reftet_0e_3v_newels -}; - - - - - -// HP_TET_0E_4V -int reftet_0e_4v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_0e_4v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 1, 2, 4, 18 }, - { 1, 3, 4, 19 }, - - { 2, 1, 3, 20 }, - { 2, 1, 4, 21 }, - { 2, 3, 4, 22 }, - - { 3, 1, 2, 23 }, - { 3, 1, 4, 24 }, - { 3, 2, 4, 25 }, - - { 4, 1, 2, 26 }, - { 4, 1, 3, 27 }, - { 4, 2, 3, 28 }, - { 0, 0, 0, 0 }, - }; -int reftet_0e_4v_splitelements[][5] = - { - { 1, 2, 3, 4, 29 }, - { 2, 3, 4, 1, 30 }, - { 3, 4, 1, 2, 31 }, - { 4, 1, 2, 3, 32 }, - { 0 }, - }; -HPREF_ELEMENT_TYPE reftet_0e_4v_newelstypes[] = -{ - HP_HEX_0E_1V, - HP_HEX_0E_1V, - HP_HEX_0E_1V, - HP_HEX_0E_1V, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - /* - HP_HEX, - HP_HEX, - HP_HEX, - HP_HEX, - HP_HEX, - HP_HEX, - */ - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, -}; -int reftet_0e_4v_newels[][8] = -{ - { 1, 5, 17, 6, 7, 18, 29, 19 }, - { 2, 9, 20, 8, 10, 22, 30, 21 }, - { 3, 11, 23, 12, 13, 24, 31, 25 }, - { 4, 15, 26, 14, 16, 28, 32, 27 }, - { 5, 17, 18, 8, 20, 21 }, - { 18, 17, 29, 21, 20, 30 }, - { 6, 19, 17, 11, 24, 23 }, - { 17, 19, 29, 23, 24, 31 }, - { 7, 18, 19, 14, 26, 27 }, - { 19, 18, 29, 27, 26, 32 }, - { 9, 20, 22, 12, 23, 25 }, - { 22, 20, 30, 25, 23, 31 }, - { 10, 22, 21, 15, 28, 26 }, - { 21, 22, 30, 26, 28, 32 }, - { 13, 24, 25, 16, 27, 28 }, - { 25, 24, 31, 28, 27, 32 }, - /* - { 5, 17, 29, 18, 8, 20, 30, 21 }, - { 6, 19, 29, 17, 11, 24, 31, 23 }, - { 7, 18, 29, 19, 14, 26, 32, 27 }, - { 9, 20, 30, 22, 12, 23, 31, 25 }, - { 10, 22, 30, 21, 15, 28, 32, 26 }, - { 13, 24, 31, 25, 16, 27, 32, 28 }, - */ - { 17, 20, 23, 29, 30, 31 }, - { 18, 26, 21, 29, 32, 30 }, - { 19, 24, 27, 29, 31, 32 }, - { 22, 28, 25, 30, 32, 31 }, - - { 29, 30, 31, 32 }, -}; -HPRef_Struct reftet_0e_4v = -{ - HP_TET, - reftet_0e_4v_splitedges, - reftet_0e_4v_splitfaces, - reftet_0e_4v_splitelements, - reftet_0e_4v_newelstypes, - reftet_0e_4v_newels -}; - - - - - - - - - - - - - - - - - -/* *********** Tet - Refinement - 1 edge *************** */ - - - -// HP_TET_1E_0V -int reftet_1e_0v_splitedges[][3] = -{ - { 1, 3, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 2, 4, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1e_0v_newelstypes[] = -{ - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_NONE, -}; -int reftet_1e_0v_newels[][8] = -{ - { 1, 5, 6, 2, 7, 8 }, - { 7, 3, 5, 8, 4, 6 } -}; -HPRef_Struct reftet_1e_0v = -{ - HP_TET, - reftet_1e_0v_splitedges, - 0, 0, - reftet_1e_0v_newelstypes, - reftet_1e_0v_newels -}; - - - - - -// HP_TET_1E_1VA -int reftet_1e_1va_splitedges[][3] = -{ - { 1, 3, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 2, 4, 8 }, - { 1, 2, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1e_1va_newelstypes[] = -{ - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_NONE, -}; -int reftet_1e_1va_newels[][8] = -{ - { 1, 9, 5, 6 }, - { 9, 5, 6, 2, 7, 8 }, - { 7, 3, 5, 8, 4, 6 } -}; -HPRef_Struct reftet_1e_1va = -{ - HP_TET, - reftet_1e_1va_splitedges, - 0, 0, - reftet_1e_1va_newelstypes, - reftet_1e_1va_newels -}; - - - - - - -// HP_TET_1E_1VB -int reftet_1e_1vb_splitedges[][3] = -{ - { 1, 3, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 2, 4, 8 }, - { 4, 1, 9 }, - { 4, 2, 10 }, - { 4, 3, 11 }, - { 0, 0, 0 } -}; -int reftet_1e_1vb_splitelements[][5] = -{ - { 4, 1, 2, 3, 12 }, - { 0 } -}; - -HPREF_ELEMENT_TYPE reftet_1e_1vb_newelstypes[] = -{ - HP_PRISM_SINGEDGE, - HP_TET_0E_1V, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_NONE, -}; -int reftet_1e_1vb_newels[][8] = -{ - { 1, 5, 6, 2, 7, 8 }, - { 4, 11, 10, 9 }, - { 7, 8, 10, 11, 12 }, - { 3, 7, 11, 12 }, - { 5, 11, 9, 6, 12 }, - { 5, 3, 11, 12 }, - { 6, 9, 10, 8, 12 }, - { 5, 7, 3, 12 }, - { 5, 6, 8, 7, 12 }, - { 9, 11, 10, 12 } -}; -HPRef_Struct reftet_1e_1vb = -{ - HP_TET, - reftet_1e_1vb_splitedges, - 0, - reftet_1e_1vb_splitelements, - reftet_1e_1vb_newelstypes, - reftet_1e_1vb_newels -}; - - - - - - - - -// HP_TET_1E_2VA -int reftet_1e_2va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1e_2va_newelstypes[] = -{ - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_NONE, -}; -int reftet_1e_2va_newels[][8] = -{ - { 1, 5, 6, 7 }, - { 2, 8, 10, 9 }, - { 5, 6, 7, 8, 9, 10 }, - { 4, 10, 7, 3, 9, 6 }, -}; -HPRef_Struct reftet_1e_2va = -{ - HP_TET, - reftet_1e_2va_splitedges, - 0, 0, - reftet_1e_2va_newelstypes, - reftet_1e_2va_newels -}; - - - - - - - -// HP_TET_1E_2VB -int reftet_1e_2vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 1, 10 }, - { 3, 2, 11 }, - { 3, 4, 12 }, - { 0, 0, 0 } -}; -int reftet_1e_2vb_splitelements[][5] = -{ - { 3, 4, 1, 2, 13 }, - { 0 } -}; - -HPREF_ELEMENT_TYPE reftet_1e_2vb_newelstypes[] = -{ - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_TET_0E_1V, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_NONE, -}; -int reftet_1e_2vb_newels[][8] = -{ - { 1, 5, 6, 7 }, - { 5, 6, 7, 2, 8, 9 }, - { 3, 10, 11, 12 }, - - { 8, 9, 12, 11, 13 }, - { 4, 12, 9, 13 }, - { 6, 10, 12, 7, 13 }, - { 4, 7, 12, 13 }, - { 6, 8, 11, 10, 13 }, - { 4, 9, 7, 13 }, - { 6, 7, 9, 8, 13 }, - { 10, 11, 12, 13 }, -}; -HPRef_Struct reftet_1e_2vb = -{ - HP_TET, - reftet_1e_2vb_splitedges, - 0, - reftet_1e_2vb_splitelements, - reftet_1e_2vb_newelstypes, - reftet_1e_2vb_newels -}; - - - - - - -// HP_TET_1E_2VC -int reftet_1e_2vc_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 4, 1, 10 }, - { 4, 2, 11 }, - { 4, 3, 12 }, - { 0, 0, 0 } -}; -int reftet_1e_2vc_splitelements[][5] = -{ - { 4, 1, 2, 3, 13 }, - { 0 } -}; - -HPREF_ELEMENT_TYPE reftet_1e_2vc_newelstypes[] = -{ - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_TET_0E_1V, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_NONE, -}; -int reftet_1e_2vc_newels[][8] = -{ - { 1, 5, 6, 7 }, - { 5, 6, 7, 2, 8, 9 }, - { 4, 11, 10, 12 }, - { 8, 9, 11, 12, 13 }, - { 3, 8, 12, 13 }, - { 7, 6, 12, 10, 13 }, - { 3, 12, 6, 13 }, - { 9, 7, 10, 11, 13 }, - { 3, 6, 8, 13 }, - { 6, 7, 9, 8, 13 }, - { 10, 12, 11, 13 } -}; -HPRef_Struct reftet_1e_2vc = -{ - HP_TET, - reftet_1e_2vc_splitedges, - 0, - reftet_1e_2vc_splitelements, - reftet_1e_2vc_newelstypes, - reftet_1e_2vc_newels -}; - - - - - - - - -/* - -// HP_TET_1E_2VD -int reftet_1e_2vd_splitedges[][3] = -{ - { 1, 3, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 2, 4, 8 }, - { 3, 1, 9 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 4, 1, 12 }, - { 4, 2, 13 }, - { 4, 3, 14 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1e_2vd_newelstypes[] = -{ - HP_PRISM_SINGEDGE, - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_PRISM, - HP_HEX, - HP_NONE, -}; -int reftet_1e_2vd_newels[][8] = -{ - { 1, 5, 6, 2, 7, 8 }, - { 4, 13, 12, 14 }, - { 3, 10, 11, 9 }, - { 14, 13, 12, 11, 10, 9 }, - { 6, 12, 13, 8, 5, 9, 10, 7 }, -}; -HPRef_Struct reftet_1e_2vd = -{ - HP_TET, - reftet_1e_2vd_splitedges, - 0, 0, - reftet_1e_2vd_newelstypes, - reftet_1e_2vd_newels -}; - -*/ - - - - -// HP_TET_1E_2VD, // 1 v on edge -int reftet_1e_2vd_splitedges[][3] = -{ - // { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - // { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_1e_2vd_splitfaces[][4] = - { - { 1, 3, 4, 19 }, - { 2, 3, 4, 22 }, - { 3, 1, 4, 24 }, - { 3, 2, 4, 25 }, - { 4, 1, 3, 27 }, - { 4, 2, 3, 28 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_1e_2vd_newelstypes[] = - { - HP_PRISM_SINGEDGE, - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_PRISM, - HP_HEX, - HP_PYRAMID, - HP_HEX, - HP_PYRAMID, - HP_PRISM, - HP_PRISM, - HP_NONE, - }; -int reftet_1e_2vd_newels[][8] = -{ - { 1, 6, 7, 2, 9, 10 }, - { 3, 11, 12, 13 }, - { 4, 16, 15, 14 }, - { 7, 6, 19, 10, 9, 22 }, - { 7, 19, 27, 14, 10, 22, 28, 15 }, - { 14, 15, 28, 27, 16 }, - { 9, 6, 19, 22, 12, 11, 24, 25 }, - { 12, 11, 24, 25, 13 }, - { 19, 24, 27, 22, 25, 28 }, - { 16, 28, 27, 13, 25, 24 } -}; -HPRef_Struct reftet_1e_2vd = -{ - HP_TET, - reftet_1e_2vd_splitedges, - reftet_1e_2vd_splitfaces, - 0, - reftet_1e_2vd_newelstypes, - reftet_1e_2vd_newels -}; - - - - - - - - - - - - - - - -// HP_TET_1E_3VA -int reftet_1e_3va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 0, 0, 0 } -}; -int reftet_1e_3va_splitelements[][5] = -{ - { 1, 2, 3, 4, 14 }, - { 0 } -}; - -HPREF_ELEMENT_TYPE reftet_1e_3va_newelstypes[] = -{ - HP_PRISM_SINGEDGE, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_TET_0E_1V, - - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_PYRAMID, - HP_TET, - HP_NONE, -}; -int reftet_1e_3va_newels[][8] = -{ - { 5, 6, 7, 8, 9, 10 }, - { 1, 5, 6, 7 }, - { 2, 8, 10, 9 }, - { 3, 11, 12, 13 }, - - { 6, 7, 10, 9, 14 }, - { 4, 10, 7, 14 }, - { 9, 10, 13, 12, 14 }, - { 4, 13, 10, 14 }, - { 6, 11, 13, 7, 14 }, - { 4, 7, 13, 14 }, - { 6, 11, 12, 9, 14 }, - { 11, 13, 12, 14 }, -}; - -HPRef_Struct reftet_1e_3va = -{ - HP_TET, - reftet_1e_3va_splitedges, - 0, - reftet_1e_3va_splitelements, - reftet_1e_3va_newelstypes, - reftet_1e_3va_newels -}; - - - - - - - - - - - - - - - - - - - - - - -// HP_TET_1E_3VB, // 1 v on edge -int reftet_1e_3vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - // { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_1e_3vb_splitfaces[][4] = - { - { 1, 3, 4, 19 }, - { 2, 3, 4, 22 }, - { 3, 1, 4, 24 }, - { 3, 2, 4, 25 }, - { 4, 1, 3, 27 }, - { 4, 2, 3, 28 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_1e_3vb_newelstypes[] = - { - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_PRISM, - HP_HEX, - HP_PYRAMID, - HP_HEX, - HP_PYRAMID, - HP_PRISM, - HP_PRISM, - HP_NONE, - }; -int reftet_1e_3vb_newels[][8] = -{ - { 1, 5, 6, 7 }, - { 5, 6, 7, 2, 9, 10 }, - { 3, 11, 12, 13 }, - { 4, 16, 15, 14 }, - { 7, 6, 19, 10, 9, 22 }, - { 7, 19, 27, 14, 10, 22, 28, 15 }, - { 14, 15, 28, 27, 16 }, - { 9, 6, 19, 22, 12, 11, 24, 25 }, - { 12, 11, 24, 25, 13 }, - { 19, 24, 27, 22, 25, 28 }, - { 16, 28, 27, 13, 25, 24 } -}; -HPRef_Struct reftet_1e_3vb = -{ - HP_TET, - reftet_1e_3vb_splitedges, - reftet_1e_3vb_splitfaces, - 0, - reftet_1e_3vb_newelstypes, - reftet_1e_3vb_newels -}; - - - - - - - - - -// HP_TET_1E_4V -int reftet_1e_4v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_1e_4v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 1, 2, 4, 18 }, - { 1, 3, 4, 19 }, - - { 2, 1, 3, 20 }, - { 2, 1, 4, 21 }, - { 2, 3, 4, 22 }, - - { 3, 1, 2, 23 }, - { 3, 1, 4, 24 }, - { 3, 2, 4, 25 }, - - { 4, 1, 2, 26 }, - { 4, 1, 3, 27 }, - { 4, 2, 3, 28 }, - { 0, 0, 0, 0 }, - }; -int reftet_1e_4v_splitelements[][5] = - { - { 1, 2, 3, 4, 29 }, - { 2, 3, 4, 1, 30 }, - { 3, 4, 1, 2, 31 }, - { 4, 1, 2, 3, 32 }, - { 0 }, - }; -HPREF_ELEMENT_TYPE reftet_1e_4v_newelstypes[] = -{ - HP_HEX_1E_1V, - HP_HEX_1E_1V, - HP_HEX_0E_1V, - HP_HEX_0E_1V, - HP_PRISM_SINGEDGE, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, -}; -int reftet_1e_4v_newels[][8] = -{ - { 1, 5, 17, 6, 7, 18, 29, 19 }, - // { 2, 9, 20, 8, 10, 22, 30, 21 }, - { 2, 8, 21, 10, 9, 20, 30, 22 }, - { 3, 11, 23, 12, 13, 24, 31, 25 }, - { 4, 15, 26, 14, 16, 28, 32, 27 }, - { 5, 17, 18, 8, 20, 21 }, - { 18, 17, 29, 21, 20, 30 }, - { 6, 19, 17, 11, 24, 23 }, - { 17, 19, 29, 23, 24, 31 }, - { 7, 18, 19, 14, 26, 27 }, - { 19, 18, 29, 27, 26, 32 }, - { 9, 20, 22, 12, 23, 25 }, - { 22, 20, 30, 25, 23, 31 }, - { 10, 22, 21, 15, 28, 26 }, - { 21, 22, 30, 26, 28, 32 }, - { 13, 24, 25, 16, 27, 28 }, - { 25, 24, 31, 28, 27, 32 }, - /* - { 5, 17, 29, 18, 8, 20, 30, 21 }, - { 6, 19, 29, 17, 11, 24, 31, 23 }, - { 7, 18, 29, 19, 14, 26, 32, 27 }, - { 9, 20, 30, 22, 12, 23, 31, 25 }, - { 10, 22, 30, 21, 15, 28, 32, 26 }, - { 13, 24, 31, 25, 16, 27, 32, 28 }, - */ - { 17, 20, 23, 29, 30, 31 }, - { 18, 26, 21, 29, 32, 30 }, - { 19, 24, 27, 29, 31, 32 }, - { 22, 28, 25, 30, 32, 31 }, - - { 29, 30, 31, 32 }, -}; -HPRef_Struct reftet_1e_4v = -{ - HP_TET, - reftet_1e_4v_splitedges, - reftet_1e_4v_splitfaces, - reftet_1e_4v_splitelements, - reftet_1e_4v_newelstypes, - reftet_1e_4v_newels -}; - - - - - - - - - - - - -// HP_TET_2EA_0V, // 2 edges connected -int reftet_2ea_0v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 0, 0, 0 } -}; -int reftet_2ea_0v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_0v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_2ea_0v_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 5, 17, 7, 2, 9, 10 }, - { 6, 7, 17, 3, 13, 12 }, - { 17, 9, 12, 7, 10, 13 }, - { 7, 10, 13, 4 }, -}; -HPRef_Struct reftet_2ea_0v = -{ - HP_TET, - reftet_2ea_0v_splitedges, - reftet_2ea_0v_splitfaces, - 0, - reftet_2ea_0v_newelstypes, - reftet_2ea_0v_newels -}; - - - - - - -// HP_TET_2EA_1VA, // 2 edges connected -int reftet_2ea_1va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 0, 0, 0 } -}; -int reftet_2ea_1va_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_1va_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PRISM_SINGEDGE, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_2ea_1va_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 5, 17, 7, 8, 9, 10 }, - { 2, 8, 10, 9 }, - { 6, 7, 17, 3, 13, 12 }, - { 17, 9, 12, 7, 10, 13 }, - { 7, 10, 13, 4 }, -}; -HPRef_Struct reftet_2ea_1va = -{ - HP_TET, - reftet_2ea_1va_splitedges, - reftet_2ea_1va_splitfaces, - 0, - reftet_2ea_1va_newelstypes, - reftet_2ea_1va_newels -}; - - - - - - - - -// HP_TET_2EA_1VB, -int reftet_2ea_1vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 0, 0, 0 } -}; -int reftet_2ea_1vb_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_1vb_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_2ea_1vb_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 3, 11, 12, 13 }, - { 5, 17, 7, 2, 9, 10 }, - { 6, 7, 17, 11, 13, 12 }, - { 17, 9, 12, 7, 10, 13 }, - { 7, 10, 13, 4 }, -}; -HPRef_Struct reftet_2ea_1vb = -{ - HP_TET, - reftet_2ea_1vb_splitedges, - reftet_2ea_1vb_splitfaces, - 0, - reftet_2ea_1vb_newelstypes, - reftet_2ea_1vb_newels -}; - - - - - - -// HP_TET_2EA_1VC, // 2 edges connected -int reftet_2ea_1vc_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - // { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_2ea_1vc_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 3, 4, 18 }, - { 3, 4, 2, 19 }, - { 4, 2, 3, 20 }, - { 0, 0, 0, 0 } - }; -int reftet_2ea_1vc_splitelements[][5] = - { - { 1, 2, 3, 4, 21 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_1vc_newelstypes[] = - { - HP_PYRAMID_EDGES, - // HP_TET_1E_1VA, - HP_TET_0E_1V, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_TET, HP_TET, HP_TET, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, - HP_PYRAMID, HP_PYRAMID, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_TET, - // HP_PRISM, - // HP_PRISM, - HP_NONE, - }; -int reftet_2ea_1vc_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - // { 3, 11, 12, 13 }, - { 4, 15, 14, 16 }, - { 5, 17, 7, 2, 9, 10 }, - { 6, 7, 17, 3, 13, 12 }, - - { 9, 10, 18, 21 }, - { 13, 12, 19, 21 }, - { 15, 16, 20, 21 }, - { 18, 20, 19, 21 }, - { 10, 15, 20, 18, 21 }, - { 13, 19, 20, 16, 21 }, - { 9, 18, 19, 12, 21 }, - - { 7, 13, 16, 14, 21 }, - { 7, 14, 15, 10, 21 }, - { 9, 12, 17, 21 }, - { 7, 10, 9, 17, 21 }, - { 7, 17, 12, 13, 21 }, - { 14, 16, 15, 21 }, - // { 17, 9, 12, 7, 10, 13 }, - // { 7, 10, 13, 14, 15, 16 }, -}; -HPRef_Struct reftet_2ea_1vc = -{ - HP_TET, - reftet_2ea_1vc_splitedges, - reftet_2ea_1vc_splitfaces, - reftet_2ea_1vc_splitelements, - reftet_2ea_1vc_newelstypes, - reftet_2ea_1vc_newels -}; - - - - - - - - - - - - -// HP_TET_2EA_2VA, -int reftet_2ea_2va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 0, 0, 0 } -}; -int reftet_2ea_2va_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_2va_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_2ea_2va_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 3, 11, 12, 13 }, - { 2, 8, 10, 9 }, - { 5, 17, 7, 8, 9, 10 }, - { 6, 7, 17, 11, 13, 12 }, - { 17, 9, 12, 7, 10, 13 }, - { 7, 10, 13, 4 }, -}; -HPRef_Struct reftet_2ea_2va = -{ - HP_TET, - reftet_2ea_2va_splitedges, - reftet_2ea_2va_splitfaces, - 0, - reftet_2ea_2va_newelstypes, - reftet_2ea_2va_newels -}; - - - - - - - - - - - -// HP_TET_2EA_2VB, // 2 edges connected -int reftet_2ea_2vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - // { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_2ea_2vb_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 3, 4, 18 }, - { 3, 4, 2, 19 }, - { 4, 2, 3, 20 }, - { 0, 0, 0, 0 } - }; -int reftet_2ea_2vb_splitelements[][5] = - { - { 1, 2, 3, 4, 21 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_2vb_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_TET_0E_1V, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_TET, HP_TET, HP_TET, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, - HP_PYRAMID, HP_PYRAMID, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_TET, - // HP_PRISM, - // HP_PRISM, - HP_NONE, - }; -int reftet_2ea_2vb_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 2, 8, 10, 9 }, - // { 3, 11, 12, 13 }, - { 4, 15, 14, 16 }, - { 5, 17, 7, 8, 9, 10 }, - { 6, 7, 17, 3, 13, 12 }, - - { 9, 10, 18, 21 }, - { 13, 12, 19, 21 }, - { 15, 16, 20, 21 }, - { 18, 20, 19, 21 }, - { 10, 15, 20, 18, 21 }, - { 13, 19, 20, 16, 21 }, - { 9, 18, 19, 12, 21 }, - - { 7, 13, 16, 14, 21 }, - { 7, 14, 15, 10, 21 }, - { 9, 12, 17, 21 }, - { 7, 10, 9, 17, 21 }, - { 7, 17, 12, 13, 21 }, - { 14, 16, 15, 21 }, - // { 17, 9, 12, 7, 10, 13 }, - // { 7, 10, 13, 14, 15, 16 }, -}; -HPRef_Struct reftet_2ea_2vb = -{ - HP_TET, - reftet_2ea_2vb_splitedges, - reftet_2ea_2vb_splitfaces, - reftet_2ea_2vb_splitelements, - reftet_2ea_2vb_newelstypes, - reftet_2ea_2vb_newels -}; - - - - - - - - - - -// HP_TET_2EA_2VC, // 2 edges connected -int reftet_2ea_2vc_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - // { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_2ea_2vc_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 3, 4, 18 }, - { 3, 4, 2, 19 }, - { 4, 2, 3, 20 }, - { 0, 0, 0, 0 } - }; -int reftet_2ea_2vc_splitelements[][5] = - { - { 1, 2, 3, 4, 21 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_2vc_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_TET_0E_1V, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_TET, HP_TET, HP_TET, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, - HP_PYRAMID, HP_PYRAMID, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_TET, - // HP_PRISM, - // HP_PRISM, - HP_NONE, - }; -int reftet_2ea_2vc_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - // { 2, 8, 10, 9 }, - { 3, 11, 12, 13 }, - { 4, 15, 14, 16 }, - { 5, 17, 7, 2, 9, 10 }, - { 6, 7, 17, 11, 13, 12 }, - - { 9, 10, 18, 21 }, - { 13, 12, 19, 21 }, - { 15, 16, 20, 21 }, - { 18, 20, 19, 21 }, - { 10, 15, 20, 18, 21 }, - { 13, 19, 20, 16, 21 }, - { 9, 18, 19, 12, 21 }, - - { 7, 13, 16, 14, 21 }, - { 7, 14, 15, 10, 21 }, - { 9, 12, 17, 21 }, - { 7, 10, 9, 17, 21 }, - { 7, 17, 12, 13, 21 }, - { 14, 16, 15, 21 }, - // { 17, 9, 12, 7, 10, 13 }, - // { 7, 10, 13, 14, 15, 16 }, -}; -HPRef_Struct reftet_2ea_2vc = -{ - HP_TET, - reftet_2ea_2vc_splitedges, - reftet_2ea_2vc_splitfaces, - reftet_2ea_2vc_splitelements, - reftet_2ea_2vc_newelstypes, - reftet_2ea_2vc_newels -}; - - - - - - - - -// HP_TET_2EA_3V, // 2 edges connected -int reftet_2ea_3v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_2ea_3v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 3, 4, 18 }, - { 3, 4, 2, 19 }, - { 4, 2, 3, 20 }, - { 0, 0, 0, 0 } - }; -int reftet_2ea_3v_splitelements[][5] = - { - { 1, 2, 3, 4, 21 }, - { 0, 0, 0, 0 } - }; -HPREF_ELEMENT_TYPE reftet_2ea_3v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_TET_0E_1V, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_TET, HP_TET, HP_TET, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, - HP_PYRAMID, HP_PYRAMID, HP_TET, - HP_PYRAMID, HP_PYRAMID, HP_TET, - // HP_PRISM, - // HP_PRISM, - HP_NONE, - }; -int reftet_2ea_3v_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 2, 8, 10, 9 }, - { 3, 11, 12, 13 }, - { 4, 15, 14, 16 }, - { 5, 17, 7, 8, 9, 10 }, - { 6, 7, 17, 11, 13, 12 }, - - { 9, 10, 18, 21 }, - { 13, 12, 19, 21 }, - { 15, 16, 20, 21 }, - { 18, 20, 19, 21 }, - { 10, 15, 20, 18, 21 }, - { 13, 19, 20, 16, 21 }, - { 9, 18, 19, 12, 21 }, - - { 7, 13, 16, 14, 21 }, - { 7, 14, 15, 10, 21 }, - { 9, 12, 17, 21 }, - { 7, 10, 9, 17, 21 }, - { 7, 17, 12, 13, 21 }, - { 14, 16, 15, 21 }, - // { 17, 9, 12, 7, 10, 13 }, - // { 7, 10, 13, 14, 15, 16 }, -}; -HPRef_Struct reftet_2ea_3v = -{ - HP_TET, - reftet_2ea_3v_splitedges, - reftet_2ea_3v_splitfaces, - reftet_2ea_3v_splitelements, - reftet_2ea_3v_newelstypes, - reftet_2ea_3v_newels -}; - - - - - - - -// HP_TET_2EB_0V, // 2 opposite edges -int reftet_2eb_0v_splitedges[][3] = -{ - { 1, 3, 5 }, - { 1, 4, 6 }, - { 2, 3, 7 }, - { 2, 4, 8 }, - { 3, 1, 9 }, - { 3, 2, 10 }, - { 4, 1, 11 }, - { 4, 2, 12 }, - { 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftet_2eb_0v_newelstypes[] = - { - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_HEX, - HP_NONE, - }; -int reftet_2eb_0v_newels[][8] = -{ - { 1, 5, 6, 2, 7, 8 }, - { 3, 9, 10, 4, 11, 12 }, - { 6, 11, 12, 8, 5, 9, 10, 7 }, -}; -HPRef_Struct reftet_2eb_0v = -{ - HP_TET, - reftet_2eb_0v_splitedges, - 0, 0, - reftet_2eb_0v_newelstypes, - reftet_2eb_0v_newels -}; - - - - - - - -// HP_TET_2EB_2VA, // 2 opposite edges -int reftet_2eb_2va_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftet_2eb_2va_newelstypes[] = - { - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_HEX, - HP_NONE, - }; -int reftet_2eb_2va_newels[][8] = -{ - { 5, 6, 7, 2, 9, 10 }, - { 4, 15, 14, 13, 12, 11 }, - { 1, 5, 6, 7 }, - // { 2, 8, 10, 9 }, - { 3, 13, 11, 12 }, - // { 4, 16, 15, 14 }, - { 7, 14, 15, 10, 6, 11, 12, 9 } -}; -HPRef_Struct reftet_2eb_2va = -{ - HP_TET, - reftet_2eb_2va_splitedges, - 0, 0, - reftet_2eb_2va_newelstypes, - reftet_2eb_2va_newels -}; - - - - - - -// HP_TET_2EB_4V, // 2 opposite edges -int reftet_2eb_4v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftet_2eb_4v_newelstypes[] = - { - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_HEX, - HP_NONE, - }; -int reftet_2eb_4v_newels[][8] = -{ - { 5, 6, 7, 8, 9, 10 }, - { 16, 15, 14, 13, 12, 11 }, - { 1, 5, 6, 7 }, - { 2, 8, 10, 9 }, - { 3, 13, 11, 12 }, - { 4, 16, 15, 14 }, - { 7, 14, 15, 10, 6, 11, 12, 9 } -}; -HPRef_Struct reftet_2eb_4v = -{ - HP_TET, - reftet_2eb_4v_splitedges, - 0, 0, - reftet_2eb_4v_newelstypes, - reftet_2eb_4v_newels -}; - - - - - - - - - - - - - - - - - -// HP_TET_3EA_0V, -int reftet_3ea_0v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 4, 2, 12 }, - { 4, 3, 13 }, - { 0, 0, 0 } -}; -int reftet_3ea_0v_splitfaces[][4] = - { - { 1, 2, 3, 14 }, - { 1, 2, 4, 15 }, - { 1, 3, 4, 16 }, - { 2, 3, 4, 17 }, - { 3, 4, 2, 18 }, - { 4, 2, 3, 19 }, - { 0, 0, 0, 0 } - }; -int reftet_3ea_0v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ea_0v_newelstypes[] = - { - HP_HEX_3E_0V, - HP_HEX_1E_0V, - HP_HEX_1E_0V, - HP_HEX_1E_0V, - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_3ea_0v_newels[][8] = -{ - { 1, 5, 14, 6, 7, 15, 20, 16 }, - { 5, 2, 8, 14, 15, 9, 17, 20 }, - { 3, 6, 14, 10, 11, 16, 20, 18 }, - { 7, 4, 12, 15, 16, 13, 19, 20 }, - { 11, 13, 16, 18, 19, 20 }, - { 15, 12, 9, 20, 19, 17 }, - { 8, 10, 14, 17, 18, 20 }, - { 20, 17, 18, 19 }, -}; -HPRef_Struct reftet_3ea_0v = -{ - HP_TET, - reftet_3ea_0v_splitedges, - reftet_3ea_0v_splitfaces, - reftet_3ea_0v_splitelements, - reftet_3ea_0v_newelstypes, - reftet_3ea_0v_newels -}; - - - - - - - - - - -// HP_TET_3EA_1V, -int reftet_3ea_1v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 4, 2, 12 }, - { 4, 3, 13 }, - { 2, 1, 21 }, - { 3, 1, 22 }, - { 4, 1, 23 }, - { 0, 0, 0 } -}; -int reftet_3ea_1v_splitfaces[][4] = - { - { 1, 2, 3, 14 }, - { 1, 2, 4, 15 }, - { 1, 3, 4, 16 }, - { 2, 3, 4, 17 }, - { 3, 4, 2, 18 }, - { 4, 2, 3, 19 }, - { 0, 0, 0, 0 } - }; -int reftet_3ea_1v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ea_1v_newelstypes[] = - { - HP_HEX_3E_0V, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_3ea_1v_newels[][8] = -{ - { 1, 5, 14, 6, 7, 15, 20, 16 }, - - { 2, 21, 9, 8 }, - { 5, 14, 15, 21, 8, 9 }, - { 15, 14, 20, 9, 8, 17 }, - // { 3, 22, 10, 11 }, - // { 6, 16, 14, 22, 11, 10 }, - { 6, 16, 14, 3, 11, 10 }, - { 14, 16, 20, 10, 11, 18 }, - // { 4, 23, 13, 12 }, - // { 7, 15, 16, 23, 12, 13 }, - { 7, 15, 16, 4, 12, 13 }, - { 16, 15, 20, 13, 12, 19 }, - - { 11, 13, 16, 18, 19, 20 }, - { 15, 12, 9, 20, 19, 17 }, - { 8, 10, 14, 17, 18, 20 }, - { 20, 17, 18, 19 }, -}; -HPRef_Struct reftet_3ea_1v = -{ - HP_TET, - reftet_3ea_1v_splitedges, - reftet_3ea_1v_splitfaces, - reftet_3ea_1v_splitelements, - reftet_3ea_1v_newelstypes, - reftet_3ea_1v_newels -}; - - - - - - - - - - -// HP_TET_3EA_2V, -int reftet_3ea_2v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 4, 2, 12 }, - { 4, 3, 13 }, - { 2, 1, 21 }, - { 3, 1, 22 }, - { 4, 1, 23 }, - { 0, 0, 0 } -}; -int reftet_3ea_2v_splitfaces[][4] = - { - { 1, 2, 3, 14 }, - { 1, 2, 4, 15 }, - { 1, 3, 4, 16 }, - { 2, 3, 4, 17 }, - { 3, 4, 2, 18 }, - { 4, 2, 3, 19 }, - { 0, 0, 0, 0 } - }; -int reftet_3ea_2v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ea_2v_newelstypes[] = - { - HP_HEX_3E_0V, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_3ea_2v_newels[][8] = -{ - { 1, 5, 14, 6, 7, 15, 20, 16 }, - - { 2, 21, 9, 8 }, - { 5, 14, 15, 21, 8, 9 }, - { 15, 14, 20, 9, 8, 17 }, - { 3, 22, 10, 11 }, - { 6, 16, 14, 22, 11, 10 }, - { 14, 16, 20, 10, 11, 18 }, - // { 4, 23, 13, 12 }, - { 7, 15, 16, 4, 12, 13 }, - { 16, 15, 20, 13, 12, 19 }, - - { 11, 13, 16, 18, 19, 20 }, - { 15, 12, 9, 20, 19, 17 }, - { 8, 10, 14, 17, 18, 20 }, - { 20, 17, 18, 19 }, -}; -HPRef_Struct reftet_3ea_2v = -{ - HP_TET, - reftet_3ea_2v_splitedges, - reftet_3ea_2v_splitfaces, - reftet_3ea_2v_splitelements, - reftet_3ea_2v_newelstypes, - reftet_3ea_2v_newels -}; - - - - - - - - -// HP_TET_3EA_3V, -int reftet_3ea_3v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 2, 10 }, - { 3, 4, 11 }, - { 4, 2, 12 }, - { 4, 3, 13 }, - { 2, 1, 21 }, - { 3, 1, 22 }, - { 4, 1, 23 }, - { 0, 0, 0 } -}; -int reftet_3ea_3v_splitfaces[][4] = - { - { 1, 2, 3, 14 }, - { 1, 2, 4, 15 }, - { 1, 3, 4, 16 }, - { 2, 3, 4, 17 }, - { 3, 4, 2, 18 }, - { 4, 2, 3, 19 }, - { 0, 0, 0, 0 } - }; -int reftet_3ea_3v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ea_3v_newelstypes[] = - { - HP_HEX_3E_0V, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - - HP_PRISM, - HP_PRISM, - HP_PRISM, - HP_TET, - HP_NONE, - }; -int reftet_3ea_3v_newels[][8] = -{ - { 1, 5, 14, 6, 7, 15, 20, 16 }, - - { 2, 21, 9, 8 }, - { 5, 14, 15, 21, 8, 9 }, - { 15, 14, 20, 9, 8, 17 }, - { 3, 22, 10, 11 }, - { 6, 16, 14, 22, 11, 10 }, - { 14, 16, 20, 10, 11, 18 }, - { 4, 23, 13, 12 }, - { 7, 15, 16, 23, 12, 13 }, - { 16, 15, 20, 13, 12, 19 }, - - { 11, 13, 16, 18, 19, 20 }, - { 15, 12, 9, 20, 19, 17 }, - { 8, 10, 14, 17, 18, 20 }, - { 20, 17, 18, 19 }, -}; -HPRef_Struct reftet_3ea_3v = -{ - HP_TET, - reftet_3ea_3v_splitedges, - reftet_3ea_3v_splitfaces, - reftet_3ea_3v_splitelements, - reftet_3ea_3v_newelstypes, - reftet_3ea_3v_newels -}; - - - - - - - -// HP_TET_3EV_0V, -int reftet_3eb_0v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - // { 3, 2, 12 }, - { 3, 4, 13 }, - // { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_3eb_0v_splitfaces[][4] = - { - { 1, 2, 4, 17 }, - { 2, 1, 3, 18 }, - { 0, 0, 0, 0 } - }; -int reftet_3eb_0v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3eb_0v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PYRAMID_EDGES, - // HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_PYRAMID, - HP_PYRAMID, - HP_TET, - HP_TET, - HP_PYRAMID, - HP_PYRAMID, - HP_PYRAMID, - HP_NONE, - }; -int reftet_3eb_0v_newels[][8] = -{ - { 1, 7, 17, 5, 6 }, - { 2, 9, 18, 8, 10 }, - // { 3, 12, 13, 11 }, - // { 4, 14, 16, 15 }, - { 5, 6, 17, 8, 18, 10 }, - { 7, 17, 6, 4, 15, 16 }, - { 9, 18, 10, 3, 11, 13 }, - - { 10, 15, 16, 13, 20 }, - { 6, 11, 13, 16, 20 }, - { 10, 17, 15, 20 }, - { 6, 18, 11, 20 }, - { 6, 17, 10, 18, 20 }, - { 6, 16, 15, 17, 20 }, - { 18, 10, 13, 11, 20 }, -}; -HPRef_Struct reftet_3eb_0v = -{ - HP_TET, - reftet_3eb_0v_splitedges, - reftet_3eb_0v_splitfaces, - reftet_3eb_0v_splitelements, - reftet_3eb_0v_newelstypes, - reftet_3eb_0v_newels -}; - - - - - - - - - -// HP_TET_3EV_1V, -int reftet_3eb_1v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - // { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_3eb_1v_splitfaces[][4] = - { - { 1, 2, 4, 17 }, - { 2, 1, 3, 18 }, - { 0, 0, 0, 0 } - }; -int reftet_3eb_1v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3eb_1v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_PYRAMID, - HP_PYRAMID, - HP_TET, - HP_TET, - HP_PYRAMID, - HP_PYRAMID, - HP_PYRAMID, - HP_NONE, - }; -int reftet_3eb_1v_newels[][8] = -{ - { 1, 7, 17, 5, 6 }, - { 2, 9, 18, 8, 10 }, - { 3, 12, 13, 11 }, - // { 4, 14, 16, 15 }, - { 5, 6, 17, 8, 18, 10 }, - { 7, 17, 6, 4, 15, 16 }, - { 9, 18, 10, 12, 11, 13 }, - - { 10, 15, 16, 13, 20 }, - { 6, 11, 13, 16, 20 }, - { 10, 17, 15, 20 }, - { 6, 18, 11, 20 }, - { 6, 17, 10, 18, 20 }, - { 6, 16, 15, 17, 20 }, - { 18, 10, 13, 11, 20 }, -}; -HPRef_Struct reftet_3eb_1v = -{ - HP_TET, - reftet_3eb_1v_splitedges, - reftet_3eb_1v_splitfaces, - reftet_3eb_1v_splitelements, - reftet_3eb_1v_newelstypes, - reftet_3eb_1v_newels -}; - - - - - - - - -// HP_TET_3EV_2V, -int reftet_3eb_2v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_3eb_2v_splitfaces[][4] = - { - { 1, 2, 4, 17 }, - { 2, 1, 3, 18 }, - { 0, 0, 0, 0 } - }; -int reftet_3eb_2v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3eb_2v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_PYRAMID, - HP_PYRAMID, - HP_TET, - HP_TET, - HP_PYRAMID, - HP_PYRAMID, - HP_PYRAMID, - HP_NONE, - }; -int reftet_3eb_2v_newels[][8] = -{ - { 1, 7, 17, 5, 6 }, - { 2, 9, 18, 8, 10 }, - { 3, 12, 13, 11 }, - { 4, 14, 16, 15 }, - { 5, 6, 17, 8, 18, 10 }, - { 7, 17, 6, 14, 15, 16 }, - { 9, 18, 10, 12, 11, 13 }, - - { 10, 15, 16, 13, 20 }, - { 6, 11, 13, 16, 20 }, - { 10, 17, 15, 20 }, - { 6, 18, 11, 20 }, - { 6, 17, 10, 18, 20 }, - { 6, 16, 15, 17, 20 }, - { 18, 10, 13, 11, 20 }, -}; -HPRef_Struct reftet_3eb_2v = -{ - HP_TET, - reftet_3eb_2v_splitedges, - reftet_3eb_2v_splitfaces, - reftet_3eb_2v_splitelements, - reftet_3eb_2v_newelstypes, - reftet_3eb_2v_newels -}; - - - - - - - - - - - - - -// HP_TET_3EC_0V, -int reftet_3ec_0v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - // { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - // { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_3ec_0v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 1, 4, 18 }, - { 0, 0, 0, 0 } - }; -int reftet_3ec_0v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ec_0v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PYRAMID_EDGES, - // HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_PYRAMID, - HP_PYRAMID, - HP_TET, - HP_TET, - HP_PYRAMID, - HP_PYRAMID, - HP_PYRAMID, - HP_NONE, - }; -int reftet_3ec_0v_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 2, 8, 18, 10, 9 }, - // { 3, 11, 12, 13 }, - // { 4, 15, 14, 16 }, - { 5, 17, 7, 8, 9, 18 }, - { 6, 7, 17, 3, 13, 12 }, - { 10, 9, 18, 4, 16, 14 }, - - { 9, 16, 13, 12, 20 }, - { 7, 13, 16, 14, 20 }, - { 7, 14, 18, 20 }, - { 9, 12, 17, 20 }, - { 17, 7, 18, 9, 20 }, - { 7, 17, 12, 13, 20 }, - { 9, 18, 14, 16, 20 }, -}; -HPRef_Struct reftet_3ec_0v = -{ - HP_TET, - reftet_3ec_0v_splitedges, - reftet_3ec_0v_splitfaces, - reftet_3ec_0v_splitelements, - reftet_3ec_0v_newelstypes, - reftet_3ec_0v_newels -}; - - - - - - - - - -// HP_TET_3EC_1V, -int reftet_3ec_1v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - // { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_3ec_1v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 1, 4, 18 }, - { 0, 0, 0, 0 } - }; -int reftet_3ec_1v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ec_1v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - // HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_PYRAMID, - HP_PYRAMID, - HP_TET, - HP_TET, - HP_PYRAMID, - HP_PYRAMID, - HP_PYRAMID, - HP_NONE, - }; -int reftet_3ec_1v_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 2, 8, 18, 10, 9 }, - { 3, 11, 12, 13 }, - // { 4, 15, 14, 16 }, - { 5, 17, 7, 8, 9, 18 }, - { 6, 7, 17, 11, 13, 12 }, - { 10, 9, 18, 4, 16, 14 }, - - { 9, 16, 13, 12, 20 }, - { 7, 13, 16, 14, 20 }, - { 7, 14, 18, 20 }, - { 9, 12, 17, 20 }, - { 17, 7, 18, 9, 20 }, - { 7, 17, 12, 13, 20 }, - { 9, 18, 14, 16, 20 }, -}; -HPRef_Struct reftet_3ec_1v = -{ - HP_TET, - reftet_3ec_1v_splitedges, - reftet_3ec_1v_splitfaces, - reftet_3ec_1v_splitelements, - reftet_3ec_1v_newelstypes, - reftet_3ec_1v_newels -}; - - - - - - - - -// HP_TET_3EC_2V, -int reftet_3ec_2v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 2, 3, 9 }, - { 2, 4, 10 }, - { 3, 1, 11 }, - { 3, 2, 12 }, - { 3, 4, 13 }, - { 4, 1, 14 }, - { 4, 2, 15 }, - { 4, 3, 16 }, - { 0, 0, 0 } -}; -int reftet_3ec_2v_splitfaces[][4] = - { - { 1, 2, 3, 17 }, - { 2, 1, 4, 18 }, - { 0, 0, 0, 0 } - }; -int reftet_3ec_2v_splitelements[][5] = - { - { 1, 2, 3, 4, 20 }, - { 0 }, - }; - -HPREF_ELEMENT_TYPE reftet_3ec_2v_newelstypes[] = - { - HP_PYRAMID_EDGES, - HP_PYRAMID_EDGES, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE, - - HP_PYRAMID, - HP_PYRAMID, - HP_TET, - HP_TET, - HP_PYRAMID, - HP_PYRAMID, - HP_PYRAMID, - HP_NONE, - }; -int reftet_3ec_2v_newels[][8] = -{ - { 1, 5, 17, 6, 7 }, - { 2, 8, 18, 10, 9 }, - { 3, 11, 12, 13 }, - { 4, 15, 14, 16 }, - { 5, 17, 7, 8, 9, 18 }, - { 6, 7, 17, 11, 13, 12 }, - { 10, 9, 18, 15, 16, 14 }, - - { 9, 16, 13, 12, 20 }, - { 7, 13, 16, 14, 20 }, - { 7, 14, 18, 20 }, - { 9, 12, 17, 20 }, - { 17, 7, 18, 9, 20 }, - { 7, 17, 12, 13, 20 }, - { 9, 18, 14, 16, 20 }, -}; -HPRef_Struct reftet_3ec_2v = -{ - HP_TET, - reftet_3ec_2v_splitedges, - reftet_3ec_2v_splitfaces, - reftet_3ec_2v_splitelements, - reftet_3ec_2v_newelstypes, - reftet_3ec_2v_newels -}; - - - - - - - - - - -/* ************************ 1 singular face ******************** */ - - -// HP_TET_1F_0E_0V -int reftet_1f_0e_0v_splitedges[][3] = -{ - { 2, 1, 5 }, - { 3, 1, 6 }, - { 4, 1, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1f_0e_0v_newelstypes[] = -{ - HP_PRISM_1FA_0E_0V, - HP_TET, - HP_NONE, -}; -int reftet_1f_0e_0v_newels[][8] = -{ - { 3, 2, 4, 6, 5, 7 }, - { 5, 7, 6, 1 } -}; -HPRef_Struct reftet_1f_0e_0v = -{ - HP_TET, - reftet_1f_0e_0v_splitedges, - 0, 0, - reftet_1f_0e_0v_newelstypes, - reftet_1f_0e_0v_newels -}; - - - - - -// HP_TET_1F_0E_1VA ... singular vertex in face -int reftet_1f_0e_1va_splitedges[][3] = -{ - { 2, 1, 5 }, - { 2, 3, 6 }, - { 2, 4, 7 }, - { 3, 1, 8 }, - { 4, 1, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1f_0e_1va_newelstypes[] = -{ - HP_HEX_1F_0E_0V, - HP_TET_1F_0E_1VA, - HP_TET, - HP_NONE, -}; -int reftet_1f_0e_1va_newels[][8] = -{ - { 3, 6, 7, 4, 8, 5, 5, 9 }, - { 5, 2, 6, 7 }, - { 5, 9, 8, 1 }, -}; -HPRef_Struct reftet_1f_0e_1va = -{ - HP_TET, - reftet_1f_0e_1va_splitedges, - 0, 0, - reftet_1f_0e_1va_newelstypes, - reftet_1f_0e_1va_newels -}; - - - - - -// HP_TET_1F_0E_1VB ... singular vertex not in face -int reftet_1f_0e_1vb_splitedges[][3] = -{ - { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 1, 8 }, - { 3, 1, 9 }, - { 4, 1, 10 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftet_1f_0e_1vb_newelstypes[] = -{ - HP_PRISM_1FA_0E_0V, - HP_PRISM, - HP_TET_0E_1V, - HP_NONE, -}; -int reftet_1f_0e_1vb_newels[][8] = -{ - { 2, 4, 3, 8, 10, 9 }, - { 8, 10, 9, 5, 7, 6 }, - { 1, 5, 6, 7 }, -}; -HPRef_Struct reftet_1f_0e_1vb = -{ - HP_TET, - reftet_1f_0e_1vb_splitedges, - 0, 0, - reftet_1f_0e_1vb_newelstypes, - reftet_1f_0e_1vb_newels -}; - - - - - - - - -// HP_TET_1F_1EA_0V ... sing edge is 1..2 -int reftet_1f_1ea_0v_splitedges[][3] = -{ - { 1, 3, 5 }, - { 1, 4, 6 }, - { 2, 1, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 1, 10 }, - { 4, 1, 11 }, - { 0, 0, 0 } -}; - -int reftet_1f_1ea_0v_splitfaces[][4] = - { - { 2, 1, 3, 12 }, - { 2, 1, 4, 13 }, - { 0, 0, 0, 0 } - }; - - -HPREF_ELEMENT_TYPE reftet_1f_1ea_0v_newelstypes[] = -{ - HP_HEX_1F_0E_0V, - // HP_PRISM, - HP_PYRAMID_1FB_0E_1VA, - HP_TET_1E_1VA, - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_NONE, -}; -int reftet_1f_1ea_0v_newels[][8] = -{ - { 3, 8, 9, 4, 10, 12, 13, 11 }, - // { 2, 9, 8, 7, 13, 12 }, - { 8, 9, 13, 12, 2 }, - { 2, 7, 13, 12 }, - { 7, 13, 12, 1, 6, 5 }, - { 6, 11, 13, 5, 10, 12 } -}; -HPRef_Struct reftet_1f_1ea_0v = -{ - HP_TET, - reftet_1f_1ea_0v_splitedges, - reftet_1f_1ea_0v_splitfaces, - 0, - reftet_1f_1ea_0v_newelstypes, - reftet_1f_1ea_0v_newels -}; - - - - - - - - -// HP_TET_1F_1EB_0V singular edge in face, edge is 2-3 -int reftet_1f_1eb_0v_splitedges[][3] = -{ - { 2, 1, 5 }, - { 2, 4, 6 }, - { 3, 1, 7 }, - { 3, 4, 8 }, - { 4, 1, 9 }, - { 0, 0, 0 } -}; - - -HPREF_ELEMENT_TYPE reftet_1f_1eb_0v_newelstypes[] = -{ - HP_PRISM_1FB_1EA_0V, - HP_PRISM_1FA_0E_0V, - HP_TET, - HP_NONE, -}; -int reftet_1f_1eb_0v_newels[][8] = -{ - // { 2, 5, 6, 3, 7, 8 }, - { 3, 8, 7, 2, 6, 5 }, - { 6, 4, 8, 5, 9, 7 }, - { 5, 9, 7, 1} -}; -HPRef_Struct reftet_1f_1eb_0v = -{ - HP_TET, - reftet_1f_1eb_0v_splitedges, - 0, 0, - reftet_1f_1eb_0v_newelstypes, - reftet_1f_1eb_0v_newels -}; - - - - - - - - - - -/* ************************ 2 singular faces ******************** */ - - -// HP_TET_2F_0E_0V -int reftet_2f_0e_0v_splitedges[][3] = -{ - { 1, 2, 5 }, - { 2, 1, 6 }, - { 3, 1, 7 }, - { 3, 2, 8 }, - { 4, 1, 9 }, - { 4, 2, 10 }, - { 0, 0, 0 } -}; - -int reftet_2f_0e_0v_splitfaces[][4] = - { - { 3, 1, 2, 11 }, - { 4, 1, 2, 12 }, - { 0, 0, 0, 0 } - }; - - -HPREF_ELEMENT_TYPE reftet_2f_0e_0v_newelstypes[] = -{ - HP_PRISM_1FA_0E_0V, - HP_PRISM_1FA_0E_0V, - HP_PRISM_1FB_1EA_0V, - HP_PRISM_1FB_1EA_0V, - HP_TET, - HP_NONE, -}; -int reftet_2f_0e_0v_newels[][8] = -{ - { 2, 10, 8, 6, 12, 11 }, - { 1, 7, 9, 5, 11, 12 }, - // { 3, 11, 8, 4, 12, 10 }, - { 4, 10, 12, 3, 8, 11 }, - { 3, 7, 11, 4, 9, 12 }, - { 5, 6, 11, 12 } -}; -HPRef_Struct reftet_2f_0e_0v = -{ - HP_TET, - reftet_2f_0e_0v_splitedges, - reftet_2f_0e_0v_splitfaces, - 0, - reftet_2f_0e_0v_newelstypes, - reftet_2f_0e_0v_newels -}; - - diff --git a/Netgen/libsrc/meshing/hpref_trig.hpp b/Netgen/libsrc/meshing/hpref_trig.hpp deleted file mode 100644 index 6e2ede0eb0..0000000000 --- a/Netgen/libsrc/meshing/hpref_trig.hpp +++ /dev/null @@ -1,750 +0,0 @@ - - - - - -// HP_TRIG -int reftrig_splitedges[][3] = -{ - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_newelstypes[] = -{ - HP_TRIG, - HP_NONE, -}; -int reftrig_newels[][8] = -{ - { 1, 2, 3 }, -}; -HPRef_Struct reftrig = -{ - HP_TRIG, - reftrig_splitedges, - 0, 0, - reftrig_newelstypes, - reftrig_newels -}; - - - - - - -// HP_TRIG_SINGCORNER -int reftrig_singcorner_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singcorner_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_NONE, -}; -int reftrig_singcorner_newels[][8] = -{ - { 1, 4, 5 }, - { 2, 3, 5, 4 }, -}; -HPRef_Struct reftrig_singcorner = -{ - HP_TRIG, - reftrig_singcorner_splitedges, - 0, 0, - reftrig_singcorner_newelstypes, - reftrig_singcorner_newels -}; - - -/* -// HP_TRIG_SINGCORNER, trigs only -int reftrig_singcorner_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singcorner_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_TRIG, - HP_TRIG, - HP_NONE, -}; -int reftrig_singcorner_newels[][8] = -{ - { 1, 4, 5 }, - { 4, 2, 5 }, - { 5, 2, 3 }, -}; -HPRef_Struct reftrig_singcorner = -{ - HP_TRIG, - reftrig_singcorner_splitedges, - 0, 0, - reftrig_singcorner_newelstypes, - reftrig_singcorner_newels -}; -*/ - - - - - -// HP_TRIG_SINGCORNER12 -int reftrig_singcorner12_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singcorner12_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_TRIG, - HP_NONE, -}; -int reftrig_singcorner12_newels[][8] = -{ - { 1, 4, 5 }, - { 2, 7, 6 }, - { 4, 6, 7, 5 }, - { 5, 7, 3 }, -}; -HPRef_Struct reftrig_singcorner12 = -{ - HP_TRIG, - reftrig_singcorner12_splitedges, - 0, 0, - reftrig_singcorner12_newelstypes, - reftrig_singcorner12_newels -}; - - - - -// HP_TRIG_SINGCORNER123_2D -int reftrig_singcorner123_2D_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 3, 1, 8 }, - { 3, 2, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singcorner123_2D_newelstypes[] = -{ - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER, - HP_QUAD, - HP_QUAD, - HP_NONE, -}; -int reftrig_singcorner123_2D_newels[][8] = -{ - { 1, 4, 5 }, - { 2, 7, 6 }, - { 3, 8, 9 }, - { 4, 6, 8, 5 }, - { 6, 7, 9, 8 }, -}; -HPRef_Struct reftrig_singcorner123_2D = -{ - HP_TRIG, - reftrig_singcorner123_2D_splitedges, - 0, 0, - reftrig_singcorner123_2D_newelstypes, - reftrig_singcorner123_2D_newels -}; - - - - - - -// HP_TRIG_SINGCORNER123 -int reftrig_singcorner123_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 3, 1, 8 }, - { 3, 2, 9 }, - { 0, 0, 0 } -}; - -int reftrig_singcorner123_splitfaces[][4] = -{ - { 1, 2, 3, 10 }, - { 2, 3, 1, 11 }, - { 3, 1, 2, 12 }, - { 0, 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singcorner123_newelstypes[] = -{ - HP_DUMMY_QUAD_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - // HP_TRIG_SINGCORNER, - // HP_TRIG, - // HP_TRIG_SINGCORNER, - // HP_TRIG, - // HP_TRIG_SINGCORNER, - // HP_TRIG, - HP_QUAD, - HP_QUAD, - HP_QUAD, - HP_TRIG, - HP_NONE, -}; -int reftrig_singcorner123_newels[][8] = -{ - { 1, 4, 10, 5 }, - { 2, 7, 11, 6 }, - { 3, 8, 12, 9 }, - // { 1, 4, 5 }, - // { 5, 4, 10 }, - // { 2, 7, 6 }, - // { 6, 7, 11 }, - // { 3, 8, 9 }, - // { 8, 12, 9 }, - { 4, 6, 11, 10 }, - { 7, 9, 12, 11 }, - { 8, 5, 10, 12 }, - { 10, 11, 12 }, -}; -HPRef_Struct reftrig_singcorner123 = -{ - HP_TRIG, - reftrig_singcorner123_splitedges, - reftrig_singcorner123_splitfaces, - 0, - reftrig_singcorner123_newelstypes, - reftrig_singcorner123_newels -}; - - - - - - - - - - - - -// HP_TRIG_SINGEDGE -int reftrig_singedge_splitedges[][3] = -{ - { 2, 3, 4 }, - { 1, 3, 5 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedge_newelstypes[] = -{ - HP_TRIG, - HP_QUAD_SINGEDGE, - HP_NONE, -}; -int reftrig_singedge_newels[][8] = -{ - { 4, 3, 5 }, - { 1, 2, 4, 5 }, -}; -HPRef_Struct reftrig_singedge = -{ - HP_TRIG, - reftrig_singedge_splitedges, - 0, 0, - reftrig_singedge_newelstypes, - reftrig_singedge_newels -}; - - - - - - -// HP_TRIG_SINGEDGECORNER1 -int reftrig_singedgecorner1_splitedges[][3] = -{ - { 1, 2, 6 }, - { 1, 3, 5 }, - { 2, 3, 4 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner1_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedgecorner1_newels[][8] = -{ - { 1, 6, 5 }, - { 6, 2, 4, 5 }, - { 5, 4, 3 }, -}; -HPRef_Struct reftrig_singedgecorner1 = -{ - HP_TRIG, - reftrig_singedgecorner1_splitedges, - 0, 0, - reftrig_singedgecorner1_newelstypes, - reftrig_singedgecorner1_newels -}; - - - - - - - - -// HP_TRIG_SINGEDGECORNER2 -int reftrig_singedgecorner2_splitedges[][3] = -{ - { 2, 1, 6 }, - { 1, 3, 5 }, - { 2, 3, 4 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner2_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedgecorner2_newels[][8] = -{ - { 6, 2, 4}, - { 1, 6, 4, 5 }, - { 5, 4, 3 }, -}; -HPRef_Struct reftrig_singedgecorner2 = -{ - HP_TRIG, - reftrig_singedgecorner2_splitedges, - 0, 0, - reftrig_singedgecorner2_newelstypes, - reftrig_singedgecorner2_newels -}; - - - - -// HP_TRIG_SINGEDGECORNER12 -int reftrig_singedgecorner12_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner12_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedgecorner12_newels[][8] = -{ - { 1, 4, 5 }, - { 6, 2, 7 }, - { 4, 6, 7, 5 }, - { 5, 7, 3 }, -}; -HPRef_Struct reftrig_singedgecorner12 = -{ - HP_TRIG, - reftrig_singedgecorner12_splitedges, - 0, 0, - reftrig_singedgecorner12_newelstypes, - reftrig_singedgecorner12_newels -}; - - - - - - - -// HP_TRIG_SINGEDGECORNER3 -int reftrig_singedgecorner3_splitedges[][3] = -{ - { 1, 3, 4 }, - { 3, 1, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner3_newelstypes[] = -{ - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int reftrig_singedgecorner3_newels[][8] = -{ - { 1, 2, 6, 4 }, - { 4, 6, 7, 5 }, - { 3, 5, 7 }, -}; -HPRef_Struct reftrig_singedgecorner3 = -{ - HP_TRIG, - reftrig_singedgecorner3_splitedges, - 0, 0, - reftrig_singedgecorner3_newelstypes, - reftrig_singedgecorner3_newels -}; - - - - -// HP_TRIG_SINGEDGECORNER13 -int reftrig_singedgecorner13_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 3, 6 }, - { 3, 1, 7 }, - { 3, 2, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner13_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int reftrig_singedgecorner13_newels[][8] = -{ - { 1, 4, 5 }, - { 4, 2, 6, 5 }, - { 5, 6, 8, 7 }, - { 3, 7, 8 }, -}; -HPRef_Struct reftrig_singedgecorner13 = -{ - HP_TRIG, - reftrig_singedgecorner13_splitedges, - 0, 0, - reftrig_singedgecorner13_newelstypes, - reftrig_singedgecorner13_newels -}; - - - - - -// HP_TRIG_SINGEDGECORNER23 -int reftrig_singedgecorner23_splitedges[][3] = -{ - { 1, 3, 4 }, - { 2, 1, 5 }, - { 2, 3, 6 }, - { 3, 1, 7 }, - { 3, 2, 8 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner23_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int reftrig_singedgecorner23_newels[][8] = -{ - { 5, 2, 6 }, - { 1, 5, 6, 4 }, - { 4, 6, 8, 7 }, - { 3, 7, 8 }, -}; -HPRef_Struct reftrig_singedgecorner23 = -{ - HP_TRIG, - reftrig_singedgecorner23_splitedges, - 0, 0, - reftrig_singedgecorner23_newelstypes, - reftrig_singedgecorner23_newels -}; - - - -// HP_TRIG_SINGEDGECORNER123 -int reftrig_singedgecorner123_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 3, 1, 8 }, - { 3, 2, 9 }, - { 0, 0, 0 } -}; -HPREF_ELEMENT_TYPE reftrig_singedgecorner123_newelstypes[] = -{ - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD, - HP_TRIG_SINGCORNER, - HP_NONE, -}; -int reftrig_singedgecorner123_newels[][8] = -{ - { 1, 4, 5 }, - { 6, 2, 7 }, - { 4, 6, 7, 5 }, - { 5, 7, 9, 8 }, - { 3, 8, 9 }, -}; -HPRef_Struct reftrig_singedgecorner123 = -{ - HP_TRIG, - reftrig_singedgecorner123_splitedges, - 0, 0, - reftrig_singedgecorner123_newelstypes, - reftrig_singedgecorner123_newels -}; - - - - - - - - - - - - - -// HP_TRIG_SINGEDGES -int reftrig_singedges_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 3, 6 }, - { 3, 2, 7 }, - { 0, 0, 0 } -}; -int reftrig_singedges_splitfaces[][4] = -{ - { 1, 2, 3, 8 }, - { 0, 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftrig_singedges_newelstypes[] = -{ - // HP_QUAD_2E, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedges_newels[][8] = -{ - // { 1, 4, 8, 5 }, - { 1, 4, 8 }, - { 5, 1, 8 }, - { 4, 2, 6, 8 }, - { 3, 5, 8, 7 }, - { 6, 7, 8 }, -}; -HPRef_Struct reftrig_singedges = -{ - HP_TRIG, - reftrig_singedges_splitedges, - reftrig_singedges_splitfaces, - 0, - reftrig_singedges_newelstypes, - reftrig_singedges_newels -}; - - - - - - - - -// HP_TRIG_SINGEDGES2 -int reftrig_singedges2_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 3, 2, 8 }, - { 0, 0, 0 } -}; -int reftrig_singedges2_splitfaces[][4] = -{ - { 1, 2, 3, 9 }, - { 0, 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftrig_singedges2_newelstypes[] = -{ - // HP_QUAD_2E, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedges2_newels[][8] = -{ - // { 1, 4, 9, 5 }, - { 1, 4, 9 }, - { 5, 1, 9 }, - { 4, 6, 7, 9 }, - { 3, 5, 9, 8 }, - { 6, 2, 7 }, - { 7, 8, 9 }, -}; -HPRef_Struct reftrig_singedges2 = -{ - HP_TRIG, - reftrig_singedges2_splitedges, - reftrig_singedges2_splitfaces, - 0, - reftrig_singedges2_newelstypes, - reftrig_singedges2_newels -}; - - - - -// HP_TRIG_SINGEDGES3 -int reftrig_singedges3_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 3, 6 }, - { 3, 1, 7 }, - { 3, 2, 8 }, - { 0, 0, 0 } -}; -int reftrig_singedges3_splitfaces[][4] = -{ - { 1, 2, 3, 9 }, - { 0, 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftrig_singedges3_newelstypes[] = -{ - // HP_QUAD_2E, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedges3_newels[][8] = -{ - // { 1, 4, 9, 5 }, - { 1, 4, 9 }, - { 5, 1, 9 }, - { 4, 2, 6, 9 }, - { 7, 5, 9, 8 }, - { 3, 7, 8 }, - { 6, 8, 9 }, -}; -HPRef_Struct reftrig_singedges3 = -{ - HP_TRIG, - reftrig_singedges3_splitedges, - reftrig_singedges3_splitfaces, - 0, - reftrig_singedges3_newelstypes, - reftrig_singedges3_newels -}; - - - - - - -// HP_TRIG_SINGEDGES23 -int reftrig_singedges23_splitedges[][3] = -{ - { 1, 2, 4 }, - { 1, 3, 5 }, - { 2, 1, 6 }, - { 2, 3, 7 }, - { 3, 1, 8 }, - { 3, 2, 9 }, - { 0, 0, 0 } -}; -int reftrig_singedges23_splitfaces[][4] = -{ - { 1, 2, 3, 10 }, - { 0, 0, 0, 0 } -}; - -HPREF_ELEMENT_TYPE reftrig_singedges23_newelstypes[] = -{ - // HP_QUAD_2E, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - - HP_QUAD_SINGEDGE, - HP_QUAD_SINGEDGE, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG, - HP_NONE, -}; -int reftrig_singedges23_newels[][8] = -{ - // { 1, 4, 10, 5 }, - { 1 , 4, 10 }, - { 5, 1, 10 }, - { 4, 6, 7, 10 }, - { 8, 5, 10, 9 }, - { 6, 2, 7 }, - { 3, 8, 9 }, - { 7, 9, 10 }, -}; -HPRef_Struct reftrig_singedges23 = -{ - HP_TRIG, - reftrig_singedges23_splitedges, - reftrig_singedges23_splitfaces, - 0, - reftrig_singedges23_newelstypes, - reftrig_singedges23_newels -}; - - diff --git a/Netgen/libsrc/meshing/hprefinement.cpp b/Netgen/libsrc/meshing/hprefinement.cpp deleted file mode 100644 index 6a63e87675..0000000000 --- a/Netgen/libsrc/meshing/hprefinement.cpp +++ /dev/null @@ -1,2605 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - - - -namespace netgen -{ - - - // HP_SEGM - int refsegm_splitedges[][3] = - { - { 0, 0, 0 } - }; - - HPREF_ELEMENT_TYPE refsegm_newelstypes[] = - { - HP_SEGM, - HP_NONE, - }; - int refsegm_newels[][8] = - { - { 1, 2 }, - }; - HPRef_Struct refsegm = - { - HP_SEGM, - refsegm_splitedges, - 0, 0, - refsegm_newelstypes, - refsegm_newels - }; - - - // HP_SEGM_SINGCORNERL = 2, - int refsegm_scl_splitedges[][3] = - { - { 1, 2, 3 }, - { 0, 0, 0 } - }; - - HPREF_ELEMENT_TYPE refsegm_scl_newelstypes[] = - { - HP_SEGM_SINGCORNERL, - HP_SEGM, - HP_NONE, - }; - int refsegm_scl_newels[][8] = - { - { 1, 3 }, - { 3, 2 }, - { 0, 0 }, - }; - HPRef_Struct refsegm_scl = - { - HP_SEGM, - refsegm_scl_splitedges, - 0, 0, - refsegm_scl_newelstypes, - refsegm_scl_newels - }; - - - - // HP_SEGM_SINGCORNERR - int refsegm_scr_splitedges[][3] = - { - { 2, 1, 3 }, - { 0, 0, 0 } - }; - - HPREF_ELEMENT_TYPE refsegm_scr_newelstypes[] = - { - HP_SEGM, - HP_SEGM_SINGCORNERR, - HP_NONE, - }; - int refsegm_scr_newels[][8] = - { - { 1, 3 }, - { 3, 2 }, - { 0, 0 }, - }; - HPRef_Struct refsegm_scr = - { - HP_SEGM, - refsegm_scr_splitedges, - 0, 0, - refsegm_scr_newelstypes, - refsegm_scr_newels - }; - - - - - - - // HP_SEGM_SINGCORNERS = 3, - int refsegm_sc2_splitedges[][3] = - { - { 1, 2, 3 }, - { 2, 1, 4 }, - { 0, 0, 0 } - }; - - HPREF_ELEMENT_TYPE refsegm_sc2_newelstypes[] = - { - HP_SEGM_SINGCORNERL, - HP_SEGM_SINGCORNERR, - HP_SEGM, - HP_NONE, - }; - int refsegm_sc2_newels[][8] = - { - { 1, 3 }, - { 4, 2 }, - { 3, 4 }, - { 0, 0 }, - }; - HPRef_Struct refsegm_sc2 = - { - HP_SEGM, - refsegm_sc2_splitedges, - 0, 0, - refsegm_sc2_newelstypes, - refsegm_sc2_newels - }; - - - - - - -#include "hpref_trig.hpp" -#include "hpref_quad.hpp" -#include "hpref_tet.hpp" -#include "hpref_prism.hpp" - - - - - - // HP_PYRAMID - int refpyramid_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refpyramid_newelstypes[] = - { - HP_PYRAMID, - HP_NONE, - }; - int refpyramid_newels[][8] = - { - { 1, 2, 3, 4, 5, 6 } - }; - HPRef_Struct refpyramid = - { - HP_PYRAMID, - refpyramid_splitedges, - 0, 0, - refpyramid_newelstypes, - refpyramid_newels - }; - - - - // HP_PYRAMID_0E_1V - int refpyramid_0e_1v_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refpyramid_0e_1v_newelstypes[] = - { - HP_TET_0E_1V, - HP_TET, - HP_NONE, - }; - int refpyramid_0e_1v_newels[][8] = - { - { 1, 2, 4, 5 }, - { 2, 3, 4, 5 }, - }; - HPRef_Struct refpyramid_0e_1v = - { - HP_PYRAMID, - refpyramid_0e_1v_splitedges, - 0, 0, - refpyramid_0e_1v_newelstypes, - refpyramid_0e_1v_newels - }; - - - - // HP_PYRAMID_EDGES - int refpyramid_edges_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refpyramid_edges_newelstypes[] = - { - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_NONE, - }; - int refpyramid_edges_newels[][8] = - { - { 1, 2, 3, 5 }, - { 1, 4, 5, 3 }, - }; - HPRef_Struct refpyramid_edges = - { - HP_PYRAMID, - refpyramid_edges_splitedges, - 0, 0, - refpyramid_edges_newelstypes, - refpyramid_edges_newels - }; - - - - - // HP_PYRAMID_1FB_0E_1VA - int refpyramid_1fb_0e_1va_splitedges[][3] = - { - { 1, 4, 6 }, - { 2, 3, 7 }, - { 5, 1, 8 }, - { 5, 2, 9 }, - { 5, 3, 10 }, - { 5, 4, 11 }, - { 0, 0, 0 }, - }; - - HPREF_ELEMENT_TYPE refpyramid_1fb_0e_1va_newelstypes[] = - { - HP_HEX_1F_0E_0V, - HP_PYRAMID_1FB_0E_1VA, - HP_PRISM, - HP_NONE, - }; - int refpyramid_1fb_0e_1va_newels[][8] = - { - { 1, 8, 9, 2, 6, 11, 10, 7 }, - { 8, 9, 10, 11, 5 }, - { 3, 7, 10, 4, 6, 11 } - }; - HPRef_Struct refpyramid_1fb_0e_1va = - { - HP_PYRAMID, - refpyramid_1fb_0e_1va_splitedges, - 0, 0, - refpyramid_1fb_0e_1va_newelstypes, - refpyramid_1fb_0e_1va_newels - }; - - - - - - - - // HP_HEX - int refhex_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refhex_newelstypes[] = - { - HP_HEX, - HP_NONE, - }; - int refhex_newels[][8] = - { - { 1, 2, 3, 4, 5, 6, 7, 8 } - }; - HPRef_Struct refhex = - { - HP_HEX, - refhex_splitedges, - 0, 0, - refhex_newelstypes, - refhex_newels - }; - - - - - // HP_HEX_0E_1V - int refhex_0e_1v_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refhex_0e_1v_newelstypes[] = - { - HP_TET_0E_1V, - HP_TET, - HP_TET, - HP_TET, - HP_TET, - HP_TET, - HP_NONE, - }; - int refhex_0e_1v_newels[][8] = - { - { 1, 5, 2, 4 }, - { 7, 3, 6, 8 }, - { 2, 8, 5, 6 }, - { 2, 8, 6, 3 }, - { 2, 8, 3, 4 }, - { 2, 8, 4, 5 }, - }; - HPRef_Struct refhex_0e_1v = - { - HP_HEX, - refhex_0e_1v_splitedges, - 0, 0, - refhex_0e_1v_newelstypes, - refhex_0e_1v_newels - }; - - - - - // HP_HEX_1E_1V - int refhex_1e_1v_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refhex_1e_1v_newelstypes[] = - { - HP_TET_1E_1VA, - HP_TET, - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_TET_0E_1V, - HP_NONE, - }; - int refhex_1e_1v_newels[][8] = - { - // { 1, 5, 2, 4 }, - { 1, 2, 4, 5 }, - { 7, 3, 6, 8 }, - { 2, 8, 5, 6 }, - { 2, 8, 6, 3 }, - { 2, 8, 3, 4 }, - { 2, 8, 4, 5 }, - }; - HPRef_Struct refhex_1e_1v = - { - HP_HEX, - refhex_1e_1v_splitedges, - 0, 0, - refhex_1e_1v_newelstypes, - refhex_1e_1v_newels - }; - - - - // HP_HEX_3E_0V - int refhex_3e_0v_splitedges[][3] = - { - { 0, 0, 0 } - }; - HPREF_ELEMENT_TYPE refhex_3e_0v_newelstypes[] = - { - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_TET_1E_1VA, - HP_TET_0E_1V, - HP_TET, - HP_NONE, - }; - int refhex_3e_0v_newels[][8] = - { - { 1, 2, 3, 6 }, - { 1, 4, 8, 3 }, - { 1, 5, 6, 8 }, - { 1, 6, 3, 8 }, - { 3, 8, 6, 7 }, - }; - HPRef_Struct refhex_3e_0v = - { - HP_HEX, - refhex_3e_0v_splitedges, - 0, 0, - refhex_3e_0v_newelstypes, - refhex_3e_0v_newels - }; - - - - - // HP_HEX_1E_0V - int refhex_1e_0v_splitedges[][3] = - { - { 0, 0, 0 } - }; - - HPREF_ELEMENT_TYPE refhex_1e_0v_newelstypes[] = - { - HP_PRISM_SINGEDGE, - HP_PRISM, - HP_NONE, - }; - int refhex_1e_0v_newels[][8] = - { - { 1, 4, 5, 2, 3, 6 }, - { 5, 4, 8, 6, 3, 7 }, - }; - HPRef_Struct refhex_1e_0v = - { - HP_HEX, - refhex_1e_0v_splitedges, - 0, 0, - refhex_1e_0v_newelstypes, - refhex_1e_0v_newels - }; - - - - - - // HP_HEX_1F_0E_0V - int refhex_1f_0e_0v_splitedges[][3] = - { - { 1, 5, 9 }, - { 2, 6, 10 }, - { 3, 7, 11 }, - { 4, 8, 12 }, - { 0, 0, 0 } - }; - - HPREF_ELEMENT_TYPE refhex_1f_0e_0v_newelstypes[] = - { - HP_HEX_1F_0E_0V, - HP_HEX, - HP_NONE, - }; - int refhex_1f_0e_0v_newels[][8] = - { - { 1, 2, 3, 4, 9, 10, 11, 12 }, - { 9, 10, 11, 12, 5, 6, 7, 8 } - }; - HPRef_Struct refhex_1f_0e_0v = - { - HP_HEX, - refhex_1f_0e_0v_splitedges, - 0, 0, - refhex_1f_0e_0v_newelstypes, - refhex_1f_0e_0v_newels - }; - - - - - - - - HPRef_Struct * Get_HPRef_Struct (HPREF_ELEMENT_TYPE type) - { - HPRef_Struct * hps = NULL; - - switch (type) - { - case HP_SEGM: - hps = &refsegm; break; - case HP_SEGM_SINGCORNERL: - hps = &refsegm_scl; break; - case HP_SEGM_SINGCORNERR: - hps = &refsegm_scr; break; - case HP_SEGM_SINGCORNERS: - hps = &refsegm_sc2; break; - - case HP_TRIG: - hps = &reftrig; break; - case HP_TRIG_SINGCORNER: - hps = &reftrig_singcorner; break; - case HP_TRIG_SINGCORNER12: - hps = &reftrig_singcorner12; break; - case HP_TRIG_SINGCORNER123: - hps = &reftrig_singcorner123; break; - case HP_TRIG_SINGCORNER123_2D: - hps = &reftrig_singcorner123_2D; break; - case HP_TRIG_SINGEDGE: - hps = &reftrig_singedge; break; - case HP_TRIG_SINGEDGECORNER1: - hps = &reftrig_singedgecorner1; break; - case HP_TRIG_SINGEDGECORNER2: - hps = &reftrig_singedgecorner2; break; - case HP_TRIG_SINGEDGECORNER12: - hps = &reftrig_singedgecorner12; break; - case HP_TRIG_SINGEDGECORNER3: - hps = &reftrig_singedgecorner3; break; - case HP_TRIG_SINGEDGECORNER13: - hps = &reftrig_singedgecorner13; break; - case HP_TRIG_SINGEDGECORNER23: - hps = &reftrig_singedgecorner23; break; - case HP_TRIG_SINGEDGECORNER123: - hps = &reftrig_singedgecorner123; break; - case HP_TRIG_SINGEDGES: - hps = &reftrig_singedges; break; - case HP_TRIG_SINGEDGES2: - hps = &reftrig_singedges2; break; - case HP_TRIG_SINGEDGES3: - hps = &reftrig_singedges3; break; - case HP_TRIG_SINGEDGES23: - hps = &reftrig_singedges23; break; - case HP_QUAD: - hps = &refquad; break; - case HP_DUMMY_QUAD_SINGCORNER: - hps = &refdummyquad_singcorner; break; - case HP_QUAD_SINGCORNER: - hps = &refquad_singcorner; break; - case HP_QUAD_SINGEDGE: - hps = &refquad_singedge; break; - - case HP_QUAD_0E_2VA: - hps = &refquad_0e_2va; break; - case HP_QUAD_0E_2VB: - hps = &refquad_0e_2vb; break; - - case HP_QUAD_0E_3V: - hps = &refquad_0e_3v; break; - case HP_QUAD_0E_4V: - hps = &refquad_0e_4v; break; - - case HP_QUAD_1E_1VA: - hps = &refquad_1e_1va; break; - case HP_QUAD_1E_1VB: - hps = &refquad_1e_1vb; break; - case HP_QUAD_1E_1VC: - hps = &refquad_1e_1vc; break; - case HP_QUAD_1E_1VD: - hps = &refquad_1e_1vd; break; - - case HP_QUAD_1E_2VA: - hps = &refquad_1e_2va; break; - case HP_QUAD_1E_2VB: - hps = &refquad_1e_2vb; break; - case HP_QUAD_1E_2VC: - hps = &refquad_1e_2vc; break; - case HP_QUAD_1E_2VD: - hps = &refquad_1e_2vd; break; - case HP_QUAD_1E_2VE: - hps = &refquad_1e_2ve; break; - case HP_QUAD_1E_2VF: - hps = &refquad_1e_2vf; break; - - case HP_QUAD_1E_3VA: - hps = &refquad_1e_3va; break; - case HP_QUAD_1E_3VB: - hps = &refquad_1e_3vb; break; - case HP_QUAD_1E_3VC: - hps = &refquad_1e_3vc; break; - case HP_QUAD_1E_3VD: - hps = &refquad_1e_3vd; break; - case HP_QUAD_1E_4V: - hps = &refquad_1e_4v; break; - - - case HP_QUAD_2E: - hps = &refquad_2e; break; - case HP_QUAD_2E_1VA: - hps = &refquad_2e_1va; break; - case HP_QUAD_2E_1VB: - hps = &refquad_2e_1vb; break; - case HP_QUAD_2E_1VC: - hps = &refquad_2e_1vc; break; - case HP_QUAD_2E_2VA: - hps = &refquad_2e_2va; break; - case HP_QUAD_2E_2VB: - hps = &refquad_2e_2vb; break; - case HP_QUAD_2E_2VC: - hps = &refquad_2e_2vc; break; - case HP_QUAD_2E_3V: - hps = &refquad_2e_3v; break; - - case HP_QUAD_2EB_0V: - hps = &refquad_2eb_0v; break; - - case HP_QUAD_2EB_1VA: - hps = &refquad_2eb_1va; break; - case HP_QUAD_2EB_1VB: - hps = &refquad_2eb_1vb; break; - - - case HP_QUAD_2EB_2VA: - hps = &refquad_2eb_2va; break; - case HP_QUAD_2EB_2VB: - hps = &refquad_2eb_2vb; break; - case HP_QUAD_2EB_2VC: - hps = &refquad_2eb_2vc; break; - case HP_QUAD_2EB_2VD: - hps = &refquad_2eb_2vd; break; - - case HP_QUAD_2EB_3VA: - hps = &refquad_2eb_3va; break; - case HP_QUAD_2EB_3VB: - hps = &refquad_2eb_3vb; break; - - case HP_QUAD_2EB_4V: - hps = &refquad_2eb_4v; break; - - case HP_QUAD_3E: - hps = &refquad_3e; break; - case HP_QUAD_3E_3VA: - hps = &refquad_3e_3va; break; - case HP_QUAD_3E_3VB: - hps = &refquad_3e_3vb; break; - case HP_QUAD_3E_4V: - hps = &refquad_3e_4v; break; - - - case HP_QUAD_4E: - hps = &refquad_4e; break; - - - case HP_TET: - hps = &reftet; break; - case HP_TET_0E_1V: - hps = &reftet_0e_1v; break; - case HP_TET_0E_2V: - hps = &reftet_0e_2v; break; - case HP_TET_0E_3V: - hps = &reftet_0e_3v; break; - case HP_TET_0E_4V: - hps = &reftet_0e_4v; break; - - case HP_TET_1E_0V: - hps = &reftet_1e_0v; break; - case HP_TET_1E_1VA: - hps = &reftet_1e_1va; break; - case HP_TET_1E_1VB: - hps = &reftet_1e_1vb; break; - - case HP_TET_1E_2VA: - hps = &reftet_1e_2va; break; - case HP_TET_1E_2VB: - hps = &reftet_1e_2vb; break; - case HP_TET_1E_2VC: - hps = &reftet_1e_2vc; break; - case HP_TET_1E_2VD: - hps = &reftet_1e_2vd; break; - - case HP_TET_1E_3VA: - hps = &reftet_1e_3va; break; - case HP_TET_1E_3VB: - hps = &reftet_1e_3vb; break; - case HP_TET_1E_4V: - hps = &reftet_1e_4v; break; - - case HP_TET_2EA_0V: - hps = &reftet_2ea_0v; break; - case HP_TET_2EA_1VB: - hps = &reftet_2ea_1vb; break; - case HP_TET_2EA_1VC: - hps = &reftet_2ea_1vc; break; - case HP_TET_2EA_1VA: - hps = &reftet_2ea_1va; break; - case HP_TET_2EA_2VA: - hps = &reftet_2ea_2va; break; - case HP_TET_2EA_2VB: - hps = &reftet_2ea_2vb; break; - case HP_TET_2EA_2VC: - hps = &reftet_2ea_2vc; break; - case HP_TET_2EA_3V: - hps = &reftet_2ea_3v; break; - - case HP_TET_2EB_0V: - hps = &reftet_2eb_0v; break; - case HP_TET_2EB_2VA: - hps = &reftet_2eb_2va; break; - case HP_TET_2EB_4V: - hps = &reftet_2eb_4v; break; - - - case HP_TET_3EA_0V: - hps = &reftet_3ea_0v; break; - case HP_TET_3EA_1V: - hps = &reftet_3ea_1v; break; - case HP_TET_3EA_2V: - hps = &reftet_3ea_2v; break; - case HP_TET_3EA_3V: - hps = &reftet_3ea_3v; break; - - case HP_TET_3EB_0V: - hps = &reftet_3eb_0v; break; - case HP_TET_3EB_1V: - hps = &reftet_3eb_1v; break; - case HP_TET_3EB_2V: - hps = &reftet_3eb_2v; break; - case HP_TET_3EC_0V: - hps = &reftet_3ec_0v; break; - case HP_TET_3EC_1V: - hps = &reftet_3ec_1v; break; - case HP_TET_3EC_2V: - hps = &reftet_3ec_2v; break; - - - case HP_TET_1F_0E_0V: - hps = &reftet_1f_0e_0v; break; - case HP_TET_1F_0E_1VA: - hps = &reftet_1f_0e_1va; break; - case HP_TET_1F_0E_1VB: - hps = &reftet_1f_0e_1vb; break; - case HP_TET_1F_1EA_0V: - hps = &reftet_1f_1ea_0v; break; - case HP_TET_1F_1EB_0V: - hps = &reftet_1f_1eb_0v; break; - case HP_TET_2F_0E_0V: - hps = &reftet_2f_0e_0v; break; - - - case HP_PRISM: - hps = &refprism; break; - case HP_PRISM_SINGEDGE: - hps = &refprism_singedge; break; - case HP_PRISM_SINGEDGE_H1: - hps = &refprism_singedge_h1; break; - case HP_PRISM_SINGEDGE_H12: - hps = &refprism_singedge_h12; break; - case HP_PRISM_SINGEDGE_V12: - hps = &refprism_singedge_v12; break; - - case HP_PRISM_1FA_0E_0V: - hps = &refprism_1fa_0e_0v; break; - case HP_PRISM_1FB_0E_0V: - hps = &refprism_1fb_0e_0v; break; - case HP_PRISM_1FB_1EA_0V: - hps = &refprism_1fb_1ea_0v; break; - - case HP_PYRAMID: - hps = &refpyramid; break; - case HP_PYRAMID_0E_1V: - hps = &refpyramid_0e_1v; break; - case HP_PYRAMID_EDGES: - hps = &refpyramid_edges; break; - case HP_PYRAMID_1FB_0E_1VA: - hps = &refpyramid_1fb_0e_1va; break; - case HP_HEX: - hps = &refhex; break; - case HP_HEX_0E_1V: - hps = &refhex_0e_1v; break; - case HP_HEX_1E_1V: - hps = &refhex_1e_1v; break; - case HP_HEX_1E_0V: - hps = &refhex_1e_0v; break; - case HP_HEX_3E_0V: - hps = &refhex_3e_0v; break; - - case HP_HEX_1F_0E_0V: - hps = &refhex_1f_0e_0v; break; - } - - if (!hps) - { - PrintSysError ("hp-refinement not implemented for case ", type); - } - - return hps; - } - - - /* *********************** PrepareElements ****************************** */ - - // Elements (volume, surface, edges) are classified by singular vertices, edges, faces - - - void PrepareElements (Mesh & mesh, ARRAY<HPRefElement> & elements) - { - INDEX_2_HASHTABLE<int> edges(mesh.GetNSeg()+1); - BitArray edgepoint(mesh.GetNP()); - INDEX_2_HASHTABLE<int> edgepoint_dom(mesh.GetNSeg()+1); - - edgepoint.Clear(); - BitArray cornerpoint(mesh.GetNP()); - cornerpoint.Clear(); - - - // value = nr > 0 ... refine elements in domain nr - // value = -1 ..... refine elements in any domain - INDEX_3_HASHTABLE<int> faces(mesh.GetNSE()+1); - INDEX_2_HASHTABLE<int> face_edges(mesh.GetNSE()+1); - ARRAY<int, PointIndex::BASE> facepoint(mesh.GetNP()); - - if (mesh.GetDimension() == 3) - { - /* - // check, if point has as least 3 different surfs: - - ARRAY<INDEX_3, PointIndex::BASE> surfonpoint(mesh.GetNP()); - surfonpoint = INDEX_3(0,0,0); - - for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) - { - const Element2d & el = mesh[sei]; - int ind = el.GetIndex(); - for (int j = 0; j < el.GetNP(); j++) - { - INDEX_3 & i3 = surfonpoint[el[j]]; - if (ind != i3.I1() && ind != i3.I2() && ind != i3.I3()) - { - i3.I1() = i3.I2(); - i3.I2() = i3.I3(); - i3.I3() = ind; - } - } - } - for (int i = 1; i <= mesh.GetNP(); i++) - if (surfonpoint.Get(i).I1()) - cornerpoint.Set(i); - */ - cornerpoint.Clear(); - - for (int i = 1; i <= mesh.GetNP(); i++) - { - if (mesh.Point(i).IsSingular()) - cornerpoint.Set(i); - } - - - for (int i = 1; i <= mesh.GetNSeg(); i++) - if (mesh.LineSegment(i).singedge_left) - { - INDEX_2 i2 (mesh.LineSegment(i).p1, - mesh.LineSegment(i).p2); - i2.Sort(); - - edges.Set (i2, 1); - INDEX_2 i2s(i2.I2(), i2.I1()); - edges.Set (i2s, 1); - - edgepoint.Set (i2.I1()); - edgepoint.Set (i2.I2()); - } - - - // if 2 adjacent edges of an element are singular, the - // commen point must be a singular point - for (int i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement(i); - const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (el.GetType()); - int nedges = MeshTopology::GetNEdges (el.GetType()); - for (int j = 0; j < nedges; j++) - for (int k = 0; k < nedges; k++) - if (j != k) - { - INDEX_2 ej(el.PNum(eledges[j][0]), el.PNum(eledges[j][1])); - ej.Sort(); - INDEX_2 ek(el.PNum(eledges[k][0]), el.PNum(eledges[k][1])); - ek.Sort(); - if (edges.Used(ej) && edges.Used(ek)) - { - if (ej.I1() == ek.I1()) cornerpoint.Set (ek.I1()); - if (ej.I1() == ek.I2()) cornerpoint.Set (ek.I2()); - if (ej.I2() == ek.I1()) cornerpoint.Set (ek.I1()); - if (ej.I2() == ek.I2()) cornerpoint.Set (ek.I2()); - } - } - } - - - edgepoint.Or (cornerpoint); - - (*testout) << "cornerpoint = " << endl << cornerpoint << endl; - (*testout) << "edgepoint = " << endl << edgepoint << endl; - - facepoint = 0; - for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) - { - const Element2d & el = mesh[sei]; - const FaceDescriptor & fd = mesh.GetFaceDescriptor (el.GetIndex()); - - if (!fd.domin_singular && !fd.domout_singular) continue; - int domnr; - if (fd.domin_singular) domnr = fd.DomainIn(); - if (fd.domout_singular) domnr = fd.DomainOut(); - if (fd.domin_singular && fd.domout_singular) domnr = -1; - - - faces.Set (INDEX_3::Sort (el[0], el[1], el[2]), domnr); - face_edges.Set (INDEX_2::Sort (el[0], el[1]), domnr); - face_edges.Set (INDEX_2::Sort (el[0], el[2]), domnr); - face_edges.Set (INDEX_2::Sort (el[2], el[1]), domnr); - facepoint[el[0]] = domnr; - facepoint[el[1]] = domnr; - facepoint[el[2]] = domnr; - } - - } - else - { - // 2D case - - // check, if point has as least 3 different surfs: - ARRAY<INDEX_3, PointIndex::BASE> surfonpoint(mesh.GetNP()); - - for (int i = 1; i <= mesh.GetNP(); i++) - surfonpoint.Elem(i) = INDEX_3(0,0,0); - - for (int i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - int ind = seg.edgenr; - - if (seg.singedge_left) - { - INDEX_2 i2 (mesh.LineSegment(i).p1, - mesh.LineSegment(i).p2); - edges.Set (i2, 1); - edgepoint.Set(i2.I1()); - edgepoint.Set(i2.I2()); - - edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I1()), 1); - edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I2()), 1); - } - if (seg.singedge_right) - { - INDEX_2 i2 (mesh.LineSegment(i).p2, - mesh.LineSegment(i).p1); - edges.Set (i2, 1); - edgepoint.Set(i2.I1()); - edgepoint.Set(i2.I2()); - - edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I1()), 1); - edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I2()), 1); - } - // (*testout) << "seg = " << ind << ", " << seg.p1 << "-" << seg.p2 << endl; - - - if (seg.singedge_left || seg.singedge_right) - { - for (int j = 0; j < 2; j++) - { - int pi = (j == 0) ? seg.p1 : seg.p2; - INDEX_3 & i3 = surfonpoint.Elem(pi); - if (ind != i3.I1() && - ind != i3.I2()) - { - i3.I1() = i3.I2(); - i3.I2() = ind; - } - } - } - } - - - for (int i = 1; i <= mesh.GetNP(); i++) - { - // mark points for refinement that are in corners between two anisotropic edges - if (surfonpoint.Get(i).I1()) - { - cornerpoint.Set(i); - edgepoint.Set(i); - } - - // mark points for refinement that are explicity specified in input file - if (mesh.Point(i).IsSingular()) - { - cornerpoint.Set(i); - edgepoint.Set(i); - } - } - - edgepoint.Or (cornerpoint); - - (*testout) << "cornerpoints: " << endl << cornerpoint << endl - << "edgepoints: " << endl << edgepoint << endl; - } - - - - - int cnt_undef = 0, cnt_nonimplement = 0; - ARRAY<int> misses(10000); - misses = 0; - - for (ElementIndex i = 0; i < mesh.GetNE(); i++) - { - Element & el = mesh[i]; - - HPREF_ELEMENT_TYPE type = HP_NONE; - int pnums[8] = { 0 }; - - - switch (el.GetType()) - { - case TET: - { - int ep1, ep2, ep3, ep4, cp1, cp2, cp3, cp4, fp1, fp2, fp3, fp4; - int isedge1, isedge2, isedge3, isedge4, isedge5, isedge6; - int isfedge1, isfedge2, isfedge3, isfedge4, isfedge5, isfedge6; - int isface1, isface2, isface3, isface4; - - for (int j = 0; j < 4; j++) - for (int k = 0; k < 4; k++) - { - if (j == k) continue; - if (type) break; - - int pi3 = 0; - while (pi3 == j || pi3 == k) pi3++; - int pi4 = 6 - j - k - pi3; - - // preserve orientation - int sort[4]; - sort[0] = j; sort[1] = k; sort[2] = pi3; sort[3] = pi4; - int cnt = 0; - for (int jj = 0; jj < 4; jj++) - for (int kk = 0; kk < 3; kk++) - if (sort[kk] > sort[kk+1]) - { - cnt++; - Swap (sort[kk], sort[kk+1]); - } - if (cnt % 2 == 1) Swap (pi3, pi4); - - ep1 = edgepoint.Test (el[j]); - ep2 = edgepoint.Test (el[k]); - ep3 = edgepoint.Test (el[pi3]); - ep4 = edgepoint.Test (el[pi4]); - - cp1 = cornerpoint.Test (el[j]); - cp2 = cornerpoint.Test (el[k]); - cp3 = cornerpoint.Test (el[pi3]); - cp4 = cornerpoint.Test (el[pi4]); - - isedge1 = edges.Used (INDEX_2::Sort (el[j], el[k])); - isedge2 = edges.Used (INDEX_2::Sort (el[j], el[pi3])); - isedge3 = edges.Used (INDEX_2::Sort (el[j], el[pi4])); - isedge4 = edges.Used (INDEX_2::Sort (el[k], el[pi3])); - isedge5 = edges.Used (INDEX_2::Sort (el[k], el[pi4])); - isedge6 = edges.Used (INDEX_2::Sort (el[pi3], el[pi4])); - - isface1 = isface2 = isface3 = isface4 = 0; - for (int l = 0; l < 4; l++) - { - INDEX_3 i3; - switch (l) - { - case 0: i3 = INDEX_3 (el[k], el[pi3], el[pi4]); break; - case 1: i3 = INDEX_3 (el[j], el[pi3], el[pi4]); break; - case 2: i3 = INDEX_3 (el[j], el[k], el[pi4]); break; - case 3: i3 = INDEX_3 (el[j], el[k], el[pi3]); break; - } - i3.Sort(); - if (faces.Used (i3)) - { - int domnr = faces.Get(i3); - if (domnr == -1 || domnr == el.GetIndex()) - { - switch (l) - { - case 0: isface1 = 1; break; - case 1: isface2 = 1; break; - case 2: isface3 = 1; break; - case 3: isface4 = 1; break; - } - } - } - } - /* - isface1 = faces.Used (INDEX_3::Sort (el[k], el[pi3], el[pi4])); - isface2 = faces.Used (INDEX_3::Sort (el[j], el[pi3], el[pi4])); - isface3 = faces.Used (INDEX_3::Sort (el[j], el[k], el[pi4])); - isface4 = faces.Used (INDEX_3::Sort (el[j], el[k], el[pi3])); - */ - - isfedge1 = isfedge2 = isfedge3 = isfedge4 = isfedge5 = isfedge6 = 0; - for (int l = 0; l < 6; l++) - { - INDEX_2 i2; - switch (l) - { - case 0: i2 = INDEX_2 (el[j], el[k]); break; - case 1: i2 = INDEX_2 (el[j], el[pi3]); break; - case 2: i2 = INDEX_2 (el[j], el[pi4]); break; - case 3: i2 = INDEX_2 (el[k], el[pi3]); break; - case 4: i2 = INDEX_2 (el[k], el[pi4]); break; - case 5: i2 = INDEX_2 (el[pi3], el[pi4]); break; - } - i2.Sort(); - if (face_edges.Used (i2)) - { - int domnr = face_edges.Get(i2); - if (domnr == -1 || domnr == el.GetIndex()) - { - switch (l) - { - case 0: isfedge1 = 1; break; - case 1: isfedge2 = 1; break; - case 2: isfedge3 = 1; break; - case 3: isfedge4 = 1; break; - case 4: isfedge5 = 1; break; - case 5: isfedge6 = 1; break; - } - } - } - } - /* - isfedge1 = face_edges.Used (INDEX_2::Sort (el[j], el[k])); - isfedge2 = face_edges.Used (INDEX_2::Sort (el[j], el[pi3])); - isfedge3 = face_edges.Used (INDEX_2::Sort (el[j], el[pi4])); - isfedge4 = face_edges.Used (INDEX_2::Sort (el[k], el[pi3])); - isfedge5 = face_edges.Used (INDEX_2::Sort (el[k], el[pi4])); - isfedge6 = face_edges.Used (INDEX_2::Sort (el[pi3], el[pi4])); - */ - - fp1 = fp2 = fp3 = fp4 = 0; - for (int l = 0; l < 4; l++) - { - int pi; - switch (l) - { - case 0: pi = el[j]; break; - case 1: pi = el[k]; break; - case 2: pi = el[pi3]; break; - case 3: pi = el[pi4]; break; - } - int domnr = facepoint[pi]; - if (domnr == -1 || domnr == el.GetIndex()) - { - switch (l) - { - case 0: fp1 = 1; break; - case 1: fp2 = 1; break; - case 2: fp3 = 1; break; - case 3: fp4 = 1; break; - } - } - } - - /* - fp1 = facepoint[el[j]] != 0; - fp2 = facepoint[el[k]] != 0; - fp3 = facepoint[el[pi3]] != 0; - fp4 = facepoint[el[pi4]] != 0; - */ - - - switch (isface1+isface2+isface3+isface4) - { - case 0: - { - isedge1 |= isfedge1; - isedge2 |= isfedge2; - isedge3 |= isfedge3; - isedge4 |= isfedge4; - isedge5 |= isfedge5; - isedge6 |= isfedge6; - - ep1 |= fp1; - ep2 |= fp2; - ep3 |= fp3; - ep4 |= fp4; - - switch (isedge1+isedge2+isedge3+isedge4+isedge5+isedge6) - { - case 0: - { - if (!ep1 && !ep2 && !ep3 && !ep4) - type = HP_TET; - - if (ep1 && !ep2 && !ep3 && !ep4) - type = HP_TET_0E_1V; - - if (ep1 && ep2 && !ep3 && !ep4) - type = HP_TET_0E_2V; - - if (ep1 && ep2 && ep3 && !ep4) - type = HP_TET_0E_3V; - - if (ep1 && ep2 && ep3 && ep4) - type = HP_TET_0E_4V; - - break; - } - - case 1: - { - if (!isedge1) break; - - if (!cp1 && !cp2 && !ep3 && !ep4) - type = HP_TET_1E_0V; - - if (cp1 && !cp2 && !ep3 && !ep4) - type = HP_TET_1E_1VA; - - if (!cp1 && !cp2 && !ep3 && ep4) - type = HP_TET_1E_1VB; - - if (cp1 && cp2 && !ep3 && !ep4) - type = HP_TET_1E_2VA; - - if (cp1 && !cp2 && ep3 && !ep4) - type = HP_TET_1E_2VB; - - if (cp1 && !cp2 && !ep3 && ep4) - type = HP_TET_1E_2VC; - - if (!cp1 && !cp2 && ep3 && ep4) - type = HP_TET_1E_2VD; - - if (cp1 && cp2 && ep3 && !ep4) - type = HP_TET_1E_3VA; - - if (cp1 && !cp2 && ep3 && ep4) - type = HP_TET_1E_3VB; - - if (cp1 && cp2 && ep3 && ep4) - type = HP_TET_1E_4V; - - break; - } - case 2: - { - if (isedge1 && isedge2) - { - if (!cp2 && !cp3 && !ep4) - type = HP_TET_2EA_0V; - - if (cp2 && !cp3 && !ep4) - type = HP_TET_2EA_1VA; - if (!cp2 && cp3 && !ep4) - type = HP_TET_2EA_1VB; - - if (!cp2 && !cp3 && ep4) - type = HP_TET_2EA_1VC; - - if (cp2 && cp3 && !ep4) - type = HP_TET_2EA_2VA; - if (cp2 && !cp3 && ep4) - type = HP_TET_2EA_2VB; - if (!cp2 && cp3 && ep4) - type = HP_TET_2EA_2VC; - - if (cp2 && cp3 && ep4) - type = HP_TET_2EA_3V; - } - if (isedge1 && isedge6) - { - if (!cp1 && !cp2 && !cp3 && !cp4) - type = HP_TET_2EB_0V; - if (cp1 && !cp2 && !cp3 && !cp4) - type = HP_TET_2EB_1V; - if (cp1 && cp2 && !cp3 && !cp4) - type = HP_TET_2EB_2VA; - if (cp1 && !cp2 && cp3 && !cp4) - type = HP_TET_2EB_2VB; - if (cp1 && !cp2 && !cp3 && cp4) - type = HP_TET_2EB_2VC; - if (cp1 && cp2 && cp3 && !cp4) - type = HP_TET_2EB_3V; - if (cp1 && cp2 && cp3 && cp4) - type = HP_TET_2EB_4V; - } - } - case 3: - { - if (isedge1 && isedge2 && isedge3) - { - if (!cp2 && !cp3 && !cp4) - type = HP_TET_3EA_0V; - if (cp2 && !cp3 && !cp4) - type = HP_TET_3EA_1V; - if (cp2 && cp3 && !cp4) - type = HP_TET_3EA_2V; - if (cp2 && cp3 && cp4) - type = HP_TET_3EA_3V; - } - if (isedge1 && isedge3 && isedge4) - { - if (!cp3 && !cp4) - type = HP_TET_3EB_0V; - if (cp3 && !cp4) - type = HP_TET_3EB_1V; - if (cp3 && cp4) - type = HP_TET_3EB_2V; - } - if (isedge1 && isedge2 && isedge5) - { - if (!cp3 && !cp4) - type = HP_TET_3EC_0V; - if (cp3 && !cp4) - type = HP_TET_3EC_1V; - if (cp3 && cp4) - type = HP_TET_3EC_2V; - } - break; - } - } - break; - } - - - - case 1: // one singular face - { - if (!isface1) break; - - switch (isfedge1+isfedge2+isfedge3+isedge4+isedge5+isedge6) - { - case 0: - { - if (!fp1 && !ep2 && !ep3 && !ep4) - type = HP_TET_1F_0E_0V; - if (fp1 && !ep2 && !ep3 && !ep4) - type = HP_TET_1F_0E_1VB; - if (!fp1 && ep2 && !ep3 & !ep4) - type = HP_TET_1F_0E_1VA; - break; - } - case 1: - { - if (isfedge1) - { - if (!ep1 && !ep3 && !ep4) - type = HP_TET_1F_1EA_0V; - } - if (isedge4) // V1-V3 - { - if (!ep1 && !cp2 && !cp3 && !ep4) - type = HP_TET_1F_1EB_0V; - } - break; - } - } - break; - } - - - case 2: // one singular face - { - if (!isface1 || !isface2) break; - - switch (isfedge1+isedge2+isedge3+isedge4+isedge5) - { - case 0: - { - if (!ep1 && !ep2 && !cp3 && !cp4) - type = HP_TET_2F_0E_0V; - break; - } - } - break; - } - - - } - - if (type != HP_NONE) - { - pnums[0] = el[j]; - pnums[1] = el[k]; - pnums[2] = el[pi3]; - pnums[3] = el[pi4]; - break; - } - } - - /* - if (type != HP_TET_2EB_2VA) - type = HP_NONE; - */ - - if (type == HP_NONE) - { - cnt_undef++; - (*testout) << "undefined element" << endl - << "cp = " << cp1 << cp2 << cp3 << cp4 << endl - << "ep = " << ep1 << ep2 << ep3 << ep4 << endl - << "isedge = " << isedge1 << isedge2 << isedge3 - << isedge4 << isedge5 << isedge6 << endl; - cout << "undefined element !!! " << endl; - } - - break; - } - - case PRISM: - { - int pi1, pi2, pi3, pi4, pi5, pi6; - int ep1, ep2, ep3, ep4, ep5, ep6, cp1, cp2, cp3, cp4, cp5, cp6; - - int ishedge1, ishedge2, ishedge3, ishedge4, ishedge5, ishedge6; - int isvedge1, isvedge2, isvedge3; - - for (int j = 1; j <= 3; j++) - { - if (type) break; - - pi1 = j; - pi2 = pi1%3 + 1; - pi3 = pi2%3 + 1; - pi4 = pi1+3; - pi5 = pi2+3; - pi6 = pi3+3; - - ep1 = edgepoint.Test (el.PNum (pi1)); - ep2 = edgepoint.Test (el.PNum (pi2)); - ep3 = edgepoint.Test (el.PNum (pi3)); - ep4 = edgepoint.Test (el.PNum (pi4)); - ep5 = edgepoint.Test (el.PNum (pi5)); - ep6 = edgepoint.Test (el.PNum (pi6)); - - cp1 = cornerpoint.Test (el.PNum (pi1)); - cp2 = cornerpoint.Test (el.PNum (pi2)); - cp3 = cornerpoint.Test (el.PNum (pi3)); - cp4 = cornerpoint.Test (el.PNum (pi4)); - cp5 = cornerpoint.Test (el.PNum (pi5)); - cp6 = cornerpoint.Test (el.PNum (pi6)); - - INDEX_2 i2 = INDEX_2::Sort(el.PNum (pi1), el.PNum (pi4)); - isvedge1 = edges.Used (i2) || ep1 || ep4; - - i2 = INDEX_2::Sort(el.PNum (pi2), el.PNum (pi5)); - isvedge2 = edges.Used (i2) || ep2 || ep5; - - i2 = INDEX_2::Sort(el.PNum (pi3), el.PNum (pi6)); - isvedge3 = edges.Used (i2) || ep3 || ep6; - - - ishedge1 = edges.Used (INDEX_2::Sort(el.PNum (pi1), el.PNum (pi2))); - ishedge2 = edges.Used (INDEX_2::Sort(el.PNum (pi2), el.PNum (pi3))); - ishedge3 = edges.Used (INDEX_2::Sort(el.PNum (pi3), el.PNum (pi1))); - - - - switch (ishedge1 + ishedge2 + ishedge3) - { - case 0: - { - if (!isvedge1 && !isvedge2 && !isvedge3) - type = HP_PRISM; - else if (isvedge1 && !isvedge2 && !isvedge3) - type = HP_PRISM_SINGEDGE; - else if (isvedge1 && isvedge2 && !isvedge3) - type = HP_PRISM_SINGEDGE_V12; - break; - } - case 1: - { - if (ishedge1) - type = HP_PRISM_SINGEDGE_H1; - break; - } - case 2: - { - if (ishedge1 && ishedge2) - type = HP_PRISM_SINGEDGE_H12; - break; - } - } - - if (type != HP_NONE) - { - cout << "classified element, type = " << type << ", el = " << el << endl; - pnums[0] = el.PNum (pi1); - pnums[1] = el.PNum (pi2); - pnums[2] = el.PNum (pi3); - pnums[3] = el.PNum (pi4); - pnums[4] = el.PNum (pi5); - pnums[5] = el.PNum (pi6); - break; - } - } - break; - } - default: - { - cerr << "hp-refinement not defined for element" << endl; - } - } - - - if (type == HP_NONE) - { - cout << "element is HP_NONE: " << el << endl; - } - - if (!Get_HPRef_Struct (type)) - { - (*testout) << "case " << type << " not implemented " << endl; - cnt_nonimplement++; - misses[type]++; - } - - HPRefElement hpel; - hpel.type = type; - for (int j = 0; j < 8; j++) - hpel.pnums[j] = pnums[j]; - hpel.index = el.GetIndex(); - hpel.level = 1; - hpel.coarse_elnr = i; - - static const double points[4][3] = - { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 } }; - for (int j = 0; j < 4; j++) - for (int k = 0; k < 4; k++) - if (pnums[j] == el[k]) - { - hpel.param[j][0] = points[k][0]; - hpel.param[j][1] = points[k][1]; - hpel.param[j][2] = points[k][2]; - } - - elements.Append (hpel); - } - - cout << "undefined elements: " << cnt_undef << endl; - cout << "non-implemented: " << cnt_nonimplement << endl; - - for (int i = 0; i < misses.Size(); i++) - if (misses[i]) - cout << "missing case " << i << " occured " << misses[i] << " times" << endl; - - for (int i = 1; i <= mesh.GetNSE(); i++) - { - int j, k, pi3, pi4; - Element2d & el = mesh.SurfaceElement(i); - - HPREF_ELEMENT_TYPE type = HP_NONE; - int pnums[8] = { 0 }; - - switch (el.GetType()) - { - case TRIG: - { - for (j = 1; j <= 3; j++) - { - int ep1 = edgepoint.Test (el.PNumMod (j)); - int ep2 = edgepoint.Test (el.PNumMod (j+1)); - int ep3 = edgepoint.Test (el.PNumMod (j+2)); - - if (mesh.GetDimension() == 2) - { - ep1 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j))); - ep2 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+1))); - ep3 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+2))); - } - - int cp1 = cornerpoint.Test (el.PNumMod (j)); - int cp2 = cornerpoint.Test (el.PNumMod (j+1)); - int cp3 = cornerpoint.Test (el.PNumMod (j+2)); - - ep1 |= cp1; - ep2 |= cp2; - ep3 |= cp3; - - INDEX_2 i2; - i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); - // i2.Sort(); - int isedge1 = edges.Used (i2); - i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); - // i2.Sort(); - int isedge2 = edges.Used (i2); - i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); - // i2.Sort(); - int isedge3 = edges.Used (i2); - - if (isedge1 + isedge2 + isedge3 == 0) - { - if (!ep1 && !ep2 && !ep3) - type = HP_TRIG; - - if (ep1 && !ep2 && !ep3) - type = HP_TRIG_SINGCORNER; - - if (ep1 && ep2 && !ep3) - type = HP_TRIG_SINGCORNER12; - - if (ep1 && ep2 && ep3) - { - if (mesh.GetDimension() == 2) - type = HP_TRIG_SINGCORNER123_2D; - else - type = HP_TRIG_SINGCORNER123; - } - - if (type != HP_NONE) - { - pnums[0] = el.PNumMod (j); - pnums[1] = el.PNumMod (j+1); - pnums[2] = el.PNumMod (j+2); - break; - } - } - - if (isedge1 && !isedge2 && !isedge3) - { - int code = 0; - if (cp1) code += 1; - if (cp2) code += 2; - if (ep3) code += 4; - - HPREF_ELEMENT_TYPE types[] = - { - HP_TRIG_SINGEDGE, - HP_TRIG_SINGEDGECORNER1, - HP_TRIG_SINGEDGECORNER2, - HP_TRIG_SINGEDGECORNER12, - HP_TRIG_SINGEDGECORNER3, - HP_TRIG_SINGEDGECORNER13, - HP_TRIG_SINGEDGECORNER23, - HP_TRIG_SINGEDGECORNER123, - }; - type = types[code]; - pnums[0] = el.PNumMod (j); - pnums[1] = el.PNumMod (j+1); - pnums[2] = el.PNumMod (j+2); - break; - } - - - if (isedge1 && !isedge2 && isedge3) - { - if (!cp3) - { - if (!cp2) type = HP_TRIG_SINGEDGES; - else type = HP_TRIG_SINGEDGES2; - } - else - { - if (!cp2) type = HP_TRIG_SINGEDGES3; - else type = HP_TRIG_SINGEDGES23; - } - - pnums[0] = el.PNumMod (j); - pnums[1] = el.PNumMod (j+1); - pnums[2] = el.PNumMod (j+2); - break; - } - - if (isedge1 && isedge2 && isedge3) - { - type = HP_TRIG_3SINGEDGES; - pnums[0] = el.PNumMod (j); - pnums[1] = el.PNumMod (j+1); - pnums[2] = el.PNumMod (j+2); - break; - } - } - break; - } - case QUAD: - { - int ep1, ep2, ep3, ep4, cp1, cp2, cp3, cp4; - int isedge1, isedge2, isedge3, isedge4; - - for (j = 1; j <= 4; j++) - { - ep1 = edgepoint.Test (el.PNumMod (j)); - ep2 = edgepoint.Test (el.PNumMod (j+1)); - ep3 = edgepoint.Test (el.PNumMod (j+2)); - ep4 = edgepoint.Test (el.PNumMod (j+3)); - - if (mesh.GetDimension() == 2) - { - ep1 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j))); - ep2 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+1))); - ep3 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+2))); - ep4 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+3))); - } - - cp1 = cornerpoint.Test (el.PNumMod (j)); - cp2 = cornerpoint.Test (el.PNumMod (j+1)); - cp3 = cornerpoint.Test (el.PNumMod (j+2)); - cp4 = cornerpoint.Test (el.PNumMod (j+3)); - - ep1 |= cp1; - ep2 |= cp2; - ep3 |= cp3; - ep4 |= cp4; - - - INDEX_2 i2; - i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); - // i2.Sort(); - isedge1 = edges.Used (i2); - i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); - // i2.Sort(); - isedge2 = edges.Used (i2); - i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); - // i2.Sort(); - isedge3 = edges.Used (i2); - i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4)); - // i2.Sort(); - isedge4 = edges.Used (i2); - - int sumcp = cp1 + cp2 + cp3 + cp4; - int sumep = ep1 + ep2 + ep3 + ep4; - int sumedge = isedge1 + isedge2 + isedge3 + isedge4; - - switch (sumedge) - { - case 0: - { - switch (sumep) - { - case 0: - type = HP_QUAD; - break; - case 1: - if (ep1) type = HP_QUAD_SINGCORNER; - break; - case 2: - { - if (ep1 && ep2) type = HP_QUAD_0E_2VA; - if (ep1 && ep3) type = HP_QUAD_0E_2VB; - break; - } - case 3: - if (!ep4) type = HP_QUAD_0E_3V; - break; - case 4: - type = HP_QUAD_0E_4V; - break; - } - break; - } - case 1: - { - if (isedge1) - { - switch (cp1+cp2+ep3+ep4) - { - case 0: - type = HP_QUAD_SINGEDGE; - break; - case 1: - { - if (cp1) type = HP_QUAD_1E_1VA; - if (cp2) type = HP_QUAD_1E_1VB; - if (ep3) type = HP_QUAD_1E_1VC; - if (ep4) type = HP_QUAD_1E_1VD; - break; - } - case 2: - { - if (cp1 && cp2) type = HP_QUAD_1E_2VA; - if (cp1 && ep3) type = HP_QUAD_1E_2VB; - if (cp1 && ep4) type = HP_QUAD_1E_2VC; - if (cp2 && ep3) type = HP_QUAD_1E_2VD; - if (cp2 && ep4) type = HP_QUAD_1E_2VE; - if (ep3 && ep4) type = HP_QUAD_1E_2VF; - break; - } - case 3: - { - if (cp1 && cp2 && ep3) type = HP_QUAD_1E_3VA; - if (cp1 && cp2 && ep4) type = HP_QUAD_1E_3VB; - if (cp1 && ep3 && ep4) type = HP_QUAD_1E_3VC; - if (cp2 && ep3 && ep4) type = HP_QUAD_1E_3VD; - break; - } - case 4: - { - type = HP_QUAD_1E_4V; - break; - } - } - } - break; - } - case 2: - { - if (isedge1 && isedge4) - { - if (!cp2 && !ep3 && !cp4) - type = HP_QUAD_2E; - - if (cp2 && !ep3 && !cp4) - type = HP_QUAD_2E_1VA; - if (!cp2 && ep3 && !cp4) - type = HP_QUAD_2E_1VB; - if (!cp2 && !ep3 && cp4) - type = HP_QUAD_2E_1VC; - - if (cp2 && ep3 && !cp4) - type = HP_QUAD_2E_2VA; - if (cp2 && !ep3 && cp4) - type = HP_QUAD_2E_2VB; - if (!cp2 && ep3 && cp4) - type = HP_QUAD_2E_2VC; - - if (cp2 && ep3 && cp4) - type = HP_QUAD_2E_3V; - } - if (isedge1 && isedge3) - { - switch (sumcp) - { - case 0: - type = HP_QUAD_2EB_0V; break; - case 1: - { - if (cp1) type = HP_QUAD_2EB_1VA; - if (cp2) type = HP_QUAD_2EB_1VB; - break; - } - case 2: - { - if (cp1 && cp2) { type = HP_QUAD_2EB_2VA; } - if (cp1 && cp3) { type = HP_QUAD_2EB_2VB; } - if (cp1 && cp4) { type = HP_QUAD_2EB_2VC; } - if (cp2 && cp4) { type = HP_QUAD_2EB_2VD; } - break; - } - case 3: - { - if (cp1 && cp2 && cp3) { type = HP_QUAD_2EB_3VA; } - if (cp1 && cp2 && cp4) { type = HP_QUAD_2EB_3VB; } - break; - } - case 4: - { - type = HP_QUAD_2EB_4V; break; - } - } - } - break; - } - - case 3: - { - if (isedge1 && isedge2 && isedge4) - { - if (!cp3 && !cp4) type = HP_QUAD_3E; - if (cp3 && !cp4) type = HP_QUAD_3E_3VA; - if (!cp3 && cp4) type = HP_QUAD_3E_3VB; - if (cp3 && cp4) type = HP_QUAD_3E_4V; - } - break; - } - - case 4: - { - type = HP_QUAD_4E; - break; - } - } - - if (type != HP_NONE) - { - pnums[0] = el.PNumMod (j); - pnums[1] = el.PNumMod (j+1); - pnums[2] = el.PNumMod (j+2); - pnums[3] = el.PNumMod (j+3); - break; - } - } - if (type == HP_NONE) - { - (*testout) << "undefined element" << endl - << "cp = " << cp1 << cp2 << cp3 << cp4 << endl - << "ep = " << ep1 << ep2 << ep3 << ep4 << endl - << "isedge = " << isedge1 << isedge2 << isedge3 - << isedge4 << endl; - } - break; - } - } - - if (type == HP_NONE) - { - cerr << "undefined QUAD type" << endl; - for (j = 0; j < 4; j++) - pnums[j] = el[j]; - } - - HPRefElement hpel; - hpel.type = type; - for (j = 0; j < 8; j++) - hpel.pnums[j] = pnums[j]; - hpel.index = el.GetIndex(); - hpel.level = 1; - hpel.coarse_elnr = i-1; - - - static const double points[3][2] = - { { 1, 0 }, { 0, 1 }, { 0, 0 } }; - for (j = 0; j < 3; j++) - for (k = 0; k < 3; k++) - if (pnums[j] == el[k]) - { - hpel.param[j][0] = points[k][0]; - hpel.param[j][1] = points[k][1]; - } - elements.Append (hpel); - } - - - - - - - for (int i = 1; i <= mesh.GetNSeg(); i++) - { - Segment & seg = mesh.LineSegment(i); - - HPREF_ELEMENT_TYPE type = HP_NONE; - - int cp1 = cornerpoint.Test (seg.p1); - int cp2 = cornerpoint.Test (seg.p2); - - INDEX_2 i2; - i2 = INDEX_2(seg.p1, seg.p2); - i2.Sort(); - if (!edges.Used (i2)) - { - cp1 = edgepoint.Test (seg.p1); - cp2 = edgepoint.Test (seg.p2); - } - - HPRefElement hpel; - hpel.index = seg.edgenr + 10000 * seg.si; - hpel.level = 1; - - hpel.pnums[0] = seg.p1; - hpel.pnums[1] = seg.p2; - hpel.param[0][0] = seg.epgeominfo[0].dist; - hpel.param[1][0] = seg.epgeominfo[1].dist; - - if (!cp1 && !cp2) - hpel.type = HP_SEGM; - else if (cp1 && !cp2) - hpel.type = HP_SEGM_SINGCORNERL; - else if (!cp1 && cp2) - hpel.type = HP_SEGM_SINGCORNERR; - else - hpel.type = HP_SEGM_SINGCORNERS; - - (*testout) << "refine segment " << seg << ", hptype= " << hpel.type << endl; - - elements.Append (hpel); - - (*testout) << "add seg: " << endl << seg << endl; - (*testout) << "param = " << elements.Last().param[0][0] << ", " << elements.Last().param[1][0] << endl; - } - } - - - - /* ******************************* DoRefinement *************************************** */ - - // parameter "fine": false ... divide elements by a factor of 3/4 to 1/4 - // true ... divide by 7/8 to 1/8 - - void DoRefinement (Mesh & mesh, ARRAY<HPRefElement> & elements, - Refinement * ref, bool fine) - { - INDEX_2_HASHTABLE<int> newpts(elements.Size()+1); - INDEX_3_HASHTABLE<int> newfacepts(elements.Size()+1); - - // prepare new points - - int oldelsize = elements.Size(); - for (int i = 0; i < oldelsize; i++) - { - HPRefElement & el = elements[i]; - HPRef_Struct * hprs = Get_HPRef_Struct (el.type); - - if (!hprs) - { - cout << "Refinementstruct not defined for element " << el.type << endl; - continue; - } - - int j = 0; - while (hprs->splitedges[j][0]) - { - INDEX_2 i2(el.pnums[hprs->splitedges[j][0]-1], - el.pnums[hprs->splitedges[j][1]-1]); - if (!newpts.Used (i2)) - { - Point3d np = Center (mesh.Point (i2.I1()), - mesh.Point (i2.I2())); - np = Center (mesh.Point (i2.I1()),np); - if ( fine ) np = Center (mesh.Point (i2.I1()),np); - - int npi = mesh.AddPoint (np); - newpts.Set (i2, npi); - } - j++; - } - - - j = 0; - if (hprs->splitfaces) - while (hprs->splitfaces[j][0]) - { - INDEX_3 i3(el.pnums[hprs->splitfaces[j][0]-1], - el.pnums[hprs->splitfaces[j][1]-1], - el.pnums[hprs->splitfaces[j][2]-1]); - - if (i3.I2() > i3.I3()) Swap (i3.I2(), i3.I3()); - - if (!newfacepts.Used (i3)) - { - Point3d np = Center (mesh.Point (i3.I2()), - mesh.Point (i3.I3())); - np = Center (mesh.Point (i3.I1()),np); - if ( fine ) np = Center (mesh.Point (i3.I1()),np); - int npi = mesh.AddPoint (np); - newfacepts.Set (i3, npi); - } - j++; - } - } - - for (int i = 0; i < oldelsize; i++) - { - HPRefElement & el = elements[i]; - HPRef_Struct * hprs = Get_HPRef_Struct (el.type); - int newlevel = el.level + 1; - - if (el.type == HP_SEGM || - el.type == HP_TRIG || - el.type == HP_QUAD || - el.type == HP_TET || - el.type == HP_PRISM || - el.type == HP_HEX) - newlevel = el.level; - - if (!hprs) continue; - - int newpnums[64]; - double newparam[64][3]; - - int j; - for (j = 0; j < 8; j++) - { - newpnums[j] = el.pnums[j]; - for (int l = 0; l < 3; l++) - newparam[j][l] = el.param[j][l]; - } - - - // split edges, incl. transferring curvature - j = 0; - while (hprs->splitedges[j][0]) - { - INDEX_2 i2(el.pnums[hprs->splitedges[j][0]-1], - el.pnums[hprs->splitedges[j][1]-1]); - - int npi = newpts.Get(i2); - newpnums[hprs->splitedges[j][2]-1] = npi; - - double fac1, fac2; - if ( fine ) { fac1 = 0.875; fac2 = 0.125; } - else { fac1 = 0.75; fac2 = 0.25; } - - for (int l = 0; l < 3; l++) - newparam[hprs->splitedges[j][2]-1][l] = - fac1 * el.param[hprs->splitedges[j][0]-1][l] + - fac2 * el.param[hprs->splitedges[j][1]-1][l]; - - j++; - } - - // split faces - j = 0; - if (hprs->splitfaces) - while (hprs->splitfaces[j][0]) - { - INDEX_3 i3(el.pnums[hprs->splitfaces[j][0]-1], - el.pnums[hprs->splitfaces[j][1]-1], - el.pnums[hprs->splitfaces[j][2]-1]); - if (i3.I2() > i3.I3()) - Swap (i3.I2(), i3.I3()); - int npi = newfacepts.Get(i3); - newpnums[hprs->splitfaces[j][3]-1] = npi; - - double fac1, fac2; - if ( fine ) { fac1 = 0.75; fac2 = 0.125; } - else { fac1 = 0.5; fac2 = 0.25; } - - for (int l = 0; l < 3; l++) - newparam[hprs->splitfaces[j][3]-1][l] = - fac1 * el.param[hprs->splitfaces[j][0]-1][l] + - fac2 * el.param[hprs->splitfaces[j][1]-1][l] + - fac2 * el.param[hprs->splitfaces[j][2]-1][l]; - j++; - } - - // split elements - j = 0; - if (hprs->splitelements) - while (hprs->splitelements[j][0]) - { - int pi1 = el.pnums[hprs->splitelements[j][0]-1]; - Point3d np = - Center (Center (mesh.Point (pi1), - mesh.Point (el.pnums[hprs->splitelements[j][1]-1])), - Center (mesh.Point (el.pnums[hprs->splitelements[j][2]-1]), - mesh.Point (el.pnums[hprs->splitelements[j][3]-1]))); - // divide once more, if fine subdivision is wanted - if ( fine ) np = Center (mesh.Point (pi1),np); - int npi = mesh.AddPoint (np); - newpnums[hprs->splitelements[j][4]-1] = npi; - - double fac1, fac2; - if ( fine ) { fac1 = 0.625; fac2 = 0.125; } - else { fac1 = 0.25; fac2 = 0.25; } - - for (int l = 0; l < 3; l++) - newparam[hprs->splitelements[j][4]-1][l] = - fac1 * el.param[hprs->splitelements[j][0]-1][l] + - fac2 * el.param[hprs->splitelements[j][1]-1][l] + - fac2 * el.param[hprs->splitelements[j][2]-1][l] + - fac2 * el.param[hprs->splitelements[j][3]-1][l]; - - j++; - } - - j = 0; - while (hprs->neweltypes[j]) - { - HPRefElement newel; - newel.type = hprs->neweltypes[j]; - for (int k = 0; k < 8; k++) - newel.pnums[k] = newpnums[hprs->newels[j][k]-1]; - - newel.index = elements[i].index; - newel.coarse_elnr = elements[i].coarse_elnr; - newel.level = newlevel; - - for (int k = 0; k < 8; k++) - for (int l = 0; l < 3; l++) - newel.param[k][l] = newparam[hprs->newels[j][k]-1][l]; - - if (j == 0) - elements[i] = newel; - else - elements.Append (newel); - - j++; - } - } - } - - - - - - - /* ************************** DoRefineDummies ******************************** */ - - void DoRefineDummies (Mesh & mesh, ARRAY<HPRefElement> & elements, - Refinement * ref) - { - int oldelsize = elements.Size(); - - for (int i = 0; i < oldelsize; i++) - { - HPRefElement & el = elements[i]; - HPRef_Struct * hprs = Get_HPRef_Struct (el.type); - if (!hprs) continue; - - if (el.type != HP_DUMMY_QUAD_SINGCORNER && - el.type != HP_PYRAMID_EDGES && - el.type != HP_PYRAMID_0E_1V && - el.type != HP_HEX_0E_1V && - el.type != HP_HEX_1E_1V && - el.type != HP_HEX_1E_0V && - el.type != HP_HEX_3E_0V - ) continue; - - int newlevel = el.level; - - int newpnums[8]; - int j; - for (j = 0; j < 8; j++) - newpnums[j] = el.pnums[j]; - - double newparam[8][3]; - for (j = 0; j < 8; j++) - for (int k = 0; k < 3; k++) - newparam[j][k] = el.param[j][k]; - - j = 0; - while (hprs->neweltypes[j]) - { - HPRefElement newel; - newel.type = hprs->neweltypes[j]; - for (int k = 0; k < 8; k++) - newel.pnums[k] = newpnums[hprs->newels[j][k]-1]; - newel.index = el.index; - newel.coarse_elnr = el.coarse_elnr; - newel.level = newlevel; - - for (int k = 0; k < 8; k++) - for (int l = 0; l < 3; l++) - newel.param[k][l] = newparam[hprs->newels[j][k]-1][l]; - - if (j == 0) - elements[i] = newel; - else - elements.Append (newel); - j++; - } - } - } - - - - - - - - void SubdivideDegeneratedHexes (Mesh & mesh, ARRAY<HPRefElement> & elements) - { - int oldne = elements.Size(); - for (int i = 0; i < oldne; i++) - if (Get_HPRef_Struct (elements[i].type)->geom == HP_HEX) - { - bool common = 0; - for (int j = 0; j < 8; j++) - for (int k = 0; k < j; k++) - if (elements[i].pnums[j] == elements[i].pnums[k]) - common = 1; - if (common) - { - HPRefElement el = elements[i]; - - Point<3> center(0,0,0); - double newparam[3] = { 0, 0, 0 }; - - for (int j = 0; j < 8; j++) - { - center += 0.125 * Vec<3> (mesh[el.pnums[j]]); - for (int l = 0; l < 3; l++) - newparam[l] += 0.125 * el.param[j][l]; - } - - int npi = mesh.AddPoint (center); - - const ELEMENT_FACE * faces = MeshTopology::GetFaces (HEX); - - for (int j = 0; j < 6; j++) - { - ARRAY<int> pts; - for (int k = 0; k < 4; k++) - { - bool same = 0; - for (int l = 0; l < pts.Size(); l++) - if (el.pnums[pts[l]] == el.pnums[faces[j][k]-1]) - same = 1; - if (!same) - pts.Append (faces[j][k]-1); - - } - - HPRefElement newel = el; - if (pts.Size() == 3) - { - for (int k = 0; k < 3; k++) - { - newel.pnums[k] = el.pnums[pts[2-k]]; - for (int l = 0; l < 3; l++) - newel.param[k][l] = el.param[pts[2-k]][l]; - } - newel.pnums[3] = npi; - for (int l = 0; l < 3; l++) - newel.param[3][l] = newparam[l]; - - newel.type = HP_TET; - } - else - { - for (int k = 0; k < 4; k++) - { - newel.pnums[k] = el.pnums[pts[3-k]]; - for (int l = 0; l < 3; l++) - newel.param[k][l] = el.param[pts[3-k]][l]; - } - - newel.pnums[4] = npi; - for (int l = 0; l < 3; l++) - newel.param[4][l] = newparam[l]; - - newel.type = HP_PYRAMID; - } - - if (j == 0) - elements[i] = newel; - else - elements.Append (newel); - } - } - } - } - - - void CalcStatistics (ARRAY<HPRefElement> & elements) - { - return; - - int i, p; - int nsegm = 0, ntrig = 0, nquad = 0; - int nhex = 0, nprism = 0, npyramid = 0, ntet = 0; - int maxlevel = 0; - - for (i = 1; i <= elements.Size(); i++) - { - const HPRefElement & el = elements.Get(i); - maxlevel = max2 (el.level, maxlevel); - switch (Get_HPRef_Struct (el.type)->geom) - { - case HP_SEGM: - - { - nsegm++; - break; - } - case HP_TRIG: - { - ntrig ++; - break; - } - case HP_QUAD: - { - nquad++; - break; - } - case HP_TET: - { - ntet++; - break; - } - - case HP_PRISM: - { - nprism++; - break; - } - - case HP_PYRAMID: - { - npyramid++; - break; - } - - case HP_HEX: - { - nhex++; - break; - } - - default: - { - cerr << "statistics error, unknown element type" << endl; - } - } - } - - cout << "level = " << maxlevel << endl; - cout << "nsegm = " << nsegm << endl; - cout << "ntrig = " << ntrig << ", nquad = " << nquad << endl; - cout << "ntet = " << ntet << ", npyr = " << npyramid - << ", nprism = " << nprism << ", nhex = " << nhex << endl; - - return; - - double memcost = 0, cpucost = 0; - for (p = 1; p <= 20; p++) - { - memcost = (ntet + nprism + nhex) * pow (static_cast<double>(p), 6.0); - cpucost = (ntet + nprism + nhex) * pow (static_cast<double>(p), 9.0); - cout << "costs for p = " << p << ": mem = " << memcost << ", cpu = " << cpucost << endl; - } - - double memcosttet = 0; - double memcostprism = 0; - double memcosthex = 0; - double memcostsctet = 0; - double memcostscprism = 0; - double memcostschex = 0; - double cpucosttet = 0; - double cpucostprism = 0; - double cpucosthex = 0; - - for (i = 1; i <= elements.Size(); i++) - { - const HPRefElement & el = elements.Get(i); - switch (el.type) - { - case HP_TET: - case HP_TET_0E_1V: - case HP_TET_1E_0V: - case HP_TET_1E_1VA: - { - int p1 = maxlevel - el.level + 1; - (*testout) << "p1 = " << p1 << ", P1^6 = " << pow (static_cast<double>(p1), 6.0) - << " (p1-3)^6 = " << pow ( static_cast<double>(max2(p1-3, 0)), 6.0) - << " p1^3 = " << pow ( static_cast<double>(p1), 3.0) - << " (p1-3)^3 = " << pow ( static_cast<double>(p1-3), 3.0) - << " [p1^3-(p1-3)^3]^2 = " << sqr (pow (static_cast<double>(p1),3.0) - pow ( static_cast<double>(p1-3), 3.0)) - << endl; - - p1 /= 2 +1; - memcosttet += pow (static_cast<double>(p1), 6.0); - memcostsctet += pow (static_cast<double>(p1), 6.0) - pow ( static_cast<double>(max2(p1-3, 1)), 6.0); - cpucosttet += pow (static_cast<double>(p1), 9.0); - break; - } - case HP_PRISM: - case HP_PRISM_SINGEDGE: - { - int p1 = maxlevel - el.level + 1; - p1 /= 2 +1; - memcostprism += pow (static_cast<double>(p1), 6.0); - memcostscprism += pow (static_cast<double>(p1), 6.0) - pow ( static_cast<double>(max2(p1-3, 1)), 6.0); - cpucostprism += pow (static_cast<double>(p1), 9.0); - break; - } - case HP_HEX: - { - int p1 = maxlevel - el.level + 1; - int p2 = maxlevel; - p1 /= 2 +1; - p2 /= 2 +1; - memcosthex += pow (static_cast<double>(p1), 4.0) * pow (static_cast<double>(p2), 2.0); - memcostschex += pow (static_cast<double>(p1), 6.0) - pow ( static_cast<double>(max2(p1-2, 0)), 6.0); - cpucosthex += pow (static_cast<double>(p1), 6.0) * pow (static_cast<double>(p2), 3.0); - break; - } - default: - ; - } - } - cout << "TET: hp-memcost = " << memcosttet - << ", scmemcost = " << memcostsctet - << ", cpucost = " << cpucosttet - << endl; - cout << "PRI: hp-memcost = " << memcostprism - << ", scmemcost = " << memcostscprism - << ", cpucost = " << cpucostprism << endl; - cout << "HEX: hp-memcost = " << memcosthex - << ", scmemcost = " << memcostschex - << ", cpucost = " << cpucosthex << endl; - } - - - - - - - - /* ***************************** HPRefinement ********************************** */ - - void HPRefinement (Mesh & mesh, Refinement * ref, int levels) - { - PrintMessage (1, "HP Refinement called, levels = ", levels); - - // ARRAY<HPRefElement> hpelements; - - delete mesh.hpelements; - mesh.hpelements = new ARRAY<HPRefElement>; - - mesh.coarsemesh = new Mesh; - *mesh.coarsemesh = mesh; - - ARRAY<HPRefElement> & hpelements = *mesh.hpelements; - - - - PrepareElements (mesh, hpelements); - - for (int j = 1; j <= levels; j++) - { - cout << "hp-refine level " << j << flush; - // last parameter: true for fine subdivision (7/8 : 1/8), false for 3/4 : 1/4 - // Please check into CVS only with this parameter set to "true"! - DoRefinement (mesh, hpelements, ref, true); // FB - DoRefineDummies (mesh, hpelements, ref); - CalcStatistics (hpelements); - cout << " done" << endl; - } - - SubdivideDegeneratedHexes (mesh, hpelements); - - mesh.ClearSegments(); - mesh.ClearSurfaceElements(); - mesh.ClearVolumeElements(); - - for (int i = 0; i < hpelements.Size(); i++) - { - HPRefElement & hpel = hpelements[i]; - if (Get_HPRef_Struct (hpel.type)) - switch (Get_HPRef_Struct (hpel.type) -> geom) - { - case HP_SEGM: - { - Segment seg; - seg.p1 = hpel.pnums[0]; - seg.p2 = hpel.pnums[1]; - // NOTE: only for less than 10000 elements (HACK) !!! - seg.edgenr = hpel.index % 10000; - seg.si = hpel.index / 10000; - seg.epgeominfo[0].dist = hpel.param[0][0]; - seg.epgeominfo[1].dist = hpel.param[1][0]; - seg.epgeominfo[0].edgenr = seg.edgenr; - seg.epgeominfo[1].edgenr = seg.edgenr; - seg.hp_elnr = i; - mesh.AddSegment (seg); - break; - } - - - case HP_TRIG: - { - Element2d el(3); - el.PNum(1) = hpel.pnums[0]; - el.PNum(2) = hpel.pnums[1]; - el.PNum(3) = hpel.pnums[2]; - el.SetIndex (hpel.index); - el.hp_elnr = i; - mesh.AddSurfaceElement (el); - break; - } - case HP_QUAD: - { - Element2d el(4); - el.PNum(1) = hpel.pnums[0]; - el.PNum(2) = hpel.pnums[1]; - el.PNum(3) = hpel.pnums[2]; - el.PNum(4) = hpel.pnums[3]; - el.SetIndex (hpel.index); - el.hp_elnr = i; - mesh.AddSurfaceElement (el); - break; - } - case HP_TET: - { - Element el(4); - el.PNum(1) = hpel.pnums[0]; - el.PNum(2) = hpel.pnums[1]; - el.PNum(3) = hpel.pnums[2]; - el.PNum(4) = hpel.pnums[3]; - el.SetIndex (hpel.index); - el.hp_elnr = i; - mesh.AddVolumeElement (el); - break; - } - case HP_PRISM: - { - Element el(6); - el.PNum(1) = hpel.pnums[0]; - el.PNum(2) = hpel.pnums[1]; - el.PNum(3) = hpel.pnums[2]; - el.PNum(4) = hpel.pnums[3]; - el.PNum(5) = hpel.pnums[4]; - el.PNum(6) = hpel.pnums[5]; - el.SetIndex (hpel.index); - el.hp_elnr = i; - mesh.AddVolumeElement (el); - break; - } - - case HP_PYRAMID: - { - Element el(5); - el.PNum(1) = hpel.pnums[0]; - el.PNum(2) = hpel.pnums[1]; - el.PNum(3) = hpel.pnums[2]; - el.PNum(4) = hpel.pnums[3]; - el.PNum(5) = hpel.pnums[4]; - el.SetIndex (hpel.index); - el.hp_elnr = i; - mesh.AddVolumeElement (el); - break; - } - case HP_HEX: - { - Element el(8); - el.PNum(1) = hpel.pnums[0]; - el.PNum(2) = hpel.pnums[1]; - el.PNum(3) = hpel.pnums[2]; - el.PNum(4) = hpel.pnums[3]; - el.PNum(5) = hpel.pnums[4]; - el.PNum(6) = hpel.pnums[5]; - el.PNum(7) = hpel.pnums[6]; - el.PNum(8) = hpel.pnums[7]; - el.SetIndex (hpel.index); - el.hp_elnr = i; - mesh.AddVolumeElement (el); - break; - } - - default: - PrintSysError ("hpref, backconversion failed for element ", - int(Get_HPRef_Struct (hpel.type) -> geom)); - } - } - - mesh.UpdateTopology(); - } - - -} diff --git a/Netgen/libsrc/meshing/hprefinement.hpp b/Netgen/libsrc/meshing/hprefinement.hpp deleted file mode 100644 index df1cc01e8e..0000000000 --- a/Netgen/libsrc/meshing/hprefinement.hpp +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef FILE_HPREFINEMENT -#define FILE_HPREFINEMENT - -/**************************************************************************/ -/* File: hprefinement.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 27. Oct. 2000 */ -/**************************************************************************/ - -/* - HP Refinement -*/ - - - - -enum HPREF_ELEMENT_TYPE { - HP_NONE=0, - - HP_SEGM = 1, - HP_SEGM_SINGCORNERL, - HP_SEGM_SINGCORNERR, - HP_SEGM_SINGCORNERS, - - HP_TRIG = 10, - HP_TRIG_SINGCORNER, - HP_TRIG_SINGCORNER12, - HP_TRIG_SINGCORNER123, - HP_TRIG_SINGCORNER123_2D, // not rotational symmetric - HP_TRIG_SINGEDGE = 20, - HP_TRIG_SINGEDGECORNER1, // E = 100, V = 100 - HP_TRIG_SINGEDGECORNER2, // E = 100, V = 010 - HP_TRIG_SINGEDGECORNER12, // E = 100, V = 110 - HP_TRIG_SINGEDGECORNER3, - HP_TRIG_SINGEDGECORNER13, - HP_TRIG_SINGEDGECORNER23, - HP_TRIG_SINGEDGECORNER123, - HP_TRIG_SINGEDGES = 30, - HP_TRIG_SINGEDGES2, - HP_TRIG_SINGEDGES3, - HP_TRIG_SINGEDGES23, - HP_TRIG_3SINGEDGES = 40, - - HP_QUAD = 50, - HP_QUAD_SINGCORNER, - HP_DUMMY_QUAD_SINGCORNER, - HP_QUAD_SINGEDGE, - HP_QUAD_0E_2VA, // V = 1100 - HP_QUAD_0E_2VB, // V = 1010 - HP_QUAD_0E_3V, - HP_QUAD_0E_4V, - - // one edge: marked edge is always edge from vertex 1 to vertex 2 (E = 1000) - HP_QUAD_1E_1VA, // vertex on beginning of edge: V = 1000 - HP_QUAD_1E_1VB, // vertex on end of edge: V = 0100 - HP_QUAD_1E_1VC, // V = 0010 - HP_QUAD_1E_1VD, // V = 0001 - - HP_QUAD_1E_2VA, // V = 1100 - HP_QUAD_1E_2VB, // V = 1010 - HP_QUAD_1E_2VC, // V = 1001 - HP_QUAD_1E_2VD, // V = 0110 - HP_QUAD_1E_2VE, // V = 0101 - HP_QUAD_1E_2VF, // V = 0011 - - HP_QUAD_1E_3VA, // V = 1110 - HP_QUAD_1E_3VB, // V = 1101 - HP_QUAD_1E_3VC, // V = 1011 - HP_QUAD_1E_3VD, // V = 0111 - - HP_QUAD_1E_4V, // V = 1111 - - - HP_QUAD_2E, // E = 1001, V = 1000 - HP_QUAD_2E_1VA, // E = 1001, V = 1100 - HP_QUAD_2E_1VB, // E = 1001, V = 1010 - HP_QUAD_2E_1VC, // E = 1001, V = 1001 - HP_QUAD_2E_2VA, // E = 1001, V = 1110 - HP_QUAD_2E_2VB, // E = 1001, V = 1101 - HP_QUAD_2E_2VC, // E = 1001, V = 1011 - HP_QUAD_2E_3V, // E = 1001, V = 1111 - - HP_QUAD_2EB_0V, // E = 1010, V = 0000 - HP_QUAD_2EB_1VA, // E = 1010, V = 1000 - HP_QUAD_2EB_1VB, // E = 1010, V = 0100 - HP_QUAD_2EB_2VA, // E = 1010, V = 1100 - HP_QUAD_2EB_2VB, // E = 1010, V = 1010 - HP_QUAD_2EB_2VC, // E = 1010, V = 1001 - HP_QUAD_2EB_2VD, // E = 1010, V = 0101 - HP_QUAD_2EB_3VA, // E = 1010, V = 1110 - HP_QUAD_2EB_3VB, // E = 1010, V = 1101 - - HP_QUAD_2EB_4V, - - - HP_QUAD_3E, // E = 1101, V = 1100 - HP_QUAD_3E_3VA, // E = 1101, V = 1110 - HP_QUAD_3E_3VB, // E = 1101, V = 1101 - HP_QUAD_3E_4V, // E = 1101, V = 1111 - - HP_QUAD_4E, - - - HP_TET = 100, // no singular vertex/edge - HP_TET_0E_1V, // V1 - HP_TET_0E_2V, // V1,2 - HP_TET_0E_3V, // V1,2,3 - HP_TET_0E_4V, // V1,2,3,4 - HP_TET_1E_0V = 200, // E1-2 - HP_TET_1E_1VA, // V1 - HP_TET_1E_1VB, // V3 - HP_TET_1E_2VA, // V1,2 - HP_TET_1E_2VB, // V1,3 - HP_TET_1E_2VC, // V1,4 - HP_TET_1E_2VD, // V3,4 - HP_TET_1E_3VA, // V1,2,3 - HP_TET_1E_3VB, // V1,3,4 - HP_TET_1E_4V, // V1,2,3,4 - - - // 2 connected edges, additonally marked Vs - HP_TET_2EA_0V = 220, // E1-2, E1-3 - HP_TET_2EA_1VA, // V2 - HP_TET_2EA_1VB, // V3 - HP_TET_2EA_1VC, // V4 - HP_TET_2EA_2VA, // V2,3 - HP_TET_2EA_2VB, // V2,4 - HP_TET_2EA_2VC, // V3,4 - HP_TET_2EA_3V, // V2,3,4 - - // 2 opposite edges - HP_TET_2EB_0V = 230, // E1-2, E3-4 - HP_TET_2EB_1V, // V1 - HP_TET_2EB_2VA, // V1,2 - HP_TET_2EB_2VB, // V1,3 - HP_TET_2EB_2VC, // V1,4 - HP_TET_2EB_3V, // V1,2,3 - HP_TET_2EB_4V, // V1,2,3,4 - - HP_TET_3EA_0V = 400, // E1-2, E1-3, E1-4, 3 edges connected - HP_TET_3EA_1V, // V2 - HP_TET_3EA_2V, // V2,3 - HP_TET_3EA_3V, // V2,3,4 - - HP_TET_3EB_0V = 420, // E1-2, E1-4, E2-3 3 edges chain - HP_TET_3EB_1V, // - HP_TET_3EB_2V, // - HP_TET_3EC_0V = 430, // 3 edges chain, alter - HP_TET_3EC_1V, // 3 edges chain, alter - HP_TET_3EC_2V, // 3 edges chain, alter - - - HP_TET_1F_0E_0V = 500, // 1 singular face - HP_TET_1F_0E_1VA, // 1 sing vertex in face (V2) - HP_TET_1F_0E_1VB, // 1 sing vertex not in face (V1) - HP_TET_1F_1EA_0V, // 1 sing edge not in face - HP_TET_1F_1EB_0V, // 1 sing edge in face - HP_TET_2F_0E_0V = 600, // 2 singular faces - - HP_PRISM = 1000, - HP_PRISM_SINGEDGE, - HP_PRISM_SINGEDGE_V12, - HP_PRISM_SINGEDGE_H1, - HP_PRISM_SINGEDGE_H12, - - HP_PRISM_1FA_0E_0V, // 1 singular trig face - HP_PRISM_1FB_0E_0V, // 1 singular quad face 1-2-4-5 - HP_PRISM_1FB_1EA_0V, // 1 singular quad face, edge is 1-2 - - HP_PYRAMID = 2000, - HP_PYRAMID_0E_1V, - HP_PYRAMID_EDGES, - HP_PYRAMID_1FB_0E_1VA, // 1 trig face, top vertex - - HP_HEX = 3000, - HP_HEX_0E_1V, - HP_HEX_1E_1V, - HP_HEX_1E_0V, - HP_HEX_3E_0V, - - HP_HEX_1F_0E_0V -}; - - - -struct HPRef_Struct { - HPREF_ELEMENT_TYPE geom; - int (*splitedges)[3]; - int (*splitfaces)[4]; - int (*splitelements)[5]; - HPREF_ELEMENT_TYPE * neweltypes; - int (*newels)[8]; -}; - - - - -class HPRefElement -{ -public: - HPRefElement () - { - for (int i = 0; i < 8; i++) - { - pnums[i] = -1; - param[i][0] = param[i][1] = param[i][2] = 0; - } - } - HPREF_ELEMENT_TYPE type; - PointIndex pnums[8]; - double param[8][3]; - int index; - int level; - int coarse_elnr; - // EdgePointGeomInfo epgeominfo[2]; -}; - - - -extern void HPRefinement (Mesh & mesh, Refinement * ref, int levels); - - -#endif - - - - diff --git a/Netgen/libsrc/meshing/improve2.cpp b/Netgen/libsrc/meshing/improve2.cpp deleted file mode 100644 index af0ea0ca45..0000000000 --- a/Netgen/libsrc/meshing/improve2.cpp +++ /dev/null @@ -1,798 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" -#include <opti.hpp> - -#ifndef SMALLLIB -//#include <visual.hpp> -#endif - -namespace netgen -{ - -class Neighbour -{ - int nr[3]; - int orient[3]; - -public: - Neighbour () { nr[0] = nr[1] = nr[2] = -1; orient[0] = orient[1] = orient[2] = 0; } - - void SetNr (int side, int anr) { nr[side-1] = anr; } - int GetNr (int side) { return nr[side-1]; } - - void SetOrientation (int side, int aorient) { orient[side-1] = aorient; } - int GetOrientation (int side) { return orient[side-1]; } -}; - - - - -class trionedge -{ -public: - int tnr; - int sidenr; - - trionedge () { tnr = 0; sidenr = 0; } - trionedge (int atnr, int asidenr) - { tnr = atnr; sidenr = asidenr; } -}; - - - - -void MeshOptimize2d :: EdgeSwapping (Mesh & mesh, int usemetric) -{ - // return; - - if (!faceindex) - { - if (usemetric) - PrintMessage (3, "Edgeswapping, metric"); - else - PrintMessage (3, "Edgeswapping, topological"); - - for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) - { - EdgeSwapping (mesh, usemetric); - - if (multithread.terminate) - throw NgException ("Meshing stopped"); - } - - faceindex = 0; - mesh.CalcSurfacesOfNode(); - return; - } - - - int i, i2, j, k, j2; - bool should; - PointIndex pi; - - ARRAY<SurfaceElementIndex> seia; - mesh.GetSurfaceElementsOfFace (faceindex, seia); - - for (i = 0; i < seia.Size(); i++) - if (mesh[seia[i]].GetNP() != 3) - { - GenericImprove (mesh); - return; - } - - int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); - - ARRAY<Neighbour> neighbors(mesh.GetNSE()); - INDEX_2_HASHTABLE<trionedge> other(seia.Size() + 2); - - - ARRAY<char> swapped(mesh.GetNSE()); - ARRAY<int,PointIndex::BASE> pdef(mesh.GetNP()); - ARRAY<double,PointIndex::BASE> pangle(mesh.GetNP()); - - SurfaceElementIndex t1, t2; - int o1, o2; - - PointIndex pi1, pi2, pi3, pi4; - PointGeomInfo gi1, gi2, gi3, gi4; - - - int nswaps = 0; - int e, done; - double d; - Vec3d nv1, nv2; - double horder; - double loch; - static const double minangle[] = { 0, 1.481, 2.565, 3.627, 4.683, 5.736, 7, 9 }; - - pangle = 0; - - for (i = 0; i < seia.Size(); i++) - { - const Element2d & sel = mesh[seia[i]]; - for (j = 0; j < 3; j++) - { - POINTTYPE typ = mesh.PointType (sel[j]); - if (typ == FIXEDPOINT || typ == EDGEPOINT) - { - pangle[sel[j]] += - Angle (mesh[sel[(j+1)%3]] - mesh[sel[j]], - mesh[sel[(j+2)%3]] - mesh[sel[j]]); - } - } - } - - for (pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - { - if (mesh.PointType(pi) == INNERPOINT || mesh.PointType(pi) == SURFACEPOINT) - pdef[pi] = -6; - else - for (j = 0; j < 8; j++) - if (pangle[pi] >= minangle[j]) - pdef[pi] = -1-j; - } - - for (i = 0; i < seia.Size(); i++) - { - const Element2d & sel = mesh[seia[i]]; - for (j = 0; j < 3; j++) - pdef[sel[j]]++; - } - - for (i = 0; i < seia.Size(); i++) - { - const Element2d & sel = mesh[seia[i]]; - for (j = 0; j < 3; j++) - { - neighbors[seia[i]].SetNr (j+1, -1); - neighbors[seia[i]].SetOrientation (j+1, 0); - } - } - - /* - ARRAY<Vec3d> normals(mesh.GetNP()); - for (i = 1; i <= mesh.GetNSE(); i++) - { - Element2d & hel = mesh.SurfaceElement(i); - if (hel.GetIndex() == faceindex) - for (k = 1; k <= 3; k++) - { - int pi = hel.PNum(k); - SelectSurfaceOfPoint (mesh.Point(pi), hel.GeomInfoPi(k)); - int surfi = mesh.GetFaceDescriptor(faceindex).SurfNr(); - GetNormalVector (surfi, mesh.Point(pi), normals.Elem(pi)); - normals.Elem(pi) /= normals.Elem(pi).Length(); - } - } - */ - - - for (i = 0; i < seia.Size(); i++) - { - const Element2d & sel = mesh[seia[i]]; - - for (j = 1; j <= 3; j++) - { - pi1 = sel.PNumMod(j+1); - pi2 = sel.PNumMod(j+2); - - loch = mesh.GetH(mesh[pi1]); - - INDEX_2 edge(pi1, pi2); - edge.Sort(); - - if (mesh.IsSegment (pi1, pi2)) - continue; - - /* - if (segments.Used (edge)) - continue; - */ - INDEX_2 ii2 (pi1, pi2); - if (other.Used (ii2)) - { - // INDEX_2 i2s(ii2); - // i2s.Sort(); - - i2 = other.Get(ii2).tnr; - j2 = other.Get(ii2).sidenr; - - neighbors[seia[i]].SetNr (j, i2); - neighbors[seia[i]].SetOrientation (j, j2); - neighbors[i2].SetNr (j2, seia[i]); - neighbors[i2].SetOrientation (j2, j); - } - else - { - other.Set (INDEX_2 (pi2, pi1), trionedge (seia[i], j)); - } - } - } - - for (i = 0; i < seia.Size(); i++) - swapped[seia[i]] = 0; - - - int t = 4; - done = 0; - while (!done && t >= 2) - { - for (i = 0; i < seia.Size(); i++) - { - t1 = seia[i]; - - if (mesh[t1].IsDeleted()) - continue; - - if (mesh[t1].GetIndex() != faceindex) - continue; - - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - for (o1 = 1; o1 <= 3; o1++) - { - t2 = neighbors[t1].GetNr (o1); - o2 = neighbors[t1].GetOrientation (o1); - - if (t2 == -1) continue; - if (swapped[t1] || swapped[t2]) continue; - - - pi1 = mesh[t1].PNumMod(o1+1); - pi2 = mesh[t1].PNumMod(o1+2); - pi3 = mesh[t1].PNumMod(o1); - pi4 = mesh[t2].PNumMod(o2); - - gi1 = mesh[t1].GeomInfoPiMod(o1+1); - gi2 = mesh[t1].GeomInfoPiMod(o1+2); - gi3 = mesh[t1].GeomInfoPiMod(o1); - gi4 = mesh[t2].GeomInfoPiMod(o2); - - // normal of old (new ?????) - nv1 = Cross (mesh.Point(pi3)-mesh.Point(pi4), - mesh.Point(pi1)-mesh.Point(pi4)); - nv2 = Cross (mesh.Point(pi4)-mesh.Point(pi3), - mesh.Point(pi2)-mesh.Point(pi3)); - - - // normals of swapped original (???JS) - Vec3d nv3, nv4; - nv3 = Cross (mesh.Point(pi1)-mesh.Point(pi4), - mesh.Point(pi2)-mesh.Point(pi4)); - nv4 = Cross (mesh.Point(pi2)-mesh.Point(pi3), - mesh.Point(pi1)-mesh.Point(pi3)); - - nv3 *= -1; - nv4 *= -1; - nv3.Normalize(); - nv4.Normalize(); - - nv1.Normalize(); - nv2.Normalize(); - - Vec3d nvp3, nvp4; - SelectSurfaceOfPoint (mesh.Point(pi3), gi3); - GetNormalVector (surfnr, mesh.Point(pi3), gi3, nvp3); - - nvp3.Normalize(); - - SelectSurfaceOfPoint (mesh.Point(pi4), gi4); - GetNormalVector (surfnr, mesh.Point(pi4), gi4, nvp4); - - nvp4.Normalize(); - - - - double critval = cos (M_PI / 6); // 30 degree - bool allowswap = - (nv1 * nvp3 > critval) && - (nv1 * nvp4 > critval) && - (nv2 * nvp3 > critval) && - (nv2 * nvp4 > critval) && - (nvp3 * nv3 > critval) && - (nvp4 * nv4 > critval); - - - horder = Dist (mesh.Point(pi1), mesh.Point(pi2)); - - if ( // nv1 * nv2 >= 0 && - nv1.Length() > 1e-3 * horder * horder && - nv2.Length() > 1e-3 * horder * horder && - allowswap ) - { - if (!usemetric) - { - e = pdef[pi1] + pdef[pi2] - pdef[pi3] - pdef[pi4]; - d = - Dist2 (mesh.Point(pi1), mesh.Point(pi2)) - - Dist2 (mesh.Point(pi3), mesh.Point(pi4)); - - should = e >= t && (e > 2 || d > 0); - } - else - { - should = - CalcTriangleBadness (mesh.Point(pi4), mesh.Point(pi3), mesh.Point(pi1), - metricweight, loch) + - CalcTriangleBadness (mesh.Point(pi3), mesh.Point(pi4), mesh.Point(pi2), - metricweight, loch) < - CalcTriangleBadness (mesh.Point(pi1), mesh.Point(pi2), mesh.Point(pi3), - metricweight, loch) + - CalcTriangleBadness (mesh.Point(pi2), mesh.Point(pi1), mesh.Point(pi4), - metricweight, loch); - - } - - - if (allowswap) - { - Element2d sw1 (pi4, pi3, pi1); - Element2d sw2 (pi3, pi4, pi2); - - int legal1 = - mesh.LegalTrig (mesh.SurfaceElement (t1)) + - mesh.LegalTrig (mesh.SurfaceElement (t2)); - int legal2 = - mesh.LegalTrig (sw1) + mesh.LegalTrig (sw2); - - if (legal1 < legal2) should = 1; - if (legal2 < legal1) should = 0; - } - - if (should) - { - // do swapping ! - - // cout << "swap " << endl; - - nswaps ++; - - // testout << "nv1 = " << nv1 << " nv2 = " << nv2 << endl; - - done = 1; - - mesh[t1].PNum(1) = pi1; - mesh[t1].PNum(2) = pi4; - mesh[t1].PNum(3) = pi3; - - mesh[t2].PNum(1) = pi2; - mesh[t2].PNum(2) = pi3; - mesh[t2].PNum(3) = pi4; - - mesh[t1].GeomInfoPi(1) = gi1; - mesh[t1].GeomInfoPi(2) = gi4; - mesh[t1].GeomInfoPi(3) = gi3; - - mesh[t2].GeomInfoPi(1) = gi2; - mesh[t2].GeomInfoPi(2) = gi3; - mesh[t2].GeomInfoPi(3) = gi4; - - pdef[pi1]--; - pdef[pi2]--; - pdef[pi3]++; - pdef[pi4]++; - - swapped[t1] = 1; - swapped[t2] = 1; - } - } - } - } - t--; - } - - mesh.SetNextTimeStamp(); -} - - - - - - - - -void MeshOptimize2d :: CombineImprove (Mesh & mesh) -{ - if (!faceindex) - { - PrintMessage (3, "Combine improve"); - - for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) - { - CombineImprove (mesh); - - if (multithread.terminate) - throw NgException ("Meshing stopped"); - } - faceindex = 0; - return; - } - - - int i, j, k, l, i2, j2; - PointIndex pi; - SurfaceElementIndex sei; - - - ARRAY<SurfaceElementIndex> seia; - mesh.GetSurfaceElementsOfFace (faceindex, seia); - - - for (i = 0; i < seia.Size(); i++) - if (mesh[seia[i]].GetNP() != 3) - return; - - - - int surfnr = 0; - if (faceindex) - surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); - - - int should; - PointIndex pi1, pi2; - MeshPoint p1, p2, pnew; - double bad1, bad2; - Vec3d nv; - - int np = mesh.GetNP(); - int nse = mesh.GetNSE(); - - TABLE<SurfaceElementIndex,PointIndex::BASE> elementsonnode(np); - ARRAY<SurfaceElementIndex> hasonepi, hasbothpi; - - for (i = 0; i < seia.Size(); i++) - { - Element2d & el = mesh[seia[i]]; - for (j = 0; j < el.GetNP(); j++) - { - elementsonnode.Add (el[j], seia[i]); - } - } - - - ARRAY<int,PointIndex::BASE> fixed(np); - fixed = 0; - - SegmentIndex si; - for (si = 0; si < mesh.GetNSeg(); si++) - { - INDEX_2 i2(mesh[si].p1, mesh[si].p2); - fixed[i2.I1()] = 1; - fixed[i2.I2()] = 1; - } - - - ARRAY<Vec3d,PointIndex::BASE> normals(np); - - for (pi = PointIndex::BASE; - pi < np + PointIndex::BASE; pi++) - { - if (elementsonnode[pi].Size()) - { - Element2d & hel = mesh[elementsonnode[pi][0]]; - for (k = 0; k < 3; k++) - if (hel[k] == pi) - { - SelectSurfaceOfPoint (mesh[pi], hel.GeomInfoPi(k+1)); - GetNormalVector (surfnr, mesh[pi], hel.GeomInfoPi(k+1), normals[pi]); - break; - } - if (k == 3) - { - cerr << "Neuer Fehler von Joachim, code 17121" << endl; - } - } - } - - - for (i = 0; i < seia.Size(); i++) - { - - sei = seia[i]; - Element2d & elem = mesh[sei]; - if (elem.IsDeleted()) continue; - - for (j = 0; j < 3; j++) - { - pi1 = elem[j]; - pi2 = elem[(j+1) % 3]; - - if (pi1 < PointIndex::BASE || - pi2 < PointIndex::BASE) - continue; - - /* - INDEX_2 i2(pi1, pi2); - i2.Sort(); - if (segmentht.Used(i2)) - continue; - */ - - bool debugflag = 0; - - if (debugflag) - { - (*testout) << "Combineimprove, face = " << faceindex - << "pi1 = " << pi1 << " pi2 = " << pi2 << endl; - } - - /* - // save version: - if (fixed.Get(pi1) || fixed.Get(pi2)) - continue; - if (pi2 < pi1) swap (pi1, pi2); - */ - - // more general - if (fixed[pi2]) - Swap (pi1, pi2); - - if (fixed[pi2]) - continue; - - double loch = mesh.GetH (mesh[pi1]); - - INDEX_2 si2 (pi1, pi2); - si2.Sort(); - - /* - if (edgetested.Used (si2)) - continue; - edgetested.Set (si2, 1); - */ - - hasonepi.SetSize(0); - hasbothpi.SetSize(0); - - for (k = 0; k < elementsonnode[pi1].Size(); k++) - { - const Element2d & el2 = mesh[elementsonnode[pi1][k]]; - - if (el2.IsDeleted()) continue; - - if (el2[0] == pi2 || el2[1] == pi2 || el2[2] == pi2) - { - hasbothpi.Append (elementsonnode[pi1][k]); - nv = Cross (Vec3d (mesh[el2[0]], mesh[el2[1]]), - Vec3d (mesh[el2[0]], mesh[el2[2]])); - } - else - { - hasonepi.Append (elementsonnode[pi1][k]); - } - } - - - Element2d & hel = mesh[hasbothpi[0]]; - for (k = 0; k < 3; k++) - if (hel[k] == pi1) - { - SelectSurfaceOfPoint (mesh[pi1], - hel.GeomInfoPi(k+1)); - GetNormalVector (surfnr, mesh[pi1], hel.GeomInfoPi(k+1), nv); - break; - } - if (k == 3) - { - cerr << "Neuer Fehler von Joachim, code 32434" << endl; - } - - - // nv = normals.Get(pi1); - - - - for (k = 0; k < elementsonnode[pi2].Size(); k++) - { - const Element2d & el2 = mesh[elementsonnode[pi2][k]]; - if (el2.IsDeleted()) continue; - - if (el2[0] == pi1 || el2[1] == pi1 || el2[2] == pi1) - ; - else - hasonepi.Append (elementsonnode[pi2][k]); - } - - bad1 = 0; - int illegal1 = 0, illegal2 = 0; - for (k = 0; k < hasonepi.Size(); k++) - { - const Element2d & el = mesh[hasonepi[k]]; - bad1 += CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]], - nv, -1, loch); - illegal1 += 1-mesh.LegalTrig(el); - } - - for (k = 0; k < hasbothpi.Size(); k++) - { - const Element2d & el = mesh[hasbothpi[k]]; - bad1 += CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]], - nv, -1, loch); - illegal1 += 1-mesh.LegalTrig(el); - } - bad1 /= (hasonepi.Size()+hasbothpi.Size()); - - p1 = mesh[pi1]; - p2 = mesh[pi2]; - - pnew = p1; - mesh[pi1] = pnew; - mesh[pi2] = pnew; - - bad2 = 0; - for (k = 0; k < hasonepi.Size(); k++) - { - Element2d & el = mesh[hasonepi[k]]; - double err = - CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]], - nv, -1, loch); - bad2 += err; - - Vec3d hnv = Cross (Vec3d (mesh[el[0]], - mesh[el[1]]), - Vec3d (mesh[el[0]], - mesh[el[2]])); - if (hnv * nv < 0) - bad2 += 1e10; - - for (l = 0; l < 3; l++) - if ( (normals[el[l]] * nv) < 0.5) - bad2 += 1e10; - - illegal2 += 1-mesh.LegalTrig(el); - } - bad2 /= hasonepi.Size(); - - mesh[pi1] = p1; - mesh[pi2] = p2; - - - if (debugflag) - { - (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl; - } - - - bool should = (bad2 < bad1 && bad2 < 1e4); - if (bad2 < 1e4) - { - if (illegal1 > illegal2) should = 1; - if (illegal2 > illegal1) should = 0; - } - - - if (should) - { - // (*testout) << "combine !" << endl; - // (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl; - - - mesh[pi1] = pnew; - PointGeomInfo gi; - bool gi_set(false); - - - Element2d *el1p; - l=0; - while(mesh[elementsonnode[pi1][l]].IsDeleted() && l<elementsonnode.EntrySize(pi1)) l++; - if(l<elementsonnode.EntrySize(pi1)) - el1p = &mesh[elementsonnode[pi1][l]]; - else - cerr << "OOPS!" << endl; - - for (l = 0; l < el1p->GetNP(); l++) - if ((*el1p)[l] == pi1) - { - gi = el1p->GeomInfoPi (l+1); - gi_set = true; - } - - // (*testout) << "Connect point " << pi2 << " to " << pi1 << "\n"; - for (k = 0; k < elementsonnode[pi2].Size(); k++) - { - Element2d & el = mesh[elementsonnode[pi2][k]]; - if(el.IsDeleted()) continue; - elementsonnode.Add (pi1, elementsonnode[pi2][k]); - - bool haspi1 = 0; - for (l = 0; l < el.GetNP(); l++) - if (el[l] == pi1) - haspi1 = 1; - if (haspi1) continue; - - for (l = 0; l < el.GetNP(); l++) - { - if (el[l] == pi2) - { - el[l] = pi1; - el.GeomInfoPi (l+1) = gi; - } - - fixed[el[l]] = 1; - } - } - - /* - for (k = 0; k < hasbothpi.Size(); k++) - { - cout << mesh[hasbothpi[k]] << endl; - for (l = 0; l < 3; l++) - cout << mesh[mesh[hasbothpi[k]][l]] << " "; - cout << endl; - } - */ - - for (k = 0; k < hasbothpi.Size(); k++) - { - mesh[hasbothpi[k]].Delete(); - /* - for (l = 0; l < 4; l++) - mesh[hasbothpi[k]][l] = PointIndex::BASE-1; - */ - } - - } - } - } - - // mesh.Compress(); - mesh.SetNextTimeStamp(); -} - - -void MeshOptimize2d :: CheckMeshApproximation (Mesh & mesh) -{ - // Check angles between elements and normals at corners - /* - - int i, j; - int ne = mesh.GetNSE(); - int surfnr; - - Vec3d n, ng; - ARRAY<Vec3d> ngs(3); - - (*mycout) << "Check Surface Approxiamtion" << endl; - (*testout) << "Check Surface Approxiamtion" << endl; - - for (i = 1; i <= ne; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - surfnr = mesh.GetFaceDescriptor (el.GetIndex()).SurfNr(); - Vec3d n = Cross (mesh.Point (el.PNum(1)) - mesh.Point (el.PNum(2)), - mesh.Point (el.PNum(1)) - mesh.Point (el.PNum(3))); - n /= n.Length(); - - for (j = 1; j <= el.GetNP(); j++) - { - SelectSurfaceOfPoint (mesh.Point(el.PNum(j)), el.GeomInfoPi(j)); - GetNormalVector (surfnr, mesh.Point(el.PNum(j)), ng); - ng /= ng.Length(); - ngs.Elem(j) = ng; - - double angle = (180.0 / M_PI) * Angle (n, ng); - if (angle > 60) - { - (*testout) << "el " << i << " node " << el.PNum(j) - << "has angle = " << angle << endl; - } - } - - for (j = 1; j <= 3; j++) - { - double angle = (180.0 / M_PI) * Angle (ngs.Get(j), ngs.Get(j%3+1)); - if (angle > 60) - { - (*testout) << "el " << i << " node-node " - << ngs.Get(j) << " - " << ngs.Get(j%3+1) - << " has angle = " << angle << endl; - } - } - } - */ -} -} diff --git a/Netgen/libsrc/meshing/improve2.hpp b/Netgen/libsrc/meshing/improve2.hpp deleted file mode 100644 index 0770a93b05..0000000000 --- a/Netgen/libsrc/meshing/improve2.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef FILE_IMPROVE2 -#define FILE_IMPROVE2 - - - -/// -class MeshOptimize2d -{ - int faceindex; - int improveedges; - double metricweight; - int writestatus; - -public: - /// - MeshOptimize2d (); - /// - void ImproveMesh (Mesh & mesh2d); - void ImproveMeshJacobian (Mesh & mesh2d); - - void EdgeSwapping (Mesh & mesh, int usemetric); - void CombineImprove (Mesh & mesh); - - void GenericImprove (Mesh & mesh); - - - void SetFaceIndex (int fi) { faceindex = fi; } - void SetImproveEdges (int ie) { improveedges = ie; } - void SetMetricWeight (double mw) { metricweight = mw; } - void SetWriteStatus (int ws) { writestatus = ws; } - - /// - virtual void SelectSurfaceOfPoint (const Point3d & p, - const PointGeomInfo & gi); - /// - virtual void ProjectPoint (INDEX /* surfind */, Point3d & /* p */) const { }; - /// - virtual void ProjectPoint2 (INDEX /* surfind */, INDEX /* surfind2 */, Point3d & /* p */) const { }; - /// liefert zu einem 3d-Punkt die geominfo (Dreieck) und liefert 1, wenn erfolgreich, - /// 0, wenn nicht (Punkt ausserhalb von chart) - virtual int CalcPointGeomInfo(PointGeomInfo& gi, const Point3d& /*p3*/) const - { gi.trignum = 1; return 1;}; - - virtual int CalcPointGeomInfo(int /* surfind */, PointGeomInfo& gi, const Point3d& p3) const - { return CalcPointGeomInfo (gi, p3); } - - /// - virtual void GetNormalVector(INDEX surfind, const Point3d & p, PointGeomInfo & gi, Vec3d & n) const; - virtual void GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const; - - void CheckMeshApproximation (Mesh & mesh); - - - /// - friend class Opti2SurfaceMinFunction; - /// - friend class Opti2EdgeMinFunction; - /// - friend double Opti2FunctionValueGrad (const Vector & x, Vector & grad); - /// - friend double Opti2EdgeFunctionValueGrad (const Vector & x, Vector & grad); - - - -}; - - -extern void CalcTriangleBadness (double x2, double x3, double y3, - double metricweight, - double h, double & badness, - double & g1x, double & g1y); - - - - -extern double CalcTriangleBadness (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - double metricweight, - double h); - -extern double CalcTriangleBadness (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Vec3d & n, - double metricweight, - double h); - -#endif - - diff --git a/Netgen/libsrc/meshing/improve2gen.cpp b/Netgen/libsrc/meshing/improve2gen.cpp deleted file mode 100644 index 69f0e23b27..0000000000 --- a/Netgen/libsrc/meshing/improve2gen.cpp +++ /dev/null @@ -1,441 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" -#include <opti.hpp> - -namespace netgen -{ - - class ImprovementRule - { - public: - ARRAY<Element2d> oldels; - ARRAY<Element2d> newels; - ARRAY<INDEX_2> deledges; - ARRAY<int> incelsonnode; - ARRAY<int> reused; - int bonus; - int onp; - }; - - - void MeshOptimize2d :: GenericImprove (Mesh & mesh) - { - if (!faceindex) - { - if (writestatus) - PrintMessage (3, "Generic Improve"); - - for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) - GenericImprove (mesh); - - faceindex = 0; - } - - // int j, k, l, ri; - int np = mesh.GetNP(); - int ne = mesh.GetNSE(); - // SurfaceElementIndex sei; - - bool ok; - int olddef, newdef; - - ARRAY<ImprovementRule*> rules; - ARRAY<SurfaceElementIndex> elmap; - ARRAY<int> elrot; - ARRAY<PointIndex> pmap; - ARRAY<PointGeomInfo> pgi; - - int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); - - ImprovementRule * r1; - - // 2 triangles to quad - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3)); - r1->oldels.Append (Element2d (3, 2, 4)); - r1->newels.Append (Element2d (1, 2, 4, 3)); - r1->deledges.Append (INDEX_2 (2,3)); - r1->onp = 4; - r1->bonus = 2; - rules.Append (r1); - - // 2 quad to 1 quad - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (4, 3, 2, 5)); - r1->newels.Append (Element2d (1, 2, 5, 4)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->deledges.Append (INDEX_2 (3, 4)); - r1->onp = 5; - r1->bonus = 0; - rules.Append (r1); - - // swap quads - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (3, 2, 5, 6)); - r1->newels.Append (Element2d (1, 6, 3, 4)); - r1->newels.Append (Element2d (1, 2, 5, 6)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->onp = 6; - r1->bonus = 0; - rules.Append (r1); - - // three quads to 2 - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 5, 6, 3)); - r1->oldels.Append (Element2d (3, 6, 7, 4)); - r1->newels.Append (Element2d (1, 2, 5, 4)); - r1->newels.Append (Element2d (4, 5, 6, 7)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->deledges.Append (INDEX_2 (3, 4)); - r1->deledges.Append (INDEX_2 (3, 6)); - r1->onp = 7; - r1->bonus = -1; - rules.Append (r1); - - // quad + 2 connected trigs to quad - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 5, 3)); - r1->oldels.Append (Element2d (3, 5, 4)); - r1->newels.Append (Element2d (1, 2, 5, 4)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->deledges.Append (INDEX_2 (3, 4)); - r1->deledges.Append (INDEX_2 (3, 5)); - r1->onp = 5; - r1->bonus = 0; - rules.Append (r1); - - // quad + 2 non-connected trigs to quad (a and b) - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 6, 3)); - r1->oldels.Append (Element2d (1, 4, 5)); - r1->newels.Append (Element2d (1, 3, 4, 5)); - r1->newels.Append (Element2d (1, 2, 6, 3)); - r1->deledges.Append (INDEX_2 (1, 4)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->onp = 6; - r1->bonus = 0; - rules.Append (r1); - - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 6, 3)); - r1->oldels.Append (Element2d (1, 4, 5)); - r1->newels.Append (Element2d (1, 2, 4, 5)); - r1->newels.Append (Element2d (4, 2, 6, 3)); - r1->deledges.Append (INDEX_2 (1, 4)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->onp = 6; - r1->bonus = 0; - rules.Append (r1); - - // two quad + trig -> one quad + trig - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 5, 6, 3)); - r1->oldels.Append (Element2d (4, 3, 6)); - r1->newels.Append (Element2d (1, 2, 6, 4)); - r1->newels.Append (Element2d (2, 5, 6)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->deledges.Append (INDEX_2 (3, 4)); - r1->deledges.Append (INDEX_2 (3, 6)); - r1->onp = 6; - r1->bonus = -1; - rules.Append (r1); - - // swap quad + trig (a and b) - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 5, 3)); - r1->newels.Append (Element2d (2, 5, 3, 4)); - r1->newels.Append (Element2d (1, 2, 4)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->onp = 5; - r1->bonus = 0; - rules.Append (r1); - - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (2, 5, 3)); - r1->newels.Append (Element2d (1, 2, 5, 3)); - r1->newels.Append (Element2d (1, 3, 4)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->onp = 5; - r1->bonus = 0; - rules.Append (r1); - - - // 2 quads to quad + 2 trigs - r1 = new ImprovementRule; - r1->oldels.Append (Element2d (1, 2, 3, 4)); - r1->oldels.Append (Element2d (3, 2, 5, 6)); - r1->newels.Append (Element2d (1, 5, 6, 4)); - r1->newels.Append (Element2d (1, 2, 5)); - r1->newels.Append (Element2d (4, 6, 3)); - r1->deledges.Append (INDEX_2 (2, 3)); - r1->onp = 6; - r1->bonus = 0; - // rules.Append (r1); - - - - - ARRAY<int> mapped(rules.Size()); - ARRAY<int> used(rules.Size()); - used = 0; - mapped = 0; - - - - for (int ri = 0; ri < rules.Size(); ri++) - { - ImprovementRule & rule = *rules[ri]; - rule.incelsonnode.SetSize (rule.onp); - rule.reused.SetSize (rule.onp); - - for (int j = 1; j <= rule.onp; j++) - { - rule.incelsonnode.Elem(j) = 0; - rule.reused.Elem(j) = 0; - } - - for (int j = 1; j <= rule.oldels.Size(); j++) - { - const Element2d & el = rule.oldels.Elem(j); - for (int k = 1; k <= el.GetNP(); k++) - rule.incelsonnode.Elem(el.PNum(k))--; - } - - for (int j = 1; j <= rule.newels.Size(); j++) - { - const Element2d & el = rule.newels.Elem(j); - for (int k = 1; k <= el.GetNP(); k++) - { - rule.incelsonnode.Elem(el.PNum(k))++; - rule.reused.Elem(el.PNum(k)) = 1; - } - } - } - - - - - TABLE<int,PointIndex::BASE> elonnode(np); - ARRAY<int,PointIndex::BASE> nelonnode(np); - TABLE<SurfaceElementIndex> nbels(ne); - - nelonnode = -4; - - for (SurfaceElementIndex sei = 0; sei < ne; sei++) - { - const Element2d & el = mesh[sei]; - if (el.GetIndex() == faceindex && !el.IsDeleted()) - { - for (int j = 0; j < el.GetNP(); j++) - elonnode.Add (el[j], sei); - } - for (int j = 0; j < el.GetNP(); j++) - nelonnode[el[j]]++; - } - - for (SurfaceElementIndex sei = 0; sei < ne; sei++) - { - const Element2d & el = mesh[sei]; - if (el.GetIndex() == faceindex && !el.IsDeleted()) - { - for (int j = 0; j < el.GetNP(); j++) - { - for (int k = 0; k < elonnode[el[j]].Size(); k++) - { - int nbel = elonnode[el[j]] [k]; - int used = 0; - for (int l = 0; l < nbels[sei].Size(); l++) - if (nbels[sei][l] == nbel) - used = 1; - if (!used) - nbels.Add (sei, nbel); - } - } - } - } - - - for (int ri = 0; ri < rules.Size(); ri++) - { - const ImprovementRule & rule = *rules[ri]; - - elmap.SetSize (rule.oldels.Size()); - elrot.SetSize (rule.oldels.Size()); - pmap.SetSize (rule.onp); - pgi.SetSize (rule.onp); - - - for (SurfaceElementIndex sei = 0; sei < ne; sei++) - { - if (multithread.terminate) - break; - if (mesh[sei].IsDeleted()) continue; - - elmap[0] = sei; - FlatArray<SurfaceElementIndex> neighbours = nbels[sei]; - - for (elrot[0] = 0; elrot[0] < mesh[sei].GetNP(); elrot[0]++) - { - const Element2d & el0 = mesh[sei]; - const Element2d & rel0 = rule.oldels[0]; - - if (el0.GetIndex() != faceindex) continue; - if (el0.IsDeleted()) continue; - if (el0.GetNP() != rel0.GetNP()) continue; - - - pmap = -1; - - for (int k = 0; k < el0.GetNP(); k++) - { - pmap.Elem(rel0[k]) = el0.PNumMod(k+elrot[0]+1); - pgi.Elem(rel0[k]) = el0.GeomInfoPiMod(k+elrot[0]+1); - } - - ok = 1; - for (int i = 1; i < elmap.Size(); i++) - { - // try to find a mapping for reference-element i - - const Element2d & rel = rule.oldels[i]; - bool possible = 0; - - for (elmap[i] = 0; elmap[i] < neighbours.Size(); elmap[i]++) - { - const Element2d & el = mesh[neighbours[elmap[i]]]; - if (el.IsDeleted()) continue; - if (el.GetNP() != rel.GetNP()) continue; - - for (elrot[i] = 0; elrot[i] < rel.GetNP(); elrot[i]++) - { - possible = 1; - - for (int k = 0; k < rel.GetNP(); k++) - if (pmap.Elem(rel[k]) != -1 && - pmap.Elem(rel[k]) != el.PNumMod (k+elrot[i]+1)) - possible = 0; - - if (possible) - { - for (int k = 0; k < el.GetNP(); k++) - { - pmap.Elem(rel[k]) = el.PNumMod(k+elrot[i]+1); - pgi.Elem(rel[k]) = el.GeomInfoPiMod(k+elrot[i]+1); - } - break; - } - } - if (possible) break; - } - - if (!possible) - { - ok = 0; - break; - } - - elmap[i] = neighbours[elmap[i]]; - } - - for(int i=0; ok && i<rule.deledges.Size(); i++) - { - ok = !mesh.IsSegment(pmap.Elem(rule.deledges[i].I1()), - pmap.Elem(rule.deledges[i].I2())); - } - - - - - if (!ok) continue; - - mapped[ri]++; - - olddef = 0; - for (int j = 1; j <= pmap.Size(); j++) - olddef += sqr (nelonnode[pmap.Get(j)]); - olddef += rule.bonus; - - newdef = 0; - for (int j = 1; j <= pmap.Size(); j++) - if (rule.reused.Get(j)) - newdef += sqr (nelonnode[pmap.Get(j)] + - rule.incelsonnode.Get(j)); - - if (newdef > olddef) - continue; - - // calc metric badness - double bad1 = 0, bad2 = 0; - Vec3d n; - - SelectSurfaceOfPoint (mesh.Point(pmap.Get(1)), pgi.Get(1)); - GetNormalVector (surfnr, mesh.Point(pmap.Get(1)), pgi.Elem(1), n); - - for (int j = 1; j <= rule.oldels.Size(); j++) - bad1 += mesh.SurfaceElement(elmap.Get(j)).CalcJacobianBadness (mesh.Points(), n); - - // check new element: - for (int j = 1; j <= rule.newels.Size(); j++) - { - const Element2d & rnel = rule.newels.Get(j); - Element2d nel(rnel.GetNP()); - for (int k = 1; k <= rnel.GetNP(); k++) - nel.PNum(k) = pmap.Get(rnel.PNum(k)); - - bad2 += nel.CalcJacobianBadness (mesh.Points(), n); - } - - if (bad2 > 1e3) continue; - - if (newdef == olddef && bad2 > bad1) continue; - - - // generate new element: - for (int j = 1; j <= rule.newels.Size(); j++) - { - const Element2d & rnel = rule.newels.Get(j); - Element2d nel(rnel.GetNP()); - nel.SetIndex (faceindex); - for (int k = 1; k <= rnel.GetNP(); k++) - { - nel.PNum(k) = pmap.Get(rnel.PNum(k)); - nel.GeomInfoPi(k) = pgi.Get(rnel.PNum(k)); - } - - mesh.AddSurfaceElement(nel); - } - - for (int j = 0; j < rule.oldels.Size(); j++) - mesh.DeleteSurfaceElement ( elmap[j] ); - - for (int j = 1; j <= pmap.Size(); j++) - nelonnode[pmap.Get(j)] += rule.incelsonnode.Get(j); - - used[ri]++; - } - } - } - - mesh.Compress(); - - for (int ri = 0; ri < rules.Size(); ri++) - { - PrintMessage (5, "rule ", ri+1, " ", - mapped[ri], "/", used[ri], " mapped/used"); - } - } - - - - -} diff --git a/Netgen/libsrc/meshing/improve3.cpp b/Netgen/libsrc/meshing/improve3.cpp deleted file mode 100644 index 1b9c8c52f6..0000000000 --- a/Netgen/libsrc/meshing/improve3.cpp +++ /dev/null @@ -1,1947 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - -#ifdef SOLIDGEOM -#include <csg.hpp> -#endif -#include <opti.hpp> - -namespace netgen -{ - -/* - Combine two points to one. - Set new point into the center, if both are - inner points. - Connect inner point to boundary point, if one - point is inner point. -*/ - -void MeshOptimize3d :: CombineImprove (Mesh & mesh, - OPTIMIZEGOAL goal) -{ - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - - TABLE<ElementIndex, PointIndex::BASE> elementsonnode(np); - ARRAY<ElementIndex> hasonepi, hasbothpi; - - ARRAY<double> oneperr; - ARRAY<double> elerrs (ne); - - PrintMessage (3, "CombineImprove"); - (*testout) << "Start CombineImprove" << "\n"; - - // mesh.CalcSurfacesOfNode (); - char * savetask = multithread.task; - multithread.task = "Combine Improve"; - - - double totalbad = 0; - for (ElementIndex ei = 0; ei < ne; ei++) - { - double elerr = CalcBad (mesh.Points(), mesh[ei], 0); - totalbad += elerr; - elerrs[ei] = elerr; - } - - if (goal == OPT_QUALITY) - { - totalbad = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << totalbad << endl; - PrintMessage (5, "Total badness = ", totalbad); - } - - for (ElementIndex ei = 0; ei < ne; ei++) - if (!mesh[ei].IsDeleted()) - for (int j = 0; j < mesh[ei].GetNP(); j++) - elementsonnode.Add (mesh[ei][j], ei); - - INDEX_2_HASHTABLE<int> edgetested (np+1); - - int cnt = 0; - - for (ElementIndex ei = 0; ei < ne; ei++) - { - if (multithread.terminate) - break; - - multithread.percent = 100.0 * (ei+1) / ne; - - if (mesh.ElementType(ei) == FIXEDELEMENT) - continue; - - for (int j = 0; j < 6; j++) - { - Element & elemi = mesh[ei]; - if (elemi.IsDeleted()) continue; - - static const int tetedges[6][2] = - { { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 1, 2 }, { 1, 3 }, { 2, 3 } }; - - PointIndex pi1 = elemi[tetedges[j][0]]; - PointIndex pi2 = elemi[tetedges[j][1]]; - - if (pi2 < pi1) Swap (pi1, pi2); - - INDEX_2 si2 (pi1, pi2); - si2.Sort(); - - if (edgetested.Used (si2)) continue; - edgetested.Set (si2, 1); - - - // hasonepoint.SetSize(0); - // hasbothpoints.SetSize(0); - hasonepi.SetSize(0); - hasbothpi.SetSize(0); - - FlatArray<ElementIndex> row1 = elementsonnode[pi1]; - for (int k = 0; k < row1.Size(); k++) - { - Element & elem = mesh[row1[k]]; - if (elem.IsDeleted()) continue; - - if (elem[0] == pi2 || elem[1] == pi2 || - elem[2] == pi2 || elem[3] == pi2) - { - hasbothpi.Append (row1[k]); - } - else - { - hasonepi.Append (row1[k]); - } - } - - FlatArray<ElementIndex> row2 = elementsonnode[pi2]; - for (int k = 0; k < row2.Size(); k++) - { - Element & elem = mesh[row2[k]]; - if (elem.IsDeleted()) continue; - - if (elem[0] == pi1 || elem[1] == pi1 || - elem[2] == pi1 || elem[3] == pi1) - ; - else - { - hasonepi.Append (row2[k]); - } - } - - double bad1 = 0; - for (int k = 0; k < hasonepi.Size(); k++) - bad1 += elerrs[hasonepi[k]]; - for (int k = 0; k < hasbothpi.Size(); k++) - bad1 += elerrs[hasbothpi[k]]; - - MeshPoint p1 = mesh[pi1]; - MeshPoint p2 = mesh[pi2]; - - // if (mesh.PointType(pi2) != INNERPOINT) - if (p2.Type() != INNERPOINT) - continue; - - MeshPoint pnew; - // if (mesh.PointType(pi1) != INNERPOINT) - if (p1.Type() != INNERPOINT) - pnew = p1; - else - pnew = Center (p1, p2); - - mesh[pi1] = pnew; - mesh[pi2] = pnew; - - oneperr.SetSize (hasonepi.Size()); - - double bad2 = 0; - for (int k = 0; k < hasonepi.Size(); k++) - { - const Element & elem = mesh[hasonepi[k]]; - double err = CalcTetBadness (mesh[elem[0]], mesh[elem[1]], - mesh[elem[2]], mesh[elem[3]], 0); - bad2 += err; - oneperr[k] = err; - } - - mesh[pi1] = p1; - mesh[pi2] = p2; - - - // if (mesh.PointType(pi1) != INNERPOINT) - if (p1.Type() != INNERPOINT) - { - for (int k = 0; k < hasonepi.Size(); k++) - { - Element & elem = mesh[hasonepi[k]]; - int l; - for (l = 0; l < 4; l++) - if (elem[l] == pi2) - { - elem[l] = pi1; - break; - } - - elem.flags.illegal_valid = 0; - if (!mesh.LegalTet(elem)) - bad2 += 1e4; - - if (l < 4) - { - elem.flags.illegal_valid = 0; - elem[l] = pi2; - } - } - } - - if (bad2 / hasonepi.Size() < - bad1 / (hasonepi.Size()+hasbothpi.Size())) - { - mesh[pi1] = pnew; - cnt++; - - FlatArray<ElementIndex> row = elementsonnode[pi2]; - for (int k = 0; k < row.Size(); k++) - { - Element & elem = mesh[row[k]]; - if (elem.IsDeleted()) continue; - - elementsonnode.Add (pi1, row[k]); - for (int l = 0; l < elem.GetNP(); l++) - if (elem[l] == pi2) - elem[l] = pi1; - - elem.flags.illegal_valid = 0; - if (!mesh.LegalTet (elem)) - (*testout) << "illegal tet " << elementsonnode[pi2][k] << endl; - } - - for (int k = 0; k < hasonepi.Size(); k++) - elerrs[hasonepi[k]] = oneperr[k]; - - for (int k = 0; k < hasbothpi.Size(); k++) - { - mesh[hasbothpi[k]].flags.illegal_valid = 0; - mesh[hasbothpi[k]].Delete(); - } - } - } - } - - mesh.Compress(); - mesh.MarkIllegalElements(); - - PrintMessage (5, cnt, " elements combined"); - (*testout) << "CombineImprove done" << "\n"; - - totalbad = 0; - for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) - totalbad += CalcBad (mesh.Points(), mesh[ei], 0); - - if (goal == OPT_QUALITY) - { - totalbad = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << totalbad << endl; - - int cntill = 0; - int ne = mesh.GetNE(); - for (ElementIndex ei = 0; ei < ne; ei++) - if (!mesh.LegalTet (mesh[ei])) - cntill++; - - PrintMessage (5, cntill, " illegal tets"); - } - multithread.task = savetask; -} - - - - - -/* - Mesh improvement by edge splitting. - If mesh quality is improved by inserting a node into an inner edge, - the edge is split into two parts. -*/ -void MeshOptimize3d :: SplitImprove (Mesh & mesh, - OPTIMIZEGOAL goal) -{ - int j, k, l; - Point3d p1, p2, pnew; - - ElementIndex ei; - SurfaceElementIndex sei; - PointIndex pi1, pi2; - - double bad1, bad2, badmax, badlimit; - - - int cnt = 0; - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - - TABLE<ElementIndex,PointIndex::BASE> elementsonnode(np); - ARRAY<ElementIndex> hasbothpoints; - - BitArray origpoint(np), boundp(np); - origpoint.Set(); - - ARRAY<double> elerrs(ne); - BitArray illegaltet(ne); - illegaltet.Clear(); - - char * savetask = multithread.task; - multithread.task = "Split Improve"; - - - PrintMessage (3, "SplitImprove"); - (*testout) << "start SplitImprove" << "\n"; - - ARRAY<INDEX_3> locfaces; - - INDEX_2_HASHTABLE<int> edgetested (np); - - bad1 = 0; - badmax = 0; - for (ei = 0; ei < ne; ei++) - { - elerrs[ei] = CalcBad (mesh.Points(), mesh[ei], 0); - bad1 += elerrs[ei]; - if (elerrs[ei] > badmax) badmax = elerrs[ei]; - } - - PrintMessage (5, "badmax = ", badmax); - badlimit = 0.5 * badmax; - - - boundp.Clear(); - for (sei = 0; sei < mesh.GetNSE(); sei++) - for (j = 0; j < 3; j++) - boundp.Set (mesh[sei][j]); - - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << bad1 << endl; - } - - for (ei = 0; ei < ne; ei++) - for (j = 0; j < mesh[ei].GetNP(); j++) - elementsonnode.Add (mesh[ei][j], ei); - - - mesh.MarkIllegalElements(); - if (goal == OPT_QUALITY || goal == OPT_LEGAL) - { - int cntill = 0; - for (ei = 0; ei < ne; ei++) - { - // if (!LegalTet (volelements.Get(i))) - if (mesh[ei].flags.illegal) - { - cntill++; - illegaltet.Set (ei+1); - } - } - // (*mycout) << cntill << " illegal tets" << endl; - } - - - for (ei = 0; ei < ne; ei++) - { - if (multithread.terminate) - break; - - multithread.percent = 100.0 * (ei+1) / ne; - - bool ltestmode = 0; - - - if (elerrs[ei] < badlimit && !illegaltet.Test(ei+1)) continue; - - if ((goal == OPT_LEGAL) && - !illegaltet.Test(ei+1) && - CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) - continue; - - - Element & elem = mesh[ei]; - - if (ltestmode) - { - (*testout) << "test el " << ei << endl; - for (j = 0; j < 4; j++) - (*testout) << elem[j] << " "; - (*testout) << endl; - } - - - for (j = 0; j < 6; j++) - { - - static const int tetedges[6][2] = - { { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 1, 2 }, { 1, 3 }, { 2, 3 } }; - - pi1 = elem[tetedges[j][0]]; - pi2 = elem[tetedges[j][1]]; - - if (pi2 < pi1) Swap (pi1, pi2); - if (pi2 > elementsonnode.Size()) continue; - - if (!origpoint.Test(pi1) || !origpoint.Test(pi2)) - continue; - - - INDEX_2 i2(pi1, pi2); - i2.Sort(); - - if (mesh.BoundaryEdge (pi1, pi2)) continue; - - if (edgetested.Used (i2) && !illegaltet.Test(ei+1)) continue; - edgetested.Set (i2, 1); - - hasbothpoints.SetSize (0); - for (k = 1; k <= elementsonnode.EntrySize(pi1); k++) - { - bool has1 = 0, has2 = 0; - - ElementIndex elnr = elementsonnode.Get(pi1, k); - Element & el = mesh[elnr]; - - for (l = 0; l < el.GetNP(); l++) - { - if (el[l] == pi1) has1 = 1; - if (el[l] == pi2) has2 = 1; - } - if (has1 && has2) - { // only once - for (l = 0; l < hasbothpoints.Size(); l++) - if (hasbothpoints[l] == elnr) - has1 = 0; - - if (has1) - hasbothpoints.Append (elnr); - } - } - - bad1 = 0; - for (k = 0; k < hasbothpoints.Size(); k++) - bad1 += CalcBad (mesh.Points(), mesh[hasbothpoints[k]], 0); - - - bool puretet = 1; - for (k = 0; k < hasbothpoints.Size(); k++) - if (mesh[hasbothpoints[k]].GetType() != TET) - puretet = 0; - if (!puretet) continue; - - p1 = mesh[pi1]; - p2 = mesh[pi2]; - - /* - pnew = Center (p1, p2); - - points.Elem(pi1) = pnew; - bad2 = 0; - for (k = 1; k <= hasbothpoints.Size(); k++) - bad2 += CalcBad (points, - volelements.Get(hasbothpoints.Get(k)), 0); - - points.Elem(pi1) = p1; - points.Elem(pi2) = pnew; - - for (k = 1; k <= hasbothpoints.Size(); k++) - bad2 += CalcBad (points, - volelements.Get(hasbothpoints.Get(k)), 0); - points.Elem(pi2) = p2; - */ - - - locfaces.SetSize (0); - for (k = 0; k < hasbothpoints.Size(); k++) - { - const Element & el = mesh[hasbothpoints[k]]; - - for (int l = 0; l < 4; l++) - if (el[l] == pi1 || el[l] == pi2) - { - INDEX_3 i3; - Element2d face; - el.GetFace (l+1, face); - for (int kk = 1; kk <= 3; kk++) - i3.I(kk) = face.PNum(kk); - locfaces.Append (i3); - } - } - - PointFunction1 pf (mesh.Points(), locfaces, -1); - OptiParameters par; - par.maxit_linsearch = 50; - par.maxit_bfgs = 20; - - pnew = Center (p1, p2); - Vector px(3); - px.Elem(1) = pnew.X(); - px.Elem(2) = pnew.Y(); - px.Elem(3) = pnew.Z(); - - if (elerrs[ei] > 0.1 * badmax) - BFGS (px, pf, par); - - bad2 = pf.Func (px); - - pnew.X() = px.Get(1); - pnew.Y() = px.Get(2); - pnew.Z() = px.Get(3); - - - int hpinew = mesh.AddPoint (pnew); - // ptyps.Append (INNERPOINT); - - for (k = 0; k < hasbothpoints.Size(); k++) - { - Element & oldel = mesh[hasbothpoints[k]]; - Element newel1 = oldel; - Element newel2 = oldel; - - oldel.flags.illegal_valid = 0; - newel1.flags.illegal_valid = 0; - newel2.flags.illegal_valid = 0; - - for (l = 0; l < 4; l++) - { - if (newel1[l] == pi2) newel1[l] = hpinew; - if (newel2[l] == pi1) newel2[l] = hpinew; - } - - if (!mesh.LegalTet (oldel)) bad1 += 1e6; - if (!mesh.LegalTet (newel1)) bad2 += 1e6; - if (!mesh.LegalTet (newel2)) bad2 += 1e6; - } - - // mesh.PointTypes().DeleteLast(); - mesh.Points().DeleteLast(); - - if (bad2 < bad1) - /* (bad1 > 1e4 && boundp.Test(pi1) && boundp.Test(pi2)) */ - { - cnt++; - - PointIndex pinew = mesh.AddPoint (pnew); - - for (k = 0; k < hasbothpoints.Size(); k++) - { - Element & oldel = mesh[hasbothpoints[k]]; - Element newel = oldel; - - newel.flags.illegal_valid = 0; - oldel.flags.illegal_valid = 0; - - for (l = 0; l < 4; l++) - { - origpoint.Clear (oldel[l]); - - if (oldel[l] == pi2) oldel[l] = pinew; - if (newel[l] == pi1) newel[l] = pinew; - } - mesh.AddVolumeElement (newel); - } - - j = 10; - } - } - } - - - mesh.Compress(); - PrintMessage (5, cnt, " splits performed"); - - (*testout) << "Splitt - Improve done" << "\n"; - - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << bad1 << endl; - - int cntill = 0; - ne = mesh.GetNE(); - for (ei = 0; ei < ne; ei++) - { - if (!mesh.LegalTet (mesh[ei])) - cntill++; - } - // cout << cntill << " illegal tets" << endl; - } - - multithread.task = savetask; -} - - - - - -void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal) -{ - int j, k, l; - - ElementIndex ei; - SurfaceElementIndex sei; - - PointIndex pi1, pi2, pi3, pi4, pi5, pi6; - int cnt = 0; - - Element el21(TET), el22(TET), el31(TET), el32(TET), el33(TET); - Element el1(TET), el2(TET), el3(TET), el4(TET); - Element el1b(TET), el2b(TET), el3b(TET), el4b(TET); - - double bad1, bad2, bad3; - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - - - // contains at least all elements at node - TABLE<ElementIndex,PointIndex::BASE> elementsonnode(np); - - ARRAY<ElementIndex> hasbothpoints; - - PrintMessage (3, "SwapImprove "); - (*testout) << "\n" << "Start SwapImprove" << endl; - - char * savetask = multithread.task; - multithread.task = "Swap Improve"; - - // mesh.CalcSurfacesOfNode (); - /* - for (i = 1; i <= GetNE(); i++) - if (volelements.Get(i).PNum(1)) - if (!LegalTet (volelements.Get(i))) - { - cout << "detected illegal tet, 1" << endl; - (*testout) << "detected illegal tet1: " << i << endl; - } - */ - - - INDEX_3_HASHTABLE<int> faces(mesh.GetNOpenElements()/3 + 2); - if (goal == OPT_CONFORM) - { - for (int i = 1; i <= mesh.GetNOpenElements(); i++) - { - const Element2d & hel = mesh.OpenElement(i); - INDEX_3 face(hel[0], hel[1], hel[2]); - face.Sort(); - faces.Set (face, 1); - } - } - - // Calculate total badness - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << bad1 << endl; - } - - // find elements on node - for (ei = 0; ei < ne; ei++) - for (j = 0; j < mesh[ei].GetNP(); j++) - elementsonnode.Add (mesh[ei][j], ei); - - /* - BitArray illegaltet(GetNE()); - MarkIllegalElements(); - if (goal == OPT_QUALITY || goal == OPT_LEGAL) - { - int cntill = 0; - for (i = 1; i <= GetNE(); i++) - { - // if (!LegalTet (volelements.Get(i))) - if (VolumeElement(i).flags.illegal) - { - cntill++; - illegaltet.Set (i); - } - } - // (*mycout) << cntill << " illegal tets" << endl; - } - */ - - INDEX_2_HASHTABLE<int> edgeused(2 * ne + 5); - - for (ei = 0; ei < ne; ei++) - { - if (multithread.terminate) - break; - - multithread.percent = 100.0 * (ei+1) / ne; - - if (mesh.ElementType(ei) == FIXEDELEMENT) - continue; - - if (mesh[ei].IsDeleted()) - continue; - - if ((goal == OPT_LEGAL) && - mesh.LegalTet (mesh[ei]) && - CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) - continue; - - - // int onlybedges = 1; - - for (j = 0; j < 6; j++) - { - // loop over edges - - const Element & elemi = mesh[ei]; - if (elemi.IsDeleted()) continue; - - - // (*testout) << "check element " << elemi << endl; - - int mattyp = elemi.GetIndex(); - - static const int tetedges[6][2] = - { { 0, 1 }, { 0, 2 }, { 0, 3 }, - { 1, 2 }, { 1, 3 }, { 2, 3 } }; - - pi1 = elemi[tetedges[j][0]]; - pi2 = elemi[tetedges[j][1]]; - - if (pi2 < pi1) Swap (pi1, pi2); - - if (mesh.BoundaryEdge (pi1, pi2)) continue; - - - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - if (edgeused.Used(i2)) continue; - edgeused.Set (i2, 1); - - hasbothpoints.SetSize (0); - for (k = 0; k < elementsonnode[pi1].Size(); k++) - { - bool has1 = 0, has2 = 0; - ElementIndex elnr = elementsonnode[pi1][k]; - const Element & elem = mesh[elnr]; - - if (elem.IsDeleted()) continue; - - for (l = 0; l < elem.GetNP(); l++) - { - if (elem[l] == pi1) has1 = 1; - if (elem[l] == pi2) has2 = 1; - } - - if (has1 && has2) - { // only once - for (l = 0; l < hasbothpoints.Size(); l++) - if (hasbothpoints[l] == elnr) - has1 = 0; - - if (has1) - hasbothpoints.Append (elnr); - } - } - - bool puretet = 1; - for (k = 0; k < hasbothpoints.Size(); k++) - if (mesh[hasbothpoints[k]].GetType () != TET) - puretet = 0; - if (!puretet) - continue; - - int nsuround = hasbothpoints.Size(); - - if ( nsuround == 3 ) - { - Element & elem = mesh[hasbothpoints[0]]; - for (l = 0; l < 4; l++) - if (elem[l] != pi1 && elem[l] != pi2) - { - pi4 = pi3; - pi3 = elem[l]; - } - - el31[0] = pi1; - el31[1] = pi2; - el31[2] = pi3; - el31[3] = pi4; - el31.SetIndex (mattyp); - - if (WrongOrientation (mesh.Points(), el31)) - { - Swap (pi3, pi4); - el31[2] = pi3; - el31[3] = pi4; - } - - pi5 = 0; - for (k = 1; k < 3; k++) - { - const Element & elem = mesh[hasbothpoints[k]]; - bool has1 = 0; - for (l = 0; l < 4; l++) - if (elem[l] == pi4) - has1 = 1; - if (has1) - { - for (l = 0; l < 4; l++) - if (elem[l] != pi1 && elem[l] != pi2 && elem[l] != pi4) - pi5 = elem[l]; - } - } - - el32[0] = pi1; - el32[1] = pi2; - el32[2] = pi4; - el32[3] = pi5; - el32.SetIndex (mattyp); - - el33[0] = pi1; - el33[1] = pi2; - el33[2] = pi5; - el33[3] = pi3; - el33.SetIndex (mattyp); - - elementsonnode.Add (pi4, hasbothpoints[1]); - elementsonnode.Add (pi3, hasbothpoints[2]); - - bad1 = CalcBad (mesh.Points(), el31, 0) + - CalcBad (mesh.Points(), el32, 0) + - CalcBad (mesh.Points(), el33, 0); - - el31.flags.illegal_valid = 0; - el32.flags.illegal_valid = 0; - el33.flags.illegal_valid = 0; - - if (!mesh.LegalTet(el31) || - !mesh.LegalTet(el32) || - !mesh.LegalTet(el33)) - bad1 += 1e4; - - el21[0] = pi3; - el21[1] = pi4; - el21[2] = pi5; - el21[3] = pi2; - el21.SetIndex (mattyp); - - el22[0] = pi5; - el22[1] = pi4; - el22[2] = pi3; - el22[3] = pi1; - el22.SetIndex (mattyp); - - bad2 = CalcBad (mesh.Points(), el21, 0) + - CalcBad (mesh.Points(), el22, 0); - - el21.flags.illegal_valid = 0; - el22.flags.illegal_valid = 0; - - if (!mesh.LegalTet(el21) || - !mesh.LegalTet(el22)) - bad2 += 1e4; - - - if (goal == OPT_CONFORM && bad2 < 1e4) - { - INDEX_3 face(pi3, pi4, pi5); - face.Sort(); - if (faces.Used(face)) - { - // (*testout) << "3->2 swap, could improve conformity, bad1 = " << bad1 - // << ", bad2 = " << bad2 << endl; - if (bad2 < 1e4) - bad1 = 2 * bad2; - } - /* - else - { - INDEX_2 hi1(pi3, pi4); - hi1.Sort(); - INDEX_2 hi2(pi3, pi5); - hi2.Sort(); - INDEX_2 hi3(pi4, pi5); - hi3.Sort(); - - if (boundaryedges->Used (hi1) || - boundaryedges->Used (hi2) || - boundaryedges->Used (hi3) ) - bad1 = 2 * bad2; - } - */ - } - - if (bad2 < bad1) - { - // (*mycout) << "3->2 " << flush; - // (*testout) << "3->2 conversion" << endl; - cnt++; - - - /* - (*testout) << "3->2 swap, old els = " << endl - << mesh[hasbothpoints[0]] << endl - << mesh[hasbothpoints[1]] << endl - << mesh[hasbothpoints[2]] << endl - << "new els = " << endl - << el21 << endl - << el22 << endl; - */ - - - el21.flags.illegal_valid = 0; - el22.flags.illegal_valid = 0; - mesh[hasbothpoints[0]] = el21; - mesh[hasbothpoints[1]] = el22; - for (l = 0; l < 4; l++) - mesh[hasbothpoints[2]][l] = 0; - mesh[hasbothpoints[2]].Delete(); - - for (k = 0; k < 2; k++) - for (l = 0; l < 4; l++) - elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]); - } - } - - - if (nsuround == 4) - { - const Element & elem1 = mesh[hasbothpoints[0]]; - for (l = 0; l < 4; l++) - if (elem1[l] != pi1 && elem1[l] != pi2) - { - pi4 = pi3; - pi3 = elem1[l]; - } - - el1[0] = pi1; el1[1] = pi2; - el1[2] = pi3; el1[3] = pi4; - el1.SetIndex (mattyp); - - if (WrongOrientation (mesh.Points(), el1)) - { - Swap (pi3, pi4); - el1[2] = pi3; - el1[3] = pi4; - } - - pi5 = 0; - for (k = 1; k < 4; k++) - { - const Element & elem = mesh[hasbothpoints[k]]; - bool has1 = 0; - for (l = 0; l < 4; l++) - if (elem[l] == pi4) - has1 = 1; - if (has1) - { - for (l = 0; l < 4; l++) - if (elem[l] != pi1 && elem[l] != pi2 && elem[l] != pi4) - pi5 = elem[l]; - } - } - - pi6 = 0; - for (k = 1; k < 4; k++) - { - const Element & elem = mesh[hasbothpoints[k]]; - bool has1 = 0; - for (l = 0; l < 4; l++) - if (elem[l] == pi3) - has1 = 1; - if (has1) - { - for (l = 0; l < 4; l++) - if (elem[l] != pi1 && elem[l] != pi2 && elem[l] != pi3) - pi6 = elem[l]; - } - } - - /* - INDEX_2 i22(pi3, pi5); - i22.Sort(); - INDEX_2 i23(pi4, pi6); - i23.Sort(); - */ - - el1[0] = pi1; el1[1] = pi2; - el1[2] = pi3; el1[3] = pi4; - el1.SetIndex (mattyp); - - el2[0] = pi1; el2[1] = pi2; - el2[2] = pi4; el2[3] = pi5; - el2.SetIndex (mattyp); - - el3[0] = pi1; el3[1] = pi2; - el3[2] = pi5; el3[3] = pi6; - el3.SetIndex (mattyp); - - el4[0] = pi1; el4[1] = pi2; - el4[2] = pi6; el4[3] = pi3; - el4.SetIndex (mattyp); - - // elementsonnode.Add (pi4, hasbothpoints.Elem(2)); - // elementsonnode.Add (pi3, hasbothpoints.Elem(3)); - - bad1 = CalcBad (mesh.Points(), el1, 0) + - CalcBad (mesh.Points(), el2, 0) + - CalcBad (mesh.Points(), el3, 0) + - CalcBad (mesh.Points(), el4, 0); - - - el1.flags.illegal_valid = 0; - el2.flags.illegal_valid = 0; - el3.flags.illegal_valid = 0; - el4.flags.illegal_valid = 0; - - - if (goal != OPT_CONFORM) - { - if (!mesh.LegalTet(el1) || - !mesh.LegalTet(el2) || - !mesh.LegalTet(el3) || - !mesh.LegalTet(el4)) - bad1 += 1e4; - } - - el1[0] = pi3; el1[1] = pi5; - el1[2] = pi2; el1[3] = pi4; - el1.SetIndex (mattyp); - - el2[0] = pi3; el2[1] = pi5; - el2[2] = pi4; el2[3] = pi1; - el2.SetIndex (mattyp); - - el3[0] = pi3; el3[1] = pi5; - el3[2] = pi1; el3[3] = pi6; - el3.SetIndex (mattyp); - - el4[0] = pi3; el4[1] = pi5; - el4[2] = pi6; el4[3] = pi2; - el4.SetIndex (mattyp); - - bad2 = CalcBad (mesh.Points(), el1, 0) + - CalcBad (mesh.Points(), el2, 0) + - CalcBad (mesh.Points(), el3, 0) + - CalcBad (mesh.Points(), el4, 0); - - el1.flags.illegal_valid = 0; - el2.flags.illegal_valid = 0; - el3.flags.illegal_valid = 0; - el4.flags.illegal_valid = 0; - - if (goal != OPT_CONFORM) - { - if (!mesh.LegalTet(el1) || - !mesh.LegalTet(el2) || - !mesh.LegalTet(el3) || - !mesh.LegalTet(el4)) - bad2 += 1e4; - } - - - el1b[0] = pi4; el1b[1] = pi6; - el1b[2] = pi3; el1b[3] = pi2; - el1b.SetIndex (mattyp); - - el2b[0] = pi4; el2b[1] = pi6; - el2b[2] = pi2; el2b[3] = pi5; - el2b.SetIndex (mattyp); - - el3b[0] = pi4; el3b[1] = pi6; - el3b[2] = pi5; el3b[3] = pi1; - el3b.SetIndex (mattyp); - - el4b[0] = pi4; el4b[1] = pi6; - el4b[2] = pi1; el4b[3] = pi3; - el4b.SetIndex (mattyp); - - bad3 = CalcBad (mesh.Points(), el1b, 0) + - CalcBad (mesh.Points(), el2b, 0) + - CalcBad (mesh.Points(), el3b, 0) + - CalcBad (mesh.Points(), el4b, 0); - - el1b.flags.illegal_valid = 0; - el2b.flags.illegal_valid = 0; - el3b.flags.illegal_valid = 0; - el4b.flags.illegal_valid = 0; - - if (goal != OPT_CONFORM) - { - if (!mesh.LegalTet(el1b) || - !mesh.LegalTet(el2b) || - !mesh.LegalTet(el3b) || - !mesh.LegalTet(el4b)) - bad3 += 1e4; - } - - - /* - int swap2 = (bad2 < bad1) && (bad2 < bad3); - int swap3 = !swap2 && (bad3 < bad1); - - if ( ((bad2 < 10 * bad1) || - (bad2 < 1e6)) && mesh.BoundaryEdge (pi3, pi5)) - swap2 = 1; - else if ( ((bad3 < 10 * bad1) || - (bad3 < 1e6)) && mesh.BoundaryEdge (pi4, pi6)) - { - swap3 = 1; - swap2 = 0; - } - */ - bool swap2, swap3; - - if (goal != OPT_CONFORM) - { - swap2 = (bad2 < bad1) && (bad2 < bad3); - swap3 = !swap2 && (bad3 < bad1); - } - else - { - if (mesh.BoundaryEdge (pi3, pi5)) bad2 /= 1e6; - if (mesh.BoundaryEdge (pi4, pi6)) bad3 /= 1e6; - - swap2 = (bad2 < bad1) && (bad2 < bad3); - swap3 = !swap2 && (bad3 < bad1); - } - - - if (swap2 || swap3) - { - // (*mycout) << "4->4 " << flush; - cnt++; - // (*testout) << "4->4 conversion" << "\n"; - /* - (*testout) << "bad1 = " << bad1 - << " bad2 = " << bad2 - << " bad3 = " << bad3 << "\n"; - - (*testout) << "Points: " << pi1 << " " << pi2 << " " << pi3 - << " " << pi4 << " " << pi5 << " " << pi6 << "\n"; - (*testout) << "Elements: " - << hasbothpoints.Get(1) << " " - << hasbothpoints.Get(2) << " " - << hasbothpoints.Get(3) << " " - << hasbothpoints.Get(4) << " " << "\n"; - */ - - /* - { - int i1, j1; - for (i1 = 1; i1 <= 4; i1++) - { - for (j1 = 1; j1 <= 4; j1++) - (*testout) << volelements.Get(hasbothpoints.Get(i1)).PNum(j1) - << " "; - (*testout) << "\n"; - } - } - */ - } - - - if (swap2) - { - // (*mycout) << "bad1 = " << bad1 << " bad2 = " << bad2 << "\n"; - - - /* - (*testout) << "4->4 swap A, old els = " << endl - << mesh[hasbothpoints[0]] << endl - << mesh[hasbothpoints[1]] << endl - << mesh[hasbothpoints[2]] << endl - << mesh[hasbothpoints[3]] << endl - << "new els = " << endl - << el1 << endl - << el2 << endl - << el3 << endl - << el4 << endl; - */ - - - - el1.flags.illegal_valid = 0; - el2.flags.illegal_valid = 0; - el3.flags.illegal_valid = 0; - el4.flags.illegal_valid = 0; - - mesh[hasbothpoints[0]] = el1; - mesh[hasbothpoints[1]] = el2; - mesh[hasbothpoints[2]] = el3; - mesh[hasbothpoints[3]] = el4; - - for (k = 0; k < 4; k++) - for (l = 0; l < 4; l++) - elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]); - } - else if (swap3) - { - // (*mycout) << "bad1 = " << bad1 << " bad3 = " << bad3 << "\n"; - el1b.flags.illegal_valid = 0; - el2b.flags.illegal_valid = 0; - el3b.flags.illegal_valid = 0; - el4b.flags.illegal_valid = 0; - - - /* - (*testout) << "4->4 swap A, old els = " << endl - << mesh[hasbothpoints[0]] << endl - << mesh[hasbothpoints[1]] << endl - << mesh[hasbothpoints[2]] << endl - << mesh[hasbothpoints[3]] << endl - << "new els = " << endl - << el1b << endl - << el2b << endl - << el3b << endl - << el4b << endl; - */ - - - mesh[hasbothpoints[0]] = el1b; - mesh[hasbothpoints[1]] = el2b; - mesh[hasbothpoints[2]] = el3b; - mesh[hasbothpoints[3]] = el4b; - - for (k = 0; k < 4; k++) - for (l = 0; l < 4; l++) - elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]); - } - } - - if (nsuround >= 5) - { - Element hel(TET); - - ArrayMem<PointIndex, 50> suroundpts(nsuround); - ArrayMem<char, 50> tetused(nsuround); - - Element & elem = mesh[hasbothpoints[0]]; - - for (l = 0; l < 4; l++) - if (elem[l] != pi1 && elem[l] != pi2) - { - pi4 = pi3; - pi3 = elem[l]; - } - - hel[0] = pi1; - hel[1] = pi2; - hel[2] = pi3; - hel[3] = pi4; - hel.SetIndex (mattyp); - - if (WrongOrientation (mesh.Points(), hel)) - { - Swap (pi3, pi4); - hel[2] = pi3; - hel[3] = pi4; - } - - - // suroundpts.SetSize (nsuround); - suroundpts[0] = pi3; - suroundpts[1] = pi4; - - tetused = 0; - tetused[0] = 1; - - for (l = 2; l < nsuround; l++) - { - int oldpi = suroundpts[l-1]; - int newpi = 0; - - for (k = 0; k < nsuround && !newpi; k++) - if (!tetused[k]) - { - const Element & nel = mesh[hasbothpoints[k]]; - - for (int k2 = 0; k2 < 4 && !newpi; k2++) - if (nel[k2] == oldpi) - { - newpi = - nel[0] + nel[1] + nel[2] + nel[3] - - pi1 - pi2 - oldpi; - - tetused[k] = 1; - suroundpts[l] = newpi; - } - } - } - - - double bad1 = 0, bad2; - for (k = 0; k < nsuround; k++) - { - hel[0] = pi1; - hel[1] = pi2; - hel[2] = suroundpts[k]; - hel[3] = suroundpts[(k+1) % nsuround]; - hel.SetIndex (mattyp); - - bad1 += CalcBad (mesh.Points(), hel, 0); - } - - // (*testout) << "nsuround = " << nsuround << " bad1 = " << bad1 << endl; - - - int bestl = -1; - int confface = -1; - int confedge = -1; - double badopt = bad1; - - for (l = 0; l < nsuround; l++) - { - bad2 = 0; - - for (k = l+1; k <= nsuround + l - 2; k++) - { - hel[0] = suroundpts[l]; - hel[1] = suroundpts[k % nsuround]; - hel[2] = suroundpts[(k+1) % nsuround]; - hel[3] = pi2; - - bad2 += CalcBad (mesh.Points(), hel, 0); - hel.flags.illegal_valid = 0; - if (!mesh.LegalTet(hel)) bad2 += 1e4; - - hel[2] = suroundpts[k % nsuround]; - hel[1] = suroundpts[(k+1) % nsuround]; - hel[3] = pi1; - - bad2 += CalcBad (mesh.Points(), hel, 0); - - hel.flags.illegal_valid = 0; - if (!mesh.LegalTet(hel)) bad2 += 1e4; - } - // (*testout) << "bad2," << l << " = " << bad2 << endl; - - if ( bad2 < badopt ) - { - bestl = l; - badopt = bad2; - } - - - if (goal == OPT_CONFORM) - // (bad2 <= 100 * bad1 || bad2 <= 1e6)) - { - bool nottoobad = - (bad2 <= bad1) || - (bad2 <= 100 * bad1 && bad2 <= 1e18) || - (bad2 <= 1e8); - - for (k = l+1; k <= nsuround + l - 2; k++) - { - INDEX_3 hi3(suroundpts[l], - suroundpts[k % nsuround], - suroundpts[(k+1) % nsuround]); - hi3.Sort(); - if (faces.Used(hi3)) - { - // (*testout) << "could improve face conformity, bad1 = " << bad1 - // << ", bad 2 = " << bad2 << ", nottoobad = " << nottoobad << endl; - if (nottoobad) - confface = l; - } - } - - for (k = l+2; k <= nsuround+l-2; k++) - { - if (mesh.BoundaryEdge (suroundpts[l], - suroundpts[k % nsuround])) - { - /* - *testout << "could improve edge conformity, bad1 = " << bad1 - << ", bad 2 = " << bad2 << ", nottoobad = " << nottoobad << endl; - */ - if (nottoobad) - confedge = l; - } - } - } - } - - if (confedge != -1) - bestl = confedge; - if (confface != -1) - bestl = confface; - - if (bestl != -1) - { - // (*mycout) << nsuround << "->" << 2 * (nsuround-2) << " " << flush; - cnt++; - - for (k = bestl+1; k <= nsuround + bestl - 2; k++) - { - int k1; - - hel[0] = suroundpts[bestl]; - hel[1] = suroundpts[k % nsuround]; - hel[2] = suroundpts[(k+1) % nsuround]; - hel[3] = pi2; - hel.flags.illegal_valid = 0; - - /* - (*testout) << nsuround << "-swap, new el,top = " - << hel << endl; - */ - mesh.AddVolumeElement (hel); - for (k1 = 0; k1 < 4; k1++) - elementsonnode.Add (hel[k1], mesh.GetNE()-1); - - - hel[2] = suroundpts[k % nsuround]; - hel[1] = suroundpts[(k+1) % nsuround]; - hel[3] = pi1; - - /* - (*testout) << nsuround << "-swap, new el,bot = " - << hel << endl; - */ - - mesh.AddVolumeElement (hel); - for (k1 = 0; k1 < 4; k1++) - elementsonnode.Add (hel[k1], mesh.GetNE()-1); - } - - for (k = 0; k < nsuround; k++) - { - Element & rel = mesh[hasbothpoints[k]]; - /* - (*testout) << nsuround << "-swap, old el = " - << rel << endl; - */ - rel.Delete(); - for (int k1 = 0; k1 < 4; k1++) - rel[k1] = 0; - } - } - } - } - - /* - if (onlybedges) - { - (*testout) << "bad tet: " - << volelements.Get(i)[0] - << volelements.Get(i)[1] - << volelements.Get(i)[2] - << volelements.Get(i)[3] << "\n"; - - if (!mesh.LegalTet (volelements.Get(i))) - cerr << "Illegal tet" << "\n"; - } - */ - } - // (*mycout) << endl; - - /* - cout << "edgeused: "; - edgeused.PrintMemInfo(cout); - */ - PrintMessage (5, cnt, " swaps performed"); - - mesh.Compress (); - - /* - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - // (*testout) << "Total badness = " << bad1 << endl; - } - */ - - /* - for (i = 1; i <= GetNE(); i++) - if (volelements.Get(i)[0]) - if (!mesh.LegalTet (volelements.Get(i))) - { - cout << "detected illegal tet, 2" << endl; - (*testout) << "detected illegal tet1: " << i << endl; - } - */ - - multithread.task = savetask; -} - - - - - - - - -/* - 2 -> 3 conversion -*/ - - - -void MeshOptimize3d :: SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal) -{ - int j, k, l; - ElementIndex ei, eli1, eli2, elnr; - SurfaceElementIndex sei; - PointIndex pi1, pi2, pi3, pi4, pi5; - - int cnt = 0; - - Element el21(TET), el22(TET), el31(TET), el32(TET), el33(TET); - - double bad1, bad2; - - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - - if (goal == OPT_CONFORM) return; - - // contains at least all elements at node - TABLE<ElementIndex, PointIndex::BASE> elementsonnode(np); - TABLE<SurfaceElementIndex, PointIndex::BASE> belementsonnode(np); - - PrintMessage (3, "SwapImprove2 "); - (*testout) << "\n" << "Start SwapImprove2" << "\n"; - // TestOk(); - - - - /* - CalcSurfacesOfNode (); - for (i = 1; i <= GetNE(); i++) - if (volelements.Get(i)[0]) - if (!mesh.LegalTet (volelements.Get(i))) - { - cout << "detected illegal tet, 1" << endl; - (*testout) << "detected illegal tet1: " << i << endl; - } - */ - - - // Calculate total badness - - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << bad1 << endl; - // cout << "tot bad = " << bad1 << endl; - - // find elements on node - - for (ei = 0; ei < ne; ei++) - for (j = 0; j < mesh[ei].GetNP(); j++) - elementsonnode.Add (mesh[ei][j], ei); - - for (sei = 0; sei < nse; sei++) - for (j = 0; j < 3; j++) - belementsonnode.Add (mesh[sei][j], sei); - - for (eli1 = 0; eli1 < ne; eli1++) - { - if (multithread.terminate) - break; - - if (mesh.ElementType (eli1) == FIXEDELEMENT) - continue; - - if (mesh[eli1].GetType() != TET) - continue; - - if ((goal == OPT_LEGAL) && - mesh.LegalTet (mesh[eli1]) && - CalcBad (mesh.Points(), mesh[eli1], 0) < 1e3) - continue; - - // cout << "eli = " << eli1 << endl; - // (*testout) << "swapimp2, eli = " << eli1 << "; el = " << mesh[eli1] << endl; - - for (j = 0; j < 4; j++) - { - // loop over faces - - Element & elem = mesh[eli1]; - // if (elem[0] < PointIndex::BASE) continue; - if (elem.IsDeleted()) continue; - - int mattyp = elem.GetIndex(); - - switch (j) - { - case 0: - pi1 = elem.PNum(1); pi2 = elem.PNum(2); - pi3 = elem.PNum(3); pi4 = elem.PNum(4); - break; - case 1: - pi1 = elem.PNum(1); pi2 = elem.PNum(4); - pi3 = elem.PNum(2); pi4 = elem.PNum(3); - break; - case 2: - pi1 = elem.PNum(1); pi2 = elem.PNum(3); - pi3 = elem.PNum(4); pi4 = elem.PNum(2); - break; - case 3: - pi1 = elem.PNum(2); pi2 = elem.PNum(4); - pi3 = elem.PNum(3); pi4 = elem.PNum(1); - break; - } - - - bool bface = 0; - for (k = 0; k < belementsonnode[pi1].Size(); k++) - { - const Element2d & bel = - mesh[belementsonnode[pi1][k]]; - - bool bface1 = 1; - for (l = 0; l < 3; l++) - if (bel[l] != pi1 && bel[l] != pi2 && bel[l] != pi3) - { - bface1 = 0; - break; - } - - if (bface1) - { - bface = 1; - break; - } - } - - if (bface) continue; - - - FlatArray<ElementIndex> row = elementsonnode[pi1]; - for (k = 0; k < row.Size(); k++) - { - eli2 = row[k]; - - // cout << "\rei1 = " << eli1 << ", pi1 = " << pi1 << ", k = " << k << ", ei2 = " << eli2 - // << ", getne = " << mesh.GetNE(); - - if ( eli1 != eli2 ) - { - Element & elem2 = mesh[eli2]; - if (elem2.IsDeleted()) continue; - if (elem2.GetType() != TET) - continue; - - int comnodes=0; - for (l = 1; l <= 4; l++) - if (elem2.PNum(l) == pi1 || elem2.PNum(l) == pi2 || - elem2.PNum(l) == pi3) - { - comnodes++; - } - else - { - pi5 = elem2.PNum(l); - } - - if (comnodes == 3) - { - bad1 = CalcBad (mesh.Points(), elem, 0) + - CalcBad (mesh.Points(), elem2, 0); - - if (!mesh.LegalTet(elem) || - !mesh.LegalTet(elem2)) - bad1 += 1e4; - - - el31.PNum(1) = pi1; - el31.PNum(2) = pi2; - el31.PNum(3) = pi5; - el31.PNum(4) = pi4; - el31.SetIndex (mattyp); - - el32.PNum(1) = pi2; - el32.PNum(2) = pi3; - el32.PNum(3) = pi5; - el32.PNum(4) = pi4; - el32.SetIndex (mattyp); - - el33.PNum(1) = pi3; - el33.PNum(2) = pi1; - el33.PNum(3) = pi5; - el33.PNum(4) = pi4; - el33.SetIndex (mattyp); - - bad2 = CalcBad (mesh.Points(), el31, 0) + - CalcBad (mesh.Points(), el32, 0) + - CalcBad (mesh.Points(), el33, 0); - - - el31.flags.illegal_valid = 0; - el32.flags.illegal_valid = 0; - el33.flags.illegal_valid = 0; - - if (!mesh.LegalTet(el31) || - !mesh.LegalTet(el32) || - !mesh.LegalTet(el33)) - bad2 += 1e4; - - - bool do_swap = (bad2 < bad1); - - if ( ((bad2 < 1e6) || (bad2 < 10 * bad1)) && - mesh.BoundaryEdge (pi4, pi5)) - do_swap = 1; - - if (do_swap) - { - // cout << "do swap, eli1 = " << eli1 << "; eli2 = " << eli2 << endl; - // (*mycout) << "2->3 " << flush; - cnt++; - - el31.flags.illegal_valid = 0; - el32.flags.illegal_valid = 0; - el33.flags.illegal_valid = 0; - - mesh[eli1] = el31; - mesh[eli2] = el32; - - ElementIndex neli = - mesh.AddVolumeElement (el33); - - /* - if (!LegalTet(el31) || !LegalTet(el32) || - !LegalTet(el33)) - { - cout << "Swap to illegal tets !!!" << endl; - } - */ - // cout << "neli = " << neli << endl; - for (l = 0; l < 4; l++) - { - elementsonnode.Add (el31[l], eli1); - elementsonnode.Add (el32[l], eli2); - elementsonnode.Add (el33[l], neli); - } - - break; - } - } - } - } - } - } - - - PrintMessage (5, cnt, " swaps performed"); - - - - /* - CalcSurfacesOfNode (); - for (i = 1; i <= GetNE(); i++) - if (volelements.Get(i).PNum(1)) - if (!LegalTet (volelements.Get(i))) - { - cout << "detected illegal tet, 2" << endl; - (*testout) << "detected illegal tet2: " << i << endl; - } - */ - - - bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); - (*testout) << "Total badness = " << bad1 << endl; - (*testout) << "swapimprove2 done" << "\n"; - // (*mycout) << "Vol = " << CalcVolume (points, volelements) << "\n"; -} - - -/* - void Mesh :: SwapImprove2 (OPTIMIZEGOAL goal) - { - int i, j; - int eli1, eli2; - int mattyp; - - Element el31(4), el32(4), el33(4); - double bad1, bad2; - - - INDEX_3_HASHTABLE<INDEX_2> elsonface (GetNE()); - - (*mycout) << "SwapImprove2 " << endl; - (*testout) << "\n" << "Start SwapImprove2" << "\n"; - - // Calculate total badness - - if (goal == OPT_QUALITY) - { - double bad1 = CalcTotalBad (points, volelements); - (*testout) << "Total badness = " << bad1 << endl; - } - - // find elements on node - - - Element2d face; - for (i = 1; i <= GetNE(); i++) - if ( (i > eltyps.Size()) || (eltyps.Get(i) != FIXEDELEMENT) ) - { - const Element & el = VolumeElement(i); - if (!el.PNum(1)) continue; - - for (j = 1; j <= 4; j++) - { - el.GetFace (j, face); - INDEX_3 i3 (face.PNum(1), face.PNum(2), face.PNum(3)); - i3.Sort(); - - - int bnr, posnr; - if (!elsonface.PositionCreate (i3, bnr, posnr)) - { - INDEX_2 i2; - elsonface.GetData (bnr, posnr, i3, i2); - i2.I2() = i; - elsonface.SetData (bnr, posnr, i3, i2); - } - else - { - INDEX_2 i2 (i, 0); - elsonface.SetData (bnr, posnr, i3, i2); - } - - // if (elsonface.Used (i3)) - // { - // INDEX_2 i2 = elsonface.Get(i3); - // i2.I2() = i; - // elsonface.Set (i3, i2); - // } - // else - // { - // INDEX_2 i2 (i, 0); - // elsonface.Set (i3, i2); - // } - - } - } - - BitArray original(GetNE()); - original.Set(); - - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & sface = SurfaceElement(i); - INDEX_3 i3 (sface.PNum(1), sface.PNum(2), sface.PNum(3)); - i3.Sort(); - INDEX_2 i2(0,0); - elsonface.Set (i3, i2); - } - - - for (i = 1; i <= elsonface.GetNBags(); i++) - for (j = 1; j <= elsonface.GetBagSize(i); j++) - { - INDEX_3 i3; - INDEX_2 i2; - elsonface.GetData (i, j, i3, i2); - - - int eli1 = i2.I1(); - int eli2 = i2.I2(); - - if (eli1 && eli2 && original.Test(eli1) && original.Test(eli2) ) - { - Element & elem = volelements.Elem(eli1); - Element & elem2 = volelements.Elem(eli2); - - int pi1 = i3.I1(); - int pi2 = i3.I2(); - int pi3 = i3.I3(); - - int pi4 = elem.PNum(1) + elem.PNum(2) + elem.PNum(3) + elem.PNum(4) - pi1 - pi2 - pi3; - int pi5 = elem2.PNum(1) + elem2.PNum(2) + elem2.PNum(3) + elem2.PNum(4) - pi1 - pi2 - pi3; - - - - - - - el31.PNum(1) = pi1; - el31.PNum(2) = pi2; - el31.PNum(3) = pi3; - el31.PNum(4) = pi4; - el31.SetIndex (mattyp); - - if (WrongOrientation (points, el31)) - swap (pi1, pi2); - - - bad1 = CalcBad (points, elem, 0) + - CalcBad (points, elem2, 0); - - // if (!LegalTet(elem) || !LegalTet(elem2)) - // bad1 += 1e4; - - - el31.PNum(1) = pi1; - el31.PNum(2) = pi2; - el31.PNum(3) = pi5; - el31.PNum(4) = pi4; - el31.SetIndex (mattyp); - - el32.PNum(1) = pi2; - el32.PNum(2) = pi3; - el32.PNum(3) = pi5; - el32.PNum(4) = pi4; - el32.SetIndex (mattyp); - - el33.PNum(1) = pi3; - el33.PNum(2) = pi1; - el33.PNum(3) = pi5; - el33.PNum(4) = pi4; - el33.SetIndex (mattyp); - - bad2 = CalcBad (points, el31, 0) + - CalcBad (points, el32, 0) + - CalcBad (points, el33, 0); - - // if (!LegalTet(el31) || !LegalTet(el32) || - // !LegalTet(el33)) - // bad2 += 1e4; - - - int swap = (bad2 < bad1); - - INDEX_2 hi2b(pi4, pi5); - hi2b.Sort(); - - if ( ((bad2 < 1e6) || (bad2 < 10 * bad1)) && - boundaryedges->Used (hi2b) ) - swap = 1; - - if (swap) - { - (*mycout) << "2->3 " << flush; - - volelements.Elem(eli1) = el31; - volelements.Elem(eli2) = el32; - volelements.Append (el33); - - original.Clear (eli1); - original.Clear (eli2); - } - } - } - - (*mycout) << endl; - - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (points, volelements); - (*testout) << "Total badness = " << bad1 << endl; - } - - // FindOpenElements (); - - (*testout) << "swapimprove2 done" << "\n"; - } - -*/ -} diff --git a/Netgen/libsrc/meshing/improve3.hpp b/Netgen/libsrc/meshing/improve3.hpp deleted file mode 100644 index 9b5b2c9bec..0000000000 --- a/Netgen/libsrc/meshing/improve3.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef FILE_IMPROVE3 -#define FILE_IMPROVE3 - - - - -/// -class MeshOptimize3d -{ -public: - void CombineImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); - void SplitImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); - void SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); - void SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); -}; - - - -extern double CalcBad (const Mesh::T_POINTS & points, const Element & elem, - double h); - -extern double CalcTotalBad (const Mesh::T_POINTS & points, - const Mesh::T_VOLELEMENTS & elements); - -extern int WrongOrientation (const Mesh::T_POINTS & points, const Element & el); - - -/* Functional depending of inner point inside triangular surface */ - - - -class PointFunction1 : public MinFunction -{ - Mesh::T_POINTS & points; - const ARRAY<INDEX_3> & faces; - double h; -public: - PointFunction1 (Mesh::T_POINTS & apoints, - const ARRAY<INDEX_3> & afaces, - double ah); - - virtual double Func (const Vector & x) const; - virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double GradStopping (const Vector & x) const; -}; - - - -#endif diff --git a/Netgen/libsrc/meshing/localh.cpp b/Netgen/libsrc/meshing/localh.cpp deleted file mode 100644 index 62025737f3..0000000000 --- a/Netgen/libsrc/meshing/localh.cpp +++ /dev/null @@ -1,682 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ - -GradingBox :: GradingBox (const double * ax1, const double * ax2) -{ - int i; - - h2 = 0.5 * (ax2[0] - ax1[0]); - for (i = 0; i <= 2; i++) - { - /* - x1[i] = ax1[i]; - x2[i] = ax2[i]; - */ - xmid[i] = 0.5 * (ax1[i] + ax2[i]); - } - - /* - (*testout) << "new box: " << xmid[0] << "-" << xmid[1] << "-" << xmid[2] - << " h = " << (x2[0] - x1[0]) << endl; - */ - - for (i = 0; i < 8; i++) - childs[i] = NULL; - father = NULL; - - flags.cutboundary = 0; - flags.isinner = 0; - flags.oldcell = 0; - flags.pinner = 0; - - // hopt = x2[0] - x1[0]; - hopt = 2 * h2; -} - - - -BlockAllocator GradingBox :: ball(sizeof (GradingBox)); - -void * GradingBox :: operator new(size_t) -{ - return ball.Alloc(); -} - -void GradingBox :: operator delete (void * p) -{ - ball.Free (p); -} - - - - - - - -void GradingBox :: DeleteChilds() -{ - int i; - for (i = 0; i < 8; i++) - if (childs[i]) - { - childs[i]->DeleteChilds(); - delete childs[i]; - childs[i] = NULL; - } -} - - -LocalH :: LocalH (const Point3d & pmin, const Point3d & pmax, double agrading) -{ - double x1[3], x2[3]; - double hmax; - int i; - - boundingbox = Box3d (pmin, pmax); - grading = agrading; - - // a small enlargement, non-regular points - double val = 0.0879; - for (i = 1; i <= 3; i++) - { - - x1[i-1] = (1 + val * i) * pmin.X(i) - val * i * pmax.X(i); - x2[i-1] = 1.1 * pmax.X(i) - 0.1 * pmin.X(i); - } - - hmax = x2[0] - x1[0]; - for (i = 1; i <= 2; i++) - if (x2[i] - x1[i] > hmax) - hmax = x2[i] - x1[i]; - - for (i = 0; i <= 2; i++) - x2[i] = x1[i] + hmax; - - root = new GradingBox (x1, x2); - boxes.Append (root); -} - -LocalH :: ~LocalH () -{ - root->DeleteChilds(); - delete root; -} - -void LocalH :: Delete () -{ - root->DeleteChilds(); -} - -void LocalH :: SetH (const Point3d & p, double h) -{ - /* - (*testout) << "Set h at " << p << " to " << h << endl; - if (h < 1e-8) - { - cout << "do not set h to " << h << endl; - return; - } - */ - - if (fabs (p.X() - root->xmid[0]) > root->h2 || - fabs (p.Y() - root->xmid[1]) > root->h2 || - fabs (p.Z() - root->xmid[2]) > root->h2) - return; - - /* - if (p.X() < root->x1[0] || p.X() > root->x2[0] || - p.Y() < root->x1[1] || p.Y() > root->x2[1] || - p.Z() < root->x1[2] || p.Z() > root->x2[2]) - return; - */ - - - if (GetH(p) <= 1.2 * h) return; - - - GradingBox * box = root; - GradingBox * nbox = root; - GradingBox * ngb; - int childnr; - double x1[3], x2[3]; - - while (nbox) - { - box = nbox; - childnr = 0; - if (p.X() > box->xmid[0]) childnr += 1; - if (p.Y() > box->xmid[1]) childnr += 2; - if (p.Z() > box->xmid[2]) childnr += 4; - nbox = box->childs[childnr]; - }; - - - while (2 * box->h2 > h) - { - childnr = 0; - if (p.X() > box->xmid[0]) childnr += 1; - if (p.Y() > box->xmid[1]) childnr += 2; - if (p.Z() > box->xmid[2]) childnr += 4; - - double h2 = box->h2; - if (childnr & 1) - { - x1[0] = box->xmid[0]; - x2[0] = x1[0]+h2; // box->x2[0]; - } - else - { - x2[0] = box->xmid[0]; - x1[0] = x2[0]-h2; // box->x1[0]; - } - - if (childnr & 2) - { - x1[1] = box->xmid[1]; - x2[1] = x1[1]+h2; // box->x2[1]; - } - else - { - x2[1] = box->xmid[1]; - x1[1] = x2[1]-h2; // box->x1[1]; - } - - if (childnr & 4) - { - x1[2] = box->xmid[2]; - x2[2] = x1[2]+h2; // box->x2[2]; - } - else - { - x2[2] = box->xmid[2]; - x1[2] = x2[2]-h2; // box->x1[2]; - } - - ngb = new GradingBox (x1, x2); - box->childs[childnr] = ngb; - ngb->father = box; - - boxes.Append (ngb); - box = box->childs[childnr]; - } - - box->hopt = h; - - - double hbox = 2 * box->h2; // box->x2[0] - box->x1[0]; - double hnp = h + grading * hbox; - - Point3d np; - int i; - for (i = 1; i <= 3; i++) - { - np = p; - np.X(i) = p.X(i) + hbox; - SetH (np, hnp); - - np.X(i) = p.X(i) - hbox; - SetH (np, hnp); - } - /* - Point3d np; - int i1, i2, i3; - for (i1 = -1; i1 <= 1; i1++) - for (i2 = -1; i2 <= 1; i2++) - for (i3 = -1; i3 <= 1; i3++) - { - np.X() = p.X() + hbox * i1; - np.Y() = p.Y() + hbox * i2; - np.Z() = p.Z() + hbox * i3; - - SetH (np, hnp); - } - */ -} - - - -double LocalH :: GetH (const Point3d & x) const -{ - const GradingBox * box = root; - const GradingBox * nbox; - int childnr; - - while (1) - { - childnr = 0; - if (x.X() > box->xmid[0]) childnr += 1; - if (x.Y() > box->xmid[1]) childnr += 2; - if (x.Z() > box->xmid[2]) childnr += 4; - nbox = box->childs[childnr]; - if (nbox) - box = nbox; - else - { - // (*testout) << "diam = " << (box->x2[0] - box->x1[0]) - // << " h = " << box->hopt << endl; - return box->hopt; - } - } -} - - -/// minimal h in box (pmin, pmax) -double LocalH :: GetMinH (const Point3d & pmin, const Point3d & pmax) const -{ - Point3d pmin2, pmax2; - for (int j = 1; j <= 3; j++) - if (pmin.X(j) < pmax.X(j)) - { pmin2.X(j) = pmin.X(j); pmax2.X(j) = pmax.X(j); } - else - { pmin2.X(j) = pmax.X(j); pmax2.X(j) = pmin.X(j); } - - return GetMinHRec (pmin2, pmax2, root); -} - - -double LocalH :: GetMinHRec (const Point3d & pmin, const Point3d & pmax, - const GradingBox * box) const -{ - double h2 = box->h2; - if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 || - pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 || - pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2) - return 1e8; - /* - if (pmax.X() < box->x1[0] || pmin.X() > box->x2[0] || - pmax.Y() < box->x1[1] || pmin.Y() > box->x2[1] || - pmax.Z() < box->x1[2] || pmin.Z() > box->x2[2]) - return 1e8; - */ - - - double hmin = 2 * box->h2; // box->x2[0] - box->x1[0]; - int i; - - for (i = 0; i <= 7; i++) - { - if (box->childs[i]) - { - double hi = GetMinHRec (pmin, pmax, box->childs[i]); - if (hi < hmin) - hmin = hi; - } - } - - return hmin; -} - - -void LocalH :: CutBoundaryRec (const Point3d & pmin, const Point3d & pmax, - GradingBox * box) -{ - double h2 = box->h2; - if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 || - pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 || - pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2) - return; - /* - if (pmax.X() < box->x1[0] || pmin.X() > box->x2[0] || - pmax.Y() < box->x1[1] || pmin.Y() > box->x2[1] || - pmax.Z() < box->x1[2] || pmin.Z() > box->x2[2]) - return; - */ - - box->flags.cutboundary = 1; - for (int i = 0; i < 8; i++) - if (box->childs[i]) - CutBoundaryRec (pmin, pmax, box->childs[i]); -} - - - - -void LocalH :: FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2), - AdFront3 * adfront, - int (*testinner)(const Point3d & p1)) -{ - int i, j; - - int nf = adfront->GetNF(); - - for (i = 0; i < boxes.Size(); i++) - boxes[i] -> flags.isinner = 0; - - root->flags.isinner = 0; - - Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]); - Vec3d rv(root->h2, root->h2, root->h2); - Point3d rx2 = rpmid + rv; - Point3d rx1 = rpmid - rv; - - - root->flags.pinner = !adfront->SameSide (rpmid, rx2); - - if (testinner) - (*testout) << "inner = " << root->flags.pinner << " =?= " - << testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl; - - ARRAY<int> faceinds(nf); - ARRAY<Box3d> faceboxes(nf); - - for (i = 1; i <= nf; i++) - { - faceinds.Elem(i) = i; - adfront->GetFaceBoundingBox(i, faceboxes.Elem(i)); - } - - for (i = 0; i < 8; i++) - FindInnerBoxesRec2 (root->childs[i], adfront, faceboxes, faceinds, nf); -} - - -void LocalH :: -FindInnerBoxesRec2 (GradingBox * box, - class AdFront3 * adfront, - ARRAY<Box3d> & faceboxes, - ARRAY<int> & faceinds, int nfinbox) -{ - if (!box) return; - - int i, j; - - GradingBox * father = box -> father; - - Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); - Vec3d v(box->h2, box->h2, box->h2); - Box3d boxc(c-v, c+v); - - Point3d fc(father->xmid[0], father->xmid[1], father->xmid[2]); - Vec3d fv(father->h2, father->h2, father->h2); - Box3d fboxc(fc-fv, fc+fv); - - Box3d boxcfc(c,fc); - - - static ARRAY<int> faceused; - static ARRAY<int> faceused2; - static ARRAY<int> facenotused; - - faceused.SetSize(0); - facenotused.SetSize(0); - faceused2.SetSize(0); - - for (j = 1; j <= nfinbox; j++) - { - // adfront->GetFaceBoundingBox (faceinds.Get(j), facebox); - const Box3d & facebox = faceboxes.Get(faceinds.Get(j)); - - if (boxc.Intersect (facebox)) - faceused.Append(faceinds.Get(j)); - else - facenotused.Append(faceinds.Get(j)); - - if (boxcfc.Intersect (facebox)) - faceused2.Append (faceinds.Get(j)); - } - - for (j = 1; j <= faceused.Size(); j++) - faceinds.Elem(j) = faceused.Get(j); - for (j = 1; j <= facenotused.Size(); j++) - faceinds.Elem(j+faceused.Size()) = facenotused.Get(j); - - - if (!father->flags.cutboundary) - { - box->flags.isinner = father->flags.isinner; - box->flags.pinner = father->flags.pinner; - } - else - { - Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]); - - if (father->flags.isinner) - box->flags.pinner = 1; - else - { - if (adfront->SameSide (c, cf, &faceused2)) - box->flags.pinner = father->flags.pinner; - else - box->flags.pinner = 1 - father->flags.pinner; - } - - if (box->flags.cutboundary) - box->flags.isinner = 0; - else - box->flags.isinner = box->flags.pinner; - } - - int nf = faceused.Size(); - for (i = 0; i < 8; i++) - FindInnerBoxesRec2 (box->childs[i], adfront, faceboxes, faceinds, nf); -} - - - - - - - - - - - - -/* -void LocalH :: FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2), - AdFront3 * adfront, - int (*testinner)(const Point3d & p1)) -{ - int i; - for (i = 1; i <= boxes.Size(); i++) - boxes.Elem(i)->flags.isinner = 0; - - root->flags.isinner = 0; - - Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]); - Point3d rx2 = rpmid + Vec3d (root->h2, root->h2, root->h2); - - root->flags.pinner = !adfront->SameSide (rpmid, rx2); - - if (testinner) - (*testout) << "inner = " << root->flags.pinner << " =?= " - << testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl; - - - for (i = 2; i <= boxes.Size(); i++) - { - GradingBox * box = boxes.Elem(i); - GradingBox * father = box -> father; - - Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); - Vec3d v(box->h2, box->h2, box->h2); - Point3d x1 = c-v; - Point3d x2 = c+v; - - - if (!father->flags.cutboundary) - { - box->flags.isinner = father->flags.isinner; - box->flags.pinner = father->flags.pinner; - } - else - { - Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]); - - if (father->flags.isinner) - box->flags.pinner = 1; - else - { - if (adfront->SameSide (c, cf)) - box->flags.pinner = father->flags.pinner; - else - box->flags.pinner = 1 - father->flags.pinner; - } - - if (box->flags.cutboundary) - box->flags.isinner = 0; - else - box->flags.isinner = box->flags.pinner; - } - } - // FindInnerBoxesRec (inner, root); -} -*/ - - -void LocalH :: FindInnerBoxesRec ( int (*inner)(const Point3d & p), - GradingBox * box) -{ - int i; - if (box->flags.cutboundary) - { - for (i = 0; i < 8; i++) - if (box->childs[i]) - FindInnerBoxesRec (inner, box->childs[i]); - } - else - { - if (inner (Point3d (box->xmid[0], box->xmid[1], box->xmid[2]))) - SetInnerBoxesRec (box); - } -} - - -void LocalH :: SetInnerBoxesRec (GradingBox * box) -{ - box->flags.isinner = 1; - for (int i = 0; i < 8; i++) - if (box->childs[i]) - ClearFlagsRec (box->childs[i]); -} - -void LocalH :: ClearFlagsRec (GradingBox * box) -{ - box->flags.cutboundary = 0; - box->flags.isinner = 0; - for (int i = 0; i < 8; i++) - if (box->childs[i]) - ClearFlagsRec (box->childs[i]); -} - - -void LocalH :: WidenRefinement () -{ - int nb = boxes.Size(); - int i; - // (*testout) << "old boxes: " << nb << endl; - for (i = 1; i <= nb; i++) - { - GradingBox * box = boxes.Get(i); - // double h = box->x2[0] - box->x1[0]; - double h = box->hopt; - Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); - // (*testout) << " i = " << i - // << " c = " << c << " h = " << h << endl; - - for (int i1 = -1; i1 <= 1; i1++) - for (int i2 = -1; i2 <= 1; i2++) - for (int i3 = -1; i3 <= 1; i3++) - SetH (Point3d (c.X() + i1 * h, - c.Y() + i2 * h, - c.Z() + i3 * h), 1.001 * h); - } -} - -void LocalH :: GetInnerPoints (ARRAY<Point3d> & points) -{ - int i, nb = boxes.Size(); - - for (i = 1; i <= nb; i++) - { - GradingBox * box = boxes.Get(i); - /* - if (box->flags.pinner) - points.Append (box->randomip); - */ - // if (box->flags.pinner) - if (box->flags.isinner) - { - Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); - points.Append (c); - /* - cout << "add point " << c << "; h = " << box->hopt - << "; max-min = " << (box->x2[0]-box->x1[0]) << endl; - */ - } - } -} - - - -void LocalH :: GetOuterPoints (ARRAY<Point3d> & points) -{ - int i, nb = boxes.Size(); - - for (i = 1; i <= nb; i++) - { - GradingBox * box = boxes.Get(i); - if (!box->flags.isinner && - !box->flags.cutboundary) - { - Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); - points.Append (c); - } - } -} - - - -void LocalH :: Convexify () -{ - ConvexifyRec (root); -} - -void LocalH :: ConvexifyRec (GradingBox * box) -{ - Point3d center(box->xmid[0], box->xmid[1], box->xmid[2]); - Point3d hp; - - double size = 2 * box->h2; // box->x2[0] - box->x1[0]; - double dx = 0.6 * size; - - double maxh = box->hopt; - int i; - - - - for (i = 1; i <= 6; i++) - { - hp = center; - switch (i) - { - case 1: hp.X() += dx; break; - case 2: hp.X() -= dx; break; - case 3: hp.Y() += dx; break; - case 4: hp.Y() -= dx; break; - case 5: hp.Z() += dx; break; - case 6: hp.Z() -= dx; break; - } - - double hh = GetH (hp); - if (hh > maxh) maxh = hh; - } - - if (maxh < 0.95 * box->hopt) - SetH (center, maxh); - - for (i = 0; i < 8; i++) - if (box->childs[i]) - ConvexifyRec (box->childs[i]); -} - -void LocalH :: PrintMemInfo (ostream & ost) const -{ - ost << "LocalH: " << boxes.Size() << " boxes of " << sizeof(GradingBox) - << " bytes = " << boxes.Size()*sizeof(GradingBox) << " bytes" << endl; -} -} diff --git a/Netgen/libsrc/meshing/localh.hpp b/Netgen/libsrc/meshing/localh.hpp deleted file mode 100644 index 7531bc7faf..0000000000 --- a/Netgen/libsrc/meshing/localh.hpp +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef LOCALH -#define LOCALH - -/**************************************************************************/ -/* File: localh.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 29. Jan. 97 */ -/**************************************************************************/ - - - - -/// box for grading -class GradingBox -{ - /* - /// xmin - float x1[3]; - /// xmax - float x2[3]; - */ - /// xmid - float xmid[3]; - /// half edgelength - float h2; - /// - GradingBox * childs[8]; - /// - GradingBox * father; - /// - double hopt; - /// - struct - { - unsigned int cutboundary:1; - unsigned int isinner:1; - unsigned int oldcell:1; - unsigned int pinner:1; - } flags; -public: - /// - GradingBox (const double * ax1, const double * ax2); - /// - void DeleteChilds(); - /// - friend class LocalH; - - - static BlockAllocator ball; - void * operator new(size_t); - void operator delete (void *); -}; - - - -/** - Control of 3D mesh grading - */ -class LocalH -{ - /// - GradingBox * root; - /// - double grading; - /// - ARRAY<GradingBox*> boxes; - /// - Box3d boundingbox; -public: - /// - LocalH (const Point3d & pmin, const Point3d & pmax, double grading); - /// - ~LocalH(); - /// - void Delete(); - /// - void SetGrading (double agrading) { grading = agrading; } - /// - void SetH (const Point3d & x, double h); - /// - double GetH (const Point3d & x) const; - /// minimal h in box (pmin, pmax) - double GetMinH (const Point3d & pmin, const Point3d & pmax) const; - - /// mark boxes intersecting with boundary-box - void CutBoundary (const Point3d & pmin, const Point3d & pmax) - { CutBoundaryRec (pmin, pmax, root); } - - /// find inner boxes - void FindInnerBoxes ( // int (*sameside)(const Point3d & p1, const Point3d & p2), - class AdFront3 * adfront, - int (*testinner)(const Point3d & p1)); - - /// clears all flags - void ClearFlags () - { ClearFlagsRec(root); } - - /// widen refinement zone - void WidenRefinement (); - - /// get points in inner elements - void GetInnerPoints (ARRAY<Point3d> & points); - - /// get points in outer closure - void GetOuterPoints (ARRAY<Point3d> & points); - - /// - void Convexify (); - /// - int GetNBoxes () { return boxes.Size(); } - const Box3d & GetBoundingBox () const - { return boundingbox; } - /// - void PrintMemInfo (ostream & ost) const; -private: - /// - double GetMinHRec (const Point3d & pmin, const Point3d & pmax, - const GradingBox * box) const; - /// - void CutBoundaryRec (const Point3d & pmin, const Point3d & pmax, - GradingBox * box); - - /// - void FindInnerBoxesRec ( int (*inner)(const Point3d & p), - GradingBox * box); - - /// - void FindInnerBoxesRec2 (GradingBox * box, - class AdFront3 * adfront, - ARRAY<Box3d> & faceboxes, - ARRAY<int> & finds, int nfinbox); - - - /// - void SetInnerBoxesRec (GradingBox * box); - - /// - void ClearFlagsRec (GradingBox * box); - - /// - void ConvexifyRec (GradingBox * box); -}; - - -#endif diff --git a/Netgen/libsrc/meshing/meshclass.cpp b/Netgen/libsrc/meshing/meshclass.cpp deleted file mode 100644 index 25c44f337e..0000000000 --- a/Netgen/libsrc/meshing/meshclass.cpp +++ /dev/null @@ -1,4744 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - -namespace netgen -{ - - Mesh :: Mesh () - { - boundaryedges = NULL; - surfelementht = NULL; - segmentht = NULL; - - lochfunc = NULL; - mglevels = 1; - elementsearchtree = NULL; - elementsearchtreets = NextTimeStamp(); - majortimestamp = timestamp = NextTimeStamp(); - hglob = 1e10; - numvertices = -1; - dimension = 3; - topology = new MeshTopology (*this); - curvedelems = new CurvedElements (*this); - clusters = new AnisotropicClusters (*this); - ident = new Identifications (*this); - - hpelements = NULL; - coarsemesh = NULL; - - } - - Mesh :: ~Mesh() - { - delete lochfunc; - delete boundaryedges; - delete surfelementht; - delete segmentht; - delete curvedelems; - delete clusters; - delete topology; - delete ident; - - delete coarsemesh; - delete hpelements; - - for (int i = 0; i < materials.Size(); i++) - delete [] materials[i]; - } - - - Mesh & Mesh :: operator= (const Mesh & mesh2) - { - points = mesh2.points; - eltyps = mesh2.eltyps; - segments = mesh2.segments; - surfelements = mesh2.surfelements; - volelements = mesh2.volelements; - lockedpoints = mesh2.lockedpoints; - facedecoding = mesh2.facedecoding; - dimension = mesh2.dimension; - return *this; - } - - void Mesh :: DeleteMesh() - { - points.SetSize(0); - // ptyps.SetSize(0); - segments.SetSize(0); - surfelements.SetSize(0); - volelements.SetSize(0); - lockedpoints.SetSize(0); - surfacesonnode.SetSize(0); - - delete boundaryedges; - boundaryedges = NULL; - - openelements.SetSize(0); - facedecoding.SetSize(0); - - // ident -> Delete(); - delete ident; - ident = new Identifications (*this); - delete topology; - topology = new MeshTopology (*this); - delete curvedelems; - curvedelems = new CurvedElements (*this); - delete clusters; - clusters = new AnisotropicClusters (*this); - - timestamp = NextTimeStamp(); - } - - - - PointIndex Mesh :: AddPoint (const Point3d & p, int layer) - { - NgLock lock(mutex); - lock.Lock(); - - timestamp = NextTimeStamp(); - - PointIndex pi = points.Size() + PointIndex::BASE; - points.Append ( MeshPoint (p, layer, INNERPOINT) ); - - lock.UnLock(); - - return pi; - } - - - SegmentIndex Mesh :: AddSegment (const Segment & s) - { - NgLock lock(mutex); - lock.Lock(); - timestamp = NextTimeStamp(); - - int maxn = max2 (s.p1, s.p2); - maxn += 1-PointIndex::BASE; - - /* - if (maxn > ptyps.Size()) - { - int maxo = ptyps.Size(); - ptyps.SetSize (maxn); - for (int i = maxo; i < maxn; i++) - ptyps[i] = INNERPOINT; - } - - if (ptyps[s.p1] > EDGEPOINT) ptyps[s.p1] = EDGEPOINT; - if (ptyps[s.p2] > EDGEPOINT) ptyps[s.p2] = EDGEPOINT; - */ - - if (maxn <= points.Size()) - { - if (points[s.p1].Type() > EDGEPOINT) - points[s.p1].SetType (EDGEPOINT); - if (points[s.p2].Type() > EDGEPOINT) - points[s.p2].SetType (EDGEPOINT); - } - /* - else - { - cerr << "edge points nrs > points.Size" << endl; - } - */ - - SegmentIndex si = segments.Size(); - segments.Append (s); - - lock.UnLock(); - return si; - } - - SurfaceElementIndex Mesh :: AddSurfaceElement (const Element2d & el) - { - NgLock lock(mutex); - lock.Lock(); - timestamp = NextTimeStamp(); - - int maxn = el[0]; - for (int i = 1; i < el.GetNP(); i++) - if (el[i] > maxn) maxn = el[i]; - - maxn += 1-PointIndex::BASE; - - /* - if (maxn > ptyps.Size()) - { - int maxo = ptyps.Size(); - ptyps.SetSize (maxn); - for (i = maxo+PointIndex::BASE; - i < maxn+PointIndex::BASE; i++) - ptyps[i] = INNERPOINT; - - } - */ - if (maxn <= points.Size()) - { - for (int i = 0; i < el.GetNP(); i++) - if (points[el[i]].Type() > SURFACEPOINT) - points[el[i]].SetType(SURFACEPOINT); - } - /* - else - { - cerr << "surf points nrs > points.Size" << endl; - } - */ - - SurfaceElementIndex si = surfelements.Size(); - surfelements.Append (el); - - lock.UnLock(); - return si; - } - - - ElementIndex Mesh :: AddVolumeElement (const Element & el) - { - NgLock lock(mutex); - lock.Lock(); - - int maxn = el[0]; - for (int i = 1; i < el.GetNP(); i++) - if (el[i] > maxn) maxn = el[i]; - - maxn += 1-PointIndex::BASE; - - /* - if (maxn > ptyps.Size()) - { - int maxo = ptyps.Size(); - ptyps.SetSize (maxn); - for (i = maxo+PointIndex::BASE; - i < maxn+PointIndex::BASE; i++) - ptyps[i] = INNERPOINT; - } - */ - /* - if (maxn > points.Size()) - { - cerr << "add vol element before point" << endl; - } - */ - - int ve = volelements.Size(); - - volelements.Append (el); - volelements.Last().flags.illegal_valid = 0; - - while (volelements.Size() > eltyps.Size()) - eltyps.Append (FREEELEMENT); - - timestamp = NextTimeStamp(); - - lock.UnLock(); - return ve; - } - - - - - - - void Mesh :: Save (const string & filename) const - { - int i, j; - - double scale = 1; // globflags.GetNumFlag ("scale", 1); - int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); - int invertsurf = 0; // globflags.GetDefineFlag ("invertsurfacemesh"); - - ofstream outfile(filename.c_str()); - - - outfile << "mesh3d" << "\n"; - - outfile << "dimension\n" << GetDimension() << "\n"; - - outfile << "\n"; - outfile << "# surfnr bcnr domin domout np p1 p2 p3" - << "\n"; - - outfile << "surfaceelementsgi" << "\n"; - // outfile << "surfaceelements" << "\n"; - outfile << GetNSE() << "\n"; - - SurfaceElementIndex sei; - for (sei = 0; sei < GetNSE(); sei++) - { - if ((*this)[sei].GetIndex()) - { - outfile.width(8); - outfile << GetFaceDescriptor((*this)[sei].GetIndex ()).SurfNr()+1; - outfile.width(8); - outfile << GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); - outfile.width(8); - outfile << GetFaceDescriptor((*this)[sei].GetIndex ()).DomainIn(); - outfile.width(8); - outfile << GetFaceDescriptor((*this)[sei].GetIndex ()).DomainOut(); - } - else - outfile << " 0 0 0"; - - - Element2d sel = (*this)[sei]; - if (invertsurf) - sel.Invert(); - - outfile.width(8); - outfile << sel.GetNP(); - - for (j = 0; j < sel.GetNP(); j++) - { - outfile.width(8); - outfile << sel[j]; - } - - for (j = 1; j <= sel.GetNP(); j++) - { - outfile.width(7); - outfile << " " << sel.GeomInfoPi(j).trignum; - } - outfile << endl; - } - - outfile << "\n" << "\n"; - outfile << "# matnr np p1 p2 p3 p4" << "\n"; - outfile << "volumeelements" << "\n"; - outfile << GetNE() << "\n"; - - for (ElementIndex ei = 0; ei < GetNE(); ei++) - { - outfile.width(8); - outfile << (*this)[ei].GetIndex(); - outfile.width(8); - outfile << (*this)[ei].GetNP(); - - Element el = (*this)[ei]; - if (inverttets) - el.Invert(); - - for (j = 0; j < el.GetNP(); j++) - { - outfile.width(8); - outfile << el[j]; - } - outfile << "\n"; - } - - - outfile << "\n" << "\n"; - outfile << " surf1 surf2 p1 p2" << "\n"; - outfile << "edgesegmentsgi2" << "\n"; - outfile << GetNSeg() << "\n"; - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment (i); - outfile.width(8); - outfile << seg.si; - outfile.width(8); - outfile << 0; - outfile.width(8); - outfile << seg.p1; - outfile.width(8); - outfile << seg.p2; - outfile << " "; - outfile.width(8); - outfile << seg.geominfo[0].trignum; - outfile << " "; - outfile.width(8); - outfile << seg.geominfo[1].trignum << endl; - - outfile << " "; - outfile.width(8); - outfile << seg.surfnr1+1; - outfile << " "; - outfile.width(8); - outfile << seg.surfnr2+1; - outfile << " "; - outfile.width(8); - outfile << seg.edgenr; - // outfile << seg.epgeominfo[0].edgenr; - /* - outfile.width(8); - outfile << seg.epgeominfo[0].lefttrig; - outfile.width(8); - outfile << seg.epgeominfo[0].righttrig; - */ - outfile << " "; - outfile.width(12); - outfile << seg.epgeominfo[0].dist; - outfile << " "; - outfile.width(8); - outfile << seg.epgeominfo[1].edgenr; - /* - outfile.width(8); - outfile << seg.epgeominfo[1].lefttrig; - outfile.width(8); - outfile << seg.epgeominfo[1].righttrig; - */ - outfile << " "; - outfile.width(12); - outfile << seg.epgeominfo[1].dist; - - outfile << "\n"; - } - - - outfile << "\n" << "\n"; - outfile << "# X Y Z" << "\n"; - outfile << "points" << "\n"; - outfile << GetNP() << "\n"; - outfile.precision(16); - outfile.setf (ios::fixed, ios::floatfield); - outfile.setf (ios::showpoint); - - PointIndex pi; - for (pi = PointIndex::BASE; - pi < GetNP()+PointIndex::BASE; pi++) - { - outfile.width(22); - outfile << (*this)[pi].X()/scale << " "; - outfile.width(22); - outfile << (*this)[pi].Y()/scale << " "; - outfile.width(22); - outfile << (*this)[pi].Z()/scale << "\n"; - } - - if (ident -> GetMaxNr() > 0) - { - outfile << "identifications\n"; - ARRAY<INDEX_2> identpairs; - int cnt = 0; - for (i = 1; i <= ident -> GetMaxNr(); i++) - { - ident -> GetPairs (i, identpairs); - cnt += identpairs.Size(); - } - outfile << cnt << "\n"; - for (i = 1; i <= ident -> GetMaxNr(); i++) - { - ident -> GetPairs (i, identpairs); - for (j = 1; j <= identpairs.Size(); j++) - { - outfile.width (8); - outfile << identpairs.Get(j).I1(); - outfile.width (8); - outfile << identpairs.Get(j).I2(); - outfile.width (8); - outfile << i << "\n"; - } - } - } - - int cntmat = 0; - for (i = 1; i <= materials.Size(); i++) - if (materials.Get(i) && strlen (materials.Get(i))) - cntmat++; - - if (cntmat) - { - outfile << "materials" << endl; - outfile << cntmat << endl; - for (i = 1; i <= materials.Size(); i++) - if (materials.Get(i) && strlen (materials.Get(i))) - outfile << i << " " << materials.Get(i) << endl; - } - - - int cnt_sing = 0; - for (PointIndex pi = PointIndex::BASE; pi < GetNP()+PointIndex::BASE; pi++) - if ((*this)[pi].IsSingular()) cnt_sing++; - - if (cnt_sing) - { - outfile << "singular_points" << endl << cnt_sing << endl; - for (PointIndex pi = PointIndex::BASE; pi < GetNP()+PointIndex::BASE; pi++) - if ((*this)[pi].IsSingular()) - outfile << int(pi) << endl; - } - - cnt_sing = 0; - for (SegmentIndex si = 0; si < GetNSeg(); si++) - if ( segments[si].singedge_left ) cnt_sing++; - if (cnt_sing) - { - outfile << "singular_edge_left" << endl << cnt_sing << endl; - for (SegmentIndex si = 0; si < GetNSeg(); si++) - if ( segments[si].singedge_left ) - outfile << int(si) << endl; - } - - cnt_sing = 0; - for (SegmentIndex si = 0; si < GetNSeg(); si++) - if ( segments[si].singedge_right ) cnt_sing++; - if (cnt_sing) - { - outfile << "singular_edge_right" << endl << cnt_sing << endl; - for (SegmentIndex si = 0; si < GetNSeg(); si++) - if ( segments[si].singedge_right ) - outfile << int(si) << endl; - } - - - cnt_sing = 0; - for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) - if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domin_singular) cnt_sing++; - if (cnt_sing) - { - outfile << "singular_face_inside" << endl << cnt_sing << endl; - for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) - if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domin_singular) - outfile << int(sei) << endl; - } - - cnt_sing = 0; - for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) - if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domout_singular) cnt_sing++; - if (cnt_sing) - { - outfile << "singular_face_outside" << endl << cnt_sing << endl; - for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) - if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domout_singular) - outfile << int(sei) << endl; - } - - - } - - - void Mesh :: Load (const string & filename) - { - char str[100]; - int i, n; - - double scale = 1; // globflags.GetNumFlag ("scale", 1); - int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); - int invertsurf = 0; // globflags.GetDefineFlag ("invertsurfacemesh"); - - ifstream infile(filename.c_str()); - if (!infile.good()) - throw NgException ("mesh file not found"); - - facedecoding.SetSize(0); - - while (infile.good()) - { - infile >> str; - - if (strcmp (str, "dimension") == 0) - { - infile >> dimension; - } - - if (strcmp (str, "surfaceelements") == 0) - { - infile >> n; - PrintMessage (3, n, " surface elements"); - for (i = 1; i <= n; i++) - { - int j; - int surfnr, bcp, domin, domout, nep, faceind = 0; - - infile >> surfnr >> bcp >> domin >> domout; - surfnr--; - - for (j = 1; j <= facedecoding.Size(); j++) - if (GetFaceDescriptor(j).SurfNr() == surfnr && - GetFaceDescriptor(j).BCProperty() == bcp && - GetFaceDescriptor(j).DomainIn() == domin && - GetFaceDescriptor(j).DomainOut() == domout) - faceind = j; - - if (!faceind) - { - faceind = AddFaceDescriptor (FaceDescriptor(surfnr, domin, domout, 0)); - GetFaceDescriptor(faceind).SetBCProperty (bcp); - } - - infile >> nep; - if (!nep) nep = 3; - - Element2d tri(nep); - tri.SetIndex(faceind); - - for (j = 1; j <= nep; j++) - infile >> tri.PNum(j); - - if (invertsurf) - tri.Invert(); - - AddSurfaceElement (tri); - } - } - - if (strcmp (str, "surfaceelementsgi") == 0) - { - infile >> n; - PrintMessage (3, n, " surface elements"); - for (i = 1; i <= n; i++) - { - int j; - int surfnr, bcp, domin, domout, nep, faceind = 0; - infile >> surfnr >> bcp >> domin >> domout; - surfnr--; - - for (j = 1; j <= facedecoding.Size(); j++) - if (GetFaceDescriptor(j).SurfNr() == surfnr && - GetFaceDescriptor(j).BCProperty() == bcp && - GetFaceDescriptor(j).DomainIn() == domin && - GetFaceDescriptor(j).DomainOut() == domout) - faceind = j; - - if (!faceind) - { - faceind = AddFaceDescriptor (FaceDescriptor(surfnr, domin, domout, 0)); - GetFaceDescriptor(faceind).SetBCProperty (bcp); - } - - infile >> nep; - if (!nep) nep = 3; - - Element2d tri(nep); - tri.SetIndex(faceind); - - for (j = 1; j <= nep; j++) - infile >> tri.PNum(j); - - for (j = 1; j <= nep; j++) - infile >> tri.GeomInfoPi(j).trignum; - - if (invertsurf) - tri.Invert(); - - AddSurfaceElement (tri); - } - } - - if (strcmp (str, "volumeelements") == 0) - { - infile >> n; - PrintMessage (3, n, " volume elements"); - for (i = 1; i <= n; i++) - { - Element el; - int hi, nep; - infile >> hi; - if (hi == 0) hi = 1; - el.SetIndex(hi); - infile >> nep; - el.SetNP(nep); - - for (int j = 0; j < nep; j++) - infile >> (int&)(el[j]); - - if (inverttets) - el.Invert(); - - AddVolumeElement (el); - } - } - - - if (strcmp (str, "edgesegments") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - Segment seg; - int hi; - infile >> seg.si >> hi >> seg.p1 >> seg.p2; - AddSegment (seg); - } - } - - - - if (strcmp (str, "edgesegmentsgi") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - Segment seg; - int hi; - infile >> seg.si >> hi >> seg.p1 >> seg.p2 - >> seg.geominfo[0].trignum - >> seg.geominfo[1].trignum; - AddSegment (seg); - } - } - if (strcmp (str, "edgesegmentsgi2") == 0) - { - infile >> n; - PrintMessage (3, n, " curve elements"); - - for (i = 1; i <= n; i++) - { - Segment seg; - int hi; - infile >> seg.si >> hi >> seg.p1 >> seg.p2 - >> seg.geominfo[0].trignum - >> seg.geominfo[1].trignum - >> seg.surfnr1 >> seg.surfnr2 - >> seg.edgenr - // >> seg.epgeominfo[0].edgenr - // >> seg.epgeominfo[0].lefttrig - // >> seg.epgeominfo[0].righttrig - >> seg.epgeominfo[0].dist - >> seg.epgeominfo[1].edgenr - // >> seg.epgeominfo[1].lefttrig - // >> seg.epgeominfo[1].righttrig - >> seg.epgeominfo[1].dist; - // seg.edgenr = seg.epgeominfo[0].edgenr; - seg.epgeominfo[0].edgenr = seg.epgeominfo[1].edgenr; - - seg.surfnr1--; - seg.surfnr2--; - - AddSegment (seg); - } - } - - if (strcmp (str, "points") == 0) - { - infile >> n; - PrintMessage (3, n, " points"); - for (i = 1; i <= n; i++) - { - Point3d p; - infile >> p.X() >> p.Y() >> p.Z(); - p.X() *= scale; - p.Y() *= scale; - p.Z() *= scale; - AddPoint (p); - } - } - - if (strcmp (str, "identifications") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - PointIndex pi1, pi2; - int ind; - infile >> pi1 >> pi2 >> ind; - ident -> Add (pi1, pi2, ind); - } - } - if (strcmp (str, "materials") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - int nr; - string mat; - infile >> nr >> mat; - SetMaterial (nr, mat.c_str()); - } - } - - if (strcmp (str, "singular_points") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - PointIndex pi; - infile >> pi; - (*this)[pi].SetSingular (1); - } - } - - if (strcmp (str, "singular_edge_left") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - SegmentIndex si; - infile >> si; - (*this)[si].singedge_left = 1; - } - } - if (strcmp (str, "singular_edge_right") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - SegmentIndex si; - infile >> si; - (*this)[si].singedge_right = 1; - } - } - - if (strcmp (str, "singular_face_inside") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - SurfaceElementIndex sei; - infile >> sei; - GetFaceDescriptor((*this)[sei].GetIndex()).domin_singular = 1; - } - } - - if (strcmp (str, "singular_face_outside") == 0) - { - infile >> n; - for (i = 1; i <= n; i++) - { - SurfaceElementIndex sei; - infile >> sei; - GetFaceDescriptor((*this)[sei].GetIndex()).domout_singular = 1; - } - } - - - - strcpy (str, ""); - } - - CalcSurfacesOfNode (); - // BuildConnectedNodes (); - topology -> Update(); - clusters -> Update(); - - SetNextMajorTimeStamp(); - // PrintMemInfo (cout); - } - - - - - - - void Mesh :: Merge (const string & filename) - { - char str[100]; - int i, n; - - ifstream infile(filename.c_str()); - if (!infile.good()) - throw NgException ("mesh file not found"); - - int oldnp = GetNP(); - - while (infile.good()) - { - infile >> str; - - if (strcmp (str, "surfaceelementsgi") == 0) - { - infile >> n; - PrintMessage (3, n, " surface elements"); - for (i = 1; i <= n; i++) - { - int j; - int surfnr, bcp, domin, domout, nep, faceind = 0; - infile >> surfnr >> bcp >> domin >> domout; - surfnr--; - - // surfnr = 0; - // bcp = 1; - domin = 2; - domout = 1; - - for (j = 1; j <= facedecoding.Size(); j++) - if (GetFaceDescriptor(j).SurfNr() == surfnr && - GetFaceDescriptor(j).BCProperty() == bcp && - GetFaceDescriptor(j).DomainIn() == domin && - GetFaceDescriptor(j).DomainOut() == domout) - faceind = j; - - if (!faceind) - { - faceind = AddFaceDescriptor (FaceDescriptor(surfnr, domin, domout, 0)); - GetFaceDescriptor(faceind).SetBCProperty (bcp); - } - - infile >> nep; - if (!nep) nep = 3; - - Element2d tri(nep); - tri.SetIndex(faceind); - - for (j = 1; j <= nep; j++) - { - infile >> tri.PNum(j); - tri.PNum(j) = tri.PNum(j) + oldnp; - } - - for (j = 1; j <= nep; j++) - infile >> tri.GeomInfoPi(j).trignum; - - AddSurfaceElement (tri); - } - } - - if (strcmp (str, "points") == 0) - { - infile >> n; - PrintMessage (3, n, " points"); - for (i = 1; i <= n; i++) - { - Point3d p; - infile >> p.X() >> p.Y() >> p.Z(); - AddPoint (p); - } - } - - strcpy (str, ""); - } - - CalcSurfacesOfNode (); - - topology -> Update(); - clusters -> Update(); - - SetNextMajorTimeStamp(); - } - - - - - - - - - - - bool Mesh :: TestOk () const - { - for (ElementIndex ei = 0; ei < volelements.Size(); ei++) - { - for (int j = 0; j < 4; j++) - if ( (*this)[ei][j] <= PointIndex::BASE-1) - { - (*testout) << "El " << ei << " has 0 nodes: "; - for (int k = 0; k < 4; k++) - (*testout) << (*this)[ei][k]; - break; - } - } - CheckMesh3D (*this); - return 1; - } - - void Mesh :: CalcSurfacesOfNode () - { - int i, j, k; - SurfaceElementIndex sei; - - surfacesonnode.SetSize (GetNP()); - if (boundaryedges) - delete boundaryedges; - if (surfelementht) - delete surfelementht; - if (segmentht) - delete segmentht; - - boundaryedges = new INDEX_2_CLOSED_HASHTABLE<int> - (3 * (GetNSE() + GetNOpenElements()) + GetNSeg() + 1); - - /* - surfelementht = new INDEX_3_HASHTABLE<int> (GetNSE()/4 + 1); - segmentht = new INDEX_2_HASHTABLE<int> (GetNSeg() + 1); - */ - - surfelementht = new INDEX_3_CLOSED_HASHTABLE<int> (3*GetNSE() + 1); - segmentht = new INDEX_2_CLOSED_HASHTABLE<int> (3*GetNSeg() + 1); - - for (sei = 0; sei < GetNSE(); sei++) - { - const Element2d & sel = surfelements[sei]; - if (sel.IsDeleted()) continue; - - int si = sel.GetIndex(); - - for (j = 0; j < sel.GetNP(); j++) - { - PointIndex pi = sel[j]; - bool found = 0; - for (k = 0; k < surfacesonnode[pi].Size(); k++) - if (surfacesonnode[pi][k] == si) - { - found = 1; - break; - } - - if (!found) - surfacesonnode.Add (pi, si); - - INDEX_2 i2; - i2.I1() = sel.PNumMod(j+1); - i2.I2() = sel.PNumMod(j+2); - i2.Sort(); - if (sel.GetNP() <= 4) - boundaryedges->Set (i2, 1); - } - } - /* - for (sei = 0; sei < GetNSE(); sei++) - { - const Element2d & sel = surfelements[sei]; - if (sel.IsDeleted()) continue; - - INDEX_3 i3; - i3.I1() = sel.PNum(1); - i3.I2() = sel.PNum(2); - i3.I3() = sel.PNum(3); - i3.Sort(); - surfelementht -> PrepareSet (i3); - } - - surfelementht -> AllocateElements(); - */ - for (sei = 0; sei < GetNSE(); sei++) - { - const Element2d & sel = surfelements[sei]; - if (sel.IsDeleted()) continue; - - INDEX_3 i3; - i3.I1() = sel.PNum(1); - i3.I2() = sel.PNum(2); - i3.I3() = sel.PNum(3); - i3.Sort(); - surfelementht -> Set (i3, sel.GetIndex()); - } - - int np = GetNP(); - // ptyps.SetSize(np); - // ptyps = INNERPOINT; - for (PointIndex pi = PointIndex::BASE; - pi < np+PointIndex::BASE; pi++) - points[pi].SetType (INNERPOINT); - - if (GetNFD() == 0) // || GetFaceDescriptor(1).SurfNr() == 0) - { - for (sei = 0; sei < GetNSE(); sei++) - { - const Element2d & sel = surfelements[sei]; - if (sel.IsDeleted()) continue; - for (j = 0; j < sel.GetNP(); j++) - { - PointIndex pi = SurfaceElement(sei)[j]; - points[pi].SetType(FIXEDPOINT); - } - } - } - else - { - for (sei = 0; sei < GetNSE(); sei++) - { - const Element2d & sel = surfelements[sei]; - if (sel.IsDeleted()) continue; - for (j = 0; j < sel.GetNP(); j++) - { - PointIndex pi = sel[j]; - int ns = surfacesonnode[pi].Size(); - if (ns == 1) - points[pi].SetType(SURFACEPOINT); - if (ns == 2) - points[pi].SetType(EDGEPOINT); - if (ns >= 3) - points[pi].SetType(FIXEDPOINT); - } - } - } - - for (i = 0; i < segments.Size(); i++) - { - const Segment & seg = segments[i]; - for (j = 1; j <= 2; j++) - { - PointIndex hi = (j == 1) ? seg.p1 : seg.p2; - - if (points[hi].Type() == INNERPOINT || - points[hi].Type() == SURFACEPOINT) - points[hi].SetType(EDGEPOINT); - } - } - - - for (i = 0; i < lockedpoints.Size(); i++) - points[lockedpoints[i]].SetType(FIXEDPOINT); - - for (i = 0; i < openelements.Size(); i++) - { - const Element2d & sel = openelements[i]; - for (j = 0; j < sel.GetNP(); j++) - { - INDEX_2 i2; - i2.I1() = sel.PNumMod(j+1); - i2.I2() = sel.PNumMod(j+2); - i2.Sort(); - boundaryedges->Set (i2, 1); - - points[sel[j]].SetType(FIXEDPOINT); - } - } - - eltyps.SetSize (GetNE()); - eltyps = FREEELEMENT; - - for (i = 0; i < GetNSeg(); i++) - { - const Segment & seg = segments[i]; - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort(); - - boundaryedges -> Set (i2, 2); - segmentht -> Set (i2, i); - } - } - - - void Mesh :: FixPoints (const BitArray & fixpoints) - { - if (fixpoints.Size() != GetNP()) - { - cerr << "Mesh::FixPoints: sizes don�t fit" << endl; - return; - } - int np = GetNP(); - for (int i = 1; i <= np; i++) - if (fixpoints.Test(i)) - { - points.Elem(i).SetType (FIXEDPOINT); - } - } - - - void Mesh :: FindOpenElements (int dom) - { - int i, ii, j, k, l; - PointIndex pi; - SurfaceElementIndex sei; - Element2d hel; - - - if (1) - { // nodebased - - int np = GetNP(); - int ne = GetNE(); - int nse = GetNSE(); - - ARRAY<int,PointIndex::BASE> numonpoint(np); - - Element2d hel; - - numonpoint = 0; - ElementIndex ei; - for (ei = 0; ei < ne; ei++) - { - const Element & el = (*this)[ei]; - if (dom == 0 || dom == el.GetIndex()) - { - if (el.GetNP() == 4) - { - INDEX_4 i4(el[0], el[1], el[2], el[3]); - i4.Sort(); - numonpoint[i4.I1()]++; - numonpoint[i4.I2()]++; - } - else - for (j = 0; j < el.GetNP(); j++) - numonpoint[el[j]]++; - } - } - - TABLE<ElementIndex,PointIndex::BASE> elsonpoint(numonpoint); - for (ei = 0; ei < ne; ei++) - { - const Element & el = (*this)[ei]; - if (dom == 0 || dom == el.GetIndex()) - { - if (el.GetNP() == 4) - { - INDEX_4 i4(el[0], el[1], el[2], el[3]); - i4.Sort(); - elsonpoint.Add (i4.I1(), ei); - elsonpoint.Add (i4.I2(), ei); - } - else - for (j = 0; j < el.GetNP(); j++) - elsonpoint.Add (el[j], ei); - } - } - - numonpoint = 0; - for (i = 0; i < nse; i++) - { - int ind = surfelements[i].GetIndex(); - if ( - GetFaceDescriptor(ind).DomainIn() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) - || - GetFaceDescriptor(ind).DomainOut() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) - ) - { - hel = surfelements[i]; - hel.NormalizeNumbering(); - numonpoint[hel[0]]++; - } - } - - TABLE<SurfaceElementIndex,PointIndex::BASE> selsonpoint(numonpoint); - for (i = 0; i < nse; i++) - { - int ind = surfelements[i].GetIndex(); - if ( - GetFaceDescriptor(ind).DomainIn() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) - || - GetFaceDescriptor(ind).DomainOut() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) - ) - { - hel = surfelements[i]; - hel.NormalizeNumbering(); - selsonpoint.Add (hel[0], i); - } - } - - - INDEX_3_CLOSED_HASHTABLE<INDEX_2> faceht(100); - openelements.SetSize(0); - - for (pi = PointIndex::BASE; - pi < np+PointIndex::BASE; pi++) - if (selsonpoint[pi].Size()+elsonpoint[pi].Size()) - { - faceht.SetSize (2 * selsonpoint[pi].Size() + 4 * elsonpoint[pi].Size()); - - FlatArray<SurfaceElementIndex> row = selsonpoint[pi]; - for (ii = 0; ii < row.Size(); ii++) - { - hel = SurfaceElement(row[ii]); - int ind = hel.GetIndex(); - - if (GetFaceDescriptor(ind).DomainIn() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) ) - { - hel.NormalizeNumbering(); - if (hel.PNum(1) == pi) - { - INDEX_3 i3(hel[0], hel[1], hel[2]); - INDEX_2 i2 (GetFaceDescriptor(ind).DomainIn(), - (hel.GetNP() == 3) - ? PointIndex (PointIndex::BASE-1) - : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - if (GetFaceDescriptor(ind).DomainOut() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) ) - { - hel.Invert(); - hel.NormalizeNumbering(); - if (hel.PNum(1) == pi) - { - INDEX_3 i3(hel[0], hel[1], hel[2]); - INDEX_2 i2 (GetFaceDescriptor(ind).DomainOut(), - (hel.GetNP() == 3) - ? PointIndex (PointIndex::BASE-1) - : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - } - - - FlatArray<ElementIndex> rowel = elsonpoint[pi]; - for (ii = 0; ii < rowel.Size(); ii++) - { - const Element & el = VolumeElement(rowel[ii]); - - if (dom == 0 || el.GetIndex() == dom) - { - for (j = 1; j <= el.GetNFaces(); j++) - { - el.GetFace (j, hel); - hel.Invert(); - hel.NormalizeNumbering(); - - if (hel[0] == pi) - { - INDEX_3 i3(hel[0], hel[1], hel[2]); - - if (faceht.Used (i3)) - { - INDEX_2 i2 = faceht.Get(i3); - if (i2.I1() == el.GetIndex()) - { - i2.I1() = PointIndex::BASE-1; - faceht.Set (i3, i2); - } - else - { - if (i2.I1() == 0) - { - PrintSysError ("more elements on face"); - (*testout) << "more elements on face!!!" << endl; - (*testout) << "el = " << el << endl; - (*testout) << "hel = " << hel << endl; - (*testout) << "face = " << i3 << endl; - (*testout) << "points = " << endl; - for (int jj = 1; jj <= 3; jj++) - (*testout) << "p = " << Point(i3.I(jj)) << endl; - } - } - } - else - { - hel.Invert(); - hel.NormalizeNumbering(); - INDEX_3 i3(hel[0], hel[1], hel[2]); - INDEX_2 i2(el.GetIndex(), - (hel.GetNP() == 3) - ? PointIndex (PointIndex::BASE-1) - : hel[3]); - faceht.Set (i3, i2); - } - } - } - } - } - - for (i = 1; i <= faceht.Size(); i++) - if (faceht.UsedPos (i)) - { - INDEX_3 i3; - INDEX_2 i2; - faceht.GetData (i, i3, i2); - if (i2.I1() != PointIndex::BASE-1) - { - Element2d tri; - tri.SetType ( (i2.I2() == PointIndex::BASE-1) ? TRIG : QUAD); - for (l = 0; l < 3; l++) - tri[l] = i3.I(l+1); - tri.PNum(4) = i2.I2(); - tri.SetIndex (i2.I1()); - - // tri.Invert(); - - openelements.Append (tri); - } - } - } - } - - -#ifdef OLD - - else if (GetNE() || 1) - { - // new version, general elemetns - // hash index: pnum1-3 - // hash data : domain nr, pnum4 - - openelements.SetSize(0); - - - const int steps = 4; - - for (k = 0; k < steps; k++) - { - - INDEX_3_CLOSED_HASHTABLE<INDEX_2> faceht( (5 * GetNE() + 2 * GetNSE() ) / steps +1); - - for (i = 1; i <= GetNSE(); i++) - { - hel = SurfaceElement(i); - int ind = hel.GetIndex(); - - - if (GetFaceDescriptor(ind).DomainIn() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) ) - { - hel.Invert(); - hel.NormalizeNumbering(); - if (hel.PNum(1) % steps == k) - { - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - INDEX_2 i2 (GetFaceDescriptor(ind).DomainIn(), - (hel.GetNP() == 3) - ? PointIndex (PointIndex::BASE-1) - : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - if (GetFaceDescriptor(ind).DomainOut() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) ) - { - hel.NormalizeNumbering(); - if (hel.PNum(1) % steps == k) - { - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - INDEX_2 i2 (GetFaceDescriptor(ind).DomainOut(), - (hel.GetNP() == 3) - ? PointIndex(0) - : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - } - - for (i = 1; i <= GetNE(); i++) - { - const Element & el = VolumeElement(i); - - if (dom == 0 || el.GetIndex() == dom) - { - for (j = 1; j <= el.GetNFaces(); j++) - { - el.GetFace (j, hel); - - hel.NormalizeNumbering(); - if (hel.PNum(1) % steps != k) - continue; - - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - - int pos = faceht.Position (i3); - if (pos) - { - INDEX_2 i2; - faceht.GetData (pos, i2); - if (i2.I1() == el.GetIndex()) - { - i2.I1() = 0; - faceht.SetData (pos, i2); - } - else - { - if (i2.I1() == 0) - PrintSysError ("more elements on face"); - } - } - else - { - hel.Invert(); - hel.NormalizeNumbering(); - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - INDEX_2 i2(el.GetIndex(), - (hel.GetNP() == 3) - ? PointIndex(0) - : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - } - } - - for (i = 1; i <= faceht.Size(); i++) - if (faceht.UsedPos (i)) - { - INDEX_3 i3; - INDEX_2 i2; - faceht.GetData (i, i3, i2); - if (i2.I1() != 0) - { - Element2d tri; - tri.SetType ( (i2.I2() == 0) ? TRIG : QUAD); - for (l = 1; l <= 3; l++) - tri.PNum(l) = i3.I(l); - tri.PNum(4) = i2.I2(); - tri.SetIndex (i2.I1()); - - tri.Invert(); - - openelements.Append (tri); - } - } - /* - cout << "FindOpenElements, mem = "; - faceht.PrintMemInfo (cout); - */ - } - - - - - /* - // open hashing version: - - INDEX_3_HASHTABLE<INDEX_2> faceht(4 * GetNE()+GetNSE()+1); - - for (i = 1; i <= GetNSE(); i++) - { - Element2d hel = SurfaceElement(i); - int ind = hel.GetIndex(); - - - if (GetFaceDescriptor(ind).DomainIn() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) ) - { - hel.NormalizeNumbering(); - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - INDEX_2 i2 (GetFaceDescriptor(ind).DomainIn(), - (hel.GetNP() == 3) ? 0 : hel.PNum(4)); - faceht.Set (i3, i2); - } - if (GetFaceDescriptor(ind).DomainOut() && - (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) ) - { - hel.Invert(); - hel.NormalizeNumbering(); - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - INDEX_2 i2 (GetFaceDescriptor(ind).DomainOut(), - (hel.GetNP() == 3) ? 0 : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - - for (i = 1; i <= GetNE(); i++) - { - const Element & el = VolumeElement(i); - // INDEX_3 i3; - - if (dom == 0 || el.GetIndex() == dom) - { - for (j = 1; j <= el.GetNFaces(); j++) - { - Element2d hel; - el.GetFace (j, hel); - hel.Invert(); - - hel.NormalizeNumbering(); - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - - if (faceht.Used (i3)) - { - INDEX_2 i2 = faceht.Get(i3); - if (i2.I1() == el.GetIndex()) - { - i2.I1() = 0; - faceht.Set (i3, i2); - } - else - { - if (i2.I1() == 0) - PrintSysError ("more elements on face"); - } - } - else - { - hel.Invert(); - hel.NormalizeNumbering(); - INDEX_3 i3(hel.PNum(1), hel.PNum(2), hel.PNum(3)); - INDEX_2 i2(el.GetIndex(), - (hel.GetNP() == 3) ? 0 : hel.PNum(4)); - faceht.Set (i3, i2); - } - } - } - } - - - openelements.SetSize(0); - for (i = 1; i <= faceht.GetNBags(); i++) - for (j = 1; j <= faceht.GetBagSize(i); j++) - { - INDEX_3 i3; - INDEX_2 i2; - faceht.GetData (i, j, i3, i2); - if (i2.I1() != 0) - { - Element2d tri; - tri.SetNP ( (i2.I2() == 0) ? 3 : 4); - for (k = 1; k <= 3; k++) - tri.PNum(k) = i3.I(k); - tri.PNum(4) = i2.I2(); - tri.SetIndex (i2.I1()); - - openelements.Append (tri); - } - } - */ - - } - else - { - for (i = 1; i <= GetNSE(); i++) - { - Element2d hel = SurfaceElement(i); - int ind = SurfaceElement(i).GetIndex(); - - if (GetFaceDescriptor(ind).DomainIn()) - openelements.Append (hel); - if (GetFaceDescriptor(ind).DomainOut()) - { - hel.Invert(); - openelements.Append (hel); - } - } - } -#endif - - - int cnt3 = 0, cnt4 = 0; - for (i = 1; i <= openelements.Size(); i++) - if (openelements.Elem(i).GetNP() == 3) - cnt3++; - else - cnt4++; - - - MyStr treequad; - if (cnt4) - treequad = MyStr(" (") + MyStr(cnt3) + MyStr (" + ") + - MyStr(cnt4) + MyStr(")"); - - PrintMessage (5, openelements.Size(), treequad, " open elements"); - - - for (i = 1; i <= openelements.Size(); i++) - { - const Element2d & sel = openelements.Get(i); - - if (boundaryedges) - for (j = 1; j <= sel.GetNP(); j++) - { - INDEX_2 i2; - i2.I1() = sel.PNumMod(j); - i2.I2() = sel.PNumMod(j+1); - i2.Sort(); - boundaryedges->Set (i2, 1); - } - - for (j = 1; j <= 3; j++) - { - int pi = sel.PNum(j); - if (pi < points.Size()+PointIndex::BASE) - points[pi].SetType (FIXEDPOINT); - } - } - - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment(i); - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort(); - - if (!boundaryedges->Used (i2)) - cerr << "WARNING: no boundedge, but seg edge: " << i2 << endl; - - boundaryedges -> Set (i2, 2); - segmentht -> Set (i2, i-1); - } - } - - int Mesh :: HasOpenQuads () const - { - int i; - int no = GetNOpenElements(); - for (i = 1; i <= no; i++) - if (OpenElement(i).GetNP() == 4) - return 1; - return 0; - } - - - - - - void Mesh :: FindOpenSegments (int surfnr) - { - int i, j, k; - - // new version, general elemetns - // hash index: pnum1-2 - // hash data : surfnr, surfel-nr (pos) or segment nr(neg) - INDEX_2_HASHTABLE<INDEX_2> faceht(4 * GetNSE()+GetNSeg()+1); - - PrintMessage (5, "Test Opensegments"); - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment (i); - - if (surfnr == 0 || seg.si == surfnr) - { - INDEX_2 key(seg.p1, seg.p2); - INDEX_2 data(seg.si, -i); - - if (faceht.Used (key)) - { - cerr << "ERROR: Segment " << seg << " already used" << endl; - (*testout) << "ERROR: Segment " << seg << " already used" << endl; - } - - faceht.Set (key, data); - } - } - - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment (i); - - if (surfnr == 0 || seg.si == surfnr) - { - INDEX_2 key(seg.p2, seg.p1); - if (!faceht.Used(key)) - { - cerr << "ERROR: Segment " << seg << " brother not used" << endl; - (*testout) << "ERROR: Segment " << seg << " brother not used" << endl; - } - } - } - - - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & el = SurfaceElement(i); - if (el.IsDeleted()) continue; - - if (surfnr == 0 || el.GetIndex() == surfnr) - { - for (j = 1; j <= el.GetNP(); j++) - { - INDEX_2 seg (el.PNumMod(j), el.PNumMod(j+1)); - INDEX_2 data; - - if (seg.I1() <= 0 || seg.I2() <= 0) - cerr << "seg = " << seg << endl; - - if (faceht.Used(seg)) - { - data = faceht.Get(seg); - if (data.I1() == el.GetIndex()) - { - data.I1() = 0; - faceht.Set (seg, data); - } - else - { - PrintSysError ("hash table si not fitting for segment: ", - seg.I1(), "-", seg.I2(), " other = ", - data.I2()); - } - } - else - { - Swap (seg.I1(), seg.I2()); - data.I1() = el.GetIndex(); - data.I2() = i; - - faceht.Set (seg, data); - } - } - } - } - - (*testout) << "open segments: " << endl; - opensegments.SetSize(0); - for (i = 1; i <= faceht.GetNBags(); i++) - for (j = 1; j <= faceht.GetBagSize(i); j++) - { - INDEX_2 i2; - INDEX_2 data; - faceht.GetData (i, j, i2, data); - if (data.I1()) // surfnr - { - Segment seg; - seg.p1 = i2.I1(); - seg.p2 = i2.I2(); - seg.si = data.I1(); - - // find geomdata: - if (data.I2() > 0) - { - // segment due to triangle - const Element2d & el = SurfaceElement (data.I2()); - for (k = 1; k <= el.GetNP(); k++) - { - if (seg.p1 == el.PNum(k)) - seg.geominfo[0] = el.GeomInfoPi(k); - if (seg.p2 == el.PNum(k)) - seg.geominfo[1] = el.GeomInfoPi(k); - } - - (*testout) << "trig seg: "; - } - else - { - // segment due to line - const Segment & lseg = LineSegment (-data.I2()); - seg.geominfo[0] = lseg.geominfo[0]; - seg.geominfo[1] = lseg.geominfo[1]; - - (*testout) << "line seg: "; - } - - (*testout) << seg.p1 << " - " << seg.p2 - << " len = " << Dist (Point(seg.p1), Point(seg.p2)) - << endl; - - opensegments.Append (seg); - if (seg.geominfo[0].trignum <= 0 || seg.geominfo[1].trignum <= 0) - { - (*testout) << "Problem with open segment: " << seg << endl; - } - - } - } - - PrintMessage (3, opensegments.Size(), " open segments found"); - (*testout) << opensegments.Size() << " open segments found" << endl; - - /* - ptyps.SetSize (GetNP()); - for (i = 1; i <= ptyps.Size(); i++) - ptyps.Elem(i) = SURFACEPOINT; - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment (i); - ptyps.Elem(seg.p1) = EDGEPOINT; - ptyps.Elem(seg.p2) = EDGEPOINT; - } - for (i = 1; i <= GetNOpenSegments(); i++) - { - const Segment & seg = GetOpenSegment (i); - ptyps.Elem(seg.p1) = EDGEPOINT; - ptyps.Elem(seg.p2) = EDGEPOINT; - } - */ - for (i = 1; i <= points.Size(); i++) - points.Elem(i).SetType(SURFACEPOINT); - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment (i); - points[seg.p1].SetType(EDGEPOINT); - points[seg.p2].SetType(EDGEPOINT); - } - for (i = 1; i <= GetNOpenSegments(); i++) - { - const Segment & seg = GetOpenSegment (i); - points[seg.p1].SetType (EDGEPOINT); - points[seg.p2].SetType (EDGEPOINT); - } - - - - /* - - for (i = 1; i <= openelements.Size(); i++) - { - const Element2d & sel = openelements.Get(i); - - if (boundaryedges) - for (j = 1; j <= sel.GetNP(); j++) - { - INDEX_2 i2; - i2.I1() = sel.PNumMod(j); - i2.I2() = sel.PNumMod(j+1); - i2.Sort(); - boundaryedges->Set (i2, 1); - } - - for (j = 1; j <= 3; j++) - { - int pi = sel.PNum(j); - if (pi <= ptyps.Size()) - ptyps.Elem(pi) = FIXEDPOINT; - } - } - */ - } - - - void Mesh :: RemoveOneLayerSurfaceElements () - { - int i, j; - int np = GetNP(); - - FindOpenSegments(); - BitArray frontpoints(np); - - frontpoints.Clear(); - for (i = 1; i <= GetNOpenSegments(); i++) - { - const Segment & seg = GetOpenSegment(i); - frontpoints.Set (seg.p1); - frontpoints.Set (seg.p2); - } - - for (i = 1; i <= GetNSE(); i++) - { - Element2d & sel = surfelements.Elem(i); - int remove = 0; - for (j = 1; j <= sel.GetNP(); j++) - if (frontpoints.Test(sel.PNum(j))) - remove = 1; - if (remove) - sel.PNum(1) = 0; - } - - for (i = surfelements.Size(); i >= 1; i--) - { - if (surfelements.Elem(i).PNum(1) == 0) - { - surfelements.Elem(i) = surfelements.Last(); - surfelements.DeleteLast(); - } - } - timestamp = NextTimeStamp(); - // Compress(); - } - - - - - - void Mesh :: FreeOpenElementsEnvironment (int layers) - { - int i, j, k; - PointIndex pi; - const int large = 9999; - ARRAY<int,PointIndex::BASE> dist(GetNP()); - - dist = large; - - for (i = 1; i <= GetNOpenElements(); i++) - { - const Element2d & face = OpenElement(i); - for (j = 1; j <= face.GetNP(); j++) - dist[face.PNum(j)] = 1; - } - - for (k = 1; k <= layers; k++) - for (i = 1; i <= GetNE(); i++) - { - const Element & el = VolumeElement(i); - if (el[0] == -1 || el.IsDeleted()) continue; - - int elmin = large; - for (j = 0; j < el.GetNP(); j++) - if (dist[el[j]] < elmin) - elmin = dist[el[j]]; - - if (elmin < large) - { - for (j = 0; j < el.GetNP(); j++) - if (dist[el[j]] > elmin+1) - dist[el[j]] = elmin+1; - } - } - - int cntfree = 0; - for (i = 1; i <= GetNE(); i++) - { - const Element & el = VolumeElement(i); - if (el[0] == -1 || el.IsDeleted()) continue; - - int elmin = large; - for (j = 0; j < el.GetNP(); j++) - if (dist[el[j]] < elmin) - elmin = dist[el[j]]; - - eltyps.Elem(i) = (elmin <= layers) ? - FREEELEMENT : FIXEDELEMENT; - if (elmin <= layers) - cntfree++; - } - - PrintMessage (5, "free: ", cntfree, ", fixed: ", GetNE()-cntfree); - (*testout) << "free: " << cntfree << ", fixed: " << GetNE()-cntfree << endl; - - for (pi = PointIndex::BASE; - pi < GetNP()+PointIndex::BASE; pi++) - { - if (dist[pi] > layers+1) - points[pi].SetType(FIXEDPOINT); - } - } - - - - void Mesh :: SetLocalH (const Point3d & pmin, const Point3d & pmax, double grading) - { - Point3d c = Center (pmin, pmax); - double d = max3 (pmax.X()-pmin.X(), - pmax.Y()-pmin.Y(), - pmax.Z()-pmin.Z()); - d /= 2; - Point3d pmin2 = c - Vec3d (d, d, d); - Point3d pmax2 = c + Vec3d (d, d, d); - - - delete lochfunc; - lochfunc = new LocalH (pmin2, pmax2, grading); - } - - void Mesh :: RestrictLocalH (const Point3d & p, double hloc) - { - //cout << "restrict h in " << p << " to " << hloc << endl; - if (!lochfunc) - { - PrintWarning("RestrictLocalH called, creating mesh-size tree"); - - Point3d boxmin, boxmax; - GetBox (boxmin, boxmax); - SetLocalH (boxmin, boxmax, 0.8); - } - - lochfunc -> SetH (p, hloc); - } - - void Mesh :: RestrictLocalHLine (const Point3d & p1, - const Point3d & p2, - double hloc) - { - // cout << "restrict h along " << p1 << " - " << p2 << " to " << hloc << endl; - int i; - int steps = int (Dist (p1, p2) / hloc) + 2; - Vec3d v(p1, p2); - - for (i = 0; i <= steps; i++) - { - Point3d p = p1 + (double(i)/double(steps) * v); - RestrictLocalH (p, hloc); - } - } - - - void Mesh :: SetGlobalH (double h) - { - hglob = h; - } - - double Mesh :: MaxHDomain (int dom) const - { - if (maxhdomain.Size()) - return maxhdomain.Get(dom); - else - return 1e10; - } - - void Mesh :: SetMaxHDomain (const ARRAY<double> & mhd) - { - maxhdomain.SetSize(mhd.Size()); - for (int i = 1; i <= mhd.Size(); i++) - maxhdomain.Elem(i) = mhd.Get(i); - } - - - double Mesh :: GetH (const Point3d & p) const - { - double hmin = hglob; - if (lochfunc) - { - double hl = lochfunc->GetH (p); - if (hl < hglob) - hmin = hl; - } - return hmin; - } - - double Mesh :: GetMinH (const Point3d & pmin, const Point3d & pmax) - { - double hmin = hglob; - if (lochfunc) - { - double hl = lochfunc->GetMinH (pmin, pmax); - if (hl < hmin) - hmin = hl; - } - return hmin; - } - - - - - - double Mesh :: AverageH (int surfnr) const - { - int i, j, n; - double hi, hsum; - double maxh = 0, minh = 1e10; - - hsum = 0; - n = 0; - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & el = SurfaceElement(i); - if (surfnr == 0 || el.GetIndex() == surfnr) - { - for (j = 1; j <= 3; j++) - { - hi = Dist (Point (el.PNumMod(j)), - Point (el.PNumMod(j+1))); - - hsum += hi; - - if (hi > maxh) maxh = hi; - if (hi < minh) minh = hi; - n++; - } - } - } - - PrintMessage (5, "minh = ", minh, " avh = ", (hsum/n), " maxh = ", maxh); - return (hsum / n); - } - - - - void Mesh :: CalcLocalH () - { - if (!lochfunc) - { - Point3d pmin, pmax; - GetBox (pmin, pmax); - SetLocalH (pmin, pmax, mparam.grading); - } - - PrintMessage (3, - "CalcLocalH: ", - GetNP(), " Points ", - GetNE(), " Elements ", - GetNSE(), " Surface Elements"); - - - int i; - for (i = 0; i < GetNSE(); i++) - { - const Element2d & el = surfelements[i]; - int j; - - if (el.GetNP() == 3) - { - double hel = -1; - for (j = 1; j <= 3; j++) - { - const Point3d & p1 = points[el.PNumMod(j)]; - const Point3d & p2 = points[el.PNumMod(j+1)]; - - /* - INDEX_2 i21(el.PNumMod(j), el.PNumMod(j+1)); - INDEX_2 i22(el.PNumMod(j+1), el.PNumMod(j)); - if (! identifiedpoints->Used (i21) && - ! identifiedpoints->Used (i22) ) - */ - if (!ident -> UsedSymmetric (el.PNumMod(j), - el.PNumMod(j+1))) - { - double hedge = Dist (p1, p2); - if (hedge > hel) - hel = hedge; - // lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); - // (*testout) << "trigseth, p1,2 = " << el.PNumMod(j) << ", " << el.PNumMod(j+1) - // << " h = " << (2 * Dist(p1, p2)) << endl; - } - } - - if (hel > 0) - { - const Point3d & p1 = points[el.PNum(1)]; - const Point3d & p2 = points[el.PNum(2)]; - const Point3d & p3 = points[el.PNum(3)]; - lochfunc->SetH (Center (p1, p2, p3), hel); - } - } - else - { - { - const Point3d & p1 = points[el.PNum(1)]; - const Point3d & p2 = points[el.PNum(2)]; - lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); - } - { - const Point3d & p1 = points[el.PNum(3)]; - const Point3d & p2 = points[el.PNum(4)]; - lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); - } - } - } - - for (i = 0; i < GetNSeg(); i++) - { - const Segment & seg = segments[i]; - const Point3d & p1 = points[seg.p1]; - const Point3d & p2 = points[seg.p2]; - /* - INDEX_2 i21(seg.p1, seg.p2); - INDEX_2 i22(seg.p2, seg.p1); - if (identifiedpoints) - if (!identifiedpoints->Used (i21) && !identifiedpoints->Used (i22)) - */ - if (!ident -> UsedSymmetric (seg.p1, seg.p2)) - { - lochfunc->SetH (Center (p1, p2), Dist (p1, p2)); - } - } - /* - cerr << "do vol" << endl; - for (i = 1; i <= GetNE(); i++) - { - const Element & el = VolumeElement(i); - if (el.GetType() == TET) - { - int j, k; - for (j = 2; j <= 4; j++) - for (k = 1; k < j; k++) - { - const Point3d & p1 = Point (el.PNum(j)); - const Point3d & p2 = Point (el.PNum(k)); - lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); - (*testout) << "set vol h to " << (2 * Dist (p1, p2)) << endl; - - } - } - } - */ - - /* - const char * meshsizefilename = - globflags.GetStringFlag ("meshsize", NULL); - if (meshsizefilename) - { - ifstream msf(meshsizefilename); - if (msf) - { - int nmsp; - msf >> nmsp; - for (i = 1; i <= nmsp; i++) - { - Point3d pi; - double hi; - msf >> pi.X() >> pi.Y() >> pi.Z(); - msf >> hi; - lochfunc->SetH (pi, hi); - } - } - } - */ - // lochfunc -> Convexify(); - // lochfunc -> PrintMemInfo (cout); - } - - - void Mesh :: CalcLocalHFromPointDistances(void) - { - PrintMessage (3, "Calculating local h from point distances"); - - if (!lochfunc) - { - Point3d pmin, pmax; - GetBox (pmin, pmax); - - SetLocalH (pmin, pmax, mparam.grading); - } - - PointIndex i,j; - double hl; - - - for (i = PointIndex::BASE; - i < GetNP()+PointIndex::BASE; i++) - { - for(j=i+1; j<GetNP()+PointIndex::BASE; j++) - { - const Point3d & p1 = points[i]; - const Point3d & p2 = points[j]; - hl = Dist(p1,p2); - RestrictLocalH(p1,hl); - RestrictLocalH(p2,hl); - //cout << "restricted h at " << p1 << " and " << p2 << " to " << hl << endl; - } - } - - - } - - - void Mesh :: CalcLocalHFromSurfaceCurvature (double elperr) - { - PrintMessage (3, "Calculating local h from surface curvature"); - - if (!lochfunc) - { - Point3d pmin, pmax; - GetBox (pmin, pmax); - - SetLocalH (pmin, pmax, mparam.grading); - } - - - INDEX_2_HASHTABLE<int> edges(3 * GetNP() + 2); - INDEX_2_HASHTABLE<int> bedges(GetNSeg() + 2); - int i, j; - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment(i); - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort(); - bedges.Set (i2, 1); - } - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & sel = SurfaceElement(i); - if (!sel.PNum(1)) - continue; - for (j = 1; j <= 3; j++) - { - INDEX_2 i2(sel.PNumMod(j), sel.PNumMod(j+1)); - i2.Sort(); - if (bedges.Used(i2)) continue; - - if (edges.Used(i2)) - { - int other = edges.Get(i2); - - const Element2d & elother = SurfaceElement(other); - - int pi3 = 1; - while ( (sel.PNum(pi3) == i2.I1()) || - (sel.PNum(pi3) == i2.I2())) - pi3++; - pi3 = sel.PNum(pi3); - - int pi4 = 1; - while ( (elother.PNum(pi4) == i2.I1()) || - (elother.PNum(pi4) == i2.I2())) - pi4++; - pi4 = elother.PNum(pi4); - - double rad = ComputeCylinderRadius (Point (i2.I1()), - Point (i2.I2()), - Point (pi3), - Point (pi4)); - - RestrictLocalHLine (Point(i2.I1()), Point(i2.I2()), rad/elperr); - - - /* - (*testout) << "pi1,2, 3, 4 = " << i2.I1() << ", " << i2.I2() << ", " << pi3 << ", " << pi4 - << " p1 = " << Point(i2.I1()) - << ", p2 = " << Point(i2.I2()) - // << ", p3 = " << Point(pi3) - // << ", p4 = " << Point(pi4) - << ", rad = " << rad << endl; - */ - } - else - edges.Set (i2, i); - } - } - - - // Restrict h due to line segments - - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment(i); - const Point3d & p1 = Point(seg.p1); - const Point3d & p2 = Point(seg.p2); - RestrictLocalH (Center (p1, p2), Dist (p1, p2)); - } - - - - /* - - - int i, j; - int np = GetNP(); - int nseg = GetNSeg(); - int nse = GetNSE(); - - ARRAY<Vec3d> normals(np); - BitArray linepoint(np); - - linepoint.Clear(); - for (i = 1; i <= nseg; i++) - { - linepoint.Set (LineSegment(i).p1); - linepoint.Set (LineSegment(i).p2); - } - - for (i = 1; i <= np; i++) - normals.Elem(i) = Vec3d(0,0,0); - - for (i = 1; i <= nse; i++) - { - Element2d & el = SurfaceElement(i); - Vec3d nf = Cross (Vec3d (Point (el.PNum(1)), Point(el.PNum(2))), - Vec3d (Point (el.PNum(1)), Point(el.PNum(3)))); - for (j = 1; j <= 3; j++) - normals.Elem(el.PNum(j)) += nf; - } - - for (i = 1; i <= np; i++) - normals.Elem(i) /= (1e-12 + normals.Elem(i).Length()); - - for (i = 1; i <= nse; i++) - { - Element2d & el = SurfaceElement(i); - Vec3d nf = Cross (Vec3d (Point (el.PNum(1)), Point(el.PNum(2))), - Vec3d (Point (el.PNum(1)), Point(el.PNum(3)))); - nf /= nf.Length(); - Point3d c = Center (Point(el.PNum(1)), - Point(el.PNum(2)), - Point(el.PNum(3))); - - for (j = 1; j <= 3; j++) - { - if (!linepoint.Test (el.PNum(j))) - { - double dist = Dist (c, Point(el.PNum(j))); - double dn = (nf - normals.Get(el.PNum(j))).Length(); - - RestrictLocalH (Point(el.PNum(j)), dist / (dn+1e-12) /elperr); - } - } - } - */ - } - - - void Mesh :: RestrictLocalH (resthtype rht, int nr, double loch) - { - int i; - switch (rht) - { - case RESTRICTH_FACE: - { - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & sel = SurfaceElement(i); - if (sel.GetIndex() == nr) - RestrictLocalH (RESTRICTH_SURFACEELEMENT, i, loch); - } - break; - } - case RESTRICTH_EDGE: - { - for (i = 1; i <= GetNSeg(); i++) - { - const Segment & seg = LineSegment(i); - if (seg.edgenr == nr) - RestrictLocalH (RESTRICTH_SEGMENT, i, loch); - } - break; - } - case RESTRICTH_POINT: - { - RestrictLocalH (Point (nr), loch); - break; - } - - case RESTRICTH_SURFACEELEMENT: - { - const Element2d & sel = SurfaceElement(nr); - Point3d p = Center (Point(sel.PNum(1)), - Point(sel.PNum(2)), - Point(sel.PNum(3))); - RestrictLocalH (p, loch); - break; - } - case RESTRICTH_SEGMENT: - { - const Segment & seg = LineSegment(nr); - RestrictLocalHLine (Point (seg.p1), Point(seg.p2), loch); - break; - } - } - } - - - void Mesh :: LoadLocalMeshSize (const char * meshsizefilename) - { - if (!meshsizefilename) return; - - ifstream msf(meshsizefilename); - - if (!msf) return; - - PrintMessage (3, "Load local mesh-size"); - int nmsp, nmsl; - msf >> nmsp; - for (int i = 0; i < nmsp; i++) - { - Point3d pi; - double hi; - msf >> pi.X() >> pi.Y() >> pi.Z(); - msf >> hi; - if (!msf.good()) - throw NgException ("problem in mesh-size file\n"); - RestrictLocalH (pi, hi); - } - msf >> nmsl; - for (int i = 0; i < nmsl; i++) - { - Point3d p1, p2; - double hi; - msf >> p1.X() >> p1.Y() >> p1.Z(); - msf >> p2.X() >> p2.Y() >> p2.Z(); - msf >> hi; - if (!msf.good()) - throw NgException ("problem in mesh-size file\n"); - RestrictLocalHLine (p1, p2, hi); - } - } - - - - void Mesh :: GetBox (Point3d & pmin, Point3d & pmax, int dom) const - { - if (points.Size() == 0) - { - pmin = pmax = Point3d(0,0,0); - return; - } - - if (dom <= 0) - { - pmin = Point3d (1e10, 1e10, 1e10); - pmax = Point3d (-1e10, -1e10, -1e10); - - for (PointIndex pi = PointIndex::BASE; - pi < GetNP()+PointIndex::BASE; pi++) - { - pmin.SetToMin ( (*this) [pi] ); - pmax.SetToMax ( (*this) [pi] ); - } - } - else - { - int j, nse = GetNSE(); - SurfaceElementIndex sei; - - pmin = Point3d (1e10, 1e10, 1e10); - pmax = Point3d (-1e10, -1e10, -1e10); - for (sei = 0; sei < nse; sei++) - { - const Element2d & el = (*this)[sei]; - if (el.IsDeleted() ) continue; - - if (dom == -1 || el.GetIndex() == dom) - { - for (j = 0; j < 3; j++) - { - pmin.SetToMin ( (*this) [el[j]] ); - pmax.SetToMax ( (*this) [el[j]] ); - } - } - } - } - - if (pmin.X() > 0.5e10) - { - pmin = pmax = Point3d(0,0,0); - } - } - - - - - void Mesh :: GetBox (Point3d & pmin, Point3d & pmax, POINTTYPE ptyp) const - { - if (points.Size() == 0) - { - pmin = pmax = Point3d(0,0,0); - return; - } - - pmin = Point3d (1e10, 1e10, 1e10); - pmax = Point3d (-1e10, -1e10, -1e10); - - for (PointIndex pi = PointIndex::BASE; - pi < GetNP()+PointIndex::BASE; pi++) - if (points[pi].Type() <= ptyp) - { - pmin.SetToMin ( (*this) [pi] ); - pmax.SetToMax ( (*this) [pi] ); - } - } - - - - - double Mesh :: ElementError (int eli) const - { - const Element & el = volelements.Get(eli); - return CalcTetBadness (points.Get(el[0]), points.Get(el[1]), - points.Get(el[2]), points.Get(el[3]), -1); - } - - void Mesh :: AddLockedPoint (PointIndex pi) - { - lockedpoints.Append (pi); - } - - void Mesh :: ClearLockedPoints () - { - lockedpoints.SetSize (0); - } - - - - void Mesh :: Compress () - { - int i, j; - ARRAY<int,PointIndex::BASE> op2np(GetNP()); - ARRAY<MeshPoint> hpoints; - BitArrayChar<PointIndex::BASE> pused(GetNP()); - - /* - (*testout) << "volels: " << endl; - for (i = 1; i <= volelements.Size(); i++) - { - for (j = 1; j <= volelements.Get(i).GetNP(); j++) - (*testout) << volelements.Get(i).PNum(j) << " "; - (*testout) << endl; - } - (*testout) << "np: " << GetNP() << endl; - */ - - for (i = 0; i < volelements.Size(); i++) - if (volelements[i][0] <= PointIndex::BASE-1 || - volelements[i].IsDeleted()) - { - volelements.Delete(i); - i--; - } - - - for (i = 0; i < surfelements.Size(); i++) - if (surfelements[i].IsDeleted()) - { - surfelements.Delete(i); - i--; - } - - for (i = 0; i < segments.Size(); i++) - if (segments[i].p1 <= PointIndex::BASE-1) - { - segments.Delete(i); - i--; - } - - pused.Clear(); - for (i = 0; i < volelements.Size(); i++) - { - const Element & el = volelements[i]; - for (j = 0; j < el.GetNP(); j++) - pused.Set (el[j]); - } - - for (i = 0; i < surfelements.Size(); i++) - { - const Element2d & el = surfelements[i]; - for (j = 0; j < el.GetNP(); j++) - pused.Set (el[j]); - } - - for (i = 0; i < segments.Size(); i++) - { - const Segment & seg = segments[i]; - pused.Set (seg.p1); - pused.Set (seg.p2); - } - - for (i = 0; i < openelements.Size(); i++) - { - const Element2d & el = openelements[i]; - for (j = 0; j < el.GetNP(); j++) - pused.Set(el[j]); - } - - for (i = 0; i < lockedpoints.Size(); i++) - pused.Set (lockedpoints[i]); - - - /* - // compress points doesn�t work for identified points ! - if (identifiedpoints) - { - for (i = 1; i <= identifiedpoints->GetNBags(); i++) - if (identifiedpoints->GetBagSize(i)) - { - pused.Set (); - break; - } - } - */ - // pused.Set(); - - - int npi = PointIndex::BASE-1; - - for (i = PointIndex::BASE; - i < points.Size()+PointIndex::BASE; i++) - if (pused.Test(i)) - { - npi++; - op2np[i] = npi; - hpoints.Append (points[i]); - } - else - op2np[i] = -1; - - - - points.SetSize(0); - for (i = 0; i < hpoints.Size(); i++) - points.Append (hpoints[i]); - - - for (i = 1; i <= volelements.Size(); i++) - { - Element & el = VolumeElement(i); - for (j = 0; j < el.GetNP(); j++) - el[j] = op2np[el[j]]; - } - - for (i = 1; i <= surfelements.Size(); i++) - { - Element2d & el = SurfaceElement(i); - for (j = 0; j < el.GetNP(); j++) - el[j] = op2np[el[j]]; - } - - for (i = 0; i < segments.Size(); i++) - { - Segment & seg = segments[i]; - seg.p1 = op2np[seg.p1]; - seg.p2 = op2np[seg.p2]; - } - - for (i = 1; i <= openelements.Size(); i++) - { - Element2d & el = openelements.Elem(i); - for (j = 0; j < el.GetNP(); j++) - el[j] = op2np[el[j]]; - } - - - for (i = 0; i < lockedpoints.Size(); i++) - lockedpoints[i] = op2np[lockedpoints[i]]; - - - CalcSurfacesOfNode(); - - - // FindOpenElements(); - timestamp = NextTimeStamp(); - - /* - (*testout) << "compress, done" << endl - << "np = " << points.Size() - << "ne = " << volelements.Size() << ", type.size = " << eltyps.Size() - << "volelements = " << volelements << endl; - */ - } - - - int Mesh :: CheckConsistentBoundary () const - { - int nf = GetNOpenElements(); - INDEX_2_HASHTABLE<int> edges(nf+2); - int i, j; - INDEX_2 i2; - int err = 0; - - - for (i = 1; i <= nf; i++) - { - const Element2d & sel = OpenElement(i); - - for (j = 1; j <= sel.GetNP(); j++) - { - i2.I1() = sel.PNumMod(j); - i2.I2() = sel.PNumMod(j+1); - - int sign = (i2.I2() > i2.I1()) ? 1 : -1; - i2.Sort(); - if (!edges.Used (i2)) - edges.Set (i2, 0); - - edges.Set (i2, edges.Get(i2) + sign); - /* - - if (edges.Used(i2)) - { - int hi; - hi = edges.Get(i2); - if (hi != 1) - err = 1; - edges.Set(i2, 2); - cnt2++; - } - else - { - swap (i2.I1(), i2.I2()); - edges.Set(i2, 1); - cnt1++; - } - */ - } - } - - - /* - if (cnt1 != cnt2) - err = 2; - */ - - for (i = 1; i <= edges.GetNBags(); i++) - for (j = 1; j <= edges.GetBagSize(i); j++) - { - int cnt = 0; - edges.GetData (i, j, i2, cnt); - if (cnt) - { - PrintError ("Edge ", i2.I1() , " - ", i2.I2(), " multiple times in surface mesh"); - err = 2; - } - } - - return err; - } - - - - int Mesh :: CheckOverlappingBoundary () - { - int i, j, k; - - Point3d pmin, pmax; - GetBox (pmin, pmax); - Box3dTree setree(pmin, pmax); - ARRAY<int> inters; - - bool overlap = 0; - bool incons_layers = 0; - - - for (i = 1; i <= GetNSE(); i++) - SurfaceElement(i).badel = 0; - - - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & tri = SurfaceElement(i); - - Point3d tpmin (Point(tri[0])); - Point3d tpmax (tpmin); - - for (k = 1; k < tri.GetNP(); k++) - { - tpmin.SetToMin (Point (tri[k])); - tpmax.SetToMax (Point (tri[k])); - } - Vec3d diag(tpmin, tpmax); - - tpmax = tpmax + 0.1 * diag; - tpmin = tpmin - 0.1 * diag; - - setree.Insert (tpmin, tpmax, i); - } - - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & tri = SurfaceElement(i); - - Point3d tpmin (Point(tri[0])); - Point3d tpmax (tpmin); - - for (k = 1; k < tri.GetNP(); k++) - { - tpmin.SetToMin (Point (tri[k])); - tpmax.SetToMax (Point (tri[k])); - } - - setree.GetIntersecting (tpmin, tpmax, inters); - - for (j = 1; j <= inters.Size(); j++) - { - const Element2d & tri2 = SurfaceElement(inters.Get(j)); - - if ( (*this)[tri[0]].GetLayer() != (*this)[tri2[0]].GetLayer()) - continue; - - if ( (*this)[tri[0]].GetLayer() != (*this)[tri[1]].GetLayer() || - (*this)[tri[0]].GetLayer() != (*this)[tri[2]].GetLayer()) - { - incons_layers = 1; - cout << "inconsistent layers in triangle" << endl; - } - - - const Point3d *trip1[3], *trip2[3]; - for (k = 1; k <= 3; k++) - { - trip1[k-1] = &Point (tri.PNum(k)); - trip2[k-1] = &Point (tri2.PNum(k)); - } - - if (IntersectTriangleTriangle (&trip1[0], &trip2[0])) - { - overlap = 1; - PrintWarning ("Intersecting elements" - ,i, " and ", inters.Get(j)); - - (*testout) << "Intersecting: " << endl; - (*testout) << "openelement " << i << " with open element " << inters.Get(j) << endl; - - cout << "el1 = " << tri << endl; - cout << "el2 = " << tri2 << endl; - cout << "layer1 = " << (*this)[tri[0]].GetLayer() << endl; - cout << "layer2 = " << (*this)[tri2[0]].GetLayer() << endl; - - - for (k = 1; k <= 3; k++) - (*testout) << tri.PNum(k) << " "; - (*testout) << endl; - for (k = 1; k <= 3; k++) - (*testout) << tri2.PNum(k) << " "; - (*testout) << endl; - - for (k = 0; k <= 2; k++) - (*testout) << *trip1[k] << " "; - (*testout) << endl; - for (k = 0; k <= 2; k++) - (*testout) << *trip2[k] << " "; - (*testout) << endl; - - - /* - INDEX_3 i3(tri.PNum(1), tri.PNum(2), tri.PNum(3)); - i3.Sort(); - for (k = 1; k <= GetNSE(); k++) - { - const Element2d & el2 = SurfaceElement(k); - INDEX_3 i3b(el2.PNum(1), el2.PNum(2), el2.PNum(3)); - i3b.Sort(); - if (i3 == i3b) - { - SurfaceElement(k).badel = 1; - } - } - */ - SurfaceElement(i).badel = 1; - SurfaceElement(inters.Get(j)).badel = 1; - } - } - } - - // bug 'fix' - if (incons_layers) overlap = 0; - - return overlap; - } - - - int Mesh :: CheckVolumeMesh () const - { - PrintMessage (3, "Checking volume mesh"); - - int ne = GetNE(); - DenseMatrix dtrans(3,3); - int i, j; - - PrintMessage (5, "elements: ", ne); - for (i = 1; i <= ne; i++) - { - Element & el = (Element&) VolumeElement(i); - el.flags.badel = 0; - int nip = el.GetNIP(); - for (j = 1; j <= nip; j++) - { - el.GetTransformation (j, Points(), dtrans); - double det = dtrans.Det(); - if (det > 0) - { - PrintError ("Element ", i , " has wrong orientation"); - el.flags.badel = 1; - } - } - } - - return 0; - } - - - bool Mesh :: LegalTrig (const Element2d & el) const - { - return 1; - if ( /* hp */ 1) // needed for old, simple hp-refinement - { - // trigs with 2 or more segments are illegal - int i; - int nseg = 0; - - if (!segmentht) - { - cerr << "no segmentht allocated" << endl; - return 0; - } - - // Point3d cp(0.5, 0.5, 0.5); - for (i = 1; i <= 3; i++) - { - INDEX_2 i2(el.PNumMod (i), el.PNumMod (i+1)); - i2.Sort(); - if (segmentht -> Used (i2)) - nseg++; - } - if (nseg >= 2) - return 0; - } - return 1; - } - - /// - bool Mesh :: LegalTet2 (Element & el) const - { - // return 1; - // Test, whether 4 points have a common surface plus - // at least 4 edges at the boundary - - int i, j, k; - - // non-tets are always legal - if (el.GetType() != TET) - { - el.SetLegal (1); - return 1; - } - - // element has at least 2 inner points ---> legal - int cnti = 0; - for (j = 0; j < 4; j++) - if (PointType(el[j]) == INNERPOINT) - cnti++; - if (cnti >= 2) - { - el.SetLegal (1); - return 1; - } - - // which faces are boundary faces ? - Element2d face; - int bface[4]; - - for (i = 1; i <= 4; i++) - { - el.GetFace (i, face); - INDEX_3 i3 (face.PNum(1), face.PNum(2), face.PNum(3)); - i3.Sort(); - bface[i-1] = surfelementht->Used (i3); - } - - int bedge[4][4]; - int segedge[4][4]; - for (i = 0; i < 4; i++) - for (j = 0; j < i; j++) - { - bool sege = 0, be = 0; - - INDEX_2 i2(el[i], el[j]); - i2.Sort(); - - /* - if (boundaryedges -> Used(i2)) - { - be = 1; - if (boundaryedges -> Get(i2) == 2) - sege = 1; - } - */ - int pos = boundaryedges -> Position(i2); - if (pos) - { - be = 1; - if (boundaryedges -> GetData(pos) == 2) - sege = 1; - } - - segedge[j][i] = segedge[i][j] = sege; - bedge[j][i] = bedge[i][j] = be; - } - - // two boundary faces and no edge is illegal - for (i = 0; i < 3; i++) - for (j = i+1; j < 4; j++) - { - if (bface[i] && bface[j]) - { - // common nodes: - int pi1 = 0, pi2; - while (pi1 == i || pi1 == j) - pi1++; - pi2 = 6 - i - j - pi1; - if (!segedge[pi1][pi2]) - { - // 2 boundary faces withoud edge in between - el.SetLegal (0); - return 0; - } - } - } - - - // three boundary edges meeting in a Surface point - for (i = 0; i < 4; i++) - { - bool alledges = 1; - if (PointType(el[i]) == SURFACEPOINT) - { - for (j = 0; j < 4; j++) - if (j != i) - { - if (!bedge[i][j]) - { - alledges = 0; - break; - } - } - if (alledges) - { - // cout << "tet illegal due to unmarked node" << endl; - el.SetLegal (0); - return 0; - } - } - } - - - /* - { - // having 3 boundary edges and 4 surface nodes ??? - int nodehasedge[4]; - int canbe = 1; // can be that illegal tet - - for (i = 0; i < 4; i++) - nodehasedge[i] = 0; - for (i = 1; i <= 4; i++) - { - if (PointType(el.PNum(i)) != SURFACEPOINT) - canbe = 0; - for (j = i+1; j <= 4; j++) - { - INDEX_2 i2(el.PNum(i), el.PNum(j)); - i2.Sort(); - if (boundaryedges->Used(i2)) - { - nodehasedge[i-1] = 1; - nodehasedge[j-1] = 1; - } - - } - } - for (i = 0; i < 4; i++) - if (!nodehasedge[i]) - canbe = 0; - - if (canbe) return 0; - - } - */ - - { - // two connected edges on surface, but no face - - int ltestmode = 0; // (el.PNum(1) == 10516); - - if (ltestmode) - { - (*testout) << "pnums: " << endl; - for (i = 1; i <= 4; i++) - (*testout) << el.PNum(i) << " "; - (*testout) << endl; - } - - for (i = 1; i <= 4; i++) - if (PointType(el.PNum(i)) == SURFACEPOINT) - for (j = 1; j <= 4; j++) - if (j != i) - for (k = j+1; k <= 4; k++) - if (k != i) - { - int fnr = 10 - i - j - k; - - if (!bface[fnr-1] && - bedge[i-1][j-1] && - bedge[i-1][k-1]) - { - el.SetLegal (0); - return 0; - } - /* - INDEX_2 e1(el.PNum(i), el.PNum(j)); - e1.Sort(); - INDEX_2 e2(el.PNum(i), el.PNum(k)); - e2.Sort(); - INDEX_3 face(el.PNum(i), el.PNum(j), el.PNum(k)); - face.Sort(); - - if (ltestmode) - { - (*testout) << "i, j, k = " << i << ", " << j << ", " << k << endl; - (*testout) << "eij = " << boundaryedges->Used(e1) - << " eik = " << boundaryedges->Used(e2) - << " face = " << surfelementht->Used (face) << endl; - - } - - if (boundaryedges->Used(e1) && - boundaryedges->Used(e2) && - !surfelementht->Used (face)) - { - // cout << "tet illegal due to last case" << endl; - el.SetLegal (0); - return 0; - } - */ - } - - } - - - { - // connected surface edge and edge edge, but no face - - for (i = 1; i <= 4; i++) - if (PointType(el.PNum(i)) == EDGEPOINT) - for (j = 1; j <= 4; j++) - if (j != i) - for (k = j+1; k <= 4; k++) - if (k != i) - { - int fnr = 10 - i - j - k; - - if (!bface[fnr-1] && - (bedge[i-1][j-1] && segedge[i-1][k-1] || - segedge[i-1][j-1] && bedge[i-1][k-1])) - { - el.SetLegal (0); - return 0; - } - } - - } - - - - - - - el.SetLegal (1); - return 1; - - /* - int i1, i2, i3, i4, j; - if (PointType(el.PNum(1)) != INNERPOINT && - PointType(el.PNum(2)) != INNERPOINT && - PointType(el.PNum(3)) != INNERPOINT && - PointType(el.PNum(4)) != INNERPOINT) - { - for (i1 = 1; i1 <= surfacesonnode.EntrySize(el.PNum(1)); i1++) - for (i2 = 1; i2 <= surfacesonnode.EntrySize(el.PNum(2)); i2++) - if (surfacesonnode.Get(el.PNum(1), i1) == - surfacesonnode.Get(el.PNum(2), i2)) - for (i3 = 1; i3 <= surfacesonnode.EntrySize(el.PNum(3)); i3++) - if (surfacesonnode.Get(el.PNum(1), i1) == - surfacesonnode.Get(el.PNum(3), i3)) - for (i4 = 1; i4 <= surfacesonnode.EntrySize(el.PNum(4)); i4++) - if (surfacesonnode.Get(el.PNum(1), i1) == - surfacesonnode.Get(el.PNum(4), i4)) - { - int j, numbe = 0; - INDEX_2 i2; - - for (j = 1; j <= 6; j++) - { - switch (j) - { - case 1: - i2.I1() = el.PNum(1); - i2.I2() = el.PNum(2); break; - case 2: - i2.I1() = el.PNum(1); - i2.I2() = el.PNum(3); break; - case 3: - i2.I1() = el.PNum(1); - i2.I2() = el.PNum(4); break; - case 4: - i2.I1() = el.PNum(2); - i2.I2() = el.PNum(3); break; - case 5: - i2.I1() = el.PNum(2); - i2.I2() = el.PNum(4); break; - case 6: - i2.I1() = el.PNum(3); - i2.I2() = el.PNum(4); break; - } - - i2.Sort(); - if (boundaryedges->Used (i2)) numbe++; - } - - if (numbe >= 4) - { - // (*testout) - // << "Tet illegal: " - // << "mat = " << el.GetIndex() << " " - // << "surf = " << surfacesonnode.Get(el.PNum(1), i1) - // << " " - // << el.PNum(1) << " " - // << el.PNum(2) << " " - // << el.PNum(3) << " " - // << el.PNum(4) << endl; - - return 0; - } - } - } - return 1; - */ - } - - - int Mesh :: GetNDomains() const - { - int ndom = 0; - - for (int k = 0; k < facedecoding.Size(); k++) - { - if (facedecoding[k].DomainIn() > ndom) - ndom = facedecoding[k].DomainIn(); - if (facedecoding[k].DomainOut() > ndom) - ndom = facedecoding[k].DomainOut(); - } - - return ndom; - } - - - - void Mesh :: SurfaceMeshOrientation () - { - int i, j; - int nse = GetNSE(); - - BitArray used(nse); - used.Clear(); - INDEX_2_HASHTABLE<int> edges(nse+1); - - bool haschanged = 0; - - - const Element2d & tri = SurfaceElement(1); - for (j = 1; j <= 3; j++) - { - INDEX_2 i2(tri.PNumMod(j), tri.PNumMod(j+1)); - edges.Set (i2, 1); - } - used.Set(1); - - bool unused; - do - { - bool changed; - do - { - changed = 0; - for (i = 1; i <= nse; i++) - if (!used.Test(i)) - { - Element2d & el = surfelements.Elem(i); - int found = 0, foundrev = 0; - for (j = 1; j <= 3; j++) - { - INDEX_2 i2(el.PNumMod(j), el.PNumMod(j+1)); - if (edges.Used(i2)) - foundrev = 1; - swap (i2.I1(), i2.I2()); - if (edges.Used(i2)) - found = 1; - } - - if (found || foundrev) - { - if (foundrev) - swap (el.PNum(2), el.PNum(3)); - - changed = 1; - for (j = 1; j <= 3; j++) - { - INDEX_2 i2(el.PNumMod(j), el.PNumMod(j+1)); - edges.Set (i2, 1); - } - used.Set (i); - } - } - if (changed) - haschanged = 1; - } - while (changed); - - - unused = 0; - for (i = 1; i <= nse; i++) - if (!used.Test(i)) - { - unused = 1; - const Element2d & tri = SurfaceElement(i); - for (j = 1; j <= 3; j++) - { - INDEX_2 i2(tri.PNumMod(j), tri.PNumMod(j+1)); - edges.Set (i2, 1); - } - used.Set(i); - break; - } - } - while (unused); - - if (haschanged) - timestamp = NextTimeStamp(); - } - - - void Mesh :: Split2Tets() - { - // int oldne, oldnse; - // int i, j, k, l; - - bool has_prisms = 0; - - int oldne = GetNE(); - for (int i = 1; i <= oldne; i++) - { - Element el = VolumeElement(i); - - if (el.GetType() == PRISM) - { - // prism, to 3 tets - - // make minimal node to node 1 - int minpi=0; - PointIndex minpnum; - minpnum = GetNP() + 1; - - for (int j = 1; j <= 6; j++) - { - if (el.PNum(j) < minpnum) - { - minpnum = el.PNum(j); - minpi = j; - } - } - - if (minpi >= 4) - { - for (int j = 1; j <= 3; j++) - swap (el.PNum(j), el.PNum(j+3)); - minpi -= 3; - } - - while (minpi > 1) - { - int hi = 0; - for (int j = 0; j <= 3; j+= 3) - { - hi = el.PNum(1+j); - el.PNum(1+j) = el.PNum(2+j); - el.PNum(2+j) = el.PNum(3+j); - el.PNum(3+j) = hi; - } - minpi--; - } - - /* - version 1: edge from pi2 to pi6, - version 2: edge from pi3 to pi5, - */ - - static const int ntets[2][12] = - { { 1, 4, 5, 6, 1, 2, 3, 6, 1, 2, 5, 6 }, - { 1, 4, 5, 6, 1, 2, 3, 5, 3, 1, 5, 6 } }; - - const int * min2pi; - - if (min2 (el.PNum(2), el.PNum(6)) < - min2 (el.PNum(3), el.PNum(5))) - { - min2pi = &ntets[0][0]; - // (*testout) << "version 1 "; - } - else - { - min2pi = &ntets[1][0]; - // (*testout) << "version 2 "; - } - - - int firsttet = 1; - for (int j = 1; j <= 3; j++) - { - Element nel(4); - for (int k = 1; k <= 4; k++) - nel.PNum(k) = el.PNum(min2pi[4 * j + k - 5]); - nel.SetIndex (el.GetIndex()); - - int legal = 1; - for (int k = 1; k <= 3; k++) - for (int l = k+1; l <= 4; l++) - if (nel.PNum(k) == nel.PNum(l)) - legal = 0; - - // (*testout) << nel << " "; - if (legal) - { - if (firsttet) - { - VolumeElement(i) = nel; - firsttet = 0; - } - else - { - AddVolumeElement(nel); - } - } - } - if (firsttet) (*testout) << "no legal"; - (*testout) << endl; - } - - - - else if (el.GetType() == HEX) - { - // hex to A) 2 prisms or B) to 5 tets - - // make minimal node to node 1 - int minpi=0; - PointIndex minpnum; - minpnum = GetNP() + 1; - - for (int j = 1; j <= 8; j++) - { - if (el.PNum(j) < minpnum) - { - minpnum = el.PNum(j); - minpi = j; - } - } - - if (minpi >= 5) - { - for (int j = 1; j <= 4; j++) - swap (el.PNum(j), el.PNum(j+4)); - minpi -= 4; - } - - while (minpi > 1) - { - int hi = 0; - for (int j = 0; j <= 4; j+= 4) - { - hi = el.PNum(1+j); - el.PNum(1+j) = el.PNum(2+j); - el.PNum(2+j) = el.PNum(3+j); - el.PNum(3+j) = el.PNum(4+j); - el.PNum(4+j) = hi; - } - minpi--; - } - - - - static const int to_prisms[3][12] = - { { 0, 1, 2, 4, 5, 6, 0, 2, 3, 4, 6, 7 }, - { 0, 1, 5, 3, 2, 6, 0, 5, 4, 3, 5, 7 }, - { 0, 7, 4, 1, 6, 5, 0, 3, 7, 1, 2, 6 }, - }; - - const int * min2pi = 0; - if (min2 (el[4], el[6]) < min2 (el[5], el[7])) - min2pi = &to_prisms[0][0]; - else if (min2 (el[3], el[6]) < min2 (el[2], el[7])) - min2pi = &to_prisms[1][0]; - else if (min2 (el[1], el[6]) < min2 (el[2], el[5])) - min2pi = &to_prisms[2][0]; - - if (min2pi) - { - has_prisms = 1; - for (int j = 0; j < 2; j++) - { - Element nel(PRISM); - for (int k = 0; k < 6; k++) - nel[k] = el[min2pi[6*j + k]]; - nel.SetIndex (el.GetIndex()); - - if (j == 0) - VolumeElement(i) = nel; - else - AddVolumeElement(nel); - } - } - else - { - // split to 5 tets - - static const int to_tets[20] = - { - 1, 2, 0, 5, - 3, 0, 2, 7, - 4, 5, 7, 0, - 6, 7, 5, 2, - 0, 2, 7, 5 - }; - - for (int j = 0; j < 5; j++) - { - Element nel(TET); - for (int k = 0; k < 4; k++) - nel[k] = el[to_tets[4*j + k]]; - nel.SetIndex (el.GetIndex()); - - if (j == 0) - VolumeElement(i) = nel; - else - AddVolumeElement(nel); - } - - } - } - - - - - - else if (el.GetType() == PYRAMID) - { - // pyramid, to 2 tets - - static const int ntets[2][8] = - { { 1, 2, 3, 5, 1, 3, 4, 5 }, - { 1, 2, 4, 5, 4, 2, 3, 5 }}; - - const int * min2pi; - - if (min2 (el.PNum(1), el.PNum(3)) < - min2 (el.PNum(2), el.PNum(4))) - min2pi = &ntets[0][0]; - else - min2pi = &ntets[1][0]; - - - int firsttet = 1; - for (int j = 1; j <= 2; j++) - { - Element nel(4); - for (int k = 1; k <= 4; k++) - nel.PNum(k) = el.PNum(min2pi[4 * j + k - 5]); - nel.SetIndex (el.GetIndex()); - - - int legal = 1; - for (int k = 1; k <= 3; k++) - for (int l = k+1; l <= 4; l++) - if (nel.PNum(k) == nel.PNum(l)) - legal = 0; - - if (legal) - { - (*testout) << nel << " "; - if (firsttet) - { - VolumeElement(i) = nel; - firsttet = 0; - } - else - { - AddVolumeElement(nel); - } - } - } - (*testout) << endl; - } - } - - - int oldnse = GetNSE(); - for (int i = 1; i <= oldnse; i++) - { - Element2d el = SurfaceElement(i); - if (el.GetNP() == 4) - { - (*testout) << "split el: " << el << " to "; - - static const int ntris[2][6] = - { { 1, 2, 3, 1, 3, 4 }, - { 1, 2, 4, 4, 2, 3 }}; - - const int * min2pi; - - if (min2 (el.PNum(1), el.PNum(3)) < - min2 (el.PNum(2), el.PNum(4))) - min2pi = &ntris[0][0]; - else - min2pi = &ntris[1][0]; - - for (int j = 0; j <6; j++) - (*testout) << min2pi[j] << " "; - - - int firsttri = 1; - for (int j = 1; j <= 2; j++) - { - Element2d nel(3); - for (int k = 1; k <= 3; k++) - nel.PNum(k) = el.PNum(min2pi[3 * j + k - 4]); - nel.SetIndex (el.GetIndex()); - - int legal = 1; - for (int k = 1; k <= 2; k++) - for (int l = k+1; l <= 3; l++) - if (nel.PNum(k) == nel.PNum(l)) - legal = 0; - - if (legal) - { - (*testout) << nel << " "; - if (firsttri) - { - SurfaceElement(i) = nel; - firsttri = 0; - } - else - { - AddSurfaceElement(nel); - } - } - } - (*testout) << endl; - - } - } - - - if (has_prisms) - - Split2Tets(); - - else - { - for (int i = 1; i <= GetNE(); i++) - { - Element & el = VolumeElement(i); - const Point3d & p1 = Point (el.PNum(1)); - const Point3d & p2 = Point (el.PNum(2)); - const Point3d & p3 = Point (el.PNum(3)); - const Point3d & p4 = Point (el.PNum(4)); - - double vol = (Vec3d (p1, p2) * - Cross (Vec3d (p1, p3), Vec3d(p1, p4))); - if (vol > 0) - swap (el.PNum(3), el.PNum(4)); - } - - timestamp = NextTimeStamp(); - } - } - - void Mesh :: BuildElementSearchTree () - { - if (elementsearchtreets == GetTimeStamp()) - return; - - NgLock lock(mutex); - lock.Lock(); - - PrintMessage (4, "Rebuild element searchtree"); - - if (elementsearchtree) - delete elementsearchtree; - elementsearchtree = NULL; - - Box3d box; - int i, j; - int ne = GetNE(); - if (!ne) - { - lock.UnLock(); - return; - } - - box.SetPoint (Point (VolumeElement(1).PNum(1))); - for (i = 1; i <= ne; i++) - { - const Element & el = VolumeElement(i); - for (j = 1; j <= el.GetNP(); j++) - box.AddPoint (Point (el.PNum(j))); - } - - box.Increase (1.01 * box.CalcDiam()); - elementsearchtree = new Box3dTree (box.PMin(), box.PMax()); - - - - for (i = 1; i <= ne; i++) - { - const Element & el = VolumeElement(i); - box.SetPoint (Point (el.PNum(1))); - for (j = 1; j <= el.GetNP(); j++) - box.AddPoint (Point (el.PNum(j))); - - elementsearchtree -> Insert (box.PMin(), box.PMax(), i); - } - - elementsearchtreets = GetTimeStamp(); - - lock.UnLock(); - } - - - int Mesh :: GetElementOfPoint (const Point3d & p, - double lami[3], - bool build_searchtree, - const int index) const - { - if (dimension == 2) - { - int i, j; - Vec3d col1, col2, col3; - Vec3d rhs, sol; - double eps = 1e-6; - int ne; - - ARRAY<int> locels; - if (0) - { - elementsearchtree->GetIntersecting (p, p, locels); - ne = locels.Size(); - } - else - ne = GetNSE(); - ARRAY<Element2d> loctrigs; - Vec3d nv(0, 0, 1); - for (i = 1; i <= ne; i++) - { - int ii; - if (0) - ii = locels.Get(i); - else - ii = i; - - if((index >= 0) && (index != SurfaceElement(ii).GetIndex())) continue; - - //SZ - if(SurfaceElement(ii).GetType()==QUAD) - { - - const Element2d & el = SurfaceElement(ii); - - const Point3d & p1 = Point(el.PNum(1)); - const Point3d & p2 = Point(el.PNum(2)); - const Point3d & p3 = Point(el.PNum(3)); - const Point3d & p4 = Point(el.PNum(4)); - - // Coefficients of Bilinear Mapping from Ref-Elem to global Elem - // X = a + b x + c y + d x y - Vec3d a = p1; - Vec3d b = p2 - a; - Vec3d c = p4 - a; - Vec3d d = p3 - a - b - c; - - double dxb = d.X()*b.Y()-d.Y()*b.X(); - double dxc = d.X()*c.Y()-d.Y()*c.X(); - double dxa = d.X()*a.Y()-d.Y()*a.X(); - double dxp = d.X()*p.Y()-d.Y()*p.X(); - - double c0,c1,c2,rt; - lami[2]=0.; - double eps = 1.E-12; - - if(fabs(d.X()) <= eps && fabs(d.Y())<= eps) - { - //Solve Linear System - lami[0]=(c.Y()*(p.X()-a.X())-b.Y()*(p.Y()-a.Y()))/ - (b.X()*c.Y() -b.Y()*c.X()); - lami[1]=(-c.X()*(p.X()-a.X())+b.X()*(p.Y()-a.Y()))/ - (b.X()*c.Y() -b.Y()*c.X()); - } - else - if(fabs(dxb) <= eps) - { - lami[1] = (dxp-dxa)/dxc; - if(fabs(b.X()-d.X()*lami[1])>=eps) - lami[0] = (p.X()-a.X() - c.X()*lami[1])/(b.X()+d.X()*lami[1]); - else - lami[0] = (p.Y()-a.Y() - c.Y()*lami[1])/(b.Y()+d.Y()*lami[1]); - } - else - if(fabs(dxc) <= eps) - { - lami[0] = (dxp-dxa)/dxb; - if(fabs(c.X()-d.X()*lami[0])>=eps) - lami[1] = (p.X()-a.X() - b.X()*lami[0])/(c.X()+d.X()*lami[0]); - else - lami[1] = (p.Y()-a.Y() - b.Y()*lami[0])/(c.Y()+d.Y()*lami[0]); - } - else //Solve quadratic equation - { - if(fabs(d.X()) >= eps) - { - c2 = d.X()*dxc; - c1 = d.X()*dxc - c.X()*dxb - d.X()*(dxp-dxa); - c0 = -b.X()*(dxp -dxa) - (a.X()-p.X())*dxb; - } - else - { - c2 = d.Y()*dxc; - c1 = d.Y()*dxc - c.Y()*dxb - d.Y()*(dxp-dxa); - c0 = -b.Y()*(dxp -dxa) - (a.Y()-p.Y())*dxb; - } - - double rt = c1*c1 - 4*c2*c0; - if (rt < 0.) continue; - lami[1] = (-c1 + sqrt(rt))/2/c2; - if(lami[1]<=1. && lami[1]>=0.) - { - lami[0] = (dxp - dxa -dxc*lami[1])/dxb; - if(lami[0]<=1. && lami[0]>=0.) - return(ii); - } - - lami[1] = (-c1 - sqrt(rt))/2/c2; - lami[0] = (dxp - dxa -dxc*lami[1])/dxb; - } - - if( lami[0] <= 1.+eps && lami[0] >= -eps && lami[1]<=1.+eps && lami[1]>=-eps) - return(ii); - - continue; - - } - else - { - // SurfaceElement(ii).GetTets (loctets); - loctrigs.SetSize(1); - loctrigs.Elem(1) = SurfaceElement(ii); - - - - for (j = 1; j <= loctrigs.Size(); j++) - { - const Element2d & el = loctrigs.Get(j); - - - const Point3d & p1 = Point(el.PNum(1)); - const Point3d & p2 = Point(el.PNum(2)); - const Point3d & p3 = Point(el.PNum(3)); - /* - Box3d box; - box.SetPoint (p1); - box.AddPoint (p2); - box.AddPoint (p3); - box.AddPoint (p4); - if (!box.IsIn (p)) - continue; - */ - col1 = p2-p1; - col2 = p3-p1; - col3 = nv; - rhs = p - p1; - - SolveLinearSystem (col1, col2, col3, rhs, sol); - - if (sol.X() >= -eps && sol.Y() >= -eps && - sol.X() + sol.Y() <= 1+eps) - { - lami[0] = sol.X(); - lami[1] = sol.Y(); - lami[2] = sol.Z(); - - return ii; - } - } - } - } - - return 0; - } - else - - { - int i, j; - Vec3d col1, col2, col3; - Vec3d rhs, sol; - double eps = 1e-4; - int ne; - - ARRAY<int> locels; - if (elementsearchtree || build_searchtree) - { - // update if necessary: - const_cast<Mesh&>(*this).BuildElementSearchTree (); - elementsearchtree->GetIntersecting (p, p, locels); - ne = locels.Size(); - } - else - ne = GetNE(); - - ARRAY<Element> loctets; - for (i = 1; i <= ne; i++) - { - int ii; - if (elementsearchtree) - ii = locels.Get(i); - else - ii = i; - - VolumeElement(ii).GetTets (loctets); - - for (j = 1; j <= loctets.Size(); j++) - { - const Element & el = loctets.Get(j); - - const Point3d & p1 = Point(el.PNum(1)); - const Point3d & p2 = Point(el.PNum(2)); - const Point3d & p3 = Point(el.PNum(3)); - const Point3d & p4 = Point(el.PNum(4)); - - Box3d box; - box.SetPoint (p1); - box.AddPoint (p2); - box.AddPoint (p3); - box.AddPoint (p4); - if (!box.IsIn (p)) - continue; - - col1 = p2-p1; - col2 = p3-p1; - col3 = p4-p1; - rhs = p - p1; - - SolveLinearSystem (col1, col2, col3, rhs, sol); - - if (sol.X() >= -eps && sol.Y() >= -eps && sol.Z() >= -eps && - sol.X() + sol.Y() + sol.Z() <= 1+eps) - { - ARRAY<Element> loctetsloc; - ARRAY<Point3d> pointsloc; - - VolumeElement(ii).GetTetsLocal (loctetsloc); - VolumeElement(ii).GetNodesLocalNew (pointsloc); - - const Element & le = loctetsloc.Get(j); - - Point3d p = - pointsloc.Get(le.PNum(1)) - + sol.X() * Vec3d (pointsloc.Get(le.PNum(1)), pointsloc.Get(le.PNum(2))) - + sol.Y() * Vec3d (pointsloc.Get(le.PNum(1)), pointsloc.Get(le.PNum(3))) - + sol.Z() * Vec3d (pointsloc.Get(le.PNum(1)), pointsloc.Get(le.PNum(4))) ; - - - lami[0] = p.X(); - lami[1] = p.Y(); - lami[2] = p.Z(); - return ii; - } - } - } - - return 0; - } - } - - - void Mesh::GetIntersectingVolEls(const Point3d& p1, const Point3d& p2, - ARRAY<int> & locels) const - { - elementsearchtree->GetIntersecting (p1, p2, locels); - } - - void Mesh :: SplitIntoParts() - { - int i, j, dom; - int ne = GetNE(); - int np = GetNP(); - int nse = GetNSE(); - - BitArray surfused(nse); - BitArray pused (np); - - surfused.Clear(); - - dom = 0; - - while (1) - { - int cntd = 1; - - dom++; - - pused.Clear(); - - int found = 0; - for (i = 1; i <= nse; i++) - if (!surfused.Test(i)) - { - SurfaceElement(i).SetIndex (dom); - for (j = 1; j <= 3; j++) - pused.Set (SurfaceElement(i).PNum(j)); - found = 1; - cntd = 1; - surfused.Set(i); - break; - } - - if (!found) - break; - - int change; - do - { - change = 0; - for (i = 1; i <= nse; i++) - { - int is = 0, isnot = 0; - for (j = 1; j <= 3; j++) - if (pused.Test(SurfaceElement(i).PNum(j))) - is = 1; - else - isnot = 1; - - if (is && isnot) - { - change = 1; - for (j = 1; j <= 3; j++) - pused.Set (SurfaceElement(i).PNum(j)); - } - - if (is) - { - if (!surfused.Test(i)) - { - surfused.Set(i); - SurfaceElement(i).SetIndex (dom); - cntd++; - } - } - } - - - for (i = 1; i <= ne; i++) - { - int is = 0, isnot = 0; - for (j = 1; j <= 4; j++) - if (pused.Test(VolumeElement(i).PNum(j))) - is = 1; - else - isnot = 1; - - if (is && isnot) - { - change = 1; - for (j = 1; j <= 4; j++) - pused.Set (VolumeElement(i).PNum(j)); - } - - if (is) - { - VolumeElement(i).SetIndex (dom); - } - } - } - while (change); - - PrintMessage (3, "domain ", dom, " has ", cntd, " surfaceelements"); - } - - /* - facedecoding.SetSize (dom); - for (i = 1; i <= dom; i++) - { - facedecoding.Elem(i).surfnr = 0; - facedecoding.Elem(i).domin = i; - facedecoding.Elem(i).domout = 0; - } - */ - ClearFaceDescriptors(); - for (i = 1; i <= dom; i++) - AddFaceDescriptor (FaceDescriptor (0, i, 0, 0)); - CalcSurfacesOfNode(); - timestamp = NextTimeStamp(); - } - - void Mesh :: SplitSeparatedFaces () - { - int fdi; - int i, j; - int np = GetNP(); - - BitArray usedp(np); - - fdi = 1; - while (fdi <= GetNFD()) - { - int firstel = 0; - for (i = 1; i <= GetNSE(); i++) - if (SurfaceElement(i).GetIndex() == fdi) - { - firstel = i; - break; - } - if (!firstel) continue; - - usedp.Clear(); - for (j = 1; j <= SurfaceElement(firstel).GetNP(); j++) - usedp.Set (SurfaceElement(firstel).PNum(j)); - - int changed; - do - { - changed = 0; - for (i = 1; i <= GetNSE(); i++) - { - const Element2d & el = SurfaceElement(i); - if (el.GetIndex() != fdi) - continue; - - int has = 0; - int hasno = 0; - for (j = 1; j <= el.GetNP(); j++) - { - if (usedp.Test(el.PNum(j))) - has = 1; - else - hasno = 1; - } - if (has && hasno) - changed = 1; - - if (has) - for (j = 1; j <= el.GetNP(); j++) - usedp.Set (el.PNum(j)); - } - } - while (changed); - - int nface = 0; - for (i = 1; i <= GetNSE(); i++) - { - Element2d & el = SurfaceElement(i); - if (el.GetIndex() != fdi) - continue; - - int hasno = 0; - for (j = 1; j <= el.GetNP(); j++) - { - if (!usedp.Test(el.PNum(j))) - hasno = 1; - } - - if (hasno) - { - if (!nface) - { - FaceDescriptor nfd = GetFaceDescriptor(fdi); - nface = AddFaceDescriptor (nfd); - } - - el.SetIndex (nface); - } - } - fdi++; - } - } - - - void Mesh :: GetSurfaceElementsOfFace (int facenr, ARRAY<SurfaceElementIndex> & sei) const - { - sei.SetSize (0); - for (SurfaceElementIndex i = 0; i < GetNSE(); i++) - if ( (*this)[i].GetIndex () == facenr && (*this)[i][0] >= PointIndex::BASE && - !(*this)[i].IsDeleted() ) - sei.Append (i); - } - - - - - void Mesh :: CalcMinMaxAngle (double badellimit, double * retvalues) - { - int i, j; - int lpi1, lpi2, lpi3, lpi4; - double phimax = 0, phimin = 10; - double facephimax = 0, facephimin = 10; - int illegaltets = 0, negativetets = 0, badtets = 0; - - for (i = 1; i <= GetNE(); i++) - { - int badel = 0; - - Element & el = VolumeElement(i); - - if (el.GetType() != TET) - { - VolumeElement(i).flags.badel = 0; - continue; - } - - if (el.Volume(Points()) < 0) - { - badel = 1; - negativetets++; - } - - - if (!LegalTet (el)) - { - badel = 1; - illegaltets++; - (*testout) << "illegal tet: " << i << " "; - for (j = 1; j <= el.GetNP(); j++) - (*testout) << el.PNum(j) << " "; - (*testout) << endl; - } - - - // angles between faces - for (lpi1 = 1; lpi1 <= 3; lpi1++) - for (lpi2 = lpi1+1; lpi2 <= 4; lpi2++) - { - lpi3 = 1; - while (lpi3 == lpi1 || lpi3 == lpi2) - lpi3++; - lpi4 = 10 - lpi1 - lpi2 - lpi3; - - const Point3d & p1 = Point (el.PNum(lpi1)); - const Point3d & p2 = Point (el.PNum(lpi2)); - const Point3d & p3 = Point (el.PNum(lpi3)); - const Point3d & p4 = Point (el.PNum(lpi4)); - - Vec3d n(p1, p2); - n /= n.Length(); - Vec3d v1(p1, p3); - Vec3d v2(p1, p4); - - v1 -= (n * v1) * n; - v2 -= (n * v2) * n; - - double cosphi = (v1 * v2) / (v1.Length() * v2.Length()); - double phi = acos (cosphi); - if (phi > phimax) phimax = phi; - if (phi < phimin) phimin = phi; - - if ((180/M_PI) * phi > badellimit) - badel = 1; - } - - - // angles in faces - for (j = 1; j <= 4; j++) - { - Element2d face; - el.GetFace (j, face); - for (lpi1 = 1; lpi1 <= 3; lpi1++) - { - lpi2 = lpi1 % 3 + 1; - lpi3 = lpi2 % 3 + 1; - - const Point3d & p1 = Point (el.PNum(lpi1)); - const Point3d & p2 = Point (el.PNum(lpi2)); - const Point3d & p3 = Point (el.PNum(lpi3)); - - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - double cosphi = (v1 * v2) / (v1.Length() * v2.Length()); - double phi = acos (cosphi); - if (phi > facephimax) facephimax = phi; - if (phi < facephimin) facephimin = phi; - - if ((180/M_PI) * phi > badellimit) - badel = 1; - - } - } - - - VolumeElement(i).flags.badel = badel; - if (badel) badtets++; - } - - if (!GetNE()) - { - phimin = phimax = facephimin = facephimax = 0; - } - - if (!retvalues) - { - PrintMessage (1, ""); - PrintMessage (1, "between planes: phimin = ", (180/M_PI) * phimin, - " phimax = ", (180/M_PI) *phimax); - PrintMessage (1, "inside planes: phimin = ", (180/M_PI) * facephimin, - " phimax = ", (180/M_PI) * facephimax); - PrintMessage (1, ""); - } - else - { - retvalues[0] = (180/M_PI) * facephimin; - retvalues[1] = (180/M_PI) * facephimax; - retvalues[2] = (180/M_PI) * phimin; - retvalues[3] = (180/M_PI) * phimax; - } - PrintMessage (3, "negative tets: ", negativetets); - PrintMessage (3, "illegal tets: ", illegaltets); - PrintMessage (3, "bad tets: ", badtets); - } - - - int Mesh :: MarkIllegalElements () - { - int cnt = 0; - int i; - - for (i = 1; i <= GetNE(); i++) - { - LegalTet (VolumeElement(i)); - - /* - Element & el = VolumeElement(i); - int leg1 = LegalTet (el); - el.flags.illegal_valid = 0; - int leg2 = LegalTet (el); - - if (leg1 != leg2) - { - cerr << "legal differs!!" << endl; - (*testout) << "legal differs" << endl; - (*testout) << "elnr = " << i << ", el = " << el - << " leg1 = " << leg1 << ", leg2 = " << leg2 << endl; - } - - // el.flags.illegal = !LegalTet (el); - */ - cnt += VolumeElement(i).Illegal(); - } - return cnt; - } - -#ifdef NONE - void Mesh :: AddIdentification (int pi1, int pi2, int identnr) - { - INDEX_2 pair(pi1, pi2); - // pair.Sort(); - identifiedpoints->Set (pair, identnr); - if (identnr > maxidentnr) - maxidentnr = identnr; - timestamp = NextTimeStamp(); - } - - int Mesh :: GetIdentification (int pi1, int pi2) const - { - INDEX_2 pair(pi1, pi2); - if (identifiedpoints->Used (pair)) - return identifiedpoints->Get(pair); - else - return 0; - } - - int Mesh :: GetIdentificationSym (int pi1, int pi2) const - { - INDEX_2 pair(pi1, pi2); - if (identifiedpoints->Used (pair)) - return identifiedpoints->Get(pair); - - pair = INDEX_2 (pi2, pi1); - if (identifiedpoints->Used (pair)) - return identifiedpoints->Get(pair); - - return 0; - } - - - void Mesh :: GetIdentificationMap (int identnr, ARRAY<int> & identmap) const - { - int i, j; - - identmap.SetSize (GetNP()); - for (i = 1; i <= identmap.Size(); i++) - identmap.Elem(i) = 0; - - for (i = 1; i <= identifiedpoints->GetNBags(); i++) - for (j = 1; j <= identifiedpoints->GetBagSize(i); j++) - { - INDEX_2 i2; - int nr; - identifiedpoints->GetData (i, j, i2, nr); - - if (nr == identnr) - { - identmap.Elem(i2.I1()) = i2.I2(); - } - } - } - - - void Mesh :: GetIdentificationPairs (int identnr, ARRAY<INDEX_2> & identpairs) const - { - int i, j; - - identpairs.SetSize(0); - - for (i = 1; i <= identifiedpoints->GetNBags(); i++) - for (j = 1; j <= identifiedpoints->GetBagSize(i); j++) - { - INDEX_2 i2; - int nr; - identifiedpoints->GetData (i, j, i2, nr); - - if (identnr == 0 || nr == identnr) - identpairs.Append (i2); - } - } -#endif - - void Mesh :: ComputeNVertices () - { - int i, j, nv; - int ne = GetNE(); - int nse = GetNSE(); - - numvertices = 0; - for (i = 1; i <= ne; i++) - { - const Element & el = VolumeElement(i); - nv = el.GetNV(); - for (j = 0; j < nv; j++) - if (el[j] > numvertices) - numvertices = el[j]; - } - for (i = 1; i <= nse; i++) - { - const Element2d & el = SurfaceElement(i); - nv = el.GetNV(); - for (j = 1; j <= nv; j++) - if (el.PNum(j) > numvertices) - numvertices = el.PNum(j); - } - - numvertices += 1- PointIndex::BASE; - } - - int Mesh :: GetNV () const - { - if (numvertices < 0) - return GetNP(); - else - return numvertices; - } - - void Mesh :: SetNP (int np) - { - points.SetSize(np); - // ptyps.SetSize(np); - - int mlold = mlbetweennodes.Size(); - mlbetweennodes.SetSize(np); - if (np > mlold) - for (int i = mlold+PointIndex::BASE; - i < np+PointIndex::BASE; i++) - { - mlbetweennodes[i].I1() = PointIndex::BASE-1; - mlbetweennodes[i].I2() = PointIndex::BASE-1; - } - - GetIdentifications().SetMaxPointNr (np + PointIndex::BASE-1); - } - - - /* - void Mesh :: BuildConnectedNodes () - { - if (PureTetMesh()) - { - connectedtonode.SetSize(0); - return; - } - - - int i, j, k; - int np = GetNP(); - int ne = GetNE(); - TABLE<int> conto(np); - for (i = 1; i <= ne; i++) - { - const Element & el = VolumeElement(i); - - if (el.GetType() == PRISM) - { - for (j = 1; j <= 6; j++) - { - int n1 = el.PNum (j); - int n2 = el.PNum ((j+2)%6+1); - // if (n1 != n2) - { - int found = 0; - for (k = 1; k <= conto.EntrySize(n1); k++) - if (conto.Get(n1, k) == n2) - { - found = 1; - break; - } - if (!found) - conto.Add (n1, n2); - } - } - } - else if (el.GetType() == PYRAMID) - { - for (j = 1; j <= 4; j++) - { - int n1, n2; - switch (j) - { - case 1: n1 = 1; n2 = 4; break; - case 2: n1 = 4; n2 = 1; break; - case 3: n1 = 2; n2 = 3; break; - case 4: n1 = 3; n2 = 2; break; - } - - int found = 0; - for (k = 1; k <= conto.EntrySize(n1); k++) - if (conto.Get(n1, k) == n2) - { - found = 1; - break; - } - if (!found) - conto.Add (n1, n2); - } - } - } - - connectedtonode.SetSize(np); - for (i = 1; i <= np; i++) - connectedtonode.Elem(i) = 0; - - for (i = 1; i <= np; i++) - if (connectedtonode.Elem(i) == 0) - { - connectedtonode.Elem(i) = i; - ConnectToNodeRec (i, i, conto); - } - - - - } - - void Mesh :: ConnectToNodeRec (int node, int tonode, - const TABLE<int> & conto) - { - int i, n2; - // (*testout) << "connect " << node << " to " << tonode << endl; - for (i = 1; i <= conto.EntrySize(node); i++) - { - n2 = conto.Get(node, i); - if (!connectedtonode.Get(n2)) - { - connectedtonode.Elem(n2) = tonode; - ConnectToNodeRec (n2, tonode, conto); - } - } - } - */ - - - bool Mesh :: PureTrigMesh (int faceindex) const - { - if (!faceindex) - return !mparam.quad; - - int i; - for (i = 1; i <= GetNSE(); i++) - if (SurfaceElement(i).GetIndex() == faceindex && - SurfaceElement(i).GetNP() != 3) - return 0; - return 1; - } - - bool Mesh :: PureTetMesh () const - { - for (ElementIndex ei = 0; ei < GetNE(); ei++) - if (VolumeElement(ei).GetNP() != 4) - return 0; - return 1; - } - - void Mesh :: UpdateTopology() - { - topology->Update(); - clusters->Update(); - } - - - void Mesh :: SetMaterial (int domnr, const char * mat) - { - if (domnr > materials.Size()) - { - int olds = materials.Size(); - materials.SetSize (domnr); - for (int i = olds; i < domnr; i++) - materials[i] = 0; - } - materials.Elem(domnr) = new char[strlen(mat)+1]; - strcpy (materials.Elem(domnr), mat); - } - - const char * Mesh :: GetMaterial (int domnr) const - { - if (domnr <= materials.Size()) - return materials.Get(domnr); - return 0; - } - - - - - - void Mesh :: PrintMemInfo (ostream & ost) const - { - ost << "Mesh Mem:" << endl; - - ost << GetNP() << " Points, of size " - << sizeof (Point3d) << " + " << sizeof(POINTTYPE) << " = " - << GetNP() * (sizeof (Point3d) + sizeof(POINTTYPE)) << endl; - - ost << GetNSE() << " Surface elements, of size " - << sizeof (Element2d) << " = " - << GetNSE() * sizeof(Element2d) << endl; - - ost << GetNE() << " Volume elements, of size " - << sizeof (Element) << " = " - << GetNE() * sizeof(Element) << endl; - - ost << "surfs on node:"; - surfacesonnode.PrintMemInfo (cout); - - ost << "boundaryedges: "; - if (boundaryedges) - boundaryedges->PrintMemInfo (cout); - - ost << "surfelementht: "; - if (surfelementht) - surfelementht->PrintMemInfo (cout); - } -} diff --git a/Netgen/libsrc/meshing/meshclass.hpp b/Netgen/libsrc/meshing/meshclass.hpp deleted file mode 100644 index 4ad0edbb9b..0000000000 --- a/Netgen/libsrc/meshing/meshclass.hpp +++ /dev/null @@ -1,620 +0,0 @@ -#ifndef MESHCLASS -#define MESHCLASS - -/**************************************************************************/ -/* File: meshclass.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 20. Nov. 99 */ -/**************************************************************************/ - -/* - The mesh class -*/ - - - -enum resthtype { RESTRICTH_FACE, RESTRICTH_EDGE, - RESTRICTH_SURFACEELEMENT, RESTRICTH_POINT, RESTRICTH_SEGMENT }; - -class HPRefElement; - - -/// 2d/3d mesh -class Mesh -{ -public: - // typedef MoveableArray<MeshPoint> T_POINTS; - // typedef MoveableArray<Element> T_VOLELEMENTS; - // typedef MoveableArray<Element2d> T_SURFELEMENTS; - - typedef ARRAY<MeshPoint,PointIndex::BASE> T_POINTS; - typedef ARRAY<Element> T_VOLELEMENTS; - typedef ARRAY<Element2d> T_SURFELEMENTS; - - -private: - /// point coordinates - T_POINTS points; - /// type of point, is set in calcsurfacesofnode - // ARRAY<POINTTYPE,PointIndex::BASE> ptyps; - /// type of element, set in calcsurfacesofnode - ARRAY<ELEMENTTYPE> eltyps; - - /// line-segments at edges - ARRAY<Segment> segments; - /// surface elements, 2d-inner elements - T_SURFELEMENTS surfelements; - /// volume elements - T_VOLELEMENTS volelements; - /// points will be fixed forever - ARRAY<PointIndex> lockedpoints; - - - /// surface indices at boundary nodes - TABLE<int,PointIndex::BASE> surfacesonnode; - /// boundary edges (1..normal bedge, 2..segment) - INDEX_2_CLOSED_HASHTABLE<int> * boundaryedges; - /// - INDEX_2_CLOSED_HASHTABLE<int> * segmentht; - /// - INDEX_3_CLOSED_HASHTABLE<int> * surfelementht; - - /// faces of rest-solid - ARRAY<Element2d> openelements; - /// open segmenets for surface meshing - ARRAY<Segment> opensegments; - - - - /** - Representation of local mesh-size h - */ - LocalH * lochfunc; - /// - double hglob; - /// - ARRAY<double> maxhdomain; - - /** - the face-index of the surface element maps into - this table. - */ - ARRAY<FaceDescriptor> facedecoding; - - /// sub-domain materials - ARRAY<char*> materials; - - /// Periodic surface, close surface, etc. identifications - Identifications * ident; - - - /// number of vertices (if < 0, use np) - int numvertices; - - /// geometric search tree for interval intersection search - Box3dTree * elementsearchtree; - /// time stamp for tree - int elementsearchtreets; - - /// element -> face, element -> edge etc ... - class MeshTopology * topology; - /// methods for high order elements - class CurvedElements * curvedelems; - /// nodes identified by close points - class AnisotropicClusters * clusters; - - /// space dimension (2 or 3) - int dimension; - - /// changed by every minor modification (addpoint, ...) - int timestamp; - /// changed after finishing global algorithm (improve, ...) - int majortimestamp; - - /// mesh access semaphor. - NgMutex mutex; - - -public: - - // store coarse mesh before hp-refinement - ARRAY<HPRefElement> * hpelements; - Mesh * coarsemesh; - - - /// number of refinement levels - int mglevels; - /// refinement hierarchy - ARRAY<INDEX_2,PointIndex::BASE> mlbetweennodes; - /// parent element of volume element - ARRAY<int> mlparentelement; - /// parent element of surface element - ARRAY<int> mlparentsurfaceelement; - - - - /// - Mesh(); - /// - ~Mesh(); - - Mesh & operator= (const Mesh & mesh2); - - /// - void DeleteMesh(); - - /// - void ClearSurfaceElements() - { - surfelements.SetSize(0); - timestamp = NextTimeStamp(); - } - - /// - void ClearVolumeElements() - { - volelements.SetSize(0); - eltyps.SetSize(0); - timestamp = NextTimeStamp(); - } - - /// - void ClearSegments() - { - segments.SetSize(0); - timestamp = NextTimeStamp(); - } - - /// - bool TestOk () const; - - - PointIndex AddPoint (const Point3d & p, int layer = 1); - int GetNP () const { return points.Size(); } - - MeshPoint & Point(int i) { return points.Elem(i); } - MeshPoint & Point(PointIndex pi) { return points[pi]; } - const MeshPoint & Point(int i) const { return points.Get(i); } - const MeshPoint & Point(PointIndex pi) const { return points[pi]; } - - const MeshPoint & operator[] (PointIndex pi) const { return points[pi]; } - MeshPoint & operator[] (PointIndex pi) { return points[pi]; } - - /* - POINTTYPE PointType (int i) const { return ptyps.Get(i); } - POINTTYPE PointType (PointIndex pi) const { return ptyps[pi]; } - */ - POINTTYPE PointType (int i) const { return points.Get(i).Type(); } - POINTTYPE PointType (PointIndex pi) const { return points[pi].Type(); } - - - const T_POINTS & Points() const { return points; } - T_POINTS & Points() { return points; } - // ARRAY<POINTTYPE,PointIndex::BASE> & PointTypes() { return ptyps; } - - - - - - - SegmentIndex AddSegment (const Segment & s); - void DeleteSegment (int segnr) - { - segments.Elem(segnr).p1 = PointIndex::BASE-1; - segments.Elem(segnr).p2 = PointIndex::BASE-1; - } - - int GetNSeg () const { return segments.Size(); } - Segment & LineSegment(int i) { return segments.Elem(i); } - const Segment & LineSegment(int i) const { return segments.Get(i); } - - Segment & LineSegment(SegmentIndex si) { return segments[si]; } - const Segment & LineSegment(SegmentIndex si) const { return segments[si]; } - const Segment & operator[] (SegmentIndex si) const { return segments[si]; } - Segment & operator[] (SegmentIndex si) { return segments[si]; } - - - - - SurfaceElementIndex AddSurfaceElement (const Element2d & el); - void DeleteSurfaceElement (int eli) - { - surfelements.Elem(eli).Delete(); - surfelements.Elem(eli).PNum(1) = -1; - surfelements.Elem(eli).PNum(2) = -1; - surfelements.Elem(eli).PNum(3) = -1; - timestamp = NextTimeStamp(); - } - - void DeleteSurfaceElement (SurfaceElementIndex eli) - { - DeleteSurfaceElement (int(eli)+1); - } - - int GetNSE () const { return surfelements.Size(); } - Element2d & SurfaceElement(int i) { return surfelements.Elem(i); } - const Element2d & SurfaceElement(int i) const { return surfelements.Get(i); } - - Element2d & SurfaceElement(SurfaceElementIndex i) - { return surfelements[i]; } - const Element2d & SurfaceElement(SurfaceElementIndex i) const - { return surfelements[i]; } - - const Element2d & operator[] (SurfaceElementIndex ei) const - { return surfelements[ei]; } - Element2d & operator[] (SurfaceElementIndex ei) - { return surfelements[ei]; } - - - void GetSurfaceElementsOfFace (int facenr, ARRAY<SurfaceElementIndex> & sei) const; - - - - ElementIndex AddVolumeElement (const Element & el); - - int GetNE () const { return volelements.Size(); } - - Element & VolumeElement(int i) { return volelements.Elem(i); } - const Element & VolumeElement(int i) const { return volelements.Get(i); } - Element & VolumeElement(ElementIndex i) { return volelements[i]; } - const Element & VolumeElement(ElementIndex i) const { return volelements[i]; } - - const Element & operator[] (ElementIndex ei) const - { return volelements[ei]; } - Element & operator[] (ElementIndex ei) - { return volelements[ei]; } - - - - - - ELEMENTTYPE ElementType (int i) const { return eltyps.Get(i); } - ELEMENTTYPE ElementType (ElementIndex i) const { return eltyps[i]; } - - const T_VOLELEMENTS & VolumeElements() const { return volelements; } - T_VOLELEMENTS & VolumeElements() { return volelements; } - - - /// - double ElementError (int eli) const; - - /// - void AddLockedPoint (PointIndex pi); - /// - void ClearLockedPoints (); - - const ARRAY<PointIndex> & LockedPoints() const - { return lockedpoints; } - - /// Returns number of domains - int GetNDomains() const; - - - /// - int GetDimension() const - { return dimension; } - void SetDimension(int dim) - { dimension = dim; } - - /// sets internal tables - void CalcSurfacesOfNode (); - - /// additional (temporarily) fix points - void FixPoints (const BitArray & fixpoints); - - /** - finds elements without neighbour and - boundary elements without inner element. - Results are stored in openelements. - if dom == 0, all sub-domains, else subdomain dom */ - void FindOpenElements (int dom = 0); - - - /** - finds segments without surface element, - and surface elements without neighbours. - store in opensegmentsy - */ - void FindOpenSegments (int surfnr = 0); - /** - remove one layer of surface elements - */ - void RemoveOneLayerSurfaceElements (); - - - int GetNOpenSegments () { return opensegments.Size(); } - const Segment & GetOpenSegment (int nr) { return opensegments.Get(nr); } - - /** - Checks overlap of boundary - return == 1, iff overlap - */ - int CheckOverlappingBoundary (); - /** - Checks consistent boundary - return == 0, everything ok - */ - int CheckConsistentBoundary () const; - - /* - checks element orientation - */ - int CheckVolumeMesh () const; - - - /** - finds average h of surface surfnr if surfnr > 0, - else of all surfaces. - */ - double AverageH (int surfnr = 0) const; - /// Calculates localh - void CalcLocalH (); - /// - void SetLocalH (const Point3d & pmin, const Point3d & pmax, double grading); - /// - void RestrictLocalH (const Point3d & p, double hloc); - /// - void RestrictLocalHLine (const Point3d & p1, const Point3d & p2, - double hloc); - /// number of elements per radius - void CalcLocalHFromSurfaceCurvature(double elperr); - /// - void CalcLocalHFromPointDistances(void); - /// - void RestrictLocalH (resthtype rht, int nr, double loch); - /// - void LoadLocalMeshSize (const char * meshsizefilename); - /// - void SetGlobalH (double h); - /// - double MaxHDomain (int dom) const; - /// - void SetMaxHDomain (const ARRAY<double> & mhd); - /// - double GetH (const Point3d & p) const; - /// - double GetMinH (const Point3d & pmin, const Point3d & pmax); - /// - LocalH & LocalHFunction () { return * lochfunc; } - - /// Find bounding box - void GetBox (Point3d & pmin, Point3d & pmax, int dom = -1) const; - - /// Find bounding box of points of typ ptyp or less - void GetBox (Point3d & pmin, Point3d & pmax, POINTTYPE ptyp ) const; - - /// - int GetNOpenElements() const - { return openelements.Size(); } - /// - const Element2d & OpenElement(int i) const - { return openelements.Get(i); } - - - /// are also quads open elements - int HasOpenQuads () const; - - /// split into connected pieces - void SplitIntoParts (); - - /// - void SplitSeparatedFaces (); - - /// Refines mesh and projects points to true surface - // void Refine (int levels, const CSGeometry * geom); - - - bool BoundaryEdge (PointIndex pi1, PointIndex pi2) const - { - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - return boundaryedges->Used (i2); - } - - bool IsSegment (PointIndex pi1, PointIndex pi2) const - { - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - return segmentht->Used (i2); - } - - SegmentIndex SegmentNr (PointIndex pi1, PointIndex pi2) const - { - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - return segmentht->Get (i2); - } - - - /** - Remove unused points. etc. - */ - void Compress (); - - /// - void Save (const string & filename) const; - /// - void Load (const string & filename); - /// - void Merge (const string & filename); - - - /// - void ImproveMesh (OPTIMIZEGOAL goal = OPT_QUALITY); - - /// - void ImproveMeshJacobian (OPTIMIZEGOAL goal = OPT_QUALITY); - - - /* -#ifdef SOLIDGEOM - /// old - void ImproveMesh (const CSGeometry & surfaces, - OPTIMIZEGOAL goal = OPT_QUALITY); -#endif - */ - - /** - free nodes in environment of openelements - for optimiztion - */ - void FreeOpenElementsEnvironment (int layers); - - /// - bool LegalTet (Element & el) const - { - if (el.IllegalValid()) - return !el.Illegal(); - return LegalTet2 (el); - } - /// - bool LegalTet2 (Element & el) const; - - - /// - bool LegalTrig (const Element2d & el) const; - /** - if values non-null, return values in 4-double array: - triangle angles min/max, tetangles min/max - if null, output results on cout - */ - void CalcMinMaxAngle (double badellimit, double * retvalues = NULL); - - /* - Marks elements which are dangerous to refine - return: number of illegal elements - */ - int MarkIllegalElements (); - - /// orient surface mesh, for one sub-domain only - void SurfaceMeshOrientation (); - - /// convert mixed element mesh to tet-mesh - void Split2Tets(); - - - /// build box-search tree - void BuildElementSearchTree (); - /// gives element of point, barycentric coordinates - int GetElementOfPoint (const Point3d & p, - double * lami, - bool build_searchtree = 0, - const int index = -1) const; - - /// give list of vol elements which are int the box(p1,p2) - void GetIntersectingVolEls(const Point3d& p1, const Point3d& p2, - ARRAY<int> & locels) const; - - /// - int AddFaceDescriptor(const FaceDescriptor& fd) - { return facedecoding.Append(fd); } - - - /// - void SetMaterial (int domnr, const char * mat); - /// - const char * GetMaterial (int domnr) const; - - - /// - void ClearFaceDescriptors() - { facedecoding.SetSize(0); } - - /// - int GetNFD () const - { return facedecoding.Size(); } - - const FaceDescriptor & GetFaceDescriptor (int i) const - { return facedecoding.Get(i); } - - /// - FaceDescriptor & GetFaceDescriptor (int i) - { return facedecoding.Elem(i); } - -#ifdef NONE - /* - Identify points pi1 and pi2, due to - identification nr identnr - */ - void AddIdentification (int pi1, int pi2, int identnr); - - int GetIdentification (int pi1, int pi2) const; - int GetIdentificationSym (int pi1, int pi2) const; - /// - INDEX_2_HASHTABLE<int> & GetIdentifiedPoints () - { - return *identifiedpoints; - } - - /// - void GetIdentificationMap (int identnr, ARRAY<int> & identmap) const; - /// - void GetIdentificationPairs (int identnr, ARRAY<INDEX_2> & identpairs) const; - /// - int GetMaxIdentificationNr () const - { - return maxidentnr; - } -#endif - - /// return periodic, close surface etc. identifications - Identifications & GetIdentifications () { return *ident; } - /// return periodic, close surface etc. identifications - const Identifications & GetIdentifications () const { return *ident; } - - - - /// find number of vertices - void ComputeNVertices (); - /// number of vertices (no edge-midpoints) - int GetNV () const; - /// remove edge points - void SetNP (int np); - - /* - /// build connected nodes along prism stack - void BuildConnectedNodes (); - void ConnectToNodeRec (int node, int tonode, - const TABLE<int> & conto); - */ - - bool PureTrigMesh (int faceindex = 0) const; - bool PureTetMesh () const; - - - const class MeshTopology & GetTopology () const - { return *topology; } - void UpdateTopology(); - - class CurvedElements & GetCurvedElements () const - { return *curvedelems; } - - const class AnisotropicClusters & GetClusters () const - { return *clusters; } - - - - int GetTimeStamp() const { return timestamp; } - void SetNextTimeStamp() - { timestamp = NextTimeStamp(); } - - int GetMajorTimeStamp() const { return majortimestamp; } - void SetNextMajorTimeStamp() - { majortimestamp = timestamp = NextTimeStamp(); } - - - /// return mutex - NgMutex & Mutex () { return mutex; } - - /// - friend void OptimizeRestart (Mesh & mesh3d); - /// - void PrintMemInfo (ostream & ost) const; - /// - friend class Meshing3; -}; - - - - -#endif diff --git a/Netgen/libsrc/meshing/meshfunc.cpp b/Netgen/libsrc/meshing/meshfunc.cpp deleted file mode 100644 index 90fe9e68c5..0000000000 --- a/Netgen/libsrc/meshing/meshfunc.cpp +++ /dev/null @@ -1,688 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - extern const char * tetrules[]; - // extern const char * tetrules2[]; - extern const char * prismrules2[]; - extern const char * pyramidrules[]; - extern const char * pyramidrules2[]; - - - extern double teterrpow; - MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d) - { - int i, oldne; - PointIndex pi; - - int meshed; - int cntsteps; - - - ARRAY<INDEX_2> connectednodes; - - mesh3d.Compress(); - - // mesh3d.PrintMemInfo (cout); - - - - if (mesh3d.CheckOverlappingBoundary()) - throw NgException ("Stop meshing since boundary mesh is overlapping"); - - - int nonconsist = 0; - for (int k = 1; k <= mesh3d.GetNDomains(); k++) - { - PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains()); - - mesh3d.FindOpenElements(k); - - /* - bool res = mesh3d.CheckOverlappingBoundary(); - if (res) - { - PrintError ("Surface is overlapping !!"); - nonconsist = 1; - } - */ - - bool res = mesh3d.CheckConsistentBoundary(); - if (res) - { - PrintError ("Surface mesh not consistent"); - nonconsist = 1; - } - } - - if (nonconsist) - { - PrintError ("Stop meshing since surface mesh not consistent"); - throw NgException ("Stop meshing since surface mesh not consistent"); - } - - double globmaxh = mp.maxh; - - for (int k = 1; k <= mesh3d.GetNDomains(); k++) - { - if (multithread.terminate) - break; - - PrintMessage (2, ""); - PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains()); - - mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k)); - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(k); - - if (!mesh3d.GetNOpenElements()) - continue; - - int qstep; - for (qstep = 1; qstep <= 3; qstep++) - { - if (mesh3d.HasOpenQuads()) - { - string rulefile = ngdir; - - const char ** rulep = NULL; - switch (qstep) - { - case 1: - rulefile += "/rules/prisms2.rls"; - rulep = prismrules2; - break; - case 2: // connect pyramid to triangle - rulefile += "/rules/pyramids2.rls"; - rulep = pyramidrules2; - break; - case 3: // connect to vis-a-vis point - rulefile += "/rules/pyramids.rls"; - rulep = pyramidrules; - break; - } - - // Meshing3 meshing(rulefile); - Meshing3 meshing(rulep); - - MeshingParameters mpquad = mp; - - mpquad.giveuptol = 15; - mpquad.baseelnp = 4; - mpquad.starshapeclass = 100; - - for (pi = PointIndex::BASE; - pi < mesh3d.GetNP()+PointIndex::BASE; pi++) - meshing.AddPoint (mesh3d[pi], pi); - - mesh3d.GetIdentifications().GetPairs (0, connectednodes); - for (i = 1; i <= connectednodes.Size(); i++) - meshing.AddConnectedPair (connectednodes.Get(i)); - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - Element2d hel = mesh3d.OpenElement(i); - meshing.AddBoundaryElement (hel); - } - - oldne = mesh3d.GetNE(); - - meshing.GenerateMesh (mesh3d, mpquad); - - for (i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - - (*testout) - << "mesh has " << mesh3d.GetNE() << " prism ?�elements" << endl; - - mesh3d.FindOpenElements(k); - } - } - - - if (mesh3d.HasOpenQuads()) - { - PrintSysError ("mesh has still open quads"); - throw NgException ("Stop meshing since too many attempts"); - // return MESHING3_GIVEUP; - } - - - if (mp.delaunay && mesh3d.GetNOpenElements()) - { - Meshing3 meshing((const char**)NULL); - - mesh3d.FindOpenElements(k); - - - for (pi = PointIndex::BASE; - pi < mesh3d.GetNP()+PointIndex::BASE; pi++) - meshing.AddPoint (mesh3d[pi], pi); - - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - - oldne = mesh3d.GetNE(); - - meshing.Delaunay (mesh3d, mp); - - for (i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - - PrintMessage (3, mesh3d.GetNP(), " points, ", - mesh3d.GetNE(), " elements"); - } - - - cntsteps = 0; - do - { - if (multithread.terminate) - break; - - mesh3d.FindOpenElements(k); - PrintMessage (5, mesh3d.GetNOpenElements(), " open faces"); - cntsteps++; - - if (cntsteps > mp.maxoutersteps) - throw NgException ("Stop meshing since too many attempts"); - - string rulefile = ngdir + "/tetra.rls"; - PrintMessage (1, "start tetmeshing"); - - // Meshing3 meshing(rulefile); - Meshing3 meshing(tetrules); - - - for (PointIndex pi = PointIndex::BASE; - pi < mesh3d.GetNP()+PointIndex::BASE; pi++) - meshing.AddPoint (mesh3d[pi], pi); - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - - - oldne = mesh3d.GetNE(); - - mp.giveuptol = 15; - mp.sloppy = 5; - meshing.GenerateMesh (mesh3d, mp); - - for (ElementIndex ei = oldne; ei < mesh3d.GetNE(); ei++) - mesh3d[ei].SetIndex (k); - - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(k); - - teterrpow = 2; - if (mesh3d.GetNOpenElements() != 0) - { - meshed = 0; - PrintMessage (5, mesh3d.GetNOpenElements(), " open faces found"); - - // mesh3d.Save ("tmp.vol"); - - - MeshOptimize3d optmesh; - - const char * optstr = "mcmstmcmstmcmstmcm"; - int j; - for (j = 1; j <= strlen(optstr); j++) - { - mesh3d.CalcSurfacesOfNode(); - mesh3d.FreeOpenElementsEnvironment(2); - - switch (optstr[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d, OPT_REST); break; - case 's': optmesh.SwapImprove(mesh3d, OPT_REST); break; - case 't': optmesh.SwapImprove2(mesh3d, OPT_REST); break; - case 'm': mesh3d.ImproveMesh(OPT_REST); break; - } - - } - - mesh3d.FindOpenElements(k); - PrintMessage (3, "Call remove problem"); - RemoveProblem (mesh3d); - mesh3d.FindOpenElements(k); - } - else - { - meshed = 1; - PrintMessage (1, "Success !"); - } - } - while (!meshed); - - PrintMessage (1, mesh3d.GetNP(), " points, ", - mesh3d.GetNE(), " elements"); - } - - mp.maxh = globmaxh; - - MeshQuality3d (mesh3d); - - return MESHING3_OK; - } - - - - - /* - - - MESHING3_RESULT MeshVolumeOld (MeshingParameters & mp, Mesh& mesh3d) - { - int i, k, oldne; - - - int meshed; - int cntsteps; - - - PlotStatistics3d * pstat; - if (globflags.GetNumFlag("silentflag", 1) <= 2) - pstat = new XPlotStatistics3d; - else - pstat = new TerminalPlotStatistics3d; - - cntsteps = 0; - do - { - cntsteps++; - if (cntsteps > mp.maxoutersteps) - { - return MESHING3_OUTERSTEPSEXCEEDED; - } - - - int noldp = mesh3d.GetNP(); - - - if ( (cntsteps == 1) && globflags.GetDefineFlag ("delaunay")) - { - cntsteps ++; - - mesh3d.CalcSurfacesOfNode(); - - - for (k = 1; k <= mesh3d.GetNDomains(); k++) - { - Meshing3 meshing(NULL, pstat); - - mesh3d.FindOpenElements(k); - - for (i = 1; i <= noldp; i++) - meshing.AddPoint (mesh3d.Point(i), i); - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - if (mesh3d.OpenElement(i).GetIndex() == k) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - } - - oldne = mesh3d.GetNE(); - if (globflags.GetDefineFlag ("blockfill")) - { - if (!globflags.GetDefineFlag ("localh")) - meshing.BlockFill - (mesh3d, mp.h * globflags.GetNumFlag ("relblockfillh", 1)); - else - meshing.BlockFillLocalH (mesh3d); - } - - MeshingParameters mpd; - meshing.Delaunay (mesh3d, mpd); - - for (i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - } - } - - noldp = mesh3d.GetNP(); - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - for (k = 1; k <= mesh3d.GetNDomains(); k++) - { - Meshing3 meshing(globflags.GetStringFlag ("rules3d", NULL), pstat); - - Point3d pmin, pmax; - mesh3d.GetBox (pmin, pmax, k); - - rot.SetCenter (Center (pmin, pmax)); - - for (i = 1; i <= noldp; i++) - meshing.AddPoint (mesh3d.Point(i), i); - - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - { - if (mesh3d.OpenElement(i).GetIndex() == k) - meshing.AddBoundaryElement (mesh3d.OpenElement(i)); - } - - oldne = mesh3d.GetNE(); - - - if ( (cntsteps == 1) && globflags.GetDefineFlag ("blockfill")) - { - if (!globflags.GetDefineFlag ("localh")) - { - meshing.BlockFill - (mesh3d, - mp.h * globflags.GetNumFlag ("relblockfillh", 1)); - } - else - { - meshing.BlockFillLocalH (mesh3d); - } - } - - - mp.giveuptol = int(globflags.GetNumFlag ("giveuptol", 15)); - - meshing.GenerateMesh (mesh3d, mp); - - for (i = oldne + 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (k); - } - - - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - - teterrpow = 2; - if (mesh3d.GetNOpenElements() != 0) - { - meshed = 0; - (*mycout) << "Open elements found, old" << endl; - const char * optstr = "mcmcmcmcm"; - int j; - for (j = 1; j <= strlen(optstr); j++) - switch (optstr[j-1]) - { - case 'c': mesh3d.CombineImprove(); break; - case 'd': mesh3d.SplitImprove(); break; - case 's': mesh3d.SwapImprove(); break; - case 'm': mesh3d.ImproveMesh(2); break; - } - - (*mycout) << "Call remove" << endl; - RemoveProblem (mesh3d); - (*mycout) << "Problem removed" << endl; - } - else - meshed = 1; - } - while (!meshed); - - MeshQuality3d (mesh3d); - - return MESHING3_OK; - } - - */ - - - MESHING3_RESULT MeshMixedVolume(MeshingParameters & mp, Mesh& mesh3d) - { - int i, j; - MESHING3_RESULT res; - Point3d pmin, pmax; - - mp.giveuptol = 10; - mp.baseelnp = 4; - mp.starshapeclass = 100; - - // TerminalPlotStatistics3d pstat; - - Meshing3 meshing1("pyramids.rls"); - for (i = 1; i <= mesh3d.GetNP(); i++) - meshing1.AddPoint (mesh3d.Point(i), i); - - mesh3d.FindOpenElements(); - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - if (mesh3d.OpenElement(i).GetIndex() == 1) - meshing1.AddBoundaryElement (mesh3d.OpenElement(i)); - - res = meshing1.GenerateMesh (mesh3d, mp); - - mesh3d.GetBox (pmin, pmax); - PrintMessage (1, "Mesh pyramids, res = ", res); - if (res) - exit (1); - - - for (i = 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (1); - - // do delaunay - - mp.baseelnp = 0; - mp.starshapeclass = 5; - - Meshing3 meshing2(NULL); - for (i = 1; i <= mesh3d.GetNP(); i++) - meshing2.AddPoint (mesh3d.Point(i), i); - - mesh3d.FindOpenElements(); - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - if (mesh3d.OpenElement(i).GetIndex() == 1) - meshing2.AddBoundaryElement (mesh3d.OpenElement(i)); - - MeshingParameters mpd; - meshing2.Delaunay (mesh3d, mpd); - - for (i = 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (1); - - - mp.baseelnp = 0; - mp.giveuptol = 10; - - for (int trials = 1; trials <= 50; trials++) - { - if (multithread.terminate) - return MESHING3_TERMINATE; - - Meshing3 meshing3("tetra.rls"); - for (i = 1; i <= mesh3d.GetNP(); i++) - meshing3.AddPoint (mesh3d.Point(i), i); - - mesh3d.FindOpenElements(); - for (i = 1; i <= mesh3d.GetNOpenElements(); i++) - if (mesh3d.OpenElement(i).GetIndex() == 1) - meshing3.AddBoundaryElement (mesh3d.OpenElement(i)); - - if (trials > 1) - CheckSurfaceMesh2 (mesh3d); - res = meshing3.GenerateMesh (mesh3d, mp); - - for (i = 1; i <= mesh3d.GetNE(); i++) - mesh3d.VolumeElement(i).SetIndex (1); - - if (res == 0) break; - - - - for (i = 1; i <= mesh3d.GetNE(); i++) - { - const Element & el = mesh3d.VolumeElement(i); - if (el.GetNP() != 4) - { - for (j = 1; j <= el.GetNP(); j++) - mesh3d.AddLockedPoint (el.PNum(j)); - } - } - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - - MeshOptimize3d optmesh; - - teterrpow = 2; - const char * optstr = "mcmcmcmcm"; - for (j = 1; j <= strlen(optstr); j++) - switch (optstr[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d); break; - case 's': optmesh.SwapImprove(mesh3d); break; - case 'm': mesh3d.ImproveMesh(); break; - } - - RemoveProblem (mesh3d); - } - - - PrintMessage (1, "Meshing tets, res = ", res); - if (res) - { - mesh3d.FindOpenElements(); - PrintSysError (1, "Open elemetns: ", mesh3d.GetNOpenElements()); - exit (1); - } - - - - for (i = 1; i <= mesh3d.GetNE(); i++) - { - const Element & el = mesh3d.VolumeElement(i); - if (el.GetNP() != 4) - { - for (j = 1; j <= el.GetNP(); j++) - mesh3d.AddLockedPoint (el.PNum(j)); - } - } - - mesh3d.CalcSurfacesOfNode(); - mesh3d.FindOpenElements(); - - MeshOptimize3d optmesh; - - teterrpow = 2; - const char * optstr = "mcmcmcmcm"; - for (j = 1; j <= strlen(optstr); j++) - switch (optstr[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d); break; - case 's': optmesh.SwapImprove(mesh3d); break; - case 'm': mesh3d.ImproveMesh(); break; - } - - - return MESHING3_OK; - } - - - - - - - - MESHING3_RESULT OptimizeVolume (MeshingParameters & mp, - Mesh & mesh3d) - // const CSGeometry * geometry) - { - int i, j; - - PrintMessage (1, "Volume Optimization"); - - /* - if (!mesh3d.PureTetMesh()) - return MESHING3_OK; - */ - - // (*mycout) << "optstring = " << mp.optimize3d << endl; - /* - const char * optstr = globflags.GetStringFlag ("optimize3d", "cmh"); - int optsteps = int (globflags.GetNumFlag ("optsteps3d", 2)); - */ - - mesh3d.CalcSurfacesOfNode(); - for (i = 1; i <= mp.optsteps3d; i++) - { - if (multithread.terminate) - break; - - MeshOptimize3d optmesh; - - teterrpow = mp.opterrpow; - for (j = 1; j <= strlen(mp.optimize3d); j++) - { - if (multithread.terminate) - break; - - switch (mp.optimize3d[j-1]) - { - case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; - case 'd': optmesh.SplitImprove(mesh3d); break; - case 's': optmesh.SwapImprove(mesh3d); break; - case 't': optmesh.SwapImprove2(mesh3d); break; -#ifdef SOLIDGEOM - case 'm': mesh3d.ImproveMesh(*geometry); break; - case 'M': mesh3d.ImproveMesh(*geometry); break; -#else - case 'm': mesh3d.ImproveMesh(); break; - case 'M': mesh3d.ImproveMesh(); break; -#endif - - case 'j': mesh3d.ImproveMeshJacobian(); break; - } - } - MeshQuality3d (mesh3d); - } - - return MESHING3_OK; - } - - - - - void RemoveIllegalElements (Mesh & mesh3d) - { - int it = 10; - int nillegal, oldn; - int i; - - PrintMessage (1, "Remove Illegal Elements"); - // return, if non-pure tet-mesh - /* - if (!mesh3d.PureTetMesh()) - return; - */ - mesh3d.CalcSurfacesOfNode(); - - nillegal = mesh3d.MarkIllegalElements(); - - MeshOptimize3d optmesh; - while (nillegal && (it--) > 0) - { - if (multithread.terminate) - break; - - PrintMessage (5, nillegal, " illegal tets"); - optmesh.SplitImprove (mesh3d, OPT_LEGAL); - - mesh3d.MarkIllegalElements(); // test - optmesh.SwapImprove (mesh3d, OPT_LEGAL); - mesh3d.MarkIllegalElements(); // test - optmesh.SwapImprove2 (mesh3d, OPT_LEGAL); - - oldn = nillegal; - nillegal = mesh3d.MarkIllegalElements(); - - if (oldn != nillegal) - it = 10; - } - PrintMessage (5, nillegal, " illegal tets"); - } -} diff --git a/Netgen/libsrc/meshing/meshfunc.hpp b/Netgen/libsrc/meshing/meshfunc.hpp deleted file mode 100644 index ab2d661050..0000000000 --- a/Netgen/libsrc/meshing/meshfunc.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef FILE_MESHFUNC -#define FILE_MESHFUNC - -/**************************************************************************/ -/* File: meshfunc.hh */ -/* Author: Johannes Gerstmayr */ -/* Date: 26. Jan. 98 */ -/**************************************************************************/ - - -/* - Functions for mesh-generations strategies - */ - -class Mesh; -// class CSGeometry; - -/// Build tet-mesh -MESHING3_RESULT MeshVolume(MeshingParameters & mp, Mesh& mesh3d); - -/// Build mixed-element mesh -MESHING3_RESULT MeshMixedVolume(MeshingParameters & mp, Mesh& mesh3d); - -/// Optimize tet-mesh -MESHING3_RESULT OptimizeVolume(MeshingParameters & mp, Mesh& mesh3d); -// const CSGeometry * geometry = NULL); - -void RemoveIllegalElements (Mesh & mesh3d); - - -enum MESHING_STEP { - MESHCONST_ANALYSE = 1, - MESHCONST_MESHEDGES = 2, - MESHCONST_MESHSURFACE = 3, - MESHCONST_OPTSURFACE = 4, - MESHCONST_MESHVOLUME = 5, - MESHCONST_OPTVOLUME = 6 -}; - - -#endif diff --git a/Netgen/libsrc/meshing/meshfunc2d.cpp b/Netgen/libsrc/meshing/meshfunc2d.cpp deleted file mode 100644 index f329d1df76..0000000000 --- a/Netgen/libsrc/meshing/meshfunc2d.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - - void Optimize2d (Mesh & mesh, MeshingParameters & mp) - { - int i, j; - - double h = mp.maxh; - - mesh.CalcSurfacesOfNode(); - - const char * optstr = mp.optimize2d; - int optsteps = mp.optsteps2d; - - // cout << "optstr = " << optstr << endl; - - for (i = 1; i <= optsteps; i++) - for (j = 1; j <= strlen(optstr); j++) - { - if (multithread.terminate) break; - switch (optstr[j-1]) - { - case 's': - { // topological swap - MeshOptimize2d meshopt; - meshopt.SetMetricWeight (0); - meshopt.EdgeSwapping (mesh, 0); - break; - } - case 'S': - { // metric swap - MeshOptimize2d meshopt; - meshopt.SetMetricWeight (0); - meshopt.EdgeSwapping (mesh, 1); - break; - } - case 'm': - { - MeshOptimize2d meshopt; - meshopt.SetMetricWeight (1); - meshopt.ImproveMesh(mesh); - break; - } - - case 'c': - { - MeshOptimize2d meshopt; - meshopt.SetMetricWeight (0.2); - meshopt.CombineImprove(mesh); - break; - } - default: - cerr << "Optimization code " << optstr[j-1] << " not defined" << endl; - } - } - } - -} diff --git a/Netgen/libsrc/meshing/meshing.hpp b/Netgen/libsrc/meshing/meshing.hpp deleted file mode 100644 index a4442867b3..0000000000 --- a/Netgen/libsrc/meshing/meshing.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef FILE_MESHING -#define FILE_MESHING - -#include <myadt.hpp> -#include <gprim.hpp> -#include <linalg.hpp> -#include <opti.hpp> - -namespace netgen -{ - - class CSGeometry; - - -#include "msghandler.hpp" - -#include "meshtype.hpp" -#include "localh.hpp" -#include "meshclass.hpp" -#include "global.hpp" - - -#include "meshtool.hpp" -#include "ruler2.hpp" -#include "adfront2.hpp" -#include "meshing2.hpp" -#include "improve2.hpp" - - -#include "geomsearch.hpp" -#include "adfront3.hpp" -#include "ruler3.hpp" - -#ifndef SMALLLIB -#define _INCLUDE_MORE -#endif -#ifdef LINUX -#define _INCLUDE_MORE -#endif - -#ifdef _INCLUDE_MORE -#include "meshing3.hpp" -#include "improve3.hpp" -#endif -#include "findip.hpp" - -#include "topology.hpp" -#include "curvedelems.hpp" -#include "clusters.hpp" - -#ifdef _INCLUDE_MORE -#include "meshfunc.hpp" -#endif -#include "bisect.hpp" -#include "hprefinement.hpp" -#include "boundarylayer.hpp" -#include "specials.hpp" -} - -#endif diff --git a/Netgen/libsrc/meshing/meshing2.cpp b/Netgen/libsrc/meshing/meshing2.cpp deleted file mode 100644 index e7643194c4..0000000000 --- a/Netgen/libsrc/meshing/meshing2.cpp +++ /dev/null @@ -1,1864 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - static void glrender (int wait); - - - // global variable for visualization - - static ARRAY<Point3d> locpoints; - static ARRAY<int> legalpoints; - static ARRAY<Point2d> plainpoints; - static ARRAY<int> plainzones; - static ARRAY<INDEX_2> loclines; - static int geomtrig; - //static const char * rname; - static int cntelem, trials, nfaces; - static int oldnl; - static int qualclass; - - - Meshing2 :: Meshing2 (const Box3d & aboundingbox) - { - boundingbox = aboundingbox; - - LoadRules (NULL); - // LoadRules ("rules/quad.rls"); - // LoadRules ("rules/triangle.rls"); - - adfront = new AdFront2(boundingbox); - starttime = GetTime(); - } - - - Meshing2 :: ~Meshing2 () - { - delete adfront; - for (int i = 0; i < rules.Size(); i++) - delete rules[i]; - } - - void Meshing2 :: AddPoint (const Point3d & p, PointIndex globind, - MultiPointGeomInfo * mgi) - { - // (*testout) << "add point " << globind << endl; - adfront ->AddPoint (p, globind, mgi); - } - - void Meshing2 :: AddBoundaryElement (int i1, int i2, - const PointGeomInfo & gi1, const PointGeomInfo & gi2) - { - // (*testout) << "add line " << i1 << " - " << i2 << endl; - if (!gi1.trignum || !gi2.trignum) - { - PrintSysError ("addboundaryelement: illegal geominfo"); - } - adfront -> AddLine (i1, i2, gi1, gi2); - } - - - - void Meshing2 :: StartMesh () - { - foundmap.SetSize (rules.Size()); - canuse.SetSize (rules.Size()); - ruleused.SetSize (rules.Size()); - - foundmap = 0; - canuse = 0; - ruleused = 0; - - cntelem = 0; - trials = 0; - } - - void Meshing2 :: EndMesh () - { - for (int i = 0; i < ruleused.Size(); i++) - (*testout) << setw(4) << ruleused[i] - << " times used rule " << rules[i] -> Name() << endl; - } - - void Meshing2 :: SetStartTime (double astarttime) - { - starttime = astarttime; - } - - double Meshing2 :: CalcLocalH (const Point3d & /* p */, double gh) const - { - return gh; - } - - - - // should be class variables !!(?) - static Vec3d ex, ey; - static Point3d globp1; - - void Meshing2 :: DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2) - { - globp1 = p1; - ex = p2 - p1; - ex /= ex.Length(); - ey.X() = -ex.Y(); - ey.Y() = ex.X(); - ey.Z() = 0; - } - - void Meshing2 :: TransformToPlain (const Point3d & locpoint, - const MultiPointGeomInfo & geominf, - Point2d & plainpoint, double h, int & zone) - { - Vec3d p1p (globp1, locpoint); - - // p1p = locpoint - globp1; - p1p /= h; - plainpoint.X() = p1p * ex; - plainpoint.Y() = p1p * ey; - zone = 0; - } - - int Meshing2 :: TransformFromPlain (Point2d & plainpoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h) - { - Vec3d p1p; - gi.trignum = 1; - - p1p = plainpoint.X() * ex + plainpoint.Y() * ey; - p1p *= h; - locpoint = globp1 + p1p; - return 0; - } - - - int Meshing2 :: BelongsToActiveChart (const Point3d & p, - const PointGeomInfo & gi) - { - return 1; - } - - - int Meshing2 :: ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi) - { - gi.trignum = 1; - return 0; - } - - - int Meshing2 :: ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, - PointGeomInfo & pgi) - { - pgi = mpgi.GetPGI(1); - return 0; - } - - - - int Meshing2 :: - IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, - int endpoint, const PointGeomInfo & geominfo) - { - return 1; - } - - void Meshing2 :: - GetChartBoundary (ARRAY<Point2d> & points, - ARRAY<Point3d> & points3d, - ARRAY<INDEX_2> & lines, double h) const - { - points.SetSize (0); - points3d.SetSize (0); - lines.SetSize (0); - } - - double Meshing2 :: Area () const - { - return -1; - } - - - - - - MESHING2_RESULT Meshing2 :: GenerateMesh (Mesh & mesh, double gh, int facenr) - { - ARRAY<int> pindex, lindex; - ARRAY<int> delpoints, dellines; - - ARRAY<PointGeomInfo> upgeominfo; // unique info - ARRAY<MultiPointGeomInfo> mpgeominfo; // multiple info - - ARRAY<Element2d> locelements; - - int i, k, z1, z2, j, oldnp; - SurfaceElementIndex sei; - int baselineindex; - bool found; - int rulenr; - int globind; - Point3d p1, p2; - - const PointGeomInfo * blgeominfo1; - const PointGeomInfo * blgeominfo2; - - bool morerisc; - bool debugflag; - - double h, his, hshould; - - - // test for 3d overlaps - Box3dTree surfeltree (boundingbox.PMin(), - boundingbox.PMax()); - - ARRAY<int> intersecttrias; - ARRAY<Point3d> critpoints; - - // test for doubled edges - //INDEX_2_HASHTABLE<int> doubleedge(300000); - - - testmode = 0; - - StartMesh(); - - ARRAY<Point2d> chartboundpoints; - ARRAY<Point3d> chartboundpoints3d; - ARRAY<INDEX_2> chartboundlines; - - // illegal points: points with more then 50 elements per node - int maxlegalpoint, maxlegalline; - ARRAY<int,PointIndex::BASE> trigsonnode; - ARRAY<int,PointIndex::BASE> illegalpoint; - - trigsonnode.SetSize (mesh.GetNP()); - illegalpoint.SetSize (mesh.GetNP()); - - trigsonnode = 0; - illegalpoint = 0; - - - double totalarea = Area (); - double meshedarea = 0; - - // search tree for surface elements: - for (sei = 0; sei < mesh.GetNSE(); sei++) - { - const Element2d & sel = mesh[sei]; - - if (sel.IsDeleted()) continue; - - if (sel.GetIndex() == facenr) - { - const Point3d & sep1 = mesh[sel.PNum(1)]; - const Point3d & sep2 = mesh[sel.PNum(2)]; - const Point3d & sep3 = mesh[sel.PNum(3)]; - Point3d sepmin(sep1), sepmax(sep2); - sepmin.SetToMin (sep2); - sepmin.SetToMin (sep3); - sepmin.SetToMax (sep2); - sepmin.SetToMax (sep3); - - surfeltree.Insert (sepmin, sepmax, sei); - } - - - double trigarea = Cross (Vec3d (mesh.Point (sel.PNum(1)), - mesh.Point (sel.PNum(2))), - Vec3d (mesh.Point (sel.PNum(1)), - mesh.Point (sel.PNum(3)))).Length() / 2;; - - if (sel.GetNP() == 4) - trigarea += Cross (Vec3d (mesh.Point (sel.PNum(1)), - mesh.Point (sel.PNum(3))), - Vec3d (mesh.Point (sel.PNum(1)), - mesh.Point (sel.PNum(4)))).Length() / 2;; - meshedarea += trigarea; - - } - - - char * savetask = multithread.task; - multithread.task = "Surface meshing"; - - adfront ->SetStartFront (); - - - int plotnexttrial = 999; - // starttime = GetTime(); - while (!adfront ->Empty()) // && !multithread.terminate) - { - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - - // known for STL meshing - if (totalarea > 0) - multithread.percent = 100 * meshedarea / totalarea; - /* - else - multithread.percent = 0; - */ - - locpoints.SetSize(0); - loclines.SetSize(0); - pindex.SetSize(0); - lindex.SetSize(0); - delpoints.SetSize(0); - dellines.SetSize(0); - locelements.SetSize(0); - - - - // plot statistics - if (trials > plotnexttrial) - { - PrintMessage (5, - "faces = ", nfaces, - " trials = ", trials, - " elements = ", mesh.GetNSE(), - " els/sec = ", - (mesh.GetNSE() / (GetTime() - starttime + 0.0001))); - plotnexttrial += 1000; - } - - - // unique-pgi, multi-pgi - upgeominfo.SetSize(0); - mpgeominfo.SetSize(0); - - - nfaces = adfront->GetNFL(); - trials ++; - - - if (trials % 1000 == 0) - { - (*testout) << "\n"; - for (i = 1; i <= canuse.Size(); i++) - { - (*testout) << foundmap.Get(i) << "/" - << canuse.Get(i) << "/" - << ruleused.Get(i) << " map/can/use rule " << rules.Get(i)->Name() << "\n"; - } - (*testout) << "\n"; - } - - - baselineindex = adfront -> SelectBaseLine (p1, p2, blgeominfo1, blgeominfo2, qualclass); - - // cout << "baseline = " << baselineindex << ", p1, p2 = " << p1 << ", " << p2 << endl; - - found = 1; - - - his = Dist (p1, p2); - - Point3d pmid = Center (p1, p2); - hshould = CalcLocalH (pmid, mesh.GetH (pmid)); - if (gh < hshould) - hshould = gh; - - mesh.RestrictLocalH (pmid, hshould); - - h = hshould; - - double hinner = (3 + qualclass) * max2 (his, hshould); - - adfront ->GetLocals (baselineindex, locpoints, mpgeominfo, loclines, - pindex, lindex, 2*hinner); - - - if (qualclass > 200) - { - PrintMessage (3, "give up with qualclass ", qualclass); - PrintMessage (3, "number of frontlines = ", adfront->GetNFL()); - // throw NgException ("Give up 2d meshing"); - break; - } - - /* - if (found && qualclass > 60) - { - found = 0; - } - */ - // morerisc = ((qualclass > 20) && (qualclass % 2 == 1)); - // morerisc = 1; - morerisc = 0; - - - PointIndex gpi1 = adfront -> GetGlobalIndex (pindex.Get(loclines[0].I1())); - PointIndex gpi2 = adfront -> GetGlobalIndex (pindex.Get(loclines[0].I2())); - - - debugflag = - debugparam.haltsegment && - ( (debugparam.haltsegmentp1 == gpi1) && - (debugparam.haltsegmentp2 == gpi2) || - (debugparam.haltsegmentp1 == gpi2) && - (debugparam.haltsegmentp2 == gpi1)) || - debugparam.haltnode && - ( (debugparam.haltsegmentp1 == gpi1) || - (debugparam.haltsegmentp2 == gpi1)); - - - if (debugparam.haltface && debugparam.haltfacenr == facenr) - { - debugflag = 1; - cout << "set debugflag" << endl; - } - - if (debugparam.haltlargequalclass && qualclass > 50) - debugflag = 1; - - - // problem recognition ! - if (found && - (gpi1 < illegalpoint.Size()+PointIndex::BASE) && - (gpi2 < illegalpoint.Size()+PointIndex::BASE) ) - { - if (illegalpoint[gpi1] || illegalpoint[gpi2]) - found = 0; - } - - - Point2d p12d, p22d; - - if (found) - { - oldnp = locpoints.Size(); - oldnl = loclines.Size(); - - if (debugflag) - (*testout) << "define new transformation" << endl; - - DefineTransformation (p1, p2, blgeominfo1, blgeominfo2); - - plainpoints.SetSize (locpoints.Size()); - plainzones.SetSize (locpoints.Size()); - - // (*testout) << endl; - - // (*testout) << "3d->2d transformation" << endl; - - for (i = 1; i <= locpoints.Size(); i++) - { - // (*testout) << "pindex(i) = " << pindex[i-1] << endl; - TransformToPlain (locpoints.Get(i), - mpgeominfo.Get(i), - plainpoints.Elem(i), h, plainzones.Elem(i)); - // (*testout) << mpgeominfo.Get(i).GetPGI(1).u << " " << mpgeominfo.Get(i).GetPGI(1).v << " "; - // (*testout) << plainpoints.Get(i).X() << " " << plainpoints.Get(i).Y() << endl; - } - // (*testout) << endl << endl << endl; - - p12d = plainpoints.Get(1); - p22d = plainpoints.Get(2); - - /* - // last idea on friday - plainzones.Elem(1) = 0; - plainzones.Elem(2) = 0; - */ - - - /* - // old netgen: - for (i = 2; i <= loclines.Size(); i++) // don't remove first line - { - z1 = plainzones.Get(loclines.Get(i).I1()); - z2 = plainzones.Get(loclines.Get(i).I2()); - - if (z1 && z2 && (z1 != z2) || (z1 == -1) || (z2 == -1) ) - { - loclines.DeleteElement(i); - lindex.DeleteElement(i); - oldnl--; - i--; - } - } - - // for (i = 1; i <= plainpoints.Size(); i++) - // if (plainzones.Elem(i) == -1) - // plainpoints.Elem(i) = Point2d (1e4, 1e4); - */ - - - - for (i = 2; i <= loclines.Size(); i++) // don't remove first line - { - // (*testout) << "loclines(i) = " << loclines.Get(i).I1() << " - " << loclines.Get(i).I2() << endl; - z1 = plainzones.Get(loclines.Get(i).I1()); - z2 = plainzones.Get(loclines.Get(i).I2()); - - - // one inner point, one outer - if ( (z1 >= 0) != (z2 >= 0)) - { - int innerp = (z1 >= 0) ? 1 : 2; - if (IsLineVertexOnChart (locpoints.Get(loclines.Get(i).I1()), - locpoints.Get(loclines.Get(i).I2()), - innerp, - adfront->GetLineGeomInfo (lindex.Get(i), innerp))) - // pgeominfo.Get(loclines.Get(i).I(innerp)))) - { - - if (!morerisc) - { - // use one end of line - int pini, pouti; - Vec2d v; - - pini = loclines.Get(i).I(innerp); - pouti = loclines.Get(i).I(3-innerp); - - Point2d pin (plainpoints.Get(pini)); - Point2d pout (plainpoints.Get(pouti)); - v = pout - pin; - double len = v.Length(); - if (len <= 1e-6) - (*testout) << "WARNING(js): inner-outer: short vector" << endl; - else - v /= len; - - /* - // don't elongate line towards base-line !! - if (Vec2d (pin, p12d) * v > 0 && - Vec2d (pin, p22d) * v > 0) - v *= -1; - */ - - Point2d newpout = pin + 1000 * v; - newpout = pout; - - - plainpoints.Append (newpout); - Point3d pout3d = locpoints.Get(pouti); - locpoints.Append (pout3d); - - plainzones.Append (0); - pindex.Append (0); - oldnp++; - loclines.Elem(i).I(3-innerp) = oldnp; - } - else - plainzones.Elem(loclines.Get(i).I(3-innerp)) = 0; - - - // (*testout) << "inner - outer correction" << endl; - } - else - { - // remove line - loclines.DeleteElement(i); - lindex.DeleteElement(i); - oldnl--; - i--; - } - } - - else if (z1 > 0 && z2 > 0 && (z1 != z2) || (z1 < 0) && (z2 < 0) ) - { - loclines.DeleteElement(i); - lindex.DeleteElement(i); - oldnl--; - i--; - } - } - - - - - - legalpoints.SetSize(plainpoints.Size()); - for (i = 1; i <= legalpoints.Size(); i++) - legalpoints.Elem(i) = 1; - - - for (i = 1; i <= plainpoints.Size(); i++) - { - if (plainzones.Elem(i) < 0) - { - plainpoints.Elem(i) = Point2d (1e4, 1e4); - legalpoints.Elem(i) = 0; - } - if (pindex.Elem(i) == 0) - legalpoints.Elem(i) = 0; - - if (plainpoints.Elem(i).Y() < 0) - legalpoints.Elem(i) = 0; - } - /* - for (i = 3; i <= plainpoints.Size(); i++) - if (sqr (plainpoints.Get(i).X()) + sqr (plainpoints.Get(i).Y()) - > sqr (2 + 0.2 * qualclass)) - legalpoints.Elem(i) = 0; - */ - - /* - int clp = 0; - for (i = 1; i <= plainpoints.Size(); i++) - if (legalpoints.Get(i)) - clp++; - (*testout) << "legalpts: " << clp << "/" << plainpoints.Size() << endl; - - // sort legal/illegal lines - int lastleg = 2; - int firstilleg = oldnl; - - while (lastleg < firstilleg) - { - while (legalpoints.Get(loclines.Get(lastleg).I1()) && - legalpoints.Get(loclines.Get(lastleg).I2()) && - lastleg < firstilleg) - lastleg++; - while ( ( !legalpoints.Get(loclines.Get(firstilleg).I1()) || - !legalpoints.Get(loclines.Get(firstilleg).I2())) && - lastleg < firstilleg) - firstilleg--; - - if (lastleg < firstilleg) - { - swap (loclines.Elem(lastleg), loclines.Elem(firstilleg)); - swap (lindex.Elem(lastleg), lindex.Elem(firstilleg)); - } - } - - (*testout) << "leglines " << lastleg << "/" << oldnl << endl; - */ - - - GetChartBoundary (chartboundpoints, - chartboundpoints3d, - chartboundlines, h); - - oldnp = plainpoints.Size(); - - maxlegalpoint = locpoints.Size(); - maxlegalline = loclines.Size(); - - - - if (mparam.checkchartboundary) - { - for (i = 1; i <= chartboundpoints.Size(); i++) - { - plainpoints.Append (chartboundpoints.Get(i)); - locpoints.Append (chartboundpoints3d.Get(i)); - legalpoints.Append (0); - } - - - for (i = 1; i <= chartboundlines.Size(); i++) - { - INDEX_2 line (chartboundlines.Get(i).I1()+oldnp, - chartboundlines.Get(i).I2()+oldnp); - loclines.Append (line); - // (*testout) << "line: " << line.I1() << "-" << line.I2() << endl; - } - } - - oldnl = loclines.Size(); - oldnp = plainpoints.Size(); - } - - - /* - if (qualclass > 100) - { - multithread.drawing = 1; - glrender(1); - cout << "qualclass 100, nfl = " << adfront->GetNFL() << endl; - } - */ - - if (found) - { - rulenr = ApplyRules (plainpoints, legalpoints, maxlegalpoint, - loclines, maxlegalline, locelements, - dellines, qualclass); - // (*testout) << "Rule Nr = " << rulenr << endl; - if (!rulenr) - { - found = 0; - if ( debugflag || debugparam.haltnosuccess ) - PrintWarning ("no rule found"); - } - } - - for (i = 1; i <= locelements.Size() && found; i++) - { - const Element2d & el = locelements.Get(i); - - for (j = 1; j <= el.GetNP(); j++) - if (el.PNum(j) <= oldnp && !pindex.Get(el.PNum(j))) - { - found = 0; - PrintSysError ("meshing2, index missing"); - } - } - - - if (found) - { - locpoints.SetSize (plainpoints.Size()); - upgeominfo.SetSize(locpoints.Size()); - - for (i = oldnp+1; i <= plainpoints.Size(); i++) - { - int err = - TransformFromPlain (plainpoints.Elem(i), locpoints.Elem(i), - upgeominfo.Elem(i), h); - - if (err) - { - found = 0; - - if ( debugflag || debugparam.haltnosuccess ) - PrintSysError ("meshing2, Backtransformation failed"); - - break; - } - } - } - - - // for (i = 1; i <= oldnl; i++) - // adfront -> ResetClass (lindex[i]); - - - /* - double violateminh; - if (qualclass <= 10) - violateminh = 3; - else - violateminh = 3 * qualclass; - - if (uselocalh && found) // && qualclass <= 10) - { - for (i = 1; i <= locelements.Size(); i++) - { - Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); - Point3d pmax = pmin; - for (j = 2; j <= 3; j++) - { - const Point3d & hp = - locpoints.Get(locelements.Get(i).PNum(j)); - pmin.SetToMin (hp); - pmax.SetToMax (hp); - } - double minh = mesh.GetMinH (pmin, pmax); - if (h > violateminh * minh) - { - found = 0; - loclines.SetSize (oldnl); - locpoints.SetSize (oldnp); - } - } - } - */ - - - if (found) - { - double violateminh = 3 + 0.1 * sqr (qualclass); - double minh = 1e8; - double newedgemaxh = 0; - for (i = oldnl+1; i <= loclines.Size(); i++) - { - double eh = Dist (locpoints.Get(loclines.Get(i).I1()), - locpoints.Get(loclines.Get(i).I2())); - if (eh > newedgemaxh) - newedgemaxh = eh; - } - - for (i = 1; i <= locelements.Size(); i++) - { - Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); - Point3d pmax = pmin; - for (j = 2; j <= locelements.Get(i).GetNP(); j++) - { - const Point3d & hp = - locpoints.Get(locelements.Get(i).PNum(j)); - pmin.SetToMin (hp); - pmax.SetToMax (hp); - } - double eh = mesh.GetMinH (pmin, pmax); - if (eh < minh) - minh = eh; - } - - for (i = 1; i <= locelements.Size(); i++) - for (j = 1; j <= locelements.Get(i).GetNP(); j++) - if (Dist2 (locpoints.Get(locelements.Get(i).PNum(j)), pmid) > hinner*hinner) - found = 0; - - // cout << "violate = " << newedgemaxh / minh << endl; - static double maxviolate = 0; - if (newedgemaxh / minh > maxviolate) - { - maxviolate = newedgemaxh / minh; - // cout << "max minhviolate = " << maxviolate << endl; - } - - - if (newedgemaxh > violateminh * minh) - { - found = 0; - loclines.SetSize (oldnl); - locpoints.SetSize (oldnp); - - if ( debugflag || debugparam.haltnosuccess ) - PrintSysError ("meshing2, maxh too large"); - - - } - } - - - - /* - // test good ComputeLineGeoInfo - if (found) - { - // is line on chart ? - for (i = oldnl+1; i <= loclines.Size(); i++) - { - int gisize; - void *geominfo; - - if (ComputeLineGeoInfo (locpoints.Get(loclines.Get(i).I1()), - locpoints.Get(loclines.Get(i).I2()), - gisize, geominfo)) - found = 0; - } - } - */ - - - // changed for OCC meshing - if (found) - { - // take geominfo from dellines - // upgeominfo.SetSize(locpoints.Size()); - - /* - for (i = 1; i <= dellines.Size(); i++) - for (j = 1; j <= 2; j++) - { - upgeominfo.Elem(loclines.Get(dellines.Get(i)).I(j)) = - adfront -> GetLineGeomInfo (lindex.Get(dellines.Get(i)), j); - } - */ - - - for (i = 1; i <= locelements.Size(); i++) - for (j = 1; j <= locelements.Get(i).GetNP(); j++) - { - int pi = locelements.Get(i).PNum(j); - if (pi <= oldnp) - { - - if (ChooseChartPointGeomInfo (mpgeominfo.Get(pi), upgeominfo.Elem(pi))) - { - // cannot select, compute new one - PrintWarning ("calc point geominfo instead of using"); - if (ComputePointGeomInfo (locpoints.Get(pi), upgeominfo.Elem(pi))) - { - found = 0; - PrintSysError ("meshing2d, geominfo failed"); - } - } - } - } - - /* - // use upgeominfo from ProjectFromPlane - for (i = oldnp+1; i <= locpoints.Size(); i++) - { - if (ComputePointGeomInfo (locpoints.Get(i), upgeominfo.Elem(i))) - { - found = 0; - if ( debugflag || debugparam.haltnosuccess ) - PrintSysError ("meshing2d, compute geominfo failed"); - } - } - */ - } - - - if (found && mparam.checkoverlap) - { - // cout << "checkoverlap" << endl; - // test for overlaps - - Point3d hullmin(1e10, 1e10, 1e10); - Point3d hullmax(-1e10, -1e10, -1e10); - - for (i = 1; i <= locelements.Size(); i++) - for (j = 1; j <= locelements.Get(i).GetNP(); j++) - { - const Point3d & p = locpoints.Get(locelements.Get(i).PNum(j)); - hullmin.SetToMin (p); - hullmax.SetToMax (p); - } - hullmin += Vec3d (-his, -his, -his); - hullmax += Vec3d ( his, his, his); - - surfeltree.GetIntersecting (hullmin, hullmax, intersecttrias); - - critpoints.SetSize (0); - for (i = oldnp+1; i <= locpoints.Size(); i++) - critpoints.Append (locpoints.Get(i)); - - for (i = 1; i <= locelements.Size(); i++) - { - const Element2d & tri = locelements.Get(i); - if (tri.GetNP() == 3) - { - const Point3d & tp1 = locpoints.Get(tri.PNum(1)); - const Point3d & tp2 = locpoints.Get(tri.PNum(2)); - const Point3d & tp3 = locpoints.Get(tri.PNum(3)); - - Vec3d tv1 (tp1, tp2); - Vec3d tv2 (tp1, tp3); - - double lam1, lam2; - for (lam1 = 0.2; lam1 <= 0.8; lam1 += 0.2) - for (lam2 = 0.2; lam2 + lam1 <= 0.8; lam2 += 0.2) - { - Point3d hp = tp1 + lam1 * tv1 + lam2 * tv2; - critpoints.Append (hp); - } - } - else if (tri.GetNP() == 4) - { - const Point3d & tp1 = locpoints.Get(tri.PNum(1)); - const Point3d & tp2 = locpoints.Get(tri.PNum(2)); - const Point3d & tp3 = locpoints.Get(tri.PNum(3)); - const Point3d & tp4 = locpoints.Get(tri.PNum(4)); - - double l1, l2; - for (l1 = 0.1; l1 <= 0.9; l1 += 0.1) - for (l2 = 0.1; l2 <= 0.9; l2 += 0.1) - { - Point3d hp; - hp.X() = - (1-l1)*(1-l2) * tp1.X() + - l1*(1-l2) * tp2.X() + - l1*l2 * tp3.X() + - (1-l1)*l2 * tp4.X(); - hp.Y() = - (1-l1)*(1-l2) * tp1.Y() + - l1*(1-l2) * tp2.Y() + - l1*l2 * tp3.Y() + - (1-l1)*l2 * tp4.Y(); - hp.Z() = - (1-l1)*(1-l2) * tp1.Z() + - l1*(1-l2) * tp2.Z() + - l1*l2 * tp3.Z() + - (1-l1)*l2 * tp4.Z(); - - - critpoints.Append (hp); - } - } - } - /* - for (i = oldnl+1; i <= loclines.Size(); i++) - { - Point3d hp = locpoints.Get(loclines.Get(i).I1()); - Vec3d hv(hp, locpoints.Get(loclines.Get(i).I2())); - int ncp = 2; - for (j = 1; j <= ncp; j++) - critpoints.Append ( hp + (double(j)/(ncp+1)) * hv); - } - */ - - - /* - for (i = oldnp+1; i <= locpoints.Size(); i++) - { - const Point3d & p = locpoints.Get(i); - */ - - - for (i = 1; i <= critpoints.Size(); i++) - { - const Point3d & p = critpoints.Get(i); - - - /* - for (j = 1; j <= mesh.GetNSE(); j++) - { - */ - int jj; - for (jj = 1; jj <= intersecttrias.Size(); jj++) - { - j = intersecttrias.Get(jj); - const Element2d & el = mesh.SurfaceElement(j); - - int ntrig = (el.GetNP() == 3) ? 1 : 2; - - int jl; - for (jl = 1; jl <= ntrig; jl++) - { - Point3d tp1, tp2, tp3; - - if (jl == 1) - { - tp1 = mesh.Point(el.PNum(1)); - tp2 = mesh.Point(el.PNum(2)); - tp3 = mesh.Point(el.PNum(3)); - } - else - { - tp1 = mesh.Point(el.PNum(1)); - tp2 = mesh.Point(el.PNum(3)); - tp3 = mesh.Point(el.PNum(4)); - } - - int onchart = 0; - for (k = 1; k <= el.GetNP(); k++) - if (BelongsToActiveChart (mesh.Point(el.PNum(k)), - el.GeomInfoPi(k))) - onchart = 1; - if (!onchart) - continue; - - Vec3d e1(tp1, tp2); - Vec3d e2(tp1, tp3); - Vec3d n = Cross (e1, e2); - n /= n.Length(); - double lam1, lam2, lam3; - lam3 = n * Vec3d (tp1, p); - LocalCoordinates (e1, e2, Vec3d (tp1, p), lam1, lam2); - - if (fabs (lam3) < 0.1 * hshould && - lam1 > 0 && lam2 > 0 && (lam1 + lam2) < 1) - { -#ifdef DEVELOP - cout << "overlap" << endl; - (*testout) << "overlap:" << endl - << "tri = " << tp1 << "-" << tp2 << "-" << tp3 << endl - << "point = " << p << endl - << "lam1, 2 = " << lam1 << ", " << lam2 << endl - << "lam3 = " << lam3 << endl; - - // cout << "overlap !!!" << endl; -#endif - for (int k = 1; k <= 5; k++) - adfront -> IncrementClass (lindex.Get(1)); - - found = 0; - - if ( debugflag || debugparam.haltnosuccess ) - PrintWarning ("overlapping"); - - - if (debugparam.haltoverlap) - { - debugflag = 1; - } - - /* - multithread.drawing = 1; - glrender(1); - */ - } - } - } - } - } - - - if (found) - { - // check, whether new front line already exists - - for (i = oldnl+1; i <= loclines.Size(); i++) - { - int nlgpi1 = loclines.Get(i).I1(); - int nlgpi2 = loclines.Get(i).I2(); - if (nlgpi1 <= pindex.Size() && nlgpi2 <= pindex.Size()) - { - nlgpi1 = adfront->GetGlobalIndex (pindex.Get(nlgpi1)); - nlgpi2 = adfront->GetGlobalIndex (pindex.Get(nlgpi2)); - - int exval = adfront->ExistsLine (nlgpi1, nlgpi2); - if (exval) - { - cout << "ERROR: new line exits, val = " << exval << endl; - (*testout) << "ERROR: new line exits, val = " << exval << endl; - found = 0; - - - if (debugparam.haltexistingline) - debugflag = 1; - - } - } - } - - } - - - /* - if (found) - { - // check, whether new triangles insert edges twice - for (i = 1; i <= locelements.Size(); i++) - for (j = 1; j <= 3; j++) - { - int tpi1 = locelements.Get(i).PNumMod (j); - int tpi2 = locelements.Get(i).PNumMod (j+1); - if (tpi1 <= pindex.Size() && tpi2 <= pindex.Size()) - { - tpi1 = adfront->GetGlobalIndex (pindex.Get(tpi1)); - tpi2 = adfront->GetGlobalIndex (pindex.Get(tpi2)); - - if (doubleedge.Used (INDEX_2(tpi1, tpi2))) - { - if (debugparam.haltexistingline) - debugflag = 1; - cerr << "ERROR Insert edge " - << tpi1 << " - " << tpi2 << " twice !!!" << endl; - found = 0; - } - doubleedge.Set (INDEX_2(tpi1, tpi2), 1); - } - } - } - */ - - - if (found) - { - // everything is ok, perform mesh update - - ruleused.Elem(rulenr)++; - - - pindex.SetSize(locpoints.Size()); - - for (i = oldnp+1; i <= locpoints.Size(); i++) - { - globind = mesh.AddPoint (locpoints.Get(i)); - pindex.Elem(i) = adfront -> AddPoint (locpoints.Get(i), globind); - } - - for (i = oldnl+1; i <= loclines.Size(); i++) - { - /* - for (j = 1; j <= locpoints.Size(); j++) - { - (*testout) << j << ": " << locpoints.Get(j) << endl; - } - */ - - /* - ComputeLineGeoInfo (locpoints.Get(loclines.Get(i).I1()), - locpoints.Get(loclines.Get(i).I2()), - gisize, geominfo); - */ - - if (pindex.Get(loclines.Get(i).I1()) == 0 || - pindex.Get(loclines.Get(i).I2()) == 0) - { - (*testout) << "pindex is 0" << endl; - } - - if (!upgeominfo.Get(loclines.Get(i).I1()).trignum || - !upgeominfo.Get(loclines.Get(i).I2()).trignum) - { - cout << "new el: illegal geominfo" << endl; - } - - adfront -> AddLine (pindex.Get(loclines.Get(i).I1()), - pindex.Get(loclines.Get(i).I2()), - upgeominfo.Get(loclines.Get(i).I1()), - upgeominfo.Get(loclines.Get(i).I2())); - } - for (i = 1; i <= locelements.Size(); i++) - { - Element2d mtri(locelements.Get(i).GetNP()); - mtri = locelements.Get(i); - mtri.SetIndex (facenr); - - - // compute triangle geominfo: - // (*testout) << "triggeominfo: "; - for (j = 1; j <= locelements.Get(i).GetNP(); j++) - { - mtri.GeomInfoPi(j) = upgeominfo.Get(locelements.Get(i).PNum(j)); - // (*testout) << mtri.GeomInfoPi(j).trignum << " "; - } - // (*testout) << endl; - - for (j = 1; j <= locelements.Get(i).GetNP(); j++) - { - mtri.PNum(j) = - locelements.Elem(i).PNum(j) = - adfront -> GetGlobalIndex (pindex.Get(locelements.Get(i).PNum(j))); - } - - - - - mesh.AddSurfaceElement (mtri); - cntelem++; - // cout << "elements: " << cntelem << endl; - - - - - const Point3d & sep1 = mesh.Point (mtri.PNum(1)); - const Point3d & sep2 = mesh.Point (mtri.PNum(2)); - const Point3d & sep3 = mesh.Point (mtri.PNum(3)); - - Point3d sepmin(sep1), sepmax(sep1); - for (j = 2; j <= mtri.GetNP(); j++) - { - sepmin.SetToMin (mesh.Point (mtri.PNum(j))); - sepmax.SetToMax (mesh.Point (mtri.PNum(j))); - } - - surfeltree.Insert (sepmin, sepmax, mesh.GetNSE()); - - - double trigarea = Cross (Vec3d (sep1, sep2), - Vec3d (sep1, sep3)).Length() / 2; - - if (mtri.GetNP() == 4) - { - const Point3d & sep4 = mesh.Point (mtri.PNum(4)); - trigarea += Cross (Vec3d (sep1, sep3), - Vec3d (sep1, sep4)).Length() / 2; - } - - meshedarea += trigarea; - - - - - for (j = 1; j <= locelements.Get(i).GetNP(); j++) - { - int gpi = locelements.Get(i).PNum(j); - - int oldts = trigsonnode.Size(); - if (gpi >= oldts+PointIndex::BASE) - { - trigsonnode.SetSize (gpi+1-PointIndex::BASE); - illegalpoint.SetSize (gpi+1-PointIndex::BASE); - for (k = oldts+PointIndex::BASE; - k <= gpi; k++) - { - trigsonnode[k] = 0; - illegalpoint[k] = 0; - } - } - - trigsonnode[gpi]++; - - if (trigsonnode[gpi] > 20) - { - illegalpoint[gpi] = 1; - // cout << "illegal point: " << gpi << endl; - (*testout) << "illegal point: " << gpi << endl; - } - - static int mtonnode = 0; - if (trigsonnode[gpi] > mtonnode) - mtonnode = trigsonnode[gpi]; - } - // cout << "els = " << cntelem << " trials = " << trials << endl; - // if (trials > 100) return; - } - - for (i = 1; i <= dellines.Size(); i++) - adfront -> DeleteLine (lindex.Get(dellines.Get(i))); - - // rname = rules.Get(rulenr)->Name(); -#ifdef MYGRAPH - if (silentflag<3) - { - plotsurf.DrawPnL(locpoints, loclines); - plotsurf.Plot(testmode, testmode); - } -#endif - - if (morerisc) - { - cout << "generated due to morerisc" << endl; - // multithread.drawing = 1; - // glrender(1); - } - - - - - if ( debugparam.haltsuccess || debugflag ) - { - cout << "success of rule" << rules.Get(rulenr)->Name() << endl; - multithread.drawing = 1; - multithread.testmode = 1; - multithread.pause = 1; - - - /* - extern STLGeometry * stlgeometry; - stlgeometry->ClearMarkedSegs(); - for (i = 1; i <= loclines.Size(); i++) - { - stlgeometry->AddMarkedSeg(locpoints.Get(loclines.Get(i).I1()), - locpoints.Get(loclines.Get(i).I2())); - } - */ - - (*testout) << "success of rule" << rules.Get(rulenr)->Name() << endl; - (*testout) << "trials = " << trials << endl; - - (*testout) << "old number of lines = " << oldnl << endl; - for (i = 1; i <= loclines.Size(); i++) - { - (*testout) << "line "; - for (j = 1; j <= 2; j++) - { - int hi = 0; - if (loclines.Get(i).I(j) >= 1 && - loclines.Get(i).I(j) <= pindex.Size()) - hi = adfront->GetGlobalIndex (pindex.Get(loclines.Get(i).I(j))); - - (*testout) << hi << " "; - } - (*testout) << " : " - << plainpoints.Get(loclines.Get(i).I1()) << " - " - << plainpoints.Get(loclines.Get(i).I2()) << " 3d: " - << locpoints.Get(loclines.Get(i).I1()) << " - " - << locpoints.Get(loclines.Get(i).I2()) - << endl; - } - - - - glrender(1); - } - } - else - { - adfront -> IncrementClass (lindex.Get(1)); - - if ( debugparam.haltnosuccess || debugflag ) - { - cout << "Problem with seg " << gpi1 << " - " << gpi2 - << ", class = " << qualclass << endl; - - (*testout) << "Problem with seg " << gpi1 << " - " << gpi2 - << ", class = " << qualclass << endl; - - multithread.drawing = 1; - multithread.testmode = 1; - multithread.pause = 1; - - - /* - extern STLGeometry * stlgeometry; - stlgeometry->ClearMarkedSegs(); - for (i = 1; i <= loclines.Size(); i++) - { - stlgeometry->AddMarkedSeg(locpoints.Get(loclines.Get(i).I1()), - locpoints.Get(loclines.Get(i).I2())); - } - */ - - for (i = 1; i <= loclines.Size(); i++) - { - (*testout) << "line "; - for (j = 1; j <= 2; j++) - { - int hi = 0; - if (loclines.Get(i).I(j) >= 1 && - loclines.Get(i).I(j) <= pindex.Size()) - hi = adfront->GetGlobalIndex (pindex.Get(loclines.Get(i).I(j))); - - (*testout) << hi << " "; - } - (*testout) << " : " - << plainpoints.Get(loclines.Get(i).I1()) << " - " - << plainpoints.Get(loclines.Get(i).I2()) << " 3d: " - << locpoints.Get(loclines.Get(i).I1()) << " - " - << locpoints.Get(loclines.Get(i).I2()) - << endl; - } - - - /* - cout << "p1gi = " << blgeominfo[0].trignum - << ", p2gi = " << blgeominfo[1].trignum << endl; - */ - - glrender(1); - } - - -#ifdef MYGRAPH - if (silentflag<3) - { - if (testmode || trials%2 == 0) - { - plotsurf.DrawPnL(locpoints, loclines); - plotsurf.Plot(testmode, testmode); - } - } -#endif - } - - } - - PrintMessage (3, "Surface meshing done"); - - adfront->PrintOpenSegments (*testout); - - multithread.task = savetask; - - - // cout << "surfeltree.depth = " << surfeltree.Tree().Depth() << endl; - EndMesh (); - - if (!adfront->Empty()) - return MESHING2_GIVEUP; - - return MESHING2_OK; - } - - - - - - - - - -} - - - - - - - -#ifdef OPENGL - -/* *********************** Draw Surface Meshing **************** */ - - -#include <visual.hpp> -#include <stlgeom.hpp> - -namespace netgen -{ - - extern STLGeometry * stlgeometry; - extern Mesh * mesh; - VisualSceneSurfaceMeshing vssurfacemeshing; - - - - void glrender (int wait) - { - // cout << "plot adfront" << endl; - - if (multithread.drawing) - { - // vssurfacemeshing.Render(); - Render (); - - if (wait || multithread.testmode) - { - multithread.pause = 1; - } - while (multithread.pause); - } - } - - - - VisualSceneSurfaceMeshing :: VisualSceneSurfaceMeshing () - : VisualScene() - { - ; - } - - VisualSceneSurfaceMeshing :: ~VisualSceneSurfaceMeshing () - { - ; - } - - void VisualSceneSurfaceMeshing :: DrawScene () - { - int i, j, k; - - if (loclines.Size() != changeval) - { - center = Point<3>(0,0,-5); - rad = 0.1; - - CalcTransformationMatrices(); - changeval = loclines.Size(); - } - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SetLight(); - - // glEnable (GL_COLOR_MATERIAL); - - // glDisable (GL_SHADING); - // glColor3f (0.0f, 1.0f, 1.0f); - // glLineWidth (1.0f); - // glShadeModel (GL_SMOOTH); - - // glCallList (linelists.Get(1)); - - // SetLight(); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - glShadeModel (GL_SMOOTH); - glDisable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // glEnable (GL_LIGHTING); - - double shine = vispar.shininess; - double transp = vispar.transp; - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); - glLogicOp (GL_COPY); - - - - /* - - float mat_col[] = { 0.2, 0.2, 0.8, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - float mat_colbl[] = { 0.8, 0.2, 0.2, 1 }; - float mat_cololdl[] = { 0.2, 0.8, 0.2, 1 }; - float mat_colnewl[] = { 0.8, 0.8, 0.2, 1 }; - - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - glPolygonOffset (1, -1); - glLineWidth (3); - - for (i = 1; i <= loclines.Size(); i++) - { - if (i == 1) - { - glEnable (GL_POLYGON_OFFSET_FILL); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbl); - } - else if (i <= oldnl) - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_cololdl); - else - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colnewl); - - int pi1 = loclines.Get(i).I1(); - int pi2 = loclines.Get(i).I2(); - - if (pi1 >= 1 && pi2 >= 1) - { - Point3d p1 = locpoints.Get(pi1); - Point3d p2 = locpoints.Get(pi2); - - glBegin (GL_LINES); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glEnd(); - } - - glDisable (GL_POLYGON_OFFSET_FILL); - } - - - glLineWidth (1); - - - glPointSize (5); - float mat_colp[] = { 1, 0, 0, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); - glBegin (GL_POINTS); - for (i = 1; i <= locpoints.Size(); i++) - { - Point3d p = locpoints.Get(i); - glVertex3f (p.X(), p.Y(), p.Z()); - } - glEnd(); - - - glPopMatrix(); - */ - - float mat_colp[] = { 1, 0, 0, 1 }; - - float mat_col2d1[] = { 1, 0.5, 0.5, 1 }; - float mat_col2d[] = { 1, 1, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); - - double scalex = 0.1, scaley = 0.1; - - glBegin (GL_LINES); - for (i = 1; i <= loclines.Size(); i++) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); - if (i == 1) - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d1); - - int pi1 = loclines.Get(i).I1(); - int pi2 = loclines.Get(i).I2(); - - if (pi1 >= 1 && pi2 >= 1) - { - Point2d p1 = plainpoints.Get(pi1); - Point2d p2 = plainpoints.Get(pi2); - - glBegin (GL_LINES); - glVertex3f (scalex * p1.X(), scaley * p1.Y(), -5); - glVertex3f (scalex * p2.X(), scaley * p2.Y(), -5); - glEnd(); - } - } - glEnd (); - - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); - glBegin (GL_POINTS); - for (i = 1; i <= plainpoints.Size(); i++) - { - Point2d p = plainpoints.Get(i); - glVertex3f (scalex * p.X(), scaley * p.Y(), -5); - } - glEnd(); - - - - - - - glDisable (GL_POLYGON_OFFSET_FILL); - - glPopMatrix(); - DrawCoordinateCross (); - DrawNetgenLogo (); - glFinish(); - - /* - glDisable (GL_POLYGON_OFFSET_FILL); - - // cout << "draw surfacemeshing" << endl; - // - // if (changeval != stlgeometry->GetNT()) - // BuildScene(); - // changeval = stlgeometry->GetNT(); - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - SetLight(); - - glPushMatrix(); - glLoadMatrixf (transmat); - glMultMatrixf (rotmat); - - glShadeModel (GL_SMOOTH); - glDisable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - float mat_spec_col[] = { 1, 1, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); - - double shine = vispar.shininess; - double transp = vispar.transp; - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); - glLogicOp (GL_COPY); - - - float mat_col[] = { 0.2, 0.2, 0.8, transp }; - float mat_colrt[] = { 0.2, 0.8, 0.8, transp }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glColor3f (1.0f, 1.0f, 1.0f); - - glEnable (GL_NORMALIZE); - - // glBegin (GL_TRIANGLES); - // for (j = 1; j <= stlgeometry -> GetNT(); j++) - // { - // glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - // if (j == geomtrig) - // glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colrt); - - - // const STLReadTriangle & tria = stlgeometry -> GetReadTriangle(j); - // glNormal3f (tria.normal.X(), - // tria.normal.Y(), - // tria.normal.Z()); - - // for (k = 0; k < 3; k++) - // { - // glVertex3f (tria.pts[k].X(), - // tria.pts[k].Y(), - // tria.pts[k].Z()); - // } - // } - // glEnd (); - - - - glDisable (GL_POLYGON_OFFSET_FILL); - - float mat_colbl[] = { 0.8, 0.2, 0.2, 1 }; - float mat_cololdl[] = { 0.2, 0.8, 0.2, 1 }; - float mat_colnewl[] = { 0.8, 0.8, 0.2, 1 }; - - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - glPolygonOffset (1, -1); - glLineWidth (3); - - for (i = 1; i <= loclines.Size(); i++) - { - if (i == 1) - { - glEnable (GL_POLYGON_OFFSET_FILL); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbl); - } - else if (i <= oldnl) - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_cololdl); - else - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colnewl); - - int pi1 = loclines.Get(i).I1(); - int pi2 = loclines.Get(i).I2(); - - if (pi1 >= 1 && pi2 >= 1) - { - Point3d p1 = locpoints.Get(pi1); - Point3d p2 = locpoints.Get(pi2); - - glBegin (GL_LINES); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glEnd(); - } - - glDisable (GL_POLYGON_OFFSET_FILL); - } - - - glLineWidth (1); - - - glPointSize (5); - float mat_colp[] = { 1, 0, 0, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); - glBegin (GL_POINTS); - for (i = 1; i <= locpoints.Size(); i++) - { - Point3d p = locpoints.Get(i); - glVertex3f (p.X(), p.Y(), p.Z()); - } - glEnd(); - - - glPopMatrix(); - - - float mat_col2d1[] = { 1, 0.5, 0.5, 1 }; - float mat_col2d[] = { 1, 1, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); - - double scalex = 0.1, scaley = 0.1; - - glBegin (GL_LINES); - for (i = 1; i <= loclines.Size(); i++) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); - if (i == 1) - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d1); - - int pi1 = loclines.Get(i).I1(); - int pi2 = loclines.Get(i).I2(); - - if (pi1 >= 1 && pi2 >= 1) - { - Point2d p1 = plainpoints.Get(pi1); - Point2d p2 = plainpoints.Get(pi2); - - glBegin (GL_LINES); - glVertex3f (scalex * p1.X(), scaley * p1.Y(), -5); - glVertex3f (scalex * p2.X(), scaley * p2.Y(), -5); - glEnd(); - } - } - glEnd (); - - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); - glBegin (GL_POINTS); - for (i = 1; i <= plainpoints.Size(); i++) - { - Point2d p = plainpoints.Get(i); - glVertex3f (scalex * p.X(), scaley * p.Y(), -5); - } - glEnd(); - - glFinish(); -*/ - } - - - void VisualSceneSurfaceMeshing :: BuildScene (int zoomall) - { - int i, j, k; - /* - center = stlgeometry -> GetBoundingBox().Center(); - rad = stlgeometry -> GetBoundingBox().Diam() / 2; - - CalcTransformationMatrices(); - */ - } - -} - - -#else -namespace netgen -{ - void glrender (int wait) - { ; } -} -#endif diff --git a/Netgen/libsrc/meshing/meshing2.hpp b/Netgen/libsrc/meshing/meshing2.hpp deleted file mode 100644 index a68a095d5e..0000000000 --- a/Netgen/libsrc/meshing/meshing2.hpp +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef FILE_MESHING2 -#define FILE_MESHING2 - -/**************************************************************************/ -/* File: meshing2.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - - - -enum MESHING2_RESULT -{ - MESHING2_OK = 0, - MESHING2_GIVEUP = 1 -}; - - -/* - -The basis class for 2D mesh generation. -Has the method GenerateMesh - -For surface mesh generation, or non-Euklidean meshing, -derive from Meshing2, and replace transformation. - -*/ - -class Meshing2 -{ - /// the current advancing front - AdFront2 * adfront; - /// rules for mesh generation - ARRAY<netrule*> rules; - /// statistics - ARRAY<int> ruleused, canuse, foundmap; - /// - Box3d boundingbox; - /// - double starttime; -public: - /// - Meshing2 (const Box3d & aboundingbox); - - /// - virtual ~Meshing2 (); - - /// Load rules, either from file, or compiled rules - void LoadRules (const char * filename); - - /// - MESHING2_RESULT GenerateMesh (Mesh & mesh, double gh, int facenr); - - /// - void AddPoint (const Point3d & p, PointIndex globind, MultiPointGeomInfo * mgi = NULL); - - /// - void AddBoundaryElement (INDEX i1, INDEX i2, - const PointGeomInfo & gi1, const PointGeomInfo & gi2); - - /// - void SetStartTime (double astarttime); - -protected: - /// - virtual void StartMesh (); - /// - virtual void EndMesh (); - /// - virtual double CalcLocalH (const Point3d & p, double gh) const; - - /// - virtual void DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2); - /// - virtual void TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & geominfo, - Point2d & plainpoint, double h, int & zone); - /// return 0 .. ok - /// return >0 .. cannot transform point to true surface - virtual int TransformFromPlain (Point2d & plainpoint, - Point3d & locpoint, - PointGeomInfo & geominfo, - double h); - - /// projects to surface - /// return 0 .. ok - virtual int BelongsToActiveChart (const Point3d & p, - const PointGeomInfo & gi); - - /// computes geoinfo data for line with respect to - /// selected chart - virtual int ComputePointGeomInfo (const Point3d & p, - PointGeomInfo & gi); - - /// Tries to select unique geominfo on active chart - /// return 0: success - /// return 1: failed - virtual int ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, - PointGeomInfo & pgi); - - - - /* - tests, whether endpoint (= 1 or 2) of line segment p1-p2 - is inside of the selected chart. The endpoint must be on the - chart - */ - virtual int IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, - int endpoint, const PointGeomInfo & geominfo); - - /* - get (projected) boundary of current chart - */ - virtual void GetChartBoundary (ARRAY<Point2d> & points, - ARRAY<Point3d> & points3d, - ARRAY<INDEX_2> & lines, double p) const; - - virtual double Area () const; - - -/** Applies 2D rules. - Tests all 2D rules */ - int ApplyRules (ARRAY<Point2d> & lpoints, - ARRAY<int> & legalpoints, - int maxlegalpoint, - ARRAY<INDEX_2> & llines, - int maxlegelline, - ARRAY<Element2d> & elements, ARRAY<INDEX> & dellines, - int tolerance); - - -}; - - - - - - - - -#endif - - - - - - - diff --git a/Netgen/libsrc/meshing/meshing3.cpp b/Netgen/libsrc/meshing/meshing3.cpp deleted file mode 100644 index c349b85e79..0000000000 --- a/Netgen/libsrc/meshing/meshing3.cpp +++ /dev/null @@ -1,1260 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - -double minother; -double minwithoutother; - - - - - -MeshingStat3d :: MeshingStat3d () -{ - cntsucc = cnttrials = cntelem = qualclass = 0; - vol0 = h = 1; - problemindex = 1; -} - - -Meshing3 :: Meshing3 (const string & rulefilename) -{ - tolfak = 1; - - LoadRules (rulefilename.c_str(), NULL); - adfront = new AdFront3; - - problems.SetSize (rules.Size()); - foundmap.SetSize (rules.Size()); - canuse.SetSize (rules.Size()); - ruleused.SetSize (rules.Size()); - - for (int i = 1; i <= rules.Size(); i++) - { - problems.Elem(i) = new char[255]; - foundmap.Elem(i) = 0; - canuse.Elem(i) = 0; - ruleused.Elem(i) = 0; - } -} - - -Meshing3 :: Meshing3 (const char ** rulep) -{ - tolfak = 1; - - LoadRules (NULL, rulep); - adfront = new AdFront3; - - problems.SetSize (rules.Size()); - foundmap.SetSize (rules.Size()); - canuse.SetSize (rules.Size()); - ruleused.SetSize (rules.Size()); - - for (int i = 0; i < rules.Size(); i++) - { - problems[i] = new char[255]; - foundmap[i] = 0; - canuse[i] = 0; - ruleused[i] = 0; - } -} - -Meshing3 :: ~Meshing3 () -{ - delete adfront; - for (int i = 0; i < rules.Size(); i++) - { - delete [] problems[i]; - delete rules[i]; - } -} - - - -static double CalcLocH (const ARRAY<Point3d> & locpoints, - const ARRAY<Element2d> & locfaces, - double h) -{ - return h; - - // was war das ???? - - int i, j; - double hi, h1, d, dn, sum, weight, wi; - Point3d p0, pc; - Vec3d n, v1, v2; - - p0.X() = p0.Y() = p0.Z() = 0; - for (j = 1; j <= 3; j++) - { - p0.X() += locpoints.Get(locfaces.Get(1).PNum(j)).X(); - p0.Y() += locpoints.Get(locfaces.Get(1).PNum(j)).Y(); - p0.Z() += locpoints.Get(locfaces.Get(1).PNum(j)).Z(); - } - p0.X() /= 3; p0.Y() /= 3; p0.Z() /= 3; - - v1 = locpoints.Get(locfaces.Get(1).PNum(2)) - - locpoints.Get(locfaces.Get(1).PNum(1)); - v2 = locpoints.Get(locfaces.Get(1).PNum(3)) - - locpoints.Get(locfaces.Get(1).PNum(1)); - - h1 = v1.Length(); - n = Cross (v2, v1); - n /= n.Length(); - - sum = 0; - weight = 0; - - for (i = 1; i <= locfaces.Size(); i++) - { - pc.X() = pc.Y() = pc.Z() = 0; - for (j = 1; j <= 3; j++) - { - pc.X() += locpoints.Get(locfaces.Get(i).PNum(j)).X(); - pc.Y() += locpoints.Get(locfaces.Get(i).PNum(j)).Y(); - pc.Z() += locpoints.Get(locfaces.Get(i).PNum(j)).Z(); - } - pc.X() /= 3; pc.Y() /= 3; pc.Z() /= 3; - - d = Dist (p0, pc); - dn = n * (pc - p0); - hi = Dist (locpoints.Get(locfaces.Get(i).PNum(1)), - locpoints.Get(locfaces.Get(i).PNum(2))); - - if (dn > -0.2 * h1) - { - wi = 1 / (h1 + d); - wi *= wi; - } - else - wi = 0; - - sum += hi * wi; - weight += wi; - } - - return sum/weight; -} - - -PointIndex Meshing3 :: AddPoint (const Point3d & p, PointIndex globind) -{ - return adfront -> AddPoint (p, globind); -} - -void Meshing3 :: AddBoundaryElement (const Element2d & elem) -{ - adfront -> AddFace(elem); -} - -int Meshing3 :: AddConnectedPair (const INDEX_2 & apair) -{ - return adfront -> AddConnectedPair (apair); -} - -MESHING3_RESULT Meshing3 :: -GenerateMesh (Mesh & mesh, const MeshingParameters & mp) -{ - ARRAY<Point3d> locpoints; // local points - ARRAY<Element2d> locfaces; // local faces - ARRAY<PointIndex> pindex; // mapping from local to front point numbering - ARRAY<int> allowpoint; // point is allowd ? - ARRAY<INDEX> findex; // mapping from local to front face numbering - INDEX_2_HASHTABLE<int> connectedpairs(100); // connecgted pairs for prism meshing - - ARRAY<Point3d> plainpoints; // points in reference coordinates - ARRAY<int> delpoints, delfaces; // points and lines to be deleted - ARRAY<Element> locelements; // new generated elements - - int i, j, oldnp, oldnf; - int found; - referencetransform trans; - int rotind; - INDEX globind; - Point3d inp; - float err; - - INDEX locfacesplit; //index for faces in outer area - - int loktestmode = 0; - - int uselocalh = mparam.uselocalh; - - int giveuptol = mp.giveuptol; // - MeshingStat3d stat; // statistics - int plotstat_oldne = -1; - - - // for star-shaped domain meshing - ARRAY<MeshPoint> grouppoints; - ARRAY<Element2d> groupfaces; - ARRAY<PointIndex> grouppindex; - ARRAY<INDEX> groupfindex; - - - float minerr; - int hasfound; - double tetvol; - int giveup = 0; - - - ARRAY<Point3d> tempnewpoints; - ARRAY<Element2d> tempnewfaces; - ARRAY<int> tempdelfaces; - ARRAY<Element> templocelements; - - - stat.h = mp.maxh; - - adfront->SetStartFront (mp.baseelnp); - - - found = 0; - stat.vol0 = adfront -> Volume(); - tetvol = 0; - - stat.qualclass = 1; - - while (1) - { - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - if (giveup) - break; - - // break if advancing front is empty - if (!mp.baseelnp && adfront->Empty()) - break; - - // break, if advancing front has no elements with - // mp.baseelnp nodes - if (mp.baseelnp && adfront->Empty (mp.baseelnp)) - break; - - - locpoints.SetSize(0); - locfaces.SetSize(0); - locelements.SetSize(0); - pindex.SetSize(0); - findex.SetSize(0); - - INDEX_2_HASHTABLE<int> connectedpairs(100); // connected pairs for prism meshing - - // select base-element (will be locface[1]) - // and get local environment of radius (safety * h) - - - int baseelem = adfront -> SelectBaseElement (); - if (mp.baseelnp && adfront->GetFace (baseelem).GetNP() != mp.baseelnp) - { - adfront->IncrementClass (baseelem); - continue; - } - - const Element2d & bel = adfront->GetFace (baseelem); - const Point3d & p1 = adfront->GetPoint (bel.PNum(1)); - const Point3d & p2 = adfront->GetPoint (bel.PNum(2)); - const Point3d & p3 = adfront->GetPoint (bel.PNum(3)); - - (*testout) << endl << "base = " << bel << endl; - - - Point3d pmid = Center (p1, p2, p3); - - double his = (Dist (p1, p2) + Dist(p1, p3) + Dist(p2, p3)) / 3; - double hshould; - - hshould = mesh.GetH (pmid); - - if (adfront->GetFace (baseelem).GetNP() == 4) - hshould = max2 (his, hshould); - - double hmax = (his > hshould) ? his : hshould; - - // qualclass should come from baseelem !!!!! - double hinner = hmax * (1 + stat.qualclass); - double houter = hmax * (1 + 2 * stat.qualclass); - - stat.qualclass = - adfront -> GetLocals (baseelem, locpoints, locfaces, - pindex, findex, connectedpairs, - houter, hinner, - locfacesplit); - - - int pi1 = pindex.Get(locfaces[0].PNum(1)); - int pi2 = pindex.Get(locfaces[0].PNum(2)); - int pi3 = pindex.Get(locfaces[0].PNum(3)); - - /* - (*testout) << "baseel = " << baseelem << ", ind = " << findex.Get(1) << endl; - (*testout) << "pi = " << pi1 << ", " << pi2 << ", " << pi3 << endl; - */ - - loktestmode = 0; - // testmode = loktestmode; - // loktestmode = testmode = (adfront->GetFace (baseelem).GetNP() == 4) && (rules.Size() == 5); - - if (testmode) - { - (*testout) << "baseelem = " << baseelem << " qualclass = " << stat.qualclass << endl; - (*testout) << "locpoints = " << endl << locpoints << endl; - (*testout) << "connected = " << endl << connectedpairs << endl; - } - - - - // loch = CalcLocH (locpoints, locfaces, h); - - stat.nff = adfront->GetNF(); - stat.vol = adfront->Volume(); - if (stat.vol < 0) break; - - oldnp = locpoints.Size(); - oldnf = locfaces.Size(); - - - allowpoint.SetSize(locpoints.Size()); - if (uselocalh && stat.qualclass <= 3) - for (i = 1; i <= allowpoint.Size(); i++) - { - allowpoint.Elem(i) = - mesh.GetH (locpoints.Get(i)) > 0.4 * hshould / mp.sloppy; - } - else - for (i = 1; i <= allowpoint.Size(); i++) - allowpoint.Elem(i) = 1; - - - - - - if (stat.qualclass >= mp.starshapeclass) - { - // star-shaped domain removing - - grouppoints.SetSize (0); - groupfaces.SetSize (0); - grouppindex.SetSize (0); - groupfindex.SetSize (0); - - adfront -> GetGroup (findex.Get(1), grouppoints, groupfaces, - grouppindex, groupfindex); - - int onlytri = 1; - for (i = 1; i <= groupfaces.Size(); i++) - if (groupfaces.Get(i).GetNP() != 3) - onlytri = 0; - - if (onlytri && groupfaces.Size() <= 20 && - FindInnerPoint (grouppoints, groupfaces, inp)) - { - (*testout) << "inner point found" << endl; - - for (i = 1; i <= groupfaces.Size(); i++) - adfront -> DeleteFace (groupfindex.Get(i)); - - for (i = 1; i <= groupfaces.Size(); i++) - for (j = 1; j <= locfaces.Size(); j++) - if (findex.Get(j) == groupfindex.Get(i)) - delfaces.Append (j); - - - delfaces.SetSize (0); - - INDEX npi; - Element newel; - - npi = mesh.AddPoint (inp); - newel.SetNP(4); - newel.PNum(4) = npi; - - - for (i = 1; i <= groupfaces.Size(); i++) - { - for (j = 1; j <= 3; j++) - { - newel.PNum(j) = - adfront->GetGlobalIndex - (grouppindex.Get(groupfaces.Get(i).PNum(j))); - } - mesh.AddVolumeElement (newel); - } - continue; - } - } - - - - found = 0; - hasfound = 0; - minerr = 1e6; - - - // int optother = 0; - - /* - for (i = 1; i <= locfaces.Size(); i++) - { - (*testout) << "Face " << i << ": "; - for (j = 1; j <= locfaces.Get(i).GetNP(); j++) - (*testout) << pindex.Get(locfaces.Get(i).PNum(j)) << " "; - (*testout) << endl; - } - for (i = 1; i <= locpoints.Size(); i++) - { - (*testout) << "p" << i - << ", gi = " << pindex.Get(i) - << " = " << locpoints.Get(i) << endl; - } - */ - - minother = 1e10; - minwithoutother = 1e10; - - for (rotind = 1; rotind <= locfaces.Get(1).GetNP(); rotind++) - { - // set transformatino to reference coordinates - - if (locfaces.Get(1).GetNP() == 3) - { - trans.Set (locpoints.Get(locfaces.Get(1).PNumMod(1+rotind)), - locpoints.Get(locfaces.Get(1).PNumMod(2+rotind)), - locpoints.Get(locfaces.Get(1).PNumMod(3+rotind)), hshould); - } - else - { - trans.Set (locpoints.Get(locfaces.Get(1).PNumMod(1+rotind)), - locpoints.Get(locfaces.Get(1).PNumMod(2+rotind)), - locpoints.Get(locfaces.Get(1).PNumMod(4+rotind)), hshould); - } - - trans.ToPlain (locpoints, plainpoints); - - - for (i = 1; i <= allowpoint.Size(); i++) - { - if (plainpoints.Get(i).Z() > 0) - allowpoint.Elem(i) = 0; - } - - - if (loktestmode) - (*testout) << "plainpoints = " << endl << plainpoints << endl; - - stat.cnttrials++; - - - if (stat.cnttrials % 100 == 0) - { - (*testout) << "\n"; - for (i = 1; i <= canuse.Size(); i++) - { - (*testout) << foundmap.Get(i) << "/" - << canuse.Get(i) << "/" - << ruleused.Get(i) << " map/can/use rule " << rules.Get(i)->Name() << "\n"; - } - (*testout) << endl; - } - - found = ApplyRules (plainpoints, allowpoint, - locfaces, locfacesplit, connectedpairs, - locelements, delfaces, - stat.qualclass, mp.sloppy, rotind, err); - - if (loktestmode) - { - (*testout) << "Applyrules found " << found << endl; - } - - if (found) stat.cntsucc++; - - locpoints.SetSize (plainpoints.Size()); - for (i = oldnp+1; i <= plainpoints.Size(); i++) - trans.FromPlain (plainpoints.Elem(i), locpoints.Elem(i)); - - - - // avoid meshing from large to small mesh-size - - if (uselocalh && found && stat.qualclass <= 3) - { - for (i = 1; i <= locelements.Size(); i++) - { - Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); - Point3d pmax = pmin; - for (j = 2; j <= 4; j++) - { - const Point3d & hp = locpoints.Get(locelements.Get(i).PNum(j)); - pmin.SetToMin (hp); - pmax.SetToMax (hp); - } - - if (mesh.GetMinH (pmin, pmax) < 0.4 * hshould / mp.sloppy) - found = 0; - } - } - if (found) - { - for (i = 1; i <= locelements.Size(); i++) - for (j = 1; j <= 4; j++) - { - const Point3d & hp = locpoints.Get(locelements.Get(i).PNum(j)); - if (Dist (hp, pmid) > hinner) - found = 0; - } - } - - - if (found) - ruleused.Elem(found)++; - - - if (stat.qualclass > 80) - { - cerr << "Sorry, I failed" << endl; - mesh.Save ("tempvol.out"); - exit (1); - } - - - // plotstat->Plot(stat); - - if (stat.cntelem != plotstat_oldne) - { - plotstat_oldne = stat.cntelem; - - PrintMessageCR (5, "El: ", stat.cntelem, - // << " trials: " << stat.cnttrials - " faces: ", stat.nff, - " vol = ", float(100 * stat.vol / stat.vol0)); - - multithread.percent = 100 - 100.0 * stat.vol / stat.vol0; - } - - - if (found && (!hasfound || err < minerr) ) - { - - if (testmode) - { - (*testout) << "testmode found" << endl; - for (i = 1; i <= plainpoints.Size(); i++) - { - (*testout) << "p"; - if (i <= pindex.Size()) - (*testout) << pindex.Get(i) << ": "; - else - (*testout) << "new: "; - (*testout) << plainpoints.Get(i) << endl; - } - } - - - - hasfound = found; - minerr = err; - - tempnewpoints.SetSize (0); - for (i = oldnp+1; i <= locpoints.Size(); i++) - tempnewpoints.Append (locpoints.Get(i)); - - tempnewfaces.SetSize (0); - for (i = oldnf+1; i <= locfaces.Size(); i++) - tempnewfaces.Append (locfaces.Get(i)); - - tempdelfaces.SetSize (0); - for (i = 1; i <= delfaces.Size(); i++) - tempdelfaces.Append (delfaces.Get(i)); - - templocelements.SetSize (0); - for (i = 1; i <= locelements.Size(); i++) - templocelements.Append (locelements.Get(i)); - - /* - optother = - strcmp (problems[found], "other") == 0; - */ - } - - locpoints.SetSize (oldnp); - locfaces.SetSize (oldnf); - delfaces.SetSize (0); - locelements.SetSize (0); - } - - - - if (hasfound) - { - - /* - if (optother) - (*testout) << "Other is optimal" << endl; - - if (minother < minwithoutother) - { - (*testout) << "Other is better, " << minother << " less " << minwithoutother << endl; - } - */ - - for (i = 1; i <= tempnewpoints.Size(); i++) - locpoints.Append (tempnewpoints.Get(i)); - for (i = 1; i <= tempnewfaces.Size(); i++) - locfaces.Append (tempnewfaces.Get(i)); - for (i = 1; i <= tempdelfaces.Size(); i++) - delfaces.Append (tempdelfaces.Get(i)); - for (i = 1; i <= templocelements.Size(); i++) - locelements.Append (templocelements.Get(i)); - - - if (testmode) - { - (*testout) << "testmode locpoints" << endl; - for (i = 1; i <= locpoints.Size(); i++) - { - (*testout) << "p"; - if (i <= pindex.Size()) - (*testout) << pindex.Get(i) << ": "; - else - (*testout) << "new: "; - (*testout) << locpoints.Get(i) << endl; - } - } - - - - pindex.SetSize(locpoints.Size()); - - for (i = oldnp+1; i <= locpoints.Size(); i++) - { - globind = mesh.AddPoint (locpoints.Get(i)); - pindex.Elem(i) = adfront -> AddPoint (locpoints.Get(i), globind); - } - - for (i = 1; i <= locelements.Size(); i++) - { - Point3d * hp1, * hp2, * hp3, * hp4; - hp1 = &locpoints.Elem(locelements.Get(i).PNum(1)); - hp2 = &locpoints.Elem(locelements.Get(i).PNum(2)); - hp3 = &locpoints.Elem(locelements.Get(i).PNum(3)); - hp4 = &locpoints.Elem(locelements.Get(i).PNum(4)); - - tetvol += (1.0 / 6.0) * ( Cross ( *hp2 - *hp1, *hp3 - *hp1) * (*hp4 - *hp1) ); - - for (j = 1; j <= locelements.Get(i).NP(); j++) - locelements.Elem(i).PNum(j) = - adfront -> GetGlobalIndex (pindex.Get(locelements.Get(i).PNum(j))); - - mesh.AddVolumeElement (locelements.Get(i)); - stat.cntelem++; - } - - for (i = oldnf+1; i <= locfaces.Size(); i++) - { - for (j = 1; j <= locfaces.Get(i).GetNP(); j++) - locfaces.Elem(i).PNum(j) = - pindex.Get(locfaces.Get(i).PNum(j)); - (*testout) << "add face " << locfaces.Get(i) << endl; - adfront->AddFace (locfaces.Get(i)); - } - - for (i = 1; i <= delfaces.Size(); i++) - { - adfront->DeleteFace (findex.Get(delfaces.Get(i))); - } - } - else - { - adfront->IncrementClass (findex.Get(1)); - } - - locelements.SetSize (0); - delpoints.SetSize(0); - delfaces.SetSize(0); - - if (stat.qualclass >= giveuptol) - giveup = 1; -#ifdef MYGRAPH - if (plotvolmesh && plotvolmesh->GiveUp()) - giveup = 1; -#endif - } - - - - for (i = 1; i <= ruleused.Size(); i++) - (*testout) << setw(4) << ruleused.Get(i) - << " times used rule " << rules.Get(i) -> Name() << endl; - - - if (!mp.baseelnp && adfront->Empty()) - return MESHING3_OK; - - if (mp.baseelnp && adfront->Empty (mp.baseelnp)) - return MESHING3_OK; - - if (stat.vol < -1e-15) - return MESHING3_NEGVOL; - - return MESHING3_NEGVOL; -} - - - - -enum blocktyp { BLOCKUNDEF, BLOCKINNER, BLOCKBOUND, BLOCKOUTER }; - -void Meshing3 :: BlockFill (Mesh & mesh, double gh) -{ - PrintMessage (3, "Block-filling called (obsolete) "); - - int i, j, i1, i2, i3, j1, j2, j3; - int n1, n2, n3, n, min1, min2, min3, max1, max2, max3; - int changed, filled; - double xmin, xmax, ymin, ymax, zmin, zmax; - double xminb, xmaxb, yminb, ymaxb, zminb, zmaxb; - double rad = 0.7 * gh; - - for (i = 1; i <= adfront->GetNP(); i++) - { - const Point3d & p = adfront->GetPoint(i); - if (i == 1) - { - xmin = xmax = p.X(); - ymin = ymax = p.Y(); - zmin = zmax = p.Z(); - } - else - { - if (p.X() < xmin) xmin = p.X(); - if (p.X() > xmax) xmax = p.X(); - if (p.Y() < ymin) ymin = p.Y(); - if (p.Y() > ymax) ymax = p.Y(); - if (p.Z() < zmin) zmin = p.Z(); - if (p.Z() > zmax) zmax = p.Z(); - } - } - - xmin -= 5 * gh; - ymin -= 5 * gh; - zmin -= 5 * gh; - - n1 = int ((xmax-xmin) / gh + 5); - n2 = int ((ymax-ymin) / gh + 5); - n3 = int ((zmax-zmin) / gh + 5); - n = n1 * n2 * n3; - - PrintMessage (5, "n1 = ", n1, " n2 = ", n2, " n3 = ", n3); - - ARRAY<blocktyp> inner(n); - ARRAY<int> pointnr(n), frontpointnr(n); - - - // initialize inner to 1 - - for (i = 1; i <= n; i++) - inner.Elem(i) = BLOCKUNDEF; - - - // set blocks cutting surfaces to 0 - - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & el = adfront->GetFace(i); - xminb = xmax; xmaxb = xmin; - yminb = ymax; ymaxb = ymin; - zminb = zmax; zmaxb = zmin; - - for (j = 1; j <= 3; j++) - { - const Point3d & p = adfront->GetPoint (el.PNum(j)); - if (p.X() < xminb) xminb = p.X(); - if (p.X() > xmaxb) xmaxb = p.X(); - if (p.Y() < yminb) yminb = p.Y(); - if (p.Y() > ymaxb) ymaxb = p.Y(); - if (p.Z() < zminb) zminb = p.Z(); - if (p.Z() > zmaxb) zmaxb = p.Z(); - } - - - - double filldist = 0.2; // globflags.GetNumFlag ("filldist", 0.4); - xminb -= filldist * gh; - xmaxb += filldist * gh; - yminb -= filldist * gh; - ymaxb += filldist * gh; - zminb -= filldist * gh; - zmaxb += filldist * gh; - - min1 = int ((xminb - xmin) / gh) + 1; - max1 = int ((xmaxb - xmin) / gh) + 1; - min2 = int ((yminb - ymin) / gh) + 1; - max2 = int ((ymaxb - ymin) / gh) + 1; - min3 = int ((zminb - zmin) / gh) + 1; - max3 = int ((zmaxb - zmin) / gh) + 1; - - - for (i1 = min1; i1 <= max1; i1++) - for (i2 = min2; i2 <= max2; i2++) - for (i3 = min3; i3 <= max3; i3++) - inner.Elem(i3 + (i2-1) * n3 + (i1-1) * n2 * n3) = BLOCKBOUND; - } - - - - - while (1) - { - int undefi = 0; - Point3d undefp; - - for (i1 = 1; i1 <= n1 && !undefi; i1++) - for (i2 = 1; i2 <= n2 && !undefi; i2++) - for (i3 = 1; i3 <= n3 && !undefi; i3++) - { - i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; - if (inner.Elem(i) == BLOCKUNDEF) - { - undefi = i; - undefp.X() = xmin + (i1-0.5) * gh; - undefp.Y() = ymin + (i2-0.5) * gh; - undefp.Z() = zmin + (i3-0.5) * gh; - } - } - - if (!undefi) - break; - - // PrintMessage (5, "Test point: ", undefp); - - if (adfront -> Inside (undefp)) - { - // (*mycout) << "inner" << endl; - inner.Elem(undefi) = BLOCKINNER; - } - else - { - // (*mycout) << "outer" << endl; - inner.Elem(undefi) = BLOCKOUTER; - } - - do - { - changed = 0; - for (i1 = 1; i1 <= n1; i1++) - for (i2 = 1; i2 <= n2; i2++) - for (i3 = 1; i3 <= n3; i3++) - { - i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; - - for (int k = 1; k <= 3; k++) - { - switch (k) - { - case 1: j = i + n2 * n3; break; - case 2: j = i + n3; break; - case 3: j = i + 1; break; - } - - if (j > n1 * n2 * n3) continue; - - if (inner.Elem(i) == BLOCKOUTER && inner.Elem(j) == BLOCKUNDEF) - { - changed = 1; - inner.Elem(j) = BLOCKOUTER; - } - if (inner.Elem(j) == BLOCKOUTER && inner.Elem(i) == BLOCKUNDEF) - { - changed = 1; - inner.Elem(i) = BLOCKOUTER; - } - if (inner.Elem(i) == BLOCKINNER && inner.Elem(j) == BLOCKUNDEF) - { - changed = 1; - inner.Elem(j) = BLOCKINNER; - } - if (inner.Elem(j) == BLOCKINNER && inner.Elem(i) == BLOCKUNDEF) - { - changed = 1; - inner.Elem(i) = BLOCKINNER; - } - } - } - } - while (changed); - - } - - - - filled = 0; - for (i = 1; i <= n; i++) - if (inner.Elem(i) == BLOCKINNER) - { - filled++; - } - PrintMessage (5, "Filled blocks: ", filled); - - for (i = 1; i <= n; i++) - { - pointnr.Elem(i) = 0; - frontpointnr.Elem(i) = 0; - } - - for (i1 = 1; i1 <= n1-1; i1++) - for (i2 = 1; i2 <= n2-1; i2++) - for (i3 = 1; i3 <= n3-1; i3++) - { - i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; - if (inner.Elem(i) == BLOCKINNER) - { - for (j1 = i1; j1 <= i1+1; j1++) - for (j2 = i2; j2 <= i2+1; j2++) - for (j3 = i3; j3 <= i3+1; j3++) - { - j = j3 + (j2-1) * n3 + (j1-1) * n2 * n3; - if (pointnr.Get(j) == 0) - { - Point3d hp(xmin + (j1-1) * gh, - ymin + (j2-1) * gh, - zmin + (j3-1) * gh); - pointnr.Elem(j) = mesh.AddPoint (hp); - frontpointnr.Elem(j) = - AddPoint (hp, pointnr.Elem(j)); - - } - } - } - } - - - for (i1 = 2; i1 <= n1-1; i1++) - for (i2 = 2; i2 <= n2-1; i2++) - for (i3 = 2; i3 <= n3-1; i3++) - { - i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; - if (inner.Elem(i) == BLOCKINNER) - { - int pn[9]; - pn[1] = pointnr.Get(i); - pn[2] = pointnr.Get(i+1); - pn[3] = pointnr.Get(i+n3); - pn[4] = pointnr.Get(i+n3+1); - pn[5] = pointnr.Get(i+n2*n3); - pn[6] = pointnr.Get(i+n2*n3+1); - pn[7] = pointnr.Get(i+n2*n3+n3); - pn[8] = pointnr.Get(i+n2*n3+n3+1); - static int elind[][4] = - { - { 1, 8, 2, 4 }, - { 1, 8, 4, 3 }, - { 1, 8, 3, 7 }, - { 1, 8, 7, 5 }, - { 1, 8, 5, 6 }, - { 1, 8, 6, 2 } - }; - for (j = 1; j <= 6; j++) - { - Element el(4); - for (int k = 1; k <= 4; k++) - el.PNum(k) = pn[elind[j-1][k-1]]; - - mesh.AddVolumeElement (el); - } - } - } - - - - for (i1 = 2; i1 <= n1-1; i1++) - for (i2 = 2; i2 <= n2-1; i2++) - for (i3 = 2; i3 <= n3-1; i3++) - { - i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; - if (inner.Elem(i) == BLOCKINNER) - { - int pi1, pi2, pi3, pi4; - - int pn1 = frontpointnr.Get(i); - int pn2 = frontpointnr.Get(i+1); - int pn3 = frontpointnr.Get(i+n3); - int pn4 = frontpointnr.Get(i+n3+1); - int pn5 = frontpointnr.Get(i+n2*n3); - int pn6 = frontpointnr.Get(i+n2*n3+1); - int pn7 = frontpointnr.Get(i+n2*n3+n3); - int pn8 = frontpointnr.Get(i+n2*n3+n3+1); - - for (int k = 1; k <= 6; k++) - { - switch (k) - { - case 1: // j3 = i3+1 - j = i + 1; - pi1 = pn2; - pi2 = pn6; - pi3 = pn4; - pi4 = pn8; - break; - case 2: // j3 = i3-1 - j = i - 1; - pi1 = pn1; - pi2 = pn3; - pi3 = pn5; - pi4 = pn7; - break; - case 3: // j2 = i2+1 - j = i + n3; - pi1 = pn3; - pi2 = pn4; - pi3 = pn7; - pi4 = pn8; - break; - case 4: // j2 = i2-1 - j = i - n3; - pi1 = pn1; - pi2 = pn5; - pi3 = pn2; - pi4 = pn6; - break; - case 5: // j1 = i1+1 - j = i + n3*n2; - pi1 = pn5; - pi2 = pn7; - pi3 = pn6; - pi4 = pn8; - break; - case 6: // j1 = i1-1 - j = i - n3*n2; - pi1 = pn1; - pi2 = pn2; - pi3 = pn3; - pi4 = pn4; - break; - } - - if (inner.Get(j) == BLOCKBOUND) - { - Element2d face; - face.PNum(1) = pi4; - face.PNum(2) = pi1; - face.PNum(3) = pi3; - AddBoundaryElement (face); - - face.PNum(1) = pi1; - face.PNum(2) = pi4; - face.PNum(3) = pi2; - AddBoundaryElement (face); - - } - } - } - } -} - - - -static const AdFront3 * locadfront; -static int TestInner (const Point3d & p) -{ - return locadfront->Inside (p); -} -static int TestSameSide (const Point3d & p1, const Point3d & p2) -{ - return locadfront->SameSide (p1, p2); -} - - - - -void Meshing3 :: BlockFillLocalH (Mesh & mesh, - const MeshingParameters & mp) -{ - int i, j; - - double filldist = mp.filldist; - - (*testout) << "blockfill local h" << endl; - (*testout) << "rel filldist = " << filldist << endl; - PrintMessage (3, "blockfill local h"); - - /* - (*mycout) << "boxes: " << mesh.LocalHFunction().GetNBoxes() << endl - << "filldist = " << filldist << endl; - */ - ARRAY<Point3d> npoints; - - adfront -> CreateTrees(); - - Point3d mpmin, mpmax; - // mesh.GetBox (mpmin, mpmax); - bool firstp = 1; - - double maxh = 0; - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & el = adfront->GetFace(i); - for (j = 1; j <= 3; j++) - { - const Point3d & p1 = adfront->GetPoint (el.PNumMod(j)); - const Point3d & p2 = adfront->GetPoint (el.PNumMod(j+1)); - double hi = Dist (p1, p2); - if (hi > maxh) maxh = hi; - - if (firstp) - { - mpmin = p1; - mpmax = p1; - firstp = 0; - } - else - { - mpmin.SetToMin (p1); - mpmax.SetToMax (p1); - } - } - } - - Point3d mpc = Center (mpmin, mpmax); - double d = max3(mpmax.X()-mpmin.X(), - mpmax.Y()-mpmin.Y(), - mpmax.Z()-mpmin.Z()) / 2; - mpmin = mpc - Vec3d (d, d, d); - mpmax = mpc + Vec3d (d, d, d); - Box3d meshbox (mpmin, mpmax); - - LocalH loch2 (mpmin, mpmax, 1); - - - if (mp.maxh < maxh) maxh = mp.maxh; - - int changed; - do - { - mesh.LocalHFunction().ClearFlags(); - - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & el = adfront->GetFace(i); - Point3d pmin = adfront->GetPoint (el.PNum(1)); - Point3d pmax = pmin; - - for (j = 2; j <= 3; j++) - { - const Point3d & p = adfront->GetPoint (el.PNum(j)); - pmin.SetToMin (p); - pmax.SetToMax (p); - } - - - double filld = filldist * Dist (pmin, pmax); - - pmin = pmin - Vec3d (filld, filld, filld); - pmax = pmax + Vec3d (filld, filld, filld); - // (*testout) << "cut : " << pmin << " - " << pmax << endl; - mesh.LocalHFunction().CutBoundary (pmin, pmax); - } - - locadfront = adfront; - mesh.LocalHFunction().FindInnerBoxes (adfront, NULL); - - npoints.SetSize(0); - mesh.LocalHFunction().GetInnerPoints (npoints); - - changed = 0; - for (i = 1; i <= npoints.Size(); i++) - { - if (mesh.LocalHFunction().GetH(npoints.Get(i)) > 1.5 * maxh) - { - mesh.LocalHFunction().SetH (npoints.Get(i), -maxh); - changed = 1; - } - } - } - while (changed); - - if (debugparam.slowchecks) - (*testout) << "Blockfill with points: " << endl; - for (i = 1; i <= npoints.Size(); i++) - { - if (meshbox.IsIn (npoints.Get(i))) - { - int gpnum = mesh.AddPoint (npoints.Get(i)); - adfront->AddPoint (npoints.Get(i), gpnum); - - if (debugparam.slowchecks) - { - (*testout) << npoints.Get(i) << endl; - if (!adfront->Inside(npoints.Get(i))) - { - cout << "add outside point" << endl; - (*testout) << "outside" << endl; - } - } - - } - } - - - - // find outer points - - loch2.ClearFlags(); - - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & el = adfront->GetFace(i); - Point3d pmin = adfront->GetPoint (el.PNum(1)); - Point3d pmax = pmin; - - for (j = 2; j <= 3; j++) - { - const Point3d & p = adfront->GetPoint (el.PNum(j)); - pmin.SetToMin (p); - pmax.SetToMax (p); - } - - loch2.SetH (Center (pmin, pmax), Dist (pmin, pmax)); - } - - for (i = 1; i <= adfront->GetNF(); i++) - { - const Element2d & el = adfront->GetFace(i); - Point3d pmin = adfront->GetPoint (el.PNum(1)); - Point3d pmax = pmin; - - for (j = 2; j <= 3; j++) - { - const Point3d & p = adfront->GetPoint (el.PNum(j)); - pmin.SetToMin (p); - pmax.SetToMax (p); - } - - double filld = filldist * Dist (pmin, pmax); - pmin = pmin - Vec3d (filld, filld, filld); - pmax = pmax + Vec3d (filld, filld, filld); - loch2.CutBoundary (pmin, pmax); - } - - locadfront = adfront; - loch2.FindInnerBoxes (adfront, NULL); - - npoints.SetSize(0); - loch2.GetOuterPoints (npoints); - - for (i = 1; i <= npoints.Size(); i++) - { - if (meshbox.IsIn (npoints.Get(i))) - { - int gpnum = mesh.AddPoint (npoints.Get(i)); - adfront->AddPoint (npoints.Get(i), gpnum); - } - } -} - -} diff --git a/Netgen/libsrc/meshing/meshing3.hpp b/Netgen/libsrc/meshing/meshing3.hpp deleted file mode 100644 index 45f44751e3..0000000000 --- a/Netgen/libsrc/meshing/meshing3.hpp +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef FILE_MESHING3 -#define FILE_MESHING3 - - - - -enum MESHING3_RESULT -{ - MESHING3_OK = 0, - MESHING3_GIVEUP = 1, - MESHING3_NEGVOL = 2, - MESHING3_OUTERSTEPSEXCEEDED = 3, - MESHING3_TERMINATE = 4, - MESHING3_BADSURFACEMESH = 5 -}; - - -/// 3d volume mesh generation -class Meshing3 -{ - /// current state of front - AdFront3 * adfront; - /// 3d generation rules - ARRAY<vnetrule*> rules; - /// counts how often a rule is used - ARRAY<int> ruleused, canuse, foundmap; - /// describes, why a rule is not applied - ARRAY<char*> problems; - /// tolerance criterion - double tolfak; -public: - /// - Meshing3 (const string & rulefilename); - /// - Meshing3 (const char ** rulep); - /// - virtual ~Meshing3 (); - - /// - void LoadRules (const char * filename, const char ** prules); - /// - MESHING3_RESULT GenerateMesh (Mesh & mesh, const MeshingParameters & mp); - - /// - int ApplyRules (ARRAY<Point3d> & lpoints, ARRAY<int> & allowpoint, - ARRAY<Element2d> & lfaces, INDEX lfacesplit, - INDEX_2_HASHTABLE<int> & connectedpairs, - ARRAY<Element> & elements, - ARRAY<INDEX> & delfaces, int tolerance, - double sloppy, int rotind1, - float & retminerr); - - /// - PointIndex AddPoint (const Point3d & p, PointIndex globind); - /// - void AddBoundaryElement (const Element2d & elem); - /// - int AddConnectedPair (const INDEX_2 & pair); - - /// - void BlockFill (Mesh & mesh, double gh); - /// - void BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp); - - /// uses points of adfront, and puts new elements into mesh - void Delaunay (Mesh & mesh, const MeshingParameters & mp); - /// - friend class PlotVolMesh; - /// - friend void TestRules (); -}; - - - - -/// status of mesh generation -class MeshingStat3d -{ -public: - /// - MeshingStat3d (); - /// - int cntsucc; - /// - int cnttrials; - /// - int cntelem; - /// - int nff; - /// - int qualclass; - /// - double vol0; - /// - double vol; - /// - double h; - /// - int problemindex; -}; - - - - - -/* -template <typename POINTARRAY, typename FACEARRAY> -extern int FindInnerPoint (POINTARRAY & grouppoints, - FACEARRAY & groupfaces, - Point3d & p); - -*/ - - - - - -#endif - - - - - - - - - - diff --git a/Netgen/libsrc/meshing/meshtool.cpp b/Netgen/libsrc/meshing/meshtool.cpp deleted file mode 100644 index 89bb2b16dd..0000000000 --- a/Netgen/libsrc/meshing/meshtool.cpp +++ /dev/null @@ -1,978 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" -#include <csg.hpp> -#include <geometry2d.hpp> - -namespace netgen -{ - - int CheckSurfaceMesh (const Mesh & mesh) - { - PrintMessage (3, "Check Surface mesh"); - - int nf = mesh.GetNSE(); - INDEX_2_HASHTABLE<int> edges(nf+2); - int i, j; - INDEX_2 i2; - int cnt1 = 0, cnt2 = 0; - - for (i = 1; i <= nf; i++) - for (j = 1; j <= 3; j++) - { - i2.I1() = mesh.SurfaceElement(i).PNumMod(j); - i2.I2() = mesh.SurfaceElement(i).PNumMod(j+1); - if (edges.Used(i2)) - { - int hi; - hi = edges.Get(i2); - if (hi != 1) - PrintSysError ("CheckSurfaceMesh, hi = ", hi); - edges.Set(i2, 2); - cnt2++; - } - else - { - Swap (i2.I1(), i2.I2()); - edges.Set(i2, 1); - cnt1++; - } - } - - - if (cnt1 != cnt2) - { - PrintUserError ("Surface mesh not consistent"); - // MyBeep(2); - // (*mycout) << "cnt1 = " << cnt1 << " cnt2 = " << cnt2 << endl; - return 0; - } - return 1; - } - - - - int CheckSurfaceMesh2 (const Mesh & mesh) - { - int i, j, k; - const Point3d *tri1[3], *tri2[3]; - - for (i = 1; i <= mesh.GetNOpenElements(); i++) - { - PrintDot (); - for (j = 1; j < i; j++) - { - for (k = 1; k <= 3; k++) - { - tri1[k-1] = &mesh.Point (mesh.OpenElement(i).PNum(k)); - tri2[k-1] = &mesh.Point (mesh.OpenElement(j).PNum(k)); - } - if (IntersectTriangleTriangle (&tri1[0], &tri2[0])) - { - PrintSysError ("Surface elements are intersecting"); - (*testout) << "Intersecting: " << endl; - for (k = 0; k <= 2; k++) - (*testout) << *tri1[k] << " "; - (*testout) << endl; - for (k = 0; k <= 2; k++) - (*testout) << *tri2[k] << " "; - (*testout) << endl; - } - - } - } - return 0; - } - - - - - - static double TriangleQualityInst (const Point3d & p1, const Point3d & p2, - const Point3d & p3) - { - // quality 0 (worst) .. 1 (optimal) - - Vec3d v1, v2, v3; - double s1, s2, s3; - double an1, an2, an3; - - v1 = p2 - p1; - v2 = p3 - p1; - v3 = p3 - p2; - - an1 = Angle (v1, v2); - v1 *= -1; - an2 = Angle (v1, v3); - an3 = Angle (v2, v3); - - s1 = sin (an1/2); - s2 = sin (an2/2); - s3 = sin (an3/2); - - return 8 * s1 * s2 * s3; - } - - - - - - - - - - - - - - - void MeshQuality2d (const Mesh & mesh) - { - int ncl = 20, cl; - ARRAY<INDEX> incl(ncl); - INDEX i; - SurfaceElementIndex sei; - double qual; - - incl = 0; - - for (sei = 0; sei < mesh.GetNSE(); sei++) - { - qual = TriangleQualityInst (mesh[mesh[sei][0]], - mesh[mesh[sei][1]], - mesh[mesh[sei][2]]); - - cl = int ( (ncl-1e-3) * qual ) + 1; - incl.Elem(cl)++; - } - - (*testout) << endl << endl; - - (*testout) << "Points: " << mesh.GetNP() << endl; - (*testout) << "Surface Elements: " << mesh.GetNSE() << endl; - - (*testout) << endl; - (*testout) << "Elements in qualityclasses:" << endl; - (*testout).precision(2); - for (i = 1; i <= ncl; i++) - { - (*testout) << setw(4) << double (i-1)/ncl << " - " - << setw(4) << double (i) / ncl << ": " - << incl.Get(i) << endl; - } - } - - - static double TetElementQuality (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4) - { - double vol, l, l4, l5, l6; - - - Vec3d v1 = p2 - p1; - Vec3d v2 = p3 - p1; - Vec3d v3 = p4 - p1; - - vol = fabs ((Cross (v1, v2) * v3)) / 6; - l4 = Dist (p2, p3); - l5 = Dist (p2, p4); - l6 = Dist (p3, p4); - - l = v1.Length() + v2.Length() + v3.Length() + l4 + l5 + l6; - - if (vol <= 1e-8 * l * l * l) return 1e-10; - - return vol/(l*l*l) * 1832.82; // 6^4 * sqrt(2) - } - - - - - - double teterrpow = 2; - - double CalcTetBadness (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, double h) - { - double vol, l, ll, lll, ll1, ll2, ll3, ll4, ll5, ll6; - double err; - - Vec3d v1 (p1, p2); - Vec3d v2 (p1, p3); - Vec3d v3 (p1, p4); - - vol = -Determinant (v1, v2, v3) / 6; - - ll1 = v1.Length2(); - ll2 = v2.Length2(); - ll3 = v3.Length2(); - ll4 = Dist2 (p2, p3); - ll5 = Dist2 (p2, p4); - ll6 = Dist2 (p3, p4); - - ll = ll1 + ll2 + ll3 + ll4 + ll5 + ll6; - l = sqrt (ll); - lll = l * ll; - - if (vol <= 1e-24 * lll) - return 1e24; - - err = 0.0080187537 * lll / vol; // sqrt(216) / (6^4 * sqrt(2)) - - if (h > 0) - err += ll / (h * h) + - h * h * ( 1 / ll1 + 1 / ll2 + 1 / ll3 + - 1 / ll4 + 1 / ll5 + 1 / ll6 ) - 12; - - return pow (err, teterrpow); - } - - - double CalcTetBadnessGrad (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, double h, - int pi, Vec3d & grad) - { - double vol, l, ll, lll; - double err; - - const Point3d *pp1, *pp2, *pp3, *pp4; - - pp1 = &p1; - pp2 = &p2; - pp3 = &p3; - pp4 = &p4; - - switch (pi) - { - case 2: - { - swap (pp1, pp2); - swap (pp3, pp4); - break; - } - case 3: - { - swap (pp1, pp3); - swap (pp2, pp4); - break; - } - case 4: - { - swap (pp1, pp4); - swap (pp3, pp2); - break; - } - } - - - Vec3d v1 (*pp1, *pp2); - Vec3d v2 (*pp1, *pp3); - Vec3d v3 (*pp1, *pp4); - - Vec3d v4 (*pp2, *pp3); - Vec3d v5 (*pp2, *pp4); - Vec3d v6 (*pp3, *pp4); - - vol = -Determinant (v1, v2, v3) / 6; - - Vec3d gradvol; - Cross (v5, v4, gradvol); - gradvol *= (-1.0/6.0); - - - double ll1 = v1.Length2(); - double ll2 = v2.Length2(); - double ll3 = v3.Length2(); - double ll4 = v4.Length2(); - double ll5 = v5.Length2(); - double ll6 = v6.Length2(); - - ll = ll1 + ll2 + ll3 + ll4 + ll5 + ll6; - l = sqrt (ll); - lll = l * ll; - - if (vol <= 1e-24 * lll) - { - grad = Vec3d (0, 0, 0); - return 1e24; - } - - - - Vec3d gradll1 (*pp2, *pp1); - Vec3d gradll2 (*pp3, *pp1); - Vec3d gradll3 (*pp4, *pp1); - gradll1 *= 2; - gradll2 *= 2; - gradll3 *= 2; - - Vec3d gradll (gradll1); - gradll += gradll2; - gradll += gradll3; - - - - err = 0.0080187537 * lll / vol; - - - gradll *= (0.0080187537 * 1.5 * l / vol); - Vec3d graderr(gradll); - gradvol *= ( -0.0080187537 * lll / (vol * vol) ); - graderr += gradvol; - - if (h > 0) - { - err += ll / (h*h) + - h*h * ( 1 / ll1 + 1 / ll2 + 1 / ll3 + - 1 / ll4 + 1 / ll5 + 1 / ll6 ) - 12; - - graderr += (1/(h*h) - h*h/(ll1*ll1)) * gradll1; - graderr += (1/(h*h) - h*h/(ll2*ll2)) * gradll2; - graderr += (1/(h*h) - h*h/(ll3*ll3)) * gradll3; - cout << "?"; - } - - double errpow = pow (err, teterrpow); - grad = (teterrpow * errpow / err) * graderr; - - return errpow; - } - - - - - - /* - - double CalcTetBadness (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, double h) - { - double vol, l; - double err; - - - Vec3d v1 (p1, p2); - Vec3d v2 (p1, p3); - Vec3d v3 (p1, p4); - - vol = -Determinant (v1, v2, v3) / 6; - - double l1 = v1.Length(); - double l2 = v2.Length(); - double l3 = v3.Length(); - double l4 = Dist (p2, p3); - double l5 = Dist (p2, p4); - double l6 = Dist (p3, p4); - - l = l1 + l2 + l3 + l4 + l5 + l6; - - // just for timing - // l += 1e-40 * CalcTetBadnessNew (p1, p2, p3, p4, h); - - if (vol <= 1e-24 * l * l * l) - { - return 1e24; - } - - err = (l*l*l) / (1832.82 * vol); // 6^4 * sqrt(2) - - if (h > 0) - err += l / h + - h * (1 / l1 + 1/l2 + 1/l3 + 1/l4 + 1/l5 + 1/l6) - 12; - - return pow (err, teterrpow); - } - - - - double CalcTetBadnessGrad (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, double h, - int pi, Vec3d & grad) - { - double vol, l; - double err; - - const Point3d *pp1, *pp2, *pp3, *pp4; - - pp1 = &p1; - pp2 = &p2; - pp3 = &p3; - pp4 = &p4; - - switch (pi) - { - case 2: - { - swap (pp1, pp2); - swap (pp3, pp4); - break; - } - case 3: - { - swap (pp1, pp3); - swap (pp2, pp4); - break; - } - case 4: - { - swap (pp1, pp4); - swap (pp3, pp2); - break; - } - } - - - Vec3d v1 (*pp1, *pp2); - Vec3d v2 (*pp1, *pp3); - Vec3d v3 (*pp1, *pp4); - - Vec3d v4 (*pp2, *pp3); - Vec3d v5 (*pp2, *pp4); - Vec3d v6 (*pp3, *pp4); - - - // Vec3d n; - // Cross (v1, v2, n); - // vol = - (n * v3) / 6; - - - vol = -Determinant (v1, v2, v3) / 6; - - Vec3d gradvol; - Cross (v5, v4, gradvol); - gradvol *= (-1.0/6.0); - - - double l1 = v1.Length(); - double l2 = v2.Length(); - double l3 = v3.Length(); - double l4 = v4.Length(); - double l5 = v5.Length(); - double l6 = v6.Length(); - - l = l1 + l2 + l3 +l4 + l5 + l6; - - Vec3d gradl1 (*pp2, *pp1); - Vec3d gradl2 (*pp3, *pp1); - Vec3d gradl3 (*pp4, *pp1); - gradl1 /= l1; - gradl2 /= l2; - gradl3 /= l3; - - Vec3d gradl (gradl1); - gradl += gradl2; - gradl += gradl3; - - - if (vol <= 1e-24 * l * l * l) - { - grad = Vec3d (0, 0, 0); - return 1e24; - } - - - double c1 = 1.0 / 1832.82; // 6^4 * sqrt(2) - err = c1 * (l*l*l) / vol; - - - gradl *= (c1 * 3 * l * l / vol); - Vec3d graderr(gradl); - gradvol *= ( -c1 * l * l * l / (vol * vol) ); - graderr+= gradvol; - - if (h > 0) - { - err += l / h + - h * ( 1 / l1 + 1 / l2 + 1 / l3 + - 1 / l4 + 1 / l5 + 1 / l6 ) - 12; - - graderr += (1/h - h/(l1*l1)) * gradl1; - graderr += (1/h - h/(l2*l2)) * gradl2; - graderr += (1/h - h/(l3*l3)) * gradl3; - cout << "?"; - } - - double errpow = pow (err, teterrpow); - grad = (teterrpow * errpow / err) * graderr; - - return errpow; - } - - */ - - - - - - /* - double CalcVolume (const ARRAY<Point3d> & points, - const Element & el) - { - Vec3d v1 = points.Get(el.PNum(2)) - - points.Get(el.PNum(1)); - Vec3d v2 = points.Get(el.PNum(3)) - - points.Get(el.PNum(1)); - Vec3d v3 = points.Get(el.PNum(4)) - - points.Get(el.PNum(1)); - - return -(Cross (v1, v2) * v3) / 6; - } - */ - - double CalcVolume (const ARRAY<Point3d> & points, - const ARRAY<Element> & elements) - { - double vol; - Vec3d v1, v2, v3; - - vol = 0; - for (int i = 0; i < elements.Size(); i++) - { - v1 = points.Get(elements[i][1]) - points.Get(elements[i][0]); - v2 = points.Get(elements[i][2]) - points.Get(elements[i][0]); - v3 = points.Get(elements[i][3]) - points.Get(elements[i][0]); - vol -= (Cross (v1, v2) * v3) / 6; - } - return vol; - } - - - - - void MeshQuality3d (const Mesh & mesh, ARRAY<int> * inclass) - { - int ncl = 20; - signed int cl; - ARRAY<INDEX> incl(ncl); - INDEX i; - double qual; - double sum = 0; - int nontet = 0; - - for (i = 1; i <= incl.Size(); i++) - incl.Elem(i) = 0; - - for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) - { - if (mesh[ei].GetType() != TET) - { - nontet++; - continue; - } - - qual = TetElementQuality (mesh.Point(mesh[ei][0]), - mesh.Point(mesh[ei][1]), - mesh.Point(mesh[ei][2]), - mesh.Point(mesh[ei][3])); - - if (qual > 1) qual = 1; - cl = int (ncl * qual ) + 1; - - if (cl < 1) cl = 1; - if (cl > ncl) cl = ncl; - - incl.Elem(cl)++; - if (inclass) (*inclass)[ei] = cl; - sum += 1/qual; - } - - (*testout) << endl << endl; - (*testout) << "Points: " << mesh.GetNP() << endl; - (*testout) << "Volume Elements: " << mesh.GetNE() << endl; - if (nontet) - (*testout) << nontet << " non tetrahedral elements" << endl; - (*testout) << endl; - - (*testout) << "Volume elements in qualityclasses:" << endl; - (*testout).precision(2); - for (i = 1; i <= ncl; i++) - { - (*testout) << setw(4) << double (i-1)/ncl << " - " - << setw(4) << double (i) / ncl << ": " - << incl.Get(i) << endl; - } - (*testout) << "total error: " << sum << endl; - } - - - void SaveEdges (const Mesh & mesh, const char * geomfile, double h, char * filename) - { - ofstream of (filename); - int i; - const Segment * seg; - - of << "edges" << endl; - of << geomfile << endl; - of << h << endl; - - of << mesh.GetNP() << endl; - for (i = 1; i <= mesh.GetNP(); i++) - of << mesh.Point(i).X() << " " - << mesh.Point(i).Y() << " " - << mesh.Point(i).Z() << "\n"; - - of << 2 * mesh.GetNSeg() << endl; - for (i = 1; i <= mesh.GetNSeg(); i++) - { - seg = &mesh.LineSegment(i); - - of << seg->p2 << " " << seg->p1 << " " << seg->si << "\n"; - } - - } - - - void SaveSurfaceMesh (const Mesh & mesh, - double h, - char * filename) - - { - INDEX i; - - ofstream outfile(filename); - - outfile << "surfacemesh" << endl; - outfile << h << endl; - - outfile << mesh.GetNP() << endl; - for (i = 1; i <= mesh.GetNP(); i++) - outfile << mesh.Point(i).X() << " " - << mesh.Point(i).Y() << " " - << mesh.Point(i).Z() << endl; - - - - outfile << mesh.GetNSE() << endl; - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - if (mesh.GetFaceDescriptor(el.GetIndex()).DomainOut() == 0) - outfile << mesh.SurfaceElement(i).PNum(1) << " " - << mesh.SurfaceElement(i).PNum(2) << " " - << mesh.SurfaceElement(i).PNum(3) << endl; - if (mesh.GetFaceDescriptor(el.GetIndex()).DomainIn() == 0) - outfile << mesh.SurfaceElement(i).PNum(1) << " " - << mesh.SurfaceElement(i).PNum(3) << " " - << mesh.SurfaceElement(i).PNum(2) << endl; - } - } - - -#ifdef OLD - void Save2DMesh ( - const Mesh & mesh2d, - const ARRAY<SplineSegment *> * splines, - ostream & outfile) - - { - int i, j; - outfile.precision (6); - - outfile << "areamesh2" << endl; - - - outfile << endl; - outfile << mesh2d.GetNSeg() << endl; - for (i = 1; i <= mesh2d.GetNSeg(); i++) - outfile << mesh2d.LineSegment(i).si << " " - << mesh2d.LineSegment(i).p1 << " " - << mesh2d.LineSegment(i).p2 << " " << endl; - - - outfile << mesh2d.GetNSE() << endl; - for (i = 1; i <= mesh2d.GetNSE(); i++) - { - outfile << mesh2d.SurfaceElement(i).GetIndex() << " "; - outfile << mesh2d.SurfaceElement(i).GetNP() << " "; - for (j = 1; j <= mesh2d.SurfaceElement(i).GetNP(); j++) - outfile << mesh2d.SurfaceElement(i).PNum(j) << " "; - outfile << endl; - } - - outfile << mesh2d.GetNP() << endl; - for (i = 1; i <= mesh2d.GetNP(); i++) - outfile << mesh2d.Point(i).X() << " " - << mesh2d.Point(i).Y() << endl; - - if (splines) - { - outfile << splines->Size() << endl; - for (i = 1; i <= splines->Size(); i++) - splines->Get(i) -> PrintCoeff (outfile); - } - else - outfile << "0" << endl; - } -#endif - - - - - - - - - void SaveVolumeMesh (const Mesh & mesh, - const CSGeometry & geometry, - char * filename) - { - INDEX i; - - ofstream outfile(filename); - outfile << "volumemesh" << endl; - - outfile << mesh.GetNSE() << endl; - for (i = 1; i <= mesh.GetNSE(); i++) - { - if (mesh.SurfaceElement(i).GetIndex()) - outfile << mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex ()).SurfNr() - << "\t"; - else - outfile << "0" << "\t"; - outfile << mesh.SurfaceElement(i)[0] << " " - << mesh.SurfaceElement(i)[1] << " " - << mesh.SurfaceElement(i)[2] << endl; - } - outfile << mesh.GetNE() << endl; - for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) - outfile << mesh[ei].GetIndex() << "\t" - << mesh[ei][0] << " " << mesh[ei][1] << " " - << mesh[ei][2] << " " << mesh[ei][3] << endl; - - outfile << mesh.GetNP() << endl; - for (i = 1; i <= mesh.GetNP(); i++) - outfile << mesh.Point(i).X() << " " - << mesh.Point(i).Y() << " " - << mesh.Point(i).Z() << endl; - -#ifdef SOLIDGEOM - outfile << geometry.GetNSurf() << endl; - for (i = 1; i <= geometry.GetNSurf(); i++) - geometry.GetSurface(i) -> Print (outfile); -#endif - } - - - - - int CheckCode () - { - return 1; - - /* - char st[100]; - ifstream ist("pw"); - - if (!ist.good()) return 0; - ist >> st; - if (strcmp (st, "JKULinz") == 0) return 1; - return 0; - */ - } - - - - /* ******************** CheckMesh ******************************* */ - - /// Checks, whether mesh contains a valid 3d mesh - int CheckMesh3D (const Mesh & mesh) - { - INDEX_3_HASHTABLE<int> faceused(mesh.GetNE()/3); - INDEX i; - int j, k, l; - INDEX_3 i3; - int ok = 1; - ElementIndex ei; - - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - if (mesh.GetFaceDescriptor(el.GetIndex()).DomainIn() == 0 || - mesh.GetFaceDescriptor(el.GetIndex()).DomainOut() == 0) - { - for (j = 1; j <= 3; j++) - i3.I(j) = el.PNum(j); - - i3.Sort(); - faceused.Set (i3, 1); - } - } - - for (ei = 0; ei < mesh.GetNE(); ei++) - { - const Element & el = mesh[ei]; - - for (j = 1; j <= 4; j++) - { - l = 0; - for (k = 1; k <= 4; k++) - { - if (j != k) - { - l++; - i3.I(l) = el.PNum(k); - } - } - - i3.Sort(); - if (faceused.Used(i3)) - faceused.Set(i3, faceused.Get(i3)+1); - else - faceused.Set (i3, 1); - } - } - - - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - for (j = 1; j <= 3; j++) - i3.I(j) = el.PNum(j); - - i3.Sort(); - k = faceused.Get (i3); - if (k != 2) - { - ok = 0; - (*testout) << "face " << i << " with points " - << i3.I1() << "-" << i3.I2() << "-" << i3.I3() - << " has " << k << " elements" << endl; - } - } - - for (ei = 0; ei < mesh.GetNE(); ei++) - { - const Element & el = mesh[ei]; - - for (j = 1; j <= 4; j++) - { - l = 0; - for (k = 1; k <= 4; k++) - { - if (j != k) - { - l++; - i3.I(l) = el.PNum(k); - } - } - - i3.Sort(); - k = faceused.Get(i3); - if (k != 2) - { - ok = 0; - (*testout) << "element " << ei << " with face " - << i3.I1() << "-" << i3.I2() << "-" - << i3.I3() - << " has " << k << " elements" << endl; - } - } - } - - - - - - /* - for (i = 1; i <= faceused.GetNBags(); i++) - for (j = 1; j <= faceused.GetBagSize(i); j++) - { - faceused.GetData(i, j, i3, k); - if (k != 2) - { - (*testout) << "Face: " << i3.I1() << "-" - << i3.I2() << "-" << i3.I3() << " has " - << k << " Faces " << endl; - cerr << "Face Error" << endl; - ok = 0; - } - } - */ - - - if (!ok) - { - (*testout) << "surfelements: " << endl; - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement(i); - (*testout) << setw(5) << i << ":" - << setw(6) << el.GetIndex() - << setw(6) << el.PNum(1) - << setw(4) << el.PNum(2) - << setw(4) << el.PNum(3) << endl; - } - (*testout) << "volelements: " << endl; - for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) - { - const Element & el = mesh[ei]; - (*testout) << setw(5) << i << ":" - << setw(6) << el.GetIndex() - << setw(6) << el[0] << setw(4) << el[1] - << setw(4) << el[2] << setw(4) << el[3] << endl; - } - } - - - return ok; - } - - - - void RemoveProblem (Mesh & mesh) - { - int i, j, k; - - mesh.FindOpenElements(); - int np = mesh.GetNP(); - - BitArrayChar<PointIndex::BASE> ppoints(np); - - int ndom = mesh.GetNDomains(); - - PrintMessage (3, "Elements before Remove: ", mesh.GetNE()); - for (k = 1; k <= ndom; k++) - { - ppoints.Clear(); - - for (i = 1; i <= mesh.GetNOpenElements(); i++) - { - const Element2d & sel = mesh.OpenElement(i); - if (sel.GetIndex() == k) - { - for (j = 1; j <= sel.GetNP(); j++) - ppoints.Set (sel.PNum(j)); - } - } - - for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) - { - const Element & el = mesh[ei]; - if (el.GetIndex() == k) - { - int todel = 0; - for (j = 0; j < el.GetNP(); j++) - if (ppoints.Test (el[j])) - todel = 1; - - if (el.GetNP() != 4) - todel = 0; - - if (todel) - { - mesh[ei].Delete(); - // ei--; - } - } - } - } - - mesh.Compress(); - PrintMessage (3, "Elements after Remove: ", mesh.GetNE()); - } - - -} diff --git a/Netgen/libsrc/meshing/meshtool.hpp b/Netgen/libsrc/meshing/meshtool.hpp deleted file mode 100644 index 1baafe40ff..0000000000 --- a/Netgen/libsrc/meshing/meshtool.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef FILE_MESHTOOL -#define FILE_MESHTOOL - - -/// -extern void MeshQuality2d (const Mesh & mesh); - -/// -extern void MeshQuality3d (const Mesh & mesh, - ARRAY<int> * inclass = NULL); - -/// -extern void SaveEdges (const Mesh & mesh, - const char * geomfile, - double h, - char * filename); - -/// -extern void SaveSurfaceMesh (const Mesh & mesh, - double h, - char * filename); -/* -/// -extern void Save2DMesh ( - const Mesh & mesh2d, - const ARRAY<class SplineSegment*> * splines, - ostream & outfile); -*/ - -class Surface; -/// -extern void SaveVolumeMesh ( - const ARRAY<Point3d> & points, - const ARRAY<Element> & elements, - const ARRAY<Element> & volelements, - const ARRAY<Surface*> & surfaces, - char * filename); - -/// -void SaveVolumeMesh (const Mesh & mesh, - const class CSGeometry & geometry, - char * filename); - -/// -extern int CheckCode (); - - -/// -extern double CalcTetBadness (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Point3d & p4, - double h); -/// -extern double CalcTetBadnessGrad (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Point3d & p4, - double h, int pi, - Vec3d & grad); - - -/** Calculates volume of an element. - The volume of the tetrahedron el is computed - */ -// extern double CalcVolume (const ARRAY<Point3d> & points, -// const Element & el); - -/** The total volume of all elements is computed. - This function calculates the volume of the mesh */ -extern double CalcVolume (const ARRAY<Point3d> & points, - const ARRAY<Element> & elements); - -/// -extern int CheckSurfaceMesh (const Mesh & mesh); - -/// -extern int CheckSurfaceMesh2 (const Mesh & mesh); -/// -extern int CheckMesh3D (const Mesh & mesh); -/// -extern void RemoveProblem (Mesh & mesh); -#endif diff --git a/Netgen/libsrc/meshing/meshtype.cpp b/Netgen/libsrc/meshing/meshtype.cpp deleted file mode 100644 index e26a0b48ce..0000000000 --- a/Netgen/libsrc/meshing/meshtype.cpp +++ /dev/null @@ -1,2233 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - - -namespace netgen -{ - - - - MultiPointGeomInfo :: MultiPointGeomInfo() - { - cnt = 0; - } - - int MultiPointGeomInfo :: - AddPointGeomInfo (const PointGeomInfo & gi) - { - for (int k = 0; k < cnt; k++) - if (mgi[k].trignum == gi.trignum) - return 0; - - if (cnt < MULTIPOINTGEOMINFO_MAX) - { - mgi[cnt] = gi; - cnt++; - return 0; - } - - throw NgException ("Please report error: MPGI Size too small\n"); - } - - - void MultiPointGeomInfo :: - Init () - { - cnt = 0; - } - - void MultiPointGeomInfo :: - DeleteAll () - { - cnt = 0; - } - - - - - Segment :: Segment() - { - p1 = -1; - p2 = -1; - edgenr = -1; - - singedge_left = 0; - singedge_right = 0; - seginfo = 0; - - si = -1; - - domin = -1; - domout = -1; - tlosurf = -1; - - surfnr1 = -1; - surfnr2 = -1; - pmid = -1; - meshdocval = 0; - /* - geominfo[0].trignum=-1; - geominfo[1].trignum=-1; - - epgeominfo[0].edgenr = 1; - epgeominfo[0].dist = 0; - epgeominfo[1].edgenr = 1; - epgeominfo[1].dist = 0; - */ - } - - - - Segment& Segment::operator=(const Segment & other) - { - p1 = other.p1; - p2 = other.p2; - edgenr = other.edgenr; - singedge_left = other.singedge_left; - singedge_right = other.singedge_right; - seginfo = other.seginfo; - si = other.si; - domin = other.domin; - domout = other.domout; - tlosurf = other.tlosurf; - geominfo[0] = other.geominfo[0]; - geominfo[1] = other.geominfo[1]; - surfnr1 = other.surfnr1; - surfnr2 = other.surfnr2; - epgeominfo[0] = other.epgeominfo[0]; - epgeominfo[1] = other.epgeominfo[1]; - pmid = other.pmid; - meshdocval = other.meshdocval; - - return *this; - } - - - ostream & operator<<(ostream & s, const Segment & seg) - { - s << seg.p1 << "(gi=" << seg.geominfo[0].trignum << ") - " - << seg.p2 << "(gi=" << seg.geominfo[1].trignum << ")" - << " si = " << seg.si; - return s; - } - - Element2d :: Element2d (int anp) - { - for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) - { - pnum[i] = 0; - geominfo[i].trignum = 0; - } - np = anp; - index = 0; - badel = 0; - deleted = 0; - switch (np) - { - case 3: typ = TRIG; break; - case 4: typ = QUAD; break; - case 6: typ = TRIG6; break; - case 8: typ = QUAD8; break; - } - order = 1; - refflag = 1; - } - - Element2d :: Element2d (ELEMENT_TYPE atyp) - { - for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) - { - pnum[i] = 0; - geominfo[i].trignum = 0; - } - - SetType (atyp); - - index = 0; - badel = 0; - deleted = 0; - order = 1; - refflag = 1; - } - - - - - Element2d :: Element2d (int pi1, int pi2, int pi3) -{ - pnum[0] = pi1; - pnum[1] = pi2; - pnum[2] = pi3; - np = 3; - typ = TRIG; - pnum[3] = 0; - pnum[4] = 0; - pnum[5] = 0; - - for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) - geominfo[i].trignum = 0; - index = 0; - badel = 0; - refflag = 1; - deleted = 0; - order = 1; -} - -Element2d :: Element2d (int pi1, int pi2, int pi3, int pi4) -{ - pnum[0] = pi1; - pnum[1] = pi2; - pnum[2] = pi3; - pnum[3] = pi4; - np = 4; - typ = QUAD; - - pnum[4] = 0; - pnum[5] = 0; - - for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) - geominfo[i].trignum = 0; - index = 0; - badel = 0; - refflag = 1; - deleted = 0; - order = 1; -} - - -/* -void Element2d :: SetType (ELEMENT_TYPE atyp) -{ - typ = atyp; - switch (typ) - { - case TRIG: np = 3; break; - case QUAD: np = 4; break; - case TRIG6: np = 6; break; - case QUAD6: np = 6; break; - default: - PrintSysError ("Element2d::SetType, illegal type ", typ); - } -} -*/ - - -void Element2d :: GetBox (const T_POINTS & points, Box3d & box) const -{ - box.SetPoint (points.Get(pnum[0])); - for (unsigned i = 1; i < np; i++) - box.AddPoint (points.Get(pnum[i])); -} - -void Element2d :: Invert2() -{ - switch (typ) - { - case TRIG: - { - Swap (pnum[1], pnum[2]); - break; - } - case QUAD: - { - Swap (pnum[0], pnum[3]); - Swap (pnum[1], pnum[2]); - break; - } - default: - { - cerr << "Element2d::Invert2, illegal element type " << int(typ) << endl; - } - } -} - -int Element2d::HasFace(const Element2d& el) const -{ - //nur f�r tets!!! hannes - for (int i = 1; i <= 3; i++) - { - if (PNumMod(i) == el[0] && - PNumMod(i+1) == el[1] && - PNumMod(i+2) == el[2]) - { - return 1; - } - } - return 0; -} - -void Element2d :: NormalizeNumbering2 () -{ - if (GetNP() == 3) - { - PointIndex pi1; - if (PNum(1) < PNum(2) && PNum(1) < PNum(3)) - return; - else - { - if (PNum(2) < PNum(3)) - { - pi1 = PNum(2); - PNum(2) = PNum(3); - PNum(3) = PNum(1); - PNum(1) = pi1; - } - else - { - pi1 = PNum(3); - PNum(3) = PNum(2); - PNum(2) = PNum(1); - PNum(1) = pi1; - } - } - } - else - { - int mini = 1; - for (int i = 2; i <= GetNP(); i++) - if (PNum(i) < PNum(mini)) mini = i; - - Element2d hel = (*this); - for (int i = 1; i <= GetNP(); i++) - PNum(i) = hel.PNumMod (i+mini-1); - } -} - - - - -ARRAY<IntegrationPointData*> ipdtrig; -ARRAY<IntegrationPointData*> ipdquad; - - -int Element2d :: GetNIP () const -{ - int nip; - switch (np) - { - case 3: nip = 1; break; - case 4: nip = 4; break; - default: nip = 0; break; - } - return nip; -} - -void Element2d :: -GetIntegrationPoint (int ip, Point2d & p, double & weight) const -{ - static double eltriqp[1][3] = - { - { 1.0/3.0, 1.0/3.0, 0.5 } - }; - - static double elquadqp[4][3] = - { - { 0, 0, 0.25 }, - { 0, 1, 0.25 }, - { 1, 0, 0.25 }, - { 1, 1, 0.25 } - }; - - double * pp = 0; - switch (typ) - { - case TRIG: pp = &eltriqp[0][0]; break; - case QUAD: pp = &elquadqp[ip-1][0]; break; - default: - PrintSysError ("Element2d::GetIntegrationPoint, illegal type ", typ); - } - - p.X() = pp[0]; - p.Y() = pp[1]; - weight = pp[2]; -} - -void Element2d :: -GetTransformation (int ip, const ARRAY<Point2d> & points, - DenseMatrix & trans) const -{ - int np = GetNP(); - static DenseMatrix pmat(2, np), dshape(2, np); - pmat.SetSize (2, np); - dshape.SetSize (2, np); - - Point2d p; - double w; - - GetPointMatrix (points, pmat); - GetIntegrationPoint (ip, p, w); - GetDShape (p, dshape); - - CalcABt (pmat, dshape, trans); - - /* - (*testout) << "p = " << p << endl - << "pmat = " << pmat << endl - << "dshape = " << dshape << endl - << "tans = " << trans << endl; - */ -} - -void Element2d :: -GetTransformation (int ip, class DenseMatrix & pmat, - class DenseMatrix & trans) const -{ - int np = GetNP(); - -#ifdef DEBUG - if (pmat.Width() != np || pmat.Height() != 2) - { - (*testout) << "GetTransofrmation: pmat doesn't fit" << endl; - return; - } -#endif - - ComputeIntegrationPointData (); - DenseMatrix * dshapep; - switch (typ) - { - case TRIG: dshapep = &ipdtrig.Get(ip)->dshape; break; - case QUAD: dshapep = &ipdquad.Get(ip)->dshape; break; - default: - PrintSysError ("Element2d::GetTransformation, illegal type ", typ); - } - - CalcABt (pmat, *dshapep, trans); -} - - - -void Element2d :: GetShape (const Point2d & p, Vector & shape) const -{ - if (shape.Size() != GetNP()) - { - cerr << "Element::GetShape: Length not fitting" << endl; - return; - } - - switch (typ) - { - case TRIG: - shape.Elem(1) = 1 - p.X() - p.Y(); - shape.Elem(2) = p.X(); - shape.Elem(3) = p.Y(); - break; - case QUAD: - shape.Elem(1) = (1-p.X()) * (1-p.Y()); - shape.Elem(2) = p.X() * (1-p.Y()); - shape.Elem(3) = p.X() * p.Y(); - shape.Elem(4) = (1-p.X()) * p.Y(); - break; - default: - PrintSysError ("Element2d::GetShape, illegal type ", typ); - } -} - -void Element2d :: -GetDShape (const Point2d & p, DenseMatrix & dshape) const -{ -#ifdef DEBUG - if (dshape.Height() != 2 || dshape.Width() != np) - { - PrintSysError ("Element::DShape: Sizes don't fit"); - return; - } -#endif - - switch (typ) - { - case TRIG: - dshape.Elem(1, 1) = -1; - dshape.Elem(1, 2) = 1; - dshape.Elem(1, 3) = 0; - dshape.Elem(2, 1) = -1; - dshape.Elem(2, 2) = 0; - dshape.Elem(2, 3) = 1; - break; - case QUAD: - dshape.Elem(1, 1) = -(1-p.Y()); - dshape.Elem(1, 2) = (1-p.Y()); - dshape.Elem(1, 3) = p.Y(); - dshape.Elem(1, 4) = -p.Y(); - dshape.Elem(2, 1) = -(1-p.X()); - dshape.Elem(2, 2) = -p.X(); - dshape.Elem(2, 3) = p.X(); - dshape.Elem(2, 4) = (1-p.X()); - break; - - default: - PrintSysError ("Element2d::GetDShape, illegal type ", typ); - } -} - - -void Element2d :: -GetPointMatrix (const ARRAY<Point2d> & points, - DenseMatrix & pmat) const -{ - int np = GetNP(); - -#ifdef DEBUG - if (pmat.Width() != np || pmat.Height() != 2) - { - cerr << "Element::GetPointMatrix: sizes don't fit" << endl; - return; - } -#endif - - for (int i = 1; i <= np; i++) - { - const Point2d & p = points.Get(PNum(i)); - pmat.Elem(1, i) = p.X(); - pmat.Elem(2, i) = p.Y(); - } -} - - - - - -double Element2d :: CalcJacobianBadness (const ARRAY<Point2d> & points) const -{ - int i, j; - int nip = GetNIP(); - static DenseMatrix trans(2,2); - static DenseMatrix pmat; - - pmat.SetSize (2, GetNP()); - GetPointMatrix (points, pmat); - - double err = 0; - for (i = 1; i <= nip; i++) - { - GetTransformation (i, pmat, trans); - - // Frobenius norm - double frob = 0; - for (j = 1; j <= 4; j++) - frob += sqr (trans.Get(j)); - frob = sqrt (frob); - frob /= 2; - - double det = trans.Det(); - - if (det <= 0) - err += 1e12; - else - err += frob * frob / det; - } - - err /= nip; - return err; -} - - - -static const int qip_table[4][4] = - { { 0, 1, 0, 3 }, - { 0, 1, 1, 2 }, - { 3, 2, 0, 3 }, - { 3, 2, 1, 2 } - }; - -double Element2d :: -CalcJacobianBadnessDirDeriv (const ARRAY<Point2d> & points, - int pi, Vec2d & dir, double & dd) const -{ - if (typ == QUAD) - { - Mat<2,2> trans, dtrans; - Mat<2,4> vmat, pmat; - - for (int j = 0; j < 4; j++) - { - const Point2d & p = points.Get( (*this)[j] ); - pmat(0, j) = p.X(); - pmat(1, j) = p.Y(); - } - - vmat = 0.0; - vmat(0, pi-1) = dir.X(); - vmat(1, pi-1) = dir.Y(); - - double err = 0; - dd = 0; - - for (int i = 0; i < 4; i++) - { - int ix1 = qip_table[i][0]; - int ix2 = qip_table[i][1]; - int iy1 = qip_table[i][2]; - int iy2 = qip_table[i][3]; - - trans(0,0) = pmat(0, ix2) - pmat(0,ix1); - trans(1,0) = pmat(1, ix2) - pmat(1,ix1); - trans(0,1) = pmat(0, iy2) - pmat(0,iy1); - trans(1,1) = pmat(1, iy2) - pmat(1,iy1); - - double det = trans(0,0)*trans(1,1)-trans(1,0)*trans(0,1); - - if (det <= 0) - { - dd = 0; - return 1e12; - } - - dtrans(0,0) = vmat(0, ix2) - vmat(0,ix1); - dtrans(1,0) = vmat(1, ix2) - vmat(1,ix1); - dtrans(0,1) = vmat(0, iy2) - vmat(0,iy1); - dtrans(1,1) = vmat(1, iy2) - vmat(1,iy1); - - - // Frobenius norm - double frob = 0; - for (int j = 0; j < 4; j++) - frob += sqr (trans(j)); - frob = sqrt (frob); - - double dfrob = 0; - for (int j = 0; j < 4; j++) - dfrob += trans(j) * dtrans(j); - dfrob = dfrob / frob; - - frob /= 2; - dfrob /= 2; - - - // ddet = \sum_j det (m_j) with m_j = trans, except col j = dtrans - double ddet - = dtrans(0,0) * trans(1,1) - trans(0,1) * dtrans(1,0) - + trans(0,0) * dtrans(1,1) - dtrans(0,1) * trans(1,0); - - err += frob * frob / det; - dd += (2 * frob * dfrob * det - frob * frob * ddet) / (det * det); - } - - err /= 4; - dd /= 4; - return err; - } - - int nip = GetNIP(); - static DenseMatrix trans(2,2), dtrans(2,2); - static DenseMatrix pmat, vmat; - - pmat.SetSize (2, GetNP()); - vmat.SetSize (2, GetNP()); - - GetPointMatrix (points, pmat); - - vmat = 0.0; - vmat.Elem(1, pi) = dir.X(); - vmat.Elem(2, pi) = dir.Y(); - - - double err = 0; - dd = 0; - - for (int i = 1; i <= nip; i++) - { - GetTransformation (i, pmat, trans); - GetTransformation (i, vmat, dtrans); - - // Frobenius norm - double frob = 0; - for (int j = 1; j <= 4; j++) - frob += sqr (trans.Get(j)); - frob = sqrt (frob); - - double dfrob = 0; - for (int j = 1; j <= 4; j++) - dfrob += trans.Get(j) * dtrans.Get(j); - dfrob = dfrob / frob; - - frob /= 2; - dfrob /= 2; - - double det = trans(0,0)*trans(1,1)-trans(1,0)*trans(0,1); - - // ddet = \sum_j det (m_j) with m_j = trans, except col j = dtrans - double ddet - = dtrans(0,0) * trans(1,1) - trans(0,1) * dtrans(1,0) - + trans(0,0) * dtrans(1,1) - dtrans(0,1) * trans(1,0); - - if (det <= 0) - err += 1e12; - else - { - err += frob * frob / det; - dd += (2 * frob * dfrob * det - frob * frob * ddet) / (det * det); - } - } - - err /= nip; - dd /= nip; - return err; -} - - - -double Element2d :: -CalcJacobianBadness (const T_POINTS & points, const Vec3d & n) const -{ - int i, j; - int nip = GetNIP(); - static DenseMatrix trans(2,2); - static DenseMatrix pmat; - - pmat.SetSize (2, GetNP()); - - Vec3d t1, t2; - n.GetNormal(t1); - Cross (n, t1, t2); - - for (i = 1; i <= nip; i++) - { - const Point3d & p = points.Get(PNum(i)); - pmat.Elem(1, i) = p.X() * t1.X() + p.Y() * t1.Y() + p.Z() * t1.Z(); - pmat.Elem(2, i) = p.X() * t2.X() + p.Y() * t2.Y() + p.Z() * t2.Z(); - } - - double err = 0; - for (i = 1; i <= nip; i++) - { - GetTransformation (i, pmat, trans); - - // Frobenius norm - double frob = 0; - for (j = 1; j <= 4; j++) - frob += sqr (trans.Get(j)); - frob = sqrt (frob); - frob /= 2; - - double det = trans.Det(); - if (det <= 0) - err += 1e12; - else - err += frob * frob / det; - } - - err /= nip; - return err; -} - - - -void Element2d :: ComputeIntegrationPointData () const -{ - switch (np) - { - case 3: if (ipdtrig.Size()) return; break; - case 4: if (ipdquad.Size()) return; break; - } - - for (int i = 1; i <= GetNIP(); i++) - { - IntegrationPointData * ipd = new IntegrationPointData; - Point2d hp; - GetIntegrationPoint (i, hp, ipd->weight); - ipd->p.X() = hp.X(); - ipd->p.Y() = hp.Y(); - ipd->p.Z() = 0; - - ipd->shape.SetSize(GetNP()); - ipd->dshape.SetSize(2, GetNP()); - - GetShape (hp, ipd->shape); - GetDShape (hp, ipd->dshape); - - switch (np) - { - case 3: ipdtrig.Append (ipd); break; - case 4: ipdquad.Append (ipd); break; - } - } -} - - - - - - - - - - -ostream & operator<<(ostream & s, const Element2d & el) -{ - s << "np = " << el.GetNP(); - for (int j = 1; j <= el.GetNP(); j++) - s << " " << el.PNum(j); - return s; -} - - -ostream & operator<<(ostream & s, const Element & el) -{ - s << "np = " << el.GetNP(); - for (int j = 0; j < el.GetNP(); j++) - s << " " << int(el[j]); - return s; -} - - -Element :: Element () -{ - typ = TET; - np = 4; - for (int i = 0; i < ELEMENT_MAXPOINTS; i++) - pnum[i] = 0; - index = 0; - flags.marked = 1; - flags.badel = 0; - flags.reverse = 0; - flags.illegal = 0; - flags.illegal_valid = 0; - flags.badness_valid = 0; - flags.refflag = 1; - flags.deleted = 0; - order = 1; - partitionNumber = -1; -} - - -Element :: Element (int anp) -{ - np = anp; - int i; - for (i = 0; i < ELEMENT_MAXPOINTS; i++) - pnum[i] = 0; - index = 0; - flags.marked = 1; - flags.badel = 0; - flags.reverse = 0; - flags.illegal = 0; - flags.illegal_valid = 0; - flags.badness_valid = 0; - flags.refflag = 1; - flags.deleted = 0; - switch (np) - { - case 4: typ = TET; break; - case 5: typ = PYRAMID; break; - case 6: typ = PRISM; break; - case 8: typ = HEX; break; - case 10: typ = TET10; break; - default: cerr << "Element::Element: unknown element with " << np << " points" << endl; - } - order = 1; -} - - -Element :: Element (ELEMENT_TYPE type) -{ - SetType (type); - - int i; - for (i = 0; i < ELEMENT_MAXPOINTS; i++) - pnum[i] = 0; - index = 0; - flags.marked = 1; - flags.badel = 0; - flags.reverse = 0; - flags.illegal = 0; - flags.illegal_valid = 0; - flags.badness_valid = 0; - flags.refflag = 1; - flags.deleted = 0; - order = 1; -} - - - - - -Element & Element :: operator= (const Element & el2) -{ - typ = el2.typ; - np = el2.np; - for (int i = 0; i < ELEMENT_MAXPOINTS; i++) - pnum[i] = el2.pnum[i]; - index = el2.index; - flags = el2.flags; - order = el2.order; - hp_elnr = el2.hp_elnr; - return *this; -} - - - -void Element :: SetNP (int anp) -{ - np = anp; - switch (np) - { - case 4: typ = TET; break; - case 5: typ = PYRAMID; break; - case 6: typ = PRISM; break; - case 8: typ = HEX; break; - case 10: typ = TET10; break; - // - default: break; - cerr << "Element::SetNP unknown element with " << np << " points" << endl; - } -} - - - -void Element :: SetType (ELEMENT_TYPE atyp) -{ - typ = atyp; - switch (atyp) - { - case TET: np = 4; break; - case PYRAMID: np = 5; break; - case PRISM: np = 6; break; - case HEX: np = 8; break; - case TET10: np = 10; break; - case PRISM12: np = 12; break; - } -} - - - -void Element :: Invert() -{ - switch (GetNP()) - { - case 4: - { - Swap (PNum(3), PNum(4)); - break; - } - case 5: - { - Swap (PNum(1), PNum(4)); - Swap (PNum(2), PNum(3)); - break; - } - case 6: - { - Swap (PNum(1), PNum(4)); - Swap (PNum(2), PNum(5)); - Swap (PNum(3), PNum(6)); - break; - } - } -} - - -void Element :: Print (ostream & ost) const -{ - ost << np << " Points: "; - for (int i = 1; i <= np; i++) - ost << pnum[i-1] << " " << endl; -} - -void Element :: GetBox (const T_POINTS & points, Box3d & box) const -{ - box.SetPoint (points.Get(PNum(1))); - box.AddPoint (points.Get(PNum(2))); - box.AddPoint (points.Get(PNum(3))); - box.AddPoint (points.Get(PNum(4))); -} - -double Element :: Volume (const T_POINTS & points) const -{ - Vec3d v1 = points.Get(PNum(2)) - - points.Get(PNum(1)); - Vec3d v2 = points.Get(PNum(3)) - - points.Get(PNum(1)); - Vec3d v3 = points.Get(PNum(4)) - - points.Get(PNum(1)); - - return -(Cross (v1, v2) * v3) / 6; -} - - -void Element :: GetFace2 (int i, Element2d & face) const -{ - static const int tetfaces[][5] = - { { 3, 2, 3, 4, 0 }, - { 3, 3, 1, 4, 0 }, - { 3, 1, 2, 4, 0 }, - { 3, 2, 1, 3, 0 } }; - - static const int pyramidfaces[][5] = - { { 4, 1, 4, 3, 2 }, - { 3, 1, 2, 5, 0 }, - { 3, 2, 3, 5, 0 }, - { 3, 3, 4, 5, 0 }, - { 3, 4, 1, 5, 0 } }; - - static const int prismfaces[][5] = - { - { 3, 1, 3, 2, 0 }, - { 3, 4, 5, 6, 0 }, - { 4, 1, 2, 5, 4 }, - { 4, 2, 3, 6, 5 }, - { 4, 3, 1, 4, 6 } - }; - - switch (np) - { - case 4: // tet - case 10: // tet - { - face.SetType(TRIG); - for (int j = 1; j <= 3; j++) - face.PNum(j) = PNum(tetfaces[i-1][j]); - break; - } - case 5: // pyramid - { - // face.SetNP(pyramidfaces[i-1][0]); - face.SetType ( (i == 1) ? QUAD : TRIG); - for (int j = 1; j <= face.GetNP(); j++) - face.PNum(j) = PNum(pyramidfaces[i-1][j]); - break; - } - case 6: // prism - { - // face.SetNP(prismfaces[i-1][0]); - face.SetType ( (i >= 3) ? QUAD : TRIG); - for (int j = 1; j <= face.GetNP(); j++) - face.PNum(j) = PNum(prismfaces[i-1][j]); - break; - } - } -} - - - -void Element :: GetTets (ARRAY<Element> & locels) const -{ - GetTetsLocal (locels); - int i, j; - for (i = 1; i <= locels.Size(); i++) - for (j = 1; j <= 4; j++) - locels.Elem(i).PNum(j) = PNum ( locels.Elem(i).PNum(j) ); -} - -void Element :: GetTetsLocal (ARRAY<Element> & locels) const -{ - int i, j; - locels.SetSize(0); - switch (GetType()) - { - case TET: - { - int linels[1][4] = - { { 1, 2, 3, 4 }, - }; - for (i = 0; i < 1; i++) - { - Element tet(4); - for (j = 1; j <= 4; j++) - tet.PNum(j) = linels[i][j-1]; - locels.Append (tet); - } - break; - } - case TET10: - { - int linels[8][4] = - { { 1, 5, 6, 7 }, - { 5, 2, 8, 9 }, - { 6, 8, 3, 10 }, - { 7, 9, 10, 4 }, - { 5, 6, 7, 9 }, - { 5, 6, 9, 8 }, - { 6, 7, 9, 10 }, - { 6, 8, 10, 9 } }; - for (i = 0; i < 8; i++) - { - Element tet(4); - for (j = 1; j <= 4; j++) - tet.PNum(j) = linels[i][j-1]; - locels.Append (tet); - } - break; - } - case PYRAMID: - { - int linels[2][4] = - { { 1, 2, 3, 5 }, - { 1, 3, 4, 5 } }; - for (i = 0; i < 2; i++) - { - Element tet(4); - for (j = 1; j <= 4; j++) - tet.PNum(j) = linels[i][j-1]; - locels.Append (tet); - } - break; - } - case PRISM: - case PRISM12: - { - int linels[3][4] = - { { 1, 2, 3, 4 }, - { 4, 2, 3, 5 }, - { 6, 5, 4, 3 } - }; - for (i = 0; i < 3; i++) - { - Element tet(4); - for (j = 0; j < 4; j++) - tet[j] = linels[i][j]; - locels.Append (tet); - } - break; - } - case HEX: - { - int linels[6][4] = - { { 1, 7, 2, 3 }, - { 1, 7, 3, 4 }, - { 1, 7, 4, 8 }, - { 1, 7, 8, 5 }, - { 1, 7, 5, 6 }, - { 1, 7, 6, 2 } - }; - for (i = 0; i < 6; i++) - { - Element tet(4); - for (j = 0; j < 4; j++) - tet[j] = linels[i][j]; - locels.Append (tet); - } - break; - } - default: - { - cerr << "GetTetsLocal not implemented for el with " << GetNP() << " nodes" << endl; - } - } -} - -void Element :: GetNodesLocal (ARRAY<Point3d> & points) const -{ - const static double tetpoints[4][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }}; - - const static double prismpoints[6][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { 1, 0, 1 }, - { 0, 1, 1 } }; - - const static double pyramidpoints[6][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 } }; - - const static double tet10points[10][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { 0.5, 0, 0 }, - { 0, 0.5, 0 }, - { 0, 0, 0.5 }, - { 0.5, 0.5, 0 }, - { 0.5, 0, 0.5 }, - { 0, 0.5, 0.5 } }; - - const static double hexpoints[8][3] = - { - { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 0 }, - { 1, 0, 0 }, - { 0, 0, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 1, 0, 1 } - }; - - int np, i; - const double (*pp)[3]; - switch (GetType()) - { - case TET: - { - np = 4; - pp = tetpoints; - break; - } - case PRISM: - case PRISM12: - { - np = 6; - pp = prismpoints; - break; - } - case TET10: - { - np = 10; - pp = tet10points; - break; - } - case PYRAMID: - { - np = 5; - pp = pyramidpoints; - break; - } - case HEX: - { - np = 8; - pp = hexpoints; - break; - } - default: - { - cout << "GetNodesLocal not impelemented for element " << GetType() << endl; - np = 0; - } - } - - points.SetSize(0); - for (i = 0; i < np; i++) - points.Append (Point3d (pp[i][0], pp[i][1], pp[i][2])); -} - - - - - - - -void Element :: GetNodesLocalNew (ARRAY<Point3d> & points) const -{ - const static double tetpoints[4][3] = - { - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { 0, 0, 0 } - }; - - const static double prismpoints[6][3] = - { - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 0 }, - { 1, 0, 1 }, - { 0, 1, 1 }, - { 0, 0, 1 } - }; - - const static double pyramidpoints[6][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 } }; - - const static double tet10points[10][3] = - { { 0, 0, 0 }, - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { 0.5, 0, 0 }, - { 0, 0.5, 0 }, - { 0, 0, 0.5 }, - { 0.5, 0.5, 0 }, - { 0.5, 0, 0.5 }, - { 0, 0.5, 0.5 } }; - - const static double hexpoints[8][3] = - { - { 0, 0, 0 }, - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { 1, 0, 1 }, - { 1, 1, 1 }, - { 0, 1, 1 } - }; - - - - int np, i; - const double (*pp)[3]; - switch (GetType()) - { - case TET: - { - np = 4; - pp = tetpoints; - break; - } - case PRISM: - case PRISM12: - { - np = 6; - pp = prismpoints; - break; - } - case TET10: - { - np = 10; - pp = tet10points; - break; - } - case PYRAMID: - { - np = 5; - pp = pyramidpoints; - break; - } - case HEX: - { - np = 8; - pp = hexpoints; - break; - } - default: - { - cout << "GetNodesLocal not impelemented for element " << GetType() << endl; - np = 0; - } - } - - points.SetSize(0); - for (i = 0; i < np; i++) - points.Append (Point3d (pp[i][0], pp[i][1], pp[i][2])); -} - - - - - - - - - - - - - - - - - -void Element :: GetSurfaceTriangles (ARRAY<Element2d> & surftrigs) const -{ - static int tet4trigs[][3] = - { { 2, 3, 4 }, - { 3, 1, 4 }, - { 1, 2, 4 }, - { 2, 1, 3 } }; - - // just a few: - static int tet10trigs[][3] = - { { 2, 8, 9 }, - { 3, 10, 8}, - { 4, 9, 10 }, - { 9, 8, 10 }, - { 3, 1, 4 }, - { 1, 2, 4 }, - { 2, 1, 3 } }; - - static int pyramidtrigs[][3] = - { - { 1, 3, 2 }, - { 1, 4, 3 }, - { 1, 2, 5 }, - { 2, 3, 5 }, - { 3, 4, 5 }, - { 4, 1, 5 } - }; - - static int prismtrigs[][3] = - { - { 1, 3, 2 }, - { 4, 5, 6 }, - { 1, 2, 4 }, - { 4, 2, 5 }, - { 2, 3, 5 }, - { 5, 3, 6 }, - { 3, 1, 6 }, - { 6, 1, 4 } - }; - - static int hextrigs[][3] = - { - { 1, 3, 2 }, - { 1, 4, 3 }, - { 5, 6, 7 }, - { 5, 7, 8 }, - { 1, 2, 6 }, - { 1, 6, 5 }, - { 2, 3, 7 }, - { 2, 7, 6 }, - { 3, 4, 8 }, - { 3, 8, 7 }, - { 4, 1, 8 }, - { 1, 5, 8 } - }; - - int j; - - int nf; - int (*fp)[3]; - - switch (GetType()) - { - case TET: - { - nf = 4; - fp = tet4trigs; - break; - } - case PYRAMID: - { - nf = 6; - fp = pyramidtrigs; - break; - } - case PRISM: - case PRISM12: - { - nf = 8; - fp = prismtrigs; - break; - } - case TET10: - { - nf = 7; - fp = tet10trigs; - break; - } - case HEX: - { - nf = 12; - fp = hextrigs; - break; - } - default: - { - nf = 0; - fp = NULL; - } - } - - - surftrigs.SetSize (nf); - for (j = 0; j < nf; j++) - { - surftrigs.Elem(j+1) = Element2d(3); - surftrigs.Elem(j+1).PNum(1) = fp[j][0]; - surftrigs.Elem(j+1).PNum(2) = fp[j][1]; - surftrigs.Elem(j+1).PNum(3) = fp[j][2]; - } -} - - - - - -ARRAY<IntegrationPointData*> ipdtet; -ARRAY<IntegrationPointData*> ipdtet10; - - -int Element :: GetNIP () const -{ - int nip; - switch (typ) - { - case TET: nip = 1; break; - case TET10: nip = 8; break; - default: nip = 0; break; - } - return nip; -} - -void Element :: -GetIntegrationPoint (int ip, Point3d & p, double & weight) const -{ - static double eltetqp[1][4] = - { - { 0.25, 0.25, 0.25, 1.0/6.0 } - }; - - static double eltet10qp[8][4] = - { - { 0.585410196624969, 0.138196601125011, 0.138196601125011, 1.0/24.0 }, - { 0.138196601125011, 0.585410196624969, 0.138196601125011, 1.0/24.0 }, - { 0.138196601125011, 0.138196601125011, 0.585410196624969, 1.0/24.0 }, - { 0.138196601125011, 0.138196601125011, 0.138196601125011, 1.0/24.0 }, - { 1, 0, 0, 1 }, - { 0, 1, 0, 1 }, - { 0, 0, 1, 1 }, - { 0, 0, 0, 1 }, - }; - - double * pp; - switch (typ) - { - case TET: pp = &eltetqp[0][0]; break; - case TET10: pp = &eltet10qp[ip-1][0]; break; - } - - p.X() = pp[0]; - p.Y() = pp[1]; - p.Z() = pp[2]; - weight = pp[3]; -} - -void Element :: -GetTransformation (int ip, const T_POINTS & points, - DenseMatrix & trans) const -{ - int np = GetNP(); - static DenseMatrix pmat(3, np), dshape(3, np); - pmat.SetSize (3, np); - dshape.SetSize (3, np); - - Point3d p; - double w; - - GetPointMatrix (points, pmat); - GetIntegrationPoint (ip, p, w); - GetDShape (p, dshape); - - CalcABt (pmat, dshape, trans); - - /* - (*testout) << "p = " << p << endl - << "pmat = " << pmat << endl - << "dshape = " << dshape << endl - << "tans = " << trans << endl; - */ -} - -void Element :: -GetTransformation (int ip, class DenseMatrix & pmat, - class DenseMatrix & trans) const -{ - int np = GetNP(); - - if (pmat.Width() != np || pmat.Height() != 3) - { - (*testout) << "GetTransofrmation: pmat doesn't fit" << endl; - return; - } - - ComputeIntegrationPointData (); - DenseMatrix * dshapep; - switch (GetType()) - { - case TET: dshapep = &ipdtet.Get(ip)->dshape; break; - case TET10: dshapep = &ipdtet10.Get(ip)->dshape; break; - } - - CalcABt (pmat, *dshapep, trans); -} - - - -void Element :: GetShape (const Point3d & p, Vector & shape) const -{ - if (shape.Size() != GetNP()) - { - cerr << "Element::GetShape: Length not fitting" << endl; - return; - } - - switch (typ) - { - case TET: - { - shape.Elem(1) = 1 - p.X() - p.Y() - p.Z(); - shape.Elem(2) = p.X(); - shape.Elem(3) = p.Y(); - shape.Elem(4) = p.Z(); - break; - } - case TET10: - { - double lam1 = 1 - p.X() - p.Y() - p.Z(); - double lam2 = p.X(); - double lam3 = p.Y(); - double lam4 = p.Z(); - - shape.Elem(5) = 4 * lam1 * lam2; - shape.Elem(6) = 4 * lam1 * lam3; - shape.Elem(7) = 4 * lam1 * lam4; - shape.Elem(8) = 4 * lam2 * lam3; - shape.Elem(9) = 4 * lam2 * lam4; - shape.Elem(10) = 4 * lam3 * lam4; - - shape.Elem(1) = lam1 - - 0.5 * (shape.Elem(5) + shape.Elem(6) + shape.Elem(7)); - shape.Elem(2) = lam2 - - 0.5 * (shape.Elem(5) + shape.Elem(8) + shape.Elem(9)); - shape.Elem(3) = lam3 - - 0.5 * (shape.Elem(6) + shape.Elem(8) + shape.Elem(10)); - shape.Elem(4) = lam4 - - 0.5 * (shape.Elem(7) + shape.Elem(9) + shape.Elem(10)); - break; - } - - case PRISM: - { - Point<3> hp = p; - shape(0) = hp(0) * (1-hp(2)); - shape(1) = hp(1) * (1-hp(2)); - shape(2) = (1-hp(0)-hp(1)) * (1-hp(2)); - shape(3) = hp(0) * hp(2); - shape(4) = hp(1) * hp(2); - shape(5) = (1-hp(0)-hp(1)) * hp(2); - break; - } - case HEX: - { - Point<3> hp = p; - shape(0) = (1-hp(0))*(1-hp(1))*(1-hp(2)); - shape(1) = ( hp(0))*(1-hp(1))*(1-hp(2)); - shape(2) = ( hp(0))*( hp(1))*(1-hp(2)); - shape(3) = (1-hp(0))*( hp(1))*(1-hp(2)); - shape(4) = (1-hp(0))*(1-hp(1))*( hp(2)); - shape(5) = ( hp(0))*(1-hp(1))*( hp(2)); - shape(6) = ( hp(0))*( hp(1))*( hp(2)); - shape(7) = (1-hp(0))*( hp(1))*( hp(2)); - break; - } - } -} - - -void Element :: GetShapeNew (const Point<3> & p, FlatVector & shape) const -{ - /* - if (shape.Size() < GetNP()) - { - cerr << "Element::GetShape: Length not fitting" << endl; - return; - } - */ - - switch (typ) - { - case TET: - { - shape(0) = p(0); - shape(1) = p(1); - shape(2) = p(2); - shape(3) = 1-p(0)-p(1)-p(2); - break; - } - - case PYRAMID: - { - double noz = 1-p(2); - if (noz == 0.0) noz = 1e-10; - - double xi = p(0) / noz; - double eta = p(1) / noz; - shape(0) = (1-xi)*(1-eta) * (noz); - shape(1) = ( xi)*(1-eta) * (noz); - shape(2) = ( xi)*( eta) * (noz); - shape(3) = (1-xi)*( eta) * (noz); - shape(4) = p(2); - break; - } - - case PRISM: - { - shape(0) = p(0) * (1-p(2)); - shape(1) = p(1) * (1-p(2)); - shape(2) = (1-p(0)-p(1)) * (1-p(2)); - shape(3) = p(0) * p(2); - shape(4) = p(1) * p(2); - shape(5) = (1-p(0)-p(1)) * p(2); - break; - } - case HEX: - { - shape(0) = (1-p(0))*(1-p(1))*(1-p(2)); - shape(1) = ( p(0))*(1-p(1))*(1-p(2)); - shape(2) = ( p(0))*( p(1))*(1-p(2)); - shape(3) = (1-p(0))*( p(1))*(1-p(2)); - shape(4) = (1-p(0))*(1-p(1))*( p(2)); - shape(5) = ( p(0))*(1-p(1))*( p(2)); - shape(6) = ( p(0))*( p(1))*( p(2)); - shape(7) = (1-p(0))*( p(1))*( p(2)); - break; - } - } -} - - - - -void Element :: -GetDShape (const Point3d & p, DenseMatrix & dshape) const -{ - int np = GetNP(); - if (dshape.Height() != 3 || dshape.Width() != np) - { - cerr << "Element::DShape: Sizes don't fit" << endl; - return; - } - - int i, j; - double eps = 1e-6; - Vector shaper(np), shapel(np); - - for (i = 1; i <= 3; i++) - { - Point3d pr(p), pl(p); - pr.X(i) += eps; - pl.X(i) -= eps; - - GetShape (pr, shaper); - GetShape (pl, shapel); - for (j = 1; j <= np; j++) - dshape.Elem(i, j) = (shaper.Get(j) - shapel.Get(j)) / (2 * eps); - } -} - - - -void Element :: -GetDShapeNew (const Point<3> & p, MatrixFixWidth<3> & dshape) const -{ - switch (typ) - { - case TET: - { - dshape = 0; - dshape(0,0) = 1; - dshape(1,1) = 1; - dshape(2,2) = 1; - dshape(3,0) = -1; - dshape(3,1) = -1; - dshape(3,2) = -1; - break; - } - case PRISM: - { - dshape = 0; - dshape(0,0) = 1-p(2); - dshape(0,2) = -p(0); - dshape(1,1) = 1-p(2); - dshape(1,2) = -p(1); - dshape(2,0) = -(1-p(2)); - dshape(2,1) = -(1-p(2)); - dshape(2,2) = -(1-p(0)-p(1)); - - dshape(3,0) = p(2); - dshape(3,2) = p(0); - dshape(4,1) = p(2); - dshape(4,2) = p(1); - dshape(5,0) = -p(2); - dshape(5,1) = -p(2); - dshape(5,2) = 1-p(0)-p(1); - break; - } - - default: - { - int np = GetNP(); - double eps = 1e-6; - Vector shaper(np), shapel(np); - - for (int i = 1; i <= 3; i++) - { - Point3d pr(p), pl(p); - pr.X(i) += eps; - pl.X(i) -= eps; - - GetShapeNew (pr, shaper); - GetShapeNew (pl, shapel); - for (int j = 1; j <= np; j++) - dshape.Elem(j, i) = (shaper.Get(j) - shapel.Get(j)) / (2 * eps); - } - } - } -} - -void Element :: -GetPointMatrix (const T_POINTS & points, - DenseMatrix & pmat) const -{ - int np = GetNP(); - /* - if (pmat.Width() != np || pmat.Height() != 3) - { - cerr << "Element::GetPointMatrix: sizes don't fit" << endl; - return; - } - */ - for (int i = 1; i <= np; i++) - { - const Point3d & p = points.Get(PNum(i)); - pmat.Elem(1, i) = p.X(); - pmat.Elem(2, i) = p.Y(); - pmat.Elem(3, i) = p.Z(); - } -} - - - - - - -double Element :: CalcJacobianBadness (const T_POINTS & points) const -{ - int i, j; - int nip = GetNIP(); - static DenseMatrix trans(3,3); - static DenseMatrix pmat; - - pmat.SetSize (3, GetNP()); - GetPointMatrix (points, pmat); - - double err = 0; - for (i = 1; i <= nip; i++) - { - GetTransformation (i, pmat, trans); - - // Frobenius norm - double frob = 0; - for (j = 1; j <= 9; j++) - frob += sqr (trans.Get(j)); - frob = sqrt (frob); - frob /= 3; - - double det = -trans.Det(); - - if (det <= 0) - err += 1e12; - else - err += frob * frob * frob / det; - } - - err /= nip; - return err; -} - -double Element :: -CalcJacobianBadnessDirDeriv (const T_POINTS & points, - int pi, Vec3d & dir, double & dd) const -{ - int i, j, k, l; - int nip = GetNIP(); - static DenseMatrix trans(3,3), dtrans(3,3), hmat(3,3); - static DenseMatrix pmat, vmat; - - pmat.SetSize (3, GetNP()); - vmat.SetSize (3, GetNP()); - - GetPointMatrix (points, pmat); - - for (i = 1; i <= np; i++) - for (j = 1; j <= 3; j++) - vmat.Elem(j, i) = 0; - for (j = 1; j <= 3; j++) - vmat.Elem(j, pi) = dir.X(j); - - - - double err = 0; - dd = 0; - - for (i = 1; i <= nip; i++) - { - GetTransformation (i, pmat, trans); - GetTransformation (i, vmat, dtrans); - - - // Frobenius norm - double frob = 0; - for (j = 1; j <= 9; j++) - frob += sqr (trans.Get(j)); - frob = sqrt (frob); - - double dfrob = 0; - for (j = 1; j <= 9; j++) - dfrob += trans.Get(j) * dtrans.Get(j); - dfrob = dfrob / frob; - - frob /= 3; - dfrob /= 3; - - - double det = trans.Det(); - double ddet = 0; - - for (j = 1; j <= 3; j++) - { - hmat = trans; - for (k = 1; k <= 3; k++) - hmat.Elem(k, j) = dtrans.Get(k, j); - ddet += hmat.Det(); - } - - - det *= -1; - ddet *= -1; - - - if (det <= 0) - err += 1e12; - else - { - err += frob * frob * frob / det; - dd += (3 * frob * frob * dfrob * det - frob * frob * frob * ddet) / (det * det); - } - } - - err /= nip; - dd /= nip; - return err; -} - - - - - -void Element :: ComputeIntegrationPointData () const -{ - switch (GetType()) - { - case TET: if (ipdtet.Size()) return; break; - case TET10: if (ipdtet10.Size()) return; break; - default: - PrintSysError ("Element::ComputeIntegrationPoint, illegal type ", int(typ)); - } - - int i; - for (i = 1; i <= GetNIP(); i++) - { - IntegrationPointData * ipd = new IntegrationPointData; - GetIntegrationPoint (i, ipd->p, ipd->weight); - ipd->shape.SetSize(GetNP()); - ipd->dshape.SetSize(3, GetNP()); - - GetShape (ipd->p, ipd->shape); - GetDShape (ipd->p, ipd->dshape); - - switch (GetType()) - { - case TET: ipdtet.Append (ipd); break; - case TET10: ipdtet10.Append (ipd); break; - default: - PrintSysError ("Element::ComputeIntegrationPoint(2), illegal type ", int(typ)); - } - } -} - - - - - - - - -FaceDescriptor :: FaceDescriptor() -{ - surfnr = domin = domout = bcprop = 0; - domin_singular = domout_singular = 0; - tlosurf = -1; -} - -FaceDescriptor :: -FaceDescriptor(int surfnri, int domini, int domouti, int tlosurfi) -{ - surfnr = surfnri; - domin = domini; - domout = domouti; - tlosurf = tlosurfi; - bcprop = surfnri; - domin_singular = domout_singular = 0; -} - -FaceDescriptor :: FaceDescriptor(const Segment & seg) -{ - surfnr = seg.si; - domin = seg.domin+1; - domout = seg.domout+1; - tlosurf = seg.tlosurf+1; - bcprop = 0; - domin_singular = domout_singular = 0; -} - -int FaceDescriptor :: SegmentFits (const Segment & seg) -{ - return - surfnr == seg.si && - domin == seg.domin+1 && - domout == seg.domout+1 && - tlosurf == seg.tlosurf+1; -} - - -ostream & operator<<(ostream & s, const FaceDescriptor & fd) -{ - s << "surfnr = " << fd.surfnr - << ", domin = " << fd.domin - << ", domout = " << fd.domout - << ", tlosurf = " << fd.tlosurf - << ", bcprop = " << fd.bcprop - << ", domin_sing = " << fd.domin_singular - << ", domout_sing = " << fd.domout_singular; - return s; -} - - - - - - -Identifications :: Identifications (Mesh & amesh) - : mesh(amesh) -{ - identifiedpoints = new INDEX_2_HASHTABLE<int>(100); - maxidentnr = 0; -} - -Identifications :: ~Identifications () -{ - delete identifiedpoints; -} - -void Identifications :: Delete () -{ - delete identifiedpoints; - identifiedpoints = new INDEX_2_HASHTABLE<int>(100); - maxidentnr = 0; -} - -void Identifications :: Add (PointIndex pi1, PointIndex pi2, int identnr) -{ - INDEX_2 pair (pi1, pi2); - identifiedpoints->Set (pair, identnr); - if (identnr > maxidentnr) maxidentnr = identnr; - // timestamp = NextTimeStamp(); -} - -int Identifications :: Get (PointIndex pi1, PointIndex pi2) const -{ - INDEX_2 pair(pi1, pi2); - if (identifiedpoints->Used (pair)) - return identifiedpoints->Get(pair); - else - return 0; -} - -int Identifications :: GetSymmetric (PointIndex pi1, PointIndex pi2) const -{ - INDEX_2 pair(pi1, pi2); - if (identifiedpoints->Used (pair)) - return identifiedpoints->Get(pair); - - pair = INDEX_2 (pi2, pi1); - if (identifiedpoints->Used (pair)) - return identifiedpoints->Get(pair); - - return 0; -} - - -void Identifications :: GetMap (int identnr, ARRAY<int,PointIndex::BASE> & identmap) const -{ - identmap.SetSize (mesh.GetNP()); - identmap = 0; - - for (int i = 1; i <= identifiedpoints->GetNBags(); i++) - for (int j = 1; j <= identifiedpoints->GetBagSize(i); j++) - { - INDEX_2 i2; - int nr; - identifiedpoints->GetData (i, j, i2, nr); - - if (nr == identnr || !identnr) - identmap.Elem(i2.I1()) = i2.I2(); - } -} - - -void Identifications :: GetPairs (int identnr, - ARRAY<INDEX_2> & identpairs) const -{ - int i, j; - - identpairs.SetSize(0); - - for (i = 1; i <= identifiedpoints->GetNBags(); i++) - for (j = 1; j <= identifiedpoints->GetBagSize(i); j++) - { - INDEX_2 i2; - int nr; - identifiedpoints->GetData (i, j, i2, nr); - - if (identnr == 0 || nr == identnr) - identpairs.Append (i2); - } -} - - -void Identifications :: SetMaxPointNr (int maxpnum) -{ - for (int i = 1; i <= identifiedpoints->GetNBags(); i++) - for (int j = 1; j <= identifiedpoints->GetBagSize(i); j++) - { - INDEX_2 i2; - int nr; - identifiedpoints->GetData (i, j, i2, nr); - - if (i2.I1() > maxpnum || i2.I2() > maxpnum) - { - i2.I1() = i2.I2() = -1; - identifiedpoints->SetData (i, j, i2, -1); - } - } -} - - - - - -MeshingParameters :: MeshingParameters () -{ - optimize3d = "cmdmstm"; - optsteps3d = 3; - optimize2d = "smsmsmSmSmSm"; - optsteps2d = 3; - opterrpow = 2; - blockfill = 1; - filldist = 0.1; - safety = 5; - relinnersafety = 3; - uselocalh = 1; - grading = 0.3; - delaunay = 1; - maxh = 1e10; - meshsizefilename = NULL; - startinsurface = 0; - checkoverlap = 1; - checkchartboundary = 1; - curvaturesafety = 2; - segmentsperedge = 1; - parthread = 0; - - elsizeweight = 0.2; - giveuptol = 10; - maxoutersteps = 5; - starshapeclass = 5; - baseelnp = 0; - sloppy = 1; - - badellimit = 175; - secondorder = 0; -} - -void MeshingParameters :: Print (ostream & ost) const -{ - ost << "Meshing parameters: " << endl - << "optimize3d = " << optimize3d << endl - << "optsteps3d = " << optsteps3d << endl - << " optimize2d = " << optimize2d << endl - << " optsteps2d = " << optsteps2d << endl - << " opterrpow = " << opterrpow << endl - << " blockfill = " << blockfill << endl - << " filldist = " << filldist << endl - << " safety = " << safety << endl - << " relinnersafety = " << relinnersafety << endl - << " uselocalh = " << uselocalh << endl - << " grading = " << grading << endl - << " delaunay = " << delaunay << endl - << " maxh = " << maxh << endl; - if(meshsizefilename) - ost << " meshsizefilename = " << meshsizefilename << endl; - else - ost << " meshsizefilename = NULL" << endl; - ost << " startinsurface = " << startinsurface << endl - << " checkoverlap = " << checkoverlap << endl - << " checkchartboundary = " << checkchartboundary << endl - << " curvaturesafety = " << curvaturesafety << endl - << " segmentsperedge = " << segmentsperedge << endl - << " parthread = " << parthread << endl - << " elsizeweight = " << elsizeweight << endl - << " giveuptol = " << giveuptol << endl - << " maxoutersteps = " << maxoutersteps << endl - << " starshapeclass = " << starshapeclass << endl - << " baseelnp = " << baseelnp << endl - << " sloppy = " << sloppy << endl - << " badellimit = " << badellimit << endl - << " secondorder = " << secondorder << endl - << " elementorder = " << elementorder << endl - << " quad = " << quad << endl - << " inverttets = " << inverttets << endl - << " inverttrigs = " << inverttrigs << endl; -} - -void MeshingParameters :: CopyFrom(const MeshingParameters & other) -{ - //strcpy(optimize3d,other.optimize3d); - optimize3d = other.optimize3d; - optsteps3d = other.optsteps3d; - //strcpy(optimize2d,other.optimize2d); - optimize2d = other.optimize2d; - optsteps2d = other.optsteps2d; - opterrpow = other.opterrpow; - blockfill = other.blockfill; - filldist = other.filldist; - safety = other.safety; - relinnersafety = other.relinnersafety; - uselocalh = other.uselocalh; - grading = other.grading; - delaunay = other.delaunay; - maxh = other.maxh; - //strcpy(const_cast<char*>(meshsizefilename), other.meshsizefilename); - //const_cast<char*>(meshsizefilename) = other.meshsizefilename; //??? - startinsurface = other.startinsurface; - checkoverlap = other.checkoverlap; - checkchartboundary = other.checkchartboundary; - curvaturesafety = other.curvaturesafety; - segmentsperedge = other.segmentsperedge; - parthread = other.parthread; - elsizeweight = other.elsizeweight; - giveuptol = other.giveuptol; - maxoutersteps = other.maxoutersteps; - starshapeclass = other.starshapeclass; - baseelnp = other.baseelnp; - sloppy = other.sloppy; - badellimit = other.badellimit; - secondorder = other.secondorder; - elementorder = other.elementorder; - quad = other.quad; - inverttets = other.inverttets; - inverttrigs = other.inverttrigs; -} - - -DebugParameters :: DebugParameters () -{ - slowchecks = 0; - haltsuccess = 0; - haltnosuccess = 0; - haltlargequalclass = 0; - haltsegment = 0; - haltsegmentp1 = 0; - haltsegmentp2 = 0; -} - - - -} diff --git a/Netgen/libsrc/meshing/meshtype.hpp b/Netgen/libsrc/meshing/meshtype.hpp deleted file mode 100644 index 363efd3226..0000000000 --- a/Netgen/libsrc/meshing/meshtype.hpp +++ /dev/null @@ -1,1025 +0,0 @@ -#ifndef MESHTYPE -#define MESHTYPE - -//#include <algorithm> - -/**************************************************************************/ -/* File: meshtype.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Okt. 95 */ -/**************************************************************************/ - -/* - Classes for NETGEN -*/ - - -enum ELEMENT_TYPE { - SEGMENT = 1, SEGMENT3 = 2, - TRIG = 10, QUAD=11, TRIG6 = 12, QUAD6 = 13, QUAD8 = 14, - TET = 20, TET10 = 21, - PYRAMID = 22, PRISM = 23, PRISM12 = 24, - HEX = 25 -}; - -typedef int ELEMENT_EDGE[2]; // initial point, end point -typedef int ELEMENT_FACE[4]; // points, last one is -1 for trig - - -#define ELEMENT_MAXPOINTS 12 -#define ELEMENT2D_MAXPOINTS 8 - - -enum POINTTYPE { FIXEDPOINT = 1, EDGEPOINT = 2, SURFACEPOINT = 3, INNERPOINT = 4 }; -enum ELEMENTTYPE { FREEELEMENT, FIXEDELEMENT }; -enum OPTIMIZEGOAL { OPT_QUALITY, OPT_CONFORM, OPT_REST, OPT_WORSTCASE, OPT_LEGAL }; - - -class Mesh; // Added by Christophe for Gmsh (ISO C++ forbids declaration of 'Mesh' with no type) - -// class CSGeometry; - -extern int GetTimeStamp(); -extern int NextTimeStamp(); - -class PointGeomInfo -{ -public: - int trignum; // for STL Meshing - double u, v; // for OCC Meshing - - PointGeomInfo () - : trignum(-1), u(0), v(0) { ; } -}; - -inline ostream & operator<< (ostream & ost, const PointGeomInfo & gi) -{ - return (ost << gi.trignum); -} - - - -#define MULTIPOINTGEOMINFO_MAX 100 -class MultiPointGeomInfo -{ - int cnt; - PointGeomInfo mgi[MULTIPOINTGEOMINFO_MAX]; -public: - MultiPointGeomInfo (); - int AddPointGeomInfo (const PointGeomInfo & gi); - void Init (); - void DeleteAll (); - - int GetNPGI () const { return cnt; } - const PointGeomInfo & GetPGI (int i) const { return mgi[i-1]; } -}; - - -class EdgePointGeomInfo -{ -public: - int edgenr; - double dist; - double u, v; // for OCC Meshing - - EdgePointGeomInfo () - : edgenr(0), dist(0.0), u(0.0), v(0.0) { ; } - - EdgePointGeomInfo & operator= (const EdgePointGeomInfo & gi2) - { - edgenr = gi2.edgenr; dist = gi2.dist; - u = gi2.u; v = gi2.v; - return *this; - } -}; - -inline ostream & operator<< (ostream & ost, const EdgePointGeomInfo & gi) -{ - return (ost << gi.edgenr); -} - - - - - -class PointIndex -{ - int i; -public: - PointIndex () { ; } - PointIndex (int ai) : i(ai) { ; } - PointIndex & operator= (const PointIndex &ai) { i = ai.i; return *this; } - PointIndex & operator= (int ai) { i = ai; return *this; } - operator int () const { return i; } - int GetInt () const { return i; } - PointIndex operator++ (int) { int hi = i; i++; return hi; } - PointIndex operator-- (int) { int hi = i; i--; return hi; } - -#ifdef BASE0 - enum { BASE = 0 }; -#else - enum { BASE = 1 }; -#endif -}; - -inline istream & operator>> (istream & ist, PointIndex & pi) -{ - int i; ist >> i; pi = i; return ist; -} - -inline ostream & operator<< (ostream & ost, const PointIndex & pi) -{ - return (ost << pi.GetInt()); -} - - - - -class ElementIndex -{ - int i; -public: - ElementIndex () { ; } - ElementIndex (int ai) : i(ai) { ; } - ElementIndex & operator= (const ElementIndex & ai) { i = ai.i; return *this; } - ElementIndex & operator= (int ai) { i = ai; return *this; } - operator int () const { return i; } - ElementIndex & operator++ (int) { i++; return *this; } - ElementIndex & operator-- (int) { i--; return *this; } -}; - -inline istream & operator>> (istream & ist, ElementIndex & pi) -{ - int i; ist >> i; pi = i; return ist; -} - -inline ostream & operator<< (ostream & ost, const ElementIndex & pi) -{ - return (ost << int(pi)); -} - - -class SurfaceElementIndex -{ - int i; -public: - SurfaceElementIndex () { ; } - SurfaceElementIndex (int ai) : i(ai) { ; } - SurfaceElementIndex & operator= (const SurfaceElementIndex & ai) - { i = ai.i; return *this; } - SurfaceElementIndex & operator= (int ai) { i = ai; return *this; } - operator int () const { return i; } - SurfaceElementIndex & operator++ (int) { i++; return *this; } - SurfaceElementIndex & operator-- (int) { i--; return *this; } -}; - -inline istream & operator>> (istream & ist, SurfaceElementIndex & pi) -{ - int i; ist >> i; pi = i; return ist; -} - -inline ostream & operator<< (ostream & ost, const SurfaceElementIndex & pi) -{ - return (ost << int(pi)); -} - -class SegmentIndex -{ - int i; -public: - SegmentIndex () { ; } - SegmentIndex (int ai) : i(ai) { ; } - SegmentIndex & operator= (const SegmentIndex & ai) - { i = ai.i; return *this; } - SegmentIndex & operator= (int ai) { i = ai; return *this; } - operator int () const { return i; } - SegmentIndex & operator++ (int) { i++; return *this; } - SegmentIndex & operator-- (int) { i--; return *this; } -}; - -inline istream & operator>> (istream & ist, SegmentIndex & pi) -{ - int i; ist >> i; pi = i; return ist; -} - -inline ostream & operator<< (ostream & ost, const SegmentIndex & pi) -{ - return (ost << int(pi)); -} - - - - -/** - Point in the mesh. - Contains layer (a new feature in 4.3 for overlapping meshes. - will contain pointtype - */ -class MeshPoint : public Point3d -{ - int layer; - bool singular; - POINTTYPE type; -public: - MeshPoint () : layer(1), singular(0), type(INNERPOINT) { ; } - MeshPoint (const Point3d & ap, int alayer = 1, POINTTYPE apt = INNERPOINT) - : Point3d (ap), layer(alayer), singular(0), type(apt) { ; } - - void SetPoint (const Point3d & ap) - { Point3d::operator= (ap); } - int GetLayer() const { return layer; } - - bool IsSingular() const { return singular; } - void SetSingular(bool s = 1) { singular = s; } - - POINTTYPE Type() const { return type; } - void SetType(POINTTYPE at) { type = at; } -}; - - - -// typedef MoveableArray<MeshPoint> T_POINTS; -typedef ARRAY<MeshPoint,PointIndex::BASE> T_POINTS; - - -class Element2d; -ostream & operator<<(ostream & s, const Element2d & el); - -/** - Triangle element for surface mesh generation. - */ -class Element2d -{ - /// point numbers - PointIndex pnum[ELEMENT2D_MAXPOINTS]; - /// geom info of corner points - PointGeomInfo geominfo[ELEMENT2D_MAXPOINTS]; - - /// surface nr - int index:16; - /// - ELEMENT_TYPE typ:6; - /// number of points - unsigned int np:4; - bool badel:1; - bool refflag:1; // marked for refinement - bool deleted:1; // element is deleted - - /// order for hp-FEM - unsigned int order:6; - - -public: - /// - Element2d (int anp = 3); - /// - Element2d (ELEMENT_TYPE type); - /// - Element2d (int pi1, int pi2, int pi3); - /// - Element2d (int pi1, int pi2, int pi3, int pi4); - /// - ELEMENT_TYPE GetType () const { return typ; } - /// - void SetType (ELEMENT_TYPE atyp) - { - typ = atyp; - switch (typ) - { - case TRIG: np = 3; break; - case QUAD: np = 4; break; - case TRIG6: np = 6; break; - case QUAD6: np = 6; break; - case QUAD8: np = 8; break; - default: - PrintSysError ("Element2d::SetType, illegal type ", typ); - } - } - /// - int GetNP() const { return np; } - /// - int GetNV() const - { - switch (typ) - { - case TRIG: - case TRIG6: return 3; - - case QUAD: - case QUAD8: - case QUAD6: return 4; - default: -#ifdef DEBUG - PrintSysError ("element2d::GetNV not implemented for typ", typ) -#endif - ; - } - return np; - } - - /// - PointIndex & operator[] (int i) { return pnum[i]; } - /// - const PointIndex & operator[] (int i) const { return pnum[i]; } - - /// - PointIndex & PNum (int i) { return pnum[i-1]; } - /// - const PointIndex & PNum (int i) const { return pnum[i-1]; } - /// - PointIndex & PNumMod (int i) { return pnum[(i-1) % np]; } - /// - const PointIndex & PNumMod (int i) const { return pnum[(i-1) % np]; } - /// - - /// - PointGeomInfo & GeomInfoPi (int i) { return geominfo[i-1]; } - /// - const PointGeomInfo & GeomInfoPi (int i) const { return geominfo[i-1]; } - /// - PointGeomInfo & GeomInfoPiMod (int i) { return geominfo[(i-1) % np]; } - /// - const PointGeomInfo & GeomInfoPiMod (int i) const { return geominfo[(i-1) % np]; } - - - void SetIndex (int si) { index = si; } - /// - int GetIndex () const { return index; } - - int GetOrder () const { return order; } - void SetOrder (int aorder) { order = aorder; } - - /// - void GetBox (const T_POINTS & points, Box3d & box) const; - /// invert orientation - inline void Invert (); - /// - void Invert2 (); - /// first point number is smallest - inline void NormalizeNumbering (); - /// - void NormalizeNumbering2 (); - - bool BadElement() const { return badel; } - - friend ostream & operator<<(ostream & s, const Element2d & el); - friend class Mesh; - - - /// get number of 'integration points' - int GetNIP () const; - void GetIntegrationPoint (int ip, Point2d & p, double & weight) const; - void GetTransformation (int ip, const ARRAY<Point2d> & points, - class DenseMatrix & trans) const; - void GetTransformation (int ip, class DenseMatrix & pmat, - class DenseMatrix & trans) const; - - void GetShape (const Point2d & p, class Vector & shape) const; - /// matrix 2 * np - void GetDShape (const Point2d & p, class DenseMatrix & dshape) const; - /// matrix 2 * np - void GetPointMatrix (const ARRAY<Point2d> & points, - class DenseMatrix & pmat) const; - - void ComputeIntegrationPointData () const; - - - double CalcJacobianBadness (const ARRAY<Point2d> & points) const; - double CalcJacobianBadness (const T_POINTS & points, - const Vec3d & n) const; - double CalcJacobianBadnessDirDeriv (const ARRAY<Point2d> & points, - int pi, Vec2d & dir, double & dd) const; - - - - void Delete () { deleted = 1; pnum[0] = pnum[1] = pnum[2] = pnum[3] = PointIndex::BASE-1; } - bool IsDeleted () const - { -#ifdef DEBUG - if (pnum[0] < PointIndex::BASE && !deleted) - cerr << "Surfelement has illegal pnum, but not marked as deleted" << endl; -#endif - return deleted; - } - - void SetRefinementFlag (bool rflag = 1) - { refflag = rflag; } - bool TestRefinementFlag () const - { return refflag; } - - int HasFace(const Element2d& el) const; - /// - int meshdocval; - /// - int hp_elnr; -}; - - - - -class IntegrationPointData -{ -public: - Point3d p; - double weight; - Vector shape; - DenseMatrix dshape; -}; - - - - -class Element; -ostream & operator<<(ostream & s, const Element & el); - - - -/** - Volume element - */ -class Element -{ -private: - /// point numbers - PointIndex pnum[ELEMENT_MAXPOINTS]; - /// - ELEMENT_TYPE typ:6; - /// number of points (4..tet, 5..pyramid, 6..prism, 8..hex, 10..quad tet, 12..quad prism) - int np:5; - /// - class flagstruct { - public: - bool marked:1; // marked for refinement - bool badel:1; // angles worse then limit - bool reverse:1; // for refinement a la Bey - bool illegal:1; // illegal, will be split or swaped - bool illegal_valid:1; // is illegal-flag valid ? - bool badness_valid:1; // is badness valid ? - bool refflag:1; // mark element for refinement - bool deleted:1; // element is deleted, will be removed from array - }; - /// surface or sub-domain index - short int index; - /// order for hp-FEM - unsigned int order:6; - /// stored shape-badness of element - float badness; - /// number of partition for parallel compution - short int partitionNumber; - /// - -public: - flagstruct flags; - - /// - Element (); - /// - Element (int anp); - /// - Element (ELEMENT_TYPE type); - /// - Element & operator= (const Element & el2); - - /// - void SetNP (int anp); - /// - void SetType (ELEMENT_TYPE atyp); - /// - int GetNP () const { return np; } - /// - int GetNV() const - { - switch (typ) - { - case TET: return 4; - case TET10: return 4; - case PRISM12: return 6; - case PRISM: return 6; //SZ - default: -#ifdef DEBUG - PrintSysError ("Element3d::GetNV not implemented for typ ", typ) -#endif - ; - } - return np; - } - // old style: - int NP () const { return np; } - - /// - ELEMENT_TYPE GetType () const { return typ; } - - /// - PointIndex & operator[] (int i) { return pnum[i]; } - /// - const PointIndex & operator[] (int i) const { return pnum[i]; } - - /// - PointIndex & PNum (int i) { return pnum[i-1]; } - /// - const PointIndex & PNum (int i) const { return pnum[i-1]; } - /// - PointIndex & PNumMod (int i) { return pnum[(i-1) % np]; } - /// - const PointIndex & PNumMod (int i) const { return pnum[(i-1) % np]; } - - /// - void SetIndex (int si) { index = si; } - /// - int GetIndex () const { return index; } - - int GetOrder () const { return order; } - void SetOrder (int aorder) { order = aorder; } - - /// - void GetBox (const T_POINTS & points, Box3d & box) const; - /// Calculates Volume of elemenet - double Volume (const T_POINTS & points) const; - /// - virtual void Print (ostream & ost) const; - /// - int GetNFaces () const - { - switch (typ) - { - case TET: - case TET10: return 4; - case PYRAMID: return 5; - case PRISM: - case PRISM12: return 5; - default: -#ifdef DEBUG - PrintSysError ("element3d::GetNFaces not implemented for typ", typ) -#endif - ; - } - return 0; - } - /// - inline void GetFace (int i, Element2d & face) const; - /// - void GetFace2 (int i, Element2d & face) const; - /// - void Invert (); - - /// split into 4 node tets - void GetTets (ARRAY<Element> & locels) const; - /// split into 4 node tets, local point nrs - void GetTetsLocal (ARRAY<Element> & locels) const; - /// returns coordinates of nodes - void GetNodesLocal (ARRAY<Point3d> & points) const; - void GetNodesLocalNew (ARRAY<Point3d> & points) const; - - /// split surface into 3 node trigs - void GetSurfaceTriangles (ARRAY<Element2d> & surftrigs) const; - - - /// get number of 'integration points' - int GetNIP () const; - void GetIntegrationPoint (int ip, Point3d & p, double & weight) const; - void GetTransformation (int ip, const T_POINTS & points, - class DenseMatrix & trans) const; - void GetTransformation (int ip, class DenseMatrix & pmat, - class DenseMatrix & trans) const; - - void GetShape (const Point3d & p, class Vector & shape) const; - void GetShapeNew (const Point<3> & p, class FlatVector & shape) const; - /// matrix 2 * np - void GetDShape (const Point3d & p, class DenseMatrix & dshape) const; - void GetDShapeNew (const Point<3> & p, class MatrixFixWidth<3> & dshape) const; - /// matrix 3 * np - void GetPointMatrix (const T_POINTS & points, - class DenseMatrix & pmat) const; - - void ComputeIntegrationPointData () const; - - - double CalcJacobianBadness (const T_POINTS & points) const; - double CalcJacobianBadnessDirDeriv (const T_POINTS & points, - int pi, Vec3d & dir, double & dd) const; - - /// - friend ostream & operator<<(ostream & s, const Element & el); - - void SetRefinementFlag (bool rflag = 1) - { flags.refflag = rflag; } - int TestRefinementFlag () const - { return flags.refflag; } - - int Illegal () const - { return flags.illegal; } - int IllegalValid () const - { return flags.illegal_valid; } - void SetIllegal (int aillegal) - { - flags.illegal = aillegal ? 1 : 0; - flags.illegal_valid = 1; - } - void SetLegal (int alegal) - { - flags.illegal = alegal ? 0 : 1; - flags.illegal_valid = 1; - } - - void Delete () { flags.deleted = 1; } - bool IsDeleted () const - { -#ifdef DEBUG - if (pnum[0] < PointIndex::BASE && !flags.deleted) - cerr << "Volelement has illegal pnum, but not marked as deleted" << endl; -#endif - - return flags.deleted; - } - - int GetPartition () const { return partitionNumber; } - void SetPartition (int nr) { partitionNumber = nr; }; - - int hp_elnr; -}; - - -class Segment; -ostream & operator<<(ostream & s, const Segment & seg); - - -/** - Edge segment. - */ -class Segment -{ -public: - /// - Segment(); - - friend ostream & operator<<(ostream & s, const Segment & seg); - - /// point index 1 - PointIndex p1; - /// point index 2 - PointIndex p2; - /// edge nr - int edgenr; - /// - unsigned int singedge_left:1; - unsigned int singedge_right:1; - - /// 0.. not first segment of segs, 1..first of class, 2..first of class, inverse - unsigned int seginfo:2; - - /// surface decoding index - int si; - /// domain number inner side - int domin; - /// domain number outer side - int domout; - /// top-level object number of surface - int tlosurf; - /// - PointGeomInfo geominfo[2]; - - /// surfaces describing edge - int surfnr1, surfnr2; - /// - EdgePointGeomInfo epgeominfo[2]; - /// - int pmid; // for second order - /// - int meshdocval; - - - PointIndex operator[] (int i) const - { return (i == 0) ? p1 : p2; } - - PointIndex & operator[] (int i) - { return (i == 0) ? p1 : p2; } - - Segment& operator=(const Segment & other); - - - int hp_elnr; -}; - - -// class Surface; -class FaceDescriptor; -ostream & operator<< (ostream & s, const FaceDescriptor & fd); - -/// -class FaceDescriptor -{ - /// which surface, 0 if not available - int surfnr; - /// domain nr inside - int domin; - /// domain nr outside - int domout; - /// top level object number of surface - int tlosurf; - /// boundary condition property - int bcprop; - -public: - FaceDescriptor(); - FaceDescriptor(int surfnri, int domini, int domouti, int tlosurfi); - FaceDescriptor(const Segment & seg); - - int SegmentFits (const Segment & seg); - - int SurfNr () const { return surfnr; } - int DomainIn () const { return domin; } - int DomainOut () const { return domout; } - int TLOSurface () const { return tlosurf; } - int BCProperty () const { return bcprop; } - void SetSurfNr (int sn) { surfnr = sn; } - void SetDomainIn (int di) { domin = di; } - void SetDomainOut (int dom) { domout = dom; } - void SetBCProperty (int bc) { bcprop = bc; } - - friend ostream & operator<<(ostream & s, const FaceDescriptor & fd); - - - /// - bool domin_singular; - bool domout_singular; - - -}; - - - - - - -class MeshingParameters -{ -public: - /** - 3d optimization strategy: - // m .. move nodes - // M .. move nodes, cheap functional - // s .. swap faces - // c .. combine elements - // d .. divide elements - // p .. plot, no pause - // P .. plot, Pause - // h .. Histogramm, no pause - // H .. Histogramm, pause - */ - char * optimize3d; - /// number of 3d optimization steps - int optsteps3d; - /** - 2d optimization strategy: - // s .. swap, opt 6 lines/node - // S .. swap, optimal elements - // m .. move nodes - // p .. plot, no pause - // P .. plot, pause - // c .. combine - **/ - char * optimize2d; - /// number of 2d optimization steps - int optsteps2d; - /// power of error (to approximate max err optimization) - double opterrpow; - /// do block filling ? - int blockfill; - /// block filling up to distance - double filldist; - /// radius of local environment (times h) - double safety; - /// radius of active environment (times h) - double relinnersafety; - /// use local h ? - int uselocalh; - /// grading for local h - double grading; - /// use delaunay meshing - int delaunay; - /// maximal mesh size - double maxh; - /// file for meshsize - const char * meshsizefilename; - /// start surfacemeshing from everywhere in surface - int startinsurface; - /// check overlapping surfaces (debug) - int checkoverlap; - /// check chart boundary (sometimes too restrictive) - int checkchartboundary; - /// safty factor for curvatures (elemetns per radius) - double curvaturesafety; - /// minimal number of segments per edge - double segmentsperedge; - /// use parallel threads - int parthread; - /// weight of element size w.r.t element shape - double elsizeweight; - /// init with default values - - - /// from mp3: - /// give up quality class - int giveuptol; - /// maximal outer steps - int maxoutersteps; - /// class starting star-shape filling - int starshapeclass; - /// if non-zero, baseelement must have baseelnp points - int baseelnp; - /// quality tolerances are handled less careful - int sloppy; - - /// limit for max element angle (150-180) - double badellimit; - - /// - int secondorder; - /// high order element curvature - int elementorder; - /// quad-dominated surface meshing - int quad; - /// - int inverttets; - /// - int inverttrigs; - /// - MeshingParameters (); - /// - void Print (ostream & ost) const; - - void CopyFrom(const MeshingParameters & other); -}; - -class DebugParameters -{ -public: - /// - int debugoutput; - /// use slow checks - int slowchecks; - /// - int haltsuccess; - /// - int haltnosuccess; - /// - int haltlargequalclass; - /// - int haltsegment; - /// - int haltnode; - /// - int haltsegmentp1; - /// - int haltsegmentp2; - /// - int haltexistingline; - /// - int haltoverlap; - /// - int haltface; - /// - int haltfacenr; - /// - DebugParameters (); -}; - - - - - - - -inline void Element2d :: Invert() -{ - if (typ == TRIG) - Swap (PNum(2), PNum(3)); - else - Invert2(); -} - - - - -inline void Element2d :: NormalizeNumbering () -{ - if (GetNP() == 3) - { - if (PNum(1) < PNum(2) && PNum(1) < PNum(3)) - return; - else - { - if (PNum(2) < PNum(3)) - { - PointIndex pi1 = PNum(2); - PNum(2) = PNum(3); - PNum(3) = PNum(1); - PNum(1) = pi1; - } - else - { - PointIndex pi1 = PNum(3); - PNum(3) = PNum(2); - PNum(2) = PNum(1); - PNum(1) = pi1; - } - } - } - else - NormalizeNumbering2(); -} - - - -static const int gftetfacesa[4][3] = - { { 1, 2, 3 }, - { 2, 0, 3 }, - { 0, 1, 3 }, - { 1, 0, 2 } }; - -inline void Element :: GetFace (int i, Element2d & face) const -{ - if (typ == TET) - { - face.SetType(TRIG); - face[0] = pnum[gftetfacesa[i-1][0]]; - face[1] = pnum[gftetfacesa[i-1][1]]; - face[2] = pnum[gftetfacesa[i-1][2]]; - } - else - GetFace2 (i, face); -} - - - - - - - -/** - Identification of periodic surfaces, close surfaces, etc. - */ -class Identifications -{ -private: - Mesh & mesh; - - /// identify points (thin layers, periodic b.c.) - INDEX_2_HASHTABLE<int> * identifiedpoints; - - /// number of identifications (or, actually used identifications ?) - int maxidentnr; - -public: - /// - Identifications (Mesh & amesh); - /// - ~Identifications (); - - void Delete (); - - /* - Identify points pi1 and pi2, due to - identification nr identnr - */ - void Add (PointIndex pi1, PointIndex pi2, int identnr); - - - int Get (PointIndex pi1, PointIndex pi2) const; - int GetSymmetric (PointIndex pi1, PointIndex pi2) const; - /// - INDEX_2_HASHTABLE<int> & GetIdentifiedPoints () - { - return *identifiedpoints; - } - - bool Used (PointIndex pi1, PointIndex pi2) - { - return identifiedpoints->Used (INDEX_2 (pi1, pi2)); - } - - bool UsedSymmetric (PointIndex pi1, PointIndex pi2) - { - return - identifiedpoints->Used (INDEX_2 (pi1, pi2)) || - identifiedpoints->Used (INDEX_2 (pi2, pi1)); - } - - /// - void GetMap (int identnr, ARRAY<int,PointIndex::BASE> & identmap) const; - /// - void GetPairs (int identnr, ARRAY<INDEX_2> & identpairs) const; - /// - int GetMaxNr () const { return maxidentnr; } - - /// remove secondorder - void SetMaxPointNr (int maxpnum); -}; - - - - - - - -#endif diff --git a/Netgen/libsrc/meshing/msghandler.cpp b/Netgen/libsrc/meshing/msghandler.cpp deleted file mode 100644 index 04da502a73..0000000000 --- a/Netgen/libsrc/meshing/msghandler.cpp +++ /dev/null @@ -1,193 +0,0 @@ -//File for handling warnings, errors, messages -#include <meshing.hpp> - -namespace netgen -{ - -int printmessage_importance = 5; -int printwarnings = 1; -int printerrors = 1; -int printdots = 1; -int printfnstart = 0; - -// extern void Ng_PrintDest(const MyStr& s); -extern void Ng_PrintDest(const char * s); - -//the dots for progression of program -void PrintDot(char ch) -{ - if (printdots) - { - char st[2]; - st[0] = ch; - st[1] = 0; - Ng_PrintDest(st); - } -} - -void PrintMessage(int importance, - const MyStr& s1, const MyStr& s2) -{ - if (importance <= printmessage_importance) - { - Ng_PrintDest(MyStr(" ")+s1+s2+MyStr("\n")); - } -} - -void PrintMessage(int importance, - const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4) -{ - if (importance <= printmessage_importance) - { - Ng_PrintDest(MyStr(" ")+s1+s2+s3+s4+MyStr("\n")); - } -} - -void PrintMessage(int importance, - const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (importance <= printmessage_importance) - { - Ng_PrintDest(MyStr(" ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); - } -} - -void PrintMessageCR(int importance, - const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (importance <= printmessage_importance) - { - Ng_PrintDest(MyStr(" ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\r")); - } -} - -void PrintFnStart(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (printfnstart) - Ng_PrintDest(MyStr(" Start Function: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - -void PrintWarning(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (printwarnings) - Ng_PrintDest(MyStr(" WARNING: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - -void PrintError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (printerrors) - Ng_PrintDest(MyStr(" ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - -void PrintFileError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (printerrors) - Ng_PrintDest(MyStr(" FILE ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - -void PrintUserError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - Ng_PrintDest(MyStr(" USER ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - -void PrintSysError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (printerrors) - Ng_PrintDest(MyStr(" SYSTEM ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - -void PrintTime(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) -{ - if (printmessage_importance >= 3) - Ng_PrintDest(MyStr(" Time = ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); -} - - -static ARRAY<MyStr*> msgstatus_stack(0); -static MyStr msgstatus = ""; - - - - -void ResetStatus() -{ - SetStatMsg("idle"); - - for (int i = 0; i < msgstatus_stack.Size(); i++) - delete msgstatus_stack[i]; - msgstatus_stack.SetSize(0); - - // multithread.task = ""; - multithread.percent = 100.; -} - -void PushStatus(const MyStr& s) -{ - msgstatus_stack.Append(new MyStr (s)); - SetStatMsg(s); -} - -void PushStatusF(const MyStr& s) -{ - msgstatus_stack.Append(new MyStr (s)); - SetStatMsg(s); - PrintFnStart(s); -} - -void PopStatus() -{ - SetThreadPercent(100.); - if (msgstatus_stack.Size()) - { - if (msgstatus_stack.Size() > 1) - SetStatMsg (*msgstatus_stack.Last()); - else - SetStatMsg (""); - delete msgstatus_stack.Last(); - msgstatus_stack.SetSize(msgstatus_stack.Size()-1); - } - else - { - PrintSysError("PopStatus failed"); - } -} -/* -void SetStatMsgF(const MyStr& s) -{ - PrintFnStart(s); - SetStatMsg(s); -} -*/ - -void SetStatMsg(const MyStr& s) -{ - msgstatus = s; - multithread.task = msgstatus.c_str(); -} - -void SetThreadPercent(double percent) -{ - multithread.percent = percent; -} - - - -#ifdef SMALLLIB -void Ng_PrintDest(const char * s){cout << s <<flush;} -double GetTime(){return 0;} -void MyError(const char * ch) -{ - cerr << ch << endl; -} -#endif - -} diff --git a/Netgen/libsrc/meshing/msghandler.hpp b/Netgen/libsrc/meshing/msghandler.hpp deleted file mode 100644 index 7de9425193..0000000000 --- a/Netgen/libsrc/meshing/msghandler.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef FILE_MSGHANDLER -#define FILE_MSGHANDLER - -/**************************************************************************/ -/* File: msghandler.hh */ -/* Author: Johannes Gerstmayr */ -/* Date: 20. Nov. 99 */ -/**************************************************************************/ - - -extern void PrintDot(char ch = '.'); - - -//Message Pipeline: - -//importance: importance of message: 1=very important, 3=middle, 5=low, 7=unimportant -extern void PrintMessage(int importance, - const MyStr& s1, const MyStr& s2=MyStr()); -extern void PrintMessage(int importance, - const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4=MyStr()); -extern void PrintMessage(int importance, - const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, - const MyStr& s5, const MyStr& s6=MyStr(), const MyStr& s7=MyStr(), const MyStr& s8=MyStr()); - -// CR without line-feed -extern void PrintMessageCR(int importance, - const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintFnStart(const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintWarning(const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintError(const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintFileError(const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintSysError(const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintUserError(const MyStr& s1, const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void PrintTime(const MyStr& s1="", const MyStr& s2="", const MyStr& s3="", const MyStr& s4="", - const MyStr& s5="", const MyStr& s6="", const MyStr& s7="", const MyStr& s8=""); -extern void SetStatMsg(const MyStr& s); - -extern void PushStatus(const MyStr& s); -extern void PushStatusF(const MyStr& s); -extern void PopStatus(); -extern void SetThreadPercent(double percent); - - -#endif - diff --git a/Netgen/libsrc/meshing/netrule2.cpp b/Netgen/libsrc/meshing/netrule2.cpp deleted file mode 100644 index c75c69d521..0000000000 --- a/Netgen/libsrc/meshing/netrule2.cpp +++ /dev/null @@ -1,226 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - -netrule :: netrule () -{ - name = new char[1]; - name[0] = char(0); - quality = 0; -} - -netrule :: ~netrule() -{ - if(name != NULL) delete [] name; - for(int i=0; i<oldutofreearea_i.Size(); i++) - delete oldutofreearea_i[i]; -} - - -/* -void netrule :: GetFreeArea (ARRAY<Point2d> & afreearea) - { - int i; - - afreearea.SetSize (freearea.Size()); - for (i = 1; i <= freearea.Size(); i++) - afreearea[i] = freearea[i]; - } -*/ - - -void netrule :: SetFreeZoneTransformation (const Vector & devp, int tolclass) -{ - double lam1 = 1.0/tolclass; - double lam2 = 1.-lam1; - - double mem1[100], mem2[100], mem3[100]; - - int vs = oldutofreearea.Height(); - FlatVector devfree(vs, mem1); - FlatVector devfree1(vs, mem2); - FlatVector devfree2(vs, mem3); - - if (tolclass <= oldutofreearea_i.Size()) - { - oldutofreearea_i[tolclass-1] -> Mult (devp, devfree); - } - else - { - oldutofreearea.Mult (devp, devfree1); - oldutofreearealimit.Mult (devp, devfree2); - devfree.Set2 (lam1, devfree1, lam2, devfree2); - } - - - int fzs = freezone.Size(); - transfreezone.SetSize (fzs); - - if (fzs > 0) - { - transfreezone[0].X() = lam1 * freezone[0].X() + lam2 * freezonelimit[0].X() + devfree[0]; - transfreezone[0].Y() = lam1 * freezone[0].Y() + lam2 * freezonelimit[0].Y() + devfree[1]; - fzmaxx = fzminx = transfreezone[0].X(); - fzmaxy = fzminy = transfreezone[0].Y(); - } - - for (int i = 1; i < fzs; i++) - { - transfreezone[i].X() = lam1 * freezone[i].X() + lam2 * freezonelimit[i].X() + devfree[2*i]; - transfreezone[i].Y() = lam1 * freezone[i].Y() + lam2 * freezonelimit[i].Y() + devfree[2*i+1]; - - if (transfreezone[i].X() > fzmaxx) fzmaxx = transfreezone[i].X(); - if (transfreezone[i].X() < fzminx) fzminx = transfreezone[i].X(); - if (transfreezone[i].Y() > fzmaxy) fzmaxy = transfreezone[i].Y(); - if (transfreezone[i].Y() < fzminy) fzminy = transfreezone[i].Y(); - } - - for (int i = 0; i < fzs; i++) - { - Point2d p1 = transfreezone[i]; - Point2d p2 = transfreezone[(i+1) % fzs]; - - Vec2d vn (p2.Y() - p1.Y(), p1.X() - p2.X()); - - double len2 = vn.Length2(); - - if (len2 < 1e-10) - { - freesetinequ(i, 0) = 0; - freesetinequ(i, 1) = 0; - freesetinequ(i, 2) = -1; - } - else - { - vn /= sqrt (len2); // should not be necessary - - freesetinequ(i,0) = vn.X(); - freesetinequ(i,1) = vn.Y(); - freesetinequ(i,2) = -(p1.X() * vn.X() + p1.Y() * vn.Y()); - } - - /* - freesetinequ(i,0) = vn.X(); - freesetinequ(i,1) = vn.Y(); - freesetinequ(i,2) = -(p1.X() * vn.X() + p1.Y() * vn.Y()); - */ - } -} - - -/* -int netrule :: IsInFreeZone2 (const Point2d & p) const -{ - for (int i = 0; i < transfreezone.Size(); i++) - { - if (freesetinequ(i, 0) * p.X() + - freesetinequ(i, 1) * p.Y() + - freesetinequ(i, 2) > 0) return 0; - } - return 1; -} -*/ - -int netrule :: IsLineInFreeZone2 (const Point2d & p1, const Point2d & p2) const -{ - int i; - int left, right, allleft, allright; - double nx, ny, nl, c; - - if (p1.X() > fzmaxx && p2.X() > fzmaxx || - p1.X() < fzminx && p2.X() < fzminx || - p1.Y() > fzmaxy && p2.Y() > fzmaxy || - p1.Y() < fzminy && p2.Y() < fzminy) return 0; - - for (i = 1; i <= transfreezone.Size(); i++) - { - if (freesetinequ.Get(i, 1) * p1.X() + freesetinequ.Get(i, 2) * p1.Y() + - freesetinequ.Get(i, 3) > -1e-6 && - freesetinequ.Get(i, 1) * p2.X() + freesetinequ.Get(i, 2) * p2.Y() + - freesetinequ.Get(i, 3) > -1e-6 - ) return 0; - } - - nx = (p2.Y() - p1.Y()); - ny = -(p2.X() - p1.X()); - nl = sqrt (nx * nx + ny * ny); - if (nl > 1e-8) - { - nx /= nl; - ny /= nl; - c = - (p1.X() * nx + p1.Y() * ny); - - allleft = 1; - allright = 1; - - for (i = 1; i <= transfreezone.Size(); i++) - { - left = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() + c < 1e-7; - right = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() + c > -1e-7; - - if (!left) allleft = 0; - if (!right) allright = 0; - } - if (allleft || allright) return 0; - } - - return 1; -} - -int netrule :: ConvexFreeZone () const -{ - int n = transfreezone.Size(); - for (int i = 1; i <= n; i++) - { - if (! CCW (transfreezone.Get(i), - transfreezone.Get(i % n + 1), - transfreezone.Get( (i+1) % n + 1 ) ) ) - return 0; - } - return 1; -} - - -/* -float netrule :: CalcPointDist (int pi, const Point2d & p) const -{ - float dx = p.X() - points.Get(pi).X(); - float dy = p.Y() - points.Get(pi).Y(); - const threefloat * tf = &tolerances.Get(pi); - - return tf->f1 * dx * dx + tf->f2 * dx * dy + tf->f3 * dy * dy; -} -*/ - -float netrule :: CalcLineError (int li, const Vec2d & v) const -{ - float dx = v.X() - linevecs.Get(li).X(); - float dy = v.Y() - linevecs.Get(li).Y(); - - const threefloat * tf = &linetolerances.Get(li); - return tf->f1 * dx * dx + tf->f2 * dx * dy + tf->f3 * dy * dy; -} - - - - -/* -int GetNRules () - { - return rules.Size(); - } -*/ - - - - - - - - - - - -} diff --git a/Netgen/libsrc/meshing/netrule3.cpp b/Netgen/libsrc/meshing/netrule3.cpp deleted file mode 100644 index fe6a7417c1..0000000000 --- a/Netgen/libsrc/meshing/netrule3.cpp +++ /dev/null @@ -1,1138 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -// #define MARK -// #include <prof.h> - - -namespace netgen -{ - - -vnetrule :: vnetrule () -{ - name = ""; - quality = 0; -} - -vnetrule :: ~vnetrule () -{ - if (strlen(name)) delete [] name; - for (int i = 1; i <= freefaces.Size(); i++) - delete freefaces.Elem(i); - for (int i = 1; i <= freesets.Size(); i++) - delete freesets.Elem(i); - for (int i = 1; i <= freeedges.Size(); i++) - delete freeedges.Elem(i); - for (int i = 1; i <= freefaceinequ.Size(); i++) - delete freefaceinequ.Elem(i); - delete oldutofreezone; - delete oldutofreezonelimit; -} - -int vnetrule :: TestFlag (char flag) const -{ - for (int i = 1; i <= flags.Size(); i++) - if (flags.Get(i) == flag) return 1; - return 0; -} - - -void vnetrule :: SetFreeZoneTransformation (const Vector & allp, int tolclass) -{ - int i, j; - // double nx, ny, nz, v1x, v1y, v1z, v2x, v2y, v2z; - double nl; - const threeint * ti; - int fs; - - double lam1 = 1.0/(2 * tolclass - 1); - double lam2 = 1-lam1; - - transfreezone.SetSize (freezone.Size()); - - int np = points.Size(); - int nfp = freezone.Size(); - Vector vp(np), vfp1(nfp), vfp2(nfp); - - - for (i = 1; i <= 3; i++) - { - for (j = 1; j <= np; j++) - vp.Elem(j) = allp.Get(i+3*j-3); - - oldutofreezone->Mult (vp, vfp1); - oldutofreezonelimit->Mult (vp, vfp2); - - vfp1 *= lam1; - vfp1.Add (lam2, vfp2); - - for (j = 1; j <= nfp; j++) - transfreezone.Elem(j).X(i) = vfp1.Elem(j); - } - - // MARK(setfz2); - - - fzbox.SetPoint (transfreezone.Elem(1)); - for (i = 2; i <= freezone.Size(); i++) - fzbox.AddPoint (transfreezone.Elem(i)); - - - // MARK(setfz3); - - - for (fs = 1; fs <= freesets.Size(); fs++) - { - ARRAY<threeint> & freesetfaces = *freefaces.Get(fs); - DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); - - for (i = 1; i <= freesetfaces.Size(); i++) - { - ti = &freesetfaces.Get(i); - const Point3d & p1 = transfreezone.Get(ti->i1); - const Point3d & p2 = transfreezone.Get(ti->i2); - const Point3d & p3 = transfreezone.Get(ti->i3); - - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d n; - Cross (v1, v2, n); - - nl = n.Length(); - - if (nl < 1e-10) - { - freesetinequ.Set(1, 1, 0); - freesetinequ.Set(1, 2, 0); - freesetinequ.Set(1, 3, 0); - freesetinequ.Set(1, 4, -1); - } - else - { - // n /= nl; - - freesetinequ.Set(i, 1, n.X()/nl); - freesetinequ.Set(i, 2, n.Y()/nl); - freesetinequ.Set(i, 3, n.Z()/nl); - freesetinequ.Set(i, 4, - -(p1.X() * n.X() + p1.Y() * n.Y() + p1.Z() * n.Z()) / nl); - } - } - } - - /* - (*testout) << "Transformed freezone: " << endl; - for (i = 1; i <= transfreezone.Size(); i++) - (*testout) << transfreezone.Get(i) << " "; - (*testout) << endl; - */ -} - -int vnetrule :: ConvexFreeZone () const -{ - int i, j, k, fs; - - // (*mycout) << "Convex free zone...\n"; - - int ret1=1; - // int ret2=1; - - for (fs = 1; fs <= freesets.Size(); fs++) - { - const DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); - - // const ARRAY<int> & freeset = *freesets.Get(fs); - const ARRAY<twoint> & freesetedges = *freeedges.Get(fs); - // const ARRAY<threeint> & freesetfaces = *freefaces.Get(fs); - - for (i = 1; i <= freesetedges.Size(); i++) - { - j = freesetedges.Get(i).i1; //triangle j with opposite point k - k = freesetedges.Get(i).i2; - - if ( freesetinequ.Get(j, 1) * transfreezone.Get(k).X() + - freesetinequ.Get(j, 2) * transfreezone.Get(k).Y() + - freesetinequ.Get(j, 3) * transfreezone.Get(k).Z() + - freesetinequ.Get(j, 4) > 0 ) - { - ret1=0; - } - } - - } - - return ret1; -} - - -int vnetrule :: IsInFreeZone (const Point3d & p) const -{ - int i, fs; - char inthis; - - - for (fs = 1; fs <= freesets.Size(); fs++) - { - inthis = 1; - ARRAY<threeint> & freesetfaces = *freefaces.Get(fs); - DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); - - for (i = 1; i <= freesetfaces.Size() && inthis; i++) - { - if (freesetinequ.Get(i, 1) * p.X() + freesetinequ.Get(i, 2) * p.Y() + - freesetinequ.Get(i, 3) * p.Z() + freesetinequ.Get(i, 4) > 0) - inthis = 0; - } - - if (inthis) return 1; - } - - return 0; -} - - -int vnetrule :: IsTriangleInFreeZone (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const ARRAY<int> & pi, int newone) -{ - int fs; - int infreeset, cannot = 0; - - - static ARRAY<int> pfi(3), pfi2(3); - - // convert from local index to freeset index - int i, j; - for (i = 1; i <= 3; i++) - { - pfi.Elem(i) = 0; - if (pi.Get(i)) - { - for (j = 1; j <= freezonepi.Size(); j++) - if (freezonepi.Get(j) == pi.Get(i)) - pfi.Elem(i) = j; - } - } - - for (fs = 1; fs <= freesets.Size(); fs++) - { - const ARRAY<int> & freeseti = *freesets.Get(fs); - for (i = 1; i <= 3; i++) - { - pfi2.Elem(i) = 0; - for (j = 1; j <= freeseti.Size(); j++) - if (pfi.Get(i) == freeseti.Get(j)) - pfi2.Elem(i) = pfi.Get(i); - } - - infreeset = IsTriangleInFreeSet(p1, p2, p3, fs, pfi2, newone); - if (infreeset == 1) return 1; - if (infreeset == -1) cannot = -1; - } - - return cannot; -} - - - -int vnetrule :: IsTriangleInFreeSet (const Point3d & p1, const Point3d & p2, - const Point3d & p3, int fs, - const ARRAY<int> & pi, int newone) -{ - int i, ii; - Vec3d n; - int allleft, allright; - int hos1, hos2, hos3, os1, os2, os3; - double hf, lam1, lam2, f, c1, c2, alpha; - double v1n, v2n, h11, h12, h22, dflam1, dflam2; - double lam1old, lam2old, fold; - double hpx, hpy, hpz, v1x, v1y, v1z, v2x, v2y, v2z; - int act1, act2, act3, it; - int cntout; - static ARRAY<int> activefaces; - int isin; - - - // MARK(triinfz); - - ARRAY<threeint> & freesetfaces = *freefaces.Get(fs); - DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); - - - int cnt = 0; - for (i = 1; i <= 3; i++) - if (pi.Get(i)) cnt++; - - /* - (*testout) << "trig in free set : " << p1 << " - " << p2 << " - " << p3 << endl; - (*testout) << "common points: " << cnt << endl; - */ - if (!newone) - cnt = 0; - - if (cnt == 1) - { - // MARK(triinfz1); - - int upi = 0, lpiu = 0; - for (i = 1; i <= 3; i++) - if (pi.Get(i)) - { - upi = i; - lpiu = pi.Get(i); - } - - Vec3d v1, v2; - switch (upi) - { - case 1: - { - v1 = p2 - p1; - v2 = p3 - p1; - break; - } - case 2: - { - v1 = p3 - p2; - v2 = p1 - p2; - break; - } - case 3: - { - v1 = p1 - p3; - v2 = p2 - p3; - break; - } - } - - v1 /= v1.Length(); - v2 /= v2.Length(); - Cross (v1, v2, n); - n /= n.Length(); - - // (*testout) << "Test new: " << endl; - for (i = 1; i <= freesetfaces.Size(); i++) - { - if ( (freesetfaces.Get(i).i1 == lpiu) || - (freesetfaces.Get(i).i2 == lpiu) || - (freesetfaces.Get(i).i3 == lpiu) ) - { - // freeface has point - - - Vec3d a (freesetinequ.Get(i, 1), - freesetinequ.Get(i, 2), - freesetinequ.Get(i, 3)); - - // if (1 - fabs (a * n) < 1e-8 ) - // continue; - - Vec3d an; - Cross (a, n, an); - double lan = an.Length(); - if (lan < 1e-10) - continue; - - an /= lan; - - int out1 = (a * v1) > 0; - int out2 = (a * v2) > 0; - // (*testout) << "out1, out2 = " << out1 << ", " << out2 << endl; - if (out1 && out2) - return 0; - - if (!out1 && !out2) - continue; - - - // if ( ( (an * v1) < 0) && ( (an * v2) < 0) ) // falsch !!!! - // an *= -1; - - // solve an = lam1 v1 + lam2 v2 - double vii11 = v1 * v1; - double vii12 = v1 * v2; - double vii22 = v2 * v2; - double det = vii11 * vii22 - vii12 * vii12; - if ( fabs (det) < 1e-10 ) - continue; - double rs1 = an * v1; - double rs2 = an * v2; - - double lam1 = rs1 * vii22 - rs2 * vii12; - double lam2 = rs2 * vii11 - rs1 * vii12; - - if (fabs (lam1) > fabs (lam2)) - { - if (lam1 < 0) - an *= -1; - } - else - { - if (lam2 < 0) - an *= -1; - } - - - if (lam1 * lam2 < 0 && 0) - { - if (fabs (lam1) > 1e-14 && fabs (lam2) > 1e-14) - { - // (*mycout) << "lam1 lam2 < 0" << endl; - (*testout) << "lami different" << endl; - (*testout) << "v1 = " << v1 << endl; - (*testout) << "v2 = " << v2 << endl; - (*testout) << "n = " << n << endl; - (*testout) << "a = " << a << endl; - (*testout) << "an = " << an << endl; - (*testout) << "a * v1 = " << (a * v1) << endl; - (*testout) << "a * v2 = " << (a * v2) << endl; - (*testout) << "an * v1 = " << (an * v1) << endl; - (*testout) << "an * v2 = " << (an * v2) << endl; - - (*testout) << "vii = " << vii11 << ", " << vii12 << ", " << vii22 << endl; - (*testout) << "lami = " << lam1 << ", " << lam2 << endl; - (*testout) << "rs = " << rs1 << ", " << rs2 << endl; - continue; - } - } - - if (out1) - v1 = an; - else - v2 = an; - } - } - - return 1; - - /* - (*testout) << "overlap trig " << p1 << p2 << p3 << endl; - (*testout) << "upi = " << upi << endl; - (*testout) << "v1 = " << v1 << " v2 = " << v2 << endl; - */ - - switch (upi) - { - case 1: - { - v1 = p2 - p1; - v2 = p3 - p1; - break; - } - case 2: - { - v1 = p3 - p2; - v2 = p1 - p2; - break; - } - case 3: - { - v1 = p1 - p3; - v2 = p2 - p3; - break; - } - } - - v1 /= v1.Length(); - v2 /= v2.Length(); - Cross (v1, v2, n); - n /= n.Length(); - - // (*testout) << "orig v1, v2 = " << v1 << ", " << v2 << endl; - - - for (i = 1; i <= freesetfaces.Size(); i++) - { - if ( (freesetfaces.Get(i).i1 == lpiu) || - (freesetfaces.Get(i).i2 == lpiu) || - (freesetfaces.Get(i).i3 == lpiu) ) - { - /* - (*testout) << "v1, v2, now = " << v1 << ", " << v2 << endl; - - // freeface has point - (*testout) << "freesetface: " - << freesetfaces.Get(i).i1 << " " - << freesetfaces.Get(i).i2 << " " - << freesetfaces.Get(i).i3 << " "; - */ - - Vec3d a (freesetinequ.Get(i, 1), - freesetinequ.Get(i, 2), - freesetinequ.Get(i, 3)); - // (*testout) << "a = " << a << endl; - - - Vec3d an; - Cross (a, n, an); - double lan = an.Length(); - - // (*testout) << "an = " << an << endl; - - if (lan < 1e-10) - continue; - - an /= lan; - - // (*testout) << "a*v1 = " << (a*v1) << " a*v2 = " << (a*v2) << endl; - - int out1 = (a * v1) > 0; - // int out2 = (a * v2) > 0; - - - // (*testout) << "out1, 2 = " << out1 << ", " << out2 << endl; - - - double vii11 = v1 * v1; - double vii12 = v1 * v2; - double vii22 = v2 * v2; - double det = vii11 * vii22 - vii12 * vii12; - if ( fabs (det) < 1e-10 ) - continue; - double rs1 = an * v1; - double rs2 = an * v2; - - double lam1 = rs1 * vii22 - rs2 * vii12; - double lam2 = rs2 * vii11 - rs1 * vii12; - - // (*testout) << "lam1, lam2 = " << lam1 << ", " << lam2 << endl; - - - if (fabs (lam1) > fabs (lam2)) - { - if (lam1 < 0) - an *= -1; - } - else - { - if (lam2 < 0) - an *= -1; - } - - - if (lam1 * lam2 < 0) - { - if (fabs (lam1) > 1e-14 && fabs (lam2) > 1e-14) - { - // (*mycout) << "lam1 lam2 < 0" << endl; - (*testout) << "lami different" << endl; - (*testout) << "v1 = " << v1 << endl; - (*testout) << "v2 = " << v2 << endl; - (*testout) << "n = " << n << endl; - (*testout) << "a = " << a << endl; - (*testout) << "an = " << an << endl; - (*testout) << "a * v1 = " << (a * v1) << endl; - (*testout) << "a * v2 = " << (a * v2) << endl; - (*testout) << "an * v1 = " << (an * v1) << endl; - (*testout) << "an * v2 = " << (an * v2) << endl; - - (*testout) << "vii = " << vii11 << ", " << vii12 << ", " << vii22 << endl; - (*testout) << "lami = " << lam1 << ", " << lam2 << endl; - (*testout) << "rs = " << rs1 << ", " << rs2 << endl; - continue; - } - } - - if (out1) - v1 = an; - else - v2 = an; - - - - } - } - - return 1; - } - - - - if (cnt == 2) - { - // (*testout) << "tripoitns: " << p1 << " " << p2 << " " << p3 << endl; - - // MARK(triinfz2); - - int pi1 = 0, pi2 = 0, pi3 = 0; - Vec3d a1, a2; // outer normals - Vec3d trivec; // vector from common edge to third point of triangle - for (i = 1; i <= 3; i++) - if (pi.Get(i)) - { - pi2 = pi1; - pi1 = pi.Get(i); - } - else - pi3 = i; - - switch (pi3) - { - case 1: trivec = (p1 - p2); break; - case 2: trivec = (p2 - p3); break; - case 3: trivec = (p3 - p2); break; - } - - ARRAY<int> lpi(freezonepi.Size()); - for (i = 1; i <= lpi.Size(); i++) - lpi.Elem(i) = 0; - lpi.Elem(pi1) = 1; - lpi.Elem(pi2) = 1; - - int ff1 = 0, ff2 = 0; - for (i = 1; i <= freesetfaces.Size(); i++) - { - if (lpi.Get(freesetfaces.Get(i).i1) + - lpi.Get(freesetfaces.Get(i).i2) + - lpi.Get(freesetfaces.Get(i).i3) == 2) - { - ff2 = ff1; - ff1 = i; - } - } - - if (ff2 == 0) - return 1; - - a1 = Vec3d (freesetinequ.Get(ff1, 1), - freesetinequ.Get(ff1, 2), - freesetinequ.Get(ff1, 3)); - a2 = Vec3d (freesetinequ.Get(ff2, 1), - freesetinequ.Get(ff2, 2), - freesetinequ.Get(ff2, 3)); - - if ( ( (a1 * trivec) > 0) || ( (a2 * trivec) > 0)) - return 0; - - return 1; - } - - - if (cnt == 3) - { - // MARK(triinfz3); - - ARRAY<int> lpi(freezonepi.Size()); - for (i = 1; i <= lpi.Size(); i++) - lpi.Elem(i) = 0; - - for (i = 1; i <= 3; i++) - lpi.Elem(pi.Get(i)) = 1; - - for (i = 1; i <= freesetfaces.Size(); i++) - { - if (lpi.Get(freesetfaces.Get(i).i1) + - lpi.Get(freesetfaces.Get(i).i2) + - lpi.Get(freesetfaces.Get(i).i3) == 3) - { - return 0; - } - } - return 1; - } - - // MARK(triinfz0); - - - os1 = os2 = os3 = 0; - activefaces.SetSize(0); - - // is point inside ? - - for (i = 1; i <= freesetfaces.Size(); i++) - { - hos1 = freesetinequ.Get(i, 1) * p1.X() + - freesetinequ.Get(i, 2) * p1.Y() + - freesetinequ.Get(i, 3) * p1.Z() + - freesetinequ.Get(i, 4) > -1E-5; - - hos2 = freesetinequ.Get(i, 1) * p2.X() + - freesetinequ.Get(i, 2) * p2.Y() + - freesetinequ.Get(i, 3) * p2.Z() + - freesetinequ.Get(i, 4) > -1E-5; - - hos3 = freesetinequ.Get(i, 1) * p3.X() + - freesetinequ.Get(i, 2) * p3.Y() + - freesetinequ.Get(i, 3) * p3.Z() + - freesetinequ.Get(i, 4) > -1E-5; - - if (hos1 && hos2 && hos3) return 0; - - if (hos1) os1 = 1; - if (hos2) os2 = 1; - if (hos3) os3 = 1; - - if (hos1 || hos2 || hos3) activefaces.Append (i); - } - - if (!os1 || !os2 || !os3) return 1; - - v1x = p2.X() - p1.X(); - v1y = p2.Y() - p1.Y(); - v1z = p2.Z() - p1.Z(); - - v2x = p3.X() - p1.X(); - v2y = p3.Y() - p1.Y(); - v2z = p3.Z() - p1.Z(); - - n.X() = v1y * v2z - v1z * v2y; - n.Y() = v1z * v2x - v1x * v2z; - n.Z() = v1x * v2y - v1y * v2x; - n /= n.Length(); - - allleft = allright = 1; - for (i = 1; i <= transfreezone.Size() && (allleft || allright); i++) - { - const Point3d & p = transfreezone.Get(i); - float scal = (p.X() - p1.X()) * n.X() + - (p.Y() - p1.Y()) * n.Y() + - (p.Z() - p1.Z()) * n.Z(); - - if ( scal > 1E-8 ) allleft = 0; - if ( scal < -1E-8 ) allright = 0; - } - - if (allleft || allright) return 0; - - - lam1old = lam2old = lam1 = lam2 = 1.0 / 3.0; - - - // testout << endl << endl << "Start minimizing" << endl; - - it = 0; - int minit; - minit = 1000; - fold = 1E10; - - - - while (1) - { - it++; - - if (it > 1000) return -1; - - if (lam1 < 0) lam1 = 0; - if (lam2 < 0) lam2 = 0; - if (lam1 + lam2 > 1) lam1 = 1 - lam2; - - if (it > minit) - { - (*testout) << "it = " << it << endl; - (*testout) << "lam1/2 = " << lam1 << " " << lam2 << endl; - } - - hpx = p1.X() + lam1 * v1x + lam2 * v2x; - hpy = p1.Y() + lam1 * v1y + lam2 * v2y; - hpz = p1.Z() + lam1 * v1z + lam2 * v2z; - - f = 0; - - h11 = h12 = h22 = dflam1 = dflam2 = 0; - cntout = 0; - - isin = 1; - - for (i = 1; i <= activefaces.Size(); i++) - { - ii = activefaces.Get(i); - - hf = freesetinequ.Get(ii, 1) * hpx + - freesetinequ.Get(ii, 2) * hpy + - freesetinequ.Get(ii, 3) * hpz + - freesetinequ.Get(ii, 4); - - if (hf > -1E-7) isin = 0; - - hf += 1E-4; - if (hf > 0) - { - f += hf * hf; - - v1n = freesetinequ.Get(ii, 1) * v1x + - freesetinequ.Get(ii, 2) * v1y + - freesetinequ.Get(ii, 3) * v1z; - v2n = freesetinequ.Get(ii, 1) * v2x + - freesetinequ.Get(ii, 2) * v2y + - freesetinequ.Get(ii, 3) * v2z; - - h11 += 2 * v1n * v1n; - h12 += 2 * v1n * v2n; - h22 += 2 * v2n * v2n; - dflam1 += 2 * hf * v1n; - dflam2 += 2 * hf * v2n; - cntout++; - } - } - - if (isin) return 1; - - if (it > minit) - { - (*testout) << "f = " << f - << " dfdlam = " << dflam1 << " " << dflam2 << endl; - (*testout) << "h = " << h11 << " " << h12 << " " << h22 << endl; - (*testout) << "active: " << cntout << endl; - (*testout) << "lam1-lam1old = " << (lam1 - lam1old) << endl; - (*testout) << "lam2-lam2old = " << (lam2 - lam2old) << endl; - } - - - if (f >= fold) - { - lam1 = 0.100000000000000 * lam1 + 0.9000000000000000 * lam1old; - lam2 = 0.100000000000000 * lam2 + 0.9000000000000000 * lam2old; - } - else - { - lam1old = lam1; - lam2old = lam2; - fold = f; - - - if (f < 1E-9) return 1; - - h11 += 1E-10; - h22 += 1E-10; - c1 = - ( h22 * dflam1 - h12 * dflam2) / (h11 * h22 - h12 * h12); - c2 = - (-h12 * dflam1 + h11 * dflam2) / (h11 * h22 - h12 * h12); - alpha = 1; - - - if (it > minit) - (*testout) << "c1/2 = " << c1 << " " << c2 << endl; - - act1 = lam1 <= 1E-6 && c1 <= 0; - act2 = lam2 <= 1E-6 && c2 <= 0; - act3 = lam1 + lam2 >= 1 - 1E-6 && c1 + c2 >= 0; - - if (it > minit) - (*testout) << "act1,2,3 = " << act1 << act2 << act3 << endl; - - if (act1 && act2 || act1 && act3 || act2 && act3) return 0; - - if (act1) - { - c1 = 0; - c2 = - dflam2 / h22; - } - - if (act2) - { - c1 = - dflam1 / h11; - c2 = 0; - } - - if (act3) - { - c1 = - (dflam1 - dflam2) / (h11 + h22 - 2 * h12); - c2 = -c1; - } - - if (it > minit) - (*testout) << "c1/2 now = " << c1 << " " << c2 << endl; - - - if (f > 100 * sqrt (sqr (c1) + sqr (c2))) return 0; - - - if (lam1 + alpha * c1 < 0 && !act1) - alpha = -lam1 / c1; - if (lam2 + alpha * c2 < 0 && !act2) - alpha = -lam2 / c2; - if (lam1 + lam2 + alpha * (c1 + c2) > 1 && !act3) - alpha = (1 - lam1 - lam2) / (c1 + c2); - - if (it > minit) - (*testout) << "alpha = " << alpha << endl; - - lam1 += alpha * c1; - lam2 += alpha * c2; - } - } -} - - - - -int vnetrule :: IsQuadInFreeZone (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Point3d & p4, - const ARRAY<int> & pi, int newone) -{ - int fs; - int infreeset, cannot = 0; - - - static ARRAY<int> pfi(4), pfi2(4); - - // convert from local index to freeset index - int i, j; - for (i = 1; i <= 4; i++) - { - pfi.Elem(i) = 0; - if (pi.Get(i)) - { - for (j = 1; j <= freezonepi.Size(); j++) - if (freezonepi.Get(j) == pi.Get(i)) - pfi.Elem(i) = j; - } - } - - for (fs = 1; fs <= freesets.Size(); fs++) - { - const ARRAY<int> & freeseti = *freesets.Get(fs); - for (i = 1; i <= 4; i++) - { - pfi2.Elem(i) = 0; - for (j = 1; j <= freeseti.Size(); j++) - if (pfi.Get(i) == freeseti.Get(j)) - pfi2.Elem(i) = pfi.Get(i); - } - - infreeset = IsQuadInFreeSet(p1, p2, p3, p4, fs, pfi2, newone); - if (infreeset == 1) return 1; - if (infreeset == -1) cannot = -1; - } - - return cannot; -} - - -int vnetrule :: IsQuadInFreeSet (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, - int fs, const ARRAY<int> & pi, int newone) -{ - int i; - - int cnt = 0; - for (i = 1; i <= 4; i++) - if (pi.Get(i)) cnt++; - - /* - (*testout) << "test quad in freeset: " << p1 << " - " << p2 << " - " << p3 << " - " << p4 << endl; - (*testout) << "pi = "; - for (i = 1; i <= pi.Size(); i++) - (*testout) << pi.Get(i) << " "; - (*testout) << endl; - (*testout) << "cnt = " << cnt << endl; - */ - if (cnt == 4) - { - return 1; - } - - if (cnt == 3) - { - return 1; - } - - static ARRAY<int> pi3(3); - int res; - - pi3.Elem(1) = pi.Get(1); - pi3.Elem(2) = pi.Get(2); - pi3.Elem(3) = pi.Get(3); - res = IsTriangleInFreeSet (p1, p2, p3, fs, pi3, newone); - if (res) return res; - - - pi3.Elem(1) = pi.Get(2); - pi3.Elem(2) = pi.Get(3); - pi3.Elem(3) = pi.Get(4); - res = IsTriangleInFreeSet (p2, p3, p4, fs, pi3, newone); - if (res) return res; - - pi3.Elem(1) = pi.Get(3); - pi3.Elem(2) = pi.Get(4); - pi3.Elem(3) = pi.Get(1); - res = IsTriangleInFreeSet (p3, p4, p1, fs, pi3, newone); - if (res) return res; - - pi3.Elem(1) = pi.Get(4); - pi3.Elem(2) = pi.Get(1); - pi3.Elem(3) = pi.Get(2); - res = IsTriangleInFreeSet (p4, p1, p2, fs, pi3, newone); - return res; -} - - - - - - - - - - - - -float vnetrule :: CalcPointDist (int pi, const Point3d & p) const -{ - float dx = p.X() - points.Get(pi).X(); - float dy = p.Y() - points.Get(pi).Y(); - float dz = p.Z() - points.Get(pi).Z(); - - // const threefloat * tf = &tolerances.Get(pi); - // return tf->f1 * dx * dx + tf->f2 * dx * dy + tf->f3 * dy * dy; - return tolerances.Get(pi) * (dx * dx + dy * dy + dz * dz); -} - - -int vnetrule :: TestOk () const -{ - ARRAY<int> cntpused(points.Size()); - ARRAY<int> edge1, edge2; - ARRAY<int> delf(faces.Size()); - int i, j, k; - int pi1, pi2; - int found; - - for (i = 1; i <= cntpused.Size(); i++) - cntpused.Elem(i) = 0; - for (i = 1; i <= faces.Size(); i++) - delf.Elem(i) = 0; - for (i = 1; i <= delfaces.Size(); i++) - delf.Elem(delfaces.Get(i)) = 1; - - - for (i = 1; i <= faces.Size(); i++) - if (delf.Get(i) || i > noldf) - for (j = 1; j <= faces.Get(i).GetNP(); j++) - cntpused.Elem(faces.Get(i).PNum(j))++; - - for (i = 1; i <= cntpused.Size(); i++) - if (cntpused.Get(i) > 0 && cntpused.Get(i) < 2) - { - return 0; - } - - - // (*testout) << endl; - for (i = 1; i <= faces.Size(); i++) - { - // (*testout) << "face " << i << endl; - for (j = 1; j <= faces.Get(i).GetNP(); j++) - { - pi1 = 0; pi2 = 0; - if (delf.Get(i)) - { - pi1 = faces.Get(i).PNumMod(j); - pi2 = faces.Get(i).PNumMod(j+1); - } - if (i > noldf) - { - pi1 = faces.Get(i).PNumMod(j+1); - pi2 = faces.Get(i).PNumMod(j); - } - - found = 0; - if (pi1) - { - for (k = 1; k <= edge1.Size(); k++) - if (edge1.Get(k) == pi1 && edge2.Get(k) == pi2) - { - found = 1; - edge1.DeleteElement(k); - edge2.DeleteElement(k); - k--; - // (*testout) << "Del edge " << pi1 << "-" << pi2 << endl; - } - if (!found) - { - edge1.Append (pi2); - edge2.Append (pi1); - // (*testout) << "Add edge " << pi1 << "-" << pi2 << endl; - } - } - } - } - - - if (edge1.Size() > 0) - { - return 0; - } - - /* - cntpused.SetSize(freezone.Size()); - for (i = 1; i <= cntpused.Size(); i++) - cntpused[i] = 0; - - for (i = 1; i <= freefaces.Size(); i++) - { - cntpused[freefaces[i].i1]++; - cntpused[freefaces[i].i2]++; - cntpused[freefaces[i].i3]++; - } - - for (i = 1; i <= cntpused.Size(); i++) - if (cntpused[i] < 3) - { - (*mycout) << "Fall 3" << endl; - return 0; - } - - - - for (i = 1; i <= freefaces.Size(); i++) - { - for (j = 1; j <= 3; j++) - { - if (j == 1) - { - pi1 = freefaces[i].i1; - pi2 = freefaces[i].i2; - } - if (j == 2) - { - pi1 = freefaces[i].i2; - pi2 = freefaces[i].i3; - } - if (j == 3) - { - pi1 = freefaces[i].i3; - pi2 = freefaces[i].i1; - } - - found = 0; - for (k = 1; k <= edge1.Size(); k++) - if (edge1[k] == pi1 && edge2[k] == pi2) - { - found = 1; - edge1.DeleteElement(k); - edge2.DeleteElement(k); - k--; - } - - if (!found) - { - edge1.Append (pi2); - edge2.Append (pi1); - } - } - } - - if (edge1.Size() > 0) - { - (*mycout) << "Fall 4" << endl; - return 0; - } - */ - return 1; -} - - -int vnetrule :: IsDelFace (int fn) const -{ - int i; - for (i = 1; i <= GetNDelF(); i++) - if (GetDelFace(i) == fn) return 1; - return 0; -} - -} diff --git a/Netgen/libsrc/meshing/parser2.cpp b/Netgen/libsrc/meshing/parser2.cpp deleted file mode 100644 index 48ef280eb4..0000000000 --- a/Netgen/libsrc/meshing/parser2.cpp +++ /dev/null @@ -1,559 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - - -void LoadMatrixLine (istream & ist, DenseMatrix & m, int line) -{ - char ch; - int pnum; - float f; - - ist >> ch; - while (ch != '}') - { - ist.putback (ch); - ist >> f; - ist >> ch; - ist >> pnum; - - if (ch == 'x' || ch == 'X') - m.Elem(line, 2 * pnum - 1) = f; - if (ch == 'y' || ch == 'Y') - m.Elem(line, 2 * pnum) = f; - - ist >> ch; - if (ch == ',') - ist >> ch; - } -} - - -void netrule :: LoadRule (istream & ist) -{ - char buf[256]; - char ch; - Point2d p; - INDEX_2 lin; - int i, j; - DenseMatrix tempoldutonewu(20, 20), tempoldutofreearea(20, 20), - tempoldutofreearealimit(20, 20); - - tempoldutonewu = 0; - tempoldutofreearea = 0; - tempoldutofreearealimit = 0; - - noldp = 0; - noldl = 0; - - ist.get (buf, sizeof(buf), '"'); - ist.get (ch); - ist.get (buf, sizeof(buf), '"'); - ist.get (ch); - - if(name != NULL) delete [] name; - name = new char[strlen (buf) + 1]; - strcpy (name, buf); - // (*mycout) << "Rule " << name << " found." << endl; - - do - { - ist >> buf; - - if (strcmp (buf, "quality") == 0) - - { - ist >> quality; - } - - else if (strcmp (buf, "mappoints") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ')' - - points.Append (p); - noldp++; - - tolerances.SetSize (noldp); - tolerances.Elem(noldp).f1 = 1.0; - tolerances.Elem(noldp).f2 = 0; - tolerances.Elem(noldp).f3 = 1.0; - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - ist >> tolerances.Elem(noldp).f1; - ist >> ch; // ',' - ist >> tolerances.Elem(noldp).f2; - ist >> ch; // ',' - ist >> tolerances.Elem(noldp).f3; - ist >> ch; // '}' - } - else if (ch == 'd') - { - // delpoints.Append (noldp); - ist >> ch; // 'e' - ist >> ch; // 'l' - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - - else if (strcmp (buf, "maplines") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> lin.I1(); - ist >> ch; // ',' - ist >> lin.I2(); - ist >> ch; // ')' - - lines.Append (lin); - linevecs.Append (points.Get(lin.I2()) - points.Get(lin.I1())); - noldl++; - linetolerances.SetSize (noldl); - linetolerances.Elem(noldl).f1 = 0; - linetolerances.Elem(noldl).f2 = 0; - linetolerances.Elem(noldl).f3 = 0; - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - ist >> linetolerances.Elem(noldl).f1; - ist >> ch; // ',' - ist >> linetolerances.Elem(noldl).f2; - ist >> ch; // ',' - ist >> linetolerances.Elem(noldl).f3; - ist >> ch; // '}' - } - else if (ch == 'd') - { - dellines.Append (noldl); - ist >> ch; // 'e' - ist >> ch; // 'l' - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "newpoints") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ')' - - points.Append (p); - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - LoadMatrixLine (ist, tempoldutonewu, - 2 * (points.Size()-noldp) - 1); - - ist >> ch; // '{' - LoadMatrixLine (ist, tempoldutonewu, - 2 * (points.Size()-noldp)); - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "newlines") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> lin.I1(); - ist >> ch; // ',' - ist >> lin.I2(); - ist >> ch; // ')' - - lines.Append (lin); - linevecs.Append (points.Get(lin.I2()) - points.Get(lin.I1())); - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "freearea") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ')' - - freezone.Append (p); - freezonelimit.Append (p); - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - LoadMatrixLine (ist, tempoldutofreearea, - 2 * freezone.Size() - 1); - - ist >> ch; // '{' - LoadMatrixLine (ist, tempoldutofreearea, - 2 * freezone.Size()); - } - - ist >> ch; - } - - ist >> ch; - } - - for (i = 1; i <= tempoldutofreearealimit.Height(); i++) - for (j = 1; j <= tempoldutofreearealimit.Width(); j++) - tempoldutofreearealimit.Elem(i,j) = - tempoldutofreearea.Elem(i,j); - - - ist.putback (ch); - } - else if (strcmp (buf, "freearea2") == 0) - { - ist >> ch; - int freepi = 0; - tempoldutofreearealimit = 0; - - while (ch == '(') - { - freepi++; - - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ')' - - freezonelimit.Elem(freepi) = p; - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - LoadMatrixLine (ist, tempoldutofreearealimit, - 2 * freepi - 1); - - ist >> ch; // '{' - LoadMatrixLine (ist, tempoldutofreearealimit, - 2 * freepi); - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "elements") == 0) - { - ist >> ch; - - while (ch == '(') - { - elements.Append (Element2d()); - - ist >> elements.Last().PNum(1); - ist >> ch; // ',' - - if (ch == ',') - { - ist >> elements.Last().PNum(2); - ist >> ch; // ',' - } - if (ch == ',') - { - ist >> elements.Last().PNum(3); - ist >> ch; // ',' - } - if (ch == ',') - { - elements.Last().SetType (QUAD); - ist >> elements.Last().PNum(4); - ist >> ch; // ',' - - // const Element2d & el = elements.Last(); - /* - orientations.Append (threeint(el.PNum(1), el.PNum(2), el.PNum(3))); - orientations.Append (threeint(el.PNum(2), el.PNum(3), el.PNum(4))); - orientations.Append (threeint(el.PNum(3), el.PNum(4), el.PNum(1))); - orientations.Append (threeint(el.PNum(4), el.PNum(1), el.PNum(2))); - */ - } - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "orientations") == 0) - - { - ist >> ch; - - while (ch == '(') - { - // threeint a = threeint(); - orientations.Append (threeint()); - - ist >> orientations.Last().i1; - ist >> ch; // ',' - ist >> orientations.Last().i2; - ist >> ch; // ',' - ist >> orientations.Last().i3; - ist >> ch; // ',' - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "endrule") != 0) - { - PrintSysError ("Parser error, unknown token ", buf); - } - } - while (!ist.eof() && strcmp (buf, "endrule") != 0); - - oldutonewu.SetSize (2 * (points.Size() - noldp), 2 * noldp); - oldutofreearea.SetSize (2 * freezone.Size(), 2 * noldp); - oldutofreearealimit.SetSize (2 * freezone.Size(), 2 * noldp); - - for (i = 1; i <= oldutonewu.Height(); i++) - for (j = 1; j <= oldutonewu.Width(); j++) - oldutonewu.Elem(i, j) = tempoldutonewu.Elem(i, j); - - for (i = 1; i <= oldutofreearea.Height(); i++) - for (j = 1; j <= oldutofreearea.Width(); j++) - oldutofreearea.Elem(i, j) = tempoldutofreearea.Elem(i, j); - - for (i = 1; i <= oldutofreearea.Height(); i++) - for (j = 1; j <= oldutofreearea.Width(); j++) - oldutofreearealimit.Elem(i, j) = tempoldutofreearealimit.Elem(i, j); - - freesetinequ.SetSize (freezone.Size()); - - - - { - char ok; - int minn; - ARRAY<int> pnearness (noldp); - - for (i = 1; i <= pnearness.Size(); i++) - pnearness.Elem(i) = 1000; - - for (j = 1; j <= 2; j++) - pnearness.Elem(GetPointNr (1, j)) = 0; - - do - { - ok = 1; - - for (i = 1; i <= noldl; i++) - { - minn = 1000; - for (j = 1; j <= 2; j++) - minn = min2 (minn, pnearness.Get(GetPointNr (i, j))); - - for (j = 1; j <= 2; j++) - if (pnearness.Get(GetPointNr (i, j)) > minn+1) - { - ok = 0; - pnearness.Elem(GetPointNr (i, j)) = minn+1; - } - } - } - while (!ok); - - lnearness.SetSize (noldl); - - for (i = 1; i <= noldl; i++) - { - lnearness.Elem(i) = 0; - for (j = 1; j <= 2; j++) - lnearness.Elem(i) += pnearness.Get(GetPointNr (i, j)); - } - } - - oldutofreearea_i.SetSize (10); - for (i = 0; i < oldutofreearea_i.Size(); i++) - { - oldutofreearea_i[i] = new DenseMatrix (oldutofreearea.Height(), oldutofreearea.Width()); - DenseMatrix & mati = *oldutofreearea_i[i]; - for (int j = 0; j < oldutofreearea.Height(); j++) - for (int k = 0; k < oldutofreearea.Width(); k++) - mati(j,k) = 1.0 / (i+1) * oldutofreearea(j,k) + (1 - 1.0/(i+1)) * oldutofreearealimit(j,k); - } -} - - - - -extern const char * triarules[]; -extern const char * quadrules[]; - -void Meshing2 :: LoadRules (const char * filename) -{ - char buf[256]; - istream * ist; - char *tr1 = NULL; - - /* - ifstream ist (filename); - if (!ist.good()) - { - cerr << "Rule description file " << filename << " not found" << endl; - exit (1); - } - */ - - - if (filename) - { - // (*mycout) << "rule-filename = " << filename << endl; - ist = new ifstream (filename); - } - else - { - /* connect tetrules to one string */ - const char ** hcp; - - if (!mparam.quad) - { - hcp = triarules; - PrintMessage (3, "load internal triangle rules"); - } - else - { - hcp = quadrules; - PrintMessage (3, "load internal quad rules"); - // LoadRules ("rules/quad.rls"); - } - - int len = 0; - while (*hcp) - { - len += strlen (*hcp); - hcp++; - } - tr1 = new char[len+1]; - tr1[0] = 0; - - - if (!mparam.quad) - hcp = triarules; - else - hcp = quadrules; - - - char * tt1 = tr1; - while (*hcp) - { - strcat (tt1, *hcp); - tt1 += strlen (*hcp); - hcp++; - } - - ist = new istringstream (tr1); - } - - - if (!ist->good()) - { - cerr << "Rule description file " << filename << " not found" << endl; - delete ist; - exit (1); - } - - while (!ist->eof()) - { - buf[0] = 0; - (*ist) >> buf; - - if (strcmp (buf, "rule") == 0) - { - netrule * rule = new netrule; - rule -> LoadRule(*ist); - rules.Append (rule); - } - } - - delete ist; - delete [] tr1; -} - -} diff --git a/Netgen/libsrc/meshing/parser3.cpp b/Netgen/libsrc/meshing/parser3.cpp deleted file mode 100644 index 23ee84802e..0000000000 --- a/Netgen/libsrc/meshing/parser3.cpp +++ /dev/null @@ -1,987 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ - -extern const char * tetrules[]; - -void LoadVMatrixLine (istream & ist, DenseMatrix & m, int line) -{ - char ch; - int pnum; - float f; - - ist >> ch; - while (ch != '}') - { - ist.putback (ch); - ist >> f; - ist >> ch; - ist >> pnum; - - if (ch == 'x' || ch == 'X') - m.Elem(line, 3 * pnum - 2) = f; - if (ch == 'y' || ch == 'Y') - m.Elem(line, 3 * pnum - 1) = f; - if (ch == 'z' || ch == 'Z') - m.Elem(line, 3 * pnum ) = f; - - if (ch == 'p' || ch == 'P') - { - m.Elem(line , 3 * pnum-2) = f; - m.Elem(line+1, 3 * pnum-1) = f; - m.Elem(line+2, 3 * pnum ) = f; - } - - ist >> ch; - if (ch == ',') - ist >> ch; - } -} - - - - - -int vnetrule :: NeighbourTrianglePoint (const threeint & t1, const threeint & t2) const -{ - ARRAY<int> tr1(3); - ARRAY<int> tr2(3); - tr1.Elem(1)=t1.i1; - tr1.Elem(2)=t1.i2; - tr1.Elem(3)=t1.i3; - tr2.Elem(1)=t2.i1; - tr2.Elem(2)=t2.i2; - tr2.Elem(3)=t2.i3; - - - int ret=0; - - for (int i=1; i<=3; i++) - { - for (int j=1; j<=3; j++) - { - if ((tr1.Get(i)==tr2.Get(j) && tr1.Get((i%3)+1)==tr2.Get((j%3)+1)) || - (tr1.Get(i)==tr2.Get((j%3)+1) && tr1.Get((i%3)+1)==tr2.Get(j))) - {ret = tr2.Get((j+1)%3+1);} - } - } - - return ret; - -} - -void vnetrule :: LoadRule (istream & ist) -{ - char buf[256]; - char ch, ok; - Point3d p; - Element2d face; - int i, j, i1, i2, i3, fs, ii, ii1, ii2, ii3; - twoint edge; - DenseMatrix tempoldutonewu(30, 20), - tempoldutofreezone(30, 20), - tempoldutofreezonelimit(30, 20), - tfz(20, 20), - tfzl(20, 20); - - tempoldutonewu = 0; - tempoldutofreezone = 0; - tfz = 0; - tfzl = 0; - - - noldp = 0; - noldf = 0; - - ist.get (buf, sizeof(buf), '"'); - ist.get (ch); - ist.get (buf, sizeof(buf), '"'); - ist.get (ch); - - name = new char[strlen (buf) + 1]; - strcpy (name, buf); - // (*mycout) << "Rule " << name << " found." << endl; - - do - { - ist >> buf; - - if (strcmp (buf, "quality") == 0) - - { - ist >> quality; - } - - else if (strcmp (buf, "flags") == 0) - { - ist >> ch; - while (ch != ';') - { - flags.Append (ch); - ist >> ch; - } - } - - else if (strcmp (buf, "mappoints") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ',' - ist >> p.Z(); - ist >> ch; // ')' - - points.Append (p); - noldp++; - - tolerances.SetSize (noldp); - tolerances.Elem(noldp) = 1; - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - ist >> tolerances.Elem(noldp); - ist >> ch; // '}' - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - - else if (strcmp (buf, "mapfaces") == 0) - { - ist >> ch; - - while (ch == '(') - { - face.SetType(TRIG); - ist >> face.PNum(1); - ist >> ch; // ',' - ist >> face.PNum(2); - ist >> ch; // ',' - ist >> face.PNum(3); - ist >> ch; // ')' or ',' - if (ch == ',') - { - face.SetType(QUAD); - ist >> face.PNum(4); - ist >> ch; // ')' - } - faces.Append (face); - noldf++; - - ist >> ch; - while (ch != ';') - { - if (ch == 'd') - { - delfaces.Append (noldf); - ist >> ch; // 'e' - ist >> ch; // 'l' - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "mapedges") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> edge.i1; - ist >> ch; // ',' - ist >> edge.i2; - ist >> ch; // ')' - - edges.Append (edge); - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - - else if (strcmp (buf, "newpoints") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ',' - ist >> p.Z(); - ist >> ch; // ')' - - points.Append (p); - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - LoadVMatrixLine (ist, tempoldutonewu, - 3 * (points.Size()-noldp) - 2); - - ist >> ch; // '{' - LoadVMatrixLine (ist, tempoldutonewu, - 3 * (points.Size()-noldp) - 1); - - ist >> ch; // '{' - LoadVMatrixLine (ist, tempoldutonewu, - 3 * (points.Size()-noldp) ); - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "newfaces") == 0) - { - ist >> ch; - - while (ch == '(') - { - face.SetType(TRIG); - ist >> face.PNum(1); - ist >> ch; // ',' - ist >> face.PNum(2); - ist >> ch; // ',' - ist >> face.PNum(3); - ist >> ch; // ')' or ',' - if (ch == ',') - { - face.SetType(QUAD); - ist >> face.PNum(4); - ist >> ch; // ')' - } - faces.Append (face); - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "freezone") == 0) - { - ist >> ch; - - while (ch == '(') - { - ist >> p.X(); - ist >> ch; // ',' - ist >> p.Y(); - ist >> ch; // ',' - ist >> p.Z(); - ist >> ch; // ')' - - freezone.Append (p); - - ist >> ch; - while (ch != ';') - { - if (ch == '{') - { - LoadVMatrixLine (ist, tempoldutofreezone, - 3 * freezone.Size() - 2); - - ist >> ch; // '{' - LoadVMatrixLine (ist, tempoldutofreezone, - 3 * freezone.Size() - 1); - - ist >> ch; // '{' - LoadVMatrixLine (ist, tempoldutofreezone, - 3 * freezone.Size() ); - } - - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - else if (strcmp (buf, "freezone2") == 0) - { - int i, j, k, nfp; - Point3d p; - - nfp = 0; - ist >> ch; - - DenseMatrix hm1(3, 50), hm2(50, 50), hm3(50, 50); - hm3 = 0; - - while (ch == '{') - { - hm1 = 0; - nfp++; - LoadVMatrixLine (ist, hm1, 1); - - for (i = 1; i <= points.Size(); i++) - tfz.Elem(nfp, i) = hm1.Get(1, 3*i-2); - - - p.X() = p.Y() = p.Z() = 0; - for (i = 1; i <= points.Size(); i++) - { - p.X() += hm1.Get(1, 3*i-2) * points.Get(i).X(); - p.Y() += hm1.Get(1, 3*i-2) * points.Get(i).Y(); - p.Z() += hm1.Get(1, 3*i-2) * points.Get(i).Z(); - } - freezone.Append (p); - freezonelimit.Append (p); - - hm2 = 0; - for (i = 1; i <= 3 * noldp; i++) - hm2.Elem(i, i) = 1; - for (i = 1; i <= 3 * noldp; i++) - for (j = 1; j <= 3 * (points.Size() - noldp); j++) - hm2.Elem(j + 3 * noldp, i) = tempoldutonewu.Get(j, i); - - for (i = 1; i <= 3; i++) - for (j = 1; j <= 3 * noldp; j++) - { - double sum = 0; - for (k = 1; k <= 3 * points.Size(); k++) - sum += hm1.Get(i, k) * hm2.Get(k, j); - - hm3.Elem(i + 3 * (nfp-1), j) = sum; - } - - // (*testout) << "freepoint: " << p << endl; - - while (ch != ';') - ist >> ch; - - ist >> ch; - } - - tfzl = tfz; - - tempoldutofreezone = hm3; - tempoldutofreezonelimit = hm3; - ist.putback(ch); - } - - else if (strcmp (buf, "freezonelimit") == 0) - { - int i, j, k, nfp; - Point3d p; - - nfp = 0; - ist >> ch; - - DenseMatrix hm1(3, 50), hm2(50, 50), hm3(50, 50); - hm3 = 0; - - while (ch == '{') - { - hm1 = 0; - nfp++; - LoadVMatrixLine (ist, hm1, 1); - - for (i = 1; i <= points.Size(); i++) - tfzl.Elem(nfp, i) = hm1.Get(1, 3*i-2); - - - p.X() = p.Y() = p.Z() = 0; - for (i = 1; i <= points.Size(); i++) - { - p.X() += hm1.Get(1, 3*i-2) * points.Get(i).X(); - p.Y() += hm1.Get(1, 3*i-2) * points.Get(i).Y(); - p.Z() += hm1.Get(1, 3*i-2) * points.Get(i).Z(); - } - freezonelimit.Elem(nfp) = p; - - hm2 = 0; - for (i = 1; i <= 3 * noldp; i++) - hm2.Elem(i, i) = 1; - for (i = 1; i <= 3 * noldp; i++) - for (j = 1; j <= 3 * (points.Size() - noldp); j++) - hm2.Elem(j + 3 * noldp, i) = tempoldutonewu.Get(j, i); - - for (i = 1; i <= 3; i++) - for (j = 1; j <= 3 * noldp; j++) - { - double sum = 0; - for (k = 1; k <= 3 * points.Size(); k++) - sum += hm1.Get(i, k) * hm2.Get(k, j); - - hm3.Elem(i + 3 * (nfp-1), j) = sum; - } - - // (*testout) << "freepoint: " << p << endl; - - while (ch != ';') - ist >> ch; - - ist >> ch; - } - - tempoldutofreezonelimit = hm3; - ist.putback(ch); - } - - else if (strcmp (buf, "freeset") == 0) - { - freesets.Append (new ARRAY<int>); - - ist >> ch; - - while (ch != ';') - { - ist.putback (ch); - ist >> i; - freesets.Last()->Append(i); - ist >> ch; - } - } - - else if (strcmp (buf, "elements") == 0) - { - ist >> ch; - - while (ch == '(') - { - elements.Append (Element(TET)); - - // elements.Last().SetNP(1); - ist >> elements.Last().PNum(1); - ist >> ch; // ',' - - if (ch == ',') - { - // elements.Last().SetNP(2); - ist >> elements.Last().PNum(2); - ist >> ch; // ',' - } - if (ch == ',') - { - // elements.Last().SetNP(3); - ist >> elements.Last().PNum(3); - ist >> ch; // ',' - } - if (ch == ',') - { - // elements.Last().SetNP(4); - elements.Last().SetType(TET); - ist >> elements.Last().PNum(4); - ist >> ch; // ',' - } - if (ch == ',') - { - // elements.Last().SetNP(5); - elements.Last().SetType(PYRAMID); - ist >> elements.Last().PNum(5); - ist >> ch; // ',' - } - if (ch == ',') - { - // elements.Last().SetNP(6); - elements.Last().SetType(PRISM); - ist >> elements.Last().PNum(6); - ist >> ch; // ',' - } - - /* - orientations.Append (fourint()); - orientations.Last().i1 = elements.Last().PNum(1); - orientations.Last().i2 = elements.Last().PNum(2); - orientations.Last().i3 = elements.Last().PNum(3); - orientations.Last().i4 = elements.Last().PNum(4); - */ - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - else if (strcmp (buf, "orientations") == 0) - - { - ist >> ch; - - while (ch == '(') - { - // fourint a = fourint(); - orientations.Append (fourint()); - - ist >> orientations.Last().i1; - ist >> ch; // ',' - ist >> orientations.Last().i2; - ist >> ch; // ',' - ist >> orientations.Last().i3; - ist >> ch; // ',' - ist >> orientations.Last().i4; - ist >> ch; // ',' - - - ist >> ch; - while (ch != ';') - { - ist >> ch; - } - - ist >> ch; - } - - ist.putback (ch); - } - - - else if (strcmp (buf, "endrule") != 0) - { - PrintSysError ("Parser3d, unknown token " , buf); - } - } - while (!ist.eof() && strcmp (buf, "endrule") != 0); - - - // (*testout) << endl; - // (*testout) << Name() << endl; - // (*testout) << "no1 = " << GetNO() << endl; - - oldutonewu.SetSize (3 * (points.Size() - noldp), 3 * noldp); - oldutonewu = 0; - - for (i = 1; i <= oldutonewu.Height(); i++) - for (j = 1; j <= oldutonewu.Width(); j++) - oldutonewu.Elem(i, j) = tempoldutonewu.Elem(i, j); - - - /* - oldutofreezone = new SparseMatrixFlex (3 * freezone.Size(), 3 * noldp); - oldutofreezonelimit = new SparseMatrixFlex (3 * freezone.Size(), 3 * noldp); - - oldutofreezone -> SetSymmetric(0); - oldutofreezonelimit -> SetSymmetric(0); - */ - - /* - oldutofreezone = new DenseMatrix (3 * freezone.Size(), 3 * noldp); - oldutofreezonelimit = new DenseMatrix (3 * freezone.Size(), 3 * noldp); - - for (i = 1; i <= oldutofreezone->Height(); i++) - for (j = 1; j <= oldutofreezone->Width(); j++) - // if (j == 4 || j >= 7) - { - if (tempoldutofreezone.Elem(i, j)) - (*oldutofreezone)(i, j) = tempoldutofreezone(i, j); - if (tempoldutofreezonelimit.Elem(i, j)) - (*oldutofreezonelimit)(i, j) = tempoldutofreezonelimit(i, j); - } - */ - - - - - oldutofreezone = new DenseMatrix (freezone.Size(), points.Size()); - oldutofreezonelimit = new DenseMatrix (freezone.Size(), points.Size()); - // oldutofreezone = new SparseMatrixFlex (freezone.Size(), points.Size()); - // oldutofreezonelimit = new SparseMatrixFlex (freezone.Size(), points.Size()); - - for (i = 1; i <= freezone.Size(); i++) - for (j = 1; j <= points.Size(); j++) - { - if (tfz.Elem(i, j)) - (*oldutofreezone).Elem(i, j) = tfz.Elem(i, j); - if (tfzl.Elem(i, j)) - (*oldutofreezonelimit).Elem(i, j) = tfzl.Elem(i, j); - } - - /* - (*testout) << "Rule " << Name() << endl; - (*testout) << "oldutofreezone = " << (*oldutofreezone) << endl; - (*testout) << "oldutofreezonelimit = " << (*oldutofreezonelimit) << endl; - */ - - freezonepi.SetSize (freezone.Size()); - for (i = 1; i <= freezonepi.Size(); i++) - freezonepi.Elem(i) = 0; - for (i = 1; i <= freezone.Size(); i++) - for (j = 1; j <= noldp; j++) - if (Dist (freezone.Get(i), points.Get(j)) < 1e-8) - freezonepi.Elem(i) = j; - - - - - for (i = 1; i <= elements.Size(); i++) - { - if (elements.Elem(i).GetNP() == 4) - { - orientations.Append (fourint()); - orientations.Last().i1 = elements.Get(i).PNum(1); - orientations.Last().i2 = elements.Get(i).PNum(2); - orientations.Last().i3 = elements.Get(i).PNum(3); - orientations.Last().i4 = elements.Get(i).PNum(4); - } - if (elements.Elem(i).GetNP() == 5) - { - orientations.Append (fourint()); - orientations.Last().i1 = elements.Get(i).PNum(1); - orientations.Last().i2 = elements.Get(i).PNum(2); - orientations.Last().i3 = elements.Get(i).PNum(3); - orientations.Last().i4 = elements.Get(i).PNum(5); - - orientations.Append (fourint()); - orientations.Last().i1 = elements.Get(i).PNum(1); - orientations.Last().i2 = elements.Get(i).PNum(3); - orientations.Last().i3 = elements.Get(i).PNum(4); - orientations.Last().i4 = elements.Get(i).PNum(5); - } - } - - - - if (freesets.Size() == 0) - { - freesets.Append (new ARRAY<int>); - for (i = 1; i <= freezone.Size(); i++) - freesets.Elem(1)->Append(i); - } - - - // testout << "Freezone: " << endl; - - // for (i = 1; i <= freezone.Size(); i++) - // (*testout) << "freepoint: " << freezone.Get(i) << endl; - Vector vp(points.Size()), vfp(freezone.Size()); - - - if (quality < 100) - { - for (i = 1; i <= 3; i++) - { - for (j = 1; j <= points.Size(); j++) - vp.Elem(j) = points.Get(j).X(i); - oldutofreezone->Mult(vp, vfp); - for (j = 1; j <= freezone.Size(); j++) - freezone.Elem(j).X(i) = vfp.Get(j); - } - // for (i = 1; i <= freezone.Size(); i++) - // (*testout) << "freepoint: " << freezone.Get(i) << endl; - } - - - for (fs = 1; fs <= freesets.Size(); fs++) - { - freefaces.Append (new ARRAY<threeint>); - - ARRAY<int> & freeset = *freesets.Elem(fs); - ARRAY<threeint> & freesetfaces = *freefaces.Last(); - - for (ii1 = 1; ii1 <= freeset.Size(); ii1++) - for (ii2 = 1; ii2 <= freeset.Size(); ii2++) - for (ii3 = 1; ii3 <= freeset.Size(); ii3++) - if (ii1 < ii2 && ii1 < ii3 && ii2 != ii3) - { - i1 = freeset.Get(ii1); - i2 = freeset.Get(ii2); - i3 = freeset.Get(ii3); - - Vec3d v1, v2, n; - - v1 = freezone.Get(i3) - freezone.Get(i1); - v2 = freezone.Get(i2) - freezone.Get(i1); - n = Cross (v1, v2); - n /= n.Length(); - // (*testout) << "i1,2,3 = " << i1 << ", " << i2 << ", " << i3 << endl; - // (*testout) << "v1 = " << v1 << " v2 = " << v2 << " n = " << n << endl; - ok = 1; - for (ii = 1; ii <= freeset.Size(); ii++) - { - i = freeset.Get(ii); - // (*testout) << "i = " << i << endl; - if (i != i1 && i != i2 && i != i3) - if ( (freezone.Get(i) - freezone.Get(i1)) * n < 0 ) ok = 0; - } - - if (ok) - { - freesetfaces.Append (threeint()); - freesetfaces.Last().i1 = i1; - freesetfaces.Last().i2 = i2; - freesetfaces.Last().i3 = i3; - } - } - } - - for (fs = 1; fs <= freesets.Size(); fs++) - { - freefaceinequ.Append (new DenseMatrix (freefaces.Get(fs)->Size(), 4)); - } - - - { - char ok; - int minn; - // ARRAY<int> pnearness (noldp); - pnearness.SetSize (noldp); - - for (i = 1; i <= pnearness.Size(); i++) - pnearness.Elem(i) = INT_MAX/10; - - for (j = 1; j <= GetNP(1); j++) - pnearness.Elem(GetPointNr (1, j)) = 0; - - do - { - ok = 1; - - for (i = 1; i <= noldf; i++) - { - minn = INT_MAX/10; - for (j = 1; j <= GetNP(i); j++) - minn = min2 (minn, pnearness.Get(GetPointNr (i, j))); - - for (j = 1; j <= GetNP(i); j++) - if (pnearness.Get(GetPointNr (i, j)) > minn+1) - { - ok = 0; - pnearness.Elem(GetPointNr (i, j)) = minn+1; - } - } - - for (i = 1; i <= elements.Size(); i++) - if (elements.Get(i).GetNP() == 6) - { - for (j = 1; j <= 3; j++) - { - int pi1 = elements.Get(i).PNum(j); - int pi2 = elements.Get(i).PNum(j+3); - - if (pnearness.Get(pi1) > pnearness.Get(pi2)+1) - { - ok = 0; - pnearness.Elem(pi1) = pnearness.Get(pi2)+1; - } - if (pnearness.Get(pi2) > pnearness.Get(pi1)+1) - { - ok = 0; - pnearness.Elem(pi2) = pnearness.Get(pi1)+1; - } - } - } - } - while (!ok); - - int maxpnearness = 0; - for (i = 1; i <= pnearness.Size(); i++) - maxpnearness = max2 (maxpnearness, pnearness.Get(i)); - - - fnearness.SetSize (noldf); - - for (i = 1; i <= noldf; i++) - { - fnearness.Elem(i) = 0; - for (j = 1; j <= GetNP(i); j++) - fnearness.Elem(i) += pnearness.Get(GetPointNr (i, j)); - } - } - - - //Table of edges: - for (fs = 1; fs <= freesets.Size(); fs++) - { - freeedges.Append (new ARRAY<twoint>); - - // ARRAY<int> & freeset = *freesets.Get(fs); - ARRAY<twoint> & freesetedges = *freeedges.Last(); - ARRAY<threeint> & freesetfaces = *freefaces.Get(fs); - int k,l; - INDEX ind; - - for (k = 1; k <= freesetfaces.Size(); k++) - { - threeint tr = freesetfaces.Get(k); - - for (l = k+1; l <= freesetfaces.Size(); l++) - { - ind = NeighbourTrianglePoint(freesetfaces.Get(k), freesetfaces.Get(l)); - if (!ind) continue; - - INDEX_3 f1(freesetfaces.Get(k).i1, - freesetfaces.Get(k).i2, - freesetfaces.Get(k).i3); - INDEX_3 f2(freesetfaces.Get(l).i1, - freesetfaces.Get(l).i2, - freesetfaces.Get(l).i3); - INDEX_2 edge(0, 0); - for (int f11 = 1; f11 <= 3; f11++) - for (int f12 = 1; f12 <= 3; f12++) - if (f11 != f12) - for (int f21 = 1; f21 <= 3; f21++) - for (int f22 = 1; f22 <= 3; f22++) - if (f1.I(f11) == f2.I(f21) && f1.I(f12) == f2.I(f22)) - { - edge.I(1) = f1.I(f11); - edge.I(2) = f1.I(f12); - } - // (*testout) << "edge = " << edge.I(1) << "-" << edge.I(2) << endl; - // (*testout) << "ind = " << ind << " edge = " << edge << endl; - for (int eli = 1; eli <= GetNOldF(); eli++) - { - if (GetNP(eli) == 4) - { - for (int elr = 1; elr <= 4; elr++) - { - if (GetPointNrMod (eli, elr) == edge.I(1) && - GetPointNrMod (eli, elr+2) == edge.I(2)) - { - /* - (*testout) << "edge is diagonal of rectangle" << endl; - (*testout) << "edge = " << edge.I(1) << "-" << edge.I(2) << endl; - (*testout) << "ind = " << ind << endl; - */ - ind = 0; - } - - } - } - } - - if (ind) - { - /* - (*testout) << "new edge from face " << k - << " = (" << freesetfaces.Get(k).i1 - << ", " << freesetfaces.Get(k).i2 - << ", " << freesetfaces.Get(k).i3 - << "), point " << ind << endl; - */ - freesetedges.Append(twoint(k,ind)); - } - } - } - } - -} - - - - - -void Meshing3 :: LoadRules (const char * filename, const char ** prules) -{ - char buf[256]; - istream * ist; - char *tr1 = NULL; - - if (filename) - { - PrintMessage (3, "rule-filename = ", filename); - ist = new ifstream (filename); - } - else - { - /* connect tetrules to one string */ - PrintMessage (3, "Use internal rules"); - if (!prules) prules = tetrules; - - const char ** hcp = prules; - int len = 0; - while (*hcp) - { - len += strlen (*hcp); - hcp++; - } - tr1 = new char[len+1]; - tr1[0] = 0; - hcp = prules; // tetrules; - - - char * tt1 = tr1; - while (*hcp) - { - strcat (tt1, *hcp); - tt1 += strlen (*hcp); - hcp++; - } - - ist = new istringstream (tr1); - } - - if (!ist->good()) - { - cerr << "Rule description file " << filename << " not found" << endl; - delete ist; - exit (1); - } - - while (!ist->eof()) - { - buf[0] = 0; - (*ist) >> buf; - - if (strcmp (buf, "rule") == 0) - { - vnetrule * rule = new vnetrule; - rule -> LoadRule(*ist); - rules.Append (rule); - if (!rule->TestOk()) - { - PrintSysError ("Parser3d: Rule ", rules.Size(), " not ok"); - exit (1); - } - } - else if (strcmp (buf, "tolfak") == 0) - { - (*ist) >> tolfak; - } - } - delete ist; - delete [] tr1; -} -} diff --git a/Netgen/libsrc/meshing/prism2rls.cpp b/Netgen/libsrc/meshing/prism2rls.cpp deleted file mode 100644 index 7e696554c0..0000000000 --- a/Netgen/libsrc/meshing/prism2rls.cpp +++ /dev/null @@ -1,457 +0,0 @@ -namespace netgen -{ -const char * prismrules2[] = { -"tolfak 0.5\n",\ -"\n",\ -"rule \"prism on quad\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3, 6);\n",\ -"(1, 5, 6, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 3, 4, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 5 6 8;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on quad, one trig\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(1, 5, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3, 6);\n",\ -"(1, 5, 6, 4);\n",\ -"(4, 6, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 3, 4, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 5 6 8;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 2 quad\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 6, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 2 quad, one trig\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(1, 5, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 6, 4);\n",\ -"(4, 6, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 2 quada\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(5, 1, 4, 6) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3, 6);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 6;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"fill prism\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(5, 1, 4, 6) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 3 quad, one trig\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(5, 1, 4, 6) del;\n",\ -"(1, 5, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 6, 3);\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"flat prism\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(0.5, 0.866, 0);\n",\ -"(0, 0, -1);\n",\ -"(1, 0, -1);\n",\ -"(0.5, 0.866, -1);\n",\ -"\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(5, 4, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 4);\n",\ -"(4, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(5, 3, 6);\n",\ -"(3, 1, 6);\n",\ -"(6, 1, 4);\n",\ -"\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5, 4, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"endrule\n",\ -"\n",\ -0}; -} diff --git a/Netgen/libsrc/meshing/prism2rls_2.cpp b/Netgen/libsrc/meshing/prism2rls_2.cpp deleted file mode 100644 index baf0bef388..0000000000 --- a/Netgen/libsrc/meshing/prism2rls_2.cpp +++ /dev/null @@ -1,446 +0,0 @@ -namespace netgen -{ -const char * prismrules2[] = { -"tolfak 0.5\n",\ -"\n",\ -"rule \"prism on quad\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3, 6);\n",\ -"(1, 5, 6, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 3, 4, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on quad, one trig\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(1, 5, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3, 6);\n",\ -"(1, 5, 6, 4);\n",\ -"(4, 6, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 3, 4, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 2 quad\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 6, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 2 quad, one trig\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(1, 5, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 6, 4);\n",\ -"(4, 6, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 2 quada\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(5, 1, 4, 6) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3, 6);\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5 6 7;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 6;\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"fill prism\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(5, 1, 4, 6) del;\n",\ -"(1, 5, 2) del;\n",\ -"(4, 3, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"prism on 3 quad, one trig\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0, -0.86);\n",\ -"(0.5, 1, -0.86);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 5, 6, 3) del;\n",\ -"(5, 1, 4, 6) del;\n",\ -"(1, 5, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 6, 3);\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 5, 2, 4, 6, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5;\n",\ -"\n",\ -"freeset\n",\ -"2 3 4 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"flat prism\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(0.5, 0.866, 0);\n",\ -"(0, 0, -1);\n",\ -"(1, 0, -1);\n",\ -"(0.5, 0.866, -1);\n",\ -"\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(5, 4, 6) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 4);\n",\ -"(4, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(5, 3, 6);\n",\ -"(3, 1, 6);\n",\ -"(6, 1, 4);\n",\ -"\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5, 4, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"endrule\n",\ -"\n",\ -0}; -} diff --git a/Netgen/libsrc/meshing/pyramid2rls.cpp b/Netgen/libsrc/meshing/pyramid2rls.cpp deleted file mode 100644 index a97e7f13e5..0000000000 --- a/Netgen/libsrc/meshing/pyramid2rls.cpp +++ /dev/null @@ -1,309 +0,0 @@ -namespace netgen -{ -const char * pyramidrules2[] = { -"tolfak 0.5\n",\ -"\n",\ -"rule \"Pyramid on quad\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.5, -0.5) \n",\ -" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ -" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"small Pyramid on quad\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.5, -0.1 )\n",\ -" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ -" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"connect pyramid\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"pyramid with one trig\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 1, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 };\n",\ -"{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 };\n",\ -"{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 };\n",\ -"{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 };\n",\ -"{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P2 };\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 3, 4, 5);\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"freeset\n",\ -"2 3 5 6;\n",\ -"freeset\n",\ -"3 4 5 7;\n",\ -"freeset \n",\ -"1 4 5 8;\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"pyramid with two trig\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 1, 5) del;\n",\ -"(3, 2, 5) del;\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"pyramid with two trig, left\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 1, 5) del;\n",\ -"(1, 4, 5) del;\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(3, 4, 5);\n",\ -"(2, 3, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff --git a/Netgen/libsrc/meshing/pyramidrls.cpp b/Netgen/libsrc/meshing/pyramidrls.cpp deleted file mode 100644 index d4e997c1fe..0000000000 --- a/Netgen/libsrc/meshing/pyramidrls.cpp +++ /dev/null @@ -1,263 +0,0 @@ -namespace netgen -{ -const char * pyramidrules[] = { -"tolfak 0.5\n",\ -"\n",\ -"rule \"Pyramid on quad\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.5, -0.5) \n",\ -" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ -" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"small Pyramid on quad\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.5, -0.1 )\n",\ -" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ -" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"connect pyramid\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 5);\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"pyramid with one trig\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 1, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(2, 3, 5);\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 };\n",\ -"{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 };\n",\ -"{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P3 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 };\n",\ -"{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 };\n",\ -"{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P3 };\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 3, 4, 5);\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"freeset\n",\ -"2 3 5 6;\n",\ -"freeset\n",\ -"3 4 5 7;\n",\ -"freeset \n",\ -"1 4 5 8;\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"pyramid with two trig\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(1, 1, 0);\n",\ -"(0, 1, 0);\n",\ -"(0.5, 0.5, -0.5);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3, 4) del;\n",\ -"(2, 1, 5) del;\n",\ -"(3, 2, 5) del;\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(3, 4, 5);\n",\ -"(4, 1, 5);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff --git a/Netgen/libsrc/meshing/quadrls.cpp b/Netgen/libsrc/meshing/quadrls.cpp deleted file mode 100644 index 57fb010144..0000000000 --- a/Netgen/libsrc/meshing/quadrls.cpp +++ /dev/null @@ -1,765 +0,0 @@ -namespace netgen -{ -const char * quadrules[] = { -"rule \"Free Quad (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2 } { };\n",\ -"(0, 1) { } { };\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"(4, 3);\n",\ -"(1, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2 } { };\n",\ -"(-0.5, 1.5) { -0.5 X2 } { };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Quad (5)\"\n",\ -"\n",\ -"quality 5\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2 } { };\n",\ -"(0, 1) { } { };\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"(4, 3);\n",\ -"(1, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2 } { };\n",\ -"(-0.5, 1.5) { -0.5 X2 } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2 } { };\n",\ -"(0, 1) { } { };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Quad Right (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 1) { } { 1 y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.5, 1.5) { } { 1.5 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Quad P Right (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 1) { -1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { -1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Quad Right PL (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(-0.2, 0.5) { -0.1 X2, -0.1 X3, 0.6 X4 } { -0.1 Y2, -0.1 Y3, 0.6 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3);\n",\ -"(1, 3, 4);\n",\ -"(1, 2, 4);\n",\ -"(4, 2, 3);\n",\ -"\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Quad (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left P Quad (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 0.5) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Quad RP (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0, 1);\n",\ -"(1, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.5) { 0.6 X2, 0.6 X4, -0.1 X3 } { 0.6 Y2, 0.6 Y4, -0.1 Y3 };\n",\ -"(1, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X4 } { 0.5 Y2, 0.5 Y4 };\n",\ -"(1, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"(0, 1) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 4);\n",\ -"(1, 4, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Two left (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"(4, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Two Right (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 120 (1)\"\n",\ -"\n",\ -"quality 1000\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left 120 (1)\"\n",\ -"\n",\ -"quality 1000\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(-0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Right (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(4, 1) del;\n",\ -"\n",\ -"\n",\ -"newlines\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1.5) { -0.25 X2, 0.75 X3, 0.75 X4 } { 0.75 Y3, 0.75 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Fill Quad\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 4) del;\n",\ -"(4, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Fill Triangle\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.86);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(0.5, 0.86) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 60 (1)\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 0.5, 0, 1.0 };\n",\ -"(0.5, 0.866) { 0.6, 0, 0.8 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Vis A Vis (2)\"\n",\ -"\n",\ -"quality 2\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1);\n",\ -"(0, 1);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ -"(1, 1) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1) { 1 X4 } { 1 Y4 };\n",\ -"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"orientations\n",\ -"(1, 3, 4);\n",\ -"(2, 3, 4);\n",\ -"(1, 2, 3);\n",\ -"(1, 2, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"2 h Vis A Vis (1)\"\n",\ -"\n",\ -"quality 3000\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1.732);\n",\ -"(0, 1.732);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 5);\n",\ -"(5, 4);\n",\ -"(3, 5);\n",\ -"(5, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1.732) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1.732) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 5);\n",\ -"(3, 4, 5);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff --git a/Netgen/libsrc/meshing/refine.cpp b/Netgen/libsrc/meshing/refine.cpp deleted file mode 100644 index f7578d3394..0000000000 --- a/Netgen/libsrc/meshing/refine.cpp +++ /dev/null @@ -1,721 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ - void Refinement :: Refine (Mesh & mesh) - { - // reduce 2nd order - mesh.ComputeNVertices(); - mesh.SetNP(mesh.GetNV()); - - - INDEX_2_HASHTABLE<int> between(mesh.GetNP() + 5); - - int oldne, oldns, oldnf; - - // refine edges - - ARRAY<EdgePointGeomInfo,PointIndex::BASE> epgi; - - oldns = mesh.GetNSeg(); - for (SegmentIndex si = 0; si < oldns; si++) - { - const Segment & el = mesh.LineSegment(si); - - INDEX_2 i2 = INDEX_2::Sort(el.p1, el.p2); - PointIndex pinew; - EdgePointGeomInfo ngi; - - if (between.Used(i2)) - { - pinew = between.Get(i2); - ngi = epgi[pinew]; - } - else - { - Point3d pnew; - - PointBetween (mesh.Point (el.p1), - mesh.Point (el.p2), 0.5, - el.surfnr1, el.surfnr2, - el.epgeominfo[0], el.epgeominfo[1], - pnew, ngi); - - pinew = mesh.AddPoint (pnew); - between.Set (i2, pinew); - - - if (pinew >= epgi.Size()+PointIndex::BASE) - epgi.SetSize (pinew+1-PointIndex::BASE); - epgi[pinew] = ngi; - } - - Segment ns1 = el; - Segment ns2 = el; - ns1.p2 = pinew; - ns1.epgeominfo[1] = ngi; - ns2.p1 = pinew; - ns2.epgeominfo[0] = ngi; - - mesh.LineSegment(si) = ns1; - mesh.AddSegment (ns2); - } - - // refine surface elements - ARRAY<PointGeomInfo,PointIndex::BASE> surfgi (8*mesh.GetNP()); - for (int i = PointIndex::BASE; - i < surfgi.Size()+PointIndex::BASE; i++) - surfgi[i].trignum = -1; - - - oldnf = mesh.GetNSE(); - for (SurfaceElementIndex sei = 0; sei < oldnf; sei++) - { - int j, k; - const Element2d & el = mesh.SurfaceElement(sei); - - switch (el.GetType()) - { - case TRIG: - case TRIG6: - { - ArrayMem<int,6> pnums(6); - ArrayMem<PointGeomInfo,6> pgis(6); - - static int betw[3][3] = - { { 2, 3, 4 }, - { 1, 3, 5 }, - { 1, 2, 6 } }; - - for (j = 1; j <= 3; j++) - { - pnums.Elem(j) = el.PNum(j); - pgis.Elem(j) = el.GeomInfoPi(j); - } - - for (j = 0; j < 3; j++) - { - PointIndex pi1 = pnums.Elem(betw[j][0]); - PointIndex pi2 = pnums.Elem(betw[j][1]); - - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - - Point3d pb; - PointGeomInfo pgi; - PointBetween (mesh.Point (pi1), - mesh.Point (pi2), 0.5, - mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), - el.GeomInfoPi (betw[j][0]), - el.GeomInfoPi (betw[j][1]), - pb, pgi); - - - pgis.Elem(4+j) = pgi; - if (between.Used(i2)) - pnums.Elem(4+j) = between.Get(i2); - else - { - pnums.Elem(4+j) = mesh.AddPoint (pb); - between.Set (i2, pnums.Get(4+j)); - } - - if (surfgi.Size() < pnums.Elem(4+j)) - surfgi.SetSize (pnums.Elem(4+j)); - surfgi.Elem(pnums.Elem(4+j)) = pgis.Elem(4+j); - } - - - static int reftab[4][3] = - { { 1, 6, 5 }, - { 2, 4, 6 }, - { 3, 5, 4 }, - { 6, 4, 5 } }; - - int ind = el.GetIndex(); - for (j = 0; j < 4; j++) - { - Element2d nel(TRIG); - for (k = 1; k <= 3; k++) - { - nel.PNum(k) = pnums.Get(reftab[j][k-1]); - nel.GeomInfoPi(k) = pgis.Get(reftab[j][k-1]); - } - nel.SetIndex(ind); - - if (j == 0) - mesh.SurfaceElement(sei) = nel; - else - mesh.AddSurfaceElement(nel); - } - break; - } - case QUAD: - case QUAD6: - case QUAD8: - { - ArrayMem<int,9> pnums(9); - ArrayMem<PointGeomInfo,9> pgis(9); - - static int betw[5][3] = - { { 1, 2, 5 }, - { 2, 3, 6 }, - { 3, 4, 7 }, - { 1, 4, 8 }, - { 1, 3, 9 } }; - - for (j = 1; j <= 4; j++) - { - pnums.Elem(j) = el.PNum(j); - pgis.Elem(j) = el.GeomInfoPi(j); - } - - for (j = 0; j < 5; j++) - { - int pi1 = pnums.Elem(betw[j][0]); - int pi2 = pnums.Elem(betw[j][1]); - - INDEX_2 i2 (pi1, pi2); - i2.Sort(); - - if (between.Used(i2)) - { - pnums.Elem(5+j) = between.Get(i2); - pgis.Elem(5+j) = surfgi.Get(pnums.Elem(4+j)); - } - else - { - Point3d pb; - PointBetween (mesh.Point (pi1), - mesh.Point (pi2), 0.5, - mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), - el.GeomInfoPi (betw[j][0]), - el.GeomInfoPi (betw[j][1]), - pb, pgis.Elem(5+j)); - - pnums.Elem(5+j) = mesh.AddPoint (pb); - - between.Set (i2, pnums.Get(5+j)); - - if (surfgi.Size() < pnums.Elem(5+j)) - surfgi.SetSize (pnums.Elem(5+j)); - surfgi.Elem(pnums.Elem(5+j)) = pgis.Elem(5+j); - } - } - - static int reftab[4][4] = - { - { 1, 5, 9, 8 }, - { 5, 2, 6, 9 }, - { 8, 9, 7, 4 }, - { 9, 6, 3, 7 } }; - - int ind = el.GetIndex(); - for (j = 0; j < 4; j++) - { - Element2d nel(QUAD); - for (k = 1; k <= 4; k++) - { - nel.PNum(k) = pnums.Get(reftab[j][k-1]); - nel.GeomInfoPi(k) = pgis.Get(reftab[j][k-1]); - } - nel.SetIndex(ind); - - if (j == 0) - mesh.SurfaceElement(sei) = nel; - else - mesh.AddSurfaceElement(nel); - } - break; - } - default: - PrintSysError ("Refine: undefined surface element type ", int(el.GetType())); - } - } - - // refine volume elements - oldne = mesh.GetNE(); - for (ElementIndex ei = 0; ei < oldne; ei++) - { - int j, k; - - const Element & el = mesh.VolumeElement(ei); - switch (el.GetType()) - { - case TET: - case TET10: - { - ArrayMem<int,10> pnums(10); - static int betw[6][3] = - { { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 4, 10 } }; - - int elrev = el.flags.reverse; - - for (j = 1; j <= 4; j++) - pnums.Elem(j) = el.PNum(j); - if (elrev) - swap (pnums.Elem(3), pnums.Elem(4)); - - for (j = 0; j < 6; j++) - { - INDEX_2 i2; - i2.I1() = pnums.Get(betw[j][0]); - i2.I2() = pnums.Get(betw[j][1]); - i2.Sort(); - - if (between.Used(i2)) - pnums.Elem(5+j) = between.Get(i2); - else - { - pnums.Elem(5+j) = mesh.AddPoint - (Center (mesh.Point(i2.I1()), - mesh.Point(i2.I2()))); - between.Set (i2, pnums.Elem(5+j)); - } - } - - static int reftab[8][4] = - { { 1, 5, 6, 7 }, - { 5, 2, 8, 9 }, - { 6, 8, 3, 10 }, - { 7, 9, 10, 4 }, - { 5, 6, 7, 9 }, - { 5, 6, 9, 8 }, - { 6, 7, 9, 10 }, - { 6, 8, 10, 9 } }; - /* - { { 1, 5, 6, 7 }, - { 5, 2, 8, 9 }, - { 6, 8, 3, 10 }, - { 7, 9, 10, 4 }, - { 5, 6, 7, 9 }, - { 5, 6, 8, 9 }, - { 6, 7, 9, 10 }, - { 6, 8, 9, 10 } }; - */ - static int reverse[8] = - { - 0, 0, 0, 0, 0, 1, 0, 1 - }; - - int ind = el.GetIndex(); - for (j = 0; j < 8; j++) - { - Element nel; - for (k = 1; k <= 4; k++) - nel.PNum(k) = pnums.Get(reftab[j][k-1]); - nel.SetIndex(ind); - nel.flags.reverse = reverse[j]; - if (elrev) - { - nel.flags.reverse = 1 - nel.flags.reverse; - swap (nel.PNum(3), nel.PNum(4)); - } - - if (j == 0) - mesh.VolumeElement(ei) = nel; - else - mesh.AddVolumeElement (nel); - } - break; - } - case HEX: - { - ArrayMem<int,27> pnums(27); - static int betw[13][3] = - { { 1, 2, 9 }, - { 3, 4, 10 }, - { 4, 1, 11 }, - { 2, 3, 12 }, - { 5, 6, 13 }, - { 7, 8, 14 }, - { 8, 5, 15 }, - { 6, 7, 16 }, - { 1, 5, 17 }, - { 2, 6, 18 }, - { 3, 7, 19 }, - { 4, 8, 20 }, - { 2, 8, 21 }, - }; - - static int fbetw[12][3] = - { { 1, 3, 22 }, - { 2, 4, 22 }, - { 5, 7, 23 }, - { 6, 8, 23 }, - { 1, 6, 24 }, - { 2, 5, 24 }, - { 2, 7, 25 }, - { 3, 6, 25 }, - { 3, 8, 26 }, - { 4, 7, 26 }, - { 1, 8, 27 }, - { 4, 5, 27 }, - }; - - - pnums = -1; - - for (j = 1; j <= 8; j++) - pnums.Elem(j) = el.PNum(j); - - - for (j = 0; j < 13; j++) - { - INDEX_2 i2; - i2.I1() = pnums.Get(betw[j][0]); - i2.I2() = pnums.Get(betw[j][1]); - i2.Sort(); - - if (between.Used(i2)) - pnums.Elem(9+j) = between.Get(i2); - else - { - pnums.Elem(9+j) = mesh.AddPoint - (Center (mesh.Point(i2.I1()), - mesh.Point(i2.I2()))); - between.Set (i2, pnums.Elem(9+j)); - } - } - - for (j = 0; j < 6; j++) - { - INDEX_2 i2a, i2b; - i2a.I1() = pnums.Get(fbetw[2*j][0]); - i2a.I2() = pnums.Get(fbetw[2*j][1]); - i2a.Sort(); - i2b.I1() = pnums.Get(fbetw[2*j+1][0]); - i2b.I2() = pnums.Get(fbetw[2*j+1][1]); - i2b.Sort(); - - if (between.Used(i2a)) - pnums.Elem(22+j) = between.Get(i2a); - else if (between.Used(i2b)) - pnums.Elem(22+j) = between.Get(i2b); - else - { - pnums.Elem(22+j) = mesh.AddPoint - (Center (mesh.Point(i2a.I1()), - mesh.Point(i2a.I2()))); - - between.Set (i2a, pnums.Elem(22+j)); - } - } - - static int reftab[8][8] = - { { 1, 9, 22, 11, 17, 24, 21, 27 }, - { 9, 2, 12, 22, 24, 18, 25, 21 }, - { 11, 22, 10, 4, 27, 21, 26, 20}, - { 22, 12, 3, 10, 21, 25, 19, 26}, - { 17, 24, 21, 27, 5, 13, 23, 15}, - { 24, 18, 25, 21, 13, 6, 16, 23}, - { 27, 21, 26, 20, 15, 23, 14, 8}, - { 21, 25, 19, 26, 23, 16, 7, 14} }; - - - int ind = el.GetIndex(); - for (j = 0; j < 8; j++) - { - Element nel(HEX); - for (k = 1; k <= 8; k++) - nel.PNum(k) = pnums.Get(reftab[j][k-1]); - nel.SetIndex(ind); - - if (j == 0) - mesh.VolumeElement(ei) = nel; - else - mesh.AddVolumeElement (nel); - } - break; - } - case PRISM: - { - ArrayMem<int,18> pnums(18); - static int betw[9][3] = - { { 3, 1, 7 }, - { 1, 2, 8 }, - { 3, 2, 9 }, - { 6, 4, 10 }, - { 4, 5, 11 }, - { 6, 5, 12 }, - { 1, 4, 13 }, - { 3, 6, 14 }, - { 2, 5, 15 }, - }; - - static int fbetw[6][3] = - { { 1, 6, 16 }, - { 3, 4, 16 }, - { 1, 5, 17 }, - { 2, 4, 17 }, - { 2, 6, 18 }, - { 3, 5, 18 }, - }; - - //int elrev = el.flags.reverse; - pnums = -1; - - for (j = 1; j <= 6; j++) - pnums.Elem(j) = el.PNum(j); - // if (elrev) - // swap (pnums.Elem(3), pnums.Elem(4)); - - for (j = 0; j < 9; j++) - { - INDEX_2 i2; - i2.I1() = pnums.Get(betw[j][0]); - i2.I2() = pnums.Get(betw[j][1]); - i2.Sort(); - - if (between.Used(i2)) - pnums.Elem(7+j) = between.Get(i2); - else - { - pnums.Elem(7+j) = mesh.AddPoint - (Center (mesh.Point(i2.I1()), - mesh.Point(i2.I2()))); - between.Set (i2, pnums.Elem(7+j)); - } - } - - for (j = 0; j < 3; j++) - { - INDEX_2 i2a, i2b; - i2a.I1() = pnums.Get(fbetw[2*j][0]); - i2a.I2() = pnums.Get(fbetw[2*j][1]); - i2a.Sort(); - i2b.I1() = pnums.Get(fbetw[2*j+1][0]); - i2b.I2() = pnums.Get(fbetw[2*j+1][1]); - i2b.Sort(); - - if (between.Used(i2a)) - pnums.Elem(16+j) = between.Get(i2a); - else if (between.Used(i2b)) - pnums.Elem(16+j) = between.Get(i2b); - else - { - pnums.Elem(16+j) = mesh.AddPoint - (Center (mesh.Point(i2a.I1()), - mesh.Point(i2a.I2()))); - - between.Set (i2a, pnums.Elem(16+j)); - } - } - - - static int reftab[8][6] = - { { 1, 8, 7, 13, 17, 16 }, - { 7, 8, 9, 16, 17, 18 }, - { 7, 9, 3, 16, 18, 14 }, - { 8, 2, 9, 17, 15, 18 }, - { 13, 17, 16, 4, 11, 10 }, - { 16, 17, 18, 10, 11, 12 }, - { 16, 18, 14, 10, 12, 6 }, - { 17, 15, 18, 11, 5, 12 } }; - - - int ind = el.GetIndex(); - for (j = 0; j < 8; j++) - { - Element nel(PRISM); - for (k = 1; k <= 6; k++) - nel.PNum(k) = pnums.Get(reftab[j][k-1]); - nel.SetIndex(ind); - - - //nel.flags.reverse = reverse[j]; - //if (elrev) - // { - //nel.flags.reverse = 1 - nel.flags.reverse; - //swap (nel.PNum(3), nel.PNum(4)); - - - if (j == 0) - mesh.VolumeElement(ei) = nel; - else - mesh.AddVolumeElement (nel); - } - break; - } - default: - PrintSysError ("Refine: undefined volume element type ", int(el.GetType())); - } - } - - - // update identification tables - for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) - { - ARRAY<int,PointIndex::BASE> identmap; - mesh.GetIdentifications().GetMap (i, identmap); - - for (int j = 1; j <= between.GetNBags(); j++) - for (int k = 1; k <= between.GetBagSize(j); k++) - { - INDEX_2 i2; - int newpi; - between.GetData (j, k, i2, newpi); - INDEX_2 oi2(identmap.Get(i2.I1()), - identmap.Get(i2.I2())); - oi2.Sort(); - if (between.Used (oi2)) - { - int onewpi = between.Get(oi2); - mesh.GetIdentifications().Add (newpi, onewpi, i); - } - } - - } - - mesh.ComputeNVertices(); - return; - - int cnttrials = 10; - int wrongels = 0; - for (int i = 1; i <= mesh.GetNE(); i++) - if (mesh.VolumeElement(i).Volume(mesh.Points()) < 0) - { - wrongels++; - mesh.VolumeElement(i).flags.badel = 1; - } - else - mesh.VolumeElement(i).flags.badel = 0; - - if (wrongels) - { - cout << "WARNING: " << wrongels << " with wrong orientation found" << endl; - - int np = mesh.GetNP(); - ARRAY<Point3d> should(np); - ARRAY<Point3d> can(np); - for (int i = 1; i <= np; i++) - { - should.Elem(i) = can.Elem(i) = mesh.Point(i); - } - for (int i = 1; i <= between.GetNBags(); i++) - for (int j = 1; j <= between.GetBagSize(i); j++) - { - INDEX_2 parent; - int child; - between.GetData (i, j, parent, child); - can.Elem(child) = Center (can.Elem(parent.I1()), - can.Elem(parent.I2())); - } - - BitArray boundp(np); - boundp.Clear(); - for (int i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & sel = mesh.SurfaceElement(i); - for (int j = 1; j <= sel.GetNP(); j++) - boundp.Set(sel.PNum(j)); - } - - - double lam = 0.5; - - while (lam < 0.9 && cnttrials > 0) - { - lam = 2; - do - { - lam *= 0.5; - cnttrials--; - - cout << "lam = " << lam << endl; - - for (int i = 1; i <= np; i++) - if (boundp.Test(i)) - { - for (int j = 1; j <= 3; j++) - mesh.Point(i).X(j) = - lam * should.Get(i).X(j) + - (1-lam) * can.Get(i).X(j); - } - else - mesh.Point(i) = can.Get(i); - - - BitArray free (mesh.GetNP()), fhelp(mesh.GetNP()); - free.Clear(); - for (int i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement(i); - if (el.Volume(mesh.Points()) < 0) - for (int j = 1; j <= el.GetNP(); j++) - free.Set (el.PNum(j)); - } - for (int k = 1; k <= 3; k++) - { - fhelp.Clear(); - for (int i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement(i); - int freeel = 0; - for (int j = 1; j <= el.GetNP(); j++) - if (free.Test(el.PNum(j))) - freeel = 1; - if (freeel) - for (int j = 1; j <= el.GetNP(); j++) - fhelp.Set (el.PNum(j)); - } - free.Or (fhelp); - } - - (*testout) << "smooth points: " << endl; - for (int i = 1; i <= free.Size(); i++) - if (free.Test(i)) - (*testout) << "p " << i << endl; - - (*testout) << "surf points: " << endl; - for (int i = 1; i <= mesh.GetNSE(); i++) - for (int j = 1; j <= 3; j++) - (*testout) << mesh.SurfaceElement(i).PNum(j) << endl; - - - - mesh.CalcSurfacesOfNode(); - free.Invert(); - mesh.FixPoints (free); - mesh.ImproveMesh (OPT_REST); - - - wrongels = 0; - for (int i = 1; i <= mesh.GetNE(); i++) - { - if (mesh.VolumeElement(i).Volume(mesh.Points()) < 0) - { - wrongels++; - mesh.VolumeElement(i).flags.badel = 1; - (*testout) << "wrong el: "; - for (int j = 1; j <= 4; j++) - (*testout) << mesh.VolumeElement(i).PNum(j) << " "; - (*testout) << endl; - } - else - mesh.VolumeElement(i).flags.badel = 0; - } - cout << "wrongels = " << wrongels << endl; - } - while (wrongels && cnttrials > 0); - - for (int i = 1; i <= np; i++) - can.Elem(i) = mesh.Point(i); - } - } - - if (cnttrials <= 0) - { - cerr << "ERROR: Sorry, reverted elements" << endl; - } - - mesh.ComputeNVertices(); - } -} diff --git a/Netgen/libsrc/meshing/ruler2.cpp b/Netgen/libsrc/meshing/ruler2.cpp deleted file mode 100644 index 82c6dbe57d..0000000000 --- a/Netgen/libsrc/meshing/ruler2.cpp +++ /dev/null @@ -1,646 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -namespace netgen -{ -static double CalcElementBadness (const ARRAY<Point2d> & points, - const Element2d & elem) -{ - // badness = sqrt(3) /36 * circumference^2 / area - 1 + - // h / li + li / h - 2 - - Vec2d v12, v13, v23; - double l12, l13, l23, cir, area; - static const double c = sqrt(3.0) / 36; - - v12 = points.Get(elem.PNum(2)) - points.Get(elem.PNum(1)); - v13 = points.Get(elem.PNum(3)) - points.Get(elem.PNum(1)); - v23 = points.Get(elem.PNum(3)) - points.Get(elem.PNum(2)); - - l12 = v12.Length(); - l13 = v13.Length(); - l23 = v23.Length(); - - cir = l12 + l13 + l23; - area = 0.5 * (v12.X() * v13.Y() - v12.Y() * v13.X()); - if (area < 1e-6) - { - return 1e8; - } - - if (testmode) - { - (*testout) << "l = " << l12 << " + " << l13 << " + " << l23 << " = " - << cir << ", area = " << area << endl; - (*testout) << "shapeerr = " << 10 * (c * cir * cir / area - 1) << endl - << "sizeerr = " << 1/l12 + l12 + 1/l13 + l13 + 1/l23 + l23 - 6 - << endl; - } - - return 10 * (c * cir * cir / area - 1) - + 1/l12 + l12 + 1/l13 + l13 + 1/l23 + l23 - 6; -} - - - -int Meshing2 ::ApplyRules (ARRAY<Point2d> & lpoints, - ARRAY<int> & legalpoints, - int maxlegalpoint, - ARRAY<INDEX_2> & llines, - int maxlegalline, - ARRAY<Element2d> & elements, - ARRAY<INDEX> & dellines, int tolerance) -{ - int i, j, ri, nlok, npok, incnpok, refpi, locli = 0; - - double maxerr = 0.5 + 0.3 * tolerance; - double minelerr = 2 + 0.5 * tolerance * tolerance; - - - bool ok; - int found; // rule number - Vector oldu, newu; - Point2d np; - Vec2d linevec; - int oldnp; - INDEX_2 loclin; - double hf, elerr; - int noldlp, noldll; - int loctestmode; - - static ARRAY<int> pused, lused; - static ARRAY<int> pmap, lmap, pfixed; - static ARRAY<int> pnearness, lnearness; - - static ARRAY<Point2d> tempnewpoints; - static ARRAY<INDEX_2> tempnewlines; - static ARRAY<int> tempdellines; - static ARRAY<Element2d> tempelements; - - - - elements.SetSize (0); - dellines.SetSize (0); - - noldlp = lpoints.Size(); - noldll = llines.Size(); - - pused.SetSize (maxlegalpoint); - lused.SetSize (maxlegalline); - pnearness.SetSize (noldlp); - lnearness.SetSize (llines.Size()); - - - testmode = debugparam.debugoutput; - loctestmode = testmode; - - if (loctestmode) - { - (*testout) << endl << endl << "Check new environment" << endl; - (*testout) << "tolerance = " << tolerance << endl; - for (i = 1; i <= lpoints.Size(); i++) - (*testout) << "P" << i << " = " << lpoints.Get(i) << endl; - (*testout) << endl; - for (i = 1; i <= llines.Size(); i++) - (*testout) << "(" << llines.Get(i).I1() << "-" << llines.Get(i).I2() << ")" << endl; - } - - // check every rule - - found = 0; - - - for (i = 1; i <= noldlp; i++) - pnearness.Set(i, 1000); - - for (j = 1; j <= 2; j++) - pnearness.Set(llines.Get(1).I(j), 0); - - - do - { - ok = 1; - for (i = 1; i <= maxlegalline; i++) - { - const INDEX_2 & hline = llines.Get(i); - - /* - int minn = INT_MAX-1; - for (j = 1; j <= 2; j++) - { - int hi = pnearness.Get(hline.I(j)); - if (hi < minn) minn = hi; - } - */ - int minn = pnearness.Get(hline.I1()); - int minn2 = pnearness.Get(hline.I2()); - if (minn2 < minn) - minn = minn2; - - /* - for (j = 1; j <= 2; j++) - { - int hpi = hline.I(j); - if (pnearness.Get(hpi) > minn+1) - { - ok = 0; - pnearness.Set(hpi, minn+1); - } - } - */ - int hpi = hline.I1(); - if (pnearness.Get(hpi) > minn+1) - { - ok = 0; - pnearness.Set(hpi, minn+1); - } - hpi = hline.I2(); - if (pnearness.Get(hpi) > minn+1) - { - ok = 0; - pnearness.Set(hpi, minn+1); - } - } - } - while (!ok); - - for (i = 1; i <= maxlegalline /* lnearness.Size() */; i++) - { - lnearness.Set(i, 0); - for (j = 1; j <= 2; j++) - lnearness.Elem(i) += pnearness.Get(llines.Get(i).I(j)); - } - - - for (ri = 1; ri <= rules.Size(); ri++) - { - netrule * rule = rules.Get(ri); - - if (loctestmode) - (*testout) << "Rule " << rule->Name() << endl; - - if (rule->GetQuality() > tolerance) continue; - - pmap.SetSize (rule->GetNP()); - lmap.SetSize (rule->GetNL()); - - lused = 0; - pused = 0; - pmap = 0; - lmap = 0; - /* - for (i = 1; i <= lused.Size(); i++) - lused.Set (i, 0); - for (i = 1; i <= pused.Size(); i++) - pused.Set (i, 0); - for (i = 1; i <= pmap.Size(); i++) - pmap.Set(i, 0); - for (i = 1; i <= lmap.Size(); i++) - lmap.Set(i, 0); - */ - - lused[0] = 1; // .Set (1, 1); - lmap[0] = 1; // .Set (1, 1); - - for (j = 1; j <= 2; j++) - { - pmap.Elem(rule->GetPointNr (1, j)) = llines.Get(1).I(j); - pused.Elem(llines.Get(1).I(j))++; - } - - - nlok = 2; - - while (nlok >= 2) - { - - if (nlok <= rule->GetNOldL()) - - { - ok = 0; - while (!ok && lmap.Get(nlok) < maxlegalline /* llines.Size() */) - { - lmap.Elem(nlok)++; - locli = lmap.Get(nlok); - - if (!lused.Get(locli) && - lnearness.Get(locli) <= rule->GetLNearness (nlok) ) - { - ok = 1; - - loclin = llines.Get(locli); - - linevec.X() = lpoints.Get (loclin.I2()).X() - - lpoints.Get (loclin.I1()).X(); - linevec.Y() = lpoints.Get (loclin.I2()).Y() - - lpoints.Get (loclin.I1()).Y(); - - if (rule->CalcLineError (nlok, linevec) > maxerr) - ok = 0; - - for (j = 1; j <= 2 && ok; j++) - { - refpi = rule->GetPointNr (nlok, j); - - if (pmap.Get(refpi) != 0) - { - if (pmap.Get(refpi) != loclin.I(j)) - ok = 0; - } - else - { - if (rule->CalcPointDist (refpi, lpoints.Get(loclin.I(j))) > maxerr - || !legalpoints.Get(loclin.I(j)) - || pused.Get(loclin.I(j))) ok = 0; - } - } - } - } - - if (ok) - { - lused.Set (locli, 1); - for (j = 1; j <= 2; j++) - { - pmap.Set(rule->GetPointNr (nlok, j), loclin.I(j)); - pused.Elem(loclin.I(j))++; - } - - nlok++; - } - else - { - lmap.Elem(nlok) = 0; - nlok--; - - lused.Set (lmap.Get(nlok), 0); - for (j = 1; j <= 2; j++) - { - pused.Elem(llines.Get(lmap.Get(nlok)).I(j)) --; - if (! pused.Get (llines.Get (lmap.Get (nlok)).I(j))) - pmap.Set (rule->GetPointNr (nlok, j), 0); - } - } - } - - else - - { - - // all lines are mapped !! - - // map also all points: - - npok = 1; - incnpok = 1; - - pfixed.SetSize (pmap.Size()); - for (i = 1; i <= pmap.Size(); i++) - pfixed.Elem(i) = (pmap.Get(i) >= 1); - - while (npok >= 1) - { - - if (npok <= rule->GetNOldP()) - - { - if (pfixed.Get(npok)) - - { - if (incnpok) - npok++; - else - npok--; - } - - else - - { - ok = 0; - - if (pmap.Get(npok)) - pused.Elem(pmap.Get(npok))--; - - while (!ok && pmap.Get(npok) < maxlegalpoint) - { - ok = 1; - - pmap.Elem(npok)++; - - if (pused.Get(pmap.Get(npok))) - { - ok = 0; - } - else - { - if (rule->CalcPointDist (npok, lpoints.Get(pmap.Get(npok))) > maxerr - || !legalpoints.Get(pmap.Get(npok)) - ) ok = 0; - } - } - - if (ok) - { - pused.Elem(pmap.Get(npok))++; - npok++; - incnpok = 1; - } - - else - - { - pmap.Elem(npok) = 0; - npok--; - incnpok = 0; - } - } - } - - else - - { - if (ok) - foundmap.Elem(ri)++; - - if (loctestmode) - (*testout) << "lines and points mapped" << endl; - - - ok = 1; - - // check orientations - - for (i = 1; i <= rule->GetNOrientations() && ok; i++) - { - if (CW (lpoints.Get(pmap.Get(rule->GetOrientation(i).i1)), - lpoints.Get(pmap.Get(rule->GetOrientation(i).i2)), - lpoints.Get(pmap.Get(rule->GetOrientation(i).i3))) ) - { - ok = 0; - if (loctestmode) - (*testout) << "Orientation " << i << " not ok" << endl; - } - } - - if (ok) - { - oldu.SetSize (2 * rule->GetNOldP()); - - for (i = 1; i <= rule->GetNOldP(); i++) - { - Vec2d ui(rule->GetPoint(i), lpoints.Get(pmap.Get(i))); - oldu.Set (2*i-1, ui.X()); - oldu.Set (2*i , ui.Y()); - } - - rule -> SetFreeZoneTransformation (oldu, tolerance); - } - - - if (ok && !rule->ConvexFreeZone()) - { - ok = 0; - if (loctestmode) (*testout) << "freezone not convex" << endl; - - /* - static int cnt = 0; - cnt++; - if (cnt % 100 == 0) - { - cout << "freezone not convex, cnt = " << cnt << "; rule = " << rule->Name() << endl; - (*testout) << "freezone not convex, cnt = " << cnt << "; rule = " << rule->Name() << endl; - (*testout) << "tol = " << tolerance << endl; - (*testout) << "maxerr = " << maxerr << "; minerr = " << minelerr << endl; - (*testout) << "freezone = " << rule->GetTransFreeZone() << endl; - } - */ - } - - // check freezone: - - for (i = 1; i <= maxlegalpoint && ok; i++) - { - if ( !pused.Get(i) && - rule->IsInFreeZone (lpoints.Get(i)) ) - { - ok = 0; - if (loctestmode) - (*testout) << "Point " << i << " in freezone" << endl; - } - } - - - for (i = maxlegalpoint+1; i <= lpoints.Size() && ok; i++) - { - if ( rule->IsInFreeZone (lpoints.Get(i)) ) - { - ok = 0; - if (loctestmode) - (*testout) << "Point " << i << " in freezone" << endl; - } - } - - for (i = 1; i <= maxlegalline && ok; i++) - { - if (!lused.Get(i) && - rule->IsLineInFreeZone (lpoints.Get(llines.Get(i).I1()), - lpoints.Get(llines.Get(i).I2()))) - { - ok = 0; - if (loctestmode) - (*testout) << "line " << llines.Get(i).I1() << "-" - << llines.Get(i).I2() << " in freezone" << endl; - } - } - for (i = maxlegalline+1; i <= llines.Size() && ok; i++) - { - if (rule->IsLineInFreeZone (lpoints.Get(llines.Get(i).I1()), - lpoints.Get(llines.Get(i).I2()))) - { - ok = 0; - if (loctestmode) - (*testout) << "line " << llines.Get(i).I1() << "-" - << llines.Get(i).I2() << " in freezone" << endl; - } - } - - - /* - // check orientations - - for (i = 1; i <= rule->GetNOrientations() && ok; i++) - { - if (CW (lpoints.Get(pmap.Get(rule->GetOrientation(i).i1)), - lpoints.Get(pmap.Get(rule->GetOrientation(i).i2)), - lpoints.Get(pmap.Get(rule->GetOrientation(i).i3))) ) - { - ok = 0; - if (loctestmode) - (*testout) << "Orientation " << i << " not ok" << endl; - } - } - */ - - - if (ok) - { - if (loctestmode) - (*testout) << "rule ok" << endl; - - // newu = rule->GetOldUToNewU() * oldu; - if (rule->GetNOldP() < rule->GetNP()) - { - newu.SetSize (rule->GetOldUToNewU().Height()); - rule->GetOldUToNewU().Mult (oldu, newu); - } - - // Setze neue Punkte: - - oldnp = rule->GetNOldP(); - - for (i = oldnp + 1; i <= rule->GetNP(); i++) - { - np = rule->GetPoint(i); - np.X() += newu.Elem (2 * (i-oldnp) - 1); - np.Y() += newu.Elem (2 * (i-oldnp)); - - pmap.Elem(i) = lpoints.Append (np); - } - - // Setze neue Linien: - - for (i = rule->GetNOldL() + 1; i <= rule->GetNL(); i++) - { - llines.Append (INDEX_2 (pmap.Get(rule->GetPointNr (i, 1)), - pmap.Get(rule->GetPointNr (i, 2)))); - } - - - // delete old lines: - - for (i = 1; i <= rule->GetNDelL(); i++) - dellines.Append (lmap.Get(rule->GetDelLine(i))); - - // insert new elements: - - for (i = 1; i <= rule->GetNE(); i++) - { - elements.Append (rule->GetElement(i)); - for (j = 1; j <= elements.Get(i).GetNP(); j++) - elements.Elem(i).PNum(j) = pmap.Get(elements.Get(i).PNum(j)); - } - - - elerr = 0; - for (i = 1; i <= elements.Size(); i++) - { - if (!mparam.quad) - hf = CalcElementBadness (lpoints, elements.Get(i)); - else - hf = elements.Get(i).CalcJacobianBadness (lpoints) * 5; - if (loctestmode) - (*testout) << "r " << rule->Name() << "bad = " << hf << endl; - if (hf > elerr) elerr = hf; - } - - if (loctestmode) - (*testout) << "error = " << elerr; - - - canuse.Elem(ri) ++; - - if (elerr < minelerr) - { - - if (loctestmode) - { - (*testout) << "rule = " << rule->Name() << endl; - (*testout) << "class = " << tolerance << endl; - (*testout) << "lpoints: " << endl; - for (i = 1; i <= lpoints.Size(); i++) - (*testout) << lpoints.Get(i) << endl; - (*testout) << "llines: " << endl; - for (i = 1; i <= llines.Size(); i++) - (*testout) << llines.Get(i).I1() << " " << llines.Get(i).I2() << endl; - - (*testout) << "Freezone: "; - for (i = 1; i <= rule -> GetTransFreeZone().Size(); i++) - (*testout) << rule->GetTransFreeZone().Get(i) << endl; - } - - - - minelerr = elerr; - found = ri; - - tempnewpoints.SetSize (0); - for (i = noldlp+1; i <= lpoints.Size(); i++) - tempnewpoints.Append (lpoints.Get(i)); - - tempnewlines.SetSize (0); - for (i = noldll+1; i <= llines.Size(); i++) - tempnewlines.Append (llines.Get(i)); - - tempdellines.SetSize (0); - for (i = 1; i <= dellines.Size(); i++) - tempdellines.Append (dellines.Get(i)); - - tempelements.SetSize (0); - for (i = 1; i <= elements.Size(); i++) - tempelements.Append (elements.Get(i)); - } - - lpoints.SetSize (noldlp); - llines.SetSize (noldll); - dellines.SetSize (0); - elements.SetSize (0); - ok = 0; - - } - - - npok = rule->GetNOldP(); - incnpok = 0; - } - } - - nlok = rule->GetNOldL(); - - lused.Set (lmap.Get(nlok), 0); - - for (j = 1; j <= 2; j++) - { - refpi = rule->GetPointNr (nlok, j); - pused.Elem(pmap.Get(refpi))--; - - if (pused.Get(pmap.Get(refpi)) == 0) - { - pmap.Set(refpi, 0); - } - } - } - } - } - - - if (found) - { - for (i = 0; i < tempnewpoints.Size(); i++) - lpoints.Append (tempnewpoints[i]); - for (i = 0; i < tempnewlines.Size(); i++) - llines.Append (tempnewlines[i]); - for (i = 0; i < tempdellines.Size(); i++) - dellines.Append (tempdellines[i]); - for (i = 0; i < tempelements.Size(); i++) - elements.Append (tempelements[i]); - } - - - return found; -} - - - - - -} diff --git a/Netgen/libsrc/meshing/ruler2.hpp b/Netgen/libsrc/meshing/ruler2.hpp deleted file mode 100644 index 4ef855d4ec..0000000000 --- a/Netgen/libsrc/meshing/ruler2.hpp +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef FILE_NETRULE -#define FILE_NETRULE - -/// -class netrule -{ -private: - /// - typedef struct tf - { float f1, f2, f3; } threefloat; - - class threeint - { - public: int i1, i2, i3; - threeint() { } - threeint(int ai1, int ai2, int ai3) - { i1 = ai1; i2 = ai2; i3 = ai3; } - }; - - - /// - int quality; - /// - char * name; - /// - ARRAY<Point2d> points; - /// - ARRAY<INDEX_2> lines; - /// - ARRAY<Point2d> freezone, freezonelimit; - /// - ARRAY<Point2d> transfreezone; - - /// - ARRAY<int> dellines; - /// - ARRAY<Element2d> elements; - /// - ARRAY<threefloat> tolerances, linetolerances; - /// - ARRAY<threeint> orientations; - /// - DenseMatrix oldutonewu, oldutofreearea, oldutofreearealimit; - /// - ARRAY<DenseMatrix*> oldutofreearea_i; - /// - MatrixFixWidth<3> freesetinequ; - - /// - ARRAY<Vec2d> linevecs; - - /// - int noldp, noldl; - /// - float fzminx, fzmaxx, fzminy, fzmaxy; - - /// topological distance of line to base element - ARRAY<int> lnearness; - -public: - - /// - netrule (); - /// - ~netrule(); - - /// - int GetNP () const { return points.Size(); } - /// - int GetNL () const { return lines.Size(); } - /// - int GetNE () const { return elements.Size(); } - /// - int GetNOldP () const { return noldp; } - /// - int GetNOldL () const { return noldl; } - /// - int GetNDelL () const { return dellines.Size(); } - /// - int GetNOrientations () const { return orientations.Size(); } - /// - int GetQuality () const { return quality; } - /// - int GetLNearness (int li) const { return lnearness.Get(li); } - - /// - const Point2d & GetPoint (int i) const { return points.Get(i); } - /// - const INDEX_2 & GetLine (int i) const { return lines.Get(i); } - /// - const Element2d & GetElement (int i) const { return elements.Get(i); } - /// - const threeint & GetOrientation (int i) const { return orientations.Get(i); } - /// - int GetDelLine (int i) const { return dellines.Get(i); } - - /// - void GetFreeZone (ARRAY<Point2d> & afreearea); - /// - - double CalcPointDist (int pi, const Point2d & p) const - { - double dx = p.X() - points.Get(pi).X(); - double dy = p.Y() - points.Get(pi).Y(); - const threefloat * tf = &tolerances.Get(pi); - return tf->f1 * dx * dx + tf->f2 * dx * dy + tf->f3 * dy * dy; - } - - /// - float CalcLineError (int li, const Vec2d & v) const; - - /// - void SetFreeZoneTransformation (const Vector & u, int tolclass); - - /// - bool IsInFreeZone (const Point2d & p) const - { - if (p.X() < fzminx || p.X() > fzmaxx || - p.Y() < fzminy || p.Y() > fzmaxy) return 0; - - for (int i = 0; i < transfreezone.Size(); i++) - { - if (freesetinequ(i, 0) * p.X() + - freesetinequ(i, 1) * p.Y() + - freesetinequ(i, 2) > 0) return 0; - } - return 1; - } - - /// - int IsLineInFreeZone (const Point2d & p1, const Point2d & p2) const - { - if (p1.X() > fzmaxx && p2.X() > fzmaxx || - p1.X() < fzminx && p2.X() < fzminx || - p1.Y() > fzmaxy && p2.Y() > fzmaxy || - p1.Y() < fzminy && p2.Y() < fzminy) return 0; - return IsLineInFreeZone2 (p1, p2); - } - /// - int IsLineInFreeZone2 (const Point2d & p1, const Point2d & p2) const; - /// - int ConvexFreeZone () const; - /// - const ARRAY<Point2d> & GetTransFreeZone () { return transfreezone; } - - /// - int GetPointNr (int ln, int endp) const { return lines.Get(ln).I(endp); } - - /// - const DenseMatrix & GetOldUToNewU () const { return oldutonewu; } - /// - const DenseMatrix & GetOldUToFreeArea () const { return oldutofreearea; } - /// - const char * Name () const { return name; } - - /// - void LoadRule (istream & ist); -}; - - - -/** Draws 2D rules. - Visual testing of 2D meshing rules */ -extern void DrawRules (); -#endif - diff --git a/Netgen/libsrc/meshing/ruler3.cpp b/Netgen/libsrc/meshing/ruler3.cpp deleted file mode 100644 index 48ba5bc465..0000000000 --- a/Netgen/libsrc/meshing/ruler3.cpp +++ /dev/null @@ -1,1176 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -// #define MARK -// #include <prof.h> - -namespace netgen -{ -extern double minother; -extern double minwithoutother; - - -static double CalcElementBadness (const ARRAY<Point3d> & points, - const Element & elem) -{ - double vol, l, l4, l5, l6; - if (elem.GetNP() != 4) - { - if (elem.GetNP() == 5) - { - double z = points.Get(elem.PNum(5)).Z(); - if (z > -1e-8) return 1e8; - return (-1 / z) - z; // - 2; - } - return 0; - } - - Vec3d v1 = points.Get(elem.PNum(2)) - points.Get(elem.PNum(1)); - Vec3d v2 = points.Get(elem.PNum(3)) - points.Get(elem.PNum(1)); - Vec3d v3 = points.Get(elem.PNum(4)) - points.Get(elem.PNum(1)); - - vol = - (Cross (v1, v2) * v3); - l4 = Dist (points.Get(elem.PNum(2)), points.Get(elem.PNum(3))); - l5 = Dist (points.Get(elem.PNum(2)), points.Get(elem.PNum(4))); - l6 = Dist (points.Get(elem.PNum(3)), points.Get(elem.PNum(4))); - - l = v1.Length() + v2.Length() + v3.Length() + l4 + l5 + l6; - - // testout << "vol = " << vol << " l = " << l << endl; - if (vol < 1e-8) return 1e10; - // (*testout) << "l^3/vol = " << (l*l*l / vol) << endl; - - double err = pow (l*l*l/vol, 1.0/3.0) / 12; - return err; -} - - - - - - -int Meshing3 :: ApplyRules -( - ARRAY<Point3d> & lpoints, // in: local points, out: old+new local points - ARRAY<int> & allowpoint, // in: 1 .. it is allowed to use pointi - ARRAY<Element2d> & lfaces, // in: local faces, out: old+new local faces - INDEX lfacesplit, // for local faces in outer radius - INDEX_2_HASHTABLE<int> & connectedpairs, // connected pairs for prism-meshing - ARRAY<Element> & elements, // out: new elements - ARRAY<INDEX> & delfaces, // out: face indices of faces to delete - int tolerance, // quality class: 1 best - double sloppy, // quality strength - int rotind1, // how to rotate base element - float & retminerr // element error - ) - -{ - int i, j, k, ri, nfok, npok, incnpok, refpi, locpi, locfi, locfr; - int hi, minn, hpi; - float hf, err, minerr, teterr, minteterr; - char ok, found, hc; - vnetrule * rule; - Vector oldu, newu, newu1, newu2, allp; - Vec3d ui; - Point3d np; - int oldnp, noldlp, noldlf; - const Element2d * locface = NULL; - int loktestmode; - - static ARRAY<int> pused; // point is already mapped - static ARRAY<int> fused; // face is already mapped - static ARRAY<int> pmap; // map of reference point to local point - static ARRAY<int> pfixed; // ??? - static ARRAY<int> fmapi; // face in reference is mapped to face nr ... - static ARRAY<int> fmapr; // face in reference is rotated to map - static ARRAY<Point3d> transfreezone; // transformed free-zone - static INDEX cnt = 0; - INDEX_2_HASHTABLE<int> ledges(lfaces.Size()); // edges in local environment - - static ARRAY<Point3d> tempnewpoints; - static ARRAY<Element2d> tempnewfaces; - static ARRAY<int> tempdelfaces; - static ARRAY<Element> tempelements; - static ARRAY<Box3d> triboxes; // bounding boxes of local faces - - - static ARRAY<int> pnearness; - static ARRAY<int> fnearness; - - cnt++; - - delfaces.SetSize (0); - elements.SetSize (0); - - - // determine topological distance of faces and points to - // base element - - - pnearness.SetSize (lpoints.Size()); - fnearness.SetSize (lfacesplit); - - for (i = 1; i <= pnearness.Size(); i++) - pnearness.Set(i, INT_MAX/10); - - for (j = 1; j <= lfaces.Get(1).GetNP(); j++) - pnearness.Set(lfaces.Get(1).PNum(j), 0); - - - // MARK(appl1); - do - { - ok = 1; - - for (i = 1; i <= lfacesplit; i++) - { - const Element2d & hface = lfaces.Get(i); - - minn = INT_MAX-1; - for (j = 1; j <= hface.GetNP(); j++) - { - hi = pnearness.Get(hface.PNum(j)); - if (hi < minn) minn = hi; - } - - for (j = 1; j <= hface.GetNP(); j++) - { - hpi = hface.PNum(j); - if (pnearness.Get(hpi) > minn+1) - { - ok = 0; - pnearness.Set(hpi, minn+1); - } - } - } - - for (i = 1; i <= connectedpairs.GetNBags(); i++) - for (j = 1; j <= connectedpairs.GetBagSize(i); j++) - { - INDEX_2 edge; - int val; - connectedpairs.GetData (i, j, edge, val); - - - if (edge.I1() > pnearness.Size() || - edge.I2() > pnearness.Size() || - edge.I1() < 1 || - edge.I2() < 1) - { - cerr << "pair out of range" << endl; - exit (1); - } - - if (pnearness.Get(edge.I1()) > - pnearness.Get(edge.I2()) + 1) - { - ; - ok = 0; - pnearness.Elem(edge.I1()) = - pnearness.Get(edge.I2()) + 1; - } - if (pnearness.Get(edge.I2()) > - pnearness.Get(edge.I1()) + 1) - { - ; - ok = 0; - pnearness.Elem(edge.I2()) = - pnearness.Get(edge.I1()) + 1; - } - } - } - while (!ok); - - - for (i = 1; i <= fnearness.Size(); i++) - { - fnearness.Set(i, 0); - for (j = 1; j <= lfaces.Get(i).GetNP(); j++) - fnearness.Elem(i) += pnearness.Get(lfaces.Get(i).PNum(j)); - } - - - // MARK(appl2); - - // find bounding boxes of faces - - triboxes.SetSize (lfaces.Size()); - for (i = 1; i <= lfaces.Size(); i++) - { - const Element2d & face = lfaces.Get(i); - triboxes.Elem(i).SetPoint (lpoints.Get(face.PNum(1))); - for (j = 2; j <= face.GetNP(); j++) - triboxes.Elem(i).AddPoint (lpoints.Get(face.PNum(j))); - } - - // MARK(appl3); - - /* - for (j = 1; j <= lfacesplit; j++) - for (k = 1; k <= lfaces.Get(j).GetNP(); k++) - { - INDEX_2 i2; - i2.I1() = lfaces.Get(j).PNumMod(k); - i2.I2() = lfaces.Get(j).PNumMod(k+1); - i2.Sort(); - ledges.Set (i2, 1); - } - */ - - for (j = 1; j <= lfacesplit; j++) - { - const Element2d & face = lfaces.Get(j); - int newp, oldp; - - newp = face.PNum(face.GetNP()); - for (k = 1; k <= face.GetNP(); k++) - { - oldp = newp; - newp = face.PNum(k); - - INDEX_2 i2(oldp, newp); - i2.Sort(); - ledges.Set (i2, 1); - } - } - - - pused.SetSize (lpoints.Size()); - fused.SetSize (lfaces.Size()); - - - - found = 0; - minerr = tolfak * tolerance * tolerance; - minteterr = sloppy * tolerance; - - if (testmode) - (*testout) << "cnt = " << cnt << " class = " << tolerance << endl; - - - // check each rule: - - // MARK(applyml); - - for (ri = 1; ri <= rules.Size(); ri++) - { - sprintf (problems.Elem(ri), ""); - - rule = rules.Get(ri); - - if (rule->GetNP(1) != lfaces.Get(1).GetNP()) - continue; - - if (rule->GetQuality() > tolerance) - { - if (testmode) - sprintf (problems.Elem(ri), "Quality not ok"); - continue; - } - - if (testmode) - sprintf (problems.Elem(ri), "no mapping found"); - - loktestmode = testmode || rule->TestFlag ('t'); - /* - if (tolerance > 8) - loktestmode = 1; - */ - - if (loktestmode) - (*testout) << "Rule " << ri << " = " << rule->Name() << endl; - - pmap.SetSize (rule->GetNP()); - fmapi.SetSize (rule->GetNF()); - fmapr.SetSize (rule->GetNF()); - - for (i = 1; i <= lfaces.Size(); i++) - fused.Set (i, 0); - for (i = 1; i <= lpoints.Size(); i++) - pused.Set (i, 0); - for (i = 1; i <= pmap.Size(); i++) - pmap.Set(i, 0); - for (i = 1; i <= fmapi.Size(); i++) - fmapi.Set(i, 0); - for (i = 1; i <= fmapr.Size(); i++) - fmapr.Set(i, rule->GetNP(i)); - - fused.Set (1, 1); - - fmapi.Set (1, 1); - fmapr.Set (1, rotind1); - - - for (j = 1; j <= lfaces.Get(1).GetNP(); j++) - { - locpi = lfaces.Get(1).PNumMod (j+rotind1); - pmap.Set (rule->GetPointNr (1, j), locpi); - pused.Elem(locpi)++; - } - - - - /* - map all faces - nfok .. first nfok-1 faces are mapped properly - */ - - nfok = 2; - while (nfok >= 2) - { - - if (nfok <= rule->GetNOldF()) - { - // not all faces mapped - - ok = 0; - locfi = fmapi.Get(nfok); - locfr = fmapr.Get(nfok); - - int actfnp = rule->GetNP(nfok); - - while (!ok) - { - locfr++; - if (locfr == actfnp + 1) - { - locfr = 1; - locfi++; - if (locfi > lfacesplit) break; - } - - - if (fnearness.Get(locfi) > rule->GetFNearness (nfok) || - fused.Get(locfi) || - actfnp != lfaces.Get(locfi).GetNP() ) - { - // face not feasible in any rotation - - locfr = actfnp; - } - else - { - - ok = 1; - - locface = &lfaces.Get(locfi); - - - // reference point already mapped differently ? - for (j = 1; j <= actfnp && ok; j++) - { - locpi = pmap.Get(rule->GetPointNr (nfok, j)); - - if (locpi && locpi != locface->PNumMod(j+locfr)) - ok = 0; - } - - // local point already used or point outside tolerance ? - for (j = 1; j <= actfnp && ok; j++) - { - refpi = rule->GetPointNr (nfok, j); - - if (pmap.Get(refpi) == 0) - { - locpi = locface->PNumMod (j + locfr); - - if (pused.Get(locpi)) - ok = 0; - else - { - const Point3d & lp = lpoints.Get(locpi); - const Point3d & rp = rule->GetPoint(refpi); - - if ( Dist2 (lp, rp) * rule->PointDistFactor(refpi) > minerr) - ok = 0; - } - } - } - } - } - - - if (ok) - { - // map face nfok - - fmapi.Set (nfok, locfi); - fmapr.Set (nfok, locfr); - fused.Set (locfi, 1); - - for (j = 1; j <= rule->GetNP (nfok); j++) - { - locpi = locface->PNumMod(j+locfr); - - if (rule->GetPointNr (nfok, j) <= 3 && - pmap.Get(rule->GetPointNr(nfok, j)) != locpi) - (*testout) << "change face1 point, mark1" << endl; - - pmap.Set(rule->GetPointNr (nfok, j), locpi); - pused.Elem(locpi)++; - } - - nfok++; - } - else - { - // backtrack one face - fmapi.Set (nfok, 0); - fmapr.Set (nfok, rule->GetNP(nfok)); - nfok--; - - fused.Set (fmapi.Get(nfok), 0); - for (j = 1; j <= rule->GetNP (nfok); j++) - { - refpi = rule->GetPointNr (nfok, j); - pused.Elem(pmap.Get(refpi))--; - - if (pused.Get(pmap.Get(refpi)) == 0) - { - pmap.Set(refpi, 0); - } - } - } - } - - else - - { - - // all faces are mapped - // now map all isolated points: - - if (loktestmode) - { - (*testout) << "Faces Ok" << endl; - sprintf (problems.Elem(ri), "Faces Ok"); - } - - npok = 1; - incnpok = 1; - - pfixed.SetSize (pmap.Size()); - for (i = 1; i <= pmap.Size(); i++) - pfixed.Set(i, (pmap.Get(i) != 0) ); - - while (npok >= 1) - { - - if (npok <= rule->GetNOldP()) - { - - if (pfixed.Get(npok)) - - { - if (incnpok) - npok++; - else - npok--; - } - - else - - { - locpi = pmap.Elem(npok); - ok = 0; - - if (locpi) - pused.Elem(locpi)--; - - while (!ok && locpi < lpoints.Size()) - { - ok = 1; - locpi++; - - if (pused.Get(locpi) || !allowpoint.Get(locpi) || - pnearness.Get(locpi) > rule->GetPNearness(npok)) - { - ok = 0; - } - else - { - const Point3d & lp = lpoints.Get(locpi); - const Point3d & rp = rule->GetPoint(npok); - - if ( Dist2 (lp, rp) * rule->PointDistFactor(npok) > minerr) - ok = 0; - } - } - - - if (ok) - { - pmap.Set (npok, locpi); - - if (npok <= 3) - (*testout) << "set face1 point, mark3" << endl; - - pused.Elem(locpi)++; - npok++; - incnpok = 1; - } - - else - - { - pmap.Set (npok, 0); - - if (npok <= 3) - (*testout) << "set face1 point, mark4" << endl; - - npok--; - incnpok = 0; - } - } - } - - else - - { - - // all points are mapped - - if (loktestmode) - { - (*testout) << "Mapping found!!: Rule " << rule->Name() << endl; - for (i = 1; i <= pmap.Size(); i++) - (*testout) << pmap.Get(i) << " "; - (*testout) << endl; - sprintf (problems.Elem(ri), "mapping found"); - (*testout) << rule->GetNP(1) << " = " << lfaces.Get(1).GetNP() << endl; - } - - ok = 1; - - - // check mapedges: - - for (i = 1; i <= rule->GetNEd(); i++) - { - int i1, i2; - i1 = pmap.Get(rule->GetEdge(i).i1); - i2 = pmap.Get(rule->GetEdge(i).i2); - - INDEX_2 in2(i1, i2); - in2.Sort(); - if (!ledges.Used (in2)) ok = 0; - } - - - // check prism edges: - for (i = 1; i <= rule->GetNE(); i++) - { - const Element & el = rule->GetElement (i); - if (el.GetType() == PRISM) - { - for (j = 1; j <= 3; j++) - { - int i1, i2; - i1 = pmap.Get(el.PNum(j)); - i2 = pmap.Get(el.PNum(j+3)); - - INDEX_2 in2(i1, i2); - in2.Sort(); - if (!connectedpairs.Used (in2)) ok = 0; - } - } - if (el.GetType() == PYRAMID) - { - if (loktestmode) - (*testout) << "map pyramid, rule = " << rule->Name() << endl; - for (j = 1; j <= 2; j++) - { - INDEX_2 in2; - if (j == 1) - { - in2.I1() = pmap.Get(el.PNum(2)); - in2.I2() = pmap.Get(el.PNum(3)); - } - else - { - in2.I1() = pmap.Get(el.PNum(1)); - in2.I2() = pmap.Get(el.PNum(4)); - } - in2.Sort(); - if (!connectedpairs.Used (in2)) - { - ok = 0; - if (loktestmode) - (*testout) << "no pair" << endl; - } - } - } - - } - - - - for (i = rule->GetNOldF() + 1; i <= rule->GetNF(); i++) - fmapi.Set(i, 0); - - - if (ok) - { - foundmap.Elem(ri)++; - } - - - - - // deviation of existing points - - oldu.SetSize (3 * rule->GetNOldP()); - newu.SetSize (3 * (rule->GetNP() - rule->GetNOldP())); - allp.SetSize (3 * rule->GetNP()); - - for (i = 1; i <= rule->GetNOldP(); i++) - { - const Point3d & lp = lpoints.Get(pmap.Get(i)); - const Point3d & rp = rule->GetPoint(i); - oldu.Set (3*i-2, lp.X()-rp.X()); - oldu.Set (3*i-1, lp.Y()-rp.Y()); - oldu.Set (3*i , lp.Z()-rp.Z()); - - allp.Set (3*i-2, lp.X()); - allp.Set (3*i-1, lp.Y()); - allp.Set (3*i , lp.Z()); - } - - if (rule->GetNP() > rule->GetNOldP()) - { - newu.SetSize (rule->GetOldUToNewU().Height()); - rule->GetOldUToNewU().Mult (oldu, newu); - } - - // int idiff = 3 * (rule->GetNP()-rule->GetNOldP()); - int idiff = 3 * rule->GetNOldP(); - for (i = rule->GetNOldP()+1; i <= rule->GetNP(); i++) - { - const Point3d & rp = rule->GetPoint(i); - allp.Set (3*i-2, rp.X() + newu.Get(3*i-2 - idiff)); - allp.Set (3*i-1, rp.Y() + newu.Get(3*i-1 - idiff)); - allp.Set (3*i , rp.Z() + newu.Get(3*i - idiff)); - } - - rule->SetFreeZoneTransformation (allp, - tolerance + int(sloppy)); - - if (!rule->ConvexFreeZone()) - { - ok = 0; - sprintf (problems.Elem(ri), "Freezone not convex"); - - if (loktestmode) - (*testout) << "Freezone not convex" << endl; - } - - if (loktestmode) - { - const ARRAY<Point3d> & fz = rule->GetTransFreeZone(); - (*testout) << "Freezone: " << endl; - for (i = 1; i <= fz.Size(); i++) - (*testout) << fz.Get(i) << endl; - } - - - // check freezone: - - for (i = 1; i <= lpoints.Size(); i++) - { - if ( !pused.Get(i) ) - { - const Point3d & lp = lpoints.Get(i); - - if (rule->fzbox.IsIn (lp)) - { - if (rule->IsInFreeZone(lp)) - { - if (loktestmode) - { - (*testout) << "Point " << i - << " in Freezone" << endl; - sprintf (problems.Elem(ri), - "locpoint %d in Freezone", i); - } - ok = 0; - break; - } - } - } - } - - for (i = 1; i <= lfaces.Size() && ok; i++) - { - static ARRAY<int> lpi(4); - - if (!fused.Get(i)) - { - int triin; - const Element2d & lfacei = lfaces.Get(i); - - if (!triboxes.Elem(i).Intersect (rule->fzbox)) - triin = 0; - else - { - int li, lj; - for (li = 1; li <= lfacei.GetNP(); li++) - { - int lpii = 0; - int pi = lfacei.PNum(li); - for (lj = 1; lj <= rule->GetNOldP(); lj++) - if (pmap.Get(lj) == pi) - lpii = lj; - lpi.Elem(li) = lpii; - } - - - if (lfacei.GetNP() == 3) - { - triin = rule->IsTriangleInFreeZone - ( - lpoints.Get(lfacei.PNum(1)), - lpoints.Get(lfacei.PNum(2)), - lpoints.Get(lfacei.PNum(3)), lpi, 1 - ); - } - else - { - triin = rule->IsQuadInFreeZone - ( - lpoints.Get(lfacei.PNum(1)), - lpoints.Get(lfacei.PNum(2)), - lpoints.Get(lfacei.PNum(3)), - lpoints.Get(lfacei.PNum(4)), - lpi, 1 - ); - } - } - - - if (triin == -1) - { - ok = 0; - } - - if (triin == 1) - { -#ifdef TEST_JS - ok = 0; - - if (loktestmode) - { - (*testout) << "El with " << lfaces.Get(i).GetNP() << " points in freezone: " - << lfaces.Get(i).PNum(1) << " - " - << lfaces.Get(i).PNum(2) << " - " - << lfaces.Get(i).PNum(3) << " - " - << lfaces.Get(i).PNum(4) << endl; - for (int lj = 1; lj <= lfaces.Get(i).GetNP(); lj++) - (*testout) << lpoints.Get(lfaces.Get(i).PNum(lj)) << " "; - - (*testout) << endl; - - sprintf (problems.Elem(ri), "triangle (%d, %d, %d) in Freezone", - lfaces.Get(i).PNum(1), lfaces.Get(i).PNum(2), - lfaces.Get(i).PNum(3)); - } -#else - if (loktestmode) - { - if (lfacei.GetNP() == 3) - { - (*testout) << "Triangle in freezone: " - << lfacei.PNum(1) << " - " - << lfacei.PNum(2) << " - " - << lfacei.PNum(3) - << ", or " - << lpoints.Get(lfacei.PNum(1)) << " - " - << lpoints.Get(lfacei.PNum(2)) << " - " - << lpoints.Get(lfacei.PNum(3)) - << endl; - (*testout) << "lpi = " << lpi.Get(1) << ", " - << lpi.Get(2) << ", " << lpi.Get(3) << endl; - } - else - (*testout) << "Quad in freezone: " - << lfacei.PNum(1) << " - " - << lfacei.PNum(2) << " - " - << lfacei.PNum(3) << " - " - << lfacei.PNum(4) - << ", or " - << lpoints.Get(lfacei.PNum(1)) << " - " - << lpoints.Get(lfacei.PNum(2)) << " - " - << lpoints.Get(lfacei.PNum(3)) << " - " - << lpoints.Get(lfacei.PNum(4)) - << endl; - - sprintf (problems.Elem(ri), "triangle (%d, %d, %d) in Freezone", - int(lfaces.Get(i).PNum(1)), - int(lfaces.Get(i).PNum(2)), - int(lfaces.Get(i).PNum(3))); - } - - hc = 0; - for (k = rule->GetNOldF() + 1; k <= rule->GetNF(); k++) - { - if (rule->GetPointNr(k, 1) <= rule->GetNOldP() && - rule->GetPointNr(k, 2) <= rule->GetNOldP() && - rule->GetPointNr(k, 3) <= rule->GetNOldP()) - { - for (j = 1; j <= 3; j++) - if (lfaces.Get(i).PNumMod(j ) == pmap.Get(rule->GetPointNr(k, 1)) && - lfaces.Get(i).PNumMod(j+1) == pmap.Get(rule->GetPointNr(k, 3)) && - lfaces.Get(i).PNumMod(j+2) == pmap.Get(rule->GetPointNr(k, 2))) - { - fmapi.Elem(k) = i; - hc = 1; - - - // (*testout) << "found from other side: " -// << rule->Name() -// << " ( " << pmap.Get (rule->GetPointNr(k, 1)) -// << " - " << pmap.Get (rule->GetPointNr(k, 2)) -// << " - " << pmap.Get (rule->GetPointNr(k, 3)) << " ) " -// << endl; - - strcpy (problems.Elem(ri), "other"); - } - } - } - - if (!hc) - { - if (loktestmode) - { - (*testout) << "Triangle in freezone: " - << lfaces.Get(i).PNum(1) << " - " - << lfaces.Get(i).PNum(2) << " - " - << lfaces.Get(i).PNum(3) << endl; - - sprintf (problems.Elem(ri), "triangle (%d, %d, %d) in Freezone", - int (lfaces.Get(i).PNum(1)), - int (lfaces.Get(i).PNum(2)), - int (lfaces.Get(i).PNum(3))); - } - ok = 0; - } -#endif - } - } - - } - - - if (ok) - { - err = 0; - for (i = 1; i <= rule->GetNOldP(); i++) - { - hf = rule->CalcPointDist (i, lpoints.Get(pmap.Get(i))); - if (hf > err) err = hf; - } - - - if (loktestmode) - { - (*testout) << "Rule ok" << endl; - sprintf (problems.Elem(ri), "Rule ok, err = %f", err); - } - - - // MARK(m2); - // newu = rule->GetOldUToNewU() * oldu; - - // set new points: - - oldnp = rule->GetNOldP(); - noldlp = lpoints.Size(); - noldlf = lfaces.Size(); - - - for (i = oldnp + 1; i <= rule->GetNP(); i++) - { - np = rule->GetPoint(i); - np.X() += newu.Elem (3 * (i-oldnp) - 2); - np.Y() += newu.Elem (3 * (i-oldnp) - 1); - np.Z() += newu.Elem (3 * (i-oldnp)); - - pmap.Elem(i) = lpoints.Append (np); - } - - // Set new Faces: - - for (i = rule->GetNOldF() + 1; i <= rule->GetNF(); i++) - if (!fmapi.Get(i)) - { - Element2d nface(rule->GetNP(i)); - for (j = 1; j <= nface.GetNP(); j++) - nface.PNum(j) = pmap.Get(rule->GetPointNr (i, j)); - - lfaces.Append (nface); - } - - - // Delete old Faces: - - for (i = 1; i <= rule->GetNDelF(); i++) - delfaces.Append (fmapi.Get(rule->GetDelFace(i))); - for (i = rule->GetNOldF()+1; i <= rule->GetNF(); i++) - if (fmapi.Get(i)) - { - delfaces.Append (fmapi.Get(i)); - fmapi.Elem(i) = 0; - } - - - // check orientation - for (i = 1; i <= rule->GetNO() && ok; i++) - { - const fourint * fouri; - - fouri = &rule->GetOrientation(i); - Vec3d v1 (lpoints.Get(pmap.Get(fouri->i1)), - lpoints.Get(pmap.Get(fouri->i2))); - Vec3d v2 (lpoints.Get(pmap.Get(fouri->i1)), - lpoints.Get(pmap.Get(fouri->i3))); - Vec3d v3 (lpoints.Get(pmap.Get(fouri->i1)), - lpoints.Get(pmap.Get(fouri->i4))); - - Vec3d n; - Cross (v1, v2, n); - if (n * v3 > -1e-7) - { - if (loktestmode) - { - sprintf (problems.Elem(ri), "Orientation wrong"); - (*testout) << "Orientation wrong" << endl; - } - ok = 0; - } - } - - - - // new points in free-zone ? - for (i = rule->GetNOldP() + 1; i <= rule->GetNP() && ok; i++) - if (!rule->IsInFreeZone (lpoints.Get(pmap.Get(i)))) - { - if (loktestmode) - { - (*testout) << "Newpoint " << lpoints.Get(pmap.Get(i)) - << " outside convex hull" << endl; - sprintf (problems.Elem(ri), "newpoint outside convex hull"); - } - ok = 0; - - } - - // insert new elements - - for (i = 1; i <= rule->GetNE(); i++) - { - elements.Append (rule->GetElement(i)); - for (j = 1; j <= elements.Get(i).NP(); j++) - elements.Elem(i).PNum(j) = pmap.Get(elements.Get(i).PNum(j)); - } - - - // Calculate Element badness - - teterr = 0; - for (i = 1; i <= elements.Size(); i++) - { - hf = CalcElementBadness (lpoints, elements.Get(i)); - if (hf > teterr) teterr = hf; - } - - /* - // keine gute Erfahrung am 25.1.2000, js - if (ok && teterr < 100 && - (rule->TestFlag('b') || tolerance > 10) ) - { - (*mycout) << "Reset teterr " - << rule->Name() - << " err = " << teterr - << endl; - teterr = 1; - } - */ - - // compare edgelength - if (rule->TestFlag('l')) - { - double oldlen = 0; - double newlen = 0; - - for (i = 1; i <= rule->GetNDelF(); i++) - { - const Element2d & face = - rule->GetFace (rule->GetDelFace(i)); - for (j = 1; j <= 3; j++) - { - const Point3d & p1 = - lpoints.Get(pmap.Get(face.PNumMod(j))); - const Point3d & p2 = - lpoints.Get(pmap.Get(face.PNumMod(j+1))); - oldlen += Dist(p1, p2); - } - } - - for (i = rule->GetNOldF()+1; i <= rule->GetNF(); i++) - { - const Element2d & face = rule->GetFace (i); - for (j = 1; j <= 3; j++) - { - const Point3d & p1 = - lpoints.Get(pmap.Get(face.PNumMod(j))); - const Point3d & p2 = - lpoints.Get(pmap.Get(face.PNumMod(j+1))); - newlen += Dist(p1, p2); - } - } - - if (oldlen < newlen) - { - ok = 0; - if (loktestmode) - sprintf (problems.Elem(ri), "oldlen < newlen"); - } - } - - - if (loktestmode) - (*testout) << "ok = " << int(ok) - << "teterr = " << teterr - << "minteterr = " << minteterr << endl; - - - if (ok && teterr < tolerance) - { - canuse.Elem(ri) ++; - /* - (*testout) << "can use rule " << rule->Name() - << ", err = " << teterr << endl; - for (i = 1; i <= pmap.Size(); i++) - (*testout) << pmap.Get(i) << " "; - (*testout) << endl; - */ - - if (strcmp (problems.Elem(ri), "other") == 0) - { - if (teterr < minother) - minother = teterr; - } - else - { - if (teterr < minwithoutother) - minwithoutother = teterr; - } - } - - if (ok && teterr < minteterr) - { - - if (loktestmode) - (*testout) << "use rule" << endl; - - found = ri; - minteterr = teterr; - - if (testmode) - { - for (i = 1; i <= rule->GetNOldP(); i++) - { - (*testout) << "P" << i << ": Ref: " - << rule->GetPoint (i) << " is: " - << lpoints.Get(pmap.Get(i)) << endl; - } - } - - tempnewpoints.SetSize (0); - for (i = noldlp+1; i <= lpoints.Size(); i++) - tempnewpoints.Append (lpoints.Get(i)); - - tempnewfaces.SetSize (0); - for (i = noldlf+1; i <= lfaces.Size(); i++) - tempnewfaces.Append (lfaces.Get(i)); - - tempdelfaces.SetSize (0); - for (i = 1; i <= delfaces.Size(); i++) - tempdelfaces.Append (delfaces.Get(i)); - - tempelements.SetSize (0); - for (i = 1; i <= elements.Size(); i++) - tempelements.Append (elements.Get(i)); - } - - lpoints.SetSize (noldlp); - lfaces.SetSize (noldlf); - delfaces.SetSize (0); - elements.SetSize (0); - } - - npok = rule->GetNOldP(); - incnpok = 0; - } - } - - nfok = rule->GetNOldF(); - - for (j = 1; j <= rule->GetNP (nfok); j++) - { - refpi = rule->GetPointNr (nfok, j); - pused.Elem(pmap.Get(refpi))--; - - if (pused.Get(pmap.Get(refpi)) == 0) - { - pmap.Set(refpi, 0); - } - } - - } - } - if (loktestmode) - (*testout) << "end rule" << endl; - } - - // (*testout) << "end" << endl; - - // if successfull, reload best choice - - if (found) - { - -#ifdef debug - // if face in advancing front ??? - for (i = 1; i <= tempnewfaces.Size(); i++) - { - hc = 1; - for (k = 1; k <= lfaces.Size() && hc; k++) - for (j = 1; j <= 3 && hc; j++) - if (tempnewfaces.Elem(i).PNumMod(j ) == lfaces.Get(k).PNum(1) && - tempnewfaces.Elem(i).PNumMod(j+1) == lfaces.Get(k).PNum(3) && - tempnewfaces.Elem(i).PNumMod(j+2) == lfaces.Get(k).PNum(2)) - { - tempdelfaces.Append(k); - tempnewfaces.Elem(i).PNum(1) = 0; - hc = 0; - cerr << "Ruler-reload necessary" << endl; - } - } -#endif - - for (i = 1; i <= tempnewpoints.Size(); i++) - lpoints.Append (tempnewpoints.Get(i)); - for (i = 1; i <= tempnewfaces.Size(); i++) - if (tempnewfaces.Get(i).PNum(1)) - lfaces.Append (tempnewfaces.Get(i)); - for (i = 1; i <= tempdelfaces.Size(); i++) - delfaces.Append (tempdelfaces.Get(i)); - for (i = 1; i <= tempelements.Size(); i++) - elements.Append (tempelements.Get(i)); - } - - retminerr = minerr; - return found; -} -} diff --git a/Netgen/libsrc/meshing/ruler3.hpp b/Netgen/libsrc/meshing/ruler3.hpp deleted file mode 100644 index 483d83ed4e..0000000000 --- a/Netgen/libsrc/meshing/ruler3.hpp +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef FILE_RULER3 -#define FILE_RULER3 - - -/** - 3D element generation rule. - */ -class vnetrule -{ -private: - /// rule is applicable for quality classes above this value - int quality; - /// name of rule - char * name; - /// point coordinates in reference position - ARRAY<Point3d> points; - /// old and new faces in reference numbering - ARRAY<Element2d> faces; - /// additional edges of rule - ARRAY<twoint> edges; - - /// points of freezone in reference coordinates - ARRAY<Point3d> freezone; - /// points of freezone in reference coordinates if tolcalss to infty - ARRAY<Point3d> freezonelimit; - /// point index, if point equal to mappoint, otherwise 0 - ARRAY<int> freezonepi; - /// faces of each convex part of freezone - ARRAY<ARRAY<threeint>*> freefaces; - /// set of points of each convex part of freezone - ARRAY<ARRAY<int>*> freesets; - /// points of transformed freezone - ARRAY<Point3d> transfreezone; - /// edges of each convex part of freezone - ARRAY<ARRAY<twoint>*> freeedges; - - /// face numbers to be deleted - ARRAY<int> delfaces; - /// elements to be generated - ARRAY<Element> elements; - /// tolerances for points and faces (used ??) - ARRAY<double> tolerances, linetolerances; - /// transformation matrix - DenseMatrix oldutonewu; - /// transformation matrix: deviation old point to dev. freezone - DenseMatrix * oldutofreezone; - /** transformation matrix: deviation old point to dev. freezone, - quality class to infinity */ - DenseMatrix * oldutofreezonelimit; - - // can be deleted: - // BaseMatrix *outf, *outfl; - - /** - a point is outside of convex part of freezone, - iff mat * (point, 1) >= 0 for each component (correct ?) - */ - ARRAY<DenseMatrix*> freefaceinequ; - /// - ARRAY<fourint> orientations; - /** - flags specified in rule-description file: - t .. test rule - */ - ARRAY<char> flags; - - /** - topological distance of face to base element - non-connected: > 100 (??) - */ - ARRAY<int> fnearness; - ARRAY<int> pnearness; - int maxpnearness; - - /// number of old points in rule - int noldp; - /// number of new poitns in rule - int noldf; - /// box containing free-zone -public: - // double fzminx, fzmaxx, fzminy, fzmaxy, fzminz, fzmaxz; - Box3d fzbox; - -public: - - /// - vnetrule (); - /// - ~vnetrule (); - /// - int GetNP () const { return points.Size(); } - /// - int GetNF () const { return faces.Size(); } - /// - int GetNE () const { return elements.Size(); } - /// - int GetNO () const { return orientations.Size(); } - /// - int GetNEd () const { return edges.Size(); } - /// - int GetNOldP () const { return noldp; } - /// - int GetNOldF () const { return noldf; } - /// - int GetNDelF () const { return delfaces.Size(); } - /// - int GetQuality () const { return quality; } - /// - int GetFNearness (int fi) const { return fnearness.Get(fi); } - /// - int GetPNearness (int pi) const { return pnearness.Get(pi); } - /// - int GetMaxPNearness () const { return maxpnearness; } - - - /// - const Point3d & GetPoint (int i) const { return points.Get(i); } - /// - const Element2d & GetFace (int i) const { return faces.Get(i); } - /// - const Element & GetElement (int i) const { return elements.Get(i); } - /// - const twoint & GetEdge (int i) const { return edges.Get(i); } - /// - int GetDelFace (int i) const { return delfaces.Get(i); } - /// - int IsDelFace (int fn) const; - - /// - float CalcPointDist (int pi, const Point3d & p) const; - /// - double PointDistFactor (int pi) const - { - return tolerances.Get(pi); - } - /// - void SetFreeZoneTransformation (const Vector & allp, - int tolclass); - /// - int IsInFreeZone (const Point3d & p) const; - /** - 0 not in free-zone - 1 in free-zone - -1 maybe - */ - int IsTriangleInFreeZone (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const ARRAY<int> & pi, int newone); - /// - int IsQuadInFreeZone (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, - const ARRAY<int> & pi, int newone); - /// - int IsTriangleInFreeSet (const Point3d & p1, const Point3d & p2, - const Point3d & p3, int fs, const ARRAY<int> & pi, int newone); - - /// - int IsQuadInFreeSet (const Point3d & p1, const Point3d & p2, - const Point3d & p3, const Point3d & p4, - int fs, const ARRAY<int> & pi, int newone); - - /// - int ConvexFreeZone () const; - - /// if t1 and t2 are neighbourtriangles, NTP returns the opposite Point of t1 in t2 - int NeighbourTrianglePoint (const threeint & t1, const threeint & t2) const; - /// - const Point3d & GetTransFreeZone (int i) { return transfreezone.Get(i); } - - /// - int GetNP (int fn) const - { return faces.Get(fn).GetNP(); } - /// - int GetPointNr (int fn, int endp) const - { return faces.Get(fn).PNum(endp); } - /// - int GetPointNrMod (int fn, int endp) const - { return faces.Get(fn).PNumMod(endp); } - /// - const fourint & GetOrientation (int i) { return orientations.Get(i); } - - /// - int TestFlag (char flag) const; - - /// - const DenseMatrix & GetOldUToNewU () const { return oldutonewu; } - // - // const DenseMatrix & GetOldUToFreeZone () const { return oldutofreezone; } - // - // const DenseMatrix & GetOldUToFreeZoneLimit () const - // { return oldutofreezonelimit; } - /// - const char * Name () const { return name; } - /// - void LoadRule (istream & ist); - - /// - const ARRAY<Point3d> & GetTransFreeZone () { return transfreezone; } - /// - int TestOk () const; - - /// - friend void TestRules (); - /// - // friend void Plot3DRule (const ROT3D & r, char key); -}; - - - -#endif - diff --git a/Netgen/libsrc/meshing/secondorder.cpp b/Netgen/libsrc/meshing/secondorder.cpp deleted file mode 100644 index d260eb20d7..0000000000 --- a/Netgen/libsrc/meshing/secondorder.cpp +++ /dev/null @@ -1,496 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ - - - - Refinement :: Refinement () - { - ; - } - - Refinement :: ~Refinement () - { - ; - } - - void Refinement :: MakeSecondOrder (Mesh & mesh) - { - int nseg, nse, ne; - - mesh.ComputeNVertices(); - mesh.SetNP(mesh.GetNV()); - - INDEX_2_HASHTABLE<int> between(mesh.GetNP() + 5); - - - bool thinlayers = 0; - for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) - if (mesh[ei].GetType() == PRISM || - mesh[ei].GetType() == PRISM12) - thinlayers = 1; - - - nseg = mesh.GetNSeg(); - for (SegmentIndex si = 0; si < nseg; si++) - { - Segment & el = mesh.LineSegment(si); - - INDEX_2 i2 = INDEX_2::Sort (el.p1, el.p2); - - if (between.Used(i2)) - el.pmid = between.Get(i2); - else - { - Point3d pb; - EdgePointGeomInfo ngi; - PointBetween (mesh.Point (el.p1), - mesh.Point (el.p2), 0.5, - el.surfnr1, el.surfnr2, - el.epgeominfo[0], el.epgeominfo[1], - pb, ngi); - - el.pmid = mesh.AddPoint (pb); - between.Set (i2, el.pmid); - } - } - - // refine surface elements - nse = mesh.GetNSE(); - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - int j; - const Element2d & el = mesh.SurfaceElement(sei); - - int onp; - - Element2d newel; - newel.SetIndex (el.GetIndex()); - - static int betw_trig[3][3] = - { { 1, 2, 3 }, - { 0, 2, 4 }, - { 0, 1, 5 } }; - static int betw_quad6[2][3] = - { { 0, 1, 4 }, - { 3, 2, 5 } }; - static int betw_quad8[4][3] = - { { 0, 1, 4 }, - { 3, 2, 5 }, - { 0, 3, 6 }, - { 1, 2, 7 } }; - int (*betw)[3]; - - switch (el.GetType()) - { - case TRIG: - case TRIG6: - { - betw = betw_trig; - newel.SetType (TRIG6); - onp = 3; - break; - } - case QUAD: - case QUAD6: - case QUAD8: - { - if (thinlayers) - { - betw = betw_quad6; - newel.SetType (QUAD6); - } - else - { - betw = betw_quad8; - newel.SetType (QUAD8); - } - onp = 4; - break; - } - default: - PrintSysError ("Unhandled element in secondorder:", int(el.GetType())); - } - - for (j = 0; j < onp; j++) - newel[j] = el[j]; - - int nnp = newel.GetNP(); - for (j = 0; j < nnp-onp; j++) - { - int pi1 = newel[betw[j][0]]; - int pi2 = newel[betw[j][1]]; - - INDEX_2 i2 = INDEX_2::Sort (pi1, pi2); - - if (between.Used(i2)) - newel[onp+j] = between.Get(i2); - else - { - Point3d pb; - PointGeomInfo newgi; - PointBetween (mesh.Point (pi1), - mesh.Point (pi2), 0.5, - mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), - el.GeomInfoPi (betw[j][0]+1), - el.GeomInfoPi (betw[j][1]+1), - pb, newgi); - - newel[onp+j] = mesh.AddPoint (pb); - between.Set (i2, newel[onp+j]); - } - } - - mesh.SurfaceElement(sei) = newel; - } - - - // int i, j; - - - - // refine volume elements - ne = mesh.GetNE(); - for (int i = 1; i <= ne; i++) - { - int j; - const Element & el = mesh.VolumeElement(i); - int onp; - - Element newel; - newel.SetIndex (el.GetIndex()); - - static int betw_tet[6][3] = - { { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 4, 10 } }; - static int betw_prism[6][3] = - { - { 1, 3, 7 }, - { 1, 2, 8 }, - { 2, 3, 9 }, - { 4, 6, 10 }, - { 4, 5, 11 }, - { 5, 6, 12 }, - }; - int (*betw)[3]; - - switch (el.GetType()) - { - case TET: - case TET10: - { - betw = betw_tet; - newel.SetType (TET10); - onp = 4; - break; - } - case PRISM: - case PRISM12: - { - betw = betw_prism; - newel.SetType (PRISM12); - onp = 6; - break; - } - default: - PrintSysError ("MakeSecondOrder, illegal vol type ", el.GetType()); - } - - - for (int j = 1; j <= onp; j++) - newel.PNum(j) = el.PNum(j); - int nnp = newel.GetNP(); - - for (int j = 0; j < nnp-onp; j++) - { - INDEX_2 i2(newel.PNum(betw[j][0]), - newel.PNum(betw[j][1])); - i2.Sort(); - - if (between.Used(i2)) - newel.PNum(onp+1+j) = between.Get(i2); - else - { - newel.PNum(onp+1+j) = mesh.AddPoint - (Center (mesh.Point(i2.I1()), - mesh.Point(i2.I2()))); - between.Set (i2, newel.PNum(onp+1+j)); - } - } - - mesh.VolumeElement (i) = newel; - } - - - // makes problems after linear mesh refinement, since - // 2nd order identifications are not removed - // update identification tables - for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) - { - ARRAY<int,PointIndex::BASE> identmap; - mesh.GetIdentifications().GetMap (i, identmap); - - for (INDEX_2_HASHTABLE<int>::Iterator it = between.Begin(); - it != between.End(); it++) - { - INDEX_2 i2; - int newpi; - between.GetData (it, i2, newpi); - INDEX_2 oi2(identmap.Get(i2.I1()), - identmap.Get(i2.I2())); - oi2.Sort(); - if (between.Used (oi2)) - { - int onewpi = between.Get(oi2); - mesh.GetIdentifications().Add (newpi, onewpi, i); - } - } - - /* - for (int j = 1; j <= between.GetNBags(); j++) - for (int k = 1; k <= between.GetBagSize(j); k++) - { - INDEX_2 i2; - int newpi; - between.GetData (j, k, i2, newpi); - INDEX_2 oi2(identmap.Get(i2.I1()), - identmap.Get(i2.I2())); - oi2.Sort(); - if (between.Used (oi2)) - { - int onewpi = between.Get(oi2); - mesh.GetIdentifications().Add (newpi, onewpi, i); - } - } - */ - } - - - // mesh.mglevels++; - int oldsize = mesh.mlbetweennodes.Size(); - mesh.mlbetweennodes.SetSize(mesh.GetNP()); - for (int i = oldsize; i < mesh.GetNP(); i++) - mesh.mlbetweennodes[i] = INDEX_2(0,0); - - /* - for (i = 1; i <= between.GetNBags(); i++) - for (j = 1; j <= between.GetBagSize(i); j++) - { - INDEX_2 oldp; - int newp; - between.GetData (i, j, oldp, newp); - mesh.mlbetweennodes.Elem(newp) = oldp; - } - */ - - for (INDEX_2_HASHTABLE<int>::Iterator it = between.Begin(); - it != between.End(); it++) - { - mesh.mlbetweennodes[between.GetData (it)] = between.GetHash(it); - } - - mesh.ComputeNVertices(); - - // ValidateSecondOrder (mesh); - } - - - void Refinement :: ValidateSecondOrder (Mesh & mesh) - { - PrintMessage (3, "Validate mesh"); - int np = mesh.GetNP(); - int ne = mesh.GetNE(); - // int i, j; - ARRAY<INDEX_2> parents(np); - - for (int i = 1; i <= np; i++) - parents.Elem(i) = INDEX_2(0,0); - - for (int i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - if (el.GetType() == TET10) - { - static int betweentab[6][3] = - { { 1, 2, 5 }, - { 1, 3, 6 }, - { 1, 4, 7 }, - { 2, 3, 8 }, - { 2, 4, 9 }, - { 3, 4, 10 } }; - for (int j = 0; j < 6; j++) - { - int f1 = el.PNum (betweentab[j][0]); - int f2 = el.PNum (betweentab[j][1]); - int son = el.PNum (betweentab[j][2]); - parents.Elem(son).I1() = f1; - parents.Elem(son).I2() = f2; - } - } - } - - ValidateRefinedMesh (mesh, parents); - } - - - void Refinement :: - ValidateRefinedMesh (Mesh & mesh, - ARRAY<INDEX_2> & parents) - { - // int i, j, k; - - // homotopy method - - int ne = mesh.GetNE(); - - int cnttrials = 100; - int wrongels = 0; - for (int i = 1; i <= ne; i++) - if (mesh.VolumeElement(i).CalcJacobianBadness (mesh.Points()) > 1e10) - { - wrongels++; - mesh.VolumeElement(i).flags.badel = 1; - } - else - mesh.VolumeElement(i).flags.badel = 0; - - double facok = 0; - double factry; - - BitArray illegalels(ne); - illegalels.Clear(); - - - if (wrongels) - { - cout << "WARNING: " << wrongels << " illegal element(s) found" << endl; - - int np = mesh.GetNP(); - ARRAY<Point3d> should(np); - ARRAY<Point3d> can(np); - - for (int i = 1; i <= np; i++) - { - should.Elem(i) = can.Elem(i) = mesh.Point(i); - } - - for (int i = 1; i <= parents.Size(); i++) - { - if (parents.Get(i).I1()) - can.Elem(i) = Center (can.Elem(parents.Get(i).I1()), - can.Elem(parents.Get(i).I2())); - } - - BitArray boundp(np); - boundp.Clear(); - for (int i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & sel = mesh.SurfaceElement(i); - for (int j = 1; j <= sel.GetNP(); j++) - boundp.Set(sel.PNum(j)); - } - - - (*testout) << "bpoints:" << endl; - for (int i = 1; i <= np; i++) - if (boundp.Test(i)) - (*testout) << i << endl; - - double lam = 0.5; - - while (facok < 1-1e-8 && cnttrials > 0) - { - lam *= 4; - if (lam > 2) lam = 2; - - do - { - // cout << "trials: " << cnttrials << endl; - lam *= 0.5; - cnttrials--; - - cout << "lam = " << lam << endl; - - factry = lam + (1-lam) * facok; - cout << "trying: " << factry << endl; - - for (int i = 1; i <= np; i++) - if (boundp.Test(i)) - { - for (int j = 1; j <= 3; j++) - mesh.Point(i).X(j) = - lam * should.Get(i).X(j) + - (1-lam) * can.Get(i).X(j); - } - else - mesh.Point(i) = can.Get(i); - - // (*testout) << "bad els: " << endl; - wrongels = 0; - for (int i = 1; i <= ne; i++) - { - if (!illegalels.Test(i) && - mesh.VolumeElement(i). - CalcJacobianBadness(mesh.Points()) > 1e10) - { - wrongels++; - Element & el = mesh.VolumeElement(i); - el.flags.badel = 1; - - - if (lam < 1e-4) - illegalels.Set(i); - - - /* - (*testout) << i << ": "; - for (j = 1; j <= el.GetNP(); j++) - (*testout) << el.PNum(j) << " "; - (*testout) << endl; - */ - } - else - mesh.VolumeElement(i).flags.badel = 0; - } - cout << "wrongels = " << wrongels << endl; - } - while (wrongels && cnttrials > 0); - - mesh.CalcSurfacesOfNode(); - mesh.ImproveMeshJacobian (OPT_WORSTCASE); - - facok = factry; - for (int i = 1; i <= np; i++) - can.Elem(i) = mesh.Point(i); - } - } - - - - for (int i = 1; i <= ne; i++) - { - if (illegalels.Test(i)) - { - cout << "illegal element: " << i << endl; - mesh.VolumeElement(i).flags.badel = 1; - } - else - mesh.VolumeElement(i).flags.badel = 0; - } - - /* - if (cnttrials <= 0) - { - cerr << "ERROR: Sorry, illegal elements:" << endl; - } - */ - } - -} diff --git a/Netgen/libsrc/meshing/smoothing2.cpp b/Netgen/libsrc/meshing/smoothing2.cpp deleted file mode 100644 index d26b20ad5d..0000000000 --- a/Netgen/libsrc/meshing/smoothing2.cpp +++ /dev/null @@ -1,922 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" -#include <opti.hpp> - -namespace netgen -{ - - static const MeshOptimize2d * meshthis; - - -#ifdef OLD - - void CalcTriangleBadness (double x2, double x3, double y3, double metricweight, - double h, double & badness, double & g1x, double & g1y) - { - // badness = sqrt(3.0) /36 * circumference^2 / area - 1 - // p1 = (0, 0), p2 = (x2, 0), p3 = (x3, y3); - - Vec2d v23; - double l12, l13, l23, cir, area; - static const double c = sqrt(3.0) / 36; - double c1, c2, c3, c4; - - v23.X() = x3 - x2; - v23.Y() = y3; - - l12 = x2; - l13 = sqrt (x3*x3 + y3*y3); - l23 = v23.Length(); - - cir = l12 + l13 + l23; - area = 0.5 * x2 * y3; - - if (area <= 1e-24 * cir * cir) - { - g1x = 0; - g1y = 0; - badness = 1e10; - return; - } - - badness = c * cir * cir / area - 1; - - c1 = 2 * c * cir / area; - c2 = 0.5 * c * cir * cir / (area * area); - - g1x = c1 * ( - 1 - x3 / l13) - c2 * (-v23.Y()); - g1y = c1 * ( - y3 / l13) - c2 * ( v23.X()); - - // metricweight = 0.1; - if (metricweight > 0) - { - // area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); - // add: metricweight * (area / h^2 + h^2 / area - 2) - - const double area = x2 * y3; - const double dareax1 = -y3; - const double dareay1 = x3 - x2; - - const double areahh = area / (h * h); - const double fac = metricweight * (areahh - 1 / areahh) / area; - - badness += metricweight * (areahh + 1 / areahh - 2); - g1x += fac * dareax1; - g1y += fac * dareay1; - - /* - // add: metricweight * (l1^2/h^2 + l2^2/h^2 + l3^2/h2 + h^2/l1^2 + h^2/l2^2 + h^2/l3^2 - 6) - double h2 = h*h; - double l1 = x2*x2; - double l2 = x3*x3+y3*y3; - double l3 = (x2-x3)*(x2-x3)+y3*y3; - double dl1dx = 2*(-x2); - double dl1dy = 0; - double dl2dx = -2*x3; - double dl2dy = -2*y3; - - badness += (l1/h2 + l2/h2 + l3/h2 +h2/l1 + h2/l2 + h2/l3-6) * metricweight; - - g1x += metricweight * (dl1dx/h2-h2/(l1*l1)*dl1dx + dl2dx/h2-h2/(l2*l2)*dl2dx); - g1y += metricweight * (dl1dy/h2-h2/(l1*l1)*dl1dy + dl2dy/h2-h2/(l2*l2)*dl2dy); - */ - } - } - -#endif - - - /* - static const double c_trig = sqrt(3.0) / 12; - static const double c_trig4 = sqrt(3.0) / 3; - */ - static const double c_trig = 0.14433756; - static const double c_trig4 = 0.57735026; - - inline double CalcTriangleBadness (double x2, double x3, double y3, - double metricweight, double h) - { - // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 - // p1 = (0, 0), p2 = (x2, 0), p3 = (x3, y3); - - double cir_2 = (x2*x2 + x3*x3 + y3*y3 - x2*x3); - double area = x2 * y3; - - if (area <= 1e-24 * cir_2) - return 1e10; - - double badness = c_trig4 * cir_2 / area - 1; - - if (metricweight > 0) - { - // add: metricweight * (area / h^2 + h^2 / area - 2) - - double areahh = area / (h * h); - badness += metricweight * (areahh + 1 / areahh - 2); - } - return badness; - } - - - - inline void CalcTriangleBadness (double x2, double x3, double y3, double metricweight, - double h, double & badness, double & g1x, double & g1y) - { - // old: badness = sqrt(3.0) /36 * circumference^2 / area - 1 - // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 - // p1 = (0, 0), p2 = (x2, 0), p3 = (x3, y3); - - - double cir_2 = 2* (x2*x2 + x3*x3 + y3*y3 - x2*x3); - double area = 0.5 * x2 * y3; - - if (area <= 1e-24 * cir_2) - { - g1x = 0; - g1y = 0; - badness = 1e10; - return; - } - - badness = c_trig * cir_2 / area - 1; - - double c1 = -2 * c_trig / area; - double c2 = 0.5 * c_trig * cir_2 / (area * area); - g1x = c1 * (x2 + x3) + c2 * y3; - g1y = c1 * (y3) + c2 * (x2-x3); - - if (metricweight > 0) - { - // area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); - // add: metricweight * (area / h^2 + h^2 / area - 2) - - double area = x2 * y3; - double dareax1 = -y3; - double dareay1 = x3 - x2; - - double areahh = area / (h * h); - double fac = metricweight * (areahh - 1 / areahh) / area; - - badness += metricweight * (areahh + 1 / areahh - 2); - g1x += fac * dareax1; - g1y += fac * dareay1; - } - } - - - - - - - - - -#ifdef OLD - double CalcTriangleBadness (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - double metricweight, - double h) - { - double badness; - double g1x, g1y; - - Vec3d e1 (p1, p2); - Vec3d e2 (p1, p3); - - double e1l = e1.Length() + 1e-24; - e1 /= e1l; - double e1e2 = (e1 * e2); - e2.Add (-e1e2, e1); - double e2l = e2.Length(); - - CalcTriangleBadness ( e1l, e1e2, e2l, - metricweight, h, badness, g1x, g1y); - return badness; - } -#endif - - - - - double CalcTriangleBadness (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - double metricweight, - double h) - { - // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 - // p1 = (0, 0), p2 = (x2, 0), p3 = (x3, y3); - - Vec3d e12(p1,p2); - Vec3d e13(p1,p3); - Vec3d e23(p2,p3); - - double l12_2 = e12.Length2(); - double l13_2 = e13.Length2(); - double l23_2 = e23.Length2(); - - double cir_2 = l12_2 + l13_2 + l23_2; - Vec3d area_v = Cross (e12, e13); - double area = 0.5 * area_v.Length(); - - if (area <= 1e-24 * cir_2) - return 1e10; - - double badness = c_trig * cir_2 / area - 1; - - if (metricweight > 0) - { - // area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); - // add: metricweight * (area / h^2 + h^2 / area - 2) - - const double areahh = area / (h * h); - badness += metricweight * (areahh + 1 / areahh - 2); - } - - return badness; - } - - - double CalcTriangleBadness (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Vec3d & n, - double metricweight, - double h) - { - Vec3d v1 (p1, p2); - Vec3d v2 (p1, p3); - - Vec3d e1 = v1; - Vec3d e2 = v2; - - e1 -= (e1 * n) * n; - e1 /= (e1.Length() + 1e-24); - e2 = Cross (n, e1); - - return CalcTriangleBadness ( (e1 * v1), (e1 * v2), (e2 * v2), - metricweight, h); - } - - - - - - static MeshPoint sp1; - static PointGeomInfo gi1; - static Vec3d n, t1, t2; - static ARRAY<SurfaceElementIndex> locelements(0); - static ARRAY<int> locrots(0); - static ARRAY<double> lochs(0); - // static int locerr2; - static double locmetricweight = 0; - static double loch; - static int surfi, surfi2; - static int uselocalh; - - - class Opti2SurfaceMinFunction : public MinFunction - { - const Mesh & mesh; - public: - Opti2SurfaceMinFunction (const Mesh & amesh) - : mesh(amesh) - { } ; - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double Func (const Vector & x) const; - }; - - double Opti2SurfaceMinFunction :: - Func (const Vector & x) const - { - Vector g(x.Size()); - return FuncGrad (x, g); - } - - - double Opti2SurfaceMinFunction :: - FuncGrad (const Vector & x, Vector & grad) const - { - Vec3d n, vgrad; - Point3d pp1; - double g1x, g1y; - double badness, hbadness; - - vgrad = 0; - badness = 0; - - meshthis -> GetNormalVector (surfi, sp1, gi1, n); - - pp1 = sp1; - pp1.Add2 (x.Get(1), t1, x.Get(2), t2); - - // meshthis -> ProjectPoint (surfi, pp1); - // meshthis -> GetNormalVector (surfi, pp1, n); - - for (int j = 0; j < locelements.Size(); j++) - { - int roti = locrots[j]; - const Element2d & bel = mesh[locelements[j]]; - - Vec3d e1(pp1, mesh[bel.PNumMod(roti + 1)]); - Vec3d e2(pp1, mesh[bel.PNumMod(roti + 2)]); - - if (uselocalh) loch = lochs[j]; - - double e1l = e1.Length(); - if (Determinant(e1, e2, n) > 1e-8 * e1l * e2.Length()) - { - e1 /= e1l; - double e1e2 = e1 * e2; - e2.Add (-e1e2, e1); - double e2l = e2.Length(); - - CalcTriangleBadness ( e1l, e1e2, e2l, locmetricweight, loch, - hbadness, g1x, g1y); - - badness += hbadness; - vgrad.Add2 (g1x, e1, g1y / e2l, e2); - } - else - badness += 1e8; - } - - vgrad.Add (-(vgrad * n), n); - - grad.Elem(1) = vgrad * t1; - grad.Elem(2) = vgrad * t2; - return badness; - } - - - class Opti2EdgeMinFunction : public MinFunction - { - const Mesh & mesh; - public: - Opti2EdgeMinFunction (const Mesh & amesh) - : mesh(amesh) { } ; - - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double Func (const Vector & x) const; - }; - - double Opti2EdgeMinFunction :: Func (const Vector & x) const - { - Vector g(x.Size()); - return FuncGrad (x, g); - } - - double Opti2EdgeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const - { - int j, rot; - Vec3d n1, n2, v1, v2, e1, e2, vgrad; - Point3d pp1; - Vec2d g1; - double badness, hbadness; - - vgrad.X() = 0; - vgrad.Y() = 0; - vgrad.Z() = 0; - badness = 0; - - pp1 = sp1 + x.Get(1) * t1; - meshthis -> ProjectPoint2 (surfi, surfi2, pp1); - - for (j = 0; j < locelements.Size(); j++) - { - rot = locrots[j]; - const Element2d & bel = mesh[locelements[j]]; - - v1 = mesh[bel.PNumMod(rot + 1)] - pp1; - v2 = mesh[bel.PNumMod(rot + 2)] - pp1; - - e1 = v1; - e2 = v2; - e1 /= e1.Length(); - e2 -= (e1 * e2) * e1; - e2 /= e2.Length(); - - if (uselocalh) loch = lochs[j]; - CalcTriangleBadness ( (e1 * v1), (e1 * v2), (e2 * v2), locmetricweight, loch, - hbadness, g1.X(), g1.Y()); - - badness += hbadness; - - vgrad.X() += g1.X() * e1.X() + g1.Y() * e2.X(); - vgrad.Y() += g1.X() * e1.Y() + g1.Y() * e2.Y(); - vgrad.Z() += g1.X() * e1.Z() + g1.Y() * e2.Z(); - } - - meshthis -> GetNormalVector (surfi, pp1, n1); - meshthis -> GetNormalVector (surfi2, pp1, n2); - - v1 = Cross (n1, n2); - v1 /= v1.Length(); - - grad.Elem(1) = (vgrad * v1) * (t1 * v1); - - return badness; - } - - - - - class Opti2SurfaceMinFunctionJacobian : public MinFunction - { - const Mesh & mesh; - public: - Opti2SurfaceMinFunctionJacobian (const Mesh & amesh) - : mesh(amesh) - { } ; - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; - virtual double Func (const Vector & x) const; - }; - - double Opti2SurfaceMinFunctionJacobian :: - Func (const Vector & x) const - { - Vector g(x.Size()); - return FuncGrad (x, g); - } - - - double Opti2SurfaceMinFunctionJacobian :: - FuncGrad (const Vector & x, Vector & grad) const - { - // from 2d: - - int j, k, lpi, gpi; - Vec3d n, vgrad; - Point3d pp1; - Vec2d g1, vdir; - double badness, hbadness, hbad, hderiv; - - vgrad = 0; - badness = 0; - - meshthis -> GetNormalVector (surfi, sp1, gi1, n); - - pp1 = sp1; - pp1.Add2 (x.Get(1), t1, x.Get(2), t2); - - // meshthis -> ProjectPoint (surfi, pp1); - // meshthis -> GetNormalVector (surfi, pp1, n); - - static ARRAY<Point2d> pts2d; - pts2d.SetSize(mesh.GetNP()); - - grad = 0; - - for (j = 1; j <= locelements.Size(); j++) - { - lpi = locrots.Get(j); - const Element2d & bel = - mesh[locelements.Get(j)]; - - gpi = bel.PNum(lpi); - - for (k = 1; k <= bel.GetNP(); k++) - { - PointIndex pi = bel.PNum(k); - pts2d.Elem(pi) = Point2d (t1 * (mesh.Point(pi) - sp1), - t2 * (mesh.Point(pi) - sp1)); - } - pts2d.Elem(gpi) = Point2d (x.Get(1), x.Get(2)); - - - for (k = 1; k <= 2; k++) - { - if (k == 1) - vdir = Vec2d (1, 0); - else - vdir = Vec2d (0, 1); - - hbad = bel. - CalcJacobianBadnessDirDeriv (pts2d, lpi, vdir, hderiv); - - grad.Elem(k) += hderiv; - if (k == 1) - badness += hbad; - } - } - - - /* - vgrad.Add (-(vgrad * n), n); - - grad.Elem(1) = vgrad * t1; - grad.Elem(2) = vgrad * t2; - */ - return badness; - } - - - - - double Opti2SurfaceMinFunctionJacobian :: - FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const - { - // from 2d: - - int j, k, lpi, gpi; - Vec3d n, vgrad; - Point3d pp1; - Vec2d g1, vdir; - double badness, hbadness, hbad, hderiv; - - vgrad = 0; - badness = 0; - - meshthis -> GetNormalVector (surfi, sp1, gi1, n); - - pp1 = sp1; - pp1.Add2 (x.Get(1), t1, x.Get(2), t2); - - static ARRAY<Point2d> pts2d; - pts2d.SetSize(mesh.GetNP()); - - deriv = 0; - - for (j = 1; j <= locelements.Size(); j++) - { - lpi = locrots.Get(j); - const Element2d & bel = - mesh[locelements.Get(j)]; - - gpi = bel.PNum(lpi); - - for (k = 1; k <= bel.GetNP(); k++) - { - PointIndex pi = bel.PNum(k); - pts2d.Elem(pi) = Point2d (t1 * (mesh.Point(pi) - sp1), - t2 * (mesh.Point(pi) - sp1)); - } - pts2d.Elem(gpi) = Point2d (x.Get(1), x.Get(2)); - - - vdir = Vec2d (dir(0), dir(1)); - - hbad = bel. - CalcJacobianBadnessDirDeriv (pts2d, lpi, vdir, hderiv); - - deriv += hderiv; - badness += hbad; - } - - - return badness; - } - - - - - - - - MeshOptimize2d dummy; - - MeshOptimize2d :: MeshOptimize2d () - { - SetFaceIndex (0); - SetImproveEdges (0); - SetMetricWeight (0); - SetWriteStatus (1); - } - - - void MeshOptimize2d :: SelectSurfaceOfPoint (const Point3d & p, - const PointGeomInfo & gi) - { - ; - } - - void MeshOptimize2d :: ImproveMesh (Mesh & mesh) - { - if (!faceindex) - { - PrintMessage (3, "Smoothing"); - - for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) - { - ImproveMesh (mesh); - if (multithread.terminate) - throw NgException ("Meshing stopped"); - } - faceindex = 0; - return; - } - - CheckMeshApproximation (mesh); - - int i, j, k, surfi3; - SurfaceElementIndex sei; - - ARRAY<SurfaceElementIndex> seia; - mesh.GetSurfaceElementsOfFace (faceindex, seia); - - bool mixed = 0; - for (i = 0; i < seia.Size(); i++) - if (mesh[seia[i]].GetNP() != 3) - { - mixed = 1; - break; - } - - - int loci; - double fact; - int moveisok; - - PointGeomInfo ngi; - Point3d origp; - - Vec3d n1, n2; - Vector x(2), xedge(1); - - ARRAY<MeshPoint, PointIndex::BASE> savepoints(mesh.GetNP()); - uselocalh = mparam.uselocalh; - - ARRAY<int, PointIndex::BASE> nelementsonpoint(mesh.GetNP()); - nelementsonpoint = 0; - - for (i = 0; i < seia.Size(); i++) - { - const Element2d & el = mesh[seia[i]]; - for (j = 0; j < el.GetNP(); j++) - nelementsonpoint[el[j]]++; - } - - - TABLE<SurfaceElementIndex,PointIndex::BASE> elementsonpoint(nelementsonpoint); - for (i = 0; i < seia.Size(); i++) - { - const Element2d & el = mesh[seia[i]]; - for (j = 0; j < el.GetNP(); j++) - elementsonpoint.Add (el[j], seia[i]); - } - - loch = mparam.maxh; - locmetricweight = metricweight; - meshthis = this; - - Opti2SurfaceMinFunction surfminf(mesh); - Opti2EdgeMinFunction edgeminf(mesh); - Opti2SurfaceMinFunctionJacobian surfminfj(mesh); - - OptiParameters par; - par.maxit_linsearch = 8; - par.maxit_bfgs = 5; - - /* - if (improveedges) - for (i = 1; i <= mesh.GetNP(); i++) - if (mesh.PointType(i) == EDGEPOINT) - { - continue; - PrintDot (); - sp1 = mesh.Point(i); - - locelements.SetSize(0); - locrots.SetSize (0); - lochs.SetSize (0); - surfi = surfi2 = surfi3 = 0; - - for (j = 0; j < elementsonpoint[i].Size(); j++) - { - sei = elementsonpoint[i][j]; - const Element2d * bel = &mesh[sei]; - - if (!surfi) - surfi = mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr(); - else if (surfi != mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr()) - { - if (surfi2 != 0 && surfi2 != - mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr()) - surfi3 = mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr(); - else - surfi2 = mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr(); - } - - locelements.Append (sei); - - if (bel->PNum(1) == i) - locrots.Append (1); - else if (bel->PNum(2) == i) - locrots.Append (2); - else - locrots.Append (3); - - if (uselocalh) - { - Point3d pmid = Center (mesh.Point(bel->PNum(1)), - mesh.Point(bel->PNum(2)), - mesh.Point(bel->PNum(3))); - lochs.Append (mesh.GetH(pmid)); - } - } - - if (surfi2 && !surfi3) - { - GetNormalVector (surfi, sp1, n1); - GetNormalVector (surfi2, sp1, n2); - t1 = Cross (n1, n2); - - xedge = 0; - BFGS (xedge, edgeminf, par, 1e-6); - - mesh.Point(i).X() += xedge.Get(1) * t1.X(); - mesh.Point(i).Y() += xedge.Get(1) * t1.Y(); - mesh.Point(i).Z() += xedge.Get(1) * t1.Z(); - ProjectPoint2 (surfi, surfi2, mesh.Point(i)); - } - } - */ - - - bool printeddot = 0; - char plotchar = '.'; - int modplot = 1; - if (mesh.GetNP() > 1000) - { - plotchar = '+'; - modplot = 10; - } - if (mesh.GetNP() > 10000) - { - plotchar = 'o'; - modplot = 100; - } - int cnt = 0; - - for (PointIndex pi = PointIndex::BASE; - pi < mesh.GetNP()+PointIndex::BASE; pi++) - - if (mesh.PointType(pi) == SURFACEPOINT) - { - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - if (pi == 3679) - (*testout) << " old: " << mesh[pi] << endl; - - - cnt++; - if (cnt % modplot == 0 && writestatus) - { - printeddot = 1; - PrintDot (plotchar); - } - - if (elementsonpoint[pi].Size() == 0) - continue; - - sp1 = mesh[pi]; - - Element2d & hel = mesh[elementsonpoint[pi][0]]; - - int hpi = 0; - for (j = 1; j <= hel.GetNP(); j++) - if (hel.PNum(j) == pi) - { - hpi = j; - break; - } - - gi1 = hel.GeomInfoPi(hpi); - SelectSurfaceOfPoint (sp1, gi1); - - locelements.SetSize(0); - locrots.SetSize (0); - lochs.SetSize (0); - - for (j = 0; j < elementsonpoint[pi].Size(); j++) - { - sei = elementsonpoint[pi][j]; - const Element2d & bel = mesh[sei]; - surfi = mesh.GetFaceDescriptor(bel.GetIndex()).SurfNr(); - - locelements.Append (sei); - - for (k = 1; k <= bel.GetNP(); k++) - if (bel.PNum(k) == pi) - { - locrots.Append (k); - break; - } - - if (uselocalh) - { - Point3d pmid = Center (mesh[bel[0]], mesh[bel[1]], mesh[bel[2]]); - lochs.Append (mesh.GetH(pmid)); - } - } - - - GetNormalVector (surfi, sp1, gi1, n); - n.GetNormal (t1); - t2 = Cross (n, t1); - - // save points, and project to tangential plane - for (j = 0; j < locelements.Size(); j++) - { - const Element2d & el = mesh[locelements[j]]; - for (k = 0; k < el.GetNP(); k++) - savepoints[el[k]] = mesh[el[k]]; - } - - for (j = 0; j < locelements.Size(); j++) - { - const Element2d & el = mesh[locelements[j]]; - for (k = 0; k < el.GetNP(); k++) - { - PointIndex hpi = el[k]; - double lam = n * (mesh[hpi] - sp1); - mesh[hpi] -= lam * n; - } - } - - x = 0; - - if (mixed) - BFGS (x, surfminfj, par, 1e-6); - else - BFGS (x, surfminf, par, 1e-6); - - origp = mesh[pi]; - loci = 1; - fact = 1; - moveisok = 0; - - // restore other points - for (j = 0; j < locelements.Size(); j++) - { - const Element2d & el = mesh[locelements[j]]; - for (k = 0; k < el.GetNP(); k++) - { - PointIndex hpi = el[k]; - if (hpi != pi) mesh[hpi] = savepoints[hpi]; - } - } - - - //optimizer loop (if not whole distance is not possible, move only a bit!!!!) - while (loci <= 5 && !moveisok) - { - loci ++; - mesh[pi].X() = origp.X() + (x.Get(1) * t1.X() + x.Get(2) * t2.X())*fact; - mesh[pi].Y() = origp.Y() + (x.Get(1) * t1.Y() + x.Get(2) * t2.Y())*fact; - mesh[pi].Z() = origp.Z() + (x.Get(1) * t1.Z() + x.Get(2) * t2.Z())*fact; - fact = fact/2.; - - if (pi == 3679) - (*testout) << " before proj: " << mesh[pi] << endl; - - ProjectPoint (surfi, mesh[pi]); - - if (pi == 3679) - { - (*testout) << " after proj: " << mesh[pi] << endl; - (*testout) << "surfi =" << surfi << endl; - } - - moveisok = CalcPointGeomInfo(surfi, ngi, mesh[pi]); - // point lies on same chart in stlsurface - - if (moveisok) - { - for (j = 0; j < locelements.Size(); j++) - mesh[locelements[j]].GeomInfoPi(locrots[j]) = ngi; - } - else - { - mesh[pi] = origp; - } - - } - - if (pi == 3679) - (*testout) << " new: " << mesh[pi] << endl; - } - - - if (printeddot) - PrintDot ('\n'); - - CheckMeshApproximation (mesh); - mesh.SetNextTimeStamp(); - } - - void MeshOptimize2d :: GetNormalVector(INDEX /* surfind */, const Point3d & p, Vec3d & nv) const - { - nv = Vec3d (0, 0, 1); - } - - void MeshOptimize2d :: GetNormalVector(INDEX surfind, const Point3d & p, PointGeomInfo & gi, Vec3d & n) const - { - GetNormalVector (surfind, p, n); - } - -} diff --git a/Netgen/libsrc/meshing/smoothing3.cpp b/Netgen/libsrc/meshing/smoothing3.cpp deleted file mode 100644 index 61c1910884..0000000000 --- a/Netgen/libsrc/meshing/smoothing3.cpp +++ /dev/null @@ -1,1546 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" -#ifdef SOLIDGEOM -#include <csg.hpp> -#endif -#include <opti.hpp> - - -namespace netgen -{ - - - PointFunction1 :: PointFunction1 (Mesh::T_POINTS & apoints, - const ARRAY<INDEX_3> & afaces, - double ah) - : points(apoints), faces(afaces) - { - h = ah; - } - - - double PointFunction1 :: Func (const Vector & vp) const - { - int j; - double badness = 0; - Point3d pp(vp(0), vp(1), vp(2)); - - for (j = 0; j < faces.Size(); j++) - { - const INDEX_3 & el = faces[j]; - - double bad = CalcTetBadness (points[el.I1()], - points[el.I3()], - points[el.I2()], - pp, 0); - badness += bad; - } - - return badness; - } - - - - double PointFunction1 :: - FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const - { - static Vector hx(3); - static double eps = 1e-6; - - double dirlen = dir.L2Norm(); - if (dirlen < 1e-14) - { - deriv = 0; - return Func(x); - } - - hx.Set(1, x); - hx.Add(eps * h / dirlen, dir); - double fr = Func (hx); - hx.Set(1, x); - hx.Add(-eps * h / dirlen, dir); - double fl = Func (hx); - - deriv = (fr - fl) / (2 * eps * h) * dirlen; - - return Func(x); - } - - - double PointFunction1 :: FuncGrad (const Vector & x, Vector & g) const - { - static Vector hx(3); - static double eps = 1e-6; - - hx = x; - for (int i = 1; i <= 3; i++) - { - hx.Elem(i) = x.Get(i) + eps * h; - double fr = Func (hx); - hx.Elem(i) = x.Get(i) - eps * h; - double fl = Func (hx); - hx.Elem(i) = x.Get(i); - - g.Elem(i) = (fr - fl) / (2 * eps * h); - } - - return Func(x); - } - - double PointFunction1 :: GradStopping (const Vector & x) const - { - double f = Func(x); - return 1e-8 * f * f; - } - - - - - /* Cheap Functional depending of inner point inside triangular surface */ - - class CheapPointFunction1 : public MinFunction - { - Mesh::T_POINTS & points; - const ARRAY<INDEX_3> & faces; - DenseMatrix m; - double h; - public: - CheapPointFunction1 (Mesh::T_POINTS & apoints, - const ARRAY<INDEX_3> & afaces, - double ah); - - virtual double Func (const Vector & x) const; - virtual double FuncGrad (const Vector & x, Vector & g) const; - }; - - CheapPointFunction1 :: CheapPointFunction1 (Mesh::T_POINTS & apoints, - const ARRAY<INDEX_3> & afaces, - double ah) - : points(apoints), faces(afaces) - { - h = ah; - - - int i, nf = faces.Size(); - - m.SetSize (nf, 4); - - for (i = 1; i <= nf; i++) - { - const Point3d & p1 = points[faces.Get(i).I1()]; - const Point3d & p2 = points[faces.Get(i).I2()]; - const Point3d & p3 = points[faces.Get(i).I3()]; - Vec3d v1 (p1, p2); - Vec3d v2 (p1, p3); - Vec3d n; - Cross (v1, v2, n); - n /= n.Length(); - - m.Elem(i, 1) = n.X(); - m.Elem(i, 2) = n.Y(); - m.Elem(i, 3) = n.Z(); - m.Elem(i, 4) = - (n.X() * p1.X() + n.Y() * p1.Y() + n.Z() * p1.Z()); - } - } - - - double CheapPointFunction1 :: Func (const Vector & vp) const - { - - /* - int j; - double badness = 0; - Point3d pp(vp.Get(1), vp.Get(2), vp.Get(3)); - - for (j = 1; j <= faces.Size(); j++) - { - const INDEX_3 & el = faces.Get(j); - - double bad = CalcTetBadness (points.Get(el.I1()), - points.Get(el.I3()), - points.Get(el.I2()), - pp, 0); - badness += bad; - } - */ - - int i; - double badness = 0; - static Vector hv(4); - static Vector res; - res.SetSize (m.Height()); - - for (i = 1;i <= 3; i++) - hv.Elem(i) = vp.Get(i); - hv.Elem(4) = 1; - m.Mult (hv, res); - - for (i = 1; i <= res.Size(); i++) - { - if (res.Get(i) < 1e-10) - badness += 1e24; - else - badness += 1 / res.Get(i); - } - - return badness; - } - - - double CheapPointFunction1 :: FuncGrad (const Vector & x, Vector & g) const - { - static Vector hx(3); - static double eps = 1e-6; - - hx = x; - for (int i = 1; i <= 3; i++) - { - hx.Elem(i) = x.Get(i) + eps * h; - double fr = Func (hx); - hx.Elem(i) = x.Get(i) - eps * h; - double fl = Func (hx); - hx.Elem(i) = x.Get(i); - - g.Elem(i) = (fr - fl) / (2 * eps * h); - } - - return Func(x); - } - - - - - - - - - - - - - - - - /* ************* PointFunction **************************** */ - - - class PointFunction - { - public: - Mesh::T_POINTS & points; - const Mesh::T_VOLELEMENTS & elements; - TABLE<INDEX,PointIndex::BASE> elementsonpoint; - PointIndex actpind; - double h; - - public: - PointFunction (Mesh::T_POINTS & apoints, - const Mesh::T_VOLELEMENTS & aelements); - - virtual void SetPointIndex (PointIndex aactpind); - void SetLocalH (double ah) { h = ah; } - double GetLocalH () const { return h; } - virtual double PointFunctionValue (const Point3d & pp) const; - virtual double PointFunctionValueGrad (const Point3d & pp, Vector & grad) const; - virtual double PointFunctionValueDeriv (const Point3d & pp, const Vec3d & dir, double & deriv) const; - - int MovePointToInner (); - }; - - - PointFunction :: PointFunction (Mesh::T_POINTS & apoints, - const Mesh::T_VOLELEMENTS & aelements) - : points(apoints), elements(aelements), elementsonpoint(apoints.Size()) - { - INDEX i; - int j; - - for (i = 1; i <= elements.Size(); i++) - { - if (elements.Get(i).NP() == 4) - for (j = 1; j <= elements.Get(i).NP(); j++) - elementsonpoint.Add (elements.Get(i).PNum(j), i); - } - } - - void PointFunction :: SetPointIndex (PointIndex aactpind) - { - actpind = aactpind; - } - - double PointFunction :: PointFunctionValue (const Point3d & pp) const - { - int j; - INDEX eli; - const Element * el; - double badness; - // ARRAY<const Point3d*> p(4); - Point3d hp; - - badness = 0; - - hp = points[actpind]; - points[actpind] = pp; - - for (j = 0; j < elementsonpoint[actpind].Size(); j++) - { - eli = elementsonpoint[actpind][j]; - el = &elements.Get(eli); - badness += CalcTetBadness (points[el->PNum(1)], - points[el->PNum(2)], - points[el->PNum(3)], - points[el->PNum(4)], -1); - } - - points[actpind] = hp; - return badness; - } - - - double PointFunction :: PointFunctionValueGrad (const Point3d & pp, Vector & grad) const - { - double f, delta = h * 1e-6; - Point3d hpp; - - f = PointFunctionValue (pp); - - /* - hpp = pp; - hpp.X() = pp.X() + delta; - fr = PointFunctionValue (hpp); - hpp.X() = pp.X() - delta; - fl = PointFunctionValue (hpp); - grad.Elem(1) = (fr - fl) / (2 * delta); - - hpp = pp; - hpp.Y() = pp.Y() + delta; - fr = PointFunctionValue (hpp); - hpp.Y() = pp.Y() - delta; - fl = PointFunctionValue (hpp); - grad.Elem(2) = (fr - fl) / (2 * delta); - - hpp = pp; - hpp.Z() = pp.Z() + delta; - fr = PointFunctionValue (hpp); - hpp.Z() = pp.Z() - delta; - fl = PointFunctionValue (hpp); - grad.Elem(3) = (fr - fl) / (2 * delta); - */ - - - - // new gradient calculation - int j, k; - INDEX eli; - // double badness; - Point3d hp; - Vec3d vgradi, vgrad(0,0,0); - - // badness = 0; - - hp = points[actpind]; - points[actpind] = pp; - - for (j = 0; j < elementsonpoint[actpind].Size(); j++) - { - eli = elementsonpoint[actpind][j]; - const Element & el = elements.Get(eli); - - for (k = 1; k <= 4; k++) - if (el.PNum(k) == actpind) - { - CalcTetBadnessGrad (points[el.PNum(1)], - points[el.PNum(2)], - points[el.PNum(3)], - points[el.PNum(4)], -1, k, vgradi); - vgrad += vgradi; - } - } - points[actpind] = hp; - - for (j = 1; j <= 3; j++) - grad.Elem(j) = vgrad.X(j); - - return f; - } - - - double PointFunction :: PointFunctionValueDeriv (const Point3d & pp, const Vec3d & dir, - double & deriv) const - { - double f; - Point3d hpp; - - Vec3d dirn (dir); - double ldir = dir.Length(); - - int j, k; - INDEX eli; - // double badness; - Point3d hp; - Vec3d vgradi, vgrad(0,0,0); - - // badness = 0; - - hp = points[actpind]; - points[actpind] = pp; - f = 0; - - for (j = 0; j < elementsonpoint[actpind].Size(); j++) - { - eli = elementsonpoint[actpind][j]; - const Element & el = elements.Get(eli); - - for (k = 1; k <= 4; k++) - if (el.PNum(k) == actpind) - { - f += CalcTetBadnessGrad (points[el.PNum(1)], - points[el.PNum(2)], - points[el.PNum(3)], - points[el.PNum(4)], -1, k, vgradi); - - vgrad += vgradi; - } - } - - points[actpind] = hp; - deriv = dir * vgrad; - return f; - } - - int PointFunction :: MovePointToInner () - { - int j, k; - - // try point movement - ARRAY<Element2d> faces; - - for (j = 0; j < elementsonpoint[actpind].Size(); j++) - { - const Element & el = - elements.Get(elementsonpoint[actpind][j]); - - for (k = 1; k <= 4; k++) - if (el.PNum(k) == actpind) - { - Element2d face; - el.GetFace (k, face); - Swap (face.PNum(2), face.PNum(3)); - faces.Append (face); - } - } - - Point3d hp; - int hi = FindInnerPoint (points, faces, hp); - if (hi) - { - cout << "inner point found" << endl; - points[actpind] = hp; - } - else - cout << "no inner point found" << endl; - - return hi; - } - - - - - - - class CheapPointFunction : public PointFunction - { - DenseMatrix m; - public: - CheapPointFunction (Mesh::T_POINTS & apoints, - const Mesh::T_VOLELEMENTS & aelements); - virtual void SetPointIndex (PointIndex aactpind); - virtual double PointFunctionValue (const Point3d & pp) const; - virtual double PointFunctionValueGrad (const Point3d & pp, Vector & grad) const; - }; - - - CheapPointFunction :: CheapPointFunction (Mesh::T_POINTS & apoints, - const Mesh::T_VOLELEMENTS & aelements) - : PointFunction (apoints, aelements) - { - ; - } - - - void CheapPointFunction :: SetPointIndex (PointIndex aactpind) - { - actpind = aactpind; - - int n = elementsonpoint[actpind].Size(); - int i, j; - int pi1, pi2, pi3; - - m.SetSize (n, 4); - - for (i = 0; i < n; i++) - { - pi1 = 0; - pi2 = 0; - pi3 = 0; - - const Element & el = elements.Get (elementsonpoint[actpind][i]); - for (j = 1; j <= 4; j++) - if (el.PNum(j) != actpind) - { - pi3 = pi2; - pi2 = pi1; - pi1 = el.PNum(j); - } - - const Point3d & p1 = points[pi1]; - Vec3d v1 (p1, points[pi2]); - Vec3d v2 (p1, points[pi3]); - Vec3d n; - Cross (v1, v2, n); - n /= n.Length(); - - Vec3d v (p1, points[actpind]); - double c = v * n; - - if (c < 0) - n *= -1; - - // n is inner normal - - m.Elem(i, 1) = n.X(); - m.Elem(i, 2) = n.Y(); - m.Elem(i, 3) = n.Z(); - m.Elem(i, 4) = - (n.X() * p1.X() + n.Y() * p1.Y() + n.Z() * p1.Z()); - } - } - - double CheapPointFunction :: PointFunctionValue (const Point3d & pp) const - { - static Vector p4(4); - static Vector di; - int n = m.Height(); - - p4.Elem(1) = pp.X(); - p4.Elem(2) = pp.Y(); - p4.Elem(3) = pp.Z(); - p4.Elem(4) = 1; - - di.SetSize (n); - m.Mult (p4, di); - - double sum = 0; - for (int i = 1; i <= n; i++) - { - if (di.Get(i) > 0) - sum += 1 / di.Get(i); - else - return 1e16; - } - return sum; - } - - - - - double CheapPointFunction :: PointFunctionValueGrad (const Point3d & pp, Vector & grad) const - { - static Vector p4(4); - static Vector di; - - grad.SetSize (3); - int n = m.Height(); - - p4.Elem(1) = pp.X(); - p4.Elem(2) = pp.Y(); - p4.Elem(3) = pp.Z(); - p4.Elem(4) = 1; - - di.SetSize (n); - m.Mult (p4, di); - - double sum = 0; - grad = 0; - for (int i = 1; i <= n; i++) - { - if (di.Get(i) > 0) - { - double idi = 1 / di.Get(i); - sum += idi; - grad.Elem(1) -= idi * idi * m.Get(i, 1); - grad.Elem(2) -= idi * idi * m.Get(i, 2); - grad.Elem(3) -= idi * idi * m.Get(i, 3); - } - else - { - return 1e16; - } - } - return sum; - } - - - - - - - - - class Opti3FreeMinFunction : public MinFunction - { - const PointFunction & pf; - Point3d sp1; - - public: - Opti3FreeMinFunction (const PointFunction & apf); - void SetPoint (const Point3d & asp1) { sp1 = asp1; } - virtual double Func (const Vector & x) const; - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; - virtual double GradStopping (const Vector & x) const; - virtual void ApproximateHesse (const Vector & x, - DenseMatrix & hesse) const; - }; - - - - Opti3FreeMinFunction :: Opti3FreeMinFunction (const PointFunction & apf) - : pf(apf) - { - ; - } - - - double Opti3FreeMinFunction :: Func (const Vector & x) const - { - Point3d pp; - pp.X() = sp1.X() + x.Get(1); - pp.Y() = sp1.Y() + x.Get(2); - pp.Z() = sp1.Z() + x.Get(3); - - return pf.PointFunctionValue (pp); - } - - double Opti3FreeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const - { - Point3d pp; - pp.X() = sp1.X() + x.Get(1); - pp.Y() = sp1.Y() + x.Get(2); - pp.Z() = sp1.Z() + x.Get(3); - - return pf.PointFunctionValueGrad (pp, grad); - } - - double Opti3FreeMinFunction :: FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const - { - Point3d pp; - pp.X() = sp1.X() + x.Get(1); - pp.Y() = sp1.Y() + x.Get(2); - pp.Z() = sp1.Z() + x.Get(3); - - Vec3d vdir; - vdir.X() = dir.Get(1); - vdir.Y() = dir.Get(2); - vdir.Z() = dir.Get(3); - - return pf.PointFunctionValueDeriv (pp, vdir, deriv); - } - - double Opti3FreeMinFunction :: GradStopping (const Vector & x) const - { - double f = Func(x); - return 1e-3 * f / pf.GetLocalH(); - } - - - void Opti3FreeMinFunction :: ApproximateHesse (const Vector & x, - DenseMatrix & hesse) const - { - int n = x.Size(); - int i, j; - - static Vector hx; - hx.SetSize(n); - - double eps = 1e-8; - double f, f11, f12, f21, f22; - - f = Func(x); - - - for (i = 1; i <= n; i++) - { - for (j = 1; j < i; j++) - { - /* - hx = x; - hx.Elem(i) = x.Get(i) + eps; - hx.Elem(j) = x.Get(j) + eps; - f11 = Func(hx); - hx.Elem(i) = x.Get(i) + eps; - hx.Elem(j) = x.Get(j) - eps; - f12 = Func(hx); - hx.Elem(i) = x.Get(i) - eps; - hx.Elem(j) = x.Get(j) + eps; - f21 = Func(hx); - hx.Elem(i) = x.Get(i) - eps; - hx.Elem(j) = x.Get(j) - eps; - f22 = Func(hx); - */ - hesse.Elem(i, j) = hesse.Elem(j, i) = 0; - // (f11 + f22 - f12 - f21) / (2 * eps * eps); - } - - hx = x; - hx.Elem(i) = x.Get(i) + eps; - f11 = Func(hx); - hx.Elem(i) = x.Get(i) - eps; - f22 = Func(hx); - - hesse.Elem(i, i) = (f11 + f22 - 2 * f) / (eps * eps) + 1e-12; - } - } - - - - - - -#ifdef SOLIDGEOM - class Opti3SurfaceMinFunction : public MinFunction - { - const PointFunction & pf; - Point3d sp1; - const Surface * surf; - Vec3d t1, t2; - - public: - Opti3SurfaceMinFunction (const PointFunction & apf); - - void SetPoint (const Surface * asurf, const Point3d & asp1); - - void CalcNewPoint (const Vector & x, Point3d & np) const; - virtual double Func (const Vector & x) const; - virtual double FuncGrad (const Vector & x, Vector & g) const; - }; - - - Opti3SurfaceMinFunction :: Opti3SurfaceMinFunction (const PointFunction & apf) - : MinFunction(), pf(apf) - { - ; - } - - void Opti3SurfaceMinFunction :: SetPoint (const Surface * asurf, const Point3d & asp1) - { - Vec3d n; - sp1 = asp1; - surf = asurf; - - Vec<3> hn; - surf -> GetNormalVector (sp1, hn); - n = hn; - - n.GetNormal (t1); - t1 /= t1.Length(); - t2 = Cross (n, t1); - } - - - void Opti3SurfaceMinFunction :: CalcNewPoint (const Vector & x, - Point3d & np) const - { - np.X() = sp1.X() + x.Get(1) * t1.X() + x.Get(2) * t2.X(); - np.Y() = sp1.Y() + x.Get(1) * t1.Y() + x.Get(2) * t2.Y(); - np.Z() = sp1.Z() + x.Get(1) * t1.Z() + x.Get(2) * t2.Z(); - - Point<3> hnp = np; - surf -> Project (hnp); - np = hnp; - } - - - double Opti3SurfaceMinFunction :: Func (const Vector & x) const - { - Point3d pp1; - - CalcNewPoint (x, pp1); - return pf.PointFunctionValue (pp1); - } - - - - double Opti3SurfaceMinFunction :: FuncGrad (const Vector & x, Vector & grad) const - { - Vec3d n, vgrad; - Point3d pp1; - double badness; - static Vector freegrad(3); - - CalcNewPoint (x, pp1); - - badness = pf.PointFunctionValueGrad (pp1, freegrad); - vgrad.X() = freegrad.Get(1); - vgrad.Y() = freegrad.Get(2); - vgrad.Z() = freegrad.Get(3); - - Vec<3> hn; - surf -> GetNormalVector (pp1, hn); - n = hn; - - vgrad -= (vgrad * n) * n; - - grad.Elem(1) = vgrad * t1; - grad.Elem(2) = vgrad * t2; - - return badness; - } -#endif - - - - - - - - -#ifdef SOLIDGEOM - class Opti3EdgeMinFunction : public MinFunction - { - const PointFunction & pf; - Point3d sp1; - const Surface *surf1, *surf2; - Vec3d t1; - - public: - Opti3EdgeMinFunction (const PointFunction & apf); - - void SetPoint (const Surface * asurf1, const Surface * asurf2, - const Point3d & asp1); - void CalcNewPoint (const Vector & x, Point3d & np) const; - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double Func (const Vector & x) const; - }; - - Opti3EdgeMinFunction :: Opti3EdgeMinFunction (const PointFunction & apf) - : MinFunction(), pf(apf) - { - ; - } - - void Opti3EdgeMinFunction :: SetPoint (const Surface * asurf1, - const Surface * asurf2, - const Point3d & asp1) - { - Vec3d n1, n2; - sp1 = asp1; - surf1 = asurf1; - surf2 = asurf2; - - Vec<3> hn1, hn2; - surf1 -> GetNormalVector (sp1, hn1); - surf2 -> GetNormalVector (sp1, hn2); - n1 = hn1; - n2 = hn2; - t1 = Cross (n1, n2); - } - - void Opti3EdgeMinFunction :: CalcNewPoint (const Vector & x, - Point3d & np) const -{ - np.X() = sp1.X() + x.Get(1) * t1.X(); - np.Y() = sp1.Y() + x.Get(1) * t1.Y(); - np.Z() = sp1.Z() + x.Get(1) * t1.Z(); - Point<3> hnp = np; - ProjectToEdge (surf1, surf2, hnp); - np = hnp; -} - -double Opti3EdgeMinFunction :: Func (const Vector & x) const -{ - Vector g(x.Size()); - return FuncGrad (x, g); -} - - -double Opti3EdgeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const -{ - Vec3d n1, n2, v1, vgrad; - Point3d pp1; - double badness; - static Vector freegrad(3); - - CalcNewPoint (x, pp1); - - - badness = pf.PointFunctionValueGrad (pp1, freegrad); - - vgrad.X() = freegrad.Get(1); - vgrad.Y() = freegrad.Get(2); - vgrad.Z() = freegrad.Get(3); - - Vec<3> hn1, hn2; - surf1 -> GetNormalVector (pp1, hn1); - surf2 -> GetNormalVector (pp1, hn2); - n1 = hn1; - n2 = hn2; - - v1 = Cross (n1, n2); - v1 /= v1.Length(); - - grad.Elem(1) = (vgrad * v1) * (t1 * v1); - return badness; -} -#endif - - - - -double CalcBad (const Mesh::T_POINTS & points, const Element & elem, - double h) -{ - if (elem.GetType() == TET) - return CalcTetBadness (points[elem.PNum(1)], - points[elem.PNum(2)], - points[elem.PNum(3)], - points[elem.PNum(4)], h); - return 0; -} - - -extern double teterrpow; -double CalcTotalBad (const Mesh::T_POINTS & points, - const Mesh::T_VOLELEMENTS & elements) -{ - int i; - double sum = 0; - double elbad; - - tets_in_qualclass.SetSize(20); - for (i = 1; i <= 20; i++) - tets_in_qualclass.Elem(i) = 0; - - - for (i = 1; i <= elements.Size(); i++) - { - elbad = pow (CalcBad (points, elements.Get(i), 0), 1/teterrpow); - - int qualclass = int (20 / elbad + 1); - if (qualclass < 1) qualclass = 1; - if (qualclass > 20) qualclass = 20; - tets_in_qualclass.Elem(qualclass)++; - - sum += elbad; - } - return sum; -} - -int WrongOrientation (const Mesh::T_POINTS & points, const Element & el) -{ - const Point3d & p1 = points[el.PNum(1)]; - const Point3d & p2 = points[el.PNum(2)]; - const Point3d & p3 = points[el.PNum(3)]; - const Point3d & p4 = points[el.PNum(4)]; - - Vec3d v1(p1, p2); - Vec3d v2(p1, p3); - Vec3d v3(p1, p4); - Vec3d n; - - Cross (v1, v2, n); - double vol = n * v3; - - return (vol > 0); -} - - - - - - - - - - - -/* ************* JacobianPointFunction **************************** */ - - - - -class JacobianPointFunction : public MinFunction -{ -public: - Mesh::T_POINTS & points; - const Mesh::T_VOLELEMENTS & elements; - TABLE<INDEX> elementsonpoint; - PointIndex actpind; - -public: - JacobianPointFunction (Mesh::T_POINTS & apoints, - const Mesh::T_VOLELEMENTS & aelements); - - virtual void SetPointIndex (PointIndex aactpind); - virtual double Func (const Vector & x) const; - virtual double FuncGrad (const Vector & x, Vector & g) const; - virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; -}; - - -JacobianPointFunction :: -JacobianPointFunction (Mesh::T_POINTS & apoints, - const Mesh::T_VOLELEMENTS & aelements) - : points(apoints), elements(aelements), elementsonpoint(apoints.Size()) -{ - INDEX i; - int j; - - for (i = 1; i <= elements.Size(); i++) - { - for (j = 1; j <= elements.Get(i).NP(); j++) - elementsonpoint.Add1 (elements.Get(i).PNum(j), i); - } -} - -void JacobianPointFunction :: SetPointIndex (PointIndex aactpind) -{ - actpind = aactpind; -} - - -double JacobianPointFunction :: Func (const Vector & v) const -{ - int j; - double badness = 0; - - Point3d hp = points.Elem(actpind); - points.Elem(actpind) = hp + Vec3d (v.Get(1), v.Get(2), v.Get(3)); - - for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) - { - int eli = elementsonpoint.Get(actpind, j); - badness += elements.Get(eli).CalcJacobianBadness (points); - } - - points.Elem(actpind) = hp; - - return badness; -} - - - - - -double JacobianPointFunction :: -FuncGrad (const Vector & x, Vector & g) const -{ - int j, k; - int lpi; - double badness = 0, hbad; - - Point3d hp = points.Elem(actpind); - points.Elem(actpind) = hp + Vec3d (x.Get(1), x.Get(2), x.Get(3)); - - double hderiv; - Vec3d vdir; - g.SetSize(3); - g = 0; - - for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) - { - int eli = elementsonpoint.Get(actpind, j); - const Element & el = elements.Get(eli); - - lpi = 0; - for (k = 1; k <= el.GetNP(); k++) - if (el.PNum(k) == actpind) - lpi = k; - if (!lpi) cerr << "loc point not found" << endl; - - for (k = 1; k <= 3; k++) - { - vdir = Vec3d(0,0,0); - vdir.X(k) = 1; - - hbad = elements.Get(eli). - CalcJacobianBadnessDirDeriv (points, lpi, vdir, hderiv); - g.Elem(k) += hderiv; - if (k == 1) - badness += hbad; - } - } - - points.Elem(actpind) = hp; - - return badness; -} - - -double JacobianPointFunction :: -FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const -{ - int j, k; - int lpi; - double badness = 0; - - Point3d hp = points.Elem(actpind); - points.Elem(actpind) = hp + Vec3d (x.Get(1), x.Get(2), x.Get(3)); - - double hderiv; - deriv = 0; - Vec3d vdir(dir.Get(1), dir.Get(2), dir.Get(3)); - - for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) - { - int eli = elementsonpoint.Get(actpind, j); - const Element & el = elements.Get(eli); - - lpi = 0; - for (k = 1; k <= el.GetNP(); k++) - if (el.PNum(k) == actpind) - lpi = k; - if (!lpi) cerr << "loc point not found" << endl; - - badness += elements.Get(eli). - CalcJacobianBadnessDirDeriv (points, lpi, vdir, hderiv); - deriv += hderiv; - } - - points.Elem(actpind) = hp; - - return badness; - - /* - (*testout) << "bad1 = " << badness << " der = " << deriv << endl; - - - - static Vector hx(3); - static double eps = 1e-6; - - double dirlen = dir.L2Norm(); - if (dirlen < 1e-14) - { - deriv = 0; - return Func(x); - } - - hx.Set(1, x); - hx.Add(eps / dirlen, dir); - double fr = Func (hx); - hx.Set(1, x); - hx.Add(-eps / dirlen, dir); - double fl = Func (hx); - - deriv = (fr - fl) / (2 * eps) * dirlen; - - - (*testout) << "bad2 = " << Func(x) << " der = " << deriv << endl; - - - return Func(x); - */ -} - - - - - - - - - - -#ifdef SOLIDGEOMxxxx -void Mesh :: ImproveMesh (const CSGeometry & geometry, OPTIMIZEGOAL goal) -{ - INDEX i, eli; - int j; - int typ = 1; - - if (!&geometry || geometry.GetNSurf() == 0) - { - ImproveMesh (goal); - return; - } - - char * savetask = multithread.task; - multithread.task = "Smooth Mesh"; - - - TABLE<INDEX> surfelementsonpoint(points.Size()); - Vector x(3), xsurf(2), xedge(1); - int surf, surf1, surf2, surf3; - - int uselocalh = mparam.uselocalh; - - (*testout).precision(8); - (*testout) << "Improve Mesh" << "\n"; - PrintMessage (3, "ImproveMesh"); - // (*mycout) << "Vol = " << CalcVolume (points, volelements) << endl; - - - for (i = 1; i <= surfelements.Size(); i++) - for (j = 1; j <= 3; j++) - surfelementsonpoint.Add1 (surfelements.Get(i).PNum(j), i); - - - PointFunction * pf; - if (typ == 1) - pf = new PointFunction(points, volelements); - else - pf = new CheapPointFunction(points, volelements); - - // pf->SetLocalH (h); - - Opti3FreeMinFunction freeminf(*pf); - Opti3SurfaceMinFunction surfminf(*pf); - Opti3EdgeMinFunction edgeminf(*pf); - - OptiParameters par; - par.maxit_linsearch = 20; - par.maxit_bfgs = 20; - - - - for (i = 1; i <= points.Size(); i++) - { - // if (ptyps.Get(i) == FIXEDPOINT) continue; - if (ptyps.Get(i) != INNERPOINT) continue; - - if (multithread.terminate) - throw NgException ("Meshing stopped"); - /* - if (multithread.terminate) - break; - */ - multithread.percent = 100.0 * i /points.Size(); - - if (points.Size() < 1000) - PrintDot (); - else - if (i % 10 == 0) - PrintDot ('+'); - - // (*testout) << "Now point " << i << "\n"; - // (*testout) << "Old: " << points.Get(i) << "\n"; - - pf->SetPointIndex (i); - - // if (uselocalh) - { - double lh = GetH (points.Get(i)); - pf->SetLocalH (GetH (points.Get(i))); - par.typx = lh / 10; - // (*testout) << "lh(" << points.Get(i) << ") = " << lh << "\n"; - } - - surf1 = surf2 = surf3 = 0; - - for (j = 1; j <= surfelementsonpoint.EntrySize(i); j++) - { - eli = surfelementsonpoint.Get(i, j); - int surfi = surfelements.Get(eli).GetIndex(); - - if (surfi) - { - surf = GetFaceDescriptor(surfi).SurfNr(); - - if (!surf1) - surf1 = surf; - else if (surf1 != surf) - { - if (!surf2) - surf2 = surf; - else if (surf2 != surf) - surf3 = surf; - } - } - else - { - surf1 = surf2 = surf3 = 1; // simulates corner point - } - } - - - if (surf2 && !surf3) - { - // (*testout) << "On Edge" << "\n"; - /* - xedge = 0; - edgeminf.SetPoint (geometry.GetSurface(surf1), - geometry.GetSurface(surf2), - points.Elem(i)); - BFGS (xedge, edgeminf, par); - - edgeminf.CalcNewPoint (xedge, points.Elem(i)); - */ - } - - if (surf1 && !surf2) - { - // (*testout) << "In Surface" << "\n"; - /* - xsurf = 0; - surfminf.SetPoint (geometry.GetSurface(surf1), - points.Get(i)); - BFGS (xsurf, surfminf, par); - - surfminf.CalcNewPoint (xsurf, points.Elem(i)); - */ - } - - if (!surf1) - { - // (*testout) << "In Volume" << "\n"; - x = 0; - freeminf.SetPoint (points.Elem(i)); - // par.typx = - BFGS (x, freeminf, par); - - points.Elem(i).X() += x.Get(1); - points.Elem(i).Y() += x.Get(2); - points.Elem(i).Z() += x.Get(3); - } - - // (*testout) << "New Point: " << points.Elem(i) << "\n" << "\n"; - - } - PrintDot ('\n'); - // (*mycout) << "Vol = " << CalcVolume (points, volelements) << endl; - - multithread.task = savetask; - -} -#endif - - -void Mesh :: ImproveMesh (OPTIMIZEGOAL goal) -{ - int typ = 1; - int j; - - (*testout) << "Improve Mesh" << "\n"; - PrintMessage (3, "ImproveMesh"); - - int np = GetNP(); - int ne = GetNE(); - - - ARRAY<double,PointIndex::BASE> perrs(np); - perrs = 1.0; - - double bad1 = 0; - double badmax = 0; - - if (goal == OPT_QUALITY) - { - for (int i = 1; i <= ne; i++) - { - const Element & el = VolumeElement(i); - if (el.GetType() != TET) - continue; - - double hbad = CalcBad (points, el, 0); - for (j = 0; j < 4; j++) - perrs[el[j]] += hbad; - - bad1 += hbad; - } - - for (PointIndex i = PointIndex::BASE; i < np+PointIndex::BASE; i++) - if (perrs[i] > badmax) - badmax = perrs[i]; - badmax = 0; - } - - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (points, volelements); - (*testout) << "Total badness = " << bad1 << endl; - PrintMessage (5, "Total badness = ", bad1); - } - - Vector x(3); - - (*testout).precision(8); - - int uselocalh = mparam.uselocalh; - - - PointFunction * pf; - - if (typ == 1) - pf = new PointFunction(points, volelements); - else - pf = new CheapPointFunction(points, volelements); - - // pf->SetLocalH (h); - - Opti3FreeMinFunction freeminf(*pf); - - OptiParameters par; - par.maxit_linsearch = 20; - par.maxit_bfgs = 20; - - - char * savetask = multithread.task; - multithread.task = "Smooth Mesh"; - - for (PointIndex i = PointIndex::BASE; - i < points.Size()+PointIndex::BASE; i++) - if (PointType(i) == INNERPOINT && perrs[i] > 0.01 * badmax) - { - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - multithread.percent = 100.0 * (i+1-PointIndex::BASE) / points.Size(); - - if (points.Size() < 1000) - PrintDot (); - else - if ( (i+1-PointIndex::BASE) % 10 == 0) - PrintDot ('+'); - - double lh = GetH(points[i]); - pf->SetLocalH (lh); - par.typx = lh; - - freeminf.SetPoint (points[i]); - pf->SetPointIndex (i); - - x = 0; - int pok; - pok = freeminf.Func (x) < 1e10; - - if (!pok) - { - pok = pf->MovePointToInner (); - - freeminf.SetPoint (points[i]); - pf->SetPointIndex (i); - } - - if (pok) - { - BFGS (x, freeminf, par); - - points[i].X() += x.Get(1); - points[i].Y() += x.Get(2); - points[i].Z() += x.Get(3); - } - } - PrintDot ('\n'); - - - delete pf; - - multithread.task = savetask; - - if (goal == OPT_QUALITY) - { - bad1 = CalcTotalBad (points, volelements); - (*testout) << "Total badness = " << bad1 << endl; - PrintMessage (5, "Total badness = ", bad1); - } -} - - - - -// Improve Condition number of Jacobian, any elements -void Mesh :: ImproveMeshJacobian (OPTIMIZEGOAL goal) -{ - int i, j; - - (*testout) << "Improve Mesh Jacobian" << "\n"; - PrintMessage (3, "ImproveMesh Jacobian"); - - int np = GetNP(); - int ne = GetNE(); - - - Vector x(3); - - (*testout).precision(8); - - JacobianPointFunction pf(points, volelements); - - - OptiParameters par; - par.maxit_linsearch = 20; - par.maxit_bfgs = 20; - - BitArray badnodes(np); - badnodes.Clear(); - - for (i = 1; i <= ne; i++) - { - const Element & el = VolumeElement(i); - double bad = el.CalcJacobianBadness (Points()); - if (bad > 1) - for (j = 1; j <= el.GetNP(); j++) - badnodes.Set (el.PNum(j)); - } - - - char * savetask = multithread.task; - multithread.task = "Smooth Mesh Jacobian"; - - for (i = 1; i <= points.Size(); i++) - if (PointType(i) == INNERPOINT) - { - - (*testout) << "improvejac, p = " << i << endl; - - if (goal == OPT_WORSTCASE && !badnodes.Test(i)) - continue; - // (*testout) << "smoot p " << i << endl; - - /* - if (multithread.terminate) - break; - */ - if (multithread.terminate) - throw NgException ("Meshing stopped"); - - multithread.percent = 100.0 * i / points.Size(); - - if (points.Size() < 1000) - PrintDot (); - else - if (i % 10 == 0) - PrintDot ('+'); - - double lh = GetH(points.Get(i)); - par.typx = lh; - - pf.SetPointIndex (i); - - x = 0; - int pok = (pf.Func (x) < 1e10); - - if (pok) - { - BFGS (x, pf, par); - - points.Elem(i).X() += x.Get(1); - points.Elem(i).Y() += x.Get(2); - points.Elem(i).Z() += x.Get(3); - } - else - { - cout << "el not ok" << endl; - } - } - PrintDot ('\n'); - - - multithread.task = savetask; -} - - - - -} diff --git a/Netgen/libsrc/meshing/specials.cpp b/Netgen/libsrc/meshing/specials.cpp deleted file mode 100644 index ae9877cc2e..0000000000 --- a/Netgen/libsrc/meshing/specials.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - - -namespace netgen -{ - -// A special function for Hermann Landes, Erlangen - - -void CutOffAndCombine (Mesh & mesh, const Mesh & othermesh) -{ - int i, j; - int nse = othermesh.GetNSE(); - int onp = othermesh.GetNP(); - - int ne = mesh.GetNE(); - - PrintMessage (1, "other mesh has ", - othermesh.GetNP(), " points, ", - othermesh.GetNSE(), " surface elements."); - - ARRAY<Box3d> otherbounds(nse); - Box3d otherbox; - - double maxh = 0; - for (i = 1; i <= nse; i++) - { - const Element2d & sel = othermesh.SurfaceElement(i); - sel.GetBox(othermesh.Points(), otherbounds.Elem(i)); - - double loch = othermesh.GetH (othermesh.Point (sel.PNum(1))); - otherbounds.Elem(i).Increase(loch); - if (loch > maxh) maxh = loch; - } - - otherbox.SetPoint (othermesh.Point(1)); - for (i = 1; i <= othermesh.GetNP(); i++) - otherbox.AddPoint (othermesh.Point(i)); - otherbox.Increase (maxh); - - for (i = 1; i <= ne; i++) - { - Box3d box; - int remove = 0; - - const Element & el = mesh.VolumeElement(i); - el.GetBox(mesh.Points(), box); - - if (i % 10000 == 0) - cout << "+" << flush; - - if (box.Intersect(otherbox)) - { - for (j = 1; j <= nse && !remove; j++) - if (box.Intersect(otherbounds.Get(j))) - remove = 1; - } - - if (remove) - mesh.VolumeElement(i).Delete(); - } - cout << endl; - - BitArray connected(mesh.GetNP()); - connected.Clear(); - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement(i); - for (j = 1; j <= 3; j++) - connected.Set(el.PNum(j)); - } - - bool changed; - do - { - changed = 0; - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement(i); - int has = 0, hasnot = 0; - if (el[0]) - { - for (j = 0; j < 4; j++) - { - if (connected.Test(el[j])) - has = 1; - else - hasnot = 1; - } - if (has && hasnot) - { - changed = 1; - for (j = 0; j < 4; j++) - connected.Set (el[j]); - } - } - } - cout << "." << flush; - } - while (changed); - cout << endl; - - for (i = 1; i <= mesh.GetNE(); i++) - { - const Element & el = mesh.VolumeElement(i); - int hasnot = 0; - if (el[0]) - { - for (j = 0; j < 4; j++) - { - if (!connected.Test(el[j])) - hasnot = 1; - } - if (hasnot) - mesh.VolumeElement(i).Delete(); - } - } - - mesh.Compress(); - - mesh.FindOpenElements(); - BitArray locked(mesh.GetNP()); - locked.Set(); - for (i = 1; i <= mesh.GetNOpenElements(); i++) - for (j = 1; j <= 3; j++) - locked.Clear (mesh.OpenElement(i).PNum(j)); - - for (i = 1; i <= locked.Size(); i++) - if (locked.Test(i)) - { - mesh.AddLockedPoint (i); - } - - - - - ARRAY<int> pmat(onp); - - for (i = 1; i <= onp; i++) - pmat.Elem(i) = mesh.AddPoint (othermesh.Point(i)); - - int fnum = - mesh.AddFaceDescriptor (FaceDescriptor(0,0,1,0)); - - for (i = 1; i <= othermesh.GetNSE(); i++) - { - Element2d tri = othermesh.SurfaceElement(i); - for (j = 1; j <= 3; j++) - tri.PNum(j) = pmat.Get(tri.PNum(j)); - tri.SetIndex(fnum); - mesh.AddSurfaceElement (tri); - } - - for (i = 1; i <= onp; i++) - mesh.AddLockedPoint (pmat.Elem(i)); - - mesh.CalcSurfacesOfNode(); - mesh.CalcLocalH(); -} - - - - -void HelmholtzMesh (Mesh & mesh) -{ - int i, j; - double ri, ra, rinf; - - cout << "ri = "; - cin >> ri; - cout << "ra = "; - cin >> ra; - cout << "rinf = "; - cin >> rinf; - - double det = ri * ra * rinf - ri * ri * rinf; - double a = (ri - rinf) / det; - double b = (ri*ri - ra * rinf) / det; - for (i = 1; i <= mesh.GetNP(); i++) - { - Point3d & p = mesh.Point(i); - double rold = sqrt (sqr(p.X()) + sqr(p.Y()) + sqr(p.Z())); - if (rold < ri) continue; - - double rnew = 1 / (a * rold - b); - double fac = rnew / rold; - p.X() *= fac; - p.Y() *= fac; - p.Z() *= fac; - } -} -} diff --git a/Netgen/libsrc/meshing/specials.hpp b/Netgen/libsrc/meshing/specials.hpp deleted file mode 100644 index 700ba4596b..0000000000 --- a/Netgen/libsrc/meshing/specials.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FILE_SPECIALS -#define FILE_SPECIALS - -/* - - Very special implementations .. - - */ - - -/// -extern void CutOffAndCombine (Mesh & mesh, const Mesh & othermesh); - -extern void HelmholtzMesh (Mesh & mesh); - -#endif diff --git a/Netgen/libsrc/meshing/tetrarls.cpp b/Netgen/libsrc/meshing/tetrarls.cpp deleted file mode 100644 index cb28648b6a..0000000000 --- a/Netgen/libsrc/meshing/tetrarls.cpp +++ /dev/null @@ -1,1466 +0,0 @@ -namespace netgen -{ -const char * tetrules[] = { -"tolfak 0.5\n",\ -"\n",\ -"rule \"Free Tetrahedron\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0);\n",\ -"(0.5, 0.866, 0);\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.816)\n",\ -" { 0.333 X1, 0.333 X2, 0.333 X3 }\n",\ -" { 0.333 Y1, 0.333 Y2, 0.333 Y3 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(4, 1, 2);\n",\ -"(4, 2, 3);\n",\ -"(4, 3, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1.6 P4, -0.2 P1, -0.2 P2, -0.2 P3 };\n",\ -"{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 60\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags c;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 } ;\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"(4, 2, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ -"\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.65 P3, 0.35 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 60 with edge(1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"flags c;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.8 };\n",\ -"(0.5, 0.866, 0) { 0.8 };\n",\ -"(0.5, 0.288, -0.816) { 0.8 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"mapedges\n",\ -"(3, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"(4, 2, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 };\n",\ -"{ 0.4 P2, 0.4 P4, 0.4 P3, -0.2 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P4, 0.3334 P3 };\n",\ -"{ 0.3333 P2, 0.3333 P4, 0.3334 P3 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point (1)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 };\n",\ -"{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 };\n",\ -"{ 0.8 P1, -0.1 P2, -0.1 P3, 0.4 P4 };\n",\ -"{ -0.1 P1, 0.8 P2, -0.1 P3, 0.4 P4 };\n",\ -"{ -0.1 P1, -0.1 P2, 0.8 P3, 0.4 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"{ 0.7 P1, 0.3 P4 };\n",\ -"{ 0.7 P2, 0.3 P4 };\n",\ -"{ 0.7 P3, 0.3 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point with edge(1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"mapedges\n",\ -"(1, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ -"{ -0.05 P1, 0.7 P2, -0.05 P3, 0.4 P4 };\n",\ -"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"{ 0.65 P2, 0.35 P4 };\n",\ -"{ 0.65 P3, 0.35 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point with 2 edges (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"mapedges\n",\ -"(1, 4);\n",\ -"(2, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ -"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"{ 0.65 P3, 0.35 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Point with 3 edges (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0.5, 0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"mapedges\n",\ -"(1, 4);\n",\ -"(2, 4);\n",\ -"(3, 4);\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(4, 3, 1);\n",\ -"(4, 2, 3);\n",\ -"(4, 1, 2);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ -"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron Vis a Vis Triangle (1)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 0.866, 0) { 0.5 };\n",\ -"(0, 0, -0.816) { 0.5 };\n",\ -"(1, 0, -0.816) { 0.5 };\n",\ -"(0.5, 0.866, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(4, 6, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 4);\n",\ -"(2, 5, 4);\n",\ -"(2, 3, 6);\n",\ -"(2, 6, 5);\n",\ -"(3, 1, 4);\n",\ -"(3, 4, 6);\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"(4, 2, 3, 6);\n",\ -"(4, 2, 6, 5);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ -0.2 P1, 0.35 P2, 0.35 P3, -0.2 P4, 0.35 P5, 0.35 P6 };\n",\ -"{ 0.35 P1, -0.2 P2, 0.35 P3, 0.35 P4, -0.2 P5, 0.35 P6 };\n",\ -"{ 0.35 P1, 0.35 P2, -0.2 P3, 0.35 P4, 0.35 P5, -0.2 P6 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Octaeder 1\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.95 };\n",\ -"(0.5, 0.866, 0) { 0.95 };\n",\ -"(0.5, -0.288, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(2, 3, 5);\n",\ -"(3, 1, 6);\n",\ -"(3, 6, 5);\n",\ -"(2, 5, 4);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 4, 1, 2);\n",\ -"(3, 4, 2, 5);\n",\ -"(3, 4, 5, 6);\n",\ -"(3, 4, 6, 1);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 };\n",\ -"( 1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Octaeder 2\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.95 };\n",\ -"(0.5, 0.866, 0) { 0.95 };\n",\ -"(0.5, -0.288, -0.816) { 0.5 };\n",\ -"(1, 0.578, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(2, 3, 5);\n",\ -"(3, 1, 6);\n",\ -"(3, 6, 5);\n",\ -"(2, 5, 4);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 4, 1, 2);\n",\ -"(3, 4, 2, 5);\n",\ -"(3, 4, 5, 6);\n",\ -"(3, 4, 6, 1);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ -"\n",\ -"(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 }\n",\ -" { 0.333 Y2, 0.333 Y4, 0.333 Y5 }\n",\ -" { 0.333 Z2, 0.333 Z4, 0.333 Z5 };\n",\ -"(0.9, 0.481, -0.272) { 0.333 X2, 0.333 X3, 0.333 X5 }\n",\ -" { 0.333 Y2, 0.333 Y3, 0.333 Y5 }\n",\ -" { 0.333 Z2, 0.333 Z3, 0.333 Z5 };\n",\ -"\n",\ -"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Octaeder 2a\"\n",\ -"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.95 };\n",\ -"(0.5, 0.866, 0) { 0.95 };\n",\ -"(0.5, -0.288, -0.816) { 0.5 };\n",\ -"(1, 0.578, -0.816) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(3, 2, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0, 0.578, -0.816)\n",\ -" { -1 X2, 1 X3, 1 X4 }\n",\ -" { -1 Y2, 1 Y3, 1 Y4 }\n",\ -" { -1 Z2, 1 Z3, 1 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 2, 4);\n",\ -"(3, 1, 6);\n",\ -"(3, 6, 5);\n",\ -"(2, 5, 4);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 4, 1, 2);\n",\ -"(3, 4, 2, 5);\n",\ -"(3, 4, 5, 6);\n",\ -"(3, 4, 6, 1);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ -"\n",\ -"(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 }\n",\ -" { 0.333 Y2, 0.333 Y4, 0.333 Y5 }\n",\ -" { 0.333 Z2, 0.333 Z4, 0.333 Z5 };\n",\ -"\n",\ -"(0.5, -0.097, -0.272) { 0.333 X2, 0.333 X4, 0.333 X1 }\n",\ -" { 0.333 Y2, 0.333 Y4, 0.333 Y1 }\n",\ -" { 0.333 Z2, 0.333 Z4, 0.333 Z1 };\n",\ -"\n",\ -"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Pyramid 1\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.288, -0.816) { 1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"(2, 3, 5);\n",\ -"(2, 5, 4);\n",\ -"(4, 5, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"(4, 2, 3, 5);\n",\ -"\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(0, 1, -1) { 0.5 X3, 0.5 X4 } { 1 Y3 } { 1 Z4 };\n",\ -"(1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 2 times 60\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.3 };\n",\ -"(0.5, 0.866, 0) { 0.3 };\n",\ -"(0.5, 0.288, -0.816) { 0.3 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(2, 4, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"(1, 4, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Fill Tetrahedron (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.2 };\n",\ -"(0.5, 0.866, 0) { 0.2 };\n",\ -"(0.5, 0.288, -0.816) { 0.2 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(2, 4, 3) del;\n",\ -"(3, 4, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newfaces\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.674, -0.544) { 1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.816)\n",\ -" { -0.5 X1, -0.5 X2, 1 X3, 1 X4 }\n",\ -" { -0.5 Y1, -0.5 Y2, 1 Y3, 1 Y4}\n",\ -" { -0.5 Z1, -0.5 Z2, 1 Z3, 1 Z4};\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 3);\n",\ -"(3, 5, 2);\n",\ -"(1, 4, 5);\n",\ -"(2, 5, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 4, 2, 5);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.3 P5, -0.3 P1 };\n",\ -"{ 1.3 P5, -0.3 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P5 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 2 times 120 (1)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.674, -0.544) { 0.8 };\n",\ -"(1.334, 0.77, -0.544) { 0.8 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(3, 2, 5) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.816) { 0.25 X1, -0.5 X2, 0.25 X3, 0.5 X4, 0.5 X5 }\n",\ -" { 0.25 Y1, -0.5 Y2, 0.25 Y3, 0.5 Y4, 0.5 Y5 }\n",\ -" { 0.25 Z1, -0.5 Z2, 0.25 Z3, 0.5 Z4, 0.5 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(6, 3, 1);\n",\ -"(6, 1, 4);\n",\ -"(6, 4, 2);\n",\ -"(6, 2, 5);\n",\ -"(6, 5, 3);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(2, 5, 3, 6);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.4 P6, -0.4 P2 };\n",\ -"{ 1.4 P6, -0.4 P1 };\n",\ -"{ 1.4 P6, -0.4 P3 };\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (4)\"\n",\ -"\n",\ -"quality 4\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.1 };\n",\ -"(0.5, 1, 0) { 0.1 };\n",\ -"(0.5, 0, -1) { 0.1 };\n",\ -"(0.5, 0.3, -0.3) { 0.1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 5, 4) del;\n",\ -"(1, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.1, -0.1)\n",\ -" { 0.333 X1, 0.333 X2, 0.334 X5 }\n",\ -" { 0.333 Y1, 0.333 Y2, 0.334 Y5 }\n",\ -" { 0.333 Z1, 0.333 Z2, 0.334 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(6, 2, 3) del;\n",\ -"(6, 4, 2) del;\n",\ -"(6, 5, 4) del;\n",\ -"(6, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(1, 5, 4, 6);\n",\ -"(1, 3, 5, 6);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.5 P6, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 6 2 3;\n",\ -"\n",\ -"freeset\n",\ -"1 6 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 6 5 4;\n",\ -"\n",\ -"freeset\n",\ -"1 6 4 2;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"five Tetrahedron non convex (4)\"\n",\ -"\n",\ -"quality 4\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0, 0.8, -0.2) { 0.5 };\n",\ -"(0, 0.2, -0.8) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 3, 4) del;\n",\ -"(1, 4, 5) del;\n",\ -"(1, 5, 6) del;\n",\ -"(1, 6, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.1, 0.1, -0.1)\n",\ -" { 0.75 X1, 0.05 X2, 0.05 X3, 0.05 X4, 0.05 X5, 0.05 X6 }\n",\ -" { 0.75 Y1, 0.05 Y2, 0.05 Y3, 0.05 Y4, 0.05 Y5, 0.05 Y6 }\n",\ -" { 0.75 Z1, 0.05 Z2, 0.05 Z3, 0.05 Z4, 0.05 Z5, 0.05 Z6 };\n",\ -"\n",\ -"newfaces\n",\ -"(7, 2, 3);\n",\ -"(7, 3, 4);\n",\ -"(7, 4, 5);\n",\ -"(7, 5, 6);\n",\ -"(7, 6, 2);\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 7);\n",\ -"(1, 3, 4, 7);\n",\ -"(1, 4, 5, 7);\n",\ -"(1, 5, 6, 7);\n",\ -"(1, 6, 2, 7);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1.5 P7, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"{ 1 P7 };\n",\ -"\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 7 2 3;\n",\ -"\n",\ -"freeset\n",\ -"1 7 3 4;\n",\ -"\n",\ -"freeset\n",\ -"1 7 4 5;\n",\ -"\n",\ -"freeset\n",\ -"1 7 5 6;\n",\ -"\n",\ -"freeset\n",\ -"1 7 6 2;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 6\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"(0.5, 0.3, -0.3) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 5, 4) del;\n",\ -"(1, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"newpoints\n",\ -"(0.095, 0.003, -0.003)\n",\ -" { 0.9 X1, 0.09 X2, 0.01 X5 }\n",\ -" { 0.9 Y1, 0.09 Y2, 0.01 Y5 }\n",\ -" { 0.9 Z1, 0.09 Z2, 0.01 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(6, 2, 3) del;\n",\ -"(6, 4, 2) del;\n",\ -"(6, 5, 4) del;\n",\ -"(6, 3, 5) del;\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(1, 5, 4, 6);\n",\ -"(1, 3, 5, 6);\n",\ -"\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.499 P6, -0.5 P1, 0.001 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"\n",\ -"\n",\ -"freeset\n",\ -"1 6 2 3;\n",\ -"\n",\ -"freeset\n",\ -"1 6 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 6 5 4;\n",\ -"\n",\ -"freeset\n",\ -"1 6 4 2;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"(0.5, 0.4, -0.4) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(4, 5, 2) del;\n",\ -"(5, 3, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.925, 0.02, -0.02)\n",\ -" { 0.05 X1, 0.9 X2, 0.05 X5 }\n",\ -" { 0.05 Y1, 0.9 Y2, 0.05 Y5 }\n",\ -" { 0.05 Z1, 0.9 Z2, 0.05 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(3, 1, 6);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"(5, 3, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 1, 2, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(4, 5, 2, 6);\n",\ -"(5, 3, 2, 6);\n",\ -"\n",\ -"orientations\n",\ -"(3, 1, 2, 5);\n",\ -"(1, 4, 2, 5);\n",\ -"(2, 4, 5, 1);\n",\ -"(3, 2, 5, 1);\n",\ -"(5, 4, 2, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1.5 P6, -0.5 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"{ 1 P6 };\n",\ -"\n",\ -"freeset\n",\ -"3 1 2 6;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 6;\n",\ -"\n",\ -"freeset\n",\ -"4 5 2 6;\n",\ -"\n",\ -"freeset\n",\ -"5 3 2 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"three Tetrahedron non convex (4)\"\n",\ -"\n",\ -"quality 4\n",\ -"flags l;\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.25, -0.25)\n",\ -" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 }\n",\ -" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 }\n",\ -" { 0.25 Z1, 0.25 Z2, 0.25 Z3, 0.25 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3);\n",\ -"(5, 4, 2);\n",\ -"(5, 3, 4);\n",\ -"\n",\ -"elements\n",\ -"(2, 3, 1, 5);\n",\ -"(3, 4, 1, 5);\n",\ -"(4, 2, 1, 5;\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 4, 3);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.5 P5, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"three Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(1, 3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.2, 0.1, -0.1)\n",\ -" { 0.7 X1, 0.1 X2, 0.1 X3, 0.1 X4 }\n",\ -" { 0.7 Y1, 0.1 Y2, 0.1 Y3, 0.1 Y4 }\n",\ -" { 0.7 Z1, 0.1 Z2, 0.1 Z3, 0.1 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3);\n",\ -"(5, 4, 2);\n",\ -"(5, 3, 4);\n",\ -"\n",\ -"elements\n",\ -"(2, 3, 1, 5);\n",\ -"(3, 4, 1, 5);\n",\ -"(4, 2, 1, 5;\n",\ -"\n",\ -"orientations\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.5 P5, -0.5 P1 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 3 4 5;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"four Tetrahedron non convex (6)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"(0.5, 0.4, -0.4) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"(4, 5, 2) del;\n",\ -"(5, 3, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.7, 0.08, -0.08) { 0.6 X2, 0.2 X5 } { 0.2 Y5 } { 0.2 Z5 };\n",\ -"\n",\ -"newfaces\n",\ -"(3, 1, 6);\n",\ -"(1, 4, 6);\n",\ -"(4, 5, 6);\n",\ -"(5, 3, 6);\n",\ -"\n",\ -"elements\n",\ -"(3, 1, 2, 6);\n",\ -"(1, 4, 2, 6);\n",\ -"(4, 5, 2, 6);\n",\ -"(5, 3, 2, 6);\n",\ -"\n",\ -"\n",\ -"orientations\n",\ -"(3, 1, 2, 5);\n",\ -"(5, 1, 2, 4);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 1, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, 0, -1) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ -"(0.5, 0.4, -0.4) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ -"(0.55, 0.12, -0.12) { 0.4 X2, 0.3 X5 } { 0.3 Y5 } { 0.3 Z5 };\n",\ -"\n",\ -"freeset\n",\ -"3 1 2 6;\n",\ -"\n",\ -"freeset\n",\ -"1 4 2 6;\n",\ -"\n",\ -"freeset\n",\ -"4 5 2 6;\n",\ -"\n",\ -"freeset\n",\ -"5 3 2 6;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 2 in 60 (12)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 0.5 };\n",\ -"(0.5, 1, 0) { 0.5 };\n",\ -"(0.5, 0, -1) { 0.5 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.1, -0.1)\n",\ -" { 0.4 X1, 0.4 X2, 0.1 X3, 0.1 X4 }\n",\ -" { 0.4 Y1, 0.4 Y2, 0.1 Y3, 0.1 Y4 }\n",\ -" { 0.4 Z1, 0.4 Z2, 0.1 Z3, 0.1 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(5, 2, 3);\n",\ -"(5, 3, 1);\n",\ -"(5, 4, 2);\n",\ -"(5, 1, 4);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5);\n",\ -"(1, 2, 5, 4);\n",\ -"\n",\ -"freezone2\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1.5 P5, -0.25 P1, -0.25 P2 };\n",\ -"\n",\ -"freezonelimit\n",\ -"{ 1 P1 };\n",\ -"{ 1 P2 };\n",\ -"{ 1 P3 };\n",\ -"{ 1 P4 };\n",\ -"{ 1 P5 };\n",\ -"\n",\ -"freeset\n",\ -"1 2 3 5;\n",\ -"\n",\ -"freeset\n",\ -"1 2 4 5;\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Tetrahedron 120, but more than 180 (13)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 };\n",\ -"(0.5, 0.866, 0) { 1 };\n",\ -"(0.5, -0.866, 0) { 1 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"(1, 4, 2);\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0, -0.3) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"newfaces\n",\ -"(1, 5, 3);\n",\ -"(3, 5, 2);\n",\ -"(2, 5, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 5);\n",\ -"\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, -0.1, -0.4) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Tetrahedron (14)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1.0 };\n",\ -"(0.5, 0.866, 0) { 1.0 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.2) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(4, 1, 2);\n",\ -"(4, 2, 3);\n",\ -"(4, 3, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, 0.288, -0.25) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Tetrahedron (15)\"\n",\ -"\n",\ -"quality 100\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1.0 };\n",\ -"(0.5, 0.866, 0) { 1.0 };\n",\ -"\n",\ -"mapfaces\n",\ -"(1, 2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.288, -0.1) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"newfaces\n",\ -"(4, 1, 2);\n",\ -"(4, 2, 3);\n",\ -"(4, 3, 1);\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3, 4);\n",\ -"\n",\ -"freezone\n",\ -"(0, 0, 0);\n",\ -"(1, 0, 0) { 1 X2 } { } { };\n",\ -"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ -"(0.5, 0.288, -0.15) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ -"\n",\ -"endrule\n", -0}; -} diff --git a/Netgen/libsrc/meshing/topology.cpp b/Netgen/libsrc/meshing/topology.cpp deleted file mode 100644 index 9c0e79d531..0000000000 --- a/Netgen/libsrc/meshing/topology.cpp +++ /dev/null @@ -1,1595 +0,0 @@ -#include <mystdlib.h> - -#include "meshing.hpp" - -namespace netgen -{ - -MeshTopology :: MeshTopology (const Mesh & amesh) - : mesh(amesh) -{ - buildedges = 1; - buildfaces = 1; - vert2element = 0; - vert2surfelement = 0; - vert2segment = 0; - timestamp = -1; - - edge2vert.SetName ("edge2vert"); - face2vert.SetName ("face2vert"); - edges.SetName ("el2edge"); - faces.SetName ("el2face"); - surfedges.SetName ("surfel2edge"); - segedges.SetName ("segment2edge"); - surffaces.SetName ("surfel2face"); - surf2volelement.SetName ("surfel2el"); - face2surfel.SetName ("face2surfel"); -} - -MeshTopology :: ~MeshTopology () -{ - delete vert2element; - delete vert2surfelement; - delete vert2segment; -} - -void MeshTopology :: Update() -{ - int i, j, k; - - if (timestamp > mesh.GetTimeStamp()) return; - - int ne = mesh.GetNE(); - int nse = mesh.GetNSE(); - int nseg = mesh.GetNSeg(); - int np = mesh.GetNP(); - int nv = mesh.GetNV(); - int nfa = 0; - int ned = edge2vert.Size(); - - PrintMessage (3, "Update mesh topology"); - - (*testout) << "ne = " << ne << endl; - (*testout) << "nse = " << nse << endl; - (*testout) << "nseg = " << nseg << endl; - (*testout) << "np = " << np << endl; - (*testout) << "nv = " << nv << endl; - - delete vert2element; - delete vert2surfelement; - delete vert2segment; - ARRAY<int,PointIndex::BASE> cnt(nv); - ARRAY<int> vnums; - - (*testout) << "tables deleted" << endl; - - /* - generate: - vertex to element - vertex to surface element - vertex to segment - */ - - cnt = 0; - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - int nelv = el.GetNV(); - for (j = 1; j <= nelv; j++) - cnt[el.PNum(j)]++; - } - - vert2element = new TABLE<int,PointIndex::BASE> (cnt); - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - int nelv = el.GetNV(); - for (j = 1; j <= nelv; j++) - vert2element->AddSave (el.PNum(j), i); - } - - cnt = 0; - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = mesh[sei]; - int nelv = el.GetNV(); - for (j = 0; j < nelv; j++) - cnt[el[j]]++; - } - - vert2surfelement = new TABLE<int,PointIndex::BASE> (cnt); - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = mesh[sei]; - int nelv = el.GetNV(); - for (j = 0; j < nelv; j++) - vert2surfelement->AddSave (el[j], sei+1); - } - - - cnt = 0; - for (i = 1; i <= nseg; i++) - { - const Segment & seg = mesh.LineSegment(i); - cnt[seg.p1]++; - cnt[seg.p2]++; - } - - vert2segment = new TABLE<int,PointIndex::BASE> (cnt); - for (i = 1; i <= nseg; i++) - { - const Segment & seg = mesh.LineSegment(i); - vert2segment->AddSave (seg.p1, i); - vert2segment->AddSave (seg.p2, i); - } - - - - - if (buildedges) - { - PrintMessage (5, "Update edges "); - - edges.SetSize(ne); - surfedges.SetSize(nse); - segedges.SetSize(nseg); - - for (i = 1; i <= ne; i++) - for (j = 0; j < 12; j++) - edges.Elem(i)[j] = 0; - for (i = 1; i <= nse; i++) - for (j = 0; j < 4; j++) - surfedges.Elem(i)[j] = 0; - - // keep existing edges - cnt = 0; - for (i = 0; i < edge2vert.Size(); i++) - cnt[edge2vert[i][0]]++; - TABLE<int,PointIndex::BASE> vert2edge (cnt); - for (i = 0; i < edge2vert.Size(); i++) - vert2edge.AddSave (edge2vert[i][0], i+1); - - // ensure all coarse grid and intermediate level edges - cnt = 0; - for (i = 1; i <= mesh.mlbetweennodes.Size(); i++) - { - int pa[2]; - pa[0] = mesh.mlbetweennodes.Get(i).I1(); - pa[1] = mesh.mlbetweennodes.Get(i).I2(); - if (pa[0] > pa[1]) Swap (pa[0], pa[1]); - if (pa[0] > 0) - cnt.Elem(pa[0])++; - } - TABLE<int,PointIndex::BASE> vert2vertcoarse (cnt); - for (i = 1; i <= mesh.mlbetweennodes.Size(); i++) - { - int pa[2]; - pa[0] = mesh.mlbetweennodes.Get(i).I1(); - pa[1] = mesh.mlbetweennodes.Get(i).I2(); - if (pa[0] > pa[1]) swap (pa[0], pa[1]); - if (pa[0] > 0) - vert2vertcoarse.AddSave1 (pa[0], pa[1]); - } - - - ARRAY<int,PointIndex::BASE> edgenr(nv), edgeflag(nv); - for (i = PointIndex::BASE; i < nv+PointIndex::BASE; i++) - edgeflag[i] = 0; - ned = edge2vert.Size(); - ARRAY<INDEX_3> missing; - - for (i = 1; i <= nv; i++) - { - for (j = 1; j <= vert2edge.EntrySize(i); j++) - { - int ednr = vert2edge.Get(i,j); - int i2 = edge2vert.Get(ednr)[1]; - edgeflag.Elem(i2) = i; - edgenr.Elem(i2) = ednr; - } - for (j = 1; j <= vert2vertcoarse.EntrySize(i); j++) - { - int v2 = vert2vertcoarse.Get(i,j); - if (edgeflag.Get(v2) < i) - { - ned++; - edgenr.Elem(v2) = ned; - edgeflag.Elem(v2) = i; - missing.Append (INDEX_3(i,v2,ned)); - } - } - - for (j = 1; j <= vert2element->EntrySize(i); j++) - { - int elnr = vert2element->Get(i,j); - const Element & el = mesh.VolumeElement (elnr); - - int neledges = GetNEdges (el.GetType()); - const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); - - for (k = 0; k < neledges; k++) - { - INDEX_2 edge(el.PNum(eledges[k][0]), - el.PNum(eledges[k][1])); - - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (edge.I1() != i) - continue; - - if (edgeflag.Get (edge.I2()) < i) - { - ned++; - edgenr.Elem(edge.I2()) = ned; - edgeflag.Elem(edge.I2()) = i; - } - - int edgenum = edgenr.Elem(edge.I2()); - if (edgedir) edgenum *= -1; - edges.Elem(elnr)[k] = edgenum; - } - } - - for (j = 1; j <= vert2surfelement->EntrySize(i); j++) - { - int elnr = vert2surfelement->Get(i,j); - const Element2d & el = mesh.SurfaceElement (elnr); - - int neledges = GetNEdges (el.GetType()); - const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); - - for (k = 0; k < neledges; k++) - { - INDEX_2 edge(el.PNum(eledges[k][0]), - el.PNum(eledges[k][1])); - - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (edge.I1() != i) - continue; - - if (edgeflag.Get (edge.I2()) < i) - { - ned++; - edgenr.Elem(edge.I2()) = ned; - edgeflag.Elem(edge.I2()) = i; - } - - int edgenum = edgenr.Elem(edge.I2()); - if (edgedir) edgenum *= -1; - surfedges.Elem(elnr)[k] = edgenum; - } - } - - for (j = 1; j <= vert2segment->EntrySize(i); j++) - { - int elnr = vert2segment->Get(i,j); - const Segment & el = mesh.LineSegment (elnr); - - INDEX_2 edge(el.p1, el.p2); - - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (edge.I1() != i) - continue; - - if (edgeflag.Get (edge.I2()) < i) - { - ned++; - edgenr.Elem(edge.I2()) = ned; - edgeflag.Elem(edge.I2()) = i; - } - int edgenum = edgenr.Elem(edge.I2()); - - if (edgedir) edgenum *= -1; - segedges.Elem(elnr) = edgenum; - } - } - - - edge2vert.SetSize (ned); - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement (i); - - int neledges = GetNEdges (el.GetType()); - const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); - - for (k = 0; k < neledges; k++) - { - INDEX_2 edge(el.PNum(eledges[k][0]), - el.PNum(eledges[k][1])); - - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - int edgenum = abs (edges.Elem(i)[k]); - - edge2vert.Elem(edgenum)[0] = edge.I1(); - edge2vert.Elem(edgenum)[1] = edge.I2(); - } - } - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement (i); - - int neledges = GetNEdges (el.GetType()); - const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); - - for (k = 0; k < neledges; k++) - { - INDEX_2 edge(el.PNum(eledges[k][0]), - el.PNum(eledges[k][1])); - - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - int edgenum = abs (surfedges.Elem(i)[k]); - - edge2vert.Elem(edgenum)[0] = edge.I1(); - edge2vert.Elem(edgenum)[1] = edge.I2(); - } - } - - for (i = 1; i <= nseg; i++) - { - const Segment & el = mesh.LineSegment (i); - - INDEX_2 edge(el.p1, el.p2); - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - int edgenum = abs (segedges.Elem(i)); - - edge2vert.Elem(edgenum)[0] = edge.I1(); - edge2vert.Elem(edgenum)[1] = edge.I2(); - } - - for (i = 1; i <= missing.Size(); i++) - { - INDEX_3 i3 = missing.Get(i); - edge2vert.Elem(i3.I3())[0] = i3.I1(); - edge2vert.Elem(i3.I3())[1] = i3.I2(); - } - - /* - (*testout) << "edge table:" << endl; - (*testout) << "edge2vert:" << endl; - for (i = 1; i <= edge2vert.Size(); i++) - (*testout) << "edge " << i << ", v1,2 = " << edge2vert.Elem(i)[0] << ", " << edge2vert.Elem(i)[1] << endl; - (*testout) << "surfedges:" << endl; - for (i = 1; i <= surfedges.Size(); i++) - (*testout) << "el " << i << ", edges = " - << surfedges.Elem(i)[0] << ", " - << surfedges.Elem(i)[1] << ", " - << surfedges.Elem(i)[2] << endl; - */ - } - - - // cout << "build edges done" << endl; - -#ifdef OLD - if (buildedges == 2) - { // old style with hash-table - edges.SetSize(ne); - surfedges.SetSize(nse); - INDEX_2_HASHTABLE<int> vert2edge(ne+nse+1); - - // keep coarse grid edges - for (i = 1; i <= ned; i++) - { - INDEX_2 edge (edge2vert.Get(i)[0], - edge2vert.Get(i)[1]); - edge.Sort (); - vert2edge.Set (edge, i); - } - - - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement(i); - - int neledges = GetNEdges (el.GetType()); - const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); - - for (j = 0; j < 12; j++) - edges.Elem(i)[j] = 0; - for (j = 0; j < neledges; j++) - { - int edgenum; - int edgedir; - - INDEX_2 edge(el.PNum(eledges[j][0]), - el.PNum(eledges[j][1])); - - edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (vert2edge.Used (edge)) - edgenum = vert2edge.Get(edge); - else - { - ned++; - vert2edge.Set (edge, ned); - edgenum = ned; - /* - edge2vert.SetSize(edge2vert.Size()+1); - edge2vert.Last()[0] = edge.I1(); - edge2vert.Last()[1] = edge.I2(); - */ - edge2vert.Append (edge); - } - - if (edgedir) edgenum *= -1; - edges.Elem(i)[j] = edgenum; - } - } - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement(i); - - int neledges = GetNEdges (el.GetType()); - const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); - - for (j = 0; j < 4; j++) - surfedges.Elem(i)[j] = 0; - for (j = 0; j < neledges; j++) - { - int edgenum; - int edgedir; - - INDEX_2 edge(el.PNum(eledges[j][0]), - el.PNum(eledges[j][1])); - - edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (vert2edge.Used (edge)) - edgenum = vert2edge.Get(edge); - else - { - ned++; - vert2edge.Set (edge, ned); - edgenum = ned; - - /* - edge2vert.SetSize(edge2vert.Size()+1); - edge2vert.Last()[0] = edge.I1(); - edge2vert.Last()[1] = edge.I2(); - */ - edge2vert.Append (edge); - if (mesh.GetDimension() == 3 && mesh.GetNE()) - cerr << "surface edge: should be in use: " - << edge.I1() << "-" << edge.I2() << endl; - } - - if (edgedir) edgenum *= -1; - surfedges.Elem(i)[j] = edgenum; - } - } - - - // find edges only in intermediate level - - for (i = 1; i <= np; i++) - { - int parents[2]; - - if (i <= mesh.mlbetweennodes.Size()) - { - parents[0] = mesh.mlbetweennodes.Get(i).I1(); - parents[1] = mesh.mlbetweennodes.Get(i).I2(); - } - else - parents[0] = parents[1] = 0; - - if (parents[0] && parents[1]) - { - INDEX_2 edge(parents[0], parents[1]); - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (!vert2edge.Used (edge)) - { - ned++; - vert2edge.Set (edge, ned); - /* - edge2vert.SetSize(edge2vert.Size()+1); - edge2vert.Last()[0] = edge.I1(); - edge2vert.Last()[1] = edge.I2(); - */ - edge2vert.Append (edge); - } - } - } - - /* - cout << "edge2vert: "; - edge2vert.PrintMemInfo(cout); - cout << "edges: "; - edges.PrintMemInfo(cout); - cout << "hashtable: "; - vert2edge.PrintMemInfo(cout); - */ - - if (mesh.GetDimension() == 2) - { - surffaces.SetSize(mesh.GetNSeg()); - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment (i); - - INDEX_2 edge(seg.p1, seg.p2); - int edgenum; - int edgedir = (edge.I1() > edge.I2()); - if (edgedir) swap (edge.I1(), edge.I2()); - - if (vert2edge.Used (edge)) - edgenum = vert2edge.Get(edge); - else - { - ned++; - vert2edge.Set (edge, ned); - edgenum = ned; - - /* - edge2vert.SetSize(edge2vert.Size()+1); - edge2vert.Last()[0] = edge.I1(); - edge2vert.Last()[1] = edge.I2(); - */ - edge2vert.Append (edge); - } - - - if (edgedir) edgenum *= -1; - surffaces.Elem(i) = edgenum; - } - } - } - -#endif - - - // generate faces - if (buildfaces) // && mesh.GetDimension() == 3) - { - PrintMessage (5, "Update faces "); - - faces.SetSize(ne); - surffaces.SetSize(nse); - - // face2vert.SetSize(0); // keep old faces - nfa = face2vert.Size(); - // INDEX_3_HASHTABLE<int> vert2face(ne+nse+1); - INDEX_3_CLOSED_HASHTABLE<int> vert2face(8*ne+2*nse+nfa+2); - - for (i = 1; i <= face2vert.Size(); i++) - { - INDEX_3 f; - f.I1() = face2vert.Get(i)[0]; - f.I2() = face2vert.Get(i)[1]; - f.I3() = face2vert.Get(i)[2]; - vert2face.Set (f, i); - } - - for (i = 1; i <= ne; i++) - { - const Element & el = mesh.VolumeElement (i); - - int nelfaces = GetNFaces (el.GetType()); - const ELEMENT_FACE * elfaces = GetFaces (el.GetType()); - - for (j = 0; j < 6; j++) - faces.Elem(i)[j] = 0; - for (j = 0; j < nelfaces; j++) - if (elfaces[j][3] == 0) - - { // triangle - - int facenum; - int facedir; - - INDEX_3 face(el.PNum(elfaces[j][0]), - el.PNum(elfaces[j][1]), - el.PNum(elfaces[j][2])); - - facedir = 0; - if (face.I1() > face.I2()) - { - swap (face.I1(), face.I2()); - facedir += 1; - } - if (face.I2() > face.I3()) - { - swap (face.I2(), face.I3()); - facedir += 2; - } - if (face.I1() > face.I2()) - { - swap (face.I1(), face.I2()); - facedir += 4; - } - - if (vert2face.Used (face)) - facenum = vert2face.Get(face); - else - { - nfa++; - vert2face.Set (face, nfa); - facenum = nfa; - - INDEX_4 hface; - face2vert.Append (hface); - // face2vert.SetSize(face2vert.Size()+1); - face2vert.Last()[0] = face.I1(); - face2vert.Last()[1] = face.I2(); - face2vert.Last()[2] = face.I3(); - face2vert.Last()[3] = 0; - - } - - faces.Elem(i)[j] = 8*(facenum-1)+facedir+1; - } - - else - - { - // quad - int facenum; - int facedir; - INDEX_4Q face4(el.PNum(elfaces[j][0]), - el.PNum(elfaces[j][1]), - el.PNum(elfaces[j][2]), - el.PNum(elfaces[j][3])); - - facedir = 0; - if (min2 (face4.I1(), face4.I2()) > - min2 (face4.I4(), face4.I3())) - { // z - flip - facedir += 1; - swap (face4.I1(), face4.I4()); - swap (face4.I2(), face4.I3()); - } - if (min2 (face4.I1(), face4.I4()) > - min2 (face4.I2(), face4.I3())) - { // x - flip - facedir += 2; - swap (face4.I1(), face4.I2()); - swap (face4.I3(), face4.I4()); - } - if (face4.I2() > face4.I4()) - { // diagonal flip - facedir += 4; - swap (face4.I2(), face4.I4()); - } - // face4.Sort(); - - INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); - - if (vert2face.Used (face)) - { - facenum = vert2face.Get(face); - } - else - { - nfa++; - vert2face.Set (face, nfa); - facenum = nfa; - - // face2vert.SetSize(face2vert.Size()+1); - - INDEX_4 hface; - face2vert.Append (hface); - face2vert.Last()[0] = face4.I1(); - face2vert.Last()[1] = face4.I2(); - face2vert.Last()[2] = face4.I3(); - face2vert.Last()[3] = face4.I4(); - - } - - faces.Elem(i)[j] = 8*(facenum-1)+facedir+1; - } - } - - face2surfel.SetSize(nfa+nse); - for (i = 1; i <= face2surfel.Size(); i++) - face2surfel.Elem(i) = 0; - - for (i = 1; i <= nse; i++) - { - const Element2d & el = mesh.SurfaceElement (i); - - const ELEMENT_FACE * elfaces = GetFaces (el.GetType()); - - if (elfaces[0][3] == 0) - - { // triangle - - int facenum; - int facedir; - - INDEX_3 face(el.PNum(elfaces[0][0]), - el.PNum(elfaces[0][1]), - el.PNum(elfaces[0][2])); - - facedir = 0; - if (face.I1() > face.I2()) - { - swap (face.I1(), face.I2()); - facedir += 1; - } - if (face.I2() > face.I3()) - { - swap (face.I2(), face.I3()); - facedir += 2; - } - if (face.I1() > face.I2()) - { - swap (face.I1(), face.I2()); - facedir += 4; - } - - if (vert2face.Used (face)) - facenum = vert2face.Get(face); - else - { - nfa++; - vert2face.Set (face, nfa); - facenum = nfa; - - // face2vert.SetSize(face2vert.Size()+1); - INDEX_4 hface; - face2vert.Append (hface); - face2vert.Last()[0] = face.I1(); - face2vert.Last()[1] = face.I2(); - face2vert.Last()[2] = face.I3(); - face2vert.Last()[3] = 0; - } - - surffaces.Elem(i) = 8*(facenum-1)+facedir+1; - face2surfel.Elem(facenum) = i; - } - - else - - { - // quad - int facenum; - int facedir; - - INDEX_4Q face4(el.PNum(elfaces[0][0]), - el.PNum(elfaces[0][1]), - el.PNum(elfaces[0][2]), - el.PNum(elfaces[0][3])); - - facedir = 0; - if (min2 (face4.I1(), face4.I2()) > - min2 (face4.I4(), face4.I3())) - { // z - orientation - facedir += 1; - swap (face4.I1(), face4.I4()); - swap (face4.I2(), face4.I3()); - } - if (min2 (face4.I1(), face4.I4()) > - min2 (face4.I2(), face4.I3())) - { // x - orientation - facedir += 2; - swap (face4.I1(), face4.I2()); - swap (face4.I3(), face4.I4()); - } - if (face4.I2() > face4.I4()) - { - facedir += 4; - swap (face4.I2(), face4.I4()); - } - - INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); - - if (vert2face.Used (face)) - facenum = vert2face.Get(face); - else - { - nfa++; - vert2face.Set (face, nfa); - facenum = nfa; - - // face2vert.SetSize(face2vert.Size()+1); - INDEX_4 hface; - face2vert.Append (hface); - face2vert.Last()[0] = face4.I1(); - face2vert.Last()[1] = face4.I2(); - face2vert.Last()[2] = face4.I3(); - face2vert.Last()[3] = face4.I3(); - } - - surffaces.Elem(i) = 8*(facenum-1)+facedir+1; - face2surfel.Elem(facenum) = i; - } - } - - surf2volelement.SetSize (nse); - for (i = 1; i <= nse; i++) - { - surf2volelement.Elem(i)[0] = 0; - surf2volelement.Elem(i)[1] = 0; - } - for (i = 1; i <= ne; i++) - for (j = 0; j < 6; j++) - { - int fnum = (faces.Get(i)[j]-1) / 8 + 1; - if (fnum > 0 && face2surfel.Elem(fnum)) - { - int sel = face2surfel.Elem(fnum); - surf2volelement.Elem(sel)[1] = - surf2volelement.Elem(sel)[0]; - surf2volelement.Elem(sel)[0] = i; - } - } - - - face2vert.SetAllocSize (face2vert.Size()); - - /* - cout << "face2vert: "; - face2vert.PrintMemInfo(cout); - cout << "faces: "; - faces.PrintMemInfo(cout); - cout << "hashtable: "; - vert2face.PrintMemInfo(cout); - */ - - - ARRAY<char> face_els(nfa), face_surfels(nfa); - face_els = 0; - face_surfels = 0; - ARRAY<int> hfaces; - for (i = 1; i <= ne; i++) - { - GetElementFaces (i, hfaces); - for (j = 0; j < hfaces.Size(); j++) - face_els[hfaces[j]-1]++; - } - for (i = 1; i <= nse; i++) - face_surfels[GetSurfaceElementFace (i)-1]++; - - if (ne) - { - int cnt_err = 0; - for (i = 0; i < nfa; i++) - { - (*testout) << "face " << i << " has " << int(face_els[i]) << " els, " - << int(face_surfels[i]) << " surfels, tot = " - << face_els[i] + face_surfels[i] << endl; - - if (face_els[i] + face_surfels[i] == 1) - { - cnt_err++; - (*testout) << "illegal face : " << i << endl; - (*testout) << "points = " << face2vert[i] << endl; - (*testout) << "pos = "; - for (int j = 0; j < 4; j++) - if (face2vert[i].I(j+1) >= 1) - (*testout) << mesh[(PointIndex)face2vert[i].I(j+1)] << " "; - (*testout) << endl; - } - } - if (cnt_err) - cout << cnt_err << " elements are not matching !!!" << endl; - } - } - - /* - for (i = 1; i <= ne; i++) - { - (*testout) << "Element " << i << endl; - (*testout) << "edges: " << endl; - for (j = 0; j < 9; j++) - (*testout) << edges.Elem(i)[j] << " "; - (*testout) << "faces: " << endl; - for (j = 0; j < 6; j++) - (*testout) << faces.Elem(i)[j] << " "; - } - */ - timestamp = NextTimeStamp(); -} - - - - -int MeshTopology :: GetNVertices (ELEMENT_TYPE et) -{ - switch (et) - { - case SEGMENT: - case SEGMENT3: - return 2; - - case TRIG: - case TRIG6: - return 3; - - case QUAD: - case QUAD6: - case QUAD8: - return 4; - - case TET: - case TET10: - return 4; - - case PYRAMID: - return 5; - - case PRISM: - case PRISM12: - return 6; - - case HEX: - return 8; - - default: - cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; - } - return 0; -} - -int MeshTopology :: GetNEdges (ELEMENT_TYPE et) -{ - switch (et) - { - case SEGMENT: - case SEGMENT3: - return 1; - - case TRIG: - case TRIG6: - return 3; - - case QUAD: - case QUAD6: - case QUAD8: - return 4; - - case TET: - case TET10: - return 6; - - case PYRAMID: - return 8; - - case PRISM: - case PRISM12: - return 9; - - case HEX: - return 12; - - default: - cerr << "Ng_ME_GetNEdges, illegal element type " << et << endl; - } - return 0; -} - - -int MeshTopology :: GetNFaces (ELEMENT_TYPE et) -{ - switch (et) - { - case SEGMENT: - case SEGMENT3: - return 0; - - case TRIG: - case TRIG6: - return 1; - - case QUAD: - case QUAD6: - case QUAD8: - return 1; - - case TET: - case TET10: - return 4; - - case PYRAMID: - return 5; - - case PRISM: - case PRISM12: - return 5; - - case HEX: - return 6; - - default: - cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; - } - return 0; -} - - - - -const Point3d * MeshTopology :: GetVertices (ELEMENT_TYPE et) -{ - static Point3d segm_points [] = - { Point3d (1, 0, 0), - Point3d (0, 0, 0) }; - - static Point3d trig_points [] = - { Point3d ( 1, 0, 0 ), - Point3d ( 0, 1, 0 ), - Point3d ( 0, 0, 0 ) }; - - static Point3d quad_points [] = - { Point3d ( 0, 0, 0 ), - Point3d ( 1, 0, 0 ), - Point3d ( 1, 1, 0 ), - Point3d ( 0, 1, 0 ) }; - - static Point3d tet_points [] = - { Point3d ( 1, 0, 0 ), - Point3d ( 0, 1, 0 ), - Point3d ( 0, 0, 1 ), - Point3d ( 0, 0, 0 ) }; - - static Point3d pyramid_points [] = - { - Point3d ( 0, 0, 0 ), - Point3d ( 1, 0, 0 ), - Point3d ( 1, 1, 0 ), - Point3d ( 0, 1, 0 ), - Point3d ( 0, 0, 1-1e-7 ), - }; - - static Point3d prism_points[] = - { - Point3d ( 1, 0, 0 ), - Point3d ( 0, 1, 0 ), - Point3d ( 0, 0, 0 ), - Point3d ( 1, 0, 1 ), - Point3d ( 0, 1, 1 ), - Point3d ( 0, 0, 1 ) - }; - - - static Point3d hex_points [] = - { Point3d ( 0, 0, 0 ), - Point3d ( 1, 0, 0 ), - Point3d ( 1, 1, 0 ), - Point3d ( 0, 1, 0 ), - Point3d ( 0, 0, 1 ), - Point3d ( 1, 0, 1 ), - Point3d ( 1, 1, 1 ), - Point3d ( 0, 1, 1 ) }; - - - switch (et) - { - case SEGMENT: - case SEGMENT3: - return segm_points; - - case TRIG: - case TRIG6: - return trig_points; - - case QUAD: - case QUAD6: - case QUAD8: - return quad_points; - - case TET: - case TET10: - return tet_points; - - case PYRAMID: - return pyramid_points; - - case PRISM: - case PRISM12: - return prism_points; - - case HEX: - return hex_points; - default: - cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; - } - return 0; -} - - - - -const ELEMENT_EDGE * MeshTopology :: GetEdges (ELEMENT_TYPE et) -{ - static int segm_edges[1][2] = - { { 1, 2 }}; - - static int trig_edges[3][2] = - { { 3, 1 }, - { 2, 3 }, - { 1, 2 }}; - - static int quad_edges[4][2] = - { { 1, 2 }, - { 3, 4 }, - { 4, 1 }, - { 2, 3 }}; - - - static int tet_edges[6][2] = - { { 4, 1 }, - { 4, 2 }, - { 4, 3 }, - { 1, 2 }, - { 1, 3 }, - { 2, 3 }}; - - static int prism_edges[9][2] = - { { 3, 1 }, - { 1, 2 }, - { 3, 2 }, - { 6, 4 }, - { 4, 5 }, - { 6, 5 }, - { 3, 6 }, - { 1, 4 }, - { 2, 5 }}; - - static int pyramid_edges[8][2] = - { { 1, 2 }, - { 2, 3 }, - { 1, 4 }, - { 4, 3 }, - { 1, 5 }, - { 2, 5 }, - { 3, 5 }, - { 4, 5 }}; - - static int hex_edges[12][2] = - { - { 1, 2 }, - { 3, 4 }, - { 4, 1 }, - { 2, 3 }, - { 5, 6 }, - { 7, 8 }, - { 8, 5 }, - { 6, 7 }, - { 1, 5 }, - { 2, 6 }, - { 3, 7 }, - { 4, 8 }, - }; - - switch (et) - { - case SEGMENT: - case SEGMENT3: - return segm_edges; - - case TRIG: - case TRIG6: - return trig_edges; - - case QUAD: - case QUAD6: - case QUAD8: - return quad_edges; - - case TET: - case TET10: - return tet_edges; - - case PYRAMID: - return pyramid_edges; - - case PRISM: - case PRISM12: - return prism_edges; - - case HEX: - return hex_edges; - default: - cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; - } - return 0; -} - - -const ELEMENT_FACE * MeshTopology :: GetFaces (ELEMENT_TYPE et) -{ - static int trig_faces[1][4] = - { { 1, 2, 3, 0 } }; - static int quad_faces[1][4] = - { { 1, 2, 3, 4 } }; - - static int tet_faces[4][4] = - { { 4, 2, 3, 0 }, - { 4, 3, 1, 0 }, - { 4, 1, 2, 0 }, - { 1, 3, 2, 0 } }; - - static int prism_faces[5][4] = - { - { 1, 3, 2, 0 }, - { 4, 5, 6, 0 }, - { 3, 1, 4, 6 }, - { 1, 2, 5, 4 }, - { 2, 3, 6, 5 } - }; - - static int pyramid_faces[5][4] = - { - { 1, 2, 5, 0 }, - { 2, 3, 5, 0 }, - { 3, 4, 5, 0 }, - { 4, 1, 5, 0 }, - { 1, 4, 3, 2 } - }; - - static int hex_faces[6][4] = - { - { 1, 4, 3, 2 }, - { 5, 6, 7, 8 }, - { 1, 2, 6, 5 }, - { 2, 3, 7, 6 }, - { 3, 4, 8, 7 }, - { 4, 1, 5, 8 } - }; - - - - switch (et) - { - case TRIG: - case TRIG6: - return trig_faces; - - case QUAD: - case QUAD6: - case QUAD8: - return quad_faces; - - - case TET: - case TET10: - return tet_faces; - - case PRISM: - case PRISM12: - return prism_faces; - - case PYRAMID: - return pyramid_faces; - - case SEGMENT: - case SEGMENT3: - - case HEX: - return hex_faces; - - default: - cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; - } - return 0; -} - - - - - - - - - - - - -void MeshTopology :: GetElementEdges (int elnr, ARRAY<int> & eledges) const -{ - int ned = GetNEdges (mesh.VolumeElement(elnr).GetType()); - eledges.SetSize (ned); - for (int i = 0; i < ned; i++) - eledges[i] = abs (edges.Get(elnr)[i]); -} -void MeshTopology :: GetElementFaces (int elnr, ARRAY<int> & elfaces) const -{ - int i; - int nfa = GetNFaces (mesh.VolumeElement(elnr).GetType()); - elfaces.SetSize (nfa); - for (i = 1; i <= nfa; i++) - elfaces.Elem(i) = (faces.Get(elnr)[i-1]-1) / 8 + 1; -} - -void MeshTopology :: GetElementEdgeOrientations (int elnr, ARRAY<int> & eorient) const -{ - int i; - int ned = GetNEdges (mesh.VolumeElement(elnr).GetType()); - eorient.SetSize (ned); - for (i = 1; i <= ned; i++) - eorient.Elem(i) = (edges.Get(elnr)[i-1] > 0) ? 1 : -1; -} - -void MeshTopology :: GetElementFaceOrientations (int elnr, ARRAY<int> & forient) const -{ - int i; - int nfa = GetNFaces (mesh.VolumeElement(elnr).GetType()); - forient.SetSize (nfa); - for (i = 1; i <= nfa; i++) - forient.Elem(i) = (faces.Get(elnr)[i-1]-1) % 8; -} - - - -int MeshTopology :: GetElementEdges (int elnr, int * eledges, int * orient) const -{ - int i; - // int ned = GetNEdges (mesh.VolumeElement(elnr).GetType()); - - if (mesh.GetDimension()==3 || 1) - { - if (orient) - { - for (i = 0; i < 12; i++) - { - if (!edges.Get(elnr)[i]) return i; - eledges[i] = abs (edges.Get(elnr)[i]); - orient[i] = (edges.Get(elnr)[i] > 0 ) ? 1 : -1; - } - } - else - { - for (i = 0; i < 12; i++) - { - if (!edges.Get(elnr)[i]) return i; - eledges[i] = abs (edges.Get(elnr)[i]); - } - } - return 12; - } - else - { - if (orient) - { - for (i = 0; i < 4; i++) - { - if (!surfedges.Get(elnr)[i]) return i; - eledges[i] = abs (surfedges.Get(elnr)[i]); - orient[i] = (surfedges.Get(elnr)[i] > 0 ) ? 1 : -1; - } - } - else - { - if (!surfedges.Get(elnr)[i]) return i; - for (i = 0; i < 4; i++) - eledges[i] = abs (surfedges.Get(elnr)[i]); - } - return 4; - // return GetSurfaceElementEdges (elnr, eledges, orient); - } -} - -int MeshTopology :: GetElementFaces (int elnr, int * elfaces, int * orient) const -{ - int i; - // int nfa = GetNFaces (mesh.VolumeElement(elnr).GetType()); - if (orient) - { - for (i = 0; i < 6; i++) - { - if (!faces.Get(elnr)[i]) return i; - elfaces[i] = (faces.Get(elnr)[i]-1) / 8 + 1; - orient[i] = (faces.Get(elnr)[i]-1) % 8; - } - } - else - { - for (i = 0; i < 6; i++) - { - if (!faces.Get(elnr)[i]) return i; - elfaces[i] = (faces.Get(elnr)[i]-1) / 8 + 1; - } - } - return 6; -} - -void MeshTopology :: GetSurfaceElementEdges (int elnr, ARRAY<int> & eledges) const -{ - int i; - if (mesh.GetDimension()==3 || 1) - { - int ned = GetNEdges (mesh.SurfaceElement(elnr).GetType()); - eledges.SetSize (ned); - for (i = 1; i <= ned; i++) - eledges.Elem(i) = abs (surfedges.Get(elnr)[i-1]); - } - else - { - cout << "surfeledge(" << elnr << ") = " << flush; - eledges.SetSize(1); - eledges.Elem(1) = abs (segedges.Get(elnr)); - cout << eledges.Elem(1) << endl; - } -} - -int MeshTopology :: GetSurfaceElementFace (int elnr) const -{ - return (surffaces.Get(elnr)-1) / 8 + 1; -} - -void MeshTopology :: -GetSurfaceElementEdgeOrientations (int elnr, ARRAY<int> & eorient) const -{ - int ned = GetNEdges (mesh.SurfaceElement(elnr).GetType()); - eorient.SetSize (ned); - for (int i = 1; i <= ned; i++) - eorient.Elem(i) = (surfedges.Get(elnr)[i-1] > 0) ? 1 : -1; -} - -int MeshTopology :: GetSurfaceElementFaceOrientation (int elnr) const -{ - return (surffaces.Get(elnr)-1) % 8; -} - -int MeshTopology :: GetSurfaceElementEdges (int elnr, int * eledges, int * orient) const -{ - int i; - if (mesh.GetDimension() == 3 || 1) - { - if (orient) - { - for (i = 0; i < 4; i++) - { - if (!surfedges.Get(elnr)[i]) return i; - eledges[i] = abs (surfedges.Get(elnr)[i]); - orient[i] = (surfedges.Get(elnr)[i] > 0 ) ? 1 : -1; - } - } - else - { - for (i = 0; i < 4; i++) - { - if (!surfedges.Get(elnr)[i]) return i; - eledges[i] = abs (surfedges.Get(elnr)[i]); - } - } - return 4; - } - else - { - eledges[0] = abs (segedges.Get(elnr)); - if (orient) - orient[0] = segedges.Get(elnr) > 0 ? 1 : -1; - } - return 1; -} - - -void MeshTopology :: GetFaceVertices (int fnr, ARRAY<int> & vertices) const -{ - vertices.SetSize(4); - int i; - for (i = 1; i <= 4; i++) - vertices.Elem(i) = face2vert.Get(fnr)[i-1]; - if (vertices.Elem(4) == 0) - vertices.SetSize(3); -} - -void MeshTopology :: GetFaceVertices (int fnr, int * vertices) const -{ - for (int i = 0; i <= 3; i++) - vertices[i] = face2vert.Get(fnr)[i]; -} - - -void MeshTopology :: GetEdgeVertices (int ednr, int & v1, int & v2) const -{ - v1 = edge2vert.Get(ednr)[0]; - v2 = edge2vert.Get(ednr)[1]; -} - - -void MeshTopology :: GetFaceEdges (int fnr, ARRAY<int> & edges) const -{ - ArrayMem<int,4> pi(4); - ArrayMem<int,12> eledges; - - edges.SetSize (0); - GetFaceVertices (fnr, pi); - - // GetVertexElements (pi[0], els); - FlatArray<int> els = GetVertexElements (pi[0]); - - // find one element having all vertices of the face - for (int i = 0; i < els.Size(); i++) - { - const Element & el = mesh.VolumeElement(els[i]); - - int cntv = 0; - for (int j = 0; j < el.GetNV(); j++) - for (int k = 0; k < pi.Size(); k++) - if (el[j] == pi[k]) - cntv++; - - if (cntv == pi.Size()) - { - GetElementEdges (els[i], eledges); - - for (int j = 0; j < eledges.Size(); j++) - { - int vi1, vi2; - GetEdgeVertices (eledges[j], vi1, vi2); - bool has1 = 0; - bool has2 = 0; - for (int k = 0; k < pi.Size(); k++) - { - if (vi1 == pi[k]) has1 = 1; - if (vi2 == pi[k]) has2 = 1; - } - if (has1 && has2) - edges.Append (eledges[j]); - } - - return; - } - } -} - - -ELEMENT_TYPE MeshTopology :: GetFaceType (int fnr) const -{ - if (face2vert.Get(fnr)[3] == 0) return TRIG; else return QUAD; -} - - -void MeshTopology :: GetVertexElements (int vnr, ARRAY<int> & elements) const -{ - if (vert2element) - { - int i; - int ne = vert2element->EntrySize(vnr); - elements.SetSize(ne); - for (i = 1; i <= ne; i++) - elements.Elem(i) = vert2element->Get(vnr, i); - } -} - - -FlatArray<int> MeshTopology :: GetVertexElements (int vnr) const -{ - if (vert2element) - return (*vert2element)[vnr]; - return FlatArray<int> (0,0); -} - -FlatArray<int> MeshTopology :: GetVertexSurfaceElements (int vnr) const -{ - if (vert2surfelement) - return (*vert2surfelement)[vnr]; - return FlatArray<int> (0,0); -} - - -void MeshTopology :: GetVertexSurfaceElements( int vnr, - ARRAY<int>& elements ) const -{ - if (vert2surfelement) - { - int i; - int ne = vert2surfelement->EntrySize(vnr); - elements.SetSize(ne); - for (i = 1; i <= ne; i++) - elements.Elem(i) = vert2surfelement->Get(vnr, i); - } -} - -} diff --git a/Netgen/libsrc/meshing/topology.hpp b/Netgen/libsrc/meshing/topology.hpp deleted file mode 100644 index 3c5ac1397f..0000000000 --- a/Netgen/libsrc/meshing/topology.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef TOPOLOGY -#define TOPOLOGY - -/**************************************************************************/ -/* File: topology.hh */ -/* Author: Joachim Schoeberl */ -/* Date: 27. Apr. 01 */ -/**************************************************************************/ - -/* - Mesh topology - (Elements, Faces, Edges, Vertices -*/ - - -class MeshTopology -{ - const Mesh & mesh; - int buildedges; - int buildfaces; - - MoveableArray<INDEX_2> edge2vert; - MoveableArray<INDEX_4> face2vert; - MoveableArray<int[12]> edges; - MoveableArray<int[6]> faces; - MoveableArray<int[4]> surfedges; - MoveableArray<int> segedges; - MoveableArray<int> surffaces; - MoveableArray<INDEX_2> surf2volelement; - MoveableArray<int> face2surfel; - TABLE<int,PointIndex::BASE> *vert2element; - TABLE<int,PointIndex::BASE> *vert2surfelement; - TABLE<int,PointIndex::BASE> *vert2segment; - int timestamp; -public: - MeshTopology (const Mesh & amesh); - ~MeshTopology (); - - void SetBuildEdges (int be) - { buildedges = be; } - void SetBuildFaces (int bf) - { buildfaces = bf; } - - int HasEdges () const - { return buildedges; } - int HasFaces () const - { return buildedges; } - - void Update(); - - - int GetNEdges () const - { return edge2vert.Size(); } - int GetNFaces () const - { return face2vert.Size(); } - - static int GetNVertices (ELEMENT_TYPE et); - static int GetNEdges (ELEMENT_TYPE et); - static int GetNFaces (ELEMENT_TYPE et); - - static const Point3d * GetVertices (ELEMENT_TYPE et); - static const ELEMENT_EDGE * GetEdges (ELEMENT_TYPE et); - static const ELEMENT_FACE * GetFaces (ELEMENT_TYPE et); - - - - int GetSegmentEdge (int segnr) const { return abs(segedges[segnr-1]); } - int GetSegmentEdgeOrientation (int segnr) const { return sgn(segedges[segnr-1]); } - - void GetSegmentEdge (int segnr, int & enr, int & orient) const - { - enr = abs(segedges.Get(segnr)); - orient = segedges.Get(segnr) > 0 ? 1 : -1; - } - - void GetElementEdges (int elnr, ARRAY<int> & edges) const; - void GetElementFaces (int elnr, ARRAY<int> & faces) const; - void GetElementEdgeOrientations (int elnr, ARRAY<int> & eorient) const; - void GetElementFaceOrientations (int elnr, ARRAY<int> & forient) const; - - int GetElementEdges (int elnr, int * edges, int * orient) const; - int GetElementFaces (int elnr, int * faces, int * orient) const; - - void GetFaceVertices (int fnr, ARRAY<int> & vertices) const; - void GetFaceVertices (int fnr, int * vertices) const; - void GetEdgeVertices (int fnr, int & v1, int & v2) const; - void GetFaceEdges (int fnr, ARRAY<int> & edges) const; - - ELEMENT_TYPE GetFaceType (int fnr) const; - - void GetSurfaceElementEdges (int elnr, ARRAY<int> & edges) const; - int GetSurfaceElementFace (int elnr) const; - void GetSurfaceElementEdgeOrientations (int elnr, ARRAY<int> & eorient) const; - int GetSurfaceElementFaceOrientation (int elnr) const; - - int GetSurfaceElementEdges (int elnr, int * edges, int * orient) const; - - void GetSurface2VolumeElement (int selnr, int & elnr1, int & elnr2) const - { - elnr1 = surf2volelement.Get(selnr)[0]; - elnr2 = surf2volelement.Get(selnr)[1]; - } - - int GetFace2SurfaceElement (int fnr) const { return face2surfel[fnr-1]; } - - void GetVertexElements (int vnr, ARRAY<int> & elements) const; - FlatArray<int> GetVertexElements (int vnr) const; - - void GetVertexSurfaceElements( int vnr, ARRAY<int>& elements ) const; - FlatArray<int> GetVertexSurfaceElements (int vnr) const; -}; - -#endif diff --git a/Netgen/libsrc/meshing/triarls.cpp b/Netgen/libsrc/meshing/triarls.cpp deleted file mode 100644 index 923763306d..0000000000 --- a/Netgen/libsrc/meshing/triarls.cpp +++ /dev/null @@ -1,468 +0,0 @@ -namespace netgen -{ -const char * triarules[] = { -"rule \"Free Triangle (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.7) { 0.5 X2 } { };\n",\ -"(0.5, 1.5) { 0.5 X2 } { };\n",\ -"(-0.5, 0.7) { 0.5 X2 } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"(0.5, 0.866) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Free Triangle (5)\"\n",\ -"\n",\ -"quality 5\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.5) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.7) { 1 X2 } { };\n",\ -"(0, 0.7) { } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.5) { 0.5 X2 } { };\n",\ -"(0.5, 0.5) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Triangle (10)\"\n",\ -"\n",\ -"quality 10\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.3) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.5) { 1 X2 } { };\n",\ -"(0, 0.5) { } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.3) { 0.5 X2 } { };\n",\ -"(0.5, 0.3) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Free Triangle (20)\"\n",\ -"\n",\ -"quality 20\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 1.0, 0, 1.0 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.1) { 0.5 X2 } { };\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1, 0.2) { 1 X2 } { };\n",\ -"(0, 0.2) { } { };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.1) { 0.5 X2 } { };\n",\ -"(0.5, 0.1) { 0.5 X2 } { };\n",\ -"\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 60 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0) { 0.5, 0, 1.0 };\n",\ -"(0.5, 0.866) { 0.6, 0, 0.8 };\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left 60 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.125, 0.6495) { 0.75 X2, 0.75 X3 } { 0.75 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Right 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 4);\n",\ -"(4, 3);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(-0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 4);\n",\ -"(4, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 };\n",\ -"(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 };\n",\ -"(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 };\n",\ -"(-0.5, 0.866) { 1 X3 } {1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 4);\n",\ -"(2, 3, 4);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Left Right 120 (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(-0.5, 0.866);\n",\ -"(1.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 1) del;\n",\ -"(2, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ -"\n",\ -"newlines\n",\ -"(3, 5);\n",\ -"(5, 4);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.5, 0.866) { 1 X4 } { 1 Y4 };\n",\ -"(1, 1.299) { -0.5 X2, 0.375 X3, 1.125 X4 } { -0.5 Y2, 0.375 Y3, 1.125 Y4 };\n",\ -"(0, 1.299) { 1.125 X3, 0.375 X4 } { 1.125 Y3, 0.375 Y4 };\n",\ -"(-0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 5);\n",\ -"(3, 1, 5);\n",\ -"(2, 4, 5);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"rule \"Fill Triangle\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(2, 3) del;\n",\ -"(3, 1) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"Vis A Vis (1)\"\n",\ -"\n",\ -"quality 1\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(0.5, 0.866);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"\n",\ -"newpoints\n",\ -"\n",\ -"newlines\n",\ -"(1, 3);\n",\ -"(3, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 };\n",\ -"\n",\ -"freearea2\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { };\n",\ -"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ -"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ -"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 3);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"rule \"2 h Vis A Vis (1)\"\n",\ -"\n",\ -"quality 3\n",\ -"\n",\ -"mappoints\n",\ -"(0, 0);\n",\ -"(1, 0);\n",\ -"(1, 1.732);\n",\ -"(0, 1.732);\n",\ -"\n",\ -"maplines\n",\ -"(1, 2) del;\n",\ -"(3, 4) del;\n",\ -"\n",\ -"newpoints\n",\ -"(0.5, 0.866) { 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 };\n",\ -"\n",\ -"newlines\n",\ -"(1, 5);\n",\ -"(5, 4);\n",\ -"(3, 5);\n",\ -"(5, 2);\n",\ -"\n",\ -"freearea\n",\ -"(0, 0);\n",\ -"(1, 0) { 1 X2 } { 1 Y2 };\n",\ -"(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 };\n",\ -"(1, 1.732) { 1 X3 } { 1 Y3 };\n",\ -"(0, 1.732) { 1 X4 } { 1 Y4 };\n",\ -"(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 };\n",\ -"\n",\ -"elements\n",\ -"(1, 2, 5);\n",\ -"(3, 4, 5);\n",\ -"\n",\ -"endrule\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -"\n",\ -0}; -} diff --git a/Netgen/libsrc/meshing/zrefine.cpp b/Netgen/libsrc/meshing/zrefine.cpp deleted file mode 100644 index 7b4d4804a9..0000000000 --- a/Netgen/libsrc/meshing/zrefine.cpp +++ /dev/null @@ -1,735 +0,0 @@ -#include <mystdlib.h> -#include "meshing.hpp" - -#include <csg.hpp> - -namespace netgen -{ - - // find singular edges - void SelectSingularEdges (const Mesh & mesh, const CSGeometry & geom, - INDEX_2_HASHTABLE<int> & singedges, - ZRefinementOptions & opt) - { - int i, j; - - // edges selected in csg input file - for (i = 1; i <= geom.singedges.Size(); i++) - { - const SingularEdge & se = *geom.singedges.Get(i); - for (j = 1; j <= se.segms.Size(); j++) - { - INDEX_2 i2 = se.segms.Get(j); - singedges.Set (i2, 1); - } - } - - // edges interactively selected - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment(i); - if (seg.singedge_left || seg.singedge_right) - { - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort(); - singedges.Set (i2, 1); - } - } - } - - - /** - Convert elements (vol-tets, surf-trigs) into prisms/quads - */ - void MakePrismsSingEdge (Mesh & mesh, INDEX_2_HASHTABLE<int> & singedges) - { - int i, j, k; - - // volume elements - for (i = 1; i <= mesh.GetNE(); i++) - { - Element & el = mesh.VolumeElement(i); - if (el.GetType() != TET) continue; - - for (j = 1; j <= 3; j++) - for (k = j+1; k <= 4; k++) - { - INDEX_2 edge(el.PNum(j), el.PNum(k)); - edge.Sort(); - if (singedges.Used (edge)) - { - int pi3 = 1, pi4 = 1; - while (pi3 == j || pi3 == k) pi3++; - pi4 = 10 - j - k - pi3; - - int p3 = el.PNum(pi3); - int p4 = el.PNum(pi4); - - el.SetType(PRISM); - el.PNum(1) = edge.I1(); - el.PNum(2) = p3; - el.PNum(3) = p4; - el.PNum(4) = edge.I2(); - el.PNum(5) = p3; - el.PNum(6) = p4; - } - } - } - - // surface elements - for (i = 1; i <= mesh.GetNSE(); i++) - { - Element2d & el = mesh.SurfaceElement(i); - if (el.GetType() != TRIG) continue; - - for (j = 1; j <= 3; j++) - { - k = (j % 3) + 1; - INDEX_2 edge(el.PNum(j), el.PNum(k)); - edge.Sort(); - - if (singedges.Used (edge)) - { - int pi3 = 6-j-k; - int p3 = el.PNum(pi3); - int p1 = el.PNum(j); - int p2 = el.PNum(k); - - el.SetType(QUAD); - el.PNum(1) = p2; - el.PNum(2) = p3; - el.PNum(3) = p3; - el.PNum(4) = p1; - } - } - } - } - - - /* - Convert tets and pyramids next to close (identified) points into prisms - */ - void MakePrismsClosePoints (Mesh & mesh) - { - int i, j, k; - for (i = 1; i <= mesh.GetNE(); i++) - { - Element & el = mesh.VolumeElement(i); - if (el.GetType() == TET) - { - for (j = 1; j <= 3; j++) - for (k = j+1; k <= 4; k++) - { - INDEX_2 edge(el.PNum(j), el.PNum(k)); - edge.Sort(); - if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k))) - { - int pi3 = 1, pi4 = 1; - while (pi3 == j || pi3 == k) pi3++; - pi4 = 10 - j - k - pi3; - - int p3 = el.PNum(pi3); - int p4 = el.PNum(pi4); - - el.SetType(PRISM); - el.PNum(1) = edge.I1(); - el.PNum(2) = p3; - el.PNum(3) = p4; - el.PNum(4) = edge.I2(); - el.PNum(5) = p3; - el.PNum(6) = p4; - } - } - } - - if (el.GetType() == PYRAMID) - { - // pyramid, base face = 1,2,3,4 - - for (j = 0; j <= 1; j++) - { - int pi1 = el.PNum( (j+0) % 4 + 1); - int pi2 = el.PNum( (j+1) % 4 + 1); - int pi3 = el.PNum( (j+2) % 4 + 1); - int pi4 = el.PNum( (j+3) % 4 + 1); - int pi5 = el.PNum(5); - - INDEX_2 edge1(pi1, pi4); - INDEX_2 edge2(pi2, pi3); - edge1.Sort(); - edge2.Sort(); - if (mesh.GetIdentifications().GetSymmetric (pi1, pi4) && - mesh.GetIdentifications().GetSymmetric (pi2, pi3)) - { - int p3 = el.PNum(pi3); - int p4 = el.PNum(pi4); - - el.SetType(PRISM); - el.PNum(1) = pi1; - el.PNum(2) = pi2; - el.PNum(3) = pi5; - el.PNum(4) = pi4; - el.PNum(5) = pi3; - el.PNum(6) = pi5; - } - } - } - } - - for (i = 1; i <= mesh.GetNSE(); i++) - { - Element2d & el = mesh.SurfaceElement(i); - if (el.GetType() != TRIG) continue; - - for (j = 1; j <= 3; j++) - { - k = (j % 3) + 1; - INDEX_2 edge(el.PNum(j), el.PNum(k)); - edge.Sort(); - - if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k))) - { - int pi3 = 6-j-k; - int p3 = el.PNum(pi3); - int p1 = el.PNum(j); - int p2 = el.PNum(k); - - el.SetType(QUAD); - el.PNum(1) = p2; - el.PNum(2) = p3; - el.PNum(3) = p3; - el.PNum(4) = p1; - } - } - } - } - - - -#ifdef OLD - void MakeCornerNodes (Mesh & mesh, - INDEX_HASHTABLE<int> & cornernodes) - { - int i, j; - int nseg = mesh.GetNSeg(); - ARRAY<int> edgesonpoint(mesh.GetNP()); - for (i = 1; i <= mesh.GetNP(); i++) - edgesonpoint.Elem(i) = 0; - - for (i = 1; i <= nseg; i++) - { - for (j = 1; j <= 2; j++) - { - int pi = (j == 1) ? - mesh.LineSegment(i).p1 : - mesh.LineSegment(i).p2; - edgesonpoint.Elem(pi)++; - } - } - - /* - cout << "cornernodes: "; - for (i = 1; i <= edgesonpoint.Size(); i++) - if (edgesonpoint.Get(i) >= 6) - { - cornernodes.Set (i, 1); - cout << i << " "; - } - cout << endl; - */ - // cornernodes.Set (5, 1); - } -#endif - - - void RefinePrisms (Mesh & mesh, const CSGeometry * geom, - ZRefinementOptions & opt) - { - int i, j, k; - bool found, change; - int cnt = 0; - - - // markers for z-refinement: p1, p2, levels - // p1-p2 is an edge to be refined - ARRAY<INDEX_3> ref_uniform; - ARRAY<INDEX_3> ref_singular; - ARRAY<INDEX_4 > ref_slices; - - BitArray first_id(geom->identifications.Size()); - first_id.Set(); - - - INDEX_2_HASHTABLE<int> & identpts = - mesh.GetIdentifications().GetIdentifiedPoints (); - - if (&identpts) - { - for (i = 1; i <= identpts.GetNBags(); i++) - for (j = 1; j <= identpts.GetBagSize(i); j++) - { - INDEX_2 pair; - int idnr; - identpts.GetData(i, j, pair, idnr); - const CloseSurfaceIdentification * csid = - dynamic_cast<const CloseSurfaceIdentification*> - (geom->identifications.Get(idnr)); - if (csid) - { - if (!csid->GetSlices().Size()) - { - if (first_id.Test (idnr)) - { - first_id.Clear(idnr); - ref_uniform.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels())); - ref_singular.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels1())); - ref_singular.Append (INDEX_3 (pair.I2(), pair.I1(), csid->RefLevels2())); - } - } - else - { - const ARRAY<double> & slices = csid->GetSlices(); - INDEX_4 i4; - i4[0] = pair.I1(); - i4[1] = pair.I2(); - i4[2] = idnr; - i4[3] = csid->GetSlices().Size(); - ref_slices.Append (i4); - } - } - } - } - - - - ARRAY<EdgePointGeomInfo> epgi; - - while (1) - { - cnt++; - PrintMessage (3, "Z-Refinement, level = ", cnt); - INDEX_2_HASHTABLE<int> refedges(mesh.GetNSE()+1); - - - found = 0; - // mark prisms due to close surface flags: - int oldsize = ref_uniform.Size(); - for (i = 1; i <= oldsize; i++) - { - int pi1 = ref_uniform.Get(i).I1(); - int pi2 = ref_uniform.Get(i).I2(); - int levels = ref_uniform.Get(i).I3(); - - if (levels > 0) - { - const Point3d & p1 = mesh.Point(pi1); - const Point3d & p2 = mesh.Point(pi2); - int npi; - - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (!refedges.Used(edge)) - { - Point3d np = Center (p1, p2); - npi = mesh.AddPoint (np); - refedges.Set (edge, npi); - found = 1; - } - - ref_uniform.Elem(i) = INDEX_3(pi1, npi, levels-1); - ref_uniform.Append (INDEX_3(pi2, npi, levels-1)); - } - } - for (i = 1; i <= ref_singular.Size(); i++) - { - int pi1 = ref_singular.Get(i).I1(); - int pi2 = ref_singular.Get(i).I2(); - int levels = ref_singular.Get(i).I3(); - - if (levels > 0) - { - const Point3d & p1 = mesh.Point(pi1); - const Point3d & p2 = mesh.Point(pi2); - int npi; - - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (!refedges.Used(edge)) - { - Point3d np = Center (p1, p2); - npi = mesh.AddPoint (np); - refedges.Set (edge, npi); - found = 1; - } - else - npi = refedges.Get (edge); - - ref_singular.Elem(i) = INDEX_3(pi1, npi, levels-1); - } - } - - for (i = 1; i <= ref_slices.Size(); i++) - { - int pi1 = ref_slices.Get(i)[0]; - int pi2 = ref_slices.Get(i)[1]; - int idnr = ref_slices.Get(i)[2]; - int slicenr = ref_slices.Get(i)[3]; - - if (slicenr > 0) - { - const Point3d & p1 = mesh.Point(pi1); - const Point3d & p2 = mesh.Point(pi2); - int npi; - - const CloseSurfaceIdentification * csid = - dynamic_cast<const CloseSurfaceIdentification*> - (geom->identifications.Get(idnr)); - - - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (!refedges.Used(edge)) - { - const ARRAY<double> & slices = csid->GetSlices(); - double slicefac = slices.Get(slicenr); - double slicefaclast = - (slicenr == slices.Size()) ? 1 : slices.Get(slicenr+1); - - Point3d np = p1 + (slicefac / slicefaclast) * (p2-p1); - npi = mesh.AddPoint (np); - refedges.Set (edge, npi); - found = 1; - } - else - npi = refedges.Get (edge); - - ref_slices.Elem(i)[1] = npi; - ref_slices.Elem(i)[3] --; - } - } - - - - - for (i = 1; i <= mesh.GetNE(); i++) - { - Element & el = mesh.VolumeElement (i); - if (el.GetType() != PRISM) - continue; - - for (j = 1; j <= 3; j++) - { - int pi1 = el.PNum(j); - int pi2 = el.PNum(j+3); - const Point3d & p1 = mesh.Point(pi1); - const Point3d & p2 = mesh.Point(pi2); - - bool ref = 0; - - /* - if (Dist (p1, p2) > mesh.GetH (Center (p1, p2))) - ref = 1; - */ - - /* - if (cnt <= opt.minref) - ref = 1; - */ - - /* - if ((pi1 == 460 || pi2 == 460 || - pi1 == 461 || pi2 == 461) && cnt <= 8) ref = 1; - */ - if (ref == 1) - { - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (!refedges.Used(edge)) - { - Point3d np = Center (p1, p2); - int npi = mesh.AddPoint (np); - refedges.Set (edge, npi); - found = 1; - } - } - } - } - - if (!found) break; - - // build closure: - PrintMessage (5, "start closure"); - do - { - PrintMessage (5, "start loop"); - change = 0; - for (i = 1; i <= mesh.GetNE(); i++) - { - Element & el = mesh.VolumeElement (i); - if (el.GetType() != PRISM) - continue; - - bool hasref = 0, hasnonref = 0; - for (j = 1; j <= 3; j++) - { - int pi1 = el.PNum(j); - int pi2 = el.PNum(j+3); - if (pi1 != pi2) - { - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (refedges.Used(edge)) - hasref = 1; - else - hasnonref = 1; - } - } - - if (hasref && hasnonref) - { - // cout << "el " << i << " in closure" << endl; - change = 1; - for (j = 1; j <= 3; j++) - { - int pi1 = el.PNum(j); - int pi2 = el.PNum(j+3); - const Point3d & p1 = mesh.Point(pi1); - const Point3d & p2 = mesh.Point(pi2); - - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (!refedges.Used(edge)) - { - Point3d np = Center (p1, p2); - int npi = mesh.AddPoint (np); - refedges.Set (edge, npi); - } - } - } - } - } - while (change); - - PrintMessage (5, "Do segments"); - - // (*testout) << "closure formed, np = " << mesh.GetNP() << endl; - - int oldns = mesh.GetNSeg(); - - for (i = 1; i <= oldns; i++) - { - const Segment & el = mesh.LineSegment(i); - - INDEX_2 i2(el.p1, el.p2); - i2.Sort(); - - int pnew; - EdgePointGeomInfo ngi; - - if (refedges.Used(i2)) - { - pnew = refedges.Get(i2); - // ngi = epgi.Get(pnew); - } - else - { - continue; - - // Point3d pb; - - // /* - // geom->PointBetween (mesh.Point (el.p1), - // mesh.Point (el.p2), - // el.surfnr1, el.surfnr2, - // el.epgeominfo[0], el.epgeominfo[1], - // pb, ngi); - // */ - // pb = Center (mesh.Point (el.p1), mesh.Point (el.p2)); - - // pnew = mesh.AddPoint (pb); - - // refedges.Set (i2, pnew); - - // if (pnew > epgi.Size()) - // epgi.SetSize (pnew); - // epgi.Elem(pnew) = ngi; - } - - Segment ns1 = el; - Segment ns2 = el; - ns1.p2 = pnew; - ns1.epgeominfo[1] = ngi; - ns2.p1 = pnew; - ns2.epgeominfo[0] = ngi; - - mesh.LineSegment(i) = ns1; - mesh.AddSegment (ns2); - } - - PrintMessage (5, "Segments done, NSeg = ", mesh.GetNSeg()); - - // do refinement - int oldne = mesh.GetNE(); - for (i = 1; i <= oldne; i++) - { - Element & el = mesh.VolumeElement (i); - if (el.GetNP() != 6) - continue; - - int npi[3]; - for (j = 1; j <= 3; j++) - { - int pi1 = el.PNum(j); - int pi2 = el.PNum(j+3); - - if (pi1 == pi2) - npi[j-1] = pi1; - else - { - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (refedges.Used (edge)) - npi[j-1] = refedges.Get(edge); - else - { - /* - (*testout) << "ERROR: prism " << i << " has hanging node !!" - << ", edge = " << edge << endl; - cerr << "ERROR: prism " << i << " has hanging node !!" << endl; - */ - npi[j-1] = 0; - } - } - } - - if (npi[0]) - { - Element nel1(6), nel2(6); - for (j = 1; j <= 3; j++) - { - nel1.PNum(j) = el.PNum(j); - nel1.PNum(j+3) = npi[j-1]; - nel2.PNum(j) = npi[j-1]; - nel2.PNum(j+3) = el.PNum(j+3); - } - nel1.SetIndex (el.GetIndex()); - nel2.SetIndex (el.GetIndex()); - mesh.VolumeElement (i) = nel1; - mesh.AddVolumeElement (nel2); - } - } - - - PrintMessage (5, "Elements done, NE = ", mesh.GetNE()); - - - // do surface elements - int oldnse = mesh.GetNSE(); - // cout << "oldnse = " << oldnse << endl; - for (i = 1; i <= oldnse; i++) - { - Element2d & el = mesh.SurfaceElement (i); - if (el.GetType() != QUAD) - continue; - - int index = el.GetIndex(); - int npi[2]; - for (j = 1; j <= 2; j++) - { - int pi1, pi2; - - if (j == 1) - { - pi1 = el.PNum(1); - pi2 = el.PNum(4); - } - else - { - pi1 = el.PNum(2); - pi2 = el.PNum(3); - } - - if (pi1 == pi2) - npi[j-1] = pi1; - else - { - INDEX_2 edge(pi1, pi2); - edge.Sort(); - if (refedges.Used (edge)) - npi[j-1] = refedges.Get(edge); - else - { - npi[j-1] = 0; - } - } - } - - if (npi[0]) - { - Element2d nel1(QUAD), nel2(QUAD); - for (j = 1; j <= 4; j++) - { - nel1.PNum(j) = el.PNum(j); - nel2.PNum(j) = el.PNum(j); - } - nel1.PNum(3) = npi[1]; - nel1.PNum(4) = npi[0]; - nel2.PNum(1) = npi[0]; - nel2.PNum(2) = npi[1]; - /* - for (j = 1; j <= 2; j++) - { - nel1.PNum(j) = el.PNum(j); - nel1.PNum(j+2) = npi[j-1]; - nel2.PNum(j) = npi[j-1]; - nel2.PNum(j+2) = el.PNum(j+2); - } - */ - nel1.SetIndex (el.GetIndex()); - nel2.SetIndex (el.GetIndex()); - - mesh.SurfaceElement (i) = nel1; - mesh.AddSurfaceElement (nel2); - - int si = mesh.GetFaceDescriptor (index).SurfNr(); - - Point<3> hp = mesh.Point(npi[0]); - geom->GetSurface(si)->Project (hp); - mesh.Point (npi[0]).SetPoint (hp); - - hp = mesh.Point(npi[1]); - geom->GetSurface(si)->Project (hp); - mesh.Point (npi[1]).SetPoint (hp); - - // geom->GetSurface(si)->Project (mesh.Point(npi[0])); - // geom->GetSurface(si)->Project (mesh.Point(npi[1])); - } - } - - PrintMessage (5, "Surface elements done, NSE = ", mesh.GetNSE()); - - } - } - - - - void ZRefinement (Mesh & mesh, const CSGeometry * geom, - ZRefinementOptions & opt) - { - INDEX_2_HASHTABLE<int> singedges(mesh.GetNSeg()); - - SelectSingularEdges (mesh, *geom, singedges, opt); - MakePrismsSingEdge (mesh, singedges); - MakePrismsClosePoints (mesh); - - RefinePrisms (mesh, geom, opt); - } - - - - ZRefinementOptions :: ZRefinementOptions() - { - minref = 0; - } - -} diff --git a/Netgen/libsrc/occ/Makefile b/Netgen/libsrc/occ/Makefile deleted file mode 100644 index 6fe1d8bc0d..0000000000 --- a/Netgen/libsrc/occ/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for open cascade library -# -src = occgeom.cpp occmeshsurf.cpp occgenmesh.cpp - -lib = occ -libpath = libsrc/occ -# -# -include ../makefile.inc - diff --git a/Netgen/libsrc/occ/occgenmesh.cpp b/Netgen/libsrc/occ/occgenmesh.cpp deleted file mode 100644 index 822edf3681..0000000000 --- a/Netgen/libsrc/occ/occgenmesh.cpp +++ /dev/null @@ -1,1245 +0,0 @@ -#ifdef OCCGEOMETRY - -#include <mystdlib.h> -#include <occgeom.hpp> -#include <meshing.hpp> - -#include <stlgeom.hpp> - - -namespace netgen -{ - -#include "occmeshsurf.hpp" - -#define TCL_OK 0 -#define TCL_ERROR 1 - -extern STLParameters stlparam; - -#define DIVIDEEDGESECTIONS 1000 -#define IGNORECURVELENGTH 1e-4 - - -void DivideEdge (TopoDS_Edge & edge, - ARRAY<MeshPoint> & ps, - ARRAY<double> & params, - Mesh & mesh) -{ - double s0, s1; - int j; - double maxh = mparam.maxh; - int nsubedges = 1; - gp_Pnt pnt, oldpnt; - double svalue[DIVIDEEDGESECTIONS]; - - GProp_GProps system; - BRepGProp::LinearProperties(edge, system); - double L = system.Mass(); - - Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); - - double hvalue[DIVIDEEDGESECTIONS+1]; - hvalue[0] = 0; - pnt = c->Value(s0); - - double olddist = 0; - double dist = 0; - - for (int i = 1; i <= DIVIDEEDGESECTIONS; i++) - { - oldpnt = pnt; - pnt = c->Value(s0+(i/double(DIVIDEEDGESECTIONS))*(s1-s0)); - hvalue[i] = hvalue[i-1] + - 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* - pnt.Distance(oldpnt); - - olddist = dist; - dist = pnt.Distance(oldpnt); - } - - // nsubedges = int(ceil(hvalue[DIVIDEEDGESECTIONS])); - nsubedges = max (1, int(floor(hvalue[DIVIDEEDGESECTIONS]+0.5))); - - ps.SetSize(nsubedges-1); - params.SetSize(nsubedges+1); - - int i = 1; - int i1 = 0; - do - { - if (hvalue[i1]/hvalue[DIVIDEEDGESECTIONS]*nsubedges >= i) - { - params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0); - pnt = c->Value(params[i]); - ps[i-1] = MeshPoint (Point3d(pnt.X(), pnt.Y(), pnt.Z())); - i++; - } - i1++; - if (i1 > DIVIDEEDGESECTIONS) - { - nsubedges = i; - ps.SetSize(nsubedges-1); - params.SetSize(nsubedges+1); - cout << "divide edge: local h too small" << endl; - } - } while (i < nsubedges); - - params[0] = s0; - params[nsubedges] = s1; - - if (params[nsubedges] <= params[nsubedges-1]) - { - cout << "CORRECTED" << endl; - ps.SetSize (nsubedges-2); - params.SetSize (nsubedges); - params[nsubedges] = s1; - } -} - - - - -static void FindEdges (OCCGeometry & geom, Mesh & mesh) -{ - int i, j; - - char * savetask = multithread.task; - multithread.task = "Edge meshing"; - - (*testout) << "edge meshing" << endl; - - TopExp_Explorer exp0, exp01, exp1, exp2, exp3; - - int nvertices = geom.vmap.Extent(); - int nedges = geom.emap.Extent(); - for (i = 1; i <= nvertices; i++) - { - gp_Pnt pnt = BRep_Tool::Pnt (TopoDS::Vertex(geom.vmap(i))); - MeshPoint mp( Point3d(pnt.X(), pnt.Y(), pnt.Z()) ); - - /* - int exists = 0; - - for (j = 1; !exists && (j <= mesh.GetNP()); j++) - if ((mesh.Point(j)-Point<3>(mp)).Length() < 1e-6) - exists = 1; - - if (!exists) - */ - - mesh.AddPoint (mp); - } - - int facenr = 0; - int edgenr = 0; - - int total = 0; - int solidnr = 0; - - ARRAY<int> face2solid; - face2solid.SetSize (geom.fmap.Extent()); - face2solid = 0; - - /* - for (exp0.Init(geom.shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - solidnr++; - for (exp01.Init(exp0.Current(), TopAbs_SHELL); exp01.More(); exp01.Next()) - { - TopoDS_Shape shell = exp01.Current(); - for (exp1.Init(shell, TopAbs_FACE); exp1.More(); exp1.Next()) - { - TopoDS_Face face = TopoDS::Face(exp1.Current()); - facenr = geom.fmap.FindIndex(face); - face2solid[facenr-1] = solidnr; - - for (exp2.Init (face, TopAbs_WIRE); exp2.More(); exp2.Next()) - { - TopoDS_Shape wire = exp2.Current(); - - for (exp3.Init (wire, TopAbs_EDGE); exp3.More(); exp3.Next()) - { - total++; - } - } - } - } - } - */ - - for (exp0.Init(geom.shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - solidnr++; - for (exp1.Init(exp0.Current(), TopAbs_FACE); exp1.More(); exp1.Next()) - { - TopoDS_Face face = TopoDS::Face(exp1.Current()); - facenr = geom.fmap.FindIndex(face); - face2solid[facenr-1] = solidnr; - } - } - - - for (int i3 = 1; i3 <= geom.fmap.Extent(); i3++) - for (exp2.Init (geom.fmap(i3), TopAbs_WIRE); exp2.More(); exp2.Next()) - for (exp3.Init (exp2.Current(), TopAbs_EDGE); exp3.More(); exp3.Next()) - total++; - - - int curr = 0; - - - solidnr = 0; - /* - for (exp0.Init(geom.shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - solidnr++; - for (exp01.Init(exp0.Current(), TopAbs_SHELL); exp01.More(); exp01.Next()) - { - TopoDS_Shape shell = exp01.Current(); - - for (exp1.Init(shell, TopAbs_FACE); exp1.More(); exp1.Next()) - { - - TopoDS_Face face = TopoDS::Face(exp1.Current()); - */ - - for (int i3 = 1; i3 <= geom.fmap.Extent(); i3++) - - - { - { - { - TopoDS_Face face = TopoDS::Face(geom.fmap(i3)); - solidnr = face2solid[i3-1]; - - - facenr = geom.fmap.FindIndex (face); - - mesh.AddFaceDescriptor (FaceDescriptor(facenr, solidnr, 0, 0)); - Handle(Geom_Surface) occface = BRep_Tool::Surface(face); - - for (exp2.Init (face, TopAbs_WIRE); exp2.More(); exp2.Next()) - { - TopoDS_Shape wire = exp2.Current(); - - for (exp3.Init (wire, TopAbs_EDGE); exp3.More(); exp3.Next()) - { - curr++; - - multithread.percent = 100 * curr / (double) total; - if (multithread.terminate) return; - - TopoDS_Edge edge = TopoDS::Edge (exp3.Current()); - if (BRep_Tool::Degenerated(edge)) continue; - - if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) == - geom.vmap.FindIndex(TopExp::LastVertex (edge))) - { - GProp_GProps system; - BRepGProp::LinearProperties(edge, system); - - if (system.Mass() < 1e-5) - { - cout << "ignoring edge " << geom.emap.FindIndex (edge) - << ". closed edge with length < 1e-5" << endl; - continue; - } - } - - - Handle(Geom2d_Curve) cof; - double s0, s1; - cof = BRep_Tool::CurveOnSurface (edge, face, s0, s1); - - int geomedgenr = geom.emap.FindIndex(edge); - - ARRAY <MeshPoint> mp; - ARRAY <double> params; - - DivideEdge (edge, mp, params, mesh); - - - ARRAY <int> pnums; - pnums.SetSize (mp.Size()+2); - - pnums[0] = geom.vmap.FindIndex (TopExp::FirstVertex (edge)); - pnums[pnums.Size()-1] = geom.vmap.FindIndex (TopExp::LastVertex (edge)); - - for (i = 1; i <= mp.Size(); i++) - { - int exists = 0; - - for (j = 1; !exists && (j <= mesh.GetNP()-nvertices); j++) - if ((mesh.Point(nvertices+j)-Point<3>(mp[i-1])).Length() < 1e-6) exists = 1; - - if (exists) - { - pnums[i] = nvertices+j-1; - } - else - { - mesh.AddPoint (mp[i-1]); - pnums[i] = mesh.GetNP(); - } - } - - for (i = 1; i <= mp.Size()+1; i++) - { - edgenr++; - Segment seg; - - seg.p1 = pnums[i-1]; - seg.p2 = pnums[i]; - seg.edgenr = edgenr; - seg.si = facenr; - seg.epgeominfo[0].dist = params[i-1]; - seg.epgeominfo[1].dist = params[i]; - seg.epgeominfo[0].edgenr = geomedgenr; - seg.epgeominfo[1].edgenr = geomedgenr; - - gp_Pnt2d p2d; - p2d = cof->Value(params[i-1]); - // if (i == 1) p2d = cof->Value(s0); - seg.epgeominfo[0].u = p2d.X(); - seg.epgeominfo[0].v = p2d.Y(); - p2d = cof->Value(params[i]); - // if (i == mp.Size()+1) p2d = cof -> Value(s1); - seg.epgeominfo[1].u = p2d.X(); - seg.epgeominfo[1].v = p2d.Y(); - - /* - if (occface->IsUPeriodic()) - { - cout << "U Periodic" << endl; - if (fabs(seg.epgeominfo[1].u-seg.epgeominfo[0].u) > - fabs(seg.epgeominfo[1].u- - (seg.epgeominfo[0].u-occface->UPeriod()))) - seg.epgeominfo[0].u = p2d.X()+occface->UPeriod(); - - if (fabs(seg.epgeominfo[1].u-seg.epgeominfo[0].u) > - fabs(seg.epgeominfo[1].u- - (seg.epgeominfo[0].u+occface->UPeriod()))) - seg.epgeominfo[0].u = p2d.X()-occface->UPeriod(); - } - - if (occface->IsVPeriodic()) - { - cout << "V Periodic" << endl; - if (fabs(seg.epgeominfo[1].v-seg.epgeominfo[0].v) > - fabs(seg.epgeominfo[1].v- - (seg.epgeominfo[0].v-occface->VPeriod()))) - seg.epgeominfo[0].v = p2d.Y()+occface->VPeriod(); - - if (fabs(seg.epgeominfo[1].v-seg.epgeominfo[0].v) > - fabs(seg.epgeominfo[1].v- - (seg.epgeominfo[0].v+occface->VPeriod()))) - seg.epgeominfo[0].v = p2d.Y()-occface->VPeriod(); - } - */ - - if (edge.Orientation() == TopAbs_REVERSED) - { - swap (seg.p1, seg.p2); - swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist); - swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u); - swap (seg.epgeominfo[0].v, seg.epgeominfo[1].v); - } - - mesh.AddSegment (seg); - - } - } - } - } - } - } - mesh.CalcSurfacesOfNode(); - multithread.task = savetask; -} - - - - -static void OCCMeshSurface (OCCGeometry & geom, Mesh & mesh, int perfstepsend) -{ - int i, j, k; - int changed; - - char * savetask = multithread.task; - multithread.task = "Surface meshing"; - - geom.facemeshstatus = 0; - - int noldp = mesh.GetNP(); - - double starttime = GetTime(); - - ARRAY<int> glob2loc(noldp); - - int projecttype = PARAMETERSPACE; - - //int projecttype = PLANESPACE; - - int notrys = 1; - - int surfmesherror = 0; - - for (k = 1; k <= mesh.GetNFD(); k++) - { - (*testout) << "mesh face " << k << endl; - multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); - geom.facemeshstatus[k-1] = -1; - - - /* - if (k != 138) - { - cout << "skipped" << endl; - continue; - } - */ - - FaceDescriptor & fd = mesh.GetFaceDescriptor(k); - - int oldnf = mesh.GetNSE(); - - Box<3> bb = geom.GetBoundingBox(); - - Meshing2OCCSurfaces meshing(TopoDS::Face(geom.fmap(k)), bb, projecttype); - - if (meshing.GetProjectionType() == PLANESPACE) - PrintMessage (2, "Face ", k, " / ", mesh.GetNFD(), " (plane space projection)"); - else - PrintMessage (2, "Face ", k, " / ", mesh.GetNFD(), " (parameter space projection)"); - - if (surfmesherror) - cout << "Surface meshing error occured before (in " << surfmesherror << " faces)" << endl; - - // Meshing2OCCSurfaces meshing(f2, bb); - meshing.SetStartTime (starttime); - - (*testout) << "Face " << k << endl << endl; - - - if (meshing.GetProjectionType() == PLANESPACE) - { - int cntp = 0; - glob2loc = 0; - for (i = 1; i <= mesh.GetNSeg(); i++) - { - Segment & seg = mesh.LineSegment(i); - if (seg.si == k) - { - for (j = 1; j <= 2; j++) - { - int pi = (j == 1) ? seg.p1 : seg.p2; - if (!glob2loc.Get(pi)) - { - meshing.AddPoint (mesh.Point(pi), pi); - cntp++; - glob2loc.Elem(pi) = cntp; - } - } - } - } - - for (i = 1; i <= mesh.GetNSeg(); i++) - { - Segment & seg = mesh.LineSegment(i); - if (seg.si == k) - { - PointGeomInfo gi0, gi1; - gi0.trignum = gi1.trignum = k; - gi0.u = seg.epgeominfo[0].u; - gi0.v = seg.epgeominfo[0].v; - gi1.u = seg.epgeominfo[1].u; - gi1.v = seg.epgeominfo[1].v; - - meshing.AddBoundaryElement (glob2loc.Get(seg.p1), glob2loc.Get(seg.p2), gi0, gi1); - (*testout) << gi0.u << " " << gi0.v << endl; - (*testout) << gi1.u << " " << gi1.v << endl; - } - } - } - else - { - int cntp = 0; - - for (i = 1; i <= mesh.GetNSeg(); i++) - if (mesh.LineSegment(i).si == k) - cntp+=2; - - - ARRAY< PointGeomInfo > gis; - - gis.SetAllocSize (cntp); - gis.SetSize (0); - - for (i = 1; i <= mesh.GetNSeg(); i++) - { - Segment & seg = mesh.LineSegment(i); - if (seg.si == k) - { - PointGeomInfo gi0, gi1; - gi0.trignum = gi1.trignum = k; - gi0.u = seg.epgeominfo[0].u; - gi0.v = seg.epgeominfo[0].v; - gi1.u = seg.epgeominfo[1].u; - gi1.v = seg.epgeominfo[1].v; - - int locpnum[2] = {0, 0}; - - for (j = 0; j < 2; j++) - { - PointGeomInfo gi = (j == 0) ? gi0 : gi1; - - int l; - for (l = 0; l < gis.Size() && locpnum[j] == 0; l++) - { - double dist = sqr (gis[l].u-gi.u)+sqr(gis[l].v-gi.v); - - if (dist < 1e-10) - locpnum[j] = l+1; - } - - if (locpnum[j] == 0) - { - int pi = (j == 0) ? seg.p1 : seg.p2; - meshing.AddPoint (mesh.Point(pi), pi); - - gis.SetSize (gis.Size()+1); - gis[l] = gi; - locpnum[j] = l+1; - } - } - - meshing.AddBoundaryElement (locpnum[0], locpnum[1], gi0, gi1); - (*testout) << gi0.u << " " << gi0.v << endl; - (*testout) << gi1.u << " " << gi1.v << endl; - - } - } - } - - - - - - - double maxh = mparam.maxh; - mparam.checkoverlap = 0; - // int noldpoints = mesh->GetNP(); - int noldsurfel = mesh.GetNSE(); - - MESHING2_RESULT res; - - try { - res = meshing.GenerateMesh (mesh, maxh, k); - } - - catch (SingularMatrixException) - { - (*myerr) << "Singular Matrix" << endl; - res = MESHING2_GIVEUP; - } - - catch (UVBoundsException) - { - (*myerr) << "UV bounds exceeded" << endl; - res = MESHING2_GIVEUP; - } - - projecttype = PARAMETERSPACE; - - if (res != MESHING2_OK) - { - if (notrys == 1) - { - for (int i = noldsurfel+1; i <= mesh.GetNSE(); i++) - mesh.DeleteSurfaceElement (i); - - mesh.Compress(); - - cout << "retry Surface " << k << endl; - - k--; - projecttype*=-1; - notrys++; - continue; - } - else - { - geom.facemeshstatus[k-1] = -1; - PrintError ("Problem in Surface mesh generation"); - surfmesherror++; - // throw NgException ("Problem in Surface mesh generation"); - } - } - else - { - geom.facemeshstatus[k-1] = 1; - } - - notrys = 1; - - for (i = oldnf+1; i <= mesh.GetNSE(); i++) - mesh.SurfaceElement(i).SetIndex (k); - - } - - if (surfmesherror) - { - cout << "WARNING! NOT ALL FACES HAVED BEEN MESHED" << endl; - cout << "SURFACE MESHING ERROR OCCURED IN " << surfmesherror << " FACES:" << endl; - for (int i = 1; i <= geom.fmap.Extent(); i++) - if (geom.facemeshstatus[i-1] == -1) - cout << "Face " << i << endl; - cout << endl; - cout << "for more information open IGES/STEP Topology Explorer" << endl; - throw NgException ("Problem in Surface mesh generation"); - } - - - if (multithread.terminate || perfstepsend < MESHCONST_OPTSURFACE) - return; - - multithread.task = "Optimizing surface"; - - for (k = 1; k <= mesh.GetNFD(); k++) - { - (*testout) << "optimize face " << k << endl; - multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); - - FaceDescriptor & fd = mesh.GetFaceDescriptor(k); - - PrintMessage (1, "Optimize Surface ", k); - for (i = 1; i <= mparam.optsteps2d; i++) - { - if (multithread.terminate) return; - - { - MeshOptimize2dOCCSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.EdgeSwapping (mesh, (i > mparam.optsteps2d/2)); - } - - if (multithread.terminate) return; - { - MeshOptimize2dOCCSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.ImproveMesh (mesh); - } - - { - MeshOptimize2dOCCSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.CombineImprove (mesh); - } - - if (multithread.terminate) return; - { - MeshOptimize2dOCCSurfaces meshopt(geom); - meshopt.SetFaceIndex (k); - meshopt.SetImproveEdges (0); - meshopt.SetMetricWeight (0.2); - meshopt.SetWriteStatus (0); - - meshopt.ImproveMesh (mesh); - } - } - - } - - - mesh.CalcSurfacesOfNode(); - mesh.Compress(); - - multithread.task = savetask; -} - -double ComputeH (double kappa) -{ - double hret; - kappa *= mparam.curvaturesafety; - - if (mparam.maxh * kappa < 1) - hret = mparam.maxh; - else - hret = 1 / kappa; - - if (mparam.maxh < hret) - hret = mparam.maxh; - - return (hret); -} - - -class Line -{ -public: - Point<3> p0, p1; - double Dist (Line l) - { - Vec<3> n = p1-p0; - Vec<3> q = l.p1-l.p0; - double nq = n*q; - - Point<3> p = p0 + 0.5*n; - double lambda = (p-l.p0)*n / nq; - - if (lambda >= 0 && lambda <= 1) - { - double d = (p-l.p0-lambda*q).Length(); - // if (d < 1e-3) d = 1e99; - return d; - } - else - return 1e99; - } - - double Length () - { - return (p1-p0).Length(); - }; -}; - - - -void RestrictHTriangle (gp_Pnt2d & par0, gp_Pnt2d & par1, gp_Pnt2d & par2, - BRepLProp_SLProps * prop, Mesh & mesh, double maxside, int depth, double h = 0) -{ - gp_Pnt2d parmid; - - parmid.SetX(0.3*(par0.X()+par1.X()+par2.X())); - parmid.SetY(0.3*(par0.Y()+par1.Y()+par2.Y())); - - if (depth == 0) - { - prop->SetParameters (parmid.X(), parmid.Y()); - if (!prop->IsCurvatureDefined()) - { - (*testout) << "curvature not defined!" << endl; - return; - } - double curvature = max(fabs(prop->MinCurvature()), fabs(prop->MaxCurvature())); - if (curvature < 1e-3) - { - (*testout) << "curvature too small (" << curvature << ")!" << endl; - // return; - } - h = ComputeH (curvature+1e-10); - } - - if (h < maxside) - { - gp_Pnt2d pm0; - gp_Pnt2d pm1; - gp_Pnt2d pm2; - - pm0.SetX(0.5*(par1.X()+par2.X())); pm0.SetY(0.5*(par1.Y()+par2.Y())); - pm1.SetX(0.5*(par0.X()+par2.X())); pm1.SetY(0.5*(par0.Y()+par2.Y())); - pm2.SetX(0.5*(par1.X()+par0.X())); pm2.SetY(0.5*(par1.Y()+par0.Y())); - - RestrictHTriangle (pm0, pm1, pm2, prop, mesh, maxside/2, depth+1, h); - RestrictHTriangle (par0, pm1, pm2, prop, mesh, maxside/2, depth+1, h); - RestrictHTriangle (par1, pm0, pm2, prop, mesh, maxside/2, depth+1, h); - RestrictHTriangle (par2, pm1, pm0, prop, mesh, maxside/2, depth+1, h); - } - else - { - prop->SetParameters (parmid.X(), parmid.Y()); - gp_Pnt pnt = prop->Value(); - Point3d p3d(pnt.X(), pnt.Y(), pnt.Z()); - mesh.RestrictLocalH (p3d, h); - - prop->SetParameters (par0.X(), par0.Y()); - pnt = prop->Value(); - p3d = Point3d(pnt.X(), pnt.Y(), pnt.Z()); - mesh.RestrictLocalH (p3d, h); - - prop->SetParameters (par1.X(), par1.Y()); - pnt = prop->Value(); - p3d = Point3d(pnt.X(), pnt.Y(), pnt.Z()); - mesh.RestrictLocalH (p3d, h); - - prop->SetParameters (par2.X(), par2.Y()); - pnt = prop->Value(); - p3d = Point3d(pnt.X(), pnt.Y(), pnt.Z()); - mesh.RestrictLocalH (p3d, h); - - // (*testout) << "p = " << p3d << ", h = " << h << ", maxside = " << maxside << endl; - /* - (*testout) << pnt.X() << " " << pnt.Y() << " " << pnt.Z() << endl; - - prop->SetParameters (par0.X(), par0.Y()); - pnt = prop->Value(); - (*testout) << pnt.X() << " " << pnt.Y() << " " << pnt.Z() << endl; - - prop->SetParameters (par1.X(), par1.Y()); - pnt = prop->Value(); - (*testout) << pnt.X() << " " << pnt.Y() << " " << pnt.Z() << endl; - - prop->SetParameters (par2.X(), par2.Y()); - pnt = prop->Value(); - (*testout) << pnt.X() << " " << pnt.Y() << " " << pnt.Z() << endl; - */ - } -} - - - - -int OCCGenerateMesh (OCCGeometry & geom, - Mesh *& mesh, - int perfstepsstart, int perfstepsend, - char * optstr) -{ - int i, j; - - multithread.percent = 0; - - if (perfstepsstart <= MESHCONST_ANALYSE) - { - delete mesh; - mesh = new Mesh(); - - mesh->SetGlobalH (mparam.maxh); - - ARRAY<double> maxhdom; - maxhdom.SetSize (geom.NrSolids()); - maxhdom = mparam.maxh; - - mesh->SetMaxHDomain (maxhdom); - - Box<3> bb = geom.GetBoundingBox(); - bb.Increase (bb.Diam()/10); - - mesh->SetLocalH (bb.PMin(), bb.PMax(), 0.5); - - - if (mparam.uselocalh) - { - - char * savetask = multithread.task; - multithread.percent = 0; - - mesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); - - int nedges = geom.emap.Extent(); - int i; - - double maxedgelen = 0; - double minedgelen = 1e99; - - - multithread.task = "Setting local mesh size (elements per edge)"; - - // setting elements per edge - - for (i = 1; i <= nedges && !multithread.terminate; i++) - { - TopoDS_Edge e = TopoDS::Edge (geom.emap(i)); - multithread.percent = 100 * (i-1)/double(nedges); - if (BRep_Tool::Degenerated(e)) continue; - - GProp_GProps system; - BRepGProp::LinearProperties(e, system); - double len = system.Mass(); - - if (len < IGNORECURVELENGTH) - { - (*testout) << "ignored" << endl; - continue; - } - - - double localh = len/mparam.segmentsperedge; - double s0, s1; - Handle(Geom_Curve) c = BRep_Tool::Curve(e, s0, s1); - - maxedgelen = max (maxedgelen, len); - minedgelen = min (minedgelen, len); - - int j; - int maxj = (int) ceil (localh); - for (j = 0; j <= localh; j++) - { - gp_Pnt pnt = c->Value (s0+double(j)/maxj*(s1-s0)); - mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), localh); - } - } - - - - - multithread.task = "Setting local mesh size (edge curvature)"; - - - // setting edge curvature - - // int nsections = 10; - int nsections = 20; - - for (i = 1; i <= nedges && !multithread.terminate; i++) - { - multithread.percent = 100 * (i-1)/double(nedges); - TopoDS_Edge edge = TopoDS::Edge (geom.emap(i)); - if (BRep_Tool::Degenerated(edge)) continue; - double s0, s1; - Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); - BRepAdaptor_Curve brepc(edge); - BRepLProp_CLProps prop(brepc, 2, 1e-5); - - int j; - for (j = 1; j <= nsections; j++) - // for (j = 0; j < nsections; j++) - { - double s = s0 + j/(double) nsections * (s1-s0); - prop.SetParameter (s); - double curvature = prop.Curvature(); - - if (curvature >= 1e99) continue; - - gp_Pnt pnt = c->Value (s); - - mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), - ComputeH (fabs(curvature))); - } - } - - - - multithread.task = "Setting local mesh size (face curvature)"; - - // setting face curvature - - int nfaces = geom.fmap.Extent(); - - for (i = 1; i <= nfaces && !multithread.terminate; i++) - { - multithread.percent = 100 * (i-1)/double(nfaces); - TopoDS_Face face = TopoDS::Face(geom.fmap(i)); - TopLoc_Location loc; - Handle(Geom_Surface) surf = BRep_Tool::Surface (face); - Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); - if (triangulation.IsNull()) continue; - - BRepAdaptor_Surface sf(face, Standard_True); - BRepLProp_SLProps prop(sf, 2, 1e-5); - - int ntriangles = triangulation -> NbTriangles(); - for (j = 1; j <= ntriangles; j++) - { - int k; - gp_Pnt p[3]; - gp_Pnt2d par[3]; - - for (k = 1; k <=3; k++) - { - int n = triangulation->Triangles()(j)(k); - p[k-1] = triangulation->Nodes()(n).Transformed(loc); - par[k-1] = triangulation->UVNodes()(n); - } - - double maxside = 0; - maxside = max (maxside, p[0].Distance(p[1])); - maxside = max (maxside, p[0].Distance(p[2])); - maxside = max (maxside, p[1].Distance(p[2])); - - RestrictHTriangle (par[0], par[1], par[2], &prop, *mesh, maxside, 0); - } - } - - - - // setting close edges - - if (stlparam.resthcloseedgeenable) - { - multithread.task = "Setting local mesh size (close edges)"; - - int sections = 100; - - ARRAY<Line> lines(sections*nedges); - - Box3dTree* searchtree = - new Box3dTree (bb.PMin(), bb.PMax()); - - int nlines = 0; - for (int i = 1; i <= nedges && !multithread.terminate; i++) - { - TopoDS_Edge edge = TopoDS::Edge (geom.emap(i)); - if (BRep_Tool::Degenerated(edge)) continue; - - double s0, s1; - Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); - BRepAdaptor_Curve brepc(edge); - BRepLProp_CLProps prop(brepc, 1, 1e-5); - prop.SetParameter (s0); - - gp_Vec d0 = prop.D1().Normalized(); - double s_start = s0; - int count = 0; - for (int j = 1; j <= sections; j++) - { - double s = s0 + (s1-s0)*(double)j/(double)sections; - prop.SetParameter (s); - gp_Vec d1 = prop.D1().Normalized(); - double cosalpha = fabs(d0*d1); - if ((j == sections) || (cosalpha < cos(10.0/180.0*M_PI))) - { - count++; - gp_Pnt p0 = c->Value (s_start); - gp_Pnt p1 = c->Value (s); - lines[nlines].p0 = Point<3> (p0.X(), p0.Y(), p0.Z()); - lines[nlines].p1 = Point<3> (p1.X(), p1.Y(), p1.Z()); - - Box3d box; - box.SetPoint (Point3d(lines[nlines].p0)); - box.AddPoint (Point3d(lines[nlines].p1)); - - searchtree->Insert (box.PMin(), box.PMax(), nlines+1); - nlines++; - - s_start = s; - d0 = d1; - } - } - } - - ARRAY<int> linenums; - - for (int i = 0; i < nlines; i++) - { - multithread.percent = (100*i)/double(nlines); - Line & line = lines[i]; - - Box3d box; - box.SetPoint (Point3d(line.p0)); - box.AddPoint (Point3d(line.p1)); - double maxhline = max (mesh->GetH(box.PMin()), - mesh->GetH(box.PMax())); - box.Increase(maxhline); - - double mindist = 1e99; - linenums.SetSize(0); - searchtree->GetIntersecting(box.PMin(),box.PMax(),linenums); - - for (int j = 0; j < linenums.Size(); j++) - { - int num = linenums[j]-1; - if (i == num) continue; - if ((line.p0-lines[num].p0).Length2() < 1e-15) continue; - if ((line.p0-lines[num].p1).Length2() < 1e-15) continue; - if ((line.p1-lines[num].p0).Length2() < 1e-15) continue; - if ((line.p1-lines[num].p1).Length2() < 1e-15) continue; - mindist = min (mindist, line.Dist(lines[num])); - } - - mindist *= stlparam.resthcloseedgefac; - - if (mindist < 1e-3) - { - (*testout) << "extremely small local h: " << mindist - << " --> setting to 1e-3" << endl; - mindist = 1e-3; - } - - mesh->RestrictLocalHLine(line.p0, line.p1, mindist); - } - } - - - - multithread.task = savetask; - - } - } - - - if (multithread.terminate || perfstepsend <= MESHCONST_ANALYSE) - return TCL_OK; - - if (perfstepsstart <= MESHCONST_MESHEDGES) - { - FindEdges (geom, *mesh); - - /* - cout << "Removing redundant points" << endl; - - int i, j; - int np = mesh->GetNP(); - ARRAY<int> equalto; - - equalto.SetSize (np); - equalto = 0; - - for (i = 1; i <= np; i++) - { - for (j = i+1; j <= np; j++) - { - if (!equalto[j-1] && (Dist2 (mesh->Point(i), mesh->Point(j)) < 1e-12)) - equalto[j-1] = i; - } - } - - for (i = 1; i <= np; i++) - if (equalto[i-1]) - { - cout << "Point " << i << " is equal to Point " << equalto[i-1] << endl; - for (j = 1; j <= mesh->GetNSeg(); j++) - { - Segment & seg = mesh->LineSegment(j); - if (seg.p1 == i) seg.p1 = equalto[i-1]; - if (seg.p2 == i) seg.p2 = equalto[i-1]; - } - } - - cout << "Removing degenerated segments" << endl; - for (j = 1; j <= mesh->GetNSeg(); j++) - { - Segment & seg = mesh->LineSegment(j); - if (seg.p1 == seg.p2) - { - mesh->DeleteSegment(j); - cout << "Deleting Segment " << j << endl; - } - } - - mesh->Compress(); - */ - - /* - for (int i = 1; i <= geom.fmap.Extent(); i++) - { - Handle(Geom_Surface) hf1 = - BRep_Tool::Surface(TopoDS::Face(geom.fmap(i))); - for (int j = i+1; j <= geom.fmap.Extent(); j++) - { - Handle(Geom_Surface) hf2 = - BRep_Tool::Surface(TopoDS::Face(geom.fmap(j))); - if (hf1 == hf2) cout << "face " << i << " and face " << j << " lie on same surface" << endl; - } - } - */ - - - -#ifdef LOG_STREAM - (*logout) << "Edges meshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - } - - if (multithread.terminate || perfstepsend <= MESHCONST_MESHEDGES) - return TCL_OK; - - if (perfstepsstart <= MESHCONST_MESHSURFACE) - { - OCCMeshSurface (geom, *mesh, perfstepsend); - if (multithread.terminate) return TCL_OK; - -#ifdef LOG_STREAM - (*logout) << "Surfaces meshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - -#ifdef STAT_STREAM - (*statout) << mesh->GetNSeg() << " & " - << mesh->GetNSE() << " & - &" - << GetTime() << " & " << endl; -#endif - - // MeshQuality2d (*mesh); - mesh->CalcSurfacesOfNode(); - } - - if (multithread.terminate || perfstepsend <= MESHCONST_OPTSURFACE) - return TCL_OK; - - - if (perfstepsstart <= MESHCONST_MESHVOLUME) - { - multithread.task = "Volume meshing"; - - MESHING3_RESULT res = - MeshVolume (mparam, *mesh); - - if (res != MESHING3_OK) return TCL_ERROR; - - if (multithread.terminate) return TCL_OK; - - RemoveIllegalElements (*mesh); - if (multithread.terminate) return TCL_OK; - - MeshQuality3d (*mesh); - -#ifdef STAT_STREAM - (*statout) << GetTime() << " & "; -#endif - -#ifdef LOG_STREAM - (*logout) << "Volume meshed" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - } - - if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME) - return TCL_OK; - - - if (perfstepsstart <= MESHCONST_OPTVOLUME) - { - multithread.task = "Volume optimization"; - - OptimizeVolume (mparam, *mesh); - if (multithread.terminate) return TCL_OK; - -#ifdef STAT_STREAM - (*statout) << GetTime() << " & " - << mesh->GetNE() << " & " - << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; -#endif - -#ifdef LOG_STREAM - (*logout) << "Volume optimized" << endl - << "time = " << GetTime() << " sec" << endl - << "points: " << mesh->GetNP() << endl; -#endif - - - cout << "Optimization complete" << endl; - - } - - (*testout) << "NP: " << mesh->GetNP() << endl; - for (i = 1; i <= mesh->GetNP(); i++) - (*testout) << mesh->Point(i) << endl; - - (*testout) << endl << "NSegments: " << mesh->GetNSeg() << endl; - for (i = 1; i <= mesh->GetNSeg(); i++) - (*testout) << mesh->LineSegment(i) << endl; - - - - return TCL_OK; -} -} - -#endif diff --git a/Netgen/libsrc/occ/occgeom.cpp b/Netgen/libsrc/occ/occgeom.cpp deleted file mode 100644 index e24f52fa0a..0000000000 --- a/Netgen/libsrc/occ/occgeom.cpp +++ /dev/null @@ -1,1102 +0,0 @@ -#ifdef OCCGEOMETRY - -#include <mystdlib.h> -#include <occgeom.hpp> -#include "ShapeAnalysis_ShapeTolerance.hxx" -#include "ShapeAnalysis_ShapeContents.hxx" -#include "ShapeAnalysis_CheckSmallFace.hxx" -#include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx" -#include "BRepAlgoAPI_Fuse.hxx" -#include "BRepCheck_Analyzer.hxx" -#include "BRepLib.hxx" -#include "ShapeBuild_ReShape.hxx" -#include "ShapeFix.hxx" -#include "ShapeFix_FixSmallFace.hxx" - - -namespace netgen -{ - -void OCCGeometry :: PrintNrShapes () -{ - TopExp_Explorer e; - int count = 0; - for (e.Init(shape, TopAbs_COMPSOLID); e.More(); e.Next()) count++; - cout << "CompSolids: " << count << endl; - - cout << "Solids : " << somap.Extent() << endl; - cout << "Shells : " << shmap.Extent() << endl; - cout << "Faces : " << fmap.Extent() << endl; - cout << "Edges : " << emap.Extent() << endl; - cout << "Vertices : " << vmap.Extent() << endl; -} - - -void PrintContents (OCCGeometry * geom) -{ - ShapeAnalysis_ShapeContents cont; - cont.Clear(); - cont.Perform(geom->shape); - - (*testout) << "OCC CONTENTS" << endl; - (*testout) << "============" << endl; - (*testout) << "SOLIDS : " << cont.NbSolids() << endl; - (*testout) << "SHELLS : " << cont.NbShells() << endl; - (*testout) << "FACES : " << cont.NbFaces() << endl; - (*testout) << "WIRES : " << cont.NbWires() << endl; - (*testout) << "EDGES : " << cont.NbEdges() << endl; - (*testout) << "VERTICES : " << cont.NbVertices() << endl; - - TopExp_Explorer e; - int count = 0; - for (e.Init(geom->shape, TopAbs_COMPOUND); e.More(); e.Next()) - count++; - (*testout) << "Compounds: " << count << endl; - - count = 0; - for (e.Init(geom->shape, TopAbs_COMPSOLID); e.More(); e.Next()) - count++; - (*testout) << "CompSolids: " << count << endl; - - (*testout) << endl; - - cout << "Highest entry in topology hierarchy: " << endl; - if (count) - cout << count << " composite solid(s)" << endl; - else - if (geom->somap.Extent()) - cout << geom->somap.Extent() << " solid(s)" << endl; - else - if (geom->shmap.Extent()) - cout << geom->shmap.Extent() << " shells(s)" << endl; - else - if (geom->fmap.Extent()) - cout << geom->fmap.Extent() << " face(s)" << endl; - else - if (geom->wmap.Extent()) - cout << geom->wmap.Extent() << " wire(s)" << endl; - else - if (geom->emap.Extent()) - cout << geom->emap.Extent() << " edge(s)" << endl; - else - if (geom->vmap.Extent()) - cout << geom->vmap.Extent() << " vertices(s)" << endl; - else - cout << "no entities" << endl; - -} - - - -void OCCGeometry :: HealGeometry () -{ - int nrc = 0, nrcs = 0, - nrso = somap.Extent(), - nrsh = shmap.Extent(), - nrf = fmap.Extent(), - nrw = wmap.Extent(), - nre = emap.Extent(), - nrv = vmap.Extent(); - - TopExp_Explorer e; - for (e.Init(shape, TopAbs_COMPOUND); e.More(); e.Next()) nrc++; - for (e.Init(shape, TopAbs_COMPSOLID); e.More(); e.Next()) nrcs++; - - double surfacecont = 0; - - for (int i = 1; i <= fmap.Extent(); i++) - { - GProp_GProps system; - BRepGProp::LinearProperties(fmap(i), system); - surfacecont += system.Mass(); - } - - cout << "Starting geometry healing procedure (tolerance: " << tolerance << ")" << endl - << "-----------------------------------" << endl; - - if (fixsmalledges) - { - cout << endl << "- fixing small edges" << endl; - - Handle(ShapeFix_Wire) sfw; - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(shape); - - for (int i = 1; i <= fmap.Extent(); i++) - { - TopExp_Explorer exp1; - for (exp1.Init (fmap(i), TopAbs_WIRE); exp1.More(); exp1.Next()) - { - TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current()); - sfw = new ShapeFix_Wire (oldwire, TopoDS::Face(fmap(i)),tolerance); - sfw->ModifyTopologyMode() = Standard_True; - - if (sfw->FixSmall (false, tolerance)) - { - cout << "Fixed small edge in wire " << wmap.FindIndex (oldwire) << endl; - TopoDS_Wire newwire = sfw->Wire(); - rebuild->Replace(oldwire, newwire, Standard_False); - } - if ((sfw->StatusSmall(ShapeExtend_FAIL1)) || - (sfw->StatusSmall(ShapeExtend_FAIL2)) || - (sfw->StatusSmall(ShapeExtend_FAIL3))) - cout << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) << endl; - - - } - } - - shape = rebuild->Apply(shape); - - - - { - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - rebuild->Apply(shape); - TopExp_Explorer exp1; - for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); - if (vmap.FindIndex(TopExp::FirstVertex (edge)) == - vmap.FindIndex(TopExp::LastVertex (edge))) - { - GProp_GProps system; - BRepGProp::LinearProperties(edge, system); - if (system.Mass() < tolerance) - { - cout << "removing degenerated edge " << emap.FindIndex(edge) << endl; - rebuild->Remove(edge, false); - } - } - } - shape = rebuild->Apply(shape); - } - - - Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe; - sfwf->SetPrecision(tolerance); - sfwf->Load (shape); - - if (sfwf->FixSmallEdges()) - { - cout << endl << "- fixing wire frames" << endl; - if (sfwf->StatusSmallEdges(ShapeExtend_OK)) cout << "no small edges found" << endl; - if (sfwf->StatusSmallEdges(ShapeExtend_DONE1)) cout << "some small edges fixed" << endl; - if (sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) cout << "failed to fix some small edges" << endl; - } - - - if (sfwf->FixWireGaps()) - { - cout << endl << "- fixing wire gaps" << endl; - if (sfwf->StatusWireGaps(ShapeExtend_OK)) cout << "no gaps found" << endl; - if (sfwf->StatusWireGaps(ShapeExtend_DONE1)) cout << "some 2D gaps fixed" << endl; - if (sfwf->StatusWireGaps(ShapeExtend_DONE2)) cout << "some 3D gaps fixed" << endl; - if (sfwf->StatusWireGaps(ShapeExtend_FAIL1)) cout << "failed to fix some 2D gaps" << endl; - if (sfwf->StatusWireGaps(ShapeExtend_FAIL2)) cout << "failed to fix some 3D gaps" << endl; - } - - - shape = sfwf->Shape(); - } - - - - - - if (fixspotstripfaces) - { - - cout << endl << "- fixing spot and strip faces" << endl; - Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace(); - sffsm -> Init (shape); - sffsm -> SetPrecision (tolerance); - sffsm -> Perform(); - - shape = sffsm -> FixShape(); - } - - if (sewfaces) - { - cout << endl << "- sewing faces" << endl; - - TopExp_Explorer exp0; - - BRepOffsetAPI_Sewing sewedObj(tolerance); - - for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) - { - TopoDS_Face face = TopoDS::Face (exp0.Current()); - sewedObj.Add (face); - } - - sewedObj.Perform(); - - if (!sewedObj.SewedShape().IsNull()) - shape = sewedObj.SewedShape(); - else - cout << " not possible"; - } - - if (makesolids) - { - cout << endl << "- making solids" << endl; - - TopExp_Explorer exp0; - - BRepBuilderAPI_MakeSolid ms; - int count = 0; - for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()) - { - count++; - ms.Add (TopoDS::Shell(exp0.Current())); - } - - if (!count) - { - cout << " not possible (no shells)" << endl; - } - else - { - BRepCheck_Analyzer ba(ms); - if (ba.IsValid ()) - { - Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; - sfs->Init (ms); - sfs->SetPrecision(tolerance); - sfs->SetMaxTolerance(tolerance); - sfs->Perform(); - shape = sfs->Shape(); - - for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); - TopoDS_Solid newsolid = solid; - BRepLib::OrientClosedSolid (newsolid); - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - // rebuild->Apply(shape); - rebuild->Replace(solid, newsolid, Standard_False); - TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_COMPSOLID, 1); - // TopoDS_Shape newshape = rebuild->Apply(shape); - shape = newshape; - } - } - else - cout << " not possible" << endl; - } - } - - BuildFMap(); - - double newsurfacecont = 0; - - for (int i = 1; i <= fmap.Extent(); i++) - { - GProp_GProps system; - BRepGProp::LinearProperties(fmap(i), system); - newsurfacecont += system.Mass(); - } - - int nnrc = 0, nnrcs = 0, - nnrso = somap.Extent(), - nnrsh = shmap.Extent(), - nnrf = fmap.Extent(), - nnrw = wmap.Extent(), - nnre = emap.Extent(), - nnrv = vmap.Extent(); - - for (e.Init(shape, TopAbs_COMPOUND); e.More(); e.Next()) nnrc++; - for (e.Init(shape, TopAbs_COMPSOLID); e.More(); e.Next()) nnrcs++; - - cout << "-----------------------------------" << endl; - cout << "Compounds : " << nnrc << " (" << nrc << ")" << endl; - cout << "Composite solids: " << nnrcs << " (" << nrcs << ")" << endl; - cout << "Solids : " << nnrso << " (" << nrso << ")" << endl; - cout << "Shells : " << nnrsh << " (" << nrsh << ")" << endl; - cout << "Wires : " << nnrw << " (" << nrw << ")" << endl; - cout << "Faces : " << nnrf << " (" << nrf << ")" << endl; - cout << "Edges : " << nnre << " (" << nre << ")" << endl; - cout << "Vertices : " << nnrv << " (" << nrv << ")" << endl; - cout << endl; - cout << "Totol surface area : " << newsurfacecont << " (" << surfacecont << ")" << endl; - cout << endl; - -} - - - - -void OCCGeometry :: BuildFMap() -{ - somap.Clear(); - shmap.Clear(); - fmap.Clear(); - wmap.Clear(); - emap.Clear(); - vmap.Clear(); - - TopExp_Explorer exp0, exp1, exp2, exp3, exp4, exp5; - - for (exp0.Init(shape, TopAbs_SOLID); - exp0.More(); exp0.Next()) - { - TopoDS_Solid solid = TopoDS::Solid (exp0.Current()); - - if (somap.FindIndex(TopoDS::Solid (exp0.Current())) < 1) - { - somap.Add (TopoDS::Solid (exp0.Current())); - - for (exp1.Init(exp0.Current(), TopAbs_SHELL); - exp1.More(); exp1.Next()) - { - TopoDS_Shell shell = TopoDS::Shell (exp1.Current().Composed (exp0.Current().Orientation())); - if (shmap.FindIndex(shell) < 1) - { - shmap.Add (shell); - - for (exp2.Init(shell, TopAbs_FACE); - exp2.More(); exp2.Next()) - { - TopoDS_Face face = TopoDS::Face(exp2.Current().Composed(shell.Orientation())); - if (fmap.FindIndex(face) < 1) - { - fmap.Add (face); - - for (exp3.Init(exp2.Current(), TopAbs_WIRE); - exp3.More(); exp3.Next()) - { - TopoDS_Wire wire = TopoDS::Wire (exp3.Current().Composed(face.Orientation())); - if (wmap.FindIndex(wire) < 1) - { - wmap.Add (wire); - - for (exp4.Init(exp3.Current(), TopAbs_EDGE); - exp4.More(); exp4.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp4.Current().Composed(wire.Orientation())); - if (emap.FindIndex(edge) < 1) - { - emap.Add (edge); - for (exp5.Init(exp4.Current(), TopAbs_VERTEX); - exp5.More(); exp5.Next()) - { - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if (vmap.FindIndex(vertex) < 1) - vmap.Add (vertex); - } - } - } - } - } - } - } - } - } - } - } - - // Free Shells - for (exp1.Init(exp0.Current(), TopAbs_SHELL, TopAbs_SOLID); - exp1.More(); exp1.Next()) - { - TopoDS_Shape shell = exp1.Current().Composed (exp0.Current().Orientation()); - if (shmap.FindIndex(shell) < 1) - { - shmap.Add (shell); - - for (exp2.Init(shell, TopAbs_FACE); - exp2.More(); exp2.Next()) - { - TopoDS_Face face = TopoDS::Face(exp2.Current().Composed(shell.Orientation())); - if (fmap.FindIndex(face) < 1) - { - fmap.Add (face); - - for (exp3.Init(exp2.Current(), TopAbs_WIRE); - exp3.More(); exp3.Next()) - { - TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); - if (wmap.FindIndex(wire) < 1) - { - wmap.Add (wire); - - for (exp4.Init(exp3.Current(), TopAbs_EDGE); - exp4.More(); exp4.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); - if (emap.FindIndex(edge) < 1) - { - emap.Add (edge); - for (exp5.Init(exp4.Current(), TopAbs_VERTEX); - exp5.More(); exp5.Next()) - { - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if (vmap.FindIndex(vertex) < 1) - vmap.Add (vertex); - } - } - } - } - } - } - } - } - } - - - // Free Faces - - for (exp2.Init(shape, TopAbs_FACE, TopAbs_SHELL); - exp2.More(); exp2.Next()) - { - TopoDS_Face face = TopoDS::Face(exp2.Current()); - if (fmap.FindIndex(face) < 1) - { - fmap.Add (face); - - for (exp3.Init(exp2.Current(), TopAbs_WIRE); - exp3.More(); exp3.Next()) - { - TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); - if (wmap.FindIndex(wire) < 1) - { - wmap.Add (wire); - - for (exp4.Init(exp3.Current(), TopAbs_EDGE); - exp4.More(); exp4.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); - if (emap.FindIndex(edge) < 1) - { - emap.Add (edge); - for (exp5.Init(exp4.Current(), TopAbs_VERTEX); - exp5.More(); exp5.Next()) - { - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if (vmap.FindIndex(vertex) < 1) - vmap.Add (vertex); - } - } - } - } - } - } - } - - - // Free Wires - - for (exp3.Init(shape, TopAbs_WIRE, TopAbs_FACE); - exp3.More(); exp3.Next()) - { - TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); - if (wmap.FindIndex(wire) < 1) - { - wmap.Add (wire); - - for (exp4.Init(exp3.Current(), TopAbs_EDGE); - exp4.More(); exp4.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); - if (emap.FindIndex(edge) < 1) - { - emap.Add (edge); - for (exp5.Init(exp4.Current(), TopAbs_VERTEX); - exp5.More(); exp5.Next()) - { - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if (vmap.FindIndex(vertex) < 1) - vmap.Add (vertex); - } - } - } - } - } - - - // Free Edges - - for (exp4.Init(shape, TopAbs_EDGE, TopAbs_WIRE); - exp4.More(); exp4.Next()) - { - TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); - if (emap.FindIndex(edge) < 1) - { - emap.Add (edge); - for (exp5.Init(exp4.Current(), TopAbs_VERTEX); - exp5.More(); exp5.Next()) - { - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if (vmap.FindIndex(vertex) < 1) - vmap.Add (vertex); - } - } - } - - - // Free Vertices - - for (exp5.Init(shape, TopAbs_VERTEX, TopAbs_EDGE); - exp5.More(); exp5.Next()) - { - TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); - if (vmap.FindIndex(vertex) < 1) - vmap.Add (vertex); - } - - - - - facemeshstatus.SetSize (fmap.Extent()); - facemeshstatus = 0; - - fvispar.SetSize (fmap.Extent()); - evispar.SetSize (emap.Extent()); - vvispar.SetSize (vmap.Extent()); -} - - - -void OCCGeometry :: SewFaces () -{ - (*testout) << "Trying to sew faces ..." << endl; - cout << "Trying to sew faces ..." << flush; - - BRepOffsetAPI_Sewing sewedObj(1); - // BRepOffsetAPI_Sewing sewedObj(healingtolerance); - - for (int i = 1; i <= fmap.Extent(); i++) - { - TopoDS_Face face = TopoDS::Face (fmap(i)); - sewedObj.Add (face); - } - - sewedObj.Perform(); - - if (!sewedObj.SewedShape().IsNull()) - { - shape = sewedObj.SewedShape(); - cout << " done" << endl; - } - else - cout << " not possible"; - - /* - ShapeUpgrade_ShellSewing sewing; - TopoDS_Shape sh = sewing.ApplySewing (shape); - shape = sh; - */ -} - - - - - -void OCCGeometry :: MakeSolid () -{ - TopExp_Explorer exp0; - - (*testout) << "Trying to build solids ..." << endl; - cout << "Trying to build solids ..." << flush; - - BRepBuilderAPI_MakeSolid ms; - int count = 0; - for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()) - { - count++; - ms.Add (TopoDS::Shell(exp0.Current())); - } - - if (!count) - { - cout << " not possible (no shells)" << endl; - return; - } - - BRepCheck_Analyzer ba(ms); - if (ba.IsValid ()) - { - Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; - sfs->Init (ms); - - sfs->SetPrecision(1e-5); - sfs->SetMaxTolerance(1e-5); - - sfs->Perform(); - - shape = sfs->Shape(); - - for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); - TopoDS_Solid newsolid = solid; - BRepLib::OrientClosedSolid (newsolid); - Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; - // rebuild->Apply(shape); - rebuild->Replace(solid, newsolid, Standard_False); - // TopoDS_Shape newshape = rebuild->Apply(shape); - - TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_SHAPE, 1); - shape = newshape; - } - - cout << " done" << endl; - } - else - cout << " not possible" << endl; -} - - -void OCCGeometry :: BuildVisualizationMesh () -{ - cout << "Preparing visualization (deflection = " << vispar.occdeflection << ") ... " << flush; - BRepTools::Clean (shape); - BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (shape, vispar.occdeflection, true); - cout << "done" << endl; - - Bnd_Box bb; - BRepBndLib::Add (shape, bb); - - double x1,y1,z1,x2,y2,z2; - bb.Get (x1,y1,z1,x2,y2,z2); - Point<3> p1 = Point<3> (x1,y1,z1); - Point<3> p2 = Point<3> (x2,y2,z2); - - (*testout) << "Bounding Box = [" << p1 << " - " << p2 << "]" << endl; - boundingbox = Box<3> (p1,p2); - SetCenter(); -} - - - - bool OCCGeometry :: FastProject (int surfi, Point<3> & ap, double& u, double& v) const - { - gp_Pnt p(ap(0), ap(1), ap(2)); - - Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); - - gp_Pnt x = surface->Value (u,v); - - if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true; - - gp_Vec du, dv; - - surface->D1(u,v,x,du,dv); - - int count = 0; - - gp_Pnt xold; - gp_Vec n; - double det, lambda, mu; - - do { - count++; - - n = du^dv; - - det = Det3 (n.X(), du.X(), dv.X(), - n.Y(), du.Y(), dv.Y(), - n.Z(), du.Z(), dv.Z()); - - if (det < 1e-15) return false; - - lambda = Det3 (n.X(), p.X()-x.X(), dv.X(), - n.Y(), p.Y()-x.Y(), dv.Y(), - n.Z(), p.Z()-x.Z(), dv.Z())/det; - - mu = Det3 (n.X(), du.X(), p.X()-x.X(), - n.Y(), du.Y(), p.Y()-x.Y(), - n.Z(), du.Z(), p.Z()-x.Z())/det; - - u += lambda; - v += mu; - - xold = x; - surface->D1(u,v,x,du,dv); - - } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) && count < 50); - -// (*testout) << "FastProject count: " << count << endl; - - if (count == 50) return false; - - ap = Point<3> (x.X(), x.Y(), x.Z()); - - return true; - } - - -OCCGeometry * LoadOCC_IGES (const char * filename) -{ - OCCGeometry * occgeo; - occgeo = new OCCGeometry; - - IGESControl_Reader reader; - -#ifdef OCC52 - Standard_Integer stat = reader.ReadFile((char*)filename); -#else - Standard_Integer stat = reader.LoadFile((char*)filename); - reader.Clear(); -#endif - -#ifdef OCC52 - reader.TransferRoots(); // Tranlate IGES -> OCC -#else - reader.TransferRoots(Standard_False); // Tranlate IGES -> OCC -#endif - - occgeo->shape = reader.OneShape(); - occgeo->changed = 1; - occgeo->BuildFMap(); - occgeo->BuildVisualizationMesh(); - PrintContents (occgeo); - - return occgeo; -} - -OCCGeometry * LoadOCC_STEP (const char * filename) -{ - OCCGeometry * occgeo; - occgeo = new OCCGeometry; - - STEPControl_Reader reader; - Standard_Integer stat = reader.ReadFile((char*)filename); - Standard_Integer nb = reader.NbRootsForTransfer(); - reader.TransferRoots (); // Tranlate STEP -> OCC - occgeo->shape = reader.OneShape(); - occgeo->changed = 1; - occgeo->BuildFMap(); - occgeo->BuildVisualizationMesh(); - PrintContents (occgeo); - - return occgeo; -} - -char * shapesname[] = - {" ", "CompSolids", "Solids", "Shells", - "Faces", "Wires", "Edges", "Vertices"}; - -char * shapename[] = - {" ", "CompSolid", "Solid", "Shell", - "Face", "Wire", "Edge", "Vertex"}; - -char * orientationstring[] = - {"+", "-"}; - -void OCCGeometry :: RecursiveTopologyTree (const TopoDS_Shape & sh, - stringstream & str, - TopAbs_ShapeEnum l, - bool isfree, - const char * lname) -{ - if (l > TopAbs_VERTEX) return; - - TopExp_Explorer e; - int count = 0; - int count2; - - if (isfree) - e.Init(sh, l, TopAbs_ShapeEnum(l-1)); - else - e.Init(sh, l); - - for (; e.More(); e.Next()) - { - count++; - - stringstream lname2; - lname2 << lname << "/" << shapename[l] << count; - str << lname2.str() << " "; - - switch (e.Current().ShapeType()) - { - case TopAbs_SOLID: - count2 = somap.FindIndex(TopoDS::Solid(e.Current())); break; - case TopAbs_SHELL: - count2 = shmap.FindIndex(TopoDS::Shell(e.Current())); break; - case TopAbs_FACE: - count2 = fmap.FindIndex(TopoDS::Face(e.Current())); break; - case TopAbs_WIRE: - count2 = wmap.FindIndex(TopoDS::Wire(e.Current())); break; - case TopAbs_EDGE: - count2 = emap.FindIndex(TopoDS::Edge(e.Current())); break; - case TopAbs_VERTEX: - count2 = vmap.FindIndex(TopoDS::Vertex(e.Current())); break; - } - - int nrsubshapes = 0; - - if (l <= TopAbs_WIRE) - { - TopExp_Explorer e2; - for (e2.Init (e.Current(), TopAbs_ShapeEnum (l+1)); - e2.More(); e2.Next()) - nrsubshapes++; - } - - str << "{" << shapename[l] << " " << count2; - - if (l <= TopAbs_EDGE) - { - str << " (" << orientationstring[e.Current().Orientation()]; - if (nrsubshapes != 0) str << ", " << nrsubshapes; - str << ") } "; - } - else - str << " } "; - - RecursiveTopologyTree (e.Current(), str, TopAbs_ShapeEnum (l+1), - false, (char*)lname2.str().c_str()); - - } -} - -void OCCGeometry :: GetTopologyTree (stringstream & str) -{ - cout << "Building topology tree ... " << flush; - RecursiveTopologyTree (shape, str, TopAbs_COMPSOLID, false, "CompSolids"); - RecursiveTopologyTree (shape, str, TopAbs_SOLID, true, "FreeSolids"); - RecursiveTopologyTree (shape, str, TopAbs_SHELL, true, "FreeShells"); - RecursiveTopologyTree (shape, str, TopAbs_FACE, true, "FreeFaces"); - RecursiveTopologyTree (shape, str, TopAbs_WIRE, true, "FreeWires"); - RecursiveTopologyTree (shape, str, TopAbs_EDGE, true, "FreeEdges"); - RecursiveTopologyTree (shape, str, TopAbs_VERTEX, true, "FreeVertices"); - str << flush; - // cout << "done" << endl; -} - -void OCCGeometry :: CheckIrregularEntities(stringstream & str) -{ - ShapeAnalysis_CheckSmallFace csm; - - csm.SetTolerance (1e-6); - - TopTools_DataMapOfShapeListOfShape mapEdges; - ShapeAnalysis_DataMapOfShapeListOfReal mapParam; - TopoDS_Compound theAllVert; - - int spotfaces = 0; - int stripsupportfaces = 0; - int singlestripfaces = 0; - int stripfaces = 0; - int facessplitbyvertices = 0; - int stretchedpinfaces = 0; - int smoothpinfaces = 0; - int twistedfaces = 0; - int edgessamebutnotidentified = 0; - - cout << "checking faces ... " << flush; - - int i; - for (i = 1; i <= fmap.Extent(); i++) - { - TopoDS_Face face = TopoDS::Face (fmap(i)); - TopoDS_Edge e1, e2; - - if (csm.CheckSpotFace (face)) - { - if (!spotfaces++) - str << "SpotFace {Spot face} "; - - (*testout) << "Face " << i << " is a spot face" << endl; - str << "SpotFace/Face" << i << " "; - str << "{Face " << i << " } "; - } - - if (csm.IsStripSupport (face)) - { - if (!stripsupportfaces++) - str << "StripSupportFace {Strip support face} "; - - (*testout) << "Face " << i << " has strip support" << endl; - str << "StripSupportFace/Face" << i << " "; - str << "{Face " << i << " } "; - } - - if (csm.CheckSingleStrip(face, e1, e2)) - { - if (!singlestripfaces++) - str << "SingleStripFace {Single strip face} "; - - (*testout) << "Face " << i << " is a single strip (edge " << emap.FindIndex(e1) - << " and edge " << emap.FindIndex(e2) << " are identical)" << endl; - str << "SingleStripFace/Face" << i << " "; - str << "{Face " << i << " (edge " << emap.FindIndex(e1) - << " and edge " << emap.FindIndex(e2) << " are identical)} "; - } - - if (csm.CheckStripFace(face, e1, e2)) - { - if (!stripfaces++) - str << "StripFace {Strip face} "; - - (*testout) << "Face " << i << " is a strip (edge " << emap.FindIndex(e1) - << " and edge " << emap.FindIndex(e2) - << " are identical)" << endl; - str << "StripFace/Face" << i << " "; - str << "{Face " << i << " (edge " << emap.FindIndex(e1) - << " and edge " << emap.FindIndex(e2) << " are identical)} "; - } - - if (int count = csm.CheckSplittingVertices(face, mapEdges, mapParam, theAllVert)) - { - if (!facessplitbyvertices++) - str << "FaceSplitByVertices {Face split by vertices} "; - - (*testout) << "Face " << i << " is split by " << count - << " vertex/vertices " << endl; - str << "FaceSplitByVertices/Face" << i << " "; - str << "{Face " << i << " (split by " << count << "vertex/vertices)} "; - } - - int whatrow, sens; - if (int type = csm.CheckPin (face, whatrow, sens)) - { - if (type == 1) - { - if (!smoothpinfaces++) - str << "SmoothPinFace {Smooth pin face} "; - - (*testout) << "Face " << i << " is a smooth pin" << endl; - str << "SmoothPinFace/Face" << i << " "; - str << "{Face " << i << " } "; - } - else - { - if (!stretchedpinfaces++) - str << "StretchedPinFace {Stretched pin face} "; - - (*testout) << "Face " << i << " is a streched pin" << endl; - str << "StretchedPinFace/Face" << i << " "; - str << "{Face " << i << " } "; - } - } - - double paramu, paramv; - if (csm.CheckTwisted (face, paramu, paramv)) - { - if (!twistedfaces++) - str << "TwistedFace {Twisted face} "; - - (*testout) << "Face " << i << " is twisted" << endl; - str << "TwistedFace/Face" << i << " "; - str << "{Face " << i << " } "; - } - } - - cout << "done" << endl; - cout << "checking edges ... " << flush; - - double dmax; - int cnt = 0; - ARRAY <double> edgeLengths; - ARRAY <int> order; - edgeLengths.SetSize (emap.Extent()); - order.SetSize (emap.Extent()); - - for (i = 1; i <= emap.Extent(); i++) - { - TopoDS_Edge edge1 = TopoDS::Edge (emap(i)); - GProp_GProps system; - BRepGProp::LinearProperties(edge1, system); - edgeLengths[i-1] = system.Mass(); - /* - int j; - for (j = i+1; j <= emap.Extent(); j++) - { - TopoDS_Edge edge2 = TopoDS::Edge (emap(j)); - - if (csm.CheckStripEdges(edge1, edge2, csm.Tolerance(), dmax)) - { - if (!edgessamebutnotidentified++) - str << "EdgesSameButNotIdentified {Edges same but not identified} "; - - cnt++; - (*testout) << "Edge " << i << " and edge " << j - << " are on one strip (same but not identified)" << endl; - str << "EdgesSameButNotIdentified/Edge" << cnt << " "; - str << "{Edge " << i << " and Edge " << j << "} "; - } - } - */ - } - - Sort (edgeLengths, order); - - str << "ShortestEdges {Shortest edges} "; - for (i = 1; i <= min(20, emap.Extent()); i++) - { - str << "ShortestEdges/Edge" << i; - str << " {Edge " << order[i-1] << " (L=" << edgeLengths[order[i-1]-1] << ")} "; - } - - str << flush; - - cout << "done" << endl; - - /* - for (i = 1; i <= shmap.Extent(); i++) - { - TopoDS_Shell shell = TopoDS::Shell (shmap(i)); - if (!shell.Closed()) - cout << "Shell " << i << " is not closed" << endl; - if (shell.Infinite()) - cout << "Shell " << i << " is infinite" << endl; - - BRepCheck_Analyzer ba(shell); - if (!ba.IsValid ()) - cout << "Shell " << i << " is not valid" << endl; - } - - for (i = 1; i <= somap.Extent(); i++) - { - TopoDS_Solid solid = TopoDS::Solid (somap(i)); - if (!solid.Closed()) - cout << "Solid " << i << " is not closed" << endl; - if (solid.Infinite()) - cout << "Solid " << i << " is infinite" << endl; - - BRepCheck_Analyzer ba(solid); - if (!ba.IsValid ()) - cout << "Solid " << i << " is not valid" << endl; - } - */ - - -} - - -void OCCGeometry :: GetUnmeshedFaceInfo (stringstream & str) -{ - for (int i = 1; i <= fmap.Extent(); i++) - { - if (facemeshstatus[i-1] == -1) - str << "Face" << i << " {Face " << i << " } "; - } - str << flush; -} - -void OCCGeometry :: GetNotDrawableFaces (stringstream & str) -{ - for (int i = 1; i <= fmap.Extent(); i++) - { - if (!fvispar[i-1].IsDrawable()) - str << "Face" << i << " {Face " << i << " } "; - } - str << flush; -} - -bool OCCGeometry :: ErrorInSurfaceMeshing () -{ - for (int i = 1; i <= fmap.Extent(); i++) - if (facemeshstatus[i-1] == -1) - return true; - - return false; -} - -} - - -#endif diff --git a/Netgen/libsrc/occ/occgeom.hpp b/Netgen/libsrc/occ/occgeom.hpp deleted file mode 100644 index 5082ab3b91..0000000000 --- a/Netgen/libsrc/occ/occgeom.hpp +++ /dev/null @@ -1,279 +0,0 @@ -#ifndef FILE_OCCGEOM -#define FILE_OCCGEOM - -/* *************************************************************************/ -/* File: occgeom.hpp */ -/* Author: Robert Gaisbauer */ -/* Date: 26. May 03 */ -/* *************************************************************************/ - -#ifdef OCCGEOMETRY - -#include <meshing.hpp> - -#include "BRep_Tool.hxx" -#include "Geom_Curve.hxx" -#include "Geom2d_Curve.hxx" -#include "Geom_Surface.hxx" -#include "GeomAPI_ProjectPointOnSurf.hxx" -#include "GeomAPI_ProjectPointOnCurve.hxx" -#include "BRepTools.hxx" -#include "TopExp.hxx" -#include "BRepBuilderAPI_MakeVertex.hxx" -#include "BRepBuilderAPI_MakeShell.hxx" -#include "BRepBuilderAPI_MakeSolid.hxx" -#include "BRepOffsetAPI_Sewing.hxx" -#include "BRepLProp_SLProps.hxx" -#include "BRepAdaptor_Surface.hxx" -#include "Poly_Triangulation.hxx" -#include "Poly_Array1OfTriangle.hxx" -#include "TColgp_Array1OfPnt2d.hxx" -#include "Poly_Triangle.hxx" -#include "GProp_GProps.hxx" -#include "BRepGProp.hxx" -#include "Geom_Surface.hxx" -#include "TopExp.hxx" -#include "gp_Pnt.hxx" -#include "TopoDS.hxx" -#include "TopoDS_Solid.hxx" -#include "TopExp_Explorer.hxx" -#include "BRep_Tool.hxx" -#include "Geom_Curve.hxx" -#include "Geom2d_Curve.hxx" -#include "Geom_Surface.hxx" -#include "GeomAPI_ProjectPointOnSurf.hxx" -#include "GeomAPI_ProjectPointOnCurve.hxx" -#include "TopoDS_Wire.hxx" -#include "BRepTools_WireExplorer.hxx" -#include "BRepTools.hxx" -#include "TopTools_IndexedMapOfShape.hxx" -#include "TopExp.hxx" -#include "BRepBuilderAPI_MakeVertex.hxx" -#include "BRepBuilderAPI_MakeShell.hxx" -#include "BRepBuilderAPI_MakeSolid.hxx" -#include "BRepOffsetAPI_Sewing.hxx" -#include "BRepLProp_CLProps.hxx" -#include "BRepLProp_SLProps.hxx" -#include "BRepAdaptor_Surface.hxx" -#include "BRepAdaptor_Curve.hxx" -#include "Poly_Triangulation.hxx" -#include "Poly_Array1OfTriangle.hxx" -#include "TColgp_Array1OfPnt2d.hxx" -#include "Poly_Triangle.hxx" -#include "GProp_GProps.hxx" -#include "BRepGProp.hxx" -#include "IGESControl_Reader.hxx" -#include "STEPControl_Reader.hxx" -#include "TopoDS_Shape.hxx" -#include "TopoDS_Face.hxx" -#include "IGESToBRep_Reader.hxx" -#include "Interface_Static.hxx" -#include "GeomAPI_ExtremaCurveCurve.hxx" -#include "Standard_ErrorHandler.hxx" -#include "Standard_Failure.hxx" -#include "ShapeUpgrade_ShellSewing.hxx" -#include "ShapeFix_Shape.hxx" -#include "ShapeFix_Wireframe.hxx" -#include "BRepMesh.hxx" -#include "BRepMesh_IncrementalMesh.hxx" -#include "BRepBndLib.hxx" -#include "Bnd_Box.hxx" -#include "ShapeAnalysis.hxx" -#include "ShapeBuild_ReShape.hxx" -#include "IGESControl_Writer.hxx" -#include "STEPControl_Writer.hxx" -#include "StlAPI_Writer.hxx" -#include "STEPControl_StepModelType.hxx" - -namespace netgen -{ - -#include "../visualization/vispar.hpp" - // class VisualizationParameters; - // extern VisualizationParameters vispar; - - -#include "occmeshsurf.hpp" - -#define PROJECTION_TOLERANCE 1e-10 - - -#define ENTITYISVISIBLE 1 -#define ENTITYISHIGHLIGHTED 2 -#define ENTITYISDRAWABLE 4 - -class EntityVisualizationCode -{ - int code; - -public: - - EntityVisualizationCode() - { code = ENTITYISVISIBLE + !ENTITYISHIGHLIGHTED + ENTITYISDRAWABLE; } - - int IsVisible () - { return code & ENTITYISVISIBLE; } - - int IsHighlighted () - { return code & ENTITYISHIGHLIGHTED; } - - int IsDrawable () - { return code & ENTITYISDRAWABLE; } - - void Show () - { code |= ENTITYISVISIBLE; } - - void Hide () - { code &= ~ENTITYISVISIBLE; } - - void Highlight () - { code |= ENTITYISHIGHLIGHTED; } - - void Lowlight () - { code &= ~ENTITYISHIGHLIGHTED; } - - void SetDrawable () - { code |= ENTITYISDRAWABLE; } - - void SetNotDrawable () - { code &= ~ENTITYISDRAWABLE; } -}; - - - -inline double Det3 (double a00, double a01, double a02, - double a10, double a11, double a12, - double a20, double a21, double a22) -{ - return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00; -} - - - -#define OCCGEOMETRYVISUALIZATIONNOCHANGE 0 -#define OCCGEOMETRYVISUALIZATIONFULLCHANGE 1 - // == compute transformation matrices and redraw -#define OCCGEOMETRYVISUALIZATIONHALFCHANGE 2 - // == redraw - -class OCCGeometry -{ - Point<3> center; - -public: - TopoDS_Shape shape; - TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap; - Box<3> boundingbox; - - int changed; - ARRAY<int> facemeshstatus; - - ARRAY<EntityVisualizationCode> fvispar, evispar, vvispar; - - double tolerance; - bool fixsmalledges; - bool fixspotstripfaces; - bool sewfaces; - bool makesolids; - - - OCCGeometry() - { - somap.Clear(); - shmap.Clear(); - fmap.Clear(); - wmap.Clear(); - emap.Clear(); - vmap.Clear(); - } - - - void BuildFMap(); - - Box<3> GetBoundingBox() - { return boundingbox; } - - int NrSolids() - { return somap.Extent(); } - - void SetCenter() - { center = boundingbox.Center(); } - - Point<3> Center() - { return center; } - - void Project (int surfi, Point<3> & p) const - { - static int cnt = 0; - if (++cnt % 1000 == 0) cout << "Project cnt = " << cnt << endl; - - gp_Pnt pnt(p(0), p(1), p(2)); - - GeomAPI_ProjectPointOnSurf proj(pnt, BRep_Tool::Surface(TopoDS::Face(fmap(surfi)))); - if (proj.NbPoints() == 0) - { - cout << "Projection fails" << endl; - } - else - { - pnt = proj.NearestPoint(); - p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); - } - } - - bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const; - - - OCCSurface GetSurface (int surfi) - { - cout << "OCCGeometry::GetSurface using PLANESPACE" << endl; - return OCCSurface (TopoDS::Face(fmap(surfi)), PLANESPACE); - } - - - void BuildVisualizationMesh (); - - void RecursiveTopologyTree (const TopoDS_Shape & sh, - stringstream & str, - TopAbs_ShapeEnum l, - bool free, - const char * lname); - - void GetTopologyTree (stringstream & str); - - void PrintNrShapes (); - - void CheckIrregularEntities (stringstream & str); - - void SewFaces(); - - void MakeSolid(); - - void HealGeometry(); - - void LowLightAll() - { - for (int i = 1; i <= fmap.Extent(); i++) - fvispar[i-1].Lowlight(); - for (int i = 1; i <= emap.Extent(); i++) - evispar[i-1].Lowlight(); - for (int i = 1; i <= vmap.Extent(); i++) - vvispar[i-1].Lowlight(); - } - - void GetUnmeshedFaceInfo (stringstream & str); - void GetNotDrawableFaces (stringstream & str); - bool ErrorInSurfaceMeshing (); -}; - - -void PrintContents (OCCGeometry * geom); - -OCCGeometry * LoadOCC_IGES (const char * filename); -OCCGeometry * LoadOCC_STEP (const char * filename); - -} - -#endif - -#endif diff --git a/Netgen/libsrc/occ/occmeshsurf.cpp b/Netgen/libsrc/occ/occmeshsurf.cpp deleted file mode 100644 index 034571c9ae..0000000000 --- a/Netgen/libsrc/occ/occmeshsurf.cpp +++ /dev/null @@ -1,592 +0,0 @@ -#ifdef OCCGEOMETRY - -#include <mystdlib.h> - -#include <occgeom.hpp> -#include <meshing.hpp> - - -namespace netgen -{ -#include "occmeshsurf.hpp" - - -void OCCSurface :: GetNormalVector (const Point<3> & p, - const PointGeomInfo & geominfo, - Vec<3> & n) const -{ - gp_Pnt pnt; - gp_Vec du, dv; - - /* - double gu = geominfo.u; - double gv = geominfo.v; - - if (fabs (gu) < 1e-3) gu = 0; - if (fabs (gv) < 1e-3) gv = 0; - - occface->D1(gu,gv,pnt,du,dv); - */ - - occface->D1(geominfo.u,geominfo.v,pnt,du,dv); - - n = Cross (Vec<3>(du.X(), du.Y(), du.Z()), - Vec<3>(dv.X(), dv.Y(), dv.Z())); - n.Normalize(); - - if (orient == TopAbs_REVERSED) n = -1*n; - // (*testout) << "GetNormalVector" << endl; -} - - -void OCCSurface :: DefineTangentialPlane (const Point<3> & ap1, - const PointGeomInfo & geominfo1, - const Point<3> & ap2, - const PointGeomInfo & geominfo2) -{ - if (projecttype == PLANESPACE) - { - p1 = ap1; p2 = ap2; - - // cout << "p1 = " << p1 << endl; - // cout << "p2 = " << p2 << endl; - - GetNormalVector (p1, geominfo1, ez); - - ex = p2 - p1; - ex -= (ex * ez) * ez; - ex.Normalize(); - ey = Cross (ez, ex); - - GetNormalVector (p2, geominfo2, n2); - - nmid = 0.5*(n2+ez); - - ez = nmid; - ez.Normalize(); - - ex = (p2 - p1).Normalize(); - ez -= (ez * ex) * ex; - ez.Normalize(); - ey = Cross (ez, ex); - nmid = ez; - } - else - { - if ( (geominfo1.u < umin) || - (geominfo1.u > umax) || - (geominfo2.u < umin) || - (geominfo2.u > umax) || - (geominfo1.v < vmin) || - (geominfo1.v > vmax) || - (geominfo2.v < vmin) || - (geominfo2.v > vmax) ) throw UVBoundsException(); - - - p1 = ap1; p2 = ap2; - psp1 = Point<2>(geominfo1.u, geominfo1.v); - psp2 = Point<2>(geominfo2.u, geominfo2.v); - - Vec<3> n; - GetNormalVector (p1, geominfo1, n); - - gp_Pnt pnt; - gp_Vec du, dv; - occface->D1 (geominfo1.u, geominfo1.v, pnt, du, dv); - - DenseMatrix D1(3,2), D1T(2,3), DDTinv(2,2); - D1(0,0) = du.X(); D1(1,0) = du.Y(); D1(2,0) = du.Z(); - D1(0,1) = dv.X(); D1(1,1) = dv.Y(); D1(2,1) = dv.Z(); - - /* - (*testout) << "DefineTangentialPlane" << endl - << "---------------------" << endl; - (*testout) << "D1 = " << endl << D1 << endl; - */ - - Transpose (D1, D1T); - DenseMatrix D1TD1(3,3); - - D1TD1 = D1T*D1; - if (D1TD1.Det() == 0) throw SingularMatrixException(); - - CalcInverse (D1TD1, DDTinv); - DenseMatrix Y(3,2); - Vec<3> y1 = (ap2-ap1).Normalize(); - Vec<3> y2 = Cross(n, y1).Normalize(); - for (int i = 0; i < 3; i++) - { - Y(i,0) = y1(i); - Y(i,1) = y2(i); - } - - DenseMatrix A(2,2); - A = DDTinv * D1T * Y; - DenseMatrix Ainv(2,2); - - if (A.Det() == 0) throw SingularMatrixException(); - - CalcInverse (A, Ainv); - - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - { - Amat(i,j) = A(i,j); - Amatinv(i,j) = Ainv(i,j); - } - - Vec<2> temp = Amatinv * (psp2-psp1); - - - double r = temp.Length(); - // double alpha = -acos (temp(0)/r); - double alpha = -atan2 (temp(1),temp(0)); - DenseMatrix R(2,2); - R(0,0) = cos (alpha); - R(1,0) = -sin (alpha); - R(0,1) = sin (alpha); - R(1,1) = cos (alpha); - - - A = A*R; - - if (A.Det() == 0) throw SingularMatrixException(); - - CalcInverse (A, Ainv); - - - for (int i = 0; i < 2; i++) - for (int j = 0; j < 2; j++) - { - Amat(i,j) = A(i,j); - Amatinv(i,j) = Ainv(i,j); - } - - temp = Amatinv * (psp2-psp1); - - }; - -} - - -void OCCSurface :: ToPlane (const Point<3> & p3d, - const PointGeomInfo & geominfo, - Point<2> & pplane, - double h, int & zone) const -{ - if (projecttype == PLANESPACE) - { - Vec<3> p1p, n; - GetNormalVector (p3d, geominfo, n); - - p1p = p3d - p1; - pplane(0) = (p1p * ex) / h; - pplane(1) = (p1p * ey) / h; - - if (n * nmid < 0) - zone = -1; - else - zone = 0; - } - else - { - pplane = Point<2>(geominfo.u, geominfo.v); - // (*testout) << "(u,v) = " << geominfo.u << ", " << geominfo.v << endl; - pplane = Point<2> (1/h * (Amatinv * (pplane-psp1))); - // pplane = Point<2> (h * (Amatinv * (pplane-psp1))); - // pplane = Point<2> (1/h * ((pplane-psp1))); - - zone = 0; - }; -} - - -void OCCSurface :: FromPlane (const Point<2> & pplane, - Point<3> & p3d, - PointGeomInfo & gi, - double h) -{ - if (projecttype == PLANESPACE) - { - // cout << "2d : " << pplane << endl; - p3d = p1 + (h * pplane(0)) * ex + (h * pplane(1)) * ey; - // cout << "3d : " << p3d << endl; - Project (p3d, gi); - // cout << "proj : " << p3d << endl; - } - else - { - // Point<2> pspnew = Point<2>(1/h * (Amat * Vec<2>(pplane)) + Vec<2>(psp1)); - Point<2> pspnew = Point<2>(h * (Amat * Vec<2>(pplane)) + Vec<2>(psp1)); - // Point<2> pspnew = Point<2>(h * (Vec<2>(pplane)) + Vec<2>(psp1)); - gi.u = pspnew(0); - gi.v = pspnew(1); - gi.trignum = 1; - gp_Pnt val = occface->Value (gi.u, gi.v); - p3d = Point<3> (val.X(), val.Y(), val.Z()); - }; -} - - - -void OCCSurface :: Project (Point<3> & p, PointGeomInfo & gi) -{ - // static int cnt = 0; - // if (cnt++ % 1000 == 0) cout << "********************************************** OCCSurfce :: Project, cnt = " << cnt << endl; - - gp_Pnt pnt(p(0), p(1), p(2)); - - // cout << "pnt = " << pnt.X() << ", " << pnt.Y() << ", " << pnt.Z() << endl; - - GeomAPI_ProjectPointOnSurf proj(pnt, occface, umin, umax, vmin, vmax); - - if (!proj.NbPoints()) - { - cout << "Project Point on Surface FAIL" << endl; - throw UVBoundsException(); - } - - - /* - cout << "NP = " << proj.NbPoints() << endl; - - for (int i = 1; i <= proj.NbPoints(); i++) - { - gp_Pnt pnt2 = proj.Point(i); - Point<3> p2 = Point<3> (pnt2.X(), pnt2.Y(), pnt2.Z()); - cout << i << ". p = " << p2 << ", dist = " << (p2-p).Length() << endl; - } - */ - - pnt = proj.NearestPoint(); - proj.LowerDistanceParameters (gi.u, gi.v); - gi.trignum = 1; - - p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); -} - - -Meshing2OCCSurfaces :: Meshing2OCCSurfaces (const TopoDS_Shape & asurf, - const Box<3> & abb, int aprojecttype) - : Meshing2(Box3d(abb.PMin(), abb.PMax())), surface(TopoDS::Face(asurf), aprojecttype) -{ - ; -} - - -void Meshing2OCCSurfaces :: DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2) -{ - ((OCCSurface&)surface).DefineTangentialPlane (p1, *geominfo1, p2, *geominfo2); -} - -void Meshing2OCCSurfaces :: TransformToPlain (const Point3d & locpoint, - const MultiPointGeomInfo & geominfo, - Point2d & planepoint, - double h, int & zone) -{ - Point<2> hp; - surface.ToPlane (locpoint, geominfo.GetPGI(1), hp, h, zone); - planepoint.X() = hp(0); - planepoint.Y() = hp(1); -} - -int Meshing2OCCSurfaces :: TransformFromPlain (Point2d & planepoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h) -{ - Point<3> hp; - Point<2> hp2 (planepoint.X(), planepoint.Y()); - surface.FromPlane (hp2, hp, gi, h); - locpoint = hp; - return 0; -} - - - -double Meshing2OCCSurfaces :: CalcLocalH (const Point3d & p, double gh) const -{ - return gh; -} - - - - - - -MeshOptimize2dOCCSurfaces :: MeshOptimize2dOCCSurfaces (const OCCGeometry & ageometry) - : MeshOptimize2d(), geometry(ageometry) -{ - ; -} - - -void MeshOptimize2dOCCSurfaces :: ProjectPoint (INDEX surfind, Point3d & p) const -{ - Point<3> hp = p; - geometry.Project (surfind, hp); - p = hp; -} - -void MeshOptimize2dOCCSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, - Point3d & p) const -{ - TopExp_Explorer exp0, exp1; - bool done = false; - Handle(Geom_Curve) c; - - for (exp0.Init(geometry.fmap(surfind), TopAbs_EDGE); !done && exp0.More(); exp0.Next()) - for (exp1.Init(geometry.fmap(surfind2), TopAbs_EDGE); !done && exp1.More(); exp1.Next()) - { - if (TopoDS::Edge(exp0.Current()).IsSame(TopoDS::Edge(exp1.Current()))) - { - done = true; - double s0, s1; - c = BRep_Tool::Curve(TopoDS::Edge(exp0.Current()), s0, s1); - } - } - - gp_Pnt pnt(p.X(), p.Y(), p.Z()); - GeomAPI_ProjectPointOnCurve proj(pnt, c); - pnt = proj.NearestPoint(); - p.X() = pnt.X(); - p.Y() = pnt.Y(); - p.Z() = pnt.Z(); - -} - -void MeshOptimize2dOCCSurfaces :: -GetNormalVector(INDEX surfind, const Point3d & p, PointGeomInfo & geominfo, Vec3d & n) const -{ - gp_Pnt pnt; - gp_Vec du, dv; - - Handle(Geom_Surface) occface; - occface = BRep_Tool::Surface(TopoDS::Face(geometry.fmap(surfind))); - - occface->D1(geominfo.u,geominfo.v,pnt,du,dv); - - n = Cross (Vec<3>(du.X(), du.Y(), du.Z()), - Vec<3>(dv.X(), dv.Y(), dv.Z())); - n.Normalize(); - - if (geometry.fmap(surfind).Orientation() == TopAbs_REVERSED) n = -1*n; - - // GetNormalVector (surfind, p, n); -} - - -void MeshOptimize2dOCCSurfaces :: -GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const -{ - // static int cnt = 0; - // if (cnt++ % 1000 == 0) cout << "GetNV cnt = " << cnt << endl; - Standard_Real u,v; - - gp_Pnt pnt(p.X(), p.Y(), p.Z()); - - Handle(Geom_Surface) occface; - occface = BRep_Tool::Surface(TopoDS::Face(geometry.fmap(surfind))); - - GeomAPI_ProjectPointOnSurf proj(pnt, occface); - - if (proj.NbPoints() < 1) - { - cout << "ERROR: OCCSurface :: GetNormalVector: GeomAPI_ProjectPointOnSurf failed!" - << endl; - cout << p << endl; - return; - } - - proj.LowerDistanceParameters (u, v); - - gp_Vec du, dv; - occface->D1(u,v,pnt,du,dv); - - /* - if (!occface->IsCNu (1) || !occface->IsCNv (1)) - (*testout) << "SurfOpt: Differentiation FAIL" << endl; - */ - - n = Cross (Vec3d(du.X(), du.Y(), du.Z()), - Vec3d(dv.X(), dv.Y(), dv.Z())); - n.Normalize(); - - if (geometry.fmap(surfind).Orientation() == TopAbs_REVERSED) n = -1*n; -} - - -int MeshOptimize2dOCCSurfaces :: -CalcPointGeomInfo(int surfind, PointGeomInfo& gi, const Point3d& p) const -{ - Standard_Real u,v; - - gp_Pnt pnt(p.X(), p.Y(), p.Z()); - - Handle(Geom_Surface) occface; - occface = BRep_Tool::Surface(TopoDS::Face(geometry.fmap(surfind))); - - GeomAPI_ProjectPointOnSurf proj(pnt, occface); - - if (proj.NbPoints() < 1) - { - cout << "ERROR: OCCSurface :: GetNormalVector: GeomAPI_ProjectPointOnSurf failed!" - << endl; - cout << p << endl; - return 0; - } - - proj.LowerDistanceParameters (u, v); - - gi.u = u; - gi.v = v; - return 1; -} - - - - - - -OCCRefinementSurfaces :: OCCRefinementSurfaces (const OCCGeometry & ageometry) - : Refinement(), geometry(ageometry) -{ - ; -} - -OCCRefinementSurfaces :: ~OCCRefinementSurfaces () -{ - ; -} - -/* -inline double Det3 (double a00, double a01, double a02, - double a10, double a11, double a12, - double a20, double a21, double a22) -{ - return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00; -} - -bool ProjectToSurface (gp_Pnt & p, Handle(Geom_Surface) surface, double& u, double& v) -{ - gp_Pnt x = surface->Value (u,v); - - if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true; - - gp_Vec du, dv; - - surface->D1(u,v,x,du,dv); - - int count = 0; - - gp_Pnt xold; - gp_Vec n; - double det, lambda, mu; - - do { - count++; - - n = du^dv; - - det = Det3 (n.X(), du.X(), dv.X(), - n.Y(), du.Y(), dv.Y(), - n.Z(), du.Z(), dv.Z()); - - if (det < 1e-15) return false; - - lambda = Det3 (n.X(), p.X()-x.X(), dv.X(), - n.Y(), p.Y()-x.Y(), dv.Y(), - n.Z(), p.Z()-x.Z(), dv.Z())/det; - - mu = Det3 (n.X(), du.X(), p.X()-x.X(), - n.Y(), du.Y(), p.Y()-x.Y(), - n.Z(), du.Z(), p.Z()-x.Z())/det; - - u += lambda; - v += mu; - - xold = x; - surface->D1(u,v,x,du,dv); - - } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) || count > 50); - - if (count > 50) return false; - - p = x; - - return true; -} -*/ - -void OCCRefinementSurfaces :: -PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi) -{ - Point<3> hnewp; - hnewp = p1+secpoint*(p2-p1); - - if (surfi > 0) - { - - double u = gi1.u+secpoint*(gi2.u-gi1.u); - double v = gi1.v+secpoint*(gi2.v-gi1.v); - - if (!geometry.FastProject (surfi, hnewp, u, v)) - { - cout << "Fast projection to surface fails! Using OCC projection" << endl; - geometry.Project (surfi, hnewp); - } - - newgi.trignum = 1; - } - - newp = hnewp; -} - - -void OCCRefinementSurfaces :: -PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi) -{ - double s0, s1; - - Point<3> hnewp = p1+secpoint*(p2-p1); - gp_Pnt pnt(hnewp(0), hnewp(1), hnewp(2)); - GeomAPI_ProjectPointOnCurve proj(pnt, BRep_Tool::Curve(TopoDS::Edge(geometry.emap(ap1.edgenr)), s0, s1)); - pnt = proj.NearestPoint(); - hnewp = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); - newp = hnewp; - newgi = ap1; -}; - - -void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) -{ - if (surfi > 0) - geometry.Project (surfi, p); -}; - -void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi) -{ - if (surfi > 0) - if (!geometry.FastProject (surfi, p, gi.u, gi.v)) - { - cout << "Fast projection to surface fails! Using OCC projection" << endl; - geometry.Project (surfi, p); - } -}; - - - -} - - -#endif diff --git a/Netgen/libsrc/occ/occmeshsurf.hpp b/Netgen/libsrc/occ/occmeshsurf.hpp deleted file mode 100644 index bda8a05a64..0000000000 --- a/Netgen/libsrc/occ/occmeshsurf.hpp +++ /dev/null @@ -1,201 +0,0 @@ -#ifdef OCCGEOMETRY - -#ifndef FILE_OCCMESHSURF -#define FILE_OCCMESHSURF - -#include "occgeom.hpp" - -#define PARAMETERSPACE -1 -#define PLANESPACE 1 - -class OCCGeometry; - -class SingularMatrixException -{}; - -class UVBoundsException -{}; - -class OCCSurface -{ -public: - TopoDS_Face topods_face; - Handle(Geom_Surface) occface; - TopAbs_Orientation orient; - int projecttype; - -protected: - Point<3> p1; - Point<3> p2; - - /// in plane, directed p1->p2 - Vec<3> ex; - /// in plane - Vec<3> ey; - /// outer normal direction - Vec<3> ez; - - /// normal vector in p2 - Vec<3> n2; - - /// average normal vector - Vec<3> nmid; - - // for transformation to parameter space - Point<2> psp1; - Point<2> psp2; - Vec<2> psex; - Vec<2> psey; - Mat<2,2> Amat, Amatinv; - - // UV Bounds - double umin, umax, vmin, vmax; - -public: - OCCSurface (const TopoDS_Face & aface, int aprojecttype) - { - topods_face = aface; - occface = BRep_Tool::Surface(topods_face); - orient = topods_face.Orientation(); - projecttype = aprojecttype; - ShapeAnalysis::GetFaceUVBounds (topods_face, umin, umax, vmin, vmax); - umin -= fabs(umax-umin)/100.0; - vmin -= fabs(vmax-vmin)/100.0; - umax += fabs(umax-umin)/100.0; - vmax += fabs(vmax-vmin)/100.0; - // projecttype = PLANESPACE; - /* - TopExp_Explorer exp1; - exp1.Init (topods_face, TopAbs_WIRE); - orient = TopAbs::Compose (orient, exp1.Current().Orientation()); - */ - }; - - ~OCCSurface() - {}; - - void Project (Point<3> & p, PointGeomInfo & gi); - - void GetNormalVector (const Point<3> & p, - const PointGeomInfo & geominfo, - Vec<3> & n) const; - - /** - Defines tangential plane in ap1. - The local x-coordinate axis point to the direction of ap2 */ - void DefineTangentialPlane (const Point<3> & ap1, - const PointGeomInfo & geominfo1, - const Point<3> & ap2, - const PointGeomInfo & geominfo2); - - - /// Transforms 3d point p3d to local coordinates pplane - void ToPlane (const Point<3> & p3d, const PointGeomInfo & geominfo, - Point<2> & pplane, double h, int & zone) const; - - /// Transforms point pplane in local coordinates to 3d point - void FromPlane (const Point<2> & pplane, - Point<3> & p3d, - PointGeomInfo & gi, - double h); -}; - - - -/// -class Meshing2OCCSurfaces : public Meshing2 -{ - /// - OCCSurface surface; - -public: - /// - Meshing2OCCSurfaces (const TopoDS_Shape & asurf, const Box<3> & aboundingbox, int aprojecttype); - - /// - int GetProjectionType () - { return surface.projecttype; } - -protected: - /// - virtual void DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2); - /// - virtual void TransformToPlain (const Point3d & locpoint, - const MultiPointGeomInfo & geominfo, - Point2d & plainpoint, - double h, int & zone); - /// - virtual int TransformFromPlain (Point2d & plainpoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h); - /// - virtual double CalcLocalH (const Point3d & p, double gh) const; - -}; - - - -/// -class MeshOptimize2dOCCSurfaces : public MeshOptimize2d - { - /// - const OCCGeometry & geometry; - -public: - /// - MeshOptimize2dOCCSurfaces (const OCCGeometry & ageometry); - - /// - virtual void ProjectPoint (INDEX surfind, Point3d & p) const; - /// - virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point3d & p) const; - /// - virtual void GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const; - /// - virtual void GetNormalVector(INDEX surfind, const Point3d & p, PointGeomInfo & gi, Vec3d & n) const; - - - virtual int CalcPointGeomInfo(int surfind, PointGeomInfo& gi, const Point3d& p3) const; - -}; - - - -class OCCGeometry; - - -class OCCRefinementSurfaces : public Refinement -{ - const OCCGeometry & geometry; - -public: - OCCRefinementSurfaces (const OCCGeometry & ageometry); - virtual ~OCCRefinementSurfaces (); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi); - - virtual void ProjectToSurface (Point<3> & p, int surfi); - - virtual void ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi); -}; - - - -#endif - - - -#endif diff --git a/Netgen/libsrc/opti/Makefile b/Netgen/libsrc/opti/Makefile deleted file mode 100644 index d73441553f..0000000000 --- a/Netgen/libsrc/opti/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for optimisation library -# -src = bfgs.cpp linsearch.cpp linopt.cpp -# -lib = opti -libpath = libsrc/opti -# -# -include ../makefile.inc diff --git a/Netgen/libsrc/opti/bfgs.cpp b/Netgen/libsrc/opti/bfgs.cpp deleted file mode 100644 index 31a499a64d..0000000000 --- a/Netgen/libsrc/opti/bfgs.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/***************************************************************************/ -/* */ -/* Vorlesung Optimierung I, Gfrerer, WS94/95 */ -/* BFGS-Verfahren zur L�sung freier nichtlinearer Optimierungsprobleme */ -/* */ -/* Programmautor: Joachim Sch�berl */ -/* Matrikelnummer: 9155284 */ -/* */ -/***************************************************************************/ - -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include "opti.hpp" - - -namespace netgen -{ - -void Cholesky (const DenseMatrix & a, - DenseMatrix & l, Vector & d) -{ - // Factors A = L D L^T - - double x; - - int i, j, k; - int n = a.Height(); - - // (*testout) << "a = " << a << endl; - - l = a; - - for (i = 1; i <= n; i++) - { - for (j = i; j <= n; j++) - { - x = l.Get(i, j); - - for (k = 1; k < i; k++) - x -= l.Get(i, k) * l.Get(j, k) * d.Get(k); - - if (i == j) - { - d.Elem(i) = x; - } - else - { - l.Elem(j, i) = x / d.Get(k); - } - } - } - - for (i = 1; i <= n; i++) - { - l.Elem(i, i) = 1; - for (j = i+1; j <= n; j++) - l.Elem(i, j) = 0; - } - - /* - // Multiply: - (*testout) << "multiplied factors: " << endl; - for (i = 1; i <= n; i++) - for (j = 1; j <= n; j++) - { - x = 0; - for (k = 1; k <= n; k++) - x += l.Get(i, k) * l.Get(j, k) * d.Get(k); - (*testout) << x << " "; - } - (*testout) << endl; - */ -} - - -void MultLDLt (const DenseMatrix & l, const Vector & d, const Vector & g, Vector & p) -{ - int i, j, n; - double val; - - n = l.Height(); - p = g; - for (i = 1; i <= n; i++) - { - val = 0; - for (j = i; j <= n; j++) - val += p.Get(j) * l.Get(j, i); - p.Set(i, val); - } - for (i = 1; i <= n; i++) - p.Elem(i) *= d.Get(i); - - for (i = n; i >= 1; i--) - { - val = 0; - for (j = 1; j <= i; j++) - val += p.Get(j) * l.Get(i, j); - p.Set(i, val); - } -} - -void SolveLDLt (const DenseMatrix & l, const Vector & d, const Vector & g, Vector & p) -{ - int i, j, n; - double val; - - n = l.Height(); - p = g; - - for (i = 1; i <= n; i++) - { - val = 0; - for (j = 1; j < i; j++) - val += p.Get(j) * l.Get(i, j); - p.Elem(i) -= val; - } - for (i = 1; i <= n; i++) - p.Elem(i) /= d.Get(i); - - for (i = n; i >= 1; i--) - { - val = 0; - for (j = i+1; j <= n; j++) - val += p.Get(j) * l.Get(j, i); - p.Elem(i) -= val; - } -} - -int LDLtUpdate (DenseMatrix & l, Vector & d, double a, const Vector & u) -{ - // Bemerkung: Es wird a aus R erlaubt - // Rueckgabewert: 0 .. D bleibt positiv definit - // 1 .. sonst - - int i, j, n; - - n = l.Height(); - - Vector v(n); - double t, told, xi; - - told = 1; - v = u; - - for (j = 1; j <= n; j++) - { - t = told + a * sqr (v.Elem(j)) / d.Get(j); - - if (t <= 0) return 1; - - xi = a * v.Elem(j) / (d.Get(j) * t); - - d.Elem(j) *= t / told; - - for (i = j + 1; i <= n; i++) - { - v.Elem(i) -= v.Elem(j) * l.Elem(i, j); - l.Elem(i, j) += xi * v.Elem(i); - } - - told = t; - } - - return 0; -} - - -double BFGS ( - Vector & x, // i: Startwert - // o: Loesung, falls IFAIL = 0 - const MinFunction & fun, - const OptiParameters & par, - double eps - ) - - -{ - - int i, j, n = x.Size(); - long it; - char a1crit, a3acrit; - - - Vector d(n), g(n), p(n), temp(n), bs(n), xneu(n), y(n), s(n), x0(n); - DenseMatrix l(n); - DenseMatrix hesse(n); - - double /* normg, */ alphahat, hd, fold; - double a1, a2; - const double mu1 = 0.1, sigma = 0.1, xi1 = 1, xi2 = 10; - const double tau = 0.1, tau1 = 0.1, tau2 = 0.6; - - Vector typx(x.Size()); // i: typische Groessenordnung der Komponenten - double f, f0; - double typf; // i: typische Groessenordnung der Loesung - double fmin = -1e5; // i: untere Schranke fuer Funktionswert - // double eps = 1e-8; // i: Abbruchschranke fuer relativen Gradienten - double tauf = 0.1; // i: Abbruchschranke fuer die relative Aenderung der - // Funktionswerte - int ifail; // o: 0 .. Erfolg - // -1 .. Unterschreitung von fmin - // 1 .. kein Erfolg bei Liniensuche - // 2 .. �berschreitung von itmax - - typx = par.typx; - typf = par.typf; - - - l = 0; - for (i = 1; i <= n; i++) - l.Elem(i, i) = 1; - - f = fun.FuncGrad (x, g); - f0 = f; - x0 = x; - - - it = 0; - do - { - // Restart - - if (it % (5 * n) == 0) - { - - for (i = 1; i <= n; i++) - d.Elem(i) = typf/ sqr (typx.Get(i)); // 1; - for (i = 2; i <= n; i++) - for (j = 1; j < i; j++) - l.Elem(i, j) = 0; - - /* - hesse = 0; - for (i = 1; i <= n; i++) - hesse.Elem(i, i) = typf / sqr (typx.Get(i)); - - fun.ApproximateHesse (x, hesse); - - Cholesky (hesse, l, d); - */ - } - - it++; - if (it > par.maxit_bfgs) - { - ifail = 2; - break; - } - - - // Solve with factorized B - - SolveLDLt (l, d, g, p); - - - p *= -1; - y = g; - - fold = f; - - // line search - - alphahat = 1; - lines (x, xneu, p, f, g, fun, par, alphahat, fmin, - mu1, sigma, xi1, xi2, tau, tau1, tau2, ifail); - - /* - if (it > par.maxit_bfgs/2) - { - (*testout) << "x = " << x << endl; - (*testout) << "xneu = " << xneu << endl; - (*testout) << "f = " << f << endl; - (*testout) << "g = " << g << endl; - } - */ - - - // (*testout) << "it = " << it << " f = " << f << endl; - // if (ifail != 0) break; - - s.Set2 (1, xneu, -1, x); - y *= -1; - y.Add (1,g); // y += g; - - x = xneu; - - // BFGS Update - - MultLDLt (l, d, s, bs); - - a1 = y * s; - a2 = s * bs; - - if (a1 > 0 && a2 > 0) - { - if (LDLtUpdate (l, d, 1 / a1, y) != 0) - { - cerr << "update error1" << endl; - ifail = 1; - break; - } - - if (LDLtUpdate (l, d, -1 / a2, bs) != 0) - { - cerr << "update error2" << endl; - ifail = 1; - break; - } - } - - // Calculate stop conditions - - hd = eps * max2 (typf, fabs (f)); - a1crit = 1; - for (i = 1; i <= n; i++) - if ( fabs (g.Elem(i)) * max2 (typx.Elem(i), fabs (x.Elem(i))) > hd) - a1crit = 0; - - - a3acrit = (fold - f <= tauf * max2 (typf, fabs (f))); - - // testout << "g = " << g << endl; - // testout << "a1crit, a3crit = " << int(a1crit) << ", " << int(a3acrit) << endl; - - /* - // Output for tests - - normg = sqrt (g * g); - - testout << "it =" << setw (5) << it - << " f =" << setw (12) << setprecision (5) << f - << " |g| =" << setw (12) << setprecision (5) << normg; - - testout << " x = (" << setw (12) << setprecision (5) << x.Elem(1); - for (i = 2; i <= n; i++) - testout << "," << setw (12) << setprecision (5) << x.Elem(i); - testout << ")" << endl; - */ - - // (*testout) << "it = " << it << " f = " << f << " x = " << x << endl - // << " g = " << g << " p = " << p << endl << endl; - - // (*testout) << "|g| = " << g.L2Norm() << endl; - - if (g.L2Norm() < fun.GradStopping (x)) break; - - } - while (!a1crit || !a3acrit); - - /* - (*testout) << "it = " << it << " g = " << g << " f = " << f - << " fail = " << ifail << endl; - */ - if (f0 < f || (ifail == 1)) - { - (*testout) << "fail, f = " << f << " f0 = " << f0 << endl; - f = f0; - x = x0; - } - - // (*testout) << "x = " << x << ", x0 = " << x0 << endl; - return f; -} - -} diff --git a/Netgen/libsrc/opti/linopt.cpp b/Netgen/libsrc/opti/linopt.cpp deleted file mode 100644 index a5d381e6b7..0000000000 --- a/Netgen/libsrc/opti/linopt.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include "opti.hpp" - -namespace netgen -{ - -void LinearOptimize (const DenseMatrix & a, const Vector & b, - const Vector & c, Vector & x) - - { - int i1, i2, i3, j; - DenseMatrix m(3), inv(3); - Vector rs(3), hx(3), res(a.Height()), res2(3); - double f, fmin; - int nrest; - - if (a.Width() != 3) - { - cerr << "LinearOptimize only implemented for 3 unknowns" << endl; - return; - } - - fmin = 1e10; - x = 0; - nrest = a.Height(); - for (i1 = 1; i1 <= nrest; i1++) - for (i2 = i1 + 1; i2 <= nrest; i2++) - for (i3 = i2 + 1; i3 <= nrest; i3++) - { - for (j = 1; j <= 3; j++) - { - m.Elem(1, j) = a.Get(i1, j); - m.Elem(2, j) = a.Get(i2, j); - m.Elem(3, j) = a.Get(i3, j); - } - - rs.Elem(1) = b.Get(i1); - rs.Elem(2) = b.Get(i2); - rs.Elem(3) = b.Get(i3); - - if (fabs (m.Det()) < 1e-12) continue; - - CalcInverse (m, inv); - inv.Mult (rs, hx); - - a.Residuum (hx, b, res); -// m.Residuum (hx, rs, res2); - f = c * hx; - -/* - testout -> precision(12); - (*testout) << "i = (" << i1 << "," << i2 << "," << i3 - << "), f = " << f << " x = " << x << " res = " << res - << " resmin = " << res.Min() - << " res2 = " << res2 << " prod = " << prod << endl; -*/ - - - double rmin = res.Elem(1); - for (int hi = 2; hi <= res.Size(); hi++) - if (res.Elem(hi) < rmin) rmin = res.Elem(hi); - - if ( (f < fmin) && rmin >= -1e-8) - { - fmin = f; - x = hx; - } - } - } -} diff --git a/Netgen/libsrc/opti/linsearch.cpp b/Netgen/libsrc/opti/linsearch.cpp deleted file mode 100644 index c847911dae..0000000000 --- a/Netgen/libsrc/opti/linsearch.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/***************************************************************************/ -/* */ -/* Problem: Liniensuche */ -/* */ -/* Programmautor: Joachim Sch�berl */ -/* Matrikelnummer: 9155284 */ -/* */ -/* Algorithmus nach: */ -/* */ -/* Optimierung I, Gfrerer, WS94/95 */ -/* Algorithmus 2.1: Liniensuche Problem (ii) */ -/* */ -/***************************************************************************/ - - - -#include <mystdlib.h> - -#include <myadt.hpp> // min, max, sqr - -#include <linalg.hpp> -#include "opti.hpp" - - -namespace netgen -{ -const double eps0 = 1E-15; - -// Liniensuche - - -double MinFunction :: Func (const Vector & /* x */) const -{ - cerr << "Func of MinFunction called" << endl; - return 0; -} - -void MinFunction :: Grad (const Vector & /* x */, Vector & /* g */) const -{ - cerr << "Grad of MinFunction called" << endl; -} - -double MinFunction :: FuncGrad (const Vector & x, Vector & g) const -{ - int n = x.Size(); - int i, j; - - static Vector xr; - static Vector xl; - xr.SetSize(n); - xl.SetSize(n); - - double eps = 1e-6; - double fl, fr; - - for (i = 1; i <= n; i++) - { - xr.Set (1, x); - xl.Set (1, x); - xr.Elem(i) += eps; - xl.Elem(i) -= eps; - - fl = Func (xl); - fr = Func (xr); - - g.Elem(i) = (fr - fl) / (2 * eps); - } - - double f = Func(x); - // (*testout) << "f = " << f << " grad = " << g << endl; - return f; -} - - -double MinFunction :: FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const -{ - Vector g(x.Size()); - double f = FuncGrad (x, g); - deriv = (g * dir); - - // (*testout) << "g = " << g << ", dir = " << dir << ", deriv = " << deriv << endl; - return f; -} - -void MinFunction :: ApproximateHesse (const Vector & x, - DenseMatrix & hesse) const -{ - int n = x.Size(); - int i, j; - - static Vector hx; - hx.SetSize(n); - - double eps = 1e-6; - double f, f11, f12, f21, f22; - - for (i = 1; i <= n; i++) - { - for (j = 1; j < i; j++) - { - hx = x; - hx.Elem(i) = x.Get(i) + eps; - hx.Elem(j) = x.Get(j) + eps; - f11 = Func(hx); - hx.Elem(i) = x.Get(i) + eps; - hx.Elem(j) = x.Get(j) - eps; - f12 = Func(hx); - hx.Elem(i) = x.Get(i) - eps; - hx.Elem(j) = x.Get(j) + eps; - f21 = Func(hx); - hx.Elem(i) = x.Get(i) - eps; - hx.Elem(j) = x.Get(j) - eps; - f22 = Func(hx); - - hesse.Elem(i, j) = hesse.Elem(j, i) = - (f11 + f22 - f12 - f21) / (2 * eps * eps); - } - - hx = x; - f = Func(x); - hx.Elem(i) = x.Get(i) + eps; - f11 = Func(hx); - hx.Elem(i) = x.Get(i) - eps; - f22 = Func(hx); - - hesse.Elem(i, i) = (f11 + f22 - 2 * f) / (eps * eps); - } - // (*testout) << "hesse = " << hesse << endl; -} - - - - - - - -/// Line search, modified Mangasarien conditions -void lines (Vector & x, // i: initial point of line-search - Vector & xneu, // o: solution, if successful - Vector & p, // i: search direction - double & f, // i: function-value at x - // o: function-value at xneu, iff ifail = 0 - Vector & g, // i: gradient at x - // o: gradient at xneu, iff ifail = 0 - const MinFunction & fun, // function to minimize - const OptiParameters & par, - double & alphahat, // i: initial value for alpha_hat - // o: solution alpha iff ifail = 0 - double fmin, // i: lower bound for f - double mu1, // i: Parameter mu_1 of Alg.2.1 - double sigma, // i: Parameter sigma of Alg.2.1 - double xi1, // i: Parameter xi_1 of Alg.2.1 - double xi2, // i: Parameter xi_1 of Alg.2.1 - double tau, // i: Parameter tau of Alg.2.1 - double tau1, // i: Parameter tau_1 of Alg.2.1 - double tau2, // i: Parameter tau_2 of Alg.2.1 - int & ifail) // o: 0 on success - // -1 bei termination because lower limit fmin - // 1 bei illegal termination due to different reasons - -{ - double phi0, phi0prime, phi1, phi1prime, phihatprime; - double alpha1, alpha2, alphaincr, c; - char flag = 1; - long it; - - alpha1 = 0; - alpha2 = 1e50; - phi0 = phi1 = f; - - phi0prime = g * p; - - - if (phi0prime > 0) - { - ifail = 1; - return; - } - - phi1prime = phi0prime; - - // (*testout) << "phi0prime = " << phi0prime << endl; - - // it = 100000l; - it = 0; - - while (it++ <= par.maxit_linsearch) - { - // (*testout) << "alphahat = " << alphahat << endl; - - xneu.Set2 (1, x, alphahat, p); - - // f = fun.FuncGrad (xneu, g); - // f = fun.Func (xneu); - f = fun.FuncDeriv (xneu, p, phihatprime); - - // (*testout) << "f = " << f << " phip = " << phihatprime << endl; - - if (f < fmin) - { - ifail = -1; - break; - } - - - if (alpha2 - alpha1 < eps0 * alpha2) - { - ifail = 0; - break; - } - - // (*testout) << "i = " << it << " al = " << alphahat << " f = " << f << " fprime " << phihatprime << endl;; - - if (f - phi0 > mu1 * alphahat * phi1prime + eps0 * fabs (phi0)) - - { - - flag = 0; - alpha2 = alphahat; - - c = - (f - phi1 - phi1prime * (alphahat-alpha1)) / - sqr (alphahat-alpha1); - - alphahat = alpha1 - 0.5 * phi1prime / c; - - if (alphahat > alpha2) - alphahat = alpha1 + 1/(4*c) * - ( (sigma+mu1) * phi0prime - 2*phi1prime - + sqrt (sqr(phi1prime - mu1 * phi0prime) - - 4 * (phi1 - phi0 - mu1 * alpha1 * phi0prime) * c)); - - alphahat = max2 (alphahat, alpha1 + tau * (alpha2 - alpha1)); - alphahat = min2 (alphahat, alpha2 - tau * (alpha2 - alpha1)); - - // (*testout) << " if-branch" << endl; - - } - - else - - { - /* - f = fun.FuncGrad (xneu, g); - phihatprime = g * p; - */ - f = fun.FuncDeriv (xneu, p, phihatprime); - - if (phihatprime < sigma * phi0prime * (1 + eps0)) - - { - if (phi1prime < phihatprime) - // Approximationsfunktion ist konvex - - alphaincr = (alphahat - alpha1) * phihatprime / - (phi1prime - phihatprime); - - else - alphaincr = 1e99; // MAXDOUBLE; - - if (flag) - { - alphaincr = max2 (alphaincr, xi1 * (alphahat-alpha1)); - alphaincr = min2 (alphaincr, xi2 * (alphahat-alpha1)); - } - else - { - alphaincr = max2 (alphaincr, tau1 * (alpha2 - alphahat)); - alphaincr = min2 (alphaincr, tau2 * (alpha2 - alphahat)); - } - - alpha1 = alphahat; - alphahat += alphaincr; - phi1 = f; - phi1prime = phihatprime; - } - - else - - { - ifail = 0; // Erfolg !! - break; - } - - // (*testout) << " else, " << endl; - - } - - } - - // (*testout) << "linsearch: it = " << it << " ifail = " << ifail << endl; - - fun.FuncGrad (xneu, g); - - - if (it < 0) - ifail = 1; - - // (*testout) << "fail = " << ifail << endl; -} - - - - - - - - - - - - - - - - - - - -void SteepestDescent (Vector & x, const MinFunction & fun, - const OptiParameters & par) -{ - int it, n = x.Size(); - Vector xnew(n), p(n), g(n), g2(n); - double val, alphahat; - int fail; - - val = fun.FuncGrad(x, g); - - alphahat = 1; - // testout << "f = "; - for (it = 0; it < 10; it++) - { - // testout << val << " "; - - // p = -g; - p.Set (-1, g); - - lines (x, xnew, p, val, g, fun, par, alphahat, -1e5, - 0.1, 0.1, 1, 10, 0.1, 0.1, 0.6, fail); - - x = xnew; - } - // testout << endl; -} -} diff --git a/Netgen/libsrc/opti/opti.hpp b/Netgen/libsrc/opti/opti.hpp deleted file mode 100644 index 5fa0735bd0..0000000000 --- a/Netgen/libsrc/opti/opti.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef FILE_OPTI -#define FILE_OPTI - -/**************************************************************************/ -/* File: opti.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 01. Jun. 95 */ -/**************************************************************************/ - - - -namespace netgen -{ - - /** - Function to be minimized. - */ - class MinFunction - { - public: - /// - virtual double Func (const Vector & x) const; - /// - virtual void Grad (const Vector & x, Vector & g) const; - /// function and gradient - virtual double FuncGrad (const Vector & x, Vector & g) const; - /// directional derivative - virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; - /// if |g| < gradaccuray, then stop bfgs - virtual double GradStopping (const Vector & /* x */) const { return 0; } - - /// - virtual void ApproximateHesse (const Vector & /* x */, - DenseMatrix & /* hesse */) const; - }; - - - class OptiParameters - { - public: - int maxit_linsearch; - int maxit_bfgs; - double typf; - double typx; - - OptiParameters () - { - maxit_linsearch = 100; - maxit_bfgs = 100; - typf = 1; - typx = 1; - } - }; - - - /** Implementation of BFGS method. - Efficient method for non-linear minimiztion problems. - @param x initial value and solution - @param fun function to be minimized - */ - extern double BFGS (Vector & x, const MinFunction & fun, - const OptiParameters & par, - double eps = 1e-8); - - /** Steepest descent method. - Simple method for non-linear minimization problems. - @param x initial value and solution - @param fun function to be minimized - */ - void SteepestDescent (Vector & x, const MinFunction & fun, - const OptiParameters & par); - - - extern void lines ( - Vector & x, // i: Ausgangspunkt der Liniensuche - Vector & xneu, // o: Loesung der Liniensuche bei Erfolg - Vector & p, // i: Suchrichtung - double & f, // i: Funktionswert an der Stelle x - // o: Funktionswert an der Stelle xneu, falls ifail = 0 - Vector & g, // i: Gradient an der Stelle x - // o: Gradient an der Stelle xneu, falls ifail = 0 - - const MinFunction & fun, // function to minmize - const OptiParameters & par, // parameters - double & alphahat, // i: Startwert f�r alpha_hat - // o: Loesung falls ifail = 0 - double fmin, // i: untere Schranke f�r f - double mu1, // i: Parameter mu_1 aus Alg.2.1 - double sigma, // i: Parameter sigma aus Alg.2.1 - double xi1, // i: Parameter xi_1 aus Alg.2.1 - double xi2, // i: Parameter xi_1 aus Alg.2.1 - double tau, // i: Parameter tau aus Alg.2.1 - double tau1, // i: Parameter tau_1 aus Alg.2.1 - double tau2, // i: Parameter tau_2 aus Alg.2.1 - int & ifail); // o: 0 bei erfolgreicher Liniensuche - // -1 bei Abbruch wegen Unterschreiten von fmin - // 1 bei Abbruch, aus sonstigen Gr�nden - - - - - /** - Solvers linear programming problem. - - \begin{verbatim} - min c^t x - A x <= b - \end{verbatim} - */ - extern void LinearOptimize (const DenseMatrix & a, const Vector & b, - const Vector & c, Vector & x); - - -#ifdef NONE - - /** - Simple projection iteration. - - find $u = argmin_{v >= 0} 0.5 u A u - f u$ - */ - extern void ApproxProject (const BaseMatrix & a, Vector & u, - const Vector & f, - double tau, int its); - - - /** - CG Algorithm for quadratic programming problem. - See: Dostal ... - - d ... diag(A) ^{-1} - */ - extern void ApproxProjectCG (const BaseMatrix & a, Vector & x, - const Vector & b, const class DiagMatrix & d, - double gamma, int & steps, int & changes); - -#endif - - -} - -#endif - diff --git a/Netgen/libsrc/stlgeom/Makefile b/Netgen/libsrc/stlgeom/Makefile deleted file mode 100644 index 007a979cad..0000000000 --- a/Netgen/libsrc/stlgeom/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for geometric library -# -src = stlgeom.cpp stltopology.cpp stlgeomchart.cpp stlgeommesh.cpp meshstlsurface.cpp stlline.cpp stltool.cpp -# -lib = stlgeom -libpath = libsrc/stlgeom -# -# -include ../makefile.inc -# diff --git a/Netgen/libsrc/stlgeom/meshstlsurface.cpp b/Netgen/libsrc/stlgeom/meshstlsurface.cpp deleted file mode 100644 index 5af12d7aa9..0000000000 --- a/Netgen/libsrc/stlgeom/meshstlsurface.cpp +++ /dev/null @@ -1,1130 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - - -#include "stlgeom.hpp" - - -namespace netgen -{ - -static void STLFindEdges (STLGeometry & geom, - class Mesh & mesh) -{ - int i, j, k; - double h; - - h = mparam.maxh; - - // mark edge points: - int ngp = geom.GetNP(); - - geom.RestrictLocalH(mesh, h); - - PushStatusF("Mesh Lines"); - - ARRAY<STLLine*> meshlines; - ARRAY<Point3d> meshpoints; - - PrintMessage(3,"Mesh Lines"); - - for (i = 1; i <= geom.GetNLines(); i++) - { - meshlines.Append(geom.GetLine(i)->Mesh(geom.GetPoints(), meshpoints, h, mesh)); - SetThreadPercent(100.0 * (double)i/(double)geom.GetNLines()); - } - - geom.meshpoints.SetSize(0); //testing - geom.meshlines.SetSize(0); //testing - for (i = 1; i <= meshpoints.Size(); i++) - { - geom.meshpoints.Append(meshpoints.Get(i)); //testing - - int pim = mesh.AddPoint(meshpoints.Get(i)); - } - //(++++++++++++++testing - for (i = 1; i <= geom.GetNLines(); i++) - { - geom.meshlines.Append(meshlines.Get(i)); - } - //++++++++++++++testing) - - PrintMessage(7,"feed with edges"); - - for (i = 1; i <= meshlines.Size(); i++) - { - STLLine* line = meshlines.Get(i); - (*testout) << "store line " << i << endl; - for (j = 1; j <= line->GetNS(); j++) - { - int p1, p2; - - line->GetSeg(j, p1, p2); - int trig1, trig2, trig1b, trig2b; - - if (p1 == p2) - cout << "Add Segment, p1 == p2 == " << p1 << endl; - - // Test auf geschlossener Rand mit 2 Segmenten - - if ((j == 2) && (line->GetNS() == 2)) - { - int oldp1, oldp2; - line->GetSeg (1, oldp1, oldp2); - if (oldp1 == p2 && oldp2 == p1) - { - PrintMessage(7,"MESSAGE: don't use second segment"); - continue; - } - } - - - //mesh point number - //p1 = geom2meshnum.Get(p1); // for unmeshed lines!!! - //p2 = geom2meshnum.Get(p2); // for unmeshed lines!!! - - //left and right trigs - trig1 = line->GetLeftTrig(j); - trig2 = line->GetRightTrig(j); - trig1b = line->GetLeftTrig(j+1); - trig2b = line->GetRightTrig(j+1); - - (*testout) << "j = " << j << ", p1 = " << p1 << ", p2 = " << p2 << endl; - (*testout) << "segm-trigs: " - << "trig1 = " << trig1 - << ", trig1b = " << trig1b - << ", trig2 = " << trig2 - << ", trig2b = " << trig2b << endl; - - if (trig1 <= 0 || trig2 <= 0 || trig1b <= 0 || trig2b <= 0) - { - cout << "negative trigs, " - << ", trig1 = " << trig1 - << ", trig1b = " << trig1b - << ", trig2 = " << trig2 - << ", trig2b = " << trig2b << endl; - } - /* - (*testout) << " trigs p1: " << trig1 << " - " << trig2 << endl; - (*testout) << " trigs p2: " << trig1b << " - " << trig2b << endl; - (*testout) << " charts p1: " << geom.GetChartNr(trig1) << " - " << geom.GetChartNr(trig2) << endl; - (*testout) << " charts p2: " << geom.GetChartNr(trig1b) << " - " << geom.GetChartNr(trig2b) << endl; - */ - Point3d hp, hp2; - Segment seg; - seg.p1 = p1; - seg.p2 = p2; - seg.si = geom.GetTriangle(trig1).GetFaceNum(); - seg.edgenr = i; - - seg.epgeominfo[0].edgenr = i; - seg.epgeominfo[0].dist = line->GetDist(j); - seg.epgeominfo[1].edgenr = i; - seg.epgeominfo[1].dist = line->GetDist(j+1); - /* - (*testout) << "seg = " - << "edgenr " << seg.epgeominfo[0].edgenr - << " dist " << seg.epgeominfo[0].dist - << " edgenr " << seg.epgeominfo[1].edgenr - << " dist " << seg.epgeominfo[1].dist << endl; - */ - - seg.geominfo[0].trignum = trig1; - seg.geominfo[1].trignum = trig1b; - - /* - geom.SelectChartOfTriangle (trig1); - hp = hp2 = mesh.Point (seg.p1); - seg.geominfo[0].trignum = geom.Project (hp); - - (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[0].trignum << endl; - if (Dist (hp, hp2) > 1e-5 || seg.geominfo[0].trignum == 0) - { - (*testout) << "PROBLEM" << endl; - } - - geom.SelectChartOfTriangle (trig1b); - hp = hp2 = mesh.Point (seg.p2); - seg.geominfo[1].trignum = geom.Project (hp); - - (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[1].trignum << endl; - if (Dist (hp, hp2) > 1e-5 || seg.geominfo[1].trignum == 0) - { - (*testout) << "PROBLEM" << endl; - } - */ - - - if (Dist (mesh.Point(seg.p1), mesh.Point(seg.p2)) < 1e-10) - { - (*testout) << "ERROR: Line segment of length 0" << endl; - (*testout) << "pi1, 2 = " << seg.p1 << ", " << seg.p2 << endl; - (*testout) << "p1, 2 = " << mesh.Point(seg.p1) - << ", " << mesh.Point(seg.p2) << endl; - throw NgException ("Line segment of length 0"); - } - - mesh.AddSegment (seg); - - - Segment seg2; - seg2.p1 = p2; - seg2.p2 = p1; - seg2.si = geom.GetTriangle(trig2).GetFaceNum(); - seg2.edgenr = i; - - seg2.epgeominfo[0].edgenr = i; - seg2.epgeominfo[0].dist = line->GetDist(j+1); - seg2.epgeominfo[1].edgenr = i; - seg2.epgeominfo[1].dist = line->GetDist(j); - /* - (*testout) << "seg = " - << "edgenr " << seg2.epgeominfo[0].edgenr - << " dist " << seg2.epgeominfo[0].dist - << " edgenr " << seg2.epgeominfo[1].edgenr - << " dist " << seg2.epgeominfo[1].dist << endl; - */ - - seg2.geominfo[0].trignum = trig2b; - seg2.geominfo[1].trignum = trig2; - - /* - geom.SelectChartOfTriangle (trig2); - hp = hp2 = mesh.Point (seg.p1); - seg2.geominfo[0].trignum = geom.Project (hp); - - (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[0].trignum << endl; - if (Dist (hp, hp2) > 1e-5 || seg2.geominfo[0].trignum == 0) - { - (*testout) << "Get GeomInfo PROBLEM" << endl; - } - - - geom.SelectChartOfTriangle (trig2b); - hp = hp2 = mesh.Point (seg.p2); - seg2.geominfo[1].trignum = geom.Project (hp); - (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[1].trignum << endl; - if (Dist (hp, hp2) > 1e-5 || seg2.geominfo[1].trignum == 0) - { - (*testout) << "Get GeomInfo PROBLEM" << endl; - } - */ - - mesh.AddSegment (seg2); - - - /* - // should be start triangle and end triangle - int bothtrigs1[2] = { trig1, trig1 }; - meshing.AddBoundaryElement (p1, p2, sizeof (bothtrigs1), &bothtrigs1); - - int bothtrigs2[2] = { trig2, trig2 }; - meshing.AddBoundaryElement (p2, p1, sizeof (bothtrigs2), &bothtrigs2); - */ - } - } - - PopStatus(); -} - - - - -void STLSurfaceMeshing1 (STLGeometry & geom, - class Mesh & mesh, - int retrynr); - -int STLSurfaceMeshing (STLGeometry & geom, - class Mesh & mesh) -{ - int i, j; - PrintFnStart("Do Surface Meshing"); - - geom.PrepareSurfaceMeshing(); - - if (mesh.GetNSeg() == 0) - STLFindEdges (geom, mesh); - - int nopen; - int outercnt = 20; - - // mesh.Save ("mesh.edges"); - - for (i = 1; i <= mesh.GetNSeg(); i++) - { - const Segment & seg = mesh.LineSegment (i); - if (seg.geominfo[0].trignum <= 0 || seg.geominfo[1].trignum <= 0) - { - (*testout) << "Problem with segment " << i << ": " << seg << endl; - } - } - - - do - { - outercnt--; - if (outercnt <= 0) - return MESHING3_OUTERSTEPSEXCEEDED; - - if (multithread.terminate) - { - return MESHING3_TERMINATE; - } - - mesh.FindOpenSegments(); - nopen = mesh.GetNOpenSegments(); - - if (nopen) - { - int trialcnt = 0; - while (nopen && trialcnt <= 5) - { - if (multithread.terminate) - { - return MESHING3_TERMINATE; - } - trialcnt++; - STLSurfaceMeshing1 (geom, mesh, trialcnt); - - mesh.FindOpenSegments(); - nopen = mesh.GetNOpenSegments(); - - if (nopen) - { - geom.ClearMarkedSegs(); - for (i = 1; i <= nopen; i++) - { - const Segment & seg = mesh.GetOpenSegment (i); - geom.AddMarkedSeg(mesh.Point(seg.p1),mesh.Point(seg.p2)); - } - - geom.InitMarkedTrigs(); - for (i = 1; i <= nopen; i++) - { - const Segment & seg = mesh.GetOpenSegment (i); - geom.SetMarkedTrig(seg.geominfo[0].trignum,1); - geom.SetMarkedTrig(seg.geominfo[1].trignum,1); - } - - MeshOptimizeSTLSurface optmesh(geom); - optmesh.SetFaceIndex (0); - optmesh.SetImproveEdges (0); - optmesh.SetMetricWeight (0); - - mesh.CalcSurfacesOfNode(); - optmesh.EdgeSwapping (mesh, 0); - mesh.CalcSurfacesOfNode(); - optmesh.ImproveMesh (mesh); - } - - mesh.Compress(); - mesh.FindOpenSegments(); - nopen = mesh.GetNOpenSegments(); - - if (trialcnt <= 5 && nopen) - { - mesh.RemoveOneLayerSurfaceElements(); - - if (trialcnt >= 4) - { - mesh.FindOpenSegments(); - mesh.RemoveOneLayerSurfaceElements(); - - mesh.FindOpenSegments (); - nopen = mesh.GetNOpenSegments(); - } - } - } - - - if (multithread.terminate) - return MESHING3_TERMINATE; - - if (nopen) - { - - PrintMessage(3,"Meshing failed, trying to refine"); - - mesh.FindOpenSegments (); - nopen = mesh.GetNOpenSegments(); - - mesh.FindOpenSegments (); - mesh.RemoveOneLayerSurfaceElements(); - mesh.FindOpenSegments (); - mesh.RemoveOneLayerSurfaceElements(); - - // Open edge-segments will be refined ! - INDEX_2_HASHTABLE<int> openseght (nopen+1); - for (i = 1; i <= mesh.GetNOpenSegments(); i++) - { - const Segment & seg = mesh.GetOpenSegment (i); - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort(); - openseght.Set (i2, 1); - } - - - mesh.FindOpenSegments (); - mesh.RemoveOneLayerSurfaceElements(); - mesh.FindOpenSegments (); - mesh.RemoveOneLayerSurfaceElements(); - - - INDEX_2_HASHTABLE<int> newpht(100); - - int nsegold = mesh.GetNSeg(); - for (i = 1; i <= nsegold; i++) - { - Segment seg = mesh.LineSegment(i); - INDEX_2 i2(seg.p1, seg.p2); - i2.Sort(); - if (openseght.Used (i2)) - { - // segment will be split - PrintMessage(7,"Split segment ", int(seg.p1), "-", int(seg.p2)); - - Segment nseg1, nseg2; - EdgePointGeomInfo newgi; - - const EdgePointGeomInfo & gi1 = seg.epgeominfo[0]; - const EdgePointGeomInfo & gi2 = seg.epgeominfo[1]; - - newgi.dist = 0.5 * (gi1.dist + gi2.dist); - newgi.edgenr = gi1.edgenr; - - int hi; - - Point3d newp; - int newpi; - - if (!newpht.Used (i2)) - { - newp = geom.GetLine (gi1.edgenr)-> - GetPointInDist (geom.GetPoints(), newgi.dist, hi); - newpi = mesh.AddPoint (newp); - newpht.Set (i2, newpi); - } - else - { - newpi = newpht.Get (i2); - newp = mesh.Point (newpi); - } - - nseg1 = seg; - nseg2 = seg; - nseg1.p2 = newpi; - nseg1.epgeominfo[1] = newgi; - - nseg2.p1 = newpi; - nseg2.epgeominfo[0] = newgi; - - mesh.LineSegment(i) = nseg1; - mesh.AddSegment (nseg2); - - mesh.RestrictLocalH (Center (mesh.Point(nseg1.p1), - mesh.Point(nseg1.p2)), - Dist (mesh.Point(nseg1.p1), - mesh.Point(nseg1.p2))); - mesh.RestrictLocalH (Center (mesh.Point(nseg2.p1), - mesh.Point(nseg2.p2)), - Dist (mesh.Point(nseg2.p1), - mesh.Point(nseg2.p2))); - } - } - - } - - nopen = -1; - } - - else - - { - PrintMessage(5,"mesh is closed, verifying ..."); - - // no open elements, check wrong elemetns (intersecting..) - - - - PrintMessage(5,"check overlapping"); - // mesh.FindOpenElements(); // would leed to locked points - mesh.CheckOverlappingBoundary(); - - geom.InitMarkedTrigs(); - - for (i = 1; i <= mesh.GetNSE(); i++) - if (mesh.SurfaceElement(i).BadElement()) - { - int trig = mesh.SurfaceElement(i).PNum(1); - geom.SetMarkedTrig(trig,1); - PrintMessage(7, "overlapping element, will be removed"); - } - - - - ARRAY<Point3d> refpts; - ARRAY<double> refh; - - // was commented: - - for (i = 1; i <= mesh.GetNSE(); i++) - if (mesh.SurfaceElement(i).BadElement()) - { - for (j = 1; j <= 3; j++) - { - refpts.Append (mesh.Point (mesh.SurfaceElement(i).PNum(j))); - refh.Append (mesh.GetH (refpts.Last()) / 2); - } - mesh.DeleteSurfaceElement(i); - } - - // delete wrong oriented element - for (i = 1; i <= mesh.GetNSE(); i++) - { - const Element2d & el = mesh.SurfaceElement(i); - if (!el.PNum(1)) - continue; - - Vec3d n = Cross (Vec3d (mesh.Point(el.PNum(1)), - mesh.Point(el.PNum(2))), - Vec3d (mesh.Point(el.PNum(1)), - mesh.Point(el.PNum(3)))); - Vec3d ng = geom.GetTriangle(el.GeomInfoPi(1).trignum).Normal(); - if (n * ng < 0) - { - refpts.Append (mesh.Point (mesh.SurfaceElement(i).PNum(1))); - refh.Append (mesh.GetH (refpts.Last()) / 2); - mesh.DeleteSurfaceElement(i); - } - } - // end comments - - for (i = 1; i <= refpts.Size(); i++) - mesh.RestrictLocalH (refpts.Get(i), refh.Get(i)); - - mesh.RemoveOneLayerSurfaceElements(); - - mesh.Compress(); - - mesh.FindOpenSegments (); - nopen = mesh.GetNOpenSegments(); - - /* - if (!nopen) - { - // mesh is still ok - - void STLSurfaceOptimization (STLGeometry & geom, - class Mesh & mesh, - MeshingParameters & mparam) - - } - */ - } - - } - while (nopen); - - mesh.Compress(); - mesh.CalcSurfacesOfNode(); - - return MESHING3_OK; -} - - - - - - -void STLSurfaceMeshing1 (STLGeometry & geom, - class Mesh & mesh, - int retrynr) -{ - int i, j, k; - double h; - - - h = mparam.maxh; - - mesh.FindOpenSegments(); - - ARRAY<int> spiralps(0); - spiralps.SetSize(0); - for (i = 1; i <= geom.GetNP(); i++) - { - if (geom.GetSpiralPoint(i)) {spiralps.Append(i);} - } - - PrintMessage(7,"NO spiralpoints = ", spiralps.Size()); - int spfound; - int sppointnum; - int spcnt = 0; - - ARRAY<int> meshsp(mesh.GetNP()); - for (i = 1; i <= mesh.GetNP(); i++) - { - meshsp.Elem(i) = 0; - for (j = 1; j <= spiralps.Size(); j++) - if (Dist2(geom.GetPoint(spiralps.Get(j)), mesh.Point(i)) < 1e-20) - meshsp.Elem(i) = spiralps.Get(j); - } - - - ARRAY<int> opensegsperface(mesh.GetNFD()); - for (i = 1; i <= mesh.GetNFD(); i++) - opensegsperface.Elem(i) = 0; - for (i = 1; i <= mesh.GetNOpenSegments(); i++) - { - int si = mesh.GetOpenSegment (i).si; - if (si >= 1 && si <= mesh.GetNFD()) - { - opensegsperface.Elem(si)++; - } - else - { - cerr << "illegal face index" << endl; - } - } - - - double starttime = GetTime (); - - for (int fnr = 1; fnr <= mesh.GetNFD(); fnr++) - if (opensegsperface.Get(fnr)) - { - if (multithread.terminate) - return; - - PrintMessage(5,"Meshing surface ", fnr, "/", mesh.GetNFD()); - MeshingSTLSurface meshing (geom); - - meshing.SetStartTime (starttime); - - for (i = 1; i <= mesh.GetNP(); i++) - { - /* - spfound = 0; - for (j = 1; j <= spiralps.Size(); j++) - { - if (Dist2(geom.GetPoint(spiralps.Get(j)),mesh.Point(i)) < 1e-20) - {spfound = 1; sppointnum = spiralps.Get(j);} - } - */ - sppointnum = 0; - if (i <= meshsp.Size()) - sppointnum = meshsp.Get(i); - - //spfound = 0; - if (sppointnum) - { - MultiPointGeomInfo mgi; - - int ntrigs = geom.NOTrigsPerPoint(sppointnum); - spcnt++; - - for (j = 0; j < ntrigs; j++) - { - PointGeomInfo gi; - gi.trignum = geom.TrigPerPoint(sppointnum, j+1); - mgi.AddPointGeomInfo (gi); - } - - // Einfuegen von ConePoint: Point bekommt alle - // Dreiecke (werden dann intern kopiert) - // Ein Segment zum ConePoint muss vorhanden sein !!! - - meshing.AddPoint (mesh.Point(i), i, &mgi); - - } - else - { - meshing.AddPoint (mesh.Point(i), i); - } - } - - - for (i = 1; i <= mesh.GetNOpenSegments(); i++) - { - const Segment & seg = mesh.GetOpenSegment (i); - if (seg.si == fnr) - meshing.AddBoundaryElement (seg.p1, seg.p2, seg.geominfo[0], seg.geominfo[1]); - } - - - PrintMessage(3,"start meshing, trialcnt = ", retrynr); - - /* - (*testout) << "start meshing with h = " << h << endl; - */ - meshing.GenerateMesh (mesh, h, fnr); // face index -#ifdef OPENGL - extern void Render(); - Render(); -#endif - } - - - mesh.CalcSurfacesOfNode(); -} - - - -void STLSurfaceOptimization (STLGeometry & geom, - class Mesh & mesh, - MeshingParameters & mparam) -{ - PrintFnStart("optimize STL Surface"); - - - MeshOptimizeSTLSurface optmesh(geom); - // - - int i, j; - /* - for (i = 1; i <= mparam.optsteps2d; i++) - { - EdgeSwapping (mesh, 1, 1); - CombineImprove (mesh, 1); - optmesh.ImproveMesh (mesh, 0, 10, 1, 1); - } - */ - - optmesh.SetFaceIndex (0); - optmesh.SetImproveEdges (0); - optmesh.SetMetricWeight (mparam.elsizeweight); - - PrintMessage(5,"optimize string = ", mparam.optimize2d, " elsizew = ", mparam.elsizeweight); - - for (i = 1; i <= mparam.optsteps2d; i++) - for (j = 1; j <= strlen(mparam.optimize2d); j++) - { - if (multithread.terminate) - break; - - (*testout) << "optimize, before, step = " << mparam.optimize2d[j-1] << mesh.Point (3679) << endl; - - mesh.CalcSurfacesOfNode(); - switch (mparam.optimize2d[j-1]) - { - case 's': - { - optmesh.EdgeSwapping (mesh, 0); - break; - } - case 'S': - { - optmesh.EdgeSwapping (mesh, 1); - break; - } - case 'm': - { - optmesh.ImproveMesh(mesh); - break; - } - case 'c': - { - optmesh.CombineImprove (mesh); - break; - } - } - (*testout) << "optimize, after, step = " << mparam.optimize2d[j-1] << mesh.Point (3679) << endl; - } - - geom.surfaceoptimized = 1; - - mesh.Compress(); - mesh.CalcSurfacesOfNode(); - - -} - - - -MeshingSTLSurface :: MeshingSTLSurface (STLGeometry & ageom) - : Meshing2(Box3d (ageom.GetBoundingBox().PMin(), - ageom.GetBoundingBox().PMax())), geom(ageom) -{ - ; -} - -void MeshingSTLSurface :: DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo, - const PointGeomInfo * geominfo2) -{ - transformationtrig = geominfo[0].trignum; - - geom.DefineTangentialPlane(p1, p2, transformationtrig); -} - -void MeshingSTLSurface :: TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & gi, - Point2d & plainpoint, double h, int & zone) -{ - int trigs[10000]; - int i; - - if (gi.GetNPGI() >= 9999) - { - PrintError("In Transform to plane: increase size of trigs!!!"); - } - - for (i = 1; i <= gi.GetNPGI(); i++) - trigs[i-1] = gi.GetPGI(i).trignum; - trigs[gi.GetNPGI()] = 0; - - // int trig = gi.trignum; - // (*testout) << "locpoint = " << locpoint; - - Point<2> hp2d; - geom.ToPlane (locpoint, trigs, hp2d, h, zone, 1); - plainpoint = hp2d; - - // geom.ToPlane (locpoint, NULL, plainpoint, h, zone, 1); - /* - (*testout) << " plainpoint = " << plainpoint - << " h = " << h - << endl; - */ -} - -/* -int MeshingSTLSurface :: ComputeLineGeoInfo (const Point3d & p1, const Point3d & p2, - int & geoinfosize, void *& geoinfo) -{ - static int geomtrig[2] = { 0, 0 }; - - Point3d hp; - hp = p1; - geomtrig[0] = geom.Project (hp); - - hp = p2; - geomtrig[1] = geom.Project (hp); - - geoinfosize = sizeof (geomtrig); - geoinfo = &geomtrig; - - if (geomtrig[0] == 0) - { - return 1; - } - return 0; -} -*/ - - -int MeshingSTLSurface :: ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi) -{ - // compute triangle of point, - // if non-unique: 0 - - Point<3> hp = p; - gi.trignum = geom.Project (hp); - - if (!gi.trignum) - { - return 1; - } - - return 0; -} - - -int MeshingSTLSurface :: -ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, - PointGeomInfo & pgi) -{ - int i; - - for (i = 1; i <= mpgi.GetNPGI(); i++) - if (geom.TrigIsInOC (mpgi.GetPGI(i).trignum, geom.meshchart)) - { - pgi = mpgi.GetPGI(i); - return 0; - } - /* - for (i = 0; i < mpgi.cnt; i++) - { - // (*testout) << "d" << endl; - if (geom.TrigIsInOC (mpgi.mgi[i].trignum, geom.meshchart)) - { - pgi = mpgi.mgi[i]; - return 0; - } - } - */ - PrintMessage(7,"INFORM: no gi on chart"); - pgi.trignum = 1; - return 1; -} - - - -int MeshingSTLSurface :: -IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, - int endpoint, const PointGeomInfo & gi) -{ - Vec3d baselinenormal = geom.meshtrignv; - - int lineendtrig = gi.trignum; - - - return geom.TrigIsInOC (lineendtrig, geom.meshchart); - - // Vec3d linenormal = geom.GetTriangleNormal (lineendtrig); - // return ( (baselinenormal * linenormal) > cos (30 * (M_PI/180)) ); -} - -void MeshingSTLSurface :: -GetChartBoundary (ARRAY<Point2d > & points, - ARRAY<Point3d > & points3d, - ARRAY<INDEX_2> & lines, double h) const -{ - points.SetSize (0); - points3d.SetSize (0); - lines.SetSize (0); - geom.GetMeshChartBoundary (points, points3d, lines, h); -} - - - - -int MeshingSTLSurface :: TransformFromPlain (Point2d & plainpoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h) -{ - //return 0, wenn alles OK - Point<3> hp3d; - int res = geom.FromPlane (plainpoint, hp3d, h); - locpoint = hp3d; - ComputePointGeomInfo (locpoint, gi); - return res; -} - - -int MeshingSTLSurface :: -BelongsToActiveChart (const Point3d & p, - const PointGeomInfo & gi) -{ - return (geom.TrigIsInOC(gi.trignum, geom.meshchart) != 0); -} - - - -double MeshingSTLSurface :: CalcLocalH (const Point3d & p, double gh) const -{ - return gh; -} - -double MeshingSTLSurface :: Area () const -{ - return geom.Area(); -} - - - - - - -MeshOptimizeSTLSurface :: MeshOptimizeSTLSurface (STLGeometry & ageom) - : MeshOptimize2d(), geom(ageom) -{ - ; -} - - -void MeshOptimizeSTLSurface :: SelectSurfaceOfPoint (const Point3d & p, - const PointGeomInfo & gi) -{ - // (*testout) << "sel char: " << gi.trignum << endl; - - geom.SelectChartOfTriangle (gi.trignum); - // geom.SelectChartOfPoint (p); -} - - -void MeshOptimizeSTLSurface :: ProjectPoint (INDEX surfind, Point3d & p) const -{ - Point<3> hp = p; - if (!geom.Project (hp)) - { - PrintMessage(7,"project failed"); - - if (!geom.ProjectOnWholeSurface(hp)) - { - PrintMessage(7, "project on whole surface failed"); - } - } - p = hp; - // geometry.GetSurface(surfind)->Project (p); -} - -void MeshOptimizeSTLSurface :: ProjectPoint2 (INDEX surfind, INDEX surfind2, Point3d & p) const -{ - /* - ProjectToEdge ( geometry.GetSurface(surfind), - geometry.GetSurface(surfind2), p); - */ -} - -int MeshOptimizeSTLSurface :: CalcPointGeomInfo(PointGeomInfo& gi, const Point3d& p3) const -{ - Point<3> hp = p3; - gi.trignum = geom.Project (hp); - - if (gi.trignum) - { - return 1; - } - - return 0; - -} - -void MeshOptimizeSTLSurface :: GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const -{ - n = geom.GetChartNormalVector(); - - /* - geometry.GetSurface(surfind)->CalcGradient (p, n); - n /= n.Length(); - if (geometry.GetSurface(surfind)->Inverse()) - n *= -1; - */ -} - - - - - - - - - - -RefinementSTLGeometry :: RefinementSTLGeometry (const STLGeometry & ageom) - : Refinement(), geom(ageom) -{ - ; -} - -RefinementSTLGeometry :: ~RefinementSTLGeometry () -{ - ; -} - -void RefinementSTLGeometry :: -PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi) -{ - newp = p1+secpoint*(p2-p1); - - /* - (*testout) << "surf-between: p1 = " << p1 << ", p2 = " << p2 - << ", gi = " << gi1 << " - " << gi2 << endl; - */ - - if (gi1.trignum > 0) - { - // ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum); - - Point<3> np1 = newp; - Point<3> np2 = newp; - ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum); - int tn1 = geom.Project (np1); - - ((STLGeometry&)geom).SelectChartOfTriangle (gi2.trignum); - int tn2 = geom.Project (np2); - - newgi.trignum = tn1; //urspruengliche version - newp = np1; //urspruengliche version - - if (!newgi.trignum) - { newgi.trignum = tn2; newp = np2; } - if (!newgi.trignum) newgi.trignum = gi1.trignum; - - /* - if (tn1 != 0 && tn2 != 0 && ((STLGeometry&)geom).GetAngle(tn1,tn2) < M_PI*0.05) { - newgi.trignum = tn1; - newp = np1; - } - else - { - newp = ((STLGeometry&)geom).PointBetween(p1, gi1.trignum, p2, gi2.trignum); - tn1 = ((STLGeometry&)geom).Project(newp); - newgi.trignum = tn1; - - if (!tn1) - { - newp = Center (p1, p2); - newgi.trignum = 0; - - } - } - */ - } - else - { - // (*testout) << "WARNING: PointBetween got geominfo = 0" << endl; - newp = p1+secpoint*(p2-p1); - newgi.trignum = 0; - } - - // (*testout) << "newp = " << newp << ", ngi = " << newgi << endl; -} - -void RefinementSTLGeometry :: -PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & gi1, - const EdgePointGeomInfo & gi2, - Point3d & newp, EdgePointGeomInfo & newgi) -{ - /* - (*testout) << "edge-between: p1 = " << p1 << ", p2 = " << p2 - << ", gi1,2 = " << gi1 << ", " << gi2 << endl; - */ - /* - newp = Center (p1, p2); - ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum); - newgi.trignum = geom.Project (newp); - */ - int hi; - newgi.dist = (1.0-secpoint) * gi1.dist + secpoint*gi2.dist; - newgi.edgenr = gi1.edgenr; - - /* - (*testout) << "p1 = " << p1 << ", p2 = " << p2 << endl; - (*testout) << "refedge: " << gi1.edgenr - << " d1 = " << gi1.dist << ", d2 = " << gi2.dist << endl; - */ - newp = geom.GetLine (gi1.edgenr)->GetPointInDist (geom.GetPoints(), newgi.dist, hi); - - // (*testout) << "newp = " << newp << endl; -} - - -void RefinementSTLGeometry :: ProjectToSurface (Point<3> & p, int surfi) -{ - cout << "RefinementSTLGeometry :: ProjectToSurface not implemented!" << endl; -} - - -void RefinementSTLGeometry :: ProjectToSurface (Point<3> & p, int surfi, - PointGeomInfo & gi) -{ - ((STLGeometry&)geom).SelectChartOfTriangle (gi.trignum); - gi.trignum = geom.Project (p); - // if (!gi.trignum) - // cout << "projectSTL failed" << endl; -} - - -} diff --git a/Netgen/libsrc/stlgeom/meshstlsurface.hpp b/Netgen/libsrc/stlgeom/meshstlsurface.hpp deleted file mode 100644 index f190d107a5..0000000000 --- a/Netgen/libsrc/stlgeom/meshstlsurface.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef FILE_MESHSTLSURF -#define FILE_MESHSTLSURF - -/* *************************************************************************/ -/* File: meshstlsurf.hpp */ -/* Author: Johannes Gerstmayr, Joachim Schoeberl */ -/* Date: 01. Aug. 99 */ -/* *************************************************************************/ - -/* - -The interface between mesh generation and stl geometry - -*/ - - -/// -class MeshingSTLSurface : public Meshing2 -{ - /// - STLGeometry & geom; - /// - int transformationtrig; -public: - /// - MeshingSTLSurface (STLGeometry & ageom); - -protected: - /// - virtual void DefineTransformation (Point3d & p1, Point3d & p2, - const PointGeomInfo * geominfo1, - const PointGeomInfo * geominfo2); - /// - virtual void TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & geominfo, - Point2d & plainpoint, double h, int & zone); - /// - virtual int TransformFromPlain (Point2d & plainpoint, - Point3d & locpoint, - PointGeomInfo & gi, - double h); - /// - virtual int BelongsToActiveChart (const Point3d & p, - const PointGeomInfo & gi); - - /// - virtual int ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi); - /// - virtual int ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, - PointGeomInfo & pgi); - - /// - virtual int IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, - int endpoint, const PointGeomInfo & gi); - - virtual void GetChartBoundary (ARRAY<Point2d > & points, - ARRAY<Point3d > & poitns3d, - ARRAY<INDEX_2> & lines, double h) const; - - /// - virtual double CalcLocalH (const Point3d & p, double gh) const; - - /// - virtual double Area () const; -}; - - - -/// -class MeshOptimizeSTLSurface : public MeshOptimize2d - { - /// - STLGeometry & geom; - -public: - /// - MeshOptimizeSTLSurface (STLGeometry & ageom); - - /// - virtual void SelectSurfaceOfPoint (const Point3d & p, - const PointGeomInfo & gi); - /// - virtual void ProjectPoint (INDEX surfind, Point3d & p) const; - /// - virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point3d & p) const; - /// - virtual int CalcPointGeomInfo(PointGeomInfo& gi, const Point3d& p3) const; - /// - virtual void GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const; -}; - - - - -class RefinementSTLGeometry : public Refinement -{ - const STLGeometry & geom; - -public: - RefinementSTLGeometry (const STLGeometry & ageom); - virtual ~RefinementSTLGeometry (); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi, - const PointGeomInfo & gi1, - const PointGeomInfo & gi2, - Point3d & newp, PointGeomInfo & newgi); - - virtual void PointBetween (const Point3d & p1, const Point3d & p2, double secpoint, - int surfi1, int surfi2, - const EdgePointGeomInfo & ap1, - const EdgePointGeomInfo & ap2, - Point3d & newp, EdgePointGeomInfo & newgi); - - virtual void ProjectToSurface (Point<3> & p, int surfi); - virtual void ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi); -}; - - - -#endif - diff --git a/Netgen/libsrc/stlgeom/stlgeom.cpp b/Netgen/libsrc/stlgeom/stlgeom.cpp deleted file mode 100644 index 2d3a358cfa..0000000000 --- a/Netgen/libsrc/stlgeom/stlgeom.cpp +++ /dev/null @@ -1,3476 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - -#include "stlgeom.hpp" - - -namespace netgen -{ - -//globalen searchtree fuer gesamte geometry aktivieren -int geomsearchtreeon = 0; - -int usechartnormal = 1; - -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -void STLMeshing (STLGeometry & geom, - Mesh & mesh) -{ - geom.Clear(); - geom.BuildEdges(); - geom.MakeAtlas(mesh); - geom.CalcFaceNums(); - geom.AddFaceEdges(); - geom.LinkEdges(); - - mesh.ClearFaceDescriptors(); - for (int i = 1; i <= geom.GetNOFaces(); i++) - mesh.AddFaceDescriptor (FaceDescriptor (i, 1, 0, 0)); -} - -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -//+++++++++++++++++++ STL GEOMETRY ++++++++++++++++++++++++++++ -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -STLGeometry :: STLGeometry() - : edges(), edgesperpoint(), - normals(), externaledges(), - atlas(), chartmark(), - lines(), outerchartspertrig(), vicinity(), markedtrigs(), markedsegs(), - lineendpoints(), spiralpoints(), edgedata(*this), selectedmultiedge() -{ - externaledges.SetSize(0); - Clear(); - meshchart = 0; // initialize all ?? JS - - if (geomsearchtreeon) - searchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1), - GetBoundingBox().PMax() + Vec3d(1,1,1)); - else - searchtree = NULL; - - status = STL_GOOD; - statustext = "Good Geometry"; - smoothedges = NULL; -} - -STLGeometry :: ~STLGeometry() -{ - ; -} - -void STLGeometry :: STLInfo(double* data) -{ - data[0] = GetNT(); - - Box<3> b = GetBoundingBox(); - data[1] = b.PMin()(0); - data[2] = b.PMax()(0); - data[3] = b.PMin()(1); - data[4] = b.PMax()(1); - data[5] = b.PMin()(2); - data[6] = b.PMax()(2); - - int i; - - int cons = 1; - for (i = 1; i <= GetNT(); i++) - { - if (NONeighbourTrigs(i) != 3) {cons = 0;} - } - data[7] = cons; -} - -void STLGeometry :: MarkNonSmoothNormals() -{ - - PrintFnStart("Mark Non-Smooth Normals"); - - int i,j; - - markedtrigs.SetSize(GetNT()); - - for (i = 1; i <= GetNT(); i++) - { - SetMarkedTrig(i, 0); - } - - double dirtyangle = stlparam.yangle/180.*M_PI; - - int cnt = 0; - int p1,p2; - for (i = 1; i <= GetNT(); i++) - { - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - if (GetAngle(i, NeighbourTrig(i,j)) > dirtyangle) - { - GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), p1, p2); - if (!IsEdge(p1,p2)) - { - if (!IsMarkedTrig(i)) {SetMarkedTrig(i,1); cnt++;} - } - } - } - } - - PrintMessage(5,"marked ",cnt," non-smooth trig-normals"); - -} - -void STLGeometry :: SmoothNormals() -{ - multithread.terminate = 0; - - // UseExternalEdges(); - - BuildEdges(); - - - DenseMatrix m(3), hm(3); - Vector rhs(3), sol(3), hv(3), hv2(3); - - Vec<3> ri; - - double wnb = stldoctor.smoothnormalsweight; // neigbour normal weight - double wgeom = 1-wnb; // geometry normal weight - - - // minimize - // wgeom sum_T \sum ri \| ri^T (n - n_geom) \|^2 - // + wnb sum_SE \| ri x (n - n_nb) \|^2 - - int i, j, k, l; - int nt = GetNT(); - - PushStatusF("Smooth Normals"); - - int testmode; - - for (i = 1; i <= nt; i++) - { - - SetThreadPercent( 100.0 * (double)i / (double)nt); - - const STLTriangle & trig = GetTriangle (i); - - m = 0; - rhs = 0; - - // normal of geometry: - Vec<3> ngeom = trig.GeomNormal(points); - ngeom.Normalize(); - - for (j = 1; j <= 3; j++) - { - int pi1 = trig.PNumMod (j); - int pi2 = trig.PNumMod (j+1); - - // edge vector - ri = GetPoint (pi2) - GetPoint (pi1); - - for (k = 0; k < 3; k++) - for (l = 0; l < 3; l++) - hm.Elem(k+1, l+1) = wgeom * ri(k) * ri(l); - - - for (k = 0; k < 3; k++) - hv.Elem(k+1) = ngeom(k); - - hm.Mult (hv, hv2); - /* - if (testmode) - (*testout) << "add vec " << hv2 << endl - << " add m " << hm << endl; - */ - rhs.Add (1, hv2); - m += hm; - - - int nbt = 0; - int fp1,fp2; - for (k = 1; k <= NONeighbourTrigs(i); k++) - { - trig.GetNeighbourPoints(GetTriangle(NeighbourTrig(i, k)),fp1,fp2); - if (fp1 == pi1 && fp2 == pi2) - { - nbt = NeighbourTrig(i, k); - } - } - - if (!nbt) - { - cerr << "ERROR: stlgeom::Smoothnormals, nbt = 0" << endl; - } - - // smoothed normal - Vec<3> nnb = GetTriangle(nbt).Normal(); // neighbour normal - nnb.Normalize(); - - if (!IsEdge(pi1,pi2)) - { - double lr2 = ri * ri; - for (k = 0; k < 3; k++) - { - for (l = 0; l < k; l++) - { - hm.Elem(k+1, l+1) = -wnb * ri(k) * ri(l); - hm.Elem(l+1, k+1) = -wnb * ri(k) * ri(l); - } - - hm.Elem(k+1, k+1) = wnb * (lr2 - ri(k) * ri(k)); - } - - for (k = 0; k < 3; k++) - hv.Elem(k+1) = nnb(k); - - hm.Mult (hv, hv2); - /* - if (testmode) - (*testout) << "add nb vec " << hv2 << endl - << " add nb m " << hm << endl; - */ - - rhs.Add (1, hv2); - m += hm; - } - } - - m.Solve (rhs, sol); - Vec3d newn(sol.Get(1), sol.Get(2), sol.Get(3)); - newn /= (newn.Length() + 1e-24); - - GetTriangle(i).SetNormal(newn); - // setnormal (sol); - } - - /* - for (i = 1; i <= nt; i++) - SetMarkedTrig(i, 0); - - - - int crloop; - for (crloop = 1; crloop <= 3; crloop++) - { - - // find critical: - - ARRAY<INDEX_2> critpairs; - for (i = 1; i <= nt; i++) - { - const STLTriangle & trig = GetTriangle (i); - - Vec3d ngeom = GetTriangleNormal (i); // trig.Normal(points); - ngeom /= (ngeom.Length() + 1e-24); - - for (j = 1; j <= 3; j++) - { - int pi1 = trig.PNumMod (j); - int pi2 = trig.PNumMod (j+1); - - int nbt = 0; - int fp1,fp2; - for (k = 1; k <= NONeighbourTrigs(i); k++) - { - trig.GetNeighbourPoints(GetTriangle(NeighbourTrig(i, k)),fp1,fp2); - if (fp1 == pi1 && fp2 == pi2) - { - nbt = NeighbourTrig(i, k); - } - } - - if (!nbt) - { - cerr << "ERROR: stlgeom::Smoothnormals, nbt = 0" << endl; - } - - Vec3d nnb = GetTriangleNormal(nbt); // neighbour normal - nnb /= (nnb.Length() + 1e-24); - - if (!IsEdge(pi1,pi2)) - { - if (Angle (nnb, ngeom) > 150 * M_PI/180) - { - SetMarkedTrig(i, 1); - SetMarkedTrig(nbt, 1); - critpairs.Append (INDEX_2 (i, nbt)); - } - } - - } - } - - if (!critpairs.Size()) - { - break; - } - - if (critpairs.Size()) - { - - ARRAY<int> friends; - double area1 = 0, area2 = 0; - - for (i = 1; i <= critpairs.Size(); i++) - { - int tnr1 = critpairs.Get(i).I1(); - int tnr2 = critpairs.Get(i).I2(); - (*testout) << "t1 = " << tnr1 << ", t2 = " << tnr2 - << " angle = " << Angle (GetTriangleNormal (tnr1), - GetTriangleNormal (tnr2)) - << endl; - - // who has more friends ? - int side; - area1 = 0; - area2 = 0; - for (side = 1; side <= 2; side++) - { - friends.SetSize (0); - friends.Append ( (side == 1) ? tnr1 : tnr2); - - for (j = 1; j <= 3; j++) - { - int fsize = friends.Size(); - for (k = 1; k <= fsize; k++) - { - int testtnr = friends.Get(k); - Vec3d ntt = GetTriangleNormal(testtnr); - ntt /= (ntt.Length() + 1e-24); - - for (l = 1; l <= NONeighbourTrigs(testtnr); l++) - { - int testnbnr = NeighbourTrig(testtnr, l); - Vec3d nbt = GetTriangleNormal(testnbnr); - nbt /= (nbt.Length() + 1e-24); - - if (Angle (nbt, ntt) < 15 * M_PI/180) - { - int ii; - int found = 0; - for (ii = 1; ii <= friends.Size(); ii++) - { - if (friends.Get(ii) == testnbnr) - { - found = 1; - break; - } - } - if (!found) - friends.Append (testnbnr); - } - } - } - } - - // compute area: - for (k = 1; k <= friends.Size(); k++) - { - double area = - GetTriangle (friends.Get(k)).Area(points); - - if (side == 1) - area1 += area; - else - area2 += area; - } - - } - - (*testout) << "area1 = " << area1 << " area2 = " << area2 << endl; - if (area1 < 0.1 * area2) - { - Vec3d n = GetTriangleNormal (tnr1); - n *= -1; - SetTriangleNormal(tnr1, n); - } - if (area2 < 0.1 * area1) - { - Vec3d n = GetTriangleNormal (tnr2); - n *= -1; - SetTriangleNormal(tnr2, n); - } - } - } - } - */ - - calcedgedataanglesnew = 1; - PopStatus(); -} - - -int STLGeometry :: AddEdge(int p1, int p2) -{ - STLEdge e(p1,p2); - e.SetLeftTrig(GetLeftTrig(p1,p2)); - e.SetRightTrig(GetRightTrig(p1,p2)); - return edges.Append(e); -} - -void STLGeometry :: STLDoctorConfirmEdge() -{ - StoreEdgeData(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) - { - if (stldoctor.selectmode == 1) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus (ED_CONFIRMED); - } - else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) - { - int i; - for (i = 1; i <= selectedmultiedge.Size(); i++) - { - int p1 = selectedmultiedge.Get(i).i1; - int p2 = selectedmultiedge.Get(i).i2; - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus (ED_CONFIRMED); - } - } - } -} - -void STLGeometry :: STLDoctorCandidateEdge() -{ - StoreEdgeData(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) - { - if (stldoctor.selectmode == 1) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus (ED_CANDIDATE); - } - else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) - { - int i; - for (i = 1; i <= selectedmultiedge.Size(); i++) - { - int p1 = selectedmultiedge.Get(i).i1; - int p2 = selectedmultiedge.Get(i).i2; - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus (ED_CANDIDATE); - } - } - } -} - -void STLGeometry :: STLDoctorExcludeEdge() -{ - StoreEdgeData(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) - { - if (stldoctor.selectmode == 1) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus(ED_EXCLUDED); - } - else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) - { - int i; - for (i = 1; i <= selectedmultiedge.Size(); i++) - { - int p1 = selectedmultiedge.Get(i).i1; - int p2 = selectedmultiedge.Get(i).i2; - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus(ED_EXCLUDED); - } - } - } -} - -void STLGeometry :: STLDoctorUndefinedEdge() -{ - StoreEdgeData(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) - { - if (stldoctor.selectmode == 1) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus(ED_UNDEFINED); - } - else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) - { - int i; - for (i = 1; i <= selectedmultiedge.Size(); i++) - { - int p1 = selectedmultiedge.Get(i).i1; - int p2 = selectedmultiedge.Get(i).i2; - edgedata.Elem(edgedata.GetEdgeNum(p1,p2)).SetStatus(ED_UNDEFINED); - } - } - } -} - -void STLGeometry :: STLDoctorSetAllUndefinedEdges() -{ - edgedata.ResetAll(); -} - -void STLGeometry :: STLDoctorEraseCandidateEdges() -{ - StoreEdgeData(); - edgedata.ChangeStatus(ED_CANDIDATE, ED_UNDEFINED); -} - -void STLGeometry :: STLDoctorConfirmCandidateEdges() -{ - StoreEdgeData(); - edgedata.ChangeStatus(ED_CANDIDATE, ED_CONFIRMED); -} - -void STLGeometry :: STLDoctorConfirmedToCandidateEdges() -{ - StoreEdgeData(); - edgedata.ChangeStatus(ED_CONFIRMED, ED_CANDIDATE); -} - -void STLGeometry :: STLDoctorDirtyEdgesToCandidates() -{ - StoreEdgeData(); -} - -void STLGeometry :: STLDoctorLongLinesToCandidates() -{ - StoreEdgeData(); -} - -twoint STLGeometry :: GetNearestSelectedDefinedEdge() -{ - Point<3> pestimate = Center(GetTriangle(GetSelectTrig()).center, - GetPoint(GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()))); - //Point3d pestimate = GetTriangle(GetSelectTrig()).center; - - int i, j, en; - ARRAY<int> vic; - GetVicinity(GetSelectTrig(),4,vic); - - - twoint fedg; - fedg.i1 = 0; - fedg.i2 = 0; - double mindist = 1E50; - double dist; - Point<3> p; - - for (i = 1; i <= vic.Size(); i++) - { - const STLTriangle& t = GetTriangle(vic.Get(i)); - for (j = 1; j <= 3; j++) - { - en = edgedata.GetEdgeNum(t.PNum(j),t.PNumMod(j+1)); - if (edgedata.Get(en).GetStatus() != ED_UNDEFINED) - { - p = pestimate; - dist = GetDistFromLine(GetPoint(t.PNum(j)),GetPoint(t.PNumMod(j+1)),p); - if (dist < mindist) - { - mindist = dist; - fedg.i1 = t.PNum(j); - fedg.i2 = t.PNumMod(j+1); - } - } - } - } - return fedg; -} - -void STLGeometry :: BuildSelectedMultiEdge(twoint ep) -{ - if (edgedata.Size() == 0 || - !GetEPPSize()) - { - return; - } - - selectedmultiedge.SetSize(0); - int tenum = GetTopEdgeNum (ep.i1, ep.i2); - - if (edgedata.Get(tenum).GetStatus() == ED_UNDEFINED) - { - twoint epnew = GetNearestSelectedDefinedEdge(); - if (epnew.i1) - { - ep = epnew; - tenum = GetTopEdgeNum (ep.i1, ep.i2); - } - } - - selectedmultiedge.Append(twoint(ep)); - - if (edgedata.Get(tenum).GetStatus() == ED_UNDEFINED) - { - return; - } - - edgedata.BuildLineWithEdge(ep.i1,ep.i2,selectedmultiedge); -} - -void STLGeometry :: BuildSelectedEdge(twoint ep) -{ - if (edgedata.Size() == 0 || - !GetEPPSize()) - { - return; - } - - selectedmultiedge.SetSize(0); - - selectedmultiedge.Append(twoint(ep)); -} - -void STLGeometry :: BuildSelectedCluster(twoint ep) -{ - if (edgedata.Size() == 0 || - !GetEPPSize()) - { - return; - } - - selectedmultiedge.SetSize(0); - - int tenum = GetTopEdgeNum (ep.i1, ep.i2); - - if (edgedata.Get(tenum).GetStatus() == ED_UNDEFINED) - { - twoint epnew = GetNearestSelectedDefinedEdge(); - if (epnew.i1) - { - ep = epnew; - tenum = GetTopEdgeNum (ep.i1, ep.i2); - } - } - - selectedmultiedge.Append(twoint(ep)); - - if (edgedata.Get(tenum).GetStatus() == ED_UNDEFINED) - { - return; - } - - edgedata.BuildClusterWithEdge(ep.i1,ep.i2,selectedmultiedge); -} - -void STLGeometry :: ImportEdges() -{ - StoreEdgeData(); - - PrintMessage(5, "import edges from file 'edges.ng'"); - ifstream fin("edges.ng"); - - int ne; - fin >> ne; - - ARRAY<Point<3> > eps; - - int i; - Point<3> p; - for (i = 1; i <= 2*ne; i++) - { - fin >> p(0); - fin >> p(1); - fin >> p(2); - eps.Append(p); - } - AddEdges(eps); -} - -void STLGeometry :: AddEdges(const ARRAY<Point<3> >& eps) -{ - int i; - int ne = eps.Size()/2; - - ARRAY<int> epsi; - Box<3> bb = GetBoundingBox(); - bb.Increase(1); - - Point3dTree pointtree (bb.PMin(), - bb.PMax()); - ARRAY<int> pintersect; - - double gtol = GetBoundingBox().Diam()/1.E10; - Point<3> p; - - for (i = 1; i <= GetNP(); i++) - { - p = GetPoint(i); - pointtree.Insert (p, i); - } - - int error = 0; - for (i = 1; i <= 2*ne; i++) - { - p = eps.Get(i); - Point3d pmin = p - Vec3d (gtol, gtol, gtol); - Point3d pmax = p + Vec3d (gtol, gtol, gtol); - - pointtree.GetIntersecting (pmin, pmax, pintersect); - if (pintersect.Size() > 1) - { - PrintError("Found too much points in epsilon-dist"); - error = 1; - } - else if (pintersect.Size() == 0) - { - error = 1; - PrintError("edgepoint does not exist!"); - PrintMessage(5,"p=",Point3d(eps.Get(i))); - } - else - { - epsi.Append(pintersect.Get(1)); - } - } - - if (error) return; - - int en; - for (i = 1; i <= ne; i++) - { - if (epsi.Get(2*i-1) == epsi.Get(2*i)) {PrintError("Edge with zero length!");} - else - { - en = edgedata.GetEdgeNum(epsi.Get(2*i-1),epsi.Get(2*i)); - edgedata.Elem(en).SetStatus (ED_CONFIRMED); - } - } - -} - - - -void STLGeometry :: ImportExternalEdges(const char * filename) -{ - //AVL edges!!!!!! - - ifstream inf (filename); - char ch; - int cnt = 0; - int records, units, i, j; - PrintFnStart("Import edges from ",filename); - - const int flen=30; - char filter[flen+1]; - filter[flen] = 0; - char buf[20]; - - ARRAY<Point3d> importpoints; - ARRAY<int> importlines; - ARRAY<int> importpnums; - - while (inf.good()) - { - inf.get(ch); - // (*testout) << cnt << ": " << ch << endl; - - for (i = 0; i < flen; i++) - filter[i] = filter[i+1]; - filter[flen-1] = ch; - // (*testout) << filter << endl; - - if (strcmp (filter+flen-7, "RECORDS") == 0) - { - inf.get(ch); // '=' - inf >> records; - } - if (strcmp (filter+flen-5, "UNITS") == 0) - { - inf.get(ch); // '=' - inf >> units; - } - - if (strcmp (filter+flen-17, "EDGE NODE NUMBERS") == 0) - { - int nodenr; - importlines.SetSize (units); - for (i = 1; i <= units; i++) - { - inf >> nodenr; - importlines.Elem(i) = nodenr; - // (*testout) << nodenr << endl; - } - } - - if (strcmp (filter+flen-23, "EDGE POINT COORD IN DIR") == 0) - { - int coord; - - inf >> coord; - - importpoints.SetSize (units); - - inf >> ch; - inf.putback (ch); - - int nodenr; - for (i = 1; i <= units; i++) - { - for (j = 0; j < 12; j++) - inf.get (buf[j]); - buf[12] = 0; - - importpoints.Elem(i).X(coord) = 1000 * atof (buf); - } - } - } - - /* - (*testout) << "lines: " << endl; - for (i = 1; i <= importlines.Size(); i++) - (*testout) << importlines.Get(i) << endl; - (*testout) << "points: " << endl; - for (i = 1; i <= importpoints.Size(); i++) - (*testout) << importpoints.Get(i) << endl; - */ - - - - importpnums.SetSize (importpoints.Size()); - - - Box3d bb (GetBoundingBox().PMin() + Vec3d (-1,-1,-1), - GetBoundingBox().PMax() + Vec3d (1, 1, 1)); - - Point3dTree pointtree (bb.PMin(), - bb.PMax()); - - - PrintMessage(7,"stl - bb: ",bb.PMin(), " - ", bb.PMax()); - - Box3d ebb; - ebb.SetPoint (importpoints.Get(1)); - for (i = 1; i <= importpoints.Size(); i++) - ebb.AddPoint (importpoints.Get(i)); - PrintMessage(7,"edgep - bb: ", ebb.PMin(), " - ", ebb.PMax()); - - ARRAY<int> pintersect; - - double gtol = GetBoundingBox().Diam()/1.E6; - - for (i = 1; i <= GetNP(); i++) - { - Point3d p = GetPoint(i); - // (*testout) << "stlpt: " << p << endl; - pointtree.Insert (p, i); - } - - - for (i = 1; i <= importpoints.Size(); i++) - { - Point3d p = importpoints.Get(i); - Point3d pmin = p - Vec3d (gtol, gtol, gtol); - Point3d pmax = p + Vec3d (gtol, gtol, gtol); - - pointtree.GetIntersecting (pmin, pmax, pintersect); - if (pintersect.Size() > 1) - { - importpnums.Elem(i) = 0; - PrintError("Found too many points in epsilon-dist"); - } - else if (pintersect.Size() == 0) - { - importpnums.Elem(i) = 0; - PrintError("Edgepoint does not exist!"); - } - else - { - importpnums.Elem(i) = pintersect.Get(1); - } - } - - // if (!error) - { - PrintMessage(7,"found all edge points in stl file"); - - - StoreEdgeData(); - - int oldp = 0; - - for (i = 1; i <= importlines.Size(); i++) - { - int newp = importlines.Get(i); - if (!importpnums.Get(abs(newp))) - newp = 0; - - if (oldp && newp) - { - int en = edgedata.GetEdgeNum(importpnums.Get(oldp), - importpnums.Get(abs(newp))); - edgedata.Elem(en).SetStatus (ED_CONFIRMED); - } - - if (newp < 0) - oldp = 0; - else - oldp = newp; - } - } - - -} - - - -void STLGeometry :: ExportEdges() -{ - PrintFnStart("Save edges to file 'edges.ng'"); - - ofstream fout("edges.ng"); - fout.precision(16); - - int n = edgedata.GetNConfEdges(); - - fout << n << endl; - - int i; - for (i = 1; i <= edgedata.Size(); i++) - { - if (edgedata.Get(i).GetStatus() == ED_CONFIRMED) - { - const STLTopEdge & e = edgedata.Get(i); - fout << GetPoint(e.PNum(1))(0) << " " << GetPoint(e.PNum(1))(1) << " " << GetPoint(e.PNum(1))(2) << endl; - fout << GetPoint(e.PNum(2))(0) << " " << GetPoint(e.PNum(2))(1) << " " << GetPoint(e.PNum(2))(2) << endl; - } - } - -} - -void STLGeometry :: LoadEdgeData(const char* file) -{ - StoreEdgeData(); - - PrintFnStart("Load edges from file '", file, "'"); - ifstream fin(file); - - edgedata.Read(fin); - - // calcedgedataanglesnew = 1; -} - -void STLGeometry :: SaveEdgeData(const char* file) -{ - PrintFnStart("save edges to file '", file, "'"); - ofstream fout(file); - - edgedata.Write(fout); -} - - - - - - - -/* -void STLGeometry :: SaveExternalEdges() -{ - ofstream fout("externaledgesp3.ng"); - fout.precision(16); - - int n = NOExternalEdges(); - fout << n << endl; - - int i; - for (i = 1; i <= n; i++) - { - twoint e = GetExternalEdge(i); - fout << GetPoint(e.i1)(0) << " " << GetPoint(e.i1)(1) << " " << GetPoint(e.i1)(2) << endl; - fout << GetPoint(e.i2)(0) << " " << GetPoint(e.i2)(1) << " " << GetPoint(e.i2)(2) << endl; - } - -} -*/ -void STLGeometry :: StoreExternalEdges() -{ - storedexternaledges.SetSize(0); - undoexternaledges = 1; - int i; - for (i = 1; i <= externaledges.Size(); i++) - { - storedexternaledges.Append(externaledges.Get(i)); - } - -} - -void STLGeometry :: UndoExternalEdges() -{ - if (!undoexternaledges) - { - PrintMessage(1, "undo not further possible!"); - return; - } - RestoreExternalEdges(); - undoexternaledges = 0; -} - -void STLGeometry :: RestoreExternalEdges() -{ - externaledges.SetSize(0); - int i; - for (i = 1; i <= storedexternaledges.Size(); i++) - { - externaledges.Append(storedexternaledges.Get(i)); - } - -} - - -void STLGeometry :: AddExternalEdgeAtSelected() -{ - StoreExternalEdges(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - if (!IsExternalEdge(p1,p2)) {AddExternalEdge(p1,p2);} - } -} - -void STLGeometry :: AddClosedLinesToExternalEdges() -{ - StoreExternalEdges(); - - int i, j; - for (i = 1; i <= GetNLines(); i++) - { - STLLine* l = GetLine(i); - if (l->StartP() == l->EndP()) - { - for (j = 1; j < l->NP(); j++) - { - int p1 = l->PNum(j); - int p2 = l->PNum(j+1); - - if (!IsExternalEdge(p1,p2)) {AddExternalEdge(p1,p2);} - } - } - } -} - -void STLGeometry :: AddLongLinesToExternalEdges() -{ - StoreExternalEdges(); - - double diamfact = stldoctor.dirtytrigfact; - double diam = GetBoundingBox().Diam(); - - int i, j; - for (i = 1; i <= GetNLines(); i++) - { - STLLine* l = GetLine(i); - if (l->GetLength(points) >= diamfact*diam) - { - for (j = 1; j < l->NP(); j++) - { - int p1 = l->PNum(j); - int p2 = l->PNum(j+1); - - if (!IsExternalEdge(p1,p2)) {AddExternalEdge(p1,p2);} - } - } - } -} - -void STLGeometry :: AddAllNotSingleLinesToExternalEdges() -{ - StoreExternalEdges(); - - int i, j; - for (i = 1; i <= GetNLines(); i++) - { - STLLine* l = GetLine(i); - if (GetNEPP(l->StartP()) > 1 || GetNEPP(l->EndP()) > 1) - { - for (j = 1; j < l->NP(); j++) - { - int p1 = l->PNum(j); - int p2 = l->PNum(j+1); - - if (!IsExternalEdge(p1,p2)) {AddExternalEdge(p1,p2);} - } - } - } -} - -void STLGeometry :: DeleteDirtyExternalEdges() -{ - //delete single triangle edges and single edge-lines in clusters" - StoreExternalEdges(); - - int i, j; - for (i = 1; i <= GetNLines(); i++) - { - STLLine* l = GetLine(i); - if (l->NP() <= 3 || (l->StartP() == l->EndP() && l->NP() == 4)) - { - for (j = 1; j < l->NP(); j++) - { - int p1 = l->PNum(j); - int p2 = l->PNum(j+1); - - if (IsExternalEdge(p1,p2)) {DeleteExternalEdge(p1,p2);} - } - } - } -} - -void STLGeometry :: AddExternalEdgesFromGeomLine() -{ - StoreExternalEdges(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - - if (IsEdge(p1,p2)) - { - int edgenum = IsEdgeNum(p1,p2); - if (!IsExternalEdge(p1,p2)) {AddExternalEdge(p1,p2);} - - int noend = 1; - int startp = p1; - int laste = edgenum; - int np1, np2; - while (noend) - { - if (GetNEPP(startp) == 2) - { - if (GetEdgePP(startp,1) != laste) {laste = GetEdgePP(startp,1);} - else {laste = GetEdgePP(startp,2);} - np1 = GetEdge(laste).PNum(1); - np2 = GetEdge(laste).PNum(2); - - if (!IsExternalEdge(np1, np2)) {AddExternalEdge(np1, np2);} - else {noend = 0;} - if (np1 != startp) {startp = np1;} - else {startp = np2;} - } - else {noend = 0;} - } - - startp = p2; - laste = edgenum; - noend = 1; - while (noend) - { - if (GetNEPP(startp) == 2) - { - if (GetEdgePP(startp,1) != laste) {laste = GetEdgePP(startp,1);} - else {laste = GetEdgePP(startp,2);} - np1 = GetEdge(laste).PNum(1); - np2 = GetEdge(laste).PNum(2); - - if (!IsExternalEdge(np1, np2)) {AddExternalEdge(np1, np2);} - else {noend = 0;} - if (np1 != startp) {startp = np1;} - else {startp = np2;} - } - else {noend = 0;} - } - - } - - } - -} - -void STLGeometry :: ClearEdges() -{ - edgesfound = 0; - edges.SetSize(0); - //edgedata.SetSize(0); - // externaledges.SetSize(0); - edgesperpoint.SetSize(0); - undoexternaledges = 0; - -} - -void STLGeometry :: STLDoctorBuildEdges() -{ - // if (!trigsconverted) {return;} - ClearEdges(); - - meshlines.SetSize(0); - FindEdgesFromAngles(); -} - -void STLGeometry :: DeleteExternalEdgeAtSelected() -{ - StoreExternalEdges(); - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) - { - int p1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - int p2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); - if (IsExternalEdge(p1,p2)) {DeleteExternalEdge(p1,p2);} - } -} - -void STLGeometry :: DeleteExternalEdgeInVicinity() -{ - StoreExternalEdges(); - if (!stldoctor.showvicinity || vicinity.Size() != GetNT()) {return;} - - int i, j, k, p1, p2; - - for (i = 1; i <= GetNT(); i++) - { - if (vicinity.Elem(i)) - { - for (j = 1; j <= 3; j++) - { - p1 = GetTriangle(i).PNum(j); - p2 = GetTriangle(i).PNumMod(j+1); - - if (IsExternalEdge(p1,p2)) - { - DeleteExternalEdge(p1,p2); - } - } - } - } -} - -void STLGeometry :: BuildExternalEdgesFromEdges() -{ - StoreExternalEdges(); - - if (GetNE() == 0) {PrintWarning("Edges possibly not generated!");} - - int i, p1, p2; - externaledges.SetSize(0); - - for (i = 1; i <= GetNE(); i++) - { - STLEdge e = GetEdge(i); - AddExternalEdge(e.PNum(1), e.PNum(2)); - } - -} - - -void STLGeometry :: AddExternalEdge(int p1, int p2) -{ - externaledges.Append(twoint(p1,p2)); -} - -void STLGeometry :: DeleteExternalEdge(int p1, int p2) -{ - - int i; - int found = 0; - for (i = 1; i <= NOExternalEdges(); i++) - { - if ((GetExternalEdge(i).i1 == p1 && GetExternalEdge(i).i2 == p2) || - (GetExternalEdge(i).i1 == p2 && GetExternalEdge(i).i2 == p1)) {found = 1;}; - if (found && i < NOExternalEdges()) - { - externaledges.Elem(i) = externaledges.Get(i+1); - } - } - if (!found) {PrintWarning("edge not found");} - else - { - externaledges.SetSize(externaledges.Size()-1); - } - -} - -int STLGeometry :: IsExternalEdge(int p1, int p2) -{ - int i; - for (i = 1; i <= NOExternalEdges(); i++) - { - if ((GetExternalEdge(i).i1 == p1 && GetExternalEdge(i).i2 == p2) || - (GetExternalEdge(i).i1 == p2 && GetExternalEdge(i).i2 == p1)) {return 1;}; - } - return 0; -} - -void STLGeometry :: DestroyDirtyTrigs() -{ - - PrintFnStart("Destroy dirty triangles"); - PrintMessage(5,"original number of triangles=", GetNT()); - - //destroy every triangle with other than 3 neighbours; - int changed = 1; - int i, j, k; - while (changed) - { - changed = 0; - Clear(); - - for (i = 1; i <= GetNT(); i++) - { - int dirty = NONeighbourTrigs(i) < 3; - - for (j = 1; j <= 3; j++) - { - int pnum = GetTriangle(i).PNum(j); - /* - if (pnum == 1546) - { - // for (k = 1; k <= NOTrigsPerPoint(pnum); k++) - } - */ - if (NOTrigsPerPoint(pnum) <= 2) - dirty = 1; - } - - int pi1 = GetTriangle(i).PNum(1); - int pi2 = GetTriangle(i).PNum(2); - int pi3 = GetTriangle(i).PNum(3); - if (pi1 == pi2 || pi1 == pi3 || pi2 == pi3) - { - PrintMessage(5,"triangle with Volume 0: ", i, " nodes: ", pi1, ", ", pi2, ", ", pi3); - dirty = 1; - } - - if (dirty) - { - for (k = i+1; k <= GetNT(); k++) - { - trias.Elem(k-1) = trias.Get(k); - // readtrias: not longer permanent, JS - // readtrias.Elem(k-1) = readtrias.Get(k); - } - int size = GetNT(); - trias.SetSize(size-1); - // readtrias.SetSize(size-1); - changed = 1; - break; - } - } - } - - FindNeighbourTrigs(); - PrintMessage(5,"final number of triangles=", GetNT()); -} - -void STLGeometry :: CalcNormalsFromGeometry() -{ - int i; - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & tr = GetTriangle(i); - const Point3d& p1 = GetPoint(tr.PNum(1)); - const Point3d& p2 = GetPoint(tr.PNum(2)); - const Point3d& p3 = GetPoint(tr.PNum(3)); - - Vec3d normal = Cross (p2-p1, p3-p1); - - if (normal.Length() != 0) - { - normal /= (normal.Length()); - } - GetTriangle(i).SetNormal(normal); - } - PrintMessage(5,"Normals calculated from geometry!!!"); - - calcedgedataanglesnew = 1; -} - -void STLGeometry :: SetSelectTrig(int trig) -{ - stldoctor.selecttrig = trig; -} - -int STLGeometry :: GetSelectTrig() const -{ - return stldoctor.selecttrig; -} - -void STLGeometry :: SetNodeOfSelTrig(int n) -{ - stldoctor.nodeofseltrig = n; -} - -int STLGeometry :: GetNodeOfSelTrig() const -{ - return stldoctor.nodeofseltrig; -} - -void STLGeometry :: MoveSelectedPointToMiddle() -{ - if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) - { - int p = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); - Point<3> pm(0.,0.,0.); //Middlevector; - Point<3> p0(0.,0.,0.); - PrintMessage(5,"original point=", Point3d(GetPoint(p))); - - int i; - int cnt = 0; - for (i = 1; i <= trigsperpoint.EntrySize(p); i++) - { - const STLTriangle& tr = GetTriangle(trigsperpoint.Get(p,i)); - int j; - for (j = 1; j <= 3; j++) - { - if (tr.PNum(j) != p) - { - cnt++; - pm(0) += GetPoint(tr.PNum(j))(0); - pm(1) += GetPoint(tr.PNum(j))(1); - pm(2) += GetPoint(tr.PNum(j))(2); - } - } - } - - Point<3> origp = GetPoint(p); - double fact = 0.2; - - SetPoint(p, p0 + fact*(1./(double)cnt)*(pm-p0)+(1.-fact)*(origp-p0)); - - PrintMessage(5,"middle point=", Point3d (GetPoint(p))); - - PrintMessage(5,"moved point ", Point3d (p)); - - } -} - -void STLGeometry :: PrintSelectInfo() -{ - - int trig = GetSelectTrig(); - int p = GetTriangle(trig).PNum(GetNodeOfSelTrig()); - - PrintMessage(1,"touch triangle ", GetSelectTrig() - , ", local node ", GetNodeOfSelTrig() - , " (=", GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()), ")"); - if (AtlasMade() && GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) - { - PrintMessage(1," chartnum=",GetChartNr(GetSelectTrig())); - /* - PointBetween(Center(Center(GetPoint(GetTriangle(270).PNum(1)), - GetPoint(GetTriangle(270).PNum(2))), - GetPoint(GetTriangle(270).PNum(3))),270, - Center(Center(GetPoint(GetTriangle(trig).PNum(1)), - GetPoint(GetTriangle(trig).PNum(2))), - GetPoint(GetTriangle(trig).PNum(3))),trig); - */ - //PointBetween(Point3d(5.7818, 7.52768, 4.14879),260,Point3d(6.80292, 6.55392, 4.70184),233); - } -} - -void STLGeometry :: ShowSelectedTrigChartnum() -{ - int st = GetSelectTrig(); - - if (st >= 1 && st <= GetNT() && AtlasMade()) - PrintMessage(1,"selected trig ", st, " has chartnumber ", GetChartNr(st)); -} - -void STLGeometry :: ShowSelectedTrigCoords() -{ - int st = GetSelectTrig(); - - /* - //testing!!!! - ARRAY<int> trigs; - GetSortedTrianglesAroundPoint(GetTriangle(st).PNum(GetNodeOfSelTrig()),st,trigs); - */ - - if (st >= 1 && st <= GetNT()) - { - PrintMessage(1, "coordinates of selected trig ", st, ":"); - PrintMessage(1, " p1 = ", GetTriangle(st).PNum(1), " = ", - Point3d (GetPoint(GetTriangle(st).PNum(1)))); - PrintMessage(1, " p2 = ", GetTriangle(st).PNum(2), " = ", - Point3d (GetPoint(GetTriangle(st).PNum(2)))); - PrintMessage(1, " p3 = ", GetTriangle(st).PNum(3), " = ", - Point3d (GetPoint(GetTriangle(st).PNum(3)))); - } -} - -void STLGeometry :: LoadMarkedTrigs() -{ - PrintFnStart("load marked trigs from file 'markedtrigs.ng'"); - ifstream fin("markedtrigs.ng"); - - int n; - fin >> n; - if (n != GetNT() || n == 0) {PrintError("Not a suitable marked-trig-file!"); return;} - - int i, m; - for (i = 1; i <= n; i++) - { - fin >> m; - SetMarkedTrig(i, m); - } - - fin >> n; - if (n != 0) - { - int i, m; - Point<3> p1, p2; - for (i = 1; i <= n; i++) - { - fin >> p1(0); fin >> p1(1); fin >> p1(2); - fin >> p2(0); fin >> p2(1); fin >> p2(2); - AddMarkedSeg(p1,p2); - } - } -} - -void STLGeometry :: SaveMarkedTrigs() -{ - PrintFnStart("save marked trigs to file 'markedtrigs.ng'"); - ofstream fout("markedtrigs.ng"); - - int n = GetNT(); - fout << n << endl; - - int i, m; - for (i = 1; i <= n; i++) - { - fout << IsMarkedTrig(i) << "\n"; - } - - n = GetNMarkedSegs(); - fout << n << endl; - - Point<3> p1,p2; - for (i = 1; i <= n; i++) - { - GetMarkedSeg(i,p1,p2); - fout << p1(0) << " " << p1(1) << " " << p1(2) << " "; - fout << p2(0) << " " << p2(1) << " " << p2(2) << " " << "\n"; - } - -} - -void STLGeometry :: NeighbourAnglesOfSelectedTrig() -{ - int st = GetSelectTrig(); - - if (st >= 1 && st <= GetNT()) - { - int i; - PrintMessage(1,"Angle to triangle ", st, ":"); - for (i = 1; i <= NONeighbourTrigs(st); i++) - { - PrintMessage(1," triangle ", NeighbourTrig(st,i), ": angle = " - , 180./M_PI*GetAngle(st, NeighbourTrig(st,i)), "�" - , ", calculated = ", 180./M_PI*Angle(GetTriangle(st).GeomNormal(points), - GetTriangle(NeighbourTrig(st,i)).GeomNormal(points)), "�"); - } - } -} - -void STLGeometry :: GetVicinity(int starttrig, int size, ARRAY<int>& vic) -{ - if (starttrig == 0 || starttrig > GetNT()) {return;} - - ARRAY<int> vicarray; - vicarray.SetSize(GetNT()); - - int i; - for (i = 1; i <= vicarray.Size(); i++) - { - vicarray.Elem(i) = 0; - } - - vicarray.Elem(starttrig) = 1; - - int j = 0,k; - - ARRAY <int> list1; - list1.SetSize(0); - ARRAY <int> list2; - list2.SetSize(0); - list1.Append(starttrig); - - while (j < size) - { - j++; - for (i = 1; i <= list1.Size(); i++) - { - for (k = 1; k <= NONeighbourTrigs(i); k++) - { - int nbtrig = NeighbourTrig(list1.Get(i),k); - if (nbtrig && vicarray.Get(nbtrig) == 0) - { - list2.Append(nbtrig); - vicarray.Elem(nbtrig) = 1; - } - } - } - list1.SetSize(0); - for (i = 1; i <= list2.Size(); i++) - { - list1.Append(list2.Get(i)); - } - list2.SetSize(0); - } - - vic.SetSize(0); - for (i = 1; i <= vicarray.Size(); i++) - { - if (vicarray.Get(i)) {vic.Append(i);} - } -} - -void STLGeometry :: CalcVicinity(int starttrig) -{ - if (starttrig == 0 || starttrig > GetNT()) {return;} - - vicinity.SetSize(GetNT()); - - if (!stldoctor.showvicinity) {return;} - - int i; - for (i = 1; i <= vicinity.Size(); i++) - { - vicinity.Elem(i) = 0; - } - - vicinity.Elem(starttrig) = 1; - - int j = 0,k; - - ARRAY <int> list1; - list1.SetSize(0); - ARRAY <int> list2; - list2.SetSize(0); - list1.Append(starttrig); - - // int cnt = 1; - while (j < stldoctor.vicinity) - { - j++; - for (i = 1; i <= list1.Size(); i++) - { - for (k = 1; k <= NONeighbourTrigs(i); k++) - { - int nbtrig = NeighbourTrig(list1.Get(i),k); - if (nbtrig && vicinity.Get(nbtrig) == 0) - { - list2.Append(nbtrig); - vicinity.Elem(nbtrig) = 1; - //cnt++; - } - } - } - list1.SetSize(0); - for (i = 1; i <= list2.Size(); i++) - { - list1.Append(list2.Get(i)); - } - list2.SetSize(0); - } - -} - -int STLGeometry :: Vicinity(int trig) const -{ - if (trig <= vicinity.Size() && trig >=1) - { - return vicinity.Get(trig); - } - else {PrintSysError("In STLGeometry::Vicinity");} - return 0; -} - -void STLGeometry :: InitMarkedTrigs() -{ - markedtrigs.SetSize(GetNT()); - int i; - for (i = 1; i <= GetNT(); i++) - { - SetMarkedTrig(i, 0); - } -} - -void STLGeometry :: MarkDirtyTrigs() -{ - PrintFnStart("mark dirty trigs"); - int i,j; - - markedtrigs.SetSize(GetNT()); - - for (i = 1; i <= GetNT(); i++) - { - SetMarkedTrig(i, 0); - } - - int found; - double dirtyangle = stlparam.yangle/2./180.*M_PI; - int cnt = 0; - for (i = 1; i <= GetNT(); i++) - { - found = 0; - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - if (GetAngle(i, NeighbourTrig(i,j)) > dirtyangle) - { - found++; - } - } - if (found && GetTriangle(i).MinHeight(points) < - stldoctor.dirtytrigfact*GetTriangle(i).MaxLength(points)) - { - SetMarkedTrig(i, 1); cnt++; - } - /* - else if (found == 3) - { - SetMarkedTrig(i, 1); cnt++; - } - */ - } - - PrintMessage(1, "marked ", cnt, " dirty trigs"); -} - - -void STLGeometry :: MarkTopErrorTrigs() -{ - int cnt = 0; - markedtrigs.SetSize(GetNT()); - for (int i = 1; i <= GetNT(); i++) - { - const STLTriangle & trig = GetTriangle(i); - - SetMarkedTrig(i, trig.flags.toperror); - if (trig.flags.toperror) cnt++; - } - PrintMessage(1,"marked ", cnt, " inconsistent triangles"); -} - - - -double STLGeometry :: CalcTrigBadness(int i) -{ - int j; - double maxbadness = 0; - int p1, p2; - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), p1, p2); - - if (!IsEdge(p1,p2) && GetGeomAngle(i, NeighbourTrig(i,j)) > maxbadness) - { - maxbadness = GetGeomAngle(i, NeighbourTrig(i,j)); - } - } - return maxbadness; - -} - -void STLGeometry :: GeomSmoothRevertedTrigs() -{ - double revertedangle = stldoctor.smoothangle/180.*M_PI; - double fact = stldoctor.dirtytrigfact; - - MarkRevertedTrigs(); - - int i, j, k, l, p; - - for (i = 1; i <= GetNT(); i++) - { - if (IsMarkedTrig(i)) - { - for (j = 1; j <= 3; j++) - { - double origbadness = CalcTrigBadness(i); - - p = GetTriangle(i).PNum(j); - Point<3> pm(0.,0.,0.); //Middlevector; - Point<3> p0(0.,0.,0.); - - int cnt = 0; - - for (k = 1; k <= trigsperpoint.EntrySize(p); k++) - { - const STLTriangle& tr = GetTriangle(trigsperpoint.Get(p,k)); - for (l = 1; l <= 3; l++) - { - if (tr.PNum(l) != p) - { - cnt++; - pm(0) += GetPoint(tr.PNum(l))(0); - pm(1) += GetPoint(tr.PNum(l))(1); - pm(2) += GetPoint(tr.PNum(l))(2); - } - } - } - Point3d origp = GetPoint(p); - Point3d newp = p0 + fact*(1./(double)cnt)*(pm-p0)+(1.-fact)*(origp-p0); - - SetPoint(p, newp); - - if (CalcTrigBadness(i) > 0.9*origbadness) {SetPoint(p,origp); PrintDot('f');} - else {PrintDot('s');} - } - } - } - MarkRevertedTrigs(); -} - -void STLGeometry :: MarkRevertedTrigs() -{ - int i,j; - if (edgesperpoint.Size() != GetNP()) {BuildEdges();} - - PrintFnStart("mark reverted trigs"); - - InitMarkedTrigs(); - - int found; - double revertedangle = stldoctor.smoothangle/180.*M_PI; - - int cnt = 0; - int p1, p2; - for (i = 1; i <= GetNT(); i++) - { - found = 0; - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), p1, p2); - - if (!IsEdge(p1,p2)) - { - if (GetGeomAngle(i, NeighbourTrig(i,j)) > revertedangle) - { - found = 1; - break; - } - } - } - - if (found) - { - SetMarkedTrig(i, 1); cnt++; - } - - } - - PrintMessage(5, "found ", cnt, " reverted trigs"); - - -} - -void STLGeometry :: SmoothDirtyTrigs() -{ - PrintFnStart("smooth dirty trigs"); - - MarkDirtyTrigs(); - - int i,j; - int changed = 1; - int p1, p2; - - while (changed) - { - changed = 0; - for (i = 1; i <= GetNT(); i++) - { - if (IsMarkedTrig(i)) - { - int foundtrig = 0; - double maxlen = 0; - // JS: darf normalvector nicht ueber kurze Seite erben - maxlen = GetTriangle(i).MaxLength(GetPoints()) / 2.1; //JG: bei flachem dreieck auch kurze Seite - - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - if (!IsMarkedTrig(NeighbourTrig(i,j))) - { - GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)),p1,p2); - if (Dist(GetPoint(p1),GetPoint(p2)) >= maxlen) - { - foundtrig = NeighbourTrig(i,j); - maxlen = Dist(GetPoint(p1),GetPoint(p2)); - } - } - } - if (foundtrig) - { - GetTriangle(i).SetNormal(GetTriangle(foundtrig).Normal()); - changed = 1; - SetMarkedTrig(i,0); - } - } - } - } - - calcedgedataanglesnew = 1; - - - MarkDirtyTrigs(); - - int cnt = 0; - for (i = 1; i <= GetNT(); i++) - { - if (IsMarkedTrig(i)) {cnt++;} - } - - PrintMessage(5,"NO marked dirty trigs=", cnt); - -} - -int STLGeometry :: IsMarkedTrig(int trig) const -{ - if (trig <= markedtrigs.Size() && trig >=1) - { - return markedtrigs.Get(trig); - } - else {PrintSysError("In STLGeometry::IsMarkedTrig");} - - return 0; -} - -void STLGeometry :: SetMarkedTrig(int trig, int num) -{ - if (trig <= markedtrigs.Size() && trig >=1) - { - markedtrigs.Elem(trig) = num; - } - else {PrintSysError("In STLGeometry::SetMarkedTrig");} -} - -void STLGeometry :: Clear() -{ - PrintFnStart("Clear"); - - surfacemeshed = 0; - surfaceoptimized = 0; - volumemeshed = 0; - - selectedmultiedge.SetSize(0); - meshlines.SetSize(0); - // neighbourtrigs.SetSize(0); - outerchartspertrig.SetSize(0); - atlas.SetSize(0); - ClearMarkedSegs(); - ClearSpiralPoints(); - ClearLineEndPoints(); - - SetSelectTrig(0); - SetNodeOfSelTrig(1); - facecnt = 0; - - SetThreadPercent(100.); - - ClearEdges(); -} - -double STLGeometry :: Area() -{ - double ar = 0; - int i; - for (i = 1; i <= GetNT(); i++) - { - ar += GetTriangle(i).Area(points); - } - return ar; -} - -double STLGeometry :: GetAngle(int t1, int t2) -{ - return Angle(GetTriangle(t1).Normal(),GetTriangle(t2).Normal()); -} - -double STLGeometry :: GetGeomAngle(int t1, int t2) -{ - Vec3d n1 = GetTriangle(t1).GeomNormal(points); - Vec3d n2 = GetTriangle(t2).GeomNormal(points); - return Angle(n1,n2); -} - - -void STLGeometry :: InitSTLGeometry(const ARRAY<STLReadTriangle> & readtrias) -{ - PrintFnStart("Init STL Geometry"); - STLTopology::InitSTLGeometry(readtrias); - - int i, j, k; - - const double geometry_tol_fact = 1E8; //distances lower than max_box_size/tol are ignored - - int np = GetNP(); - PrintMessage(5,"NO points= ", GetNP()); - normals.SetSize(GetNP()); - ARRAY<int> normal_cnt(GetNP()); // counts number of added normals in a point - - for (i = 1; i <= np; i++) - { - normal_cnt.Elem(i) = 0; - normals.Elem(i) = Vec3d (0,0,0); - } - - for(i = 1; i <= GetNT(); i++) - { - // STLReadTriangle t = GetReadTriangle(i); - // STLTriangle st; - - Vec<3> n = GetTriangle(i).Normal (); - - for (k = 1; k <= 3; k++) - { - int pi = GetTriangle(i).PNum(k); - - normal_cnt.Elem(pi)++; - SetNormal(pi, GetNormal(pi) + n); - } - } - - //normalize the normals - for (i = 1; i <= GetNP(); i++) - { - SetNormal(i,1./(double)normal_cnt.Get(i)*GetNormal(i)); - } - - trigsconverted = 1; - - vicinity.SetSize(GetNT()); - markedtrigs.SetSize(GetNT()); - for (i = 1; i <= GetNT(); i++) - { - markedtrigs.Elem(i) = 0; - vicinity.Elem(i) = 1; - } - - ha_points.SetSize(GetNP()); - for (i = 1; i <= GetNP(); i++) - ha_points.Elem(i) = 0; - - calcedgedataanglesnew = 0; - edgedatastored = 0; - edgedata.Clear(); - - - if (GetStatus() == STL_ERROR) return; - - CalcEdgeData(); - CalcEdgeDataAngles(); - - ClearLineEndPoints(); - - CheckGeometryOverlapping(); -} - -void STLGeometry :: TopologyChanged() -{ - calcedgedataanglesnew = 1; -} - -int STLGeometry :: CheckGeometryOverlapping() -{ - int i, j, k; - - Box<3> geombox = GetBoundingBox(); - Point<3> pmin = geombox.PMin(); - Point<3> pmax = geombox.PMax(); - - Box3dTree setree(pmin, pmax); - ARRAY<int> inters; - - int oltrigs = 0; - markedtrigs.SetSize(GetNT()); - - for (i = 1; i <= GetNT(); i++) - SetMarkedTrig(i, 0); - - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & tri = GetTriangle(i); - - Point<3> tpmin = tri.box.PMin(); - Point<3> tpmax = tri.box.PMax(); - Vec<3> diag = tpmax - tpmin; - - tpmax = tpmax + 0.001 * diag; - tpmin = tpmin - 0.001 * diag; - - setree.Insert (tpmin, tpmax, i); - } - - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & tri = GetTriangle(i); - - Point<3> tpmin = tri.box.PMin(); - Point<3> tpmax = tri.box.PMax(); - - setree.GetIntersecting (tpmin, tpmax, inters); - - for (j = 1; j <= inters.Size(); j++) - { - const STLTriangle & tri2 = GetTriangle(inters.Get(j)); - - const Point3d *trip1[3], *trip2[3]; - Point3d hptri1[3], hptri2[3]; - /* - for (k = 1; k <= 3; k++) - { - trip1[k-1] = &GetPoint (tri.PNum(k)); - trip2[k-1] = &GetPoint (tri2.PNum(k)); - } - */ - - for (k = 0; k < 3; k++) - { - hptri1[k] = GetPoint (tri[k]); - hptri2[k] = GetPoint (tri2[k]); - trip1[k] = &hptri1[k]; - trip2[k] = &hptri2[k]; - } - - if (IntersectTriangleTriangle (&trip1[0], &trip2[0])) - { - oltrigs++; - PrintMessage(5,"Intersecting Triangles: trig ",i," with ",inters.Get(j),"!"); - SetMarkedTrig(i, 1); - SetMarkedTrig(inters.Get(j), 1); - } - } - } - - PrintMessage(3,"Check Geometry Overlapping: overlapping triangles = ",oltrigs); - return oltrigs; -} - -/* -void STLGeometry :: InitSTLGeometry() -{ - STLTopology::InitSTLGeometry(); - - int i, j, k; - - const double geometry_tol_fact = 1E8; //distances lower than max_box_size/tol are ignored - - - trias.SetSize(0); - points.SetSize(0); - normals.SetSize(0); - - ARRAY<int> normal_cnt; // counts number of added normals in a point - - Box3d bb (GetBoundingBox().PMin() + Vec3d (-1,-1,-1), - GetBoundingBox().PMax() + Vec3d (1, 1, 1)); - - Point3dTree pointtree (bb.PMin(), - bb.PMax()); - ARRAY<int> pintersect; - - double gtol = GetBoundingBox().CalcDiam()/geometry_tol_fact; - - for(i = 1; i <= GetReadNT(); i++) - { - //if (i%500==499) {(*mycout) << (double)i/(double)GetReadNT()*100. << "%" << endl;} - - STLReadTriangle t = GetReadTriangle(i); - STLTriangle st; - Vec3d n = t.normal; - - for (k = 0; k < 3; k++) - { - Point3d p = t.pts[k]; - - Point3d pmin = p - Vec3d (gtol, gtol, gtol); - Point3d pmax = p + Vec3d (gtol, gtol, gtol); - - pointtree.GetIntersecting (pmin, pmax, pintersect); - - if (pintersect.Size() > 1) - (*mycout) << "found too much " << char(7) << endl; - int foundpos = 0; - if (pintersect.Size()) - foundpos = pintersect.Get(1); - - if (foundpos) - { - normal_cnt[foundpos]++; - SetNormal(foundpos,GetNormal(foundpos)+n); - // (*testout) << "found p " << p << endl; - } - else - { - foundpos = AddPoint(p); - AddNormal(n); - normal_cnt.Append(1); - - pointtree.Insert (p, foundpos); - } - //(*mycout) << "foundpos=" << foundpos << endl; - st.pts[k] = foundpos; - } - - if ( (st.pts[0] == st.pts[1]) || - (st.pts[0] == st.pts[2]) || - (st.pts[1] == st.pts[2]) ) - { - (*mycout) << "ERROR: STL Triangle degenerated" << endl; - } - else - { - // do not add ? js - AddTriangle(st); - } - //(*mycout) << "TRIG" << i << " = " << st << endl; - - } - //normal the normals - for (i = 1; i <= GetNP(); i++) - { - SetNormal(i,1./(double)normal_cnt[i]*GetNormal(i)); - } - - trigsconverted = 1; - - vicinity.SetSize(GetNT()); - markedtrigs.SetSize(GetNT()); - for (i = 1; i <= GetNT(); i++) - { - markedtrigs.Elem(i) = 0; - vicinity.Elem(i) = 1; - } - - ha_points.SetSize(GetNP()); - for (i = 1; i <= GetNP(); i++) - ha_points.Elem(i) = 0; - - calcedgedataanglesnew = 0; - edgedatastored = 0; - edgedata.Clear(); - - CalcEdgeData(); - CalcEdgeDataAngles(); - - ClearLineEndPoints(); - - (*mycout) << "done" << endl; -} -*/ - - - -void STLGeometry :: SetLineEndPoint(int pn) -{ - if (pn <1 || pn > lineendpoints.Size()) {PrintSysError("Illegal pnum in SetLineEndPoint!!!"); return; } - lineendpoints.Elem(pn) = 1; -} - -int STLGeometry :: IsLineEndPoint(int pn) -{ - // return 0; - if (pn <1 || pn > lineendpoints.Size()) - {PrintSysError("Illegal pnum in IsLineEndPoint!!!"); return 0;} - return lineendpoints.Get(pn); -} - -void STLGeometry :: ClearLineEndPoints() -{ - lineendpoints.SetSize(GetNP()); - int i; - for (i = 1; i <= GetNP(); i++) - { - lineendpoints.Elem(i) = 0; - } -} - -int STLGeometry :: IsEdge(int p1, int p2) -{ - int i,j; - for (i = 1; i <= GetNEPP(p1); i++) - { - for (j = 1; j <= GetNEPP(p2); j++) - { - if (GetEdgePP(p1,i) == GetEdgePP(p2,j)) {return 1;} - } - } - return 0; -} - -int STLGeometry :: IsEdgeNum(int p1, int p2) -{ - int i,j; - for (i = 1; i <= GetNEPP(p1); i++) - { - for (j = 1; j <= GetNEPP(p2); j++) - { - if (GetEdgePP(p1,i) == GetEdgePP(p2,j)) {return GetEdgePP(p1,i);} - } - } - return 0; -} - - -void STLGeometry :: BuildEdges() -{ - //PrintFnStart("build edges"); - edges.SetSize(0); - meshlines.SetSize(0); - FindEdgesFromAngles(); -} - -void STLGeometry :: UseExternalEdges() -{ - int i; - for (i = 1; i <= NOExternalEdges(); i++) - { - AddEdge(GetExternalEdge(i).i1,GetExternalEdge(i).i2); - } - //BuildEdgesPerPointy(); -} - -void STLGeometry :: UndoEdgeChange() -{ - if (edgedatastored) - { - RestoreEdgeData(); - } - else - { - PrintWarning("no edge undo possible"); - } -} - - -void STLGeometry :: StoreEdgeData() -{ - // edgedata_store = edgedata; - - edgedata.Store(); - edgedatastored = 1; - - // put stlgeom-edgedata to stltopology edgedata - /* - int i; - for (i = 1; i <= GetNTE(); i++) - { - const STLTopEdge & topedge = GetTopEdge (i); - int ednum = edgedata.GetEdgeNum (topedge.PNum(1), - topedge.PNum(2)); - topedges.Elem(i).SetStatus (edgedata.Get (ednum).status); - } - */ -} - -void STLGeometry :: RestoreEdgeData() -{ - // edgedata = edgedata_store; - edgedata.Restore(); - edgedatastored=0; -} - - -void STLGeometry :: CalcEdgeData() -{ - PushStatus("Calc Edge Data"); - - int np1, np2; - double ang; - int i; - - int ecnt = 0; - edgedata.SetSize(GetNT()/2*3); - - for (i = 1; i <= GetNT(); i++) - { - SetThreadPercent((double)i/(double)GetNT()*100.); - - const STLTriangle & t1 = GetTriangle(i); - - for (int j = 1; j <= NONeighbourTrigs(i); j++) - { - int nbti = NeighbourTrig(i,j); - if (nbti > i) - { - const STLTriangle & t2 = GetTriangle(nbti); - - if (t1.IsNeighbourFrom(t2)) - { - ecnt++; if (ecnt > edgedata.Size()) {PrintError("In Calc edge data, illegal geometry");} - - t1.GetNeighbourPoints(t2,np1,np2); - - /* ang = GetAngle(i,nbti); - if (ang < -M_PI) {ang += 2*M_PI;}*/ - - - // edgedata.Add(STLEdgeData(0, np1, np2, i, nbti),ecnt); - edgedata.Elem(ecnt).SetStatus(ED_UNDEFINED); - - // edgedata.Elem(ecnt).top = this; - // edgedata.Elem(ecnt).topedgenr = GetTopEdgeNum (np1, np2); - } - } - } - } - - //BuildEdgesPerPoint(); - PopStatus(); -} - -void STLGeometry :: CalcEdgeDataAngles() -{ - PrintMessage(5,"calc edge data angles"); - - double ang; - int i; - int t1,t2; - - for (i = 1; i <= GetNTE(); i++) - { - STLTopEdge & edge = GetTopEdge (i); - double cosang = - GetTriangle(edge.TrigNum(1)).Normal() * - GetTriangle(edge.TrigNum(2)).Normal(); - edge.SetCosAngle (cosang); - } - - for (i = 1; i <= edgedata.Size(); i++) - { - /* - const STLEdgeData& e = edgedata.Get(i); - ang = GetAngle(e.lt,e.rt); - if (ang < -M_PI) {ang += 2*M_PI;} - edgedata.Elem(i).angle = fabs(ang); - */ - } - -} - -void STLGeometry :: FindEdgesFromAngles() -{ - // PrintFnStart("find edges from angles"); - - double min_edge_angle = stlparam.yangle/180.*M_PI; - double cont_min_edge_angle = stlparam.contyangle/180.*M_PI; - - double cos_min_edge_angle = cos (min_edge_angle); - double cos_cont_min_edge_angle = cos (cont_min_edge_angle); - - if (calcedgedataanglesnew) {CalcEdgeDataAngles(); calcedgedataanglesnew = 0;} - - int i; - for (i = 1; i <= edgedata.Size(); i++) - { - STLTopEdge & sed = edgedata.Elem(i); - if (sed.GetStatus() == ED_CANDIDATE || - sed.GetStatus() == ED_UNDEFINED) - { - if (sed.CosAngle() <= cos_min_edge_angle) - { - sed.SetStatus (ED_CANDIDATE); - } - else - { - sed.SetStatus(ED_UNDEFINED); - } - } - } - - if (stlparam.contyangle < stlparam.yangle) - { - int changed = 1; - int its = 0; - while (changed && stlparam.contyangle < stlparam.yangle) - { - its++; - //(*mycout) << "." << flush; - changed = 0; - for (i = 1; i <= edgedata.Size(); i++) - { - STLTopEdge & sed = edgedata.Elem(i); - if (sed.CosAngle() <= cos_cont_min_edge_angle - && sed.GetStatus() == ED_UNDEFINED && - (edgedata.GetNConfCandEPP(sed.PNum(1)) == 1 || - edgedata.GetNConfCandEPP(sed.PNum(2)) == 1)) - { - changed = 1; - sed.SetStatus (ED_CANDIDATE); - } - } - } - } - - int confcand = 0; - if (edgedata.GetNConfEdges() == 0) - { - confcand = 1; - } - - for (i = 1; i <= edgedata.Size(); i++) - { - STLTopEdge & sed = edgedata.Elem(i); - if (sed.GetStatus() == ED_CONFIRMED || - (sed.GetStatus() == ED_CANDIDATE && confcand)) - { - STLEdge se(sed.PNum(1),sed.PNum(2)); - se.SetLeftTrig(sed.TrigNum(1)); - se.SetRightTrig(sed.TrigNum(2)); - AddEdge(se); - } - } - BuildEdgesPerPoint(); - - - - //(*mycout) << "its for continued angle = " << its << endl; - PrintMessage(5,"built ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); - -} - -/* -void STLGeometry :: FindEdgesFromAngles() -{ - double yangle = stlparam.yangle; - char * savetask = multithread.task; - multithread.task = "find edges"; - - const double min_edge_angle = yangle/180.*M_PI; - - int np1, np2; - double ang; - int i; - - //(*mycout) << "area=" << Area() << endl; - - for (i = 1; i <= GetNT(); i++) - { - multithread.percent = (double)i/(double)GetReadNT()*100.; - - const STLTriangle & t1 = GetTriangle(i); - //NeighbourTrigs(nt,i); - - for (int j = 1; j <= NONeighbourTrigs(i); j++) - { - int nbti = NeighbourTrig(i,j); - if (nbti > i) - { - const STLTriangle & t2 = GetTriangle(nbti); - - if (t1.IsNeighbourFrom(t2)) - { - ang = GetAngle(i,nbti); - if (ang < -M_PI*0.5) {ang += 2*M_PI;} - - t1.GetNeighbourPoints(t2,np1,np2); - - if (fabs(ang) >= min_edge_angle) - { - STLEdge se(np1,np2); - se.SetLeftTrig(i); - se.SetRightTrig(nbti); - AddEdge(se); - } - } - } - } - } - - (*mycout) << "added " << GetNE() << " edges" << endl; - - //BuildEdgesPerPoint(); - - multithread.percent = 100.; - multithread.task = savetask; - -} -*/ -void STLGeometry :: BuildEdgesPerPoint() -{ - //cout << "*** build edges per point" << endl; - edgesperpoint.SetSize(GetNP()); - - //add edges to points - int i, j; - for (i = 1; i <= GetNE(); i++) - { - //(*mycout) << "EDGE " << GetEdge(i).PNum(1) << " - " << GetEdge(i).PNum(2) << endl; - for (int j = 1; j <= 2; j++) - { - AddEdgePP(GetEdge(i).PNum(j),i); - } - } -} - -void STLGeometry :: AddFaceEdges() -{ - PrintFnStart("Add starting edges for faces"); - - //f�r Kugel eine STLLine hinzuf�gen (Vorteil: verfeinerbar, unabh�ngig von Aufl�sung der Geometrie!!!): - //Grenze von 1. gefundener chart - - ARRAY<int> edgecnt; - ARRAY<int> chartindex; - edgecnt.SetSize(GetNOFaces()); - chartindex.SetSize(GetNOFaces()); - - int i,j; - for (i = 1; i <= GetNOFaces(); i++) - { - edgecnt.Elem(i) = 0; - chartindex.Elem(i) = 0; - } - - for (i = 1; i <= GetNT(); i++) - { - int fn = GetTriangle(i).GetFaceNum(); - if (!chartindex.Get(fn)) {chartindex.Elem(fn) = GetChartNr(i);} - for (j = 1; j <= 3; j++) - { - edgecnt.Elem(fn) += GetNEPP(GetTriangle(i).PNum(j)); - } - } - - for (i = 1; i <= GetNOFaces(); i++) - { - if (!edgecnt.Get(i)) {PrintMessage(5,"Face", i, " has no edge!");} - } - - int changed = 0; - int k, p1, p2; - for (i = 1; i <= GetNOFaces(); i++) - { - if (!edgecnt.Get(i)) - { - const STLChart& c = GetChart(chartindex.Get(i)); - for (j = 1; j <= c.GetNChartT(); j++) - { - const STLTriangle& t1 = GetTriangle(c.GetChartTrig(j)); - for (k = 1; k <= 3; k++) - { - int nt = NeighbourTrig(c.GetChartTrig(j),k); - if (GetChartNr(nt) != chartindex.Get(i)) - { - t1.GetNeighbourPoints(GetTriangle(nt),p1,p2); - AddEdge(p1,p2); - changed = 1; - } - } - } - } - - } - - if (changed) BuildEdgesPerPoint(); - -} - -void STLGeometry :: LinkEdges() -{ - PushStatusF("Link Edges"); - PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); - - int i; - - lines.SetSize(0); - int starte; - int edgecnt = 0; - int found; - int rev; //indicates, that edge is inserted reverse - - //worked edges - ARRAY<int> we(GetNE()); - - //setlineendpoints; wenn 180�, dann keine endpunkte - //nur punkte mit 2 edges kommen in frage, da bei mehr oder weniger punkten ohnehin ein meshpoint hinkommt - - Vec3d v1,v2; - double cos_eca = cos(stlparam.edgecornerangle/180.*M_PI); - int ecnt = 0; - int lp1, lp2; - if (stlparam.edgecornerangle < 180) - { - for (i = 1; i <= GetNP(); i++) - { - if (GetNEPP(i) == 2) - { - if (GetEdge(GetEdgePP(i,1)).PNum(2) == GetEdge(GetEdgePP(i,2)).PNum(1) || - GetEdge(GetEdgePP(i,1)).PNum(1) == GetEdge(GetEdgePP(i,2)).PNum(2)) - { - lp1 = 1; lp2 = 2; - } - else - { - lp1 = 2; lp2 = 1; - } - - v1 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,1)).PNum(1)), - GetPoint(GetEdge(GetEdgePP(i,1)).PNum(2))); - v2 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp1)), - GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp2))); - if ((v1*v2)/sqrt(v1.Length2()*v2.Length2()) < cos_eca) - { - //(*testout) << "add edgepoint " << i << endl; - SetLineEndPoint(i); - ecnt++; - } - } - } - } - PrintMessage(5, "added ", ecnt, " mesh_points due to edge corner angle (", - stlparam.edgecornerangle, " degree)"); - - for (i = 1; i <= GetNE(); i++) {we.Elem(i) = 0;} - - while(edgecnt < GetNE()) - { - SetThreadPercent((double)edgecnt/(double)GetNE()*100.); - - STLLine* line = new STLLine(this); - - //find start edge - int j = 1; - found = 0; - //try second time, if only rings are left!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - int second = 0; - - //find a starting edge at point with 1 or more than 2 edges or at lineendpoint - while (!found && j<=GetNE()) - { - if (!we.Get(j)) - { - if (GetNEPP(GetEdge(j).PNum(1)) != 2 || IsLineEndPoint(GetEdge(j).PNum(1))) - { - starte = j; - found = 1; - rev = 0; - } - else - if (GetNEPP(GetEdge(j).PNum(2)) != 2 || IsLineEndPoint(GetEdge(j).PNum(2))) - { - starte = j; - found = 1; - rev = 1; - } - else if (second) - { - starte = j; - found = 1; - rev = 0; //0 or 1 are possible - } - } - j++; - if (!second && j == GetNE()) {second = 1; j = 1;} - } - - if (!found) {PrintSysError("No starting edge found, edgecnt=", edgecnt, ", GETNE=", GetNE());} - - line->AddPoint(GetEdge(starte).PNum(1+rev)); - line->AddPoint(GetEdge(starte).PNum(2-rev)); - if (!rev) - { - line->AddLeftTrig(GetEdge(starte).LeftTrig()); - line->AddRightTrig(GetEdge(starte).RightTrig()); - } - else - { - line->AddLeftTrig(GetEdge(starte).RightTrig()); - line->AddRightTrig(GetEdge(starte).LeftTrig()); - } - edgecnt++; we.Elem(starte) = 1; - - //add segments to line as long as segments other than starting edge are found or lineendpoint is reached - found = 1; - int other; - while(found) - { - found = 0; - int fp = GetEdge(starte).PNum(2-rev); - if (GetNEPP(fp) == 2 && !IsLineEndPoint(fp)) - { - //find the "other" edge of point fp - other = 0; - if (GetEdgePP(fp,1) == starte) {other = 1;} - - starte = GetEdgePP(fp,1+other); - - //falls ring -> aufhoeren !!!!!!!!!!! - if (!we.Elem(starte)) - { - found = 1; - rev = 0; - if (GetEdge(starte).PNum(2) == fp) {rev = 1;} - else if (GetEdge(starte).PNum(1) != fp) {PrintSysError("In Link Edges!");} - - line->AddPoint(GetEdge(starte).PNum(2-rev)); - if (!rev) - { - line->AddLeftTrig(GetEdge(starte).LeftTrig()); - line->AddRightTrig(GetEdge(starte).RightTrig()); - } - else - { - line->AddLeftTrig(GetEdge(starte).RightTrig()); - line->AddRightTrig(GetEdge(starte).LeftTrig()); - } - edgecnt++; we.Elem(starte) = 1; - } - } - } - AddLine(line); - } - PrintMessage(5,"number of lines generated = ", GetNLines()); - - //check, which lines must have at least one midpoint - INDEX_2_HASHTABLE<int> lineht(GetNLines()+1); - - for (i = 1; i <= GetNLines(); i++) - { - if (GetLine(i)->StartP() == GetLine(i)->EndP()) - { - GetLine(i)->DoSplit(); - } - } - - for (i = 1; i <= GetNLines(); i++) - { - INDEX_2 lineep (GetLine(i)->StartP(),GetLine(i)->EndP()); - lineep.Sort(); - - if (lineht.Used (lineep)) - { - GetLine(i)->DoSplit(); - int other = lineht.Get(lineep); - GetLine(other)->DoSplit(); - } - else - { - lineht.Set (lineep, i); - } - } - - for (i = 1; i <= GetNLines(); i++) - { - STLLine* line = GetLine(i); - for (int ii = 1; ii <= line->GetNS(); ii++) - { - int p1, p2; - line->GetSeg(ii,p1,p2); - // (*mycout) << "SEG " << p1 << " - " << p2 << endl; - } - } - - PopStatus(); -} - -int STLGeometry :: GetNOBodys() -{ - int markedtrigs = 0; - int starttrig = 1; - int i, k, nnt; - int bodycnt = 0; - - ARRAY<int> bodynum(GetNT()); - - for (i = 1; i <= GetNT(); i++) - bodynum.Elem(i)=0; - - - while (markedtrigs < GetNT()) - { - for (i = starttrig; i <= GetNT(); i++) - { - if (!bodynum.Get(i)) - { - starttrig = i; - break; - } - } - //add all triangles around starttriangle, which is reachable without going over an edge - ARRAY<int> todolist; - ARRAY<int> nextlist; - bodycnt++; - markedtrigs++; - bodynum.Elem(starttrig) = bodycnt; - todolist.Append(starttrig); - int p1, p2; - - while(todolist.Size()) - { - for (i = 1; i <= todolist.Size(); i++) - { - const STLTriangle& tt = GetTriangle(todolist.Get(i)); - for (k = 1; k <= NONeighbourTrigs(todolist.Get(i)); k++) - { - nnt = NeighbourTrig(todolist.Get(i),k); - if (!bodynum.Get(nnt)) - { - nextlist.Append(nnt); - bodynum.Elem(nnt) = bodycnt; - markedtrigs++; - } - } - } - - todolist.SetSize(0); - for (i = 1; i <= nextlist.Size(); i++) - { - todolist.Append(nextlist.Get(i)); - } - nextlist.SetSize(0); - } - } - PrintMessage(3, "Geometry has ", bodycnt, " separated bodys"); - - return bodycnt; -} - -void STLGeometry :: CalcFaceNums() -{ - int markedtrigs = 0; - int starttrig; - int laststarttrig = 1; - int i, k, nnt; - facecnt = 0; - - - for (i = 1; i <= GetNT(); i++) - GetTriangle(i).SetFaceNum(0); - - - while (markedtrigs < GetNT()) - { - for (i = laststarttrig; i <= GetNT(); i++) - { - if (!GetTriangle(i).GetFaceNum()) - { - starttrig = i; - laststarttrig = i; - break; - } - } - //add all triangles around starttriangle, which is reachable without going over an edge - ARRAY<int> todolist; - ARRAY<int> nextlist; - facecnt++; - markedtrigs++; - GetTriangle(starttrig).SetFaceNum(facecnt); - todolist.Append(starttrig); - int p1, p2; - - while(todolist.Size()) - { - for (i = 1; i <= todolist.Size(); i++) - { - const STLTriangle& tt = GetTriangle(todolist.Get(i)); - for (k = 1; k <= NONeighbourTrigs(todolist.Get(i)); k++) - { - nnt = NeighbourTrig(todolist.Get(i),k); - STLTriangle& nt = GetTriangle(nnt); - if (!nt.GetFaceNum()) - { - tt.GetNeighbourPoints(nt,p1,p2); - if (!IsEdge(p1,p2)) - { - nextlist.Append(nnt); - nt.SetFaceNum(facecnt); - markedtrigs++; - } - } - } - } - - todolist.SetSize(0); - for (i = 1; i <= nextlist.Size(); i++) - { - todolist.Append(nextlist.Get(i)); - } - nextlist.SetSize(0); - } - } - GetNOBodys(); - PrintMessage(3,"generated ", facecnt, " faces"); -} - -void STLGeometry :: ClearSpiralPoints() -{ - spiralpoints.SetSize(GetNP()); - int i; - for (i = 1; i <= spiralpoints.Size(); i++) - { - spiralpoints.Elem(i) = 0; - } -} - - -void STLGeometry :: BuildSmoothEdges () -{ - if (smoothedges) delete smoothedges; - - smoothedges = new INDEX_2_HASHTABLE<int> (GetNE()/10 + 1); - - - // Jack: Ok ? - // UseExternalEdges(); - - PushStatusF("Build Smooth Edges"); - - int i, j, k, l; - int nt = GetNT(); - Vec3d ng1, ng2; - - for (i = 1; i <= nt; i++) - { - if (multithread.terminate) - {PopStatus();return;} - - SetThreadPercent(100.0 * (double)i / (double)nt); - - const STLTriangle & trig = GetTriangle (i); - - Vec3d ng1 = trig.GeomNormal(points); - ng1 /= (ng1.Length() + 1e-24); - - for (j = 1; j <= 3; j++) - { - int nbt = NeighbourTrig (i, j); - - Vec3d ng2 = GetTriangle(nbt).GeomNormal(points); - ng2 /= (ng2.Length() + 1e-24); - - - int pi1, pi2; - - trig.GetNeighbourPoints(GetTriangle(nbt), pi1, pi2); - - if (!IsEdge(pi1,pi2)) - { - if (ng1 * ng2 < 0) - { - PrintMessage(7,"smoothedge found"); - INDEX_2 i2(pi1, pi2); - i2.Sort(); - smoothedges->Set (i2, 1); - } - } - } - } - - PopStatus(); -} - - - - - -int STLGeometry :: IsSmoothEdge (int pi1, int pi2) const -{ - if (!smoothedges) - return 0; - INDEX_2 i2(pi1, pi2); - i2.Sort(); - return smoothedges->Used (i2); -} - - - - -//function is not used now -int IsInArray(int n, const ARRAY<int>& ia) -{ - int i; - for (i = 1; i <= ia.Size(); i++) - { - if (ia.Get(i) == n) {return 1;} - } - return 0; -} - -void STLGeometry :: AddConeAndSpiralEdges() -{ - PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); - - PrintFnStart("AddConeAndSpiralEdges"); - - int i,j,k,n; - // int changed = 0; - - //check edges, where inner chart and no outer chart come together without an edge - int np1, np2, nt; - int cnt = 0; - - for (i = 1; i <= GetNOCharts(); i++) - { - STLChart& chart = GetChart(i); - for (j = 1; j <= chart.GetNChartT(); j++) - { - int t = chart.GetChartTrig(j); - const STLTriangle& tt = GetTriangle(t); - - for (k = 1; k <= 3; k++) - { - nt = NeighbourTrig(t,k); - if (GetChartNr(nt) != i && !TrigIsInOC(nt,i)) - { - tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); - if (!IsEdge(np1,np2)) - { - STLEdge se(np1,np2); - se.SetLeftTrig(t); - se.SetRightTrig(nt); - int edgenum = AddEdge(se); - AddEdgePP(np1,edgenum); - AddEdgePP(np2,edgenum); - //changed = 1; - PrintWarning("Found a spiral like structure: chart=", i, - ", trig=", t, ", p1=", np1, ", p2=", np2); - cnt++; - } - } - } - } - - } - - PrintMessage(5, "found ", cnt, " spiral like structures"); - PrintMessage(5, "added ", cnt, " edges due to spiral like structures"); - - cnt = 0; - int edgecnt = 0; - - ARRAY<int> trigsaroundp; - ARRAY<int> chartpointchecked; //gets number of chart, if in this chart already checked - chartpointchecked.SetSize(GetNP()); - - for (i = 1; i <= GetNP(); i++) - { - chartpointchecked.Elem(i) = 0; - } - - int onoc, notonoc, tpp, pn; - int p1, p2, tn1, tn2, l, problem; - - if (!stldoctor.conecheck) {PrintWarning("++++++++++++ \ncone checking deactivated by user!!!!!\n+++++++++++++++"); return ;} - - PushStatus("Find Critical Points"); - - int addedges = 0; - - for (i = 1; i <= GetNOCharts(); i++) - { - SetThreadPercent((double)i/(double)GetNOCharts()*100.); - if (multithread.terminate) - {PopStatus();return;} - - STLChart& chart = GetChart(i); - for (j = 1; j <= chart.GetNChartT(); j++) - { - int t = chart.GetChartTrig(j); - const STLTriangle& tt = GetTriangle(t); - - for (k = 1; k <= 3; k++) - { - pn = tt.PNum(k); - if (chartpointchecked.Get(pn) == i) - {continue;} - - int checkpoint = 0; - for (n = 1; n <= trigsperpoint.EntrySize(pn); n++) - { - if (trigsperpoint.Get(pn,n) != t && - GetChartNr(trigsperpoint.Get(pn,n)) != i && - !TrigIsInOC(trigsperpoint.Get(pn,n),i)) {checkpoint = 1;}; - } - if (checkpoint) - { - chartpointchecked.Elem(pn) = i; - - int worked = 0; - int spworked = 0; - GetSortedTrianglesAroundPoint(pn,t,trigsaroundp); - trigsaroundp.Append(t); - - problem = 0; - for (l = 2; l <= trigsaroundp.Size()-1; l++) - { - tn1 = trigsaroundp.Get(l-1); - tn2 = trigsaroundp.Get(l); - const STLTriangle& t1 = GetTriangle(tn1); - const STLTriangle& t2 = GetTriangle(tn2); - t1.GetNeighbourPoints(t2, p1, p2); - if (IsEdge(p1,p2)) break; - - if (GetChartNr(tn2) != i && !TrigIsInOC(tn2,i)) {problem = 1;} - } - - if (problem) - { - for (l = 2; l <= trigsaroundp.Size()-1; l++) - { - tn1 = trigsaroundp.Get(l-1); - tn2 = trigsaroundp.Get(l); - const STLTriangle& t1 = GetTriangle(tn1); - const STLTriangle& t2 = GetTriangle(tn2); - t1.GetNeighbourPoints(t2, p1, p2); - if (IsEdge(p1,p2)) break; - - if ((GetChartNr(tn1) == i && GetChartNr(tn2) != i && TrigIsInOC(tn2,i)) || - (GetChartNr(tn2) == i && GetChartNr(tn1) != i && TrigIsInOC(tn1,i))) - { - if (addedges || !GetNEPP(pn)) - { - STLEdge se(p1,p2); - se.SetLeftTrig(tn1); - se.SetRightTrig(tn2); - int edgenum = AddEdge(se); - AddEdgePP(p1,edgenum); - AddEdgePP(p2,edgenum); - edgecnt++; - } - if (!addedges && !GetSpiralPoint(pn)) - { - SetSpiralPoint(pn); - spworked = 1; - } - worked = 1; - } - } - } - //backwards: - problem = 0; - for (l = trigsaroundp.Size()-1; l >= 2; l--) - { - tn1 = trigsaroundp.Get(l+1); - tn2 = trigsaroundp.Get(l); - const STLTriangle& t1 = GetTriangle(tn1); - const STLTriangle& t2 = GetTriangle(tn2); - t1.GetNeighbourPoints(t2, p1, p2); - if (IsEdge(p1,p2)) break; - - if (GetChartNr(tn2) != i && !TrigIsInOC(tn2,i)) {problem = 1;} - } - if (problem) - for (l = trigsaroundp.Size()-1; l >= 2; l--) - { - tn1 = trigsaroundp.Get(l+1); - tn2 = trigsaroundp.Get(l); - const STLTriangle& t1 = GetTriangle(tn1); - const STLTriangle& t2 = GetTriangle(tn2); - t1.GetNeighbourPoints(t2, p1, p2); - if (IsEdge(p1,p2)) break; - - if ((GetChartNr(tn1) == i && GetChartNr(tn2) != i && TrigIsInOC(tn2,i)) || - (GetChartNr(tn2) == i && GetChartNr(tn1) != i && TrigIsInOC(tn1,i))) - { - if (addedges || !GetNEPP(pn)) - { - STLEdge se(p1,p2); - se.SetLeftTrig(tn1); - se.SetRightTrig(tn2); - int edgenum = AddEdge(se); - AddEdgePP(p1,edgenum); - AddEdgePP(p2,edgenum); - edgecnt++; - } - if (!addedges && !GetSpiralPoint(pn)) - { - SetSpiralPoint(pn); - spworked = 1; - //if (GetNEPP(pn) == 0) {(*mycout) << "ERROR: spiralpoint with no edge found!" << endl;} - } - worked = 1; - } - } - - if (worked) - { - //(*testout) << "set edgepoint due to spirals: pn=" << i << endl; - SetLineEndPoint(pn); - } - if (spworked) - { - /* - (*mycout) << "Warning: Critical Point " << tt.PNum(k) - << "( chart " << i << ", trig " << t - << ") has been neutralized!!!" << endl; - */ - cnt++; - } - // markedpoints.Elem(tt.PNum(k)) = 1; - } - } - } - } - PrintMessage(5, "found ", cnt, " critical points!"); - PrintMessage(5, "added ", edgecnt, " edges due to critical points!"); - - PopStatus(); - - //search points where inner chart and outer chart and "no chart" trig come together at edge-point - - PrintMessage(7,"search for special chart points"); - for (i = 1; i <= GetNOCharts(); i++) - { - STLChart& chart = GetChart(i); - for (j = 1; j <= chart.GetNChartT(); j++) - { - int t = chart.GetChartTrig(j); - const STLTriangle& tt = GetTriangle(t); - - for (k = 1; k <= 3; k++) - { - pn = tt.PNum(k); - if (GetNEPP(pn) == 2) - { - onoc = 0; - notonoc = 0; - for (n = 1; n <= trigsperpoint.EntrySize(pn); n++) - { - tpp = trigsperpoint.Get(pn,n); - if (tpp != t && GetChartNr(tpp) != i) - { - if (TrigIsInOC(tpp,i)) {onoc = 1;} - if (!TrigIsInOC(tpp,i)) {notonoc = 1;} - } - } - if (onoc && notonoc && !IsLineEndPoint(pn)) - { - GetSortedTrianglesAroundPoint(pn,t,trigsaroundp); - int here = 1; //we start on this side of edge, !here = there - int thereOC = 0; - int thereNotOC = 0; - for (l = 2; l <= trigsaroundp.Size(); l++) - { - GetTriangle(trigsaroundp.Get(l-1)). - GetNeighbourPoints(GetTriangle(trigsaroundp.Get(l)), p1, p2); - if (IsEdge(p1,p2)) {here = (here+1)%2;} - if (!here && TrigIsInOC(trigsaroundp.Get(l),i)) {thereOC = 1;} - if (!here && !TrigIsInOC(trigsaroundp.Get(l),i)) {thereNotOC = 1;} - } - if (thereOC && thereNotOC) - { - //(*mycout) << "Special OCICnotC - point " << pn << " found!" << endl; - //(*testout) << "set edgepoint due to spirals: pn=" << i << endl; - SetLineEndPoint(pn); - } - } - } - } - } - } - PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); -} - -//get trigs at a point, started with starttrig, then every left -void STLGeometry :: GetSortedTrianglesAroundPoint(int p, int starttrig, ARRAY<int>& trigs) -{ - int acttrig = starttrig; - trigs.SetAllocSize(trigsperpoint.EntrySize(p)); - trigs.SetSize(0); - trigs.Append(acttrig); - int i, j, t, p1, p2, locindex1, locindex2; - - //(*mycout) << "trigs around point " << p << endl; - - int end = 0; - while (!end) - { - const STLTriangle& at = GetTriangle(acttrig); - for (i = 1; i <= trigsperpoint.EntrySize(p); i++) - { - t = trigsperpoint.Get(p,i); - const STLTriangle& nt = GetTriangle(t); - if (at.IsNeighbourFrom(nt)) - { - at.GetNeighbourPoints(nt, p1, p2); - if (p2 == p) {Swap(p1,p2);} - if (p1 != p) {PrintSysError("In GetSortedTrianglesAroundPoint!!!");} - - for (j = 1; j <= 3; j++) - { - if (at.PNum(j) == p1) {locindex1 = j;}; - if (at.PNum(j) == p2) {locindex2 = j;}; - } - if ((locindex2+1)%3+1 == locindex1) - { - if (t != starttrig) - { - trigs.Append(t); - // (*mycout) << "trig " << t << endl; - acttrig = t; - } - else - { - end = 1; - } - break; - } - } - } - } - -} - -/* -int STLGeometry :: NeighbourTrig(int trig, int nr) const -{ - return neighbourtrigs.Get(trig,nr); -} -*/ - - - -void STLGeometry :: SmoothGeometry () -{ - int i, j, k; - - int np = GetNP(); - double maxerr0, maxerr; - - for (i = 1; i <= np; i++) - { - if (GetNEPP(i)) continue; - - maxerr0 = 0; - for (j = 1; j <= NOTrigsPerPoint(i); j++) - { - int tnum = TrigPerPoint(i, j); - double err = Angle (GetTriangle(tnum).Normal (), - GetTriangle(tnum).GeomNormal(GetPoints())); - if (err > maxerr0) - maxerr0 = err; - } - - Point3d pi = GetPoint (i); - if (maxerr0 < 1.1) continue; // about 60 degree - - maxerr0 /= 2; // should be at least halfen - - for (k = 1; k <= NOTrigsPerPoint(i); k++) - { - const STLTriangle & trig = GetTriangle (TrigPerPoint (i, k)); - Point3d c = Center(GetPoint (trig.PNum(1)), - GetPoint (trig.PNum(2)), - GetPoint (trig.PNum(3))); - - Point3d np = pi + 0.1 * (c - pi); - SetPoint (i, np); - - maxerr = 0; - for (j = 1; j <= NOTrigsPerPoint(i); j++) - { - int tnum = TrigPerPoint(i, j); - double err = Angle (GetTriangle(tnum).Normal (), - GetTriangle(tnum).GeomNormal(GetPoints())); - if (err > maxerr) - maxerr = err; - } - - if (maxerr < maxerr0) - { - pi = np; - } - } - - SetPoint (i, pi); - } -} -} diff --git a/Netgen/libsrc/stlgeom/stlgeom.hpp b/Netgen/libsrc/stlgeom/stlgeom.hpp deleted file mode 100644 index c9bfb1e535..0000000000 --- a/Netgen/libsrc/stlgeom/stlgeom.hpp +++ /dev/null @@ -1,450 +0,0 @@ -#ifndef FILE_STLGEOM -#define FILE_STLGEOM - -/**************************************************************************/ -/* File: stlgeom.hpp */ -/* Author: Joachim Schoeberl */ -/* Author2: Johannes Gerstmayr */ -/* Date: 26. Jul. 99 */ -/**************************************************************************/ - -/** - STL Geometry - - - Terminology: - - Point ... coordinates of STL triangles - Triangle (short Trig) STL triangle - TopEdge .... edge in topology, boundary of STL triangles (many) - Edge .... Edges which will occur in the mesh (confirmed edges, less) -*/ - - -#include <gprim.hpp> -#include <meshing.hpp> - - - -namespace netgen -{ - extern int IsInArray(int n, const ARRAY<int>& ia); - extern int AddIfNotExists(ARRAY<int>& list, int x); - - -#include "stltopology.hpp" -#include "stltool.hpp" -#include "stlline.hpp" - - - - - - - - class STLEdgeDataList - { - ARRAY<int> storedstatus; - STLTopology & geom; - public: - - STLEdgeDataList(STLTopology & ageom); - ~STLEdgeDataList(); - - void Store (); - void Restore (); - - void SetSize(int /* size */) { }; - void Clear() { }; - int Size() const { return geom.GetNTE(); } - const STLTopEdge & Get(int i) const { return geom.GetTopEdge(i); } - STLTopEdge & Elem(int i) { return geom.GetTopEdge(i); } - - int GetNEPP(int pn) const {return geom.NTopEdgesPerPoint(pn); } - int GetEdgePP(int pn, int vi) const {return geom.TopEdgePerPoint(pn, vi);}; - - //void AddEdgePP(int pn, int vn) { } ; - - void ResetAll(); - void ChangeStatus(int status1, int status2); - - int GetEdgeNum(int np1, int np2) const - { return geom.GetTopEdgeNum (np1, np2); } - - int GetNConfEdges() const; - - void Write(ofstream& of) const; - void Read(ifstream& ifs); - - void BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line); - void BuildClusterWithEdge(int ep1, int ep2, ARRAY<twoint>& line); - - int GetNEPPStat(int p, int status) const; - int GetNConfCandEPP(int p) const; - }; - - - - - - - class STLGeometry : public STLTopology - { - // edges to be meshed: - ARRAY<STLEdge> edges; - //edges per point - TABLE<int> edgesperpoint; - - // line: a connection of edges - ARRAY<STLLine*> lines; - ARRAY<int> lineendpoints; //per geometrypoint, 1 = is endpoint; 0 = no endpoint, - - ARRAY<Vec3d> normals; //normals belong to points! - - ARRAY<twoint> externaledges; - - int undoexternaledges; - ARRAY<twoint> storedexternaledges; - - STLEdgeDataList edgedata; - // STLEdgeDataList edgedata_store; - int calcedgedataanglesnew; - - int edgedatastored; - - - - int facecnt; - //meshpoint is only set, if an edge is at this point!!! - - ARRAY<int> vicinity; //is one, if a triangle belongs to vicinity (eg. of selecttrig) - ARRAY<int> markedtrigs; //is one, if a triangle belongs to marked triangles (calcdirtystrigs) - ARRAY<Point3d> markedsegs; //every pointpair is a segment!!! - ARRAY<twoint> selectedmultiedge; - - - //spiralpoints: - ARRAY<int> spiralpoints; - // - ARRAY<STLChart*> atlas; - //marks all already charted trigs with chartnumber - ARRAY<int> chartmark; - //outerchartspertrig, ascending sorted - TABLE<int> outerchartspertrig; - - - //for meshing and project: - ARRAY<int> meshcharttrigs; //per trig: 1=belong to chart, 0 not - int meshchart; - - ARRAY<int> ha_points; // help array, np long, filled with 0 - - - // sharp geometric edges not declared as edges - // (not considered for spiral check) - INDEX_2_HASHTABLE<int> * smoothedges; - - - //transformation: - Vec<3> meshtrignv; - Vec<3> ex, ey, ez; - Point<3> p1; - - public: - int edgesfound; - int surfacemeshed; - int surfaceoptimized; - int volumemeshed; - - int trigsconverted; //when STLTriangles exist -> 1 - - //for selecting nodes - //int selecttrig, nodeofseltrig; - - //only for testing; - ARRAY<STLLine*> meshlines; - ARRAY<Point3d> meshpoints; - - public: - STLGeometry(); - virtual ~STLGeometry(); - - - void Clear(); - - - - void STLInfo(double* data); - //stldoctor: - void SmoothNormals(); - void MarkNonSmoothNormals(); - - void CalcEdgeData(); - void CalcEdgeDataAngles(); - - const STLEdgeDataList& EdgeDataList() const {return edgedata;} - - void UndoEdgeChange(); - void StoreEdgeData(); - void RestoreEdgeData(); - - //void ClearSelectedMultiEdge() {selectedmultiedge.SetSize(0);} - //void AddSelectedMultiEdge(twoint ep) {selectedmultiedge.Append(ep);} - //int SelectedMultiEdgeSize() {return selectedmultiedge.Size();} - const ARRAY<twoint>& SelectedMultiEdge() {return selectedmultiedge;} - twoint GetNearestSelectedDefinedEdge(); - void BuildSelectedMultiEdge(twoint ep); - void BuildSelectedEdge(twoint ep); - void BuildSelectedCluster(twoint ep); - - void ImportEdges(); - void AddEdges(const ARRAY<Point<3> >& eps); - void ExportEdges(); - void LoadEdgeData(const char* file); - void SaveEdgeData(const char* file); - // void SetEdgeAtSelected(int mode); - - - void STLDoctorConfirmEdge(); - void STLDoctorCandidateEdge(); - void STLDoctorExcludeEdge(); - void STLDoctorUndefinedEdge(); - - void STLDoctorSetAllUndefinedEdges(); - void STLDoctorEraseCandidateEdges(); - void STLDoctorConfirmCandidateEdges(); - void STLDoctorConfirmedToCandidateEdges(); - - void STLDoctorDirtyEdgesToCandidates(); - void STLDoctorLongLinesToCandidates(); - - void UndoExternalEdges(); - void StoreExternalEdges(); - void RestoreExternalEdges(); - - void ImportExternalEdges(const char * filename); // Flame edges, JS - // void LoadExternalEdges(); - - void BuildExternalEdgesFromEdges(); - void SaveExternalEdges(); - void AddExternalEdgeAtSelected(); - void AddClosedLinesToExternalEdges(); - void AddLongLinesToExternalEdges(); - void AddAllNotSingleLinesToExternalEdges(); - void STLDoctorBuildEdges(); - void AddExternalEdgesFromGeomLine(); - void DeleteDirtyExternalEdges(); - void DeleteExternalEdgeAtSelected(); - void DeleteExternalEdgeInVicinity(); - void AddExternalEdge(int p1, int p2); - void DeleteExternalEdge(int p1, int p2); - int IsExternalEdge(int p1, int p2); - int NOExternalEdges() const {return externaledges.Size();} - twoint GetExternalEdge(int i) const {return externaledges.Get(i);} - - void DestroyDirtyTrigs(); - void CalcNormalsFromGeometry(); - void MoveSelectedPointToMiddle(); - void NeighbourAnglesOfSelectedTrig(); - void PrintSelectInfo(); - void ShowSelectedTrigChartnum(); - void ShowSelectedTrigCoords(); - void SmoothGeometry (); - - - void LoadMarkedTrigs(); - void SaveMarkedTrigs(); - void ClearMarkedSegs() {markedsegs.SetSize(0);} - void AddMarkedSeg(const Point<3> & p1, const Point<3> & p2) - { - markedsegs.Append(p1);markedsegs.Append(p2); - } - - void GetMarkedSeg(int i, Point<3> & p1, Point<3> & p2) - { - p1=markedsegs.Get(i*2-1); - p2=markedsegs.Get(i*2); - } - int GetNMarkedSegs() {return markedsegs.Size()/2;} - void CalcVicinity(int starttrig); - void GetVicinity(int starttrig, int size, ARRAY<int>& vic); - - int Vicinity(int trig) const; - - void InitMarkedTrigs(); - void MarkDirtyTrigs(); - void SmoothDirtyTrigs(); - void GeomSmoothRevertedTrigs(); - void MarkRevertedTrigs(); - double CalcTrigBadness(int i); - int IsMarkedTrig(int trig) const; - void SetMarkedTrig(int trig, int num); - void MarkTopErrorTrigs (); - - //Selected triangle - void SetSelectTrig(int trig); - int GetSelectTrig() const; - void SetNodeOfSelTrig(int n); - int GetNodeOfSelTrig() const; - - - int AddNormal(const Vec3d& n) {return normals.Append(n);} - const Vec3d & GetNormal(int nr) const {return normals.Get(nr);} - void SetNormal(int nr, const Vec3d& n) {normals.Elem(nr) = n;} - - int AddEdge(const STLEdge& v) {return edges.Append(v);} - int AddEdge(int p1, int p2); - - STLEdge GetEdge(int nr) {return edges.Get(nr);} - int GetNE() {return edges.Size();} - - double Area(); - - double GetAngle(int t1, int t2); - double GetGeomAngle(int t1, int t2); - //if triangles t1 and t2 touch, return 1 and in p1, p2 the touching points - //int TrigsTouch(int t1, int t2, int& p1, int& p2); - - - - /// - - ///ReadTriangle->STLTriangle, initialise some important variables, always after load!!! - virtual void InitSTLGeometry (const ARRAY<STLReadTriangle> & readtrigs); - virtual void TopologyChanged(); //do some things, if topology changed! - int CheckGeometryOverlapping(); - - //get NO edges per point - int GetEPPSize() const {return edgesperpoint.Size();}; - int GetNEPP(int pn) - { - if (edgesperpoint.Size() == 0) {BuildEdgesPerPoint();} - return edgesperpoint.EntrySize(pn); - }; - int GetEdgePP(int pn, int vi) - { - if (edgesperpoint.Size() == 0) {BuildEdgesPerPoint();} - return edgesperpoint.Get(pn,vi); - }; - void AddEdgePP(int pn, int vn) {edgesperpoint.Add1(pn,vn);}; - //von 2 punkten ermitteln, ob sie eine Kante sind - int IsEdge(int p1, int p2); - int IsEdgeNum(int p1, int p2); - - ///Build EdgeSegments - void ClearEdges(); - void BuildEdges(); - void BuildEdgesPerPoint(); - void UseExternalEdges(); - - - void FindEdgesFromAngles(); - void CalcFaceNums(); - int GetNOBodys(); - int GetNOFaces() {return facecnt;} - void LinkEdges(); - - void AddConeAndSpiralEdges(); - void AddFaceEdges(); //each face should have at least one starting edge (outherwise it won't be meshed) - - void GetDirtyChartTrigs(int chartnum, STLChart& chart, const ARRAY<int>& outercharttrigs, - ARRAY<int>& chartpointchecked, ARRAY<int>& dirtytrigs); - - void ClearSpiralPoints(); - void SetSpiralPoint(int pn) {spiralpoints.Elem(pn) = 1;}; - int GetSpiralPoint(int pn) const {return spiralpoints.Get(pn);}; - - void GetSortedTrianglesAroundPoint(int p, int starttrig, ARRAY<int>& trigs); - - // smooth edges: sharp geometric edges not declared as edges - void BuildSmoothEdges (); - int IsSmoothEdge (int pi1, int pi2) const; - - - //make charts with regions of a max. angle - void MakeAtlas(class Mesh & mesh); - - //outerchartspertrig, sorted! - int GetOCPTSize() const {return outerchartspertrig.Size();}; - int GetNOCPT(int tn) const {return outerchartspertrig.EntrySize(tn);}; - int GetOCPT(int tn, int vi) const {return outerchartspertrig.Get(tn,vi);}; - void SetOCPT(int tn, int vi, int ocn) {outerchartspertrig.Set(tn,vi,ocn);}; - void AddOCPT(int tn, int ocn) {outerchartspertrig.Add1(tn, ocn);}; - int TrigIsInOC(int tn, int ocn) const; - - //get chart number of a trig or 0 if unmarked - int GetChartNr(int i) const; - int GetMarker(int i) const - { return chartmark.Get(i); } - void SetMarker(int nr, int m); - int GetNOCharts() const; - //get a chart from atlas - const STLChart& GetChart(int nr) const; - STLChart& GetChart(int nr) {return *(atlas.Get(nr));}; - int AtlasMade() const; - - void GetInnerChartLimes(ARRAY<twoint>& limes, int chartnum); - - //FOR MESHING - int GetMeshChartNr () { return meshchart; } - void GetMeshChartBoundary (ARRAY<Point2d > & points, - ARRAY<Point3d > & points3d, - ARRAY<INDEX_2> & lines, double h); - - - Point<3> PointBetween(const Point<3> & p1, int t1, const Point<3> & p2, int t2); - - //select triangles in meshcharttrigs of actual (defined by trig) whole chart - void PrepareSurfaceMeshing(); - // - void DefineTangentialPlane(const Point<3> & ap1, const Point<3> & ap2, int trig); - // - void SelectChartOfTriangle (int trignum); - // - void SelectChartOfPoint (const Point<3> & p); - // - const Vec<3> & GetChartNormalVector () const { return meshtrignv; } - - // list of trigs - void ToPlane (const Point<3> & locpoint, int * trigs, Point<2> & plainpoint, - double h, int& zone, int checkchart); - //return 0, wenn alles OK, 1 sonst - int FromPlane (const Point<2> & plainpoint, Point<3> & locpoint, double h); - - //get nearest point in actual chart and return any triangle where it lies on - int ProjectNearest(Point<3> & p3d) const; - //project point with normal nv from last define tangential plane - - int LastTrig() const; - int Project(Point<3> & p3d) const; - int ProjectOnWholeSurface (Point<3> & p3d) const; - - int GetNLines() const {return lines.Size();} - int AddLine(STLLine* line) {return lines.Append(line);} - STLLine* GetLine(int nr) const {return lines.Get(nr);} - int GetLineP(int lnr, int pnr) const {return lines.Get(lnr)->PNum(pnr);} - int GetLineNP(int nr) const {return lines.Get(nr)->NP();} - - void SetLineEndPoint(int pn); - int IsLineEndPoint(int pn); - int LineEndPointsSet() const {return lineendpoints.Size() == GetNP();} - void ClearLineEndPoints(); - - void RestrictLocalH(class Mesh & mesh, double gh); - void RestrictLocalHCurv(class Mesh & mesh, double gh); - void RestrictHChartDistOneChart(int chartnum, ARRAY<int>& acttrigs, class Mesh & mesh, - double gh, double fact, double minh); - - friend class MeshingSTLSurface; - }; - - -#include "meshstlsurface.hpp" - - - extern int STLMeshingDummy (STLGeometry* stlgeometry, Mesh*& mesh, - int perfstepsstart, int perfstepsend, char* optstring); - - -} -#endif diff --git a/Netgen/libsrc/stlgeom/stlgeomchart.cpp b/Netgen/libsrc/stlgeom/stlgeomchart.cpp deleted file mode 100644 index c2f64f5f1f..0000000000 --- a/Netgen/libsrc/stlgeom/stlgeomchart.cpp +++ /dev/null @@ -1,801 +0,0 @@ -//20.11.1999 third part of stlgeom.cc, functions with chart and atlas - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - -#include "stlgeom.hpp" - -namespace netgen -{ - -int chartdebug = 0; - - - -void STLGeometry :: MakeAtlas(Mesh & mesh) -{ - - double h, h2; - - h = mparam.maxh; - - - PushStatusF("Make Atlas"); - - int i,j,k,l,m,ctl; - - double atlasminh = 5e-3 * Dist (boundingbox.PMin(), boundingbox.PMax()); - PrintMessage(5, "atlasminh = ", atlasminh); - - //speedup for make atlas - if (GetNT() > 50000) - { - mesh.SetGlobalH(0.05*Dist (boundingbox.PMin(), boundingbox.PMax())); - } - - - atlas.SetSize(0); - ClearSpiralPoints(); - BuildSmoothEdges(); - - - double chartangle = stlparam.chartangle; - double outerchartangle = stlparam.outerchartangle; - - chartangle = chartangle/180.*M_PI; - outerchartangle = outerchartangle/180.*M_PI; - - double coschartangle = cos(chartangle); - double cosouterchartangle = cos(outerchartangle); - double cosouterchartanglehalf = cos(0.5*outerchartangle); - double sinchartangle = sin(chartangle); - double sinouterchartangle = sin(outerchartangle); - - ARRAY<int> outermark(GetNT()); //marks all trigs form actual outer region - ARRAY<int> outertested(GetNT()); //marks tested trigs for outer region - ARRAY<int> pointstochart(GetNP()); //point in chart becomes chartnum - ARRAY<int> innerpointstochart(GetNP()); //point in chart becomes chartnum - ARRAY<int> chartpoints; //point in chart becomes chartnum - ARRAY<int> innerchartpoints; - ARRAY<int> dirtycharttrigs; - ARRAY<int> chartpointchecked; - - ARRAY<int> chartdistacttrigs; //outercharttrigs - chartdistacttrigs.SetSize(GetNT()); - for (i = 1; i <= GetNT(); i++) - { - chartdistacttrigs.Elem(i) = 0; - } - - STLBoundary chartbound(this); //knows the actual chart boundary - int chartboundarydivisions = 10; - markedsegs.SetSize(0); //for testing!!! - - chartpointchecked.SetSize(GetNP()); //for dirty-chart-trigs - - outermark.SetSize(GetNT()); - outertested.SetSize(GetNT()); - pointstochart.SetSize(GetNP()); - innerpointstochart.SetSize(GetNP()); - chartmark.SetSize(GetNT()); - - for (i = 1; i <= GetNP(); i++) - { - innerpointstochart.Elem(i) = 0; - pointstochart.Elem(i) = 0; - chartpointchecked.Elem(i) = 0; - } - - double eps = 1e-12 * Dist (boundingbox.PMin(), boundingbox.PMax()); - - int spiralcheckon = stldoctor.spiralcheck; - if (!spiralcheckon) {PrintWarning("++++++++++++\nspiral deactivated by user!!!!\n+++++++++++++++"); } - - for (i = 1; i <= GetNT(); i++) - { - chartmark.Elem(i) = 0; - } - - for (i = 1; i <= GetNT(); i++) - { - outermark.Elem(i) = 0; - outertested.Elem(i) = 0; - } - - int markedtrigcnt = 0; - int found = 1; - double atlasarea = Area(); - double workedarea = 0; - double showinc = 100.*5000./(double)GetNT(); - double nextshow = 0; - Point<3> startp; - int lastunmarked = 1; - int prelastunmarked; - - PrintMessage(5,"one dot per 5000 triangles: "); - - while(markedtrigcnt < GetNT() && found) - { - if (multithread.terminate) - {PopStatus();return;} - - if (workedarea / atlasarea*100. >= nextshow) - {PrintDot(); nextshow+=showinc;} - - SetThreadPercent(100.0 * workedarea / atlasarea); - - /* - for (j = 1; j <= GetNT(); j++) - { - outermark.Elem(j) = 0; - } - */ - STLChart * chart = new STLChart(this); - atlas.Append(chart); - - //find unmarked trig - prelastunmarked = lastunmarked; - j = lastunmarked; - found = 0; - while (!found && j <= GetNT()) - { - if (!GetMarker(j)) {found = 1; lastunmarked = j;} - else {j++;} - } - - chartpoints.SetSize(0); - innerchartpoints.SetSize(0); - chartbound.Clear(); - chartbound.SetChart(chart); - - if (!found) {PrintSysError("Make Atlas, no starttrig found"); return;} - - //find surrounding trigs - int starttrig = j; - - double mindist, tdist; - startp = GetPoint(GetTriangle(starttrig).PNum(1)); - - int accepted; - int chartnum = GetNOCharts(); - - Vec<3> sn = GetTriangle(starttrig).Normal(); - chart->SetNormal (startp, sn); - - - SetMarker(starttrig, chartnum); - markedtrigcnt++; - chart->AddChartTrig(starttrig); - chartbound.AddTriangle(GetTriangle(starttrig)); - - workedarea += GetTriangle(starttrig).Area(points); - - for (i = 1; i <= 3; i++) - { - innerpointstochart.Elem(GetTriangle(starttrig).PNum(i)) = chartnum; - pointstochart.Elem(GetTriangle(starttrig).PNum(i)) = chartnum; - chartpoints.Append(GetTriangle(starttrig).PNum(i)); - innerchartpoints.Append(GetTriangle(starttrig).PNum(i)); - } - - Vec<3> n2, n3; - int changed = 1; - int nt; - int ic; - int oldstartic = 1; - int oldstartic2; - int np1, np2; - - while (changed) - { - changed = 0; - oldstartic2 = oldstartic; - oldstartic = chart->GetNT(); - // for (ic = oldstartic2; ic <= chart->GetNT(); ic++) - for (ic = oldstartic2; ic <= oldstartic; ic++) - { - i = chart->GetTrig(ic); - if (GetMarker(i) == chartnum) - { - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - nt = NeighbourTrig(i,j); - GetTriangle(i).GetNeighbourPoints(GetTriangle(nt),np1,np2); - if (GetMarker(nt) == 0 && !IsEdge(np1,np2)) - { - n2 = GetTriangle(nt).Normal(); - if ( (n2 * sn) >= coschartangle ) - { - - accepted = 1; - /* - //alter spiralentest, schnell, aber ungenau - for (k = 1; k <= 3; k++) - { - //find overlapping charts: - Point3d pt = GetPoint(GetTriangle(nt).PNum(k)); - if (innerpointstochart.Get(GetTriangle(nt).PNum(k)) != chartnum) - { - for (l = 1; l <= chartpoints.Size(); l++) - { - Vec3d vptpl(GetPoint(chartpoints.Get(l)), pt); - double vlen = vptpl.Length(); - if (vlen > 0) - { - vptpl /= vlen; - if ( fabs( vptpl * sn) > sinchartangle ) - { - accepted = 0; - break; - } - } - } - - } - } - */ - - int nnp1, nnp2; - int nnt; - //find overlapping charts exacter: - for (k = 1; k <= 3; k++) - { - nnt = NeighbourTrig(nt,k); - if (GetMarker(nnt) != chartnum) - { - GetTriangle(nt).GetNeighbourPoints(GetTriangle(nnt),nnp1,nnp2); - - accepted = chartbound.TestSeg(GetPoint(nnp1), - GetPoint(nnp2), - sn,sinchartangle,1 /*chartboundarydivisions*/ ,points, eps); - - - n3 = GetTriangle(nnt).Normal(); - if ( (n3 * sn) >= coschartangle && - IsSmoothEdge (nnp1, nnp2) ) - accepted = 1; - } - if (!accepted) {break;} - } - - /* - mindist = 1E50; - for (int ii = 1; ii <= 3; ii++) - { - tdist = Dist(GetPoint(GetTriangle(nt).PNum(ii)),startp); - if (tdist < mindist) {mindist = tdist;} - } - if (mindist > maxdist1) {accepted = 0;} - */ - - if (accepted) - { - SetMarker(nt, chartnum); - changed = 1; - markedtrigcnt++; - workedarea += GetTriangle(nt).Area(points); - chart->AddChartTrig(nt); - - chartbound.AddTriangle(GetTriangle(nt)); - - for (k = 1; k <= 3; k++) - { - if (innerpointstochart.Get(GetTriangle(nt).PNum(k)) - != chartnum) - { - innerpointstochart.Elem(GetTriangle(nt).PNum(k)) = chartnum; - pointstochart.Elem(GetTriangle(nt).PNum(k)) = chartnum; - chartpoints.Append(GetTriangle(nt).PNum(k)); - innerchartpoints.Append(GetTriangle(nt).PNum(k)); - } - } - } - } - } - } - } - } - } - - - //find outertrigs - - // chartbound.Clear(); - // warum, ic-bound auf edge macht Probleme js ??? - - - outermark.Elem(starttrig) = chartnum; - //chart->AddOuterTrig(starttrig); - changed = 1; - oldstartic = 1; - while (changed) - { - changed = 0; - oldstartic2 = oldstartic; - oldstartic = chart->GetNT(); - //for (ic = oldstartic2; ic <= chart->GetNT(); ic++) - for (ic = oldstartic2; ic <= oldstartic; ic++) - { - i = chart->GetTrig(ic); - - if (outermark.Get(i) == chartnum) - { - for (j = 1; j <= NONeighbourTrigs(i); j++) - { - nt = NeighbourTrig(i,j); - if (outermark.Get(nt) == chartnum) - continue; - - const STLTriangle & ntrig = GetTriangle(nt); - GetTriangle(i).GetNeighbourPoints(GetTriangle(nt),np1,np2); - - if (IsEdge (np1, np2)) - continue; - - - /* - if (outertested.Get(nt) == chartnum) - continue; - */ - outertested.Elem(nt) = chartnum; - - - n2 = GetTriangle(nt).Normal(); - /* - double ang; - ang = Angle(n2,sn); - if (ang < -M_PI*0.5) {ang += 2*M_PI;} - - (*testout) << "ang < ocharang = " << (fabs(ang) <= outerchartangle); - (*testout) << " = " << ( (n2 * sn) >= cosouterchartangle) << endl; - - // if (fabs(ang) <= outerchartangle) - */ - //abfragen, ob noch im tolerierten Winkel - if ( (n2 * sn) >= cosouterchartangle ) - { - accepted = 1; - - int isdirtytrig = 0; - Vec<3> gn = GetTriangle(nt).GeomNormal(points); - double gnlen = gn.Length(); - - if (n2 * gn <= cosouterchartanglehalf * gnlen) - {isdirtytrig = 1;} - - //zurueckweisen, falls eine Spiralartige outerchart entsteht - int nnp1, nnp2; - int nnt; - //find overlapping charts exacter: - //do not check dirty trigs! - - - if (spiralcheckon && !isdirtytrig) - for (k = 1; k <= 3; k++) - { - nnt = NeighbourTrig(nt,k); - - if (outermark.Elem(nnt) != chartnum) - { - GetTriangle(nt).GetNeighbourPoints(GetTriangle(nnt),nnp1,nnp2); - - accepted = - chartbound.TestSeg(GetPoint(nnp1),GetPoint(nnp2), - sn,sinouterchartangle, 0 /*chartboundarydivisions*/ ,points, eps); - - - n3 = GetTriangle(nnt).Normal(); - if ( (n3 * sn) >= cosouterchartangle && - IsSmoothEdge (nnp1, nnp2) ) - accepted = 1; - } - if (!accepted) {break;} - } - - //} - - - // outer chart is only small environment of - // inner chart: - if (accepted) - { - accepted = 0; - - for (k = 1; k <= 3; k++) - { - if (innerpointstochart.Get(ntrig.PNum(k)) == chartnum) - { - accepted = 1; - break; - } - } - - if (!accepted) - for (k = 1; k <= 3; k++) - { - Point<3> pt = GetPoint(ntrig.PNum(k)); - h2 = sqr(mesh.GetH(pt)); - - for (l = 1; l <= innerchartpoints.Size(); l++) - { - tdist = Dist2(pt, GetPoint (innerchartpoints.Get(l))); - if (tdist < 4 * h2) - { - accepted = 1; - break; - } - } - if (accepted) {break;} - } - } - - - if (accepted) - { - changed = 1; - outermark.Elem(nt) = chartnum; - - if (GetMarker(nt) != chartnum) - { - chartbound.AddTriangle(GetTriangle(nt)); - chart->AddOuterTrig(nt); - for (k = 1; k <= 3; k++) - { - if (pointstochart.Get(GetTriangle(nt).PNum(k)) - != chartnum) - { - pointstochart.Elem(GetTriangle(nt).PNum(k)) = chartnum; - chartpoints.Append(GetTriangle(nt).PNum(k)); - } - } - } - } - } - } - } - } - } - //end of while loop for outer chart - GetDirtyChartTrigs(chartnum, *chart, outermark, chartpointchecked, dirtycharttrigs); - //dirtycharttrigs are local (chart) point numbers!!!!!!!!!!!!!!!! - - if (dirtycharttrigs.Size() != 0 && - (dirtycharttrigs.Size() != chart->GetNChartT() || dirtycharttrigs.Size() != 1)) - { - if (dirtycharttrigs.Size() == chart->GetNChartT() && dirtycharttrigs.Size() != 1) - { - //if all trigs would be eliminated -> leave 1 trig! - dirtycharttrigs.SetSize(dirtycharttrigs.Size() - 1); - } - for (k = 1; k <= dirtycharttrigs.Size(); k++) - { - int tn = chart->GetChartTrig(dirtycharttrigs.Get(k)); - outermark.Elem(tn) = 0; //not necessary, for later use - SetMarker(tn, 0); - markedtrigcnt--; - workedarea -= GetTriangle(tn).Area(points); - } - chart->MoveToOuterChart(dirtycharttrigs); - lastunmarked = 1; - lastunmarked = prelastunmarked; - } - - //calculate an estimate meshsize, not to produce to large outercharts, with factor 2 larger! - RestrictHChartDistOneChart(chartnum, chartdistacttrigs, mesh, h, 0.5, atlasminh); - } - - PrintMessage(5,""); - PrintMessage(5,"NO charts=", atlas.Size()); - - int cnttrias = 0; - //int found2; - outerchartspertrig.SetSize(GetNT()); - - for (i = 1; i <= atlas.Size(); i++) - { - int j; - //found2 = 1; - for (j = 1; j <= GetChart(i).GetNT(); j++) - { - int tn = GetChart(i).GetTrig(j); - AddOCPT(tn,i); - - } - - cnttrias += GetChart(i).GetNT(); - } - PrintMessage(5, "NO outer chart trias=", cnttrias); - - //sort outerchartspertrig - for (i = 1; i <= GetNT(); i++) - { - int j,k, swap; - for (k = 1; k < GetNOCPT(i); k++) - { - - for (j = 1; j < GetNOCPT(i); j++) - { - swap = GetOCPT(i,j); - if (GetOCPT(i,j+1) < swap) - { - SetOCPT(i,j,GetOCPT(i,j+1)); - SetOCPT(i,j+1,swap); - } - } - } - - // check make atlas - if (GetChartNr(i) <= 0 || GetChartNr(i) > GetNOCharts()) - { - PrintSysError("Make Atlas: chartnr(", i, ")=0!!"); - }; - } - - mesh.SetGlobalH(mparam.maxh); - - - AddConeAndSpiralEdges(); - - PrintMessage(5,"Make Atlas finished"); - - PopStatus(); -} - - -int STLGeometry::TrigIsInOC(int tn, int ocn) const -{ - if (tn < 1 || tn > GetNT()) - { - // assert (1); - abort (); - PrintSysError("STLGeometry::TrigIsInOC illegal tn: ", tn); - - return 0; - } - - /* - int firstval = 0; - int i; - for (i = 1; i <= GetNOCPT(tn); i++) - { - if (GetOCPT(tn, i) == ocn) {firstval = 1;} - } - */ - - int found = 0; - - int inc = 1; - while (inc <= GetNOCPT(tn)) {inc *= 2;} - inc /= 2; - - int start = inc; - - while (!found && inc > 0) - { - if (GetOCPT(tn,start) > ocn) {inc = inc/2; start -= inc;} - else if (GetOCPT(tn,start) < ocn) {inc = inc/2; if (start+inc <= GetNOCPT(tn)) {start += inc;}} - else {found = 1;} - } - - return GetOCPT(tn, start) == ocn; -} - -int STLGeometry :: GetChartNr(int i) const -{ - if (i > chartmark.Size()) - { - PrintSysError("GetChartNr(", i, ") not possible!!!"); - i = 1; - } - return chartmark.Get(i); -} -/* -int STLGeometry :: GetMarker(int i) const -{ - return chartmark.Get(i); -} -*/ -void STLGeometry :: SetMarker(int nr, int m) -{ - chartmark.Elem(nr) = m; -} -int STLGeometry :: GetNOCharts() const -{ - return atlas.Size(); -} -const STLChart& STLGeometry :: GetChart(int nr) const -{ - if (nr > atlas.Size()) - { - PrintSysError("GetChart(", nr, ") not possible!!!"); - nr = 1; - } - return *(atlas.Get(nr)); -} - -int STLGeometry :: AtlasMade() const -{ - return chartmark.Size() != 0; -} - - -//return 1 if not exists -int AddIfNotExists(ARRAY<int>& list, int x) -{ - int i; - for (i = 1; i <= list.Size(); i++) - { - if (list.Get(i) == x) {return 0;} - } - list.Append(x); - return 1; -} - -void STLGeometry :: GetInnerChartLimes(ARRAY<twoint>& limes, int chartnum) -{ - int j, k; - - int t, nt, np1, np2; - STLTriangle tt; - - limes.SetSize(0); - - STLChart& chart = GetChart(chartnum); - - for (j = 1; j <= chart.GetNChartT(); j++) - { - t = chart.GetChartTrig(j); - const STLTriangle& tt = GetTriangle(t); - for (k = 1; k <= 3; k++) - { - nt = NeighbourTrig(t,k); - if (GetChartNr(nt) != chartnum) - { - tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); - if (!IsEdge(np1,np2)) - { - limes.Append(twoint(np1,np2)); - /* - p3p1 = GetPoint(np1); - p3p2 = GetPoint(np2); - if (AddIfNotExists(limes,np1)) - { - plimes1.Append(p3p1); - //plimes1trigs.Append(t); - //plimes1origin.Append(np1); - } - if (AddIfNotExists(limes1,np2)) - { - plimes1.Append(p3p2); - //plimes1trigs.Append(t); - //plimes1origin.Append(np2); - } - //chart.AddILimit(twoint(np1,np2)); - - for (int di = 1; di <= divisions; di++) - { - double f1 = (double)di/(double)(divisions+1.); - double f2 = (divisions+1.-(double)di)/(double)(divisions+1.); - - plimes1.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2, - p3p1.Y()*f1+p3p2.Y()*f2, - p3p1.Z()*f1+p3p2.Z()*f2)); - //plimes1trigs.Append(t); - //plimes1origin.Append(0); - } - */ - } - } - } - } -} - - - -void STLGeometry :: GetDirtyChartTrigs(int chartnum, STLChart& chart, - const ARRAY<int>& outercharttrigs, - ARRAY<int>& chartpointchecked, - ARRAY<int>& dirtytrigs) -{ - dirtytrigs.SetSize(0); - int j,k,n; - - int np1, np2, nt; - int cnt = 0; - - for (j = 1; j <= chart.GetNChartT(); j++) - { - int t = chart.GetChartTrig(j); - const STLTriangle& tt = GetTriangle(t); - - for (k = 1; k <= 3; k++) - { - nt = NeighbourTrig(t,k); - if (GetChartNr(nt) != chartnum && outercharttrigs.Get(nt) != chartnum) - { - tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); - if (!IsEdge(np1,np2)) - { - dirtytrigs.Append(j); //local numbers!!! - cnt++; - break; //only once per trig!!! - } - } - } - } - cnt = 0; - - int addedges = 0; - int p1, p2, tn1, tn2, l, problem, pn; - ARRAY<int> trigsaroundp; - - for (j = chart.GetNChartT(); j >= 1; j--) - { - int t = chart.GetChartTrig(j); - const STLTriangle& tt = GetTriangle(t); - - for (k = 1; k <= 3; k++) - { - pn = tt.PNum(k); - //if (chartpointchecked.Get(pn) == chartnum) - //{continue;} - - int checkpoint = 0; - for (n = 1; n <= trigsperpoint.EntrySize(pn); n++) - { - if (trigsperpoint.Get(pn,n) != t && //ueberfluessig??? - GetChartNr(trigsperpoint.Get(pn,n)) != chartnum && - outercharttrigs.Get(trigsperpoint.Get(pn,n)) != chartnum) {checkpoint = 1;}; - } - if (checkpoint) - { - chartpointchecked.Elem(pn) = chartnum; - - int worked = 0; - GetSortedTrianglesAroundPoint(pn,t,trigsaroundp); - trigsaroundp.Append(t); //ring - - problem = 0; - //forward: - for (l = 2; l <= trigsaroundp.Size()-1; l++) - { - tn1 = trigsaroundp.Get(l-1); - tn2 = trigsaroundp.Get(l); - const STLTriangle& t1 = GetTriangle(tn1); - const STLTriangle& t2 = GetTriangle(tn2); - t1.GetNeighbourPoints(t2, p1, p2); - if (IsEdge(p1,p2)) break; - - if (GetChartNr(tn2) != chartnum && outercharttrigs.Get(tn2) != chartnum) {problem = 1;} - } - - //backwards: - for (l = trigsaroundp.Size()-1; l >= 2; l--) - { - tn1 = trigsaroundp.Get(l+1); - tn2 = trigsaroundp.Get(l); - const STLTriangle& t1 = GetTriangle(tn1); - const STLTriangle& t2 = GetTriangle(tn2); - t1.GetNeighbourPoints(t2, p1, p2); - if (IsEdge(p1,p2)) break; - - if (GetChartNr(tn2) != chartnum && outercharttrigs.Get(tn2) != chartnum) {problem = 1;} - } - if (problem && !IsInArray(j,dirtytrigs)) - { - dirtytrigs.Append(j); - cnt++; - break; //only once per triangle - } - } - } - } - -} - -} diff --git a/Netgen/libsrc/stlgeom/stlgeommesh.cpp b/Netgen/libsrc/stlgeom/stlgeommesh.cpp deleted file mode 100644 index 863019c04c..0000000000 --- a/Netgen/libsrc/stlgeom/stlgeommesh.cpp +++ /dev/null @@ -1,1592 +0,0 @@ -//20.11.1999 second part of stlgeom.cc, mainly mesh functions - -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - -#include "stlgeom.hpp" - -namespace netgen -{ -int EdgeUsed(int p1, int p2, ARRAY<INDEX_2>& edges, INDEX_2_HASHTABLE<int>& hashtab) -{ - if (p1 > p2) {swap (p1,p2);} - - if (hashtab.Used(INDEX_2(p1,p2))) - {return hashtab.Get(INDEX_2(p1,p2));} - - return 0; -} - -Point<3> STLGeometry :: PointBetween(const Point<3> & p1, int t1, - const Point<3> & p2, int t2) -{ - //funktioniert nicht in allen F�llen! - - PrintWarning("Point between"); - - - ClearMarkedSegs(); - - InitMarkedTrigs(); - SetMarkedTrig(t1,1); - SetMarkedTrig(t2,1); - - TABLE<Point3d> edgepoints; - TABLE<double> edgepointdists; - TABLE<int> edgepointorigines; - TABLE<int> edgepointoriginps; - - ARRAY<int> edgetrigs; - ARRAY<INDEX_2> edgepointnums; - ARRAY<int> edgetriglocinds; - - int size = 3*GetNT(); - INDEX_2_HASHTABLE<int> hashtab(size); - - int divisions = 10; - - edgepoints.SetSize(size); - edgepointdists.SetSize(size); - edgepointorigines.SetSize(size); - edgepointoriginps.SetSize(size); - - edgetrigs.SetSize(size); - edgepointnums.SetSize(size); - edgetriglocinds.SetSize(size); - - ARRAY<int> edgelist1; - ARRAY<int> edgelist2; - - edgelist1.SetSize(0); - edgelist2.SetSize(0); - - - int i, j, k, l, m; - int edgecnt = 0; - - //first triangle: - for (i = 1; i <= 3; i++) - { - int ptn1 = GetTriangle(t1).PNum(i); - int ptn2 = GetTriangle(t1).PNumMod(i+1); - - if (ptn1 > ptn2) {swap(ptn1,ptn2);} - - Point3d pt1 = GetPoint(ptn1); - Point3d pt2 = GetPoint(ptn2); - - edgecnt++; - edgetrigs.Elem(edgecnt) = t1; - edgepointnums.Elem(edgecnt) = INDEX_2(ptn1,ptn2); - hashtab.Set(edgepointnums.Get(edgecnt),edgecnt); - - edgetriglocinds.Elem(edgecnt) = i; - edgelist1.Append(edgecnt); - - for (j = 1; j <= divisions; j++) - { - double lfact = (double)j/(double)divisions; - Point3d pbtw(lfact*pt1.X()+(1.-lfact)*pt2.X(), - lfact*pt1.Y()+(1.-lfact)*pt2.Y(), - lfact*pt1.Z()+(1.-lfact)*pt2.Z()); - - //AddMarkedSeg(p1,pbtw); - - edgepoints.Add1(edgecnt,pbtw); - edgepointdists.Add1(edgecnt,Dist(pbtw,p1)); - edgepointorigines.Add1(edgecnt,0); - edgepointoriginps.Add1(edgecnt,0); - } - } - - int finished = 0; - int endpointorigine = 0; - int endpointoriginp = 0; - double endpointmindist = 1E50; - - int cnt = 0; - int maxsize = 0; - while (!finished) - { - finished = 1; - - if (edgelist1.Size() > maxsize) {maxsize = edgelist1.Size();} - - for (i = 1; i <= edgelist1.Size(); i++) - { - int en = edgelist1.Get(i); - int trig = edgetrigs.Get(en); - int edgenum = edgetriglocinds.Get(en); - int tn = NeighbourTrigSorted(trig,edgenum); - - if (tn != t2) - { - for (k = 1; k <= 3; k++) - { - int pnt1 = GetTriangle(tn).PNum(k); - int pnt2 = GetTriangle(tn).PNumMod(k+1); - - if (pnt1 > pnt2) {swap(pnt1,pnt2);} - - Point3d pt1 = GetPoint(pnt1); - Point3d pt2 = GetPoint(pnt2); - - //AddMarkedSeg(pt1,pt2); - - //if (!(pnt1 == ep1 && pnt2 == ep2)) - // { - int edgeused = 0; - int edgenum = EdgeUsed(pnt1, pnt2, edgepointnums, hashtab); - if (edgenum != en) - { - if (edgenum != 0) - {edgeused = 1;} - else - { - edgecnt++; - edgenum = edgecnt; - - edgetrigs.Elem(edgenum) = tn; - edgepointnums.Elem(edgenum) = INDEX_2(pnt1,pnt2); - hashtab.Set(edgepointnums.Get(edgenum),edgenum); - edgetriglocinds.Elem(edgenum) = k; - } - - if (edgenum > size || edgenum == 0) {PrintSysError("edgenum = ", edgenum);} - - double minofmindist = 1E50; - int changed = 0; - - for (l = 1; l <= divisions; l++) - { - double lfact = (double)l/(double)divisions; - Point3d pbtw(lfact*pt1.X()+(1.-lfact)*pt2.X(), - lfact*pt1.Y()+(1.-lfact)*pt2.Y(), - lfact*pt1.Z()+(1.-lfact)*pt2.Z()); - - double mindist = 1E50; - int index=0; - - for (m = 1; m <= divisions; m++) - { - const Point3d& p = edgepoints.Get(en,m); - if (Dist(pbtw,p) + edgepointdists.Get(en,m) < mindist) - {mindist = Dist(pbtw,p) + edgepointdists.Get(en,m); index = m;} - } - - //if (mindist < endpointmindist) {finished = 0;} - if (mindist < minofmindist) {minofmindist = mindist;} - - - if (!edgeused) - { - //AddMarkedSeg(pbtw,edgepoints.Get(en,index)); - - edgepoints.Add1(edgenum,pbtw); - edgepointdists.Add1(edgenum,mindist); - edgepointorigines.Add1(edgenum,en); - edgepointoriginps.Add1(edgenum,index); - changed = 1; - } - else - { - if (mindist < edgepointdists.Get(edgenum,l)) - { - edgepointdists.Set(edgenum,l,mindist); - edgepointorigines.Set(edgenum,l,en); - edgepointoriginps.Set(edgenum,l,index); - changed = 1; - } - } - } - if (minofmindist < endpointmindist-1E-10 && changed) - { - finished = 0; - edgelist2.Append(edgenum); - } - } - } - } - else - { - double mindist = 1E50; - int index; - for (m = 1; m <= divisions; m++) - { - const Point3d& p = edgepoints.Get(en,m); - if (Dist(p2,p) + edgepointdists.Get(en,m) < mindist) - {mindist = Dist(p2,p) + edgepointdists.Get(en,m); index = m;} - } - if (mindist < endpointmindist) - { - endpointorigine = en; - endpointoriginp = index; - endpointmindist = mindist; - } - } - } - edgelist1.SetSize(0); - for (i = 1; i <= edgelist2.Size(); i++) - { - edgelist1.Append(edgelist2.Get(i)); - } - } - - if (!endpointorigine) {PrintSysError("No connection found!");} - - ARRAY<Point3d> plist; - - plist.Append(p2); - int laste = endpointorigine; - int lastp = endpointoriginp; - int lle, llp; - - - while (laste) - { - plist.Append(edgepoints.Get(laste,lastp)); - - lle = laste; - llp = lastp; - laste = edgepointorigines.Get(lle,llp); - lastp = edgepointoriginps.Get(lle,llp); - } - - plist.Append(p1); - - for (i = 1; i <= plist.Size()-1; i++) - { - AddMarkedSeg(plist.Get(i),plist.Get(i+1)); - } - - PrintMessage(5,"PointBetween: complexity=", maxsize); - - - Point3d pm; - double dist = 0; - int found = 0; - - for (i = 1; i <= plist.Size()-1; i++) - { - dist += Dist(plist.Get(i),plist.Get(i+1)); - if (dist > endpointmindist*0.5) - { - double segl = Dist(plist.Get(i), plist.Get(i+1)); - double d = dist - endpointmindist * 0.5; - pm = Point3d(d/segl*plist.Get(i).X() + (1.-d/segl)*plist.Get(i+1).X(), - d/segl*plist.Get(i).Y() + (1.-d/segl)*plist.Get(i+1).Y(), - d/segl*plist.Get(i).Z() + (1.-d/segl)*plist.Get(i+1).Z()); - found = 1; - break; - } - } - if (!found) {PrintWarning("Problem in PointBetween"); pm = Center(p1,p2);} - - AddMarkedSeg(pm, Point3d(0.,0.,0.)); - - return pm; - -} - - -void STLGeometry :: PrepareSurfaceMeshing() -{ - meshchart = -1; //clear no old chart - meshcharttrigs.SetSize(GetNT()); - int i; - for (i = 1; i <= GetNT(); i++) - {meshcharttrigs.Elem(i) = 0;} -} - -void STLGeometry::GetMeshChartBoundary (ARRAY<Point2d > & points, - ARRAY<Point3d > & points3d, - ARRAY<INDEX_2> & lines, double h) -{ - int i, j; - twoint seg, newseg; - int zone; - int psize; - Point<2> p2; - - const STLChart& chart = GetChart(meshchart); - - - for (i = 1; i <= chart.GetNOLimit(); i++) - { - seg = chart.GetOLimit(i); - INDEX_2 i2; - for (j = 1; j <= 2; j++) - { - int pi = (j == 1) ? seg.i1 : seg.i2; - int lpi; - if (ha_points.Get(pi) == 0) - { - const Point<3> & p3d = GetPoint (pi); - Point<2> p2d; - - points3d.Append (p3d); - ToPlane(p3d, 0, p2d, h, zone, 0); - points.Append (p2d); - - lpi = points.Size(); - ha_points.Elem(pi) = lpi; - } - else - lpi = ha_points.Get(pi); - - i2.I(j) = lpi; - } - lines.Append (i2); - - /* - seg = chart.GetOLimit(i); - psize = points.Size(); - - newseg.i1 = psize+1; - newseg.i2 = psize+2; - - ToPlane(GetPoint(seg.i1), 0, p2, h, zone, 0); - points.Append(p2); - points3d.Append (GetPoint(seg.i1)); - ToPlane(GetPoint(seg.i2), 0, p2, h, zone, 0); - points.Append(p2); - points3d.Append (GetPoint(seg.i2)); - lines.Append (INDEX_2 (points.Size()-1, points.Size())); - */ - } - - for (i = 1; i <= chart.GetNOLimit(); i++) - { - seg = chart.GetOLimit(i); - ha_points.Elem(seg.i1) = 0; - ha_points.Elem(seg.i2) = 0; - } -} - -void STLGeometry :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2, int trig) -{ - p1 = ap1; //save for ToPlane, in data of STLGeometry class - Point<3> p2 = ap2; //only locally used - - meshchart = GetChartNr(trig); - - if (usechartnormal) - meshtrignv = GetChart(meshchart).GetNormal(); - else - meshtrignv = GetTriangle(trig).Normal(); - - //meshtrignv = GetTriangle(trig).Normal(points); - - meshtrignv /= meshtrignv.Length(); - - GetTriangle(trig).ProjectInPlain(points, meshtrignv, p2); - - - ez = meshtrignv; - ez /= ez.Length(); - ex = p2 - p1; - ex -= (ex * ez) * ez; - ex /= ex.Length(); - ey = Cross (ez, ex); - -} - - -void STLGeometry :: SelectChartOfTriangle (int trignum) -{ - meshchart = GetChartNr(trignum); - meshtrignv = GetTriangle(trignum).Normal(); -} - - -void STLGeometry :: SelectChartOfPoint (const Point<3> & p) -{ - int i, ii, j, k; - - ARRAY<int> trigsinbox; - - Box<3> box(p,p); - box.Increase (1e-6); - GetTrianglesInBox (box, trigsinbox); - - - // for (i = 1; i <= GetNT(); i++) - for (ii = 1; ii <= trigsinbox.Size(); ii++) - { - i = trigsinbox.Get(ii); - Point<3> hp = p; - if (GetTriangle(i).GetNearestPoint(points, hp) <= 1E-8) - { - SelectChartOfTriangle (i); - break; - } - } - return; -} - - - -void STLGeometry :: ToPlane (const Point<3> & locpoint, int * trigs, - Point<2> & plainpoint, double h, int& zone, - int checkchart) -{ - if (checkchart) - { - - //check if locpoint lies on actual chart: - zone = 0; - - - // Point3d p; - int i = 1; - const STLChart& chart = GetChart(meshchart); - int foundinchart = 0; - const double range = 1e-6; //1e-4 old - - - - - if (trigs) - { - int * htrigs = trigs; - int ci = 1; - while (*htrigs) - { - if (TrigIsInOC (*htrigs, meshchart)) - { - foundinchart = 1; - break; - } - htrigs++; - } - } - - else - { - ARRAY<int> trigsinbox; - - if (!geomsearchtreeon) - { - //alter chart-tree - Box<3> box(locpoint, locpoint); - box.Increase (range); - chart.GetTrianglesInBox (box.PMin(), box.PMax(), trigsinbox); - } - else - { - ARRAY<int> trigsinbox2; - Box<3> box(locpoint, locpoint); - box.Increase (range); - GetTrianglesInBox (box, trigsinbox2); - for (i = 1; i <= trigsinbox2.Size(); i++) - { - if (TrigIsInOC(trigsinbox2.Get(i),meshchart)) {trigsinbox.Append(trigsinbox2.Get(i));} - } - - } - - - for (i = 1; i <= trigsinbox.Size(); i++) - { - Point<3> p = locpoint; - if (GetTriangle(trigsinbox.Get(i)).GetNearestPoint(points, p) - <= 1E-8) - { - foundinchart = 1; - break; - } - - } - } - - //do not use this point (but do correct projection (joachim) - if (!foundinchart) - { - zone = -1; // plainpoint.X() = 11111; plainpoint.Y() = 11111; return; - } - } - - else - { - zone = 0; - } - - //transform in plane - Vec<3> p1p = locpoint - p1; - plainpoint(0) = (p1p * ex) / h; - plainpoint(1) = (p1p * ey) / h; - -} - -int STLGeometry :: FromPlane (const Point<2> & plainpoint, - Point<3> & locpoint, double h) -{ - Point2d plainpoint2 (plainpoint); - - plainpoint2.X() *= h; - plainpoint2.Y() *= h; - Vec3d p1p = plainpoint2.X() * ex + plainpoint2.Y() * ey; - locpoint = p1 + p1p; - - - int rv = Project(locpoint); - if (!rv) {return 1;} //project nicht gegangen - return 0; -} - -int lasttrig; -int STLGeometry :: LastTrig() const {return lasttrig;} - -//project normal to tangential plane -int STLGeometry :: Project(Point<3> & p3d) const -{ - Point<3> p, pf; - - int i, j, k; - int fi = 0; - int cnt = 0; - int different = 0; - const double lamtol = 1e-6; - - const STLChart& chart = GetChart(meshchart); - - int nt = chart.GetNT(); - - QuadraticFunction3d quadfun(p3d, meshtrignv); - - /* - Vec3d hv = meshtrignv; - hv /= hv.Length(); - Vec3d t1, t2; - hv.GetNormal (t1); - Cross (hv, t1, t2); - */ - - for (j = 1; j <= nt; j++) - { - i = chart.GetTrig(j); - - const Point<3> & c = GetTriangle(i).center; - /* - double d1 = t1 * (c-p3d); - double d2 = t2 * (c-p3d); - */ - /* - if (d1 * d1 + d2 * d2 > sqr (GetTriangle(i).rad)) - continue; - */ - if (quadfun.Eval(c) > sqr (GetTriangle(i).rad)) - continue; - - p = p3d; - Vec<3> lam; - int err = GetTriangle(i).ProjectInPlain(points, meshtrignv, p, lam); - int inside = (err == 0 && lam(0) > -lamtol && - lam(1) > -lamtol && (1-lam(0)-lam(1)) > -lamtol); - - - /* - p = p3d; - GetTriangle(i).ProjectInPlain(points, meshtrignv, p); - if (GetTriangle(i).PointInside(points, p)) - */ - if (inside) - { - if (cnt != 0) - { - if (Dist2(p,pf)>=1E-16) - { - // (*testout) << "ERROR: found two points to project which are different" << endl; - //(*testout) << "p=" << p << ", pf=" << pf << endl; - different = 1; - } - } - pf = p; fi = i; cnt++; - } - - if (inside) - break; - - } - - // if (cnt == 2) {(*testout) << "WARNING: found 2 triangles to project" << endl;} - //if (cnt == 3) {(*testout) << "WARNING: found 3 triangles to project" << endl;} - //if (cnt > 3) {(*testout) << "WARNING: found more than 3 triangles to project" << endl;} - - if (fi != 0) {lasttrig = fi;} - if (fi != 0 && !different) {p3d = pf; return fi;} - - // (*testout) << "WARNING: Project failed" << endl; - return 0; - -} - -//project normal to tangential plane -int STLGeometry :: ProjectOnWholeSurface(Point<3> & p3d) const -{ - Point<3> p, pf; - - int i, k; - int fi = 0; - int cnt = 0; - int different = 0; - const double lamtol = 1e-6; - - for (i = 1; i <= GetNT(); i++) - { - p = p3d; - Vec<3> lam; - int err = - GetTriangle(i).ProjectInPlain(points, meshtrignv, p, lam); - int inside = (err == 0 && lam(0) > -lamtol && - lam(1) > -lamtol && (1-lam(0)-lam(1)) > -lamtol); - - /* - p = p3d; - GetTriangle(i).ProjectInPlain(points, meshtrignv, p); - if (GetTriangle(i).PointInside(points, p)) - */ - if (inside) - { - if (cnt != 0) - { - if (Dist2(p,pf)>=1E-16) - { - // (*testout) << "ERROR: found two points to project which are different" << endl; - // (*testout) << "p=" << p << ", pf=" << pf << endl; - different = 1; - } - } - pf = p; fi = i; cnt++; - } - } - /* - if (cnt == 2) {(*testout) << "WARNING: found 2 triangles to project" << endl;} - if (cnt == 3) {(*testout) << "WARNING: found 3 triangles to project" << endl;} - if (cnt > 3) {(*testout) << "WARNING: found more than 3 triangles to project" << endl;} - */ - if (fi != 0) {lasttrig = fi;} - if (fi != 0 && !different) {p3d = pf; return fi;} - - // (*testout) << "WARNING: Project failed" << endl; - return 0; - -} - - -int STLGeometry :: ProjectNearest(Point<3> & p3d) const -{ - Point<3> p, pf; - - //set new chart - const STLChart& chart = GetChart(meshchart); - int i; - double nearest = 1E50; - double dist; - int ft = 0; - - for (i = 1; i <= chart.GetNT(); i++) - { - p = p3d; - dist = GetTriangle(chart.GetTrig(i)).GetNearestPoint(points, p); - if (dist < nearest) - { - pf = p; - nearest = dist; - ft = chart.GetTrig(i); - } - } - p3d = pf; - //if (!ft) {(*testout) << "ERROR: ProjectNearest failed" << endl;} - - return ft; -} - - - - -//Restrict local h due to curvature for make atlas -void STLGeometry :: RestrictLocalHCurv(class Mesh & mesh, double gh) -{ - PushStatusF("Restrict H due to surface curvature"); - - //bei jedem Dreieck alle Nachbardreiecke vergleichen, und, fallskein Kante dazwischen, - //die Meshsize auf ein bestimmtes Mass limitieren - int i,j; - - int p1,p2,p3,p4; - Point<3> p1p, p2p, p3p, p4p; - double mindist, ang; - Vec<3> n, ntn; - double rzyl, sinang, localh; - - // double localhfact = 0.5; - double geometryignorelength = 1E-4; - double minlocalh = stlparam.atlasminh; - - Box<3> bb = GetBoundingBox(); - // mesh.SetLocalH(bb.PMin() - Vec3d(10, 10, 10),bb.PMax() + Vec3d(10, 10, 10), - // mparam.grading); - - // mesh.SetGlobalH(gh); - - double mincalch = 1E10; - double maxcalch = -1E10; - - double objectsize = bb.Diam(); - double geometryignoreedgelength = objectsize * 1e-5; - - if (stlparam.resthatlasenable) - { - ARRAY<double> minh; //minimales h pro punkt - minh.SetSize(GetNP()); - for (i = 1; i <= GetNP(); i++) - { - minh.Elem(i) = gh; - } - - for (i = 1; i <= GetNT(); i++) - { - SetThreadPercent((double)i/(double)GetNT()*100.); - - if (multithread.terminate) - {PopStatus(); return;} - - const STLTriangle& trig = GetTriangle(i); - n = GetTriangle(i).Normal(); - for (j = 1; j <= 3; j++) - { - const STLTriangle& nt = GetTriangle(NeighbourTrig(i,j)); - - trig.GetNeighbourPointsAndOpposite(nt,p1,p2,p3); - - //checken, ob p1-p2 eine Kante sind - if (IsEdge(p1,p2)) continue; - - p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - p1 - p2; - - p1p = GetPoint(p1); p2p = GetPoint(p2); - p3p = GetPoint(p3); p4p = GetPoint(p4); - - double h1 = GetDistFromInfiniteLine(p1p,p2p, p4p); - double h2 = GetDistFromInfiniteLine(p1p,p2p, p3p); - double diaglen = Dist (p1p, p2p); - - if (diaglen < geometryignoreedgelength) - continue; - rzyl = ComputeCylinderRadius - (n, GetTriangle(NeighbourTrig(i,j)).Normal(), - h1, h2); - - - if (h1 < 1e-3 * diaglen && h2 < 1e-3 * diaglen) - continue; - if (h1 < 1e-5 * objectsize && h2 < 1e-5 * objectsize) - continue; - - - // rzyl = mindist/(2*sinang); - localh = 10.*rzyl / stlparam.resthatlasfac; - if (localh < mincalch) {mincalch = localh;} - if (localh > maxcalch) {maxcalch = localh;} - - if (localh < minlocalh) {localh = minlocalh;} - if (localh < gh) - { - minh.Elem(p1) = min2(minh.Elem(p1),localh); - minh.Elem(p2) = min2(minh.Elem(p2),localh); - } - - //if (localh < 0.2) {localh = 0.2;} - mesh.RestrictLocalHLine(p1p, p2p, localh); - } - - } - } - PrintMessage(7, "done\nATLAS H: nmin local h=", mincalch); - PrintMessage(7, "ATLAS H: max local h=", maxcalch); - PrintMessage(7, "Local h tree has ", mesh.LocalHFunction().GetNBoxes(), " boxes of size ", - (int)sizeof(GradingBox)); - - PopStatus(); - -} - //restrict local h due to near edges and due to outer chart distance -void STLGeometry :: RestrictLocalH(class Mesh & mesh, double gh) -{ - - //bei jedem Dreieck alle Nachbardreiecke vergleichen, und, fallskein Kante dazwischen, - //die Meshsize auf ein bestimmtes Mass limitieren - int i,j; - - int p1,p2,p3,p4; - Point3d p1p, p2p, p3p, p4p; - double mindist, ang; - Vec3d n, ntn; - double rzyl, sinang, localh; - - // double localhfact = 0.5; - double geometryignorelength = 1E-4; - - Box<3> bb = GetBoundingBox(); - //mesh.SetLocalH(bb.PMin() - Vec3d(10, 10, 10),bb.PMax() + Vec3d(10, 10, 10), - // mparam.grading); - - //mesh.SetGlobalH(gh); - - double mincalch = 1E10; - double maxcalch = -1E10; - - double objectsize = bb.Diam(); - double geometryignoreedgelength = objectsize * 1e-5; - - if (stlparam.resthsurfcurvenable) - { - PushStatusF("Restrict H due to surface curvature"); - - ARRAY<double> minh; //minimales h pro punkt - minh.SetSize(GetNP()); - for (i = 1; i <= GetNP(); i++) - { - minh.Elem(i) = gh; - } - - for (i = 1; i <= GetNT(); i++) - { - SetThreadPercent((double)i/(double)GetNT()*100.); - if (i%20000==19999) {PrintMessage(7, (double)i/(double)GetNT()*100. , "%");} - - if (multithread.terminate) - {PopStatus(); return;} - - const STLTriangle& trig = GetTriangle(i); - n = GetTriangle(i).Normal(); - for (j = 1; j <= 3; j++) - { - const STLTriangle& nt = GetTriangle(NeighbourTrig(i,j)); - - trig.GetNeighbourPointsAndOpposite(nt,p1,p2,p3); - - //checken, ob p1-p2 eine Kante sind - if (IsEdge(p1,p2)) continue; - - p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - p1 - p2; - - p1p = GetPoint(p1); p2p = GetPoint(p2); - p3p = GetPoint(p3); p4p = GetPoint(p4); - - double h1 = GetDistFromInfiniteLine(p1p,p2p, p4p); - double h2 = GetDistFromInfiniteLine(p1p,p2p, p3p); - double diaglen = Dist (p1p, p2p); - - if (diaglen < geometryignoreedgelength) - continue; - rzyl = ComputeCylinderRadius - (n, GetTriangle (NeighbourTrig(i,j)).Normal(), - h1, h2); - - - if (h1 < 1e-3 * diaglen && h2 < 1e-3 * diaglen) - continue; - if (h1 < 1e-5 * objectsize && h2 < 1e-5 * objectsize) - continue; - - - // rzyl = mindist/(2*sinang); - localh = rzyl / stlparam.resthsurfcurvfac; - if (localh < mincalch) {mincalch = localh;} - if (localh > maxcalch) {maxcalch = localh;} - if (localh < gh) - { - minh.Elem(p1) = min2(minh.Elem(p1),localh); - minh.Elem(p2) = min2(minh.Elem(p2),localh); - } - - //if (localh < 0.2) {localh = 0.2;} - mesh.RestrictLocalHLine(p1p, p2p, localh); - - if (localh < 0.1) - { - localh = 0.1; - } - - } - } - PrintMessage(7, "done\nmin local h=", mincalch, "\nmax local h=", maxcalch); - PopStatus(); - } - - if (stlparam.resthcloseedgeenable) - { - PushStatusF("Restrict H due to close edges"); - //geht nicht f�r spiralen!!!!!!!!!!!!!!!!!! - - double disttohfact = sqr(10.0 / stlparam.resthcloseedgefac); - int k,l; - double h1, h2, dist; - int rc = 0; - Point3d p3p1, p3p2; - double mindist = 1E50; - - PrintMessage(7,"build search tree..."); - Box3dTree* searchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1), - GetBoundingBox().PMax() + Vec3d(1,1,1)); - - ARRAY<Point3d> pmins(GetNLines()); - ARRAY<Point3d> pmaxs(GetNLines()); - - double maxhline; - for (i = 1; i <= GetNLines(); i++) - { - maxhline = 0; - STLLine* l1 = GetLine(i); - Point3d pmin(GetPoint(l1->StartP())), pmax(GetPoint(l1->StartP())), px; - - for (j = 2; j <= l1->NP(); j++) - { - px = GetPoint(l1->PNum(j)); - maxhline = max2(maxhline,mesh.GetH(px)); - pmin.SetToMin (px); - pmax.SetToMax (px); - } - Box3d box(pmin,pmax); - box.Increase(maxhline); - - searchtree->Insert (box.PMin(), box.PMax(), i); - pmins.Elem(i) = box.PMin(); - pmaxs.Elem(i) = box.PMax(); - } - - ARRAY<int> linenums; - int k2; - - for (i = 1; i <= GetNLines(); i++) - { - SetThreadPercent((double)i/(double)GetNLines()*100.); - if (multithread.terminate) - {PopStatus(); return;} - - linenums.SetSize(0); - searchtree->GetIntersecting(pmins.Get(i),pmaxs.Get(i),linenums); - - STLLine* l1 = GetLine(i); - for (j = 1; j <= l1->NP(); j++) - { - p3p1 = GetPoint(l1->PNum(j)); - h1 = sqr(mesh.GetH(p3p1)); - - for (k2 = 1; k2 <= linenums.Size(); k2++) - { - k = linenums.Get(k2); - if (k <= i) {continue;} - /* - //old, without searchtrees - for (k = i+1; k <= GetNLines(); k++) - { - */ - STLLine* l2 = GetLine(k); - for (l = 1; l <= l2->NP(); l++) - { - const Point3d& p3p2 = GetPoint(l2->PNum(l)); - h2 = sqr(mesh.GetH(p3p2)); - dist = Dist2(p3p1,p3p2)*disttohfact; - if (dist > 1E-12) - { - if (dist < h1) - { - mesh.RestrictLocalH(p3p1,sqrt(dist)); - rc++; - mindist = min2(mindist,sqrt(dist)); - } - if (dist < h2) - { - mesh.RestrictLocalH(p3p2,sqrt(dist)); - rc++; - mindist = min2(mindist,sqrt(dist)); - } - } - } - } - } - } - PrintMessage(5, "done\n Restricted h in ", rc, " points due to near edges!"); - PopStatus(); - } - - if (stlparam.resthedgeangleenable) - { - PushStatusF("Restrict h due to close edges"); - - int ecnt = 0; - int lp1, lp2; - int i; - Vec3d v1,v2; - double rzyl; - double mincalch = 1E50; - double maxcalch = -1E50; - - for (i = 1; i <= GetNP(); i++) - { - SetThreadPercent((double)i/(double)GetNP()*100.); - if (multithread.terminate) - {PopStatus(); return;} - - if (GetNEPP(i) == 2 && !IsLineEndPoint(i)) - { - if (GetEdge(GetEdgePP(i,1)).PNum(2) == GetEdge(GetEdgePP(i,2)).PNum(1) || - GetEdge(GetEdgePP(i,1)).PNum(1) == GetEdge(GetEdgePP(i,2)).PNum(2)) - { - lp1 = 1; lp2 = 2; - } - else - { - lp1 = 2; lp2 = 1; - } - - v1 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,1)).PNum(1)), - GetPoint(GetEdge(GetEdgePP(i,1)).PNum(2))); - v2 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp1)), - GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp2))); - - rzyl = ComputeCylinderRadius(v1, v2, v1.Length(), v2.Length()); - - localh = rzyl / stlparam.resthedgeanglefac; - if (localh < mincalch) {mincalch = localh;} - if (localh > maxcalch) {maxcalch = localh;} - - if (localh != 0) - mesh.RestrictLocalH(GetPoint(i), localh); - } - } - PrintMessage(7,"edge-angle min local h=", mincalch, "\nedge-angle max local h=", maxcalch); - PopStatus(); - } - - if (stlparam.resthchartdistenable) - { - PushStatusF("Restrict H due to outer chart distance"); - - // mesh.LocalHFunction().Delete(); - - //berechne minimale distanz von chart zu einem nicht-outerchart-punkt in jedem randpunkt einer chart - - ARRAY<int> acttrigs; //outercharttrigs - acttrigs.SetSize(GetNT()); - for (i = 1; i <= GetNT(); i++) - { - acttrigs.Elem(i) = 0; - } - for (i = 1; i <= GetNOCharts(); i++) - { - SetThreadPercent((double)i/(double)GetNOCharts()*100.); - if (multithread.terminate) - {PopStatus(); return;} - - RestrictHChartDistOneChart(i, acttrigs, mesh, gh, 1., 0.); - } - - PopStatus(); - } - - if (stlparam.resthlinelengthenable) - { - //restrict h due to short lines - PushStatusF("Restrict H due to line-length"); - - double minhl = 1E50; - double linefact = 1./stlparam.resthlinelengthfac; - double l; - for (i = 1; i <= GetNLines(); i++) - { - SetThreadPercent((double)i/(double)GetNLines()*100.); - if (multithread.terminate) - {PopStatus(); return;} - - l = GetLine(i)->GetLength(points); - - const Point3d& p1 = GetPoint(GetLine(i)->StartP()); - const Point3d& p2 = GetPoint(GetLine(i)->EndP()); - - if (l != 0) - { - minhl = min2(minhl,l*linefact); - - mesh.RestrictLocalH(p1, l*linefact); - mesh.RestrictLocalH(p2, l*linefact); - } - } - PopStatus(); - PrintMessage(5, "minh due to line length=", minhl); - } -} - -void STLGeometry :: RestrictHChartDistOneChart(int chartnum, ARRAY<int>& acttrigs, - class Mesh & mesh, double gh, double fact, double minh) -{ - int i = chartnum; - int j; - - double limessafety = stlparam.resthchartdistfac*fact; // original: 2 - double localh; - - double f1,f2; - // mincalch = 1E10; - //maxcalch = -1E10; - ARRAY<int> limes1; - ARRAY<int> limes2; - - ARRAY<Point3d> plimes1; - ARRAY<Point3d> plimes2; - - ARRAY<int> plimes1trigs; //check from wich trig the points come - ARRAY<int> plimes2trigs; - - ARRAY<int> plimes1origin; //either the original pointnumber or zero, if new point - - int divisions = 10; - - int k, t, nt, np1, np2; - Point3d p3p1, p3p2; - STLTriangle tt; - - limes1.SetSize(0); - limes2.SetSize(0); - plimes1.SetSize(0); - plimes2.SetSize(0); - plimes1trigs.SetSize(0); - plimes2trigs.SetSize(0); - plimes1origin.SetSize(0); - - STLChart& chart = GetChart(i); - chart.ClearOLimit(); - chart.ClearILimit(); - - for (j = 1; j <= chart.GetNChartT(); j++) - { - t = chart.GetChartTrig(j); - tt = GetTriangle(t); - for (k = 1; k <= 3; k++) - { - nt = NeighbourTrig(t,k); - if (GetChartNr(nt) != i) - { - tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); - if (!IsEdge(np1,np2) && !GetSpiralPoint(np1) && !GetSpiralPoint(np2)) - { - p3p1 = GetPoint(np1); - p3p2 = GetPoint(np2); - if (AddIfNotExists(limes1,np1)) - { - plimes1.Append(p3p1); - plimes1trigs.Append(t); - plimes1origin.Append(np1); - } - if (AddIfNotExists(limes1,np2)) - { - plimes1.Append(p3p2); - plimes1trigs.Append(t); - plimes1origin.Append(np2); - } - chart.AddILimit(twoint(np1,np2)); - - for (int di = 1; di <= divisions; di++) - { - f1 = (double)di/(double)(divisions+1.); - f2 = (divisions+1.-(double)di)/(double)(divisions+1.); - - plimes1.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2, - p3p1.Y()*f1+p3p2.Y()*f2, - p3p1.Z()*f1+p3p2.Z()*f2)); - plimes1trigs.Append(t); - plimes1origin.Append(0); - } - } - } - } - } - - - for (j = 1; j <= chart.GetNT(); j++) - { - acttrigs.Elem(chart.GetTrig(j)) = i; - } - - for (j = 1; j <= chart.GetNOuterT(); j++) - { - t = chart.GetOuterTrig(j); - tt = GetTriangle(t); - for (k = 1; k <= 3; k++) - { - nt = NeighbourTrig(t,k); - - if (acttrigs.Get(nt) != i) - { - tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); - - if (!IsEdge(np1,np2)) - { - p3p1 = GetPoint(np1); - p3p2 = GetPoint(np2); - - if (AddIfNotExists(limes2,np1)) {plimes2.Append(p3p1); plimes2trigs.Append(t);} - if (AddIfNotExists(limes2,np2)) {plimes2.Append(p3p2); plimes2trigs.Append(t);} - chart.AddOLimit(twoint(np1,np2)); - - for (int di = 1; di <= divisions; di++) - { - f1 = (double)di/(double)(divisions+1.); - f2 = (divisions+1.-(double)di)/(double)(divisions+1.); - - plimes2.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2, - p3p1.Y()*f1+p3p2.Y()*f2, - p3p1.Z()*f1+p3p2.Z()*f2)); - plimes2trigs.Append(t); - } - } - } - } - } - - - double chartmindist = 1E50; - - if (plimes2.Size()) - { - Box3d bbox; - bbox.SetPoint (plimes2.Get(1)); - for (j = 2; j <= plimes2.Size(); j++) - bbox.AddPoint (plimes2.Get(j)); - Point3dTree stree(bbox.PMin(), bbox.PMax()); - for (j = 1; j <= plimes2.Size(); j++) - stree.Insert (plimes2.Get(j), j); - ARRAY<int> foundpts; - - for (j = 1; j <= plimes1.Size(); j++) - { - double mindist = 1E50; - double dist; - - const Point3d & p1 = plimes1.Get(j); - double boxs = mesh.GetH (plimes1.Get(j)) * limessafety; - - Point3d pmin = p1 - Vec3d (boxs, boxs, boxs); - Point3d pmax = p1 + Vec3d (boxs, boxs, boxs); - - stree.GetIntersecting (pmin, pmax, foundpts); - - - for (int kk = 1; kk <= foundpts.Size(); kk++) - { - k = foundpts.Get(kk); - dist = Dist2(plimes1.Get(j),plimes2.Get(k)); - if (dist < mindist) - { - mindist = dist; - } - } - - /* - const Point3d & p1 = plimes1.Get(j); - double his = mesh.GetH (plimes1.Get(j)); - - double xmin = p1.X() - his * limessafety; - double xmax = p1.X() + his * limessafety; - double ymin = p1.Y() - his * limessafety; - double ymax = p1.Y() + his * limessafety; - double zmin = p1.Z() - his * limessafety; - double zmax = p1.Z() + his * limessafety; - - for (k = 1; k <= plimes2.Size(); k++) - { - const Point3d & p2 = plimes2.Get(k); - if (p2.X() >= xmin && p2.X() <= xmax && - p2.Y() >= ymin && p2.Y() <= ymax && - p2.Z() >= zmin && p2.Z() <= zmax) - { - dist = Dist2(plimes1.Get(j),plimes2.Get(k)); - if (dist < mindist) - { - mindist = dist; - } - } - } - */ - mindist = sqrt(mindist); - localh = mindist/limessafety; - - if (localh < minh && localh != 0) {localh = minh;} //minh is generally 0! (except make atlas) - if (localh < gh && localh > 0) - { - mesh.RestrictLocalH(plimes1.Get(j), localh); - // if (mindist < mincalch) {mincalch = mindist;} - // if (mindist > maxcalch) {maxcalch = mindist;} - if (mindist < chartmindist) {chartmindist = mindist;} - } - } - } - -} - - -//void * STLMeshingDummy (void *) -int STLMeshingDummy (STLGeometry* stlgeometry, Mesh*& mesh, - int perfstepsstart, int perfstepsend, char* optstring) -{ - if (perfstepsstart > perfstepsend) return 0; - - multithread.terminate = 0; - int success = 1; - //int trialcntouter = 0; - - if (perfstepsstart <= MESHCONST_MESHEDGES) - { - - mesh = new Mesh(); - mesh -> SetGlobalH (mparam.maxh); - mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), - stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), - mparam.grading); - mesh -> LoadLocalMeshSize (mparam.meshsizefilename); - - success = 0; - - //mesh->DeleteMesh(); - - STLMeshing (*stlgeometry, *mesh); - - stlgeometry->edgesfound = 1; - stlgeometry->surfacemeshed = 0; - stlgeometry->surfaceoptimized = 0; - stlgeometry->volumemeshed = 0; - } - - if (multithread.terminate) - return 0; - - if (perfstepsstart <= MESHCONST_MESHSURFACE && - perfstepsend >= MESHCONST_MESHSURFACE) - { - - if (!stlgeometry->edgesfound) - { - PrintUserError("You have to do 'analyse geometry' first!!!"); - return 0; - } - if (stlgeometry->surfacemeshed || stlgeometry->surfacemeshed) - { - PrintUserError("Already meshed. Please start again with 'Analyse Geometry'!!!"); - return 0; - } - - success = 0; - int retval = STLSurfaceMeshing (*stlgeometry, *mesh); - if (retval == MESHING3_OK) - { - PrintMessage(3,"Success !!!!"); - stlgeometry->surfacemeshed = 1; - stlgeometry->surfaceoptimized = 0; - stlgeometry->volumemeshed = 0; - success = 1; - } - else if (retval == MESHING3_OUTERSTEPSEXCEEDED) - { - PrintError("Give up because of too many trials. Meshing aborted!"); - } - else if (retval == MESHING3_TERMINATE) - { - PrintWarning("Meshing Stopped by user!"); - } - else - { - PrintError("Surface meshing not successful. Meshing aborted!"); - } - -#ifdef STAT_STREAM - (*statout) << mesh->GetNSeg() << " & " << endl - << mesh->GetNSE() << " & " << endl - << GetTime() << " & "; -#endif - } - if (multithread.terminate) - return 0; - - if (success) - { - if (perfstepsstart <= MESHCONST_OPTSURFACE && - perfstepsend >= MESHCONST_OPTSURFACE) - { - if (!stlgeometry->edgesfound) - { - PrintUserError("You have to do 'meshing->analyse geometry' first!!!"); - return 0; - } - if (!stlgeometry->surfacemeshed) - { - PrintUserError("You have to do 'meshing->mesh surface' first!!!"); - return 0; - } - if (stlgeometry->volumemeshed) - { - PrintWarning("Surface optimization with meshed volume is dangerous!!!"); - } - - if (!optstring || strlen(optstring) == 0) - { - mparam.optimize2d = "smcm"; - } - else - { - mparam.optimize2d = optstring; - } - - STLSurfaceOptimization (*stlgeometry, *mesh, mparam); - - if (stlparam.recalc_h_opt) - { - mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), - stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), - mparam.grading); - mesh -> LoadLocalMeshSize (mparam.meshsizefilename); - mesh -> CalcLocalHFromSurfaceCurvature (stlparam.resthsurfmeshcurvfac); - mparam.optimize2d = "cmsmSm"; - STLSurfaceOptimization (*stlgeometry, *mesh, mparam); -#ifdef STAT_STREAM - (*statout) << GetTime() << " & "; -#endif - -#ifdef OPENGL - extern void Render(); - Render(); -#endif - } - stlgeometry->surfaceoptimized = 1; - } - if (multithread.terminate) - return 0; - - if (perfstepsstart <= MESHCONST_MESHVOLUME && - perfstepsend >= MESHCONST_MESHVOLUME) - { - if (stlgeometry->volumemeshed) - { - PrintUserError("Volume already meshed!"); return 0; - } - - if (!stlgeometry->edgesfound) - { - PrintUserError("You have to do 'meshing->analyse geometry' first!!!"); - return 0; - } - if (!stlgeometry->surfacemeshed) - { - PrintUserError("You have to do 'meshing->mesh surface' first!!!"); - return 0; - } - if (!stlgeometry->surfaceoptimized) - { - PrintWarning("You should do 'meshing->optimize surface' first!!!"); - } - - PrintMessage(5,"Check Overlapping boundary: "); - mesh->FindOpenElements(); - mesh->CheckOverlappingBoundary(); - PrintMessage(5,""); - - if (stlparam.recalc_h_opt) - { - mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), - stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), - mparam.grading); - mesh -> LoadLocalMeshSize (mparam.meshsizefilename); - mesh -> CalcLocalH (); - } - - - PrintMessage(5,"Volume meshing"); - int retval = MeshVolume (mparam, *mesh); - if (retval == MESHING3_OK) - { - RemoveIllegalElements(*mesh); - stlgeometry->volumemeshed = 1; - } - else if (retval == MESHING3_OUTERSTEPSEXCEEDED) - { - PrintError("Give up because of too many trials. Meshing aborted!"); - return 0; - } - else if (retval == MESHING3_TERMINATE) - { - PrintWarning("Meshing Stopped by user!"); - } - else - { - PrintError("Volume meshing not successful. Meshing aborted!"); - return 0; - } - -#ifdef STAT_STREAM - (*statout) << GetTime() << " & " << endl; -#endif - MeshQuality3d (*mesh); - } - - if (multithread.terminate) - return 0; - - if (perfstepsstart <= MESHCONST_OPTVOLUME && - perfstepsend >= MESHCONST_OPTVOLUME) - { - if (!stlgeometry->edgesfound) - { - PrintUserError("You have to do 'meshing->analyse geometry' first!!!"); - return 0; - } - if (!stlgeometry->surfacemeshed) - { - PrintUserError("You have to do 'meshing->mesh surface' first!!!"); - return 0; - } - if (!stlgeometry->volumemeshed) - { - PrintUserError("You have to do 'meshing->mesh volume' first!!!"); - return 0; - } - - if (!optstring || strlen(optstring) == 0) - { - mparam.optimize3d = "cmdmstm"; - } - else - { - mparam.optimize3d = optstring; - } - - - OptimizeVolume (mparam, *mesh); - -#ifdef STAT_STREAM - (*statout) << GetTime() << " & " << endl; - (*statout) << mesh->GetNE() << " & " << endl - << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; -#endif - -#ifdef OPENGL - extern void Render(); - Render(); -#endif - - } - } - - - return 0; -} - - - -} diff --git a/Netgen/libsrc/stlgeom/stlline.cpp b/Netgen/libsrc/stlgeom/stlline.cpp deleted file mode 100644 index 0fe01967e6..0000000000 --- a/Netgen/libsrc/stlgeom/stlline.cpp +++ /dev/null @@ -1,780 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - -#include "stlgeom.hpp" - -namespace netgen -{ - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -//++++++++++++++ EDGE DATA ++++++++++++++++++++++++++++++++++++++++++ -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -/* -void STLEdgeData :: Write(ofstream& of) const -{ - of // << angle << " " - << p1 << " " - << p2 << " " - << lt << " " - << rt << " " - // << status - << endl; -} - -void STLEdgeData :: Read(ifstream& ifs) -{ - // ifs >> angle; - ifs >> p1; - ifs >> p2; - ifs >> lt; - ifs >> rt; - // ifs >> status; -} - - -int STLEdgeData :: GetStatus () const -{ - if (topedgenr <= 0 || topedgenr > top->GetNTE()) return 0; - return top->GetTopEdge (topedgenr).GetStatus(); -} - -void STLEdgeData ::SetStatus (int stat) -{ - if (topedgenr >= 1 && topedgenr <= top->GetNTE()) - top->GetTopEdge (topedgenr).SetStatus(stat); -} - - -float STLEdgeData :: CosAngle() const -{ - return top->GetTopEdge (topedgenr).CosAngle(); -} - - - -void STLEdgeDataList :: ResetAll() -{ - int i; - for (i = 1; i <= edgedata.Size(); i++) - { - edgedata.Elem(i).SetUndefined(); - } -} - -void STLEdgeDataList :: ResetCandidates() -{ - int i; - for (i = 1; i <= edgedata.Size(); i++) - { - if (edgedata.Get(i).Candidate()) - {edgedata.Elem(i).SetUndefined();} - } -} - -int STLEdgeDataList :: GetNConfEdges() const -{ - int i; - int cnt = 0; - for (i = 1; i <= edgedata.Size(); i++) - { - if (edgedata.Get(i).Confirmed()) {cnt++;} - } - return cnt; -} - -void STLEdgeDataList :: ConfirmCandidates() -{ - int i; - for (i = 1; i <= edgedata.Size(); i++) - { - if (edgedata.Get(i).Candidate()) - {edgedata.Elem(i).SetConfirmed();} - } -} - -int STLEdgeDataList :: GetEdgeNum(int np1, int np2) const -{ - INDEX_2 ed(np1,np2); - ed.Sort(); - if (hashtab.Used(ed)) - { - return hashtab.Get(ed); - } - -// int i; -// for (i = 1; i <= Size(); i++) -// { -// if ((Get(i).p1 == np1 && Get(i).p2 == np2) || -// (Get(i).p2 == np1 && Get(i).p1 == np2)) -// { -// return i; -// } -// } - - return 0; -} - -const STLEdgeDataList& STLEdgeDataList :: operator=(const STLEdgeDataList& edl) -{ - int i; - SetSize(edl.Size()); - for (i = 1; i <= Size(); i++) - { - Add(edl.Get(i), i); - } - return *this; -} - -void STLEdgeDataList :: Add(const STLEdgeData& ed, int i) -{ - INDEX_2 edge(ed.p1,ed.p2); - edge.Sort(); - hashtab.Set(edge, i); - Elem(i) = ed; - AddEdgePP(ed.p1,i); - AddEdgePP(ed.p2,i); -} - -void STLEdgeDataList :: Write(ofstream& of) const -{ - of.precision(16); - int i; - of << Size() << endl; - - for (i = 1; i <= Size(); i++) - { - Get(i).Write(of); - } -} - -void STLEdgeDataList :: Read(ifstream& ifs) -{ - int i,n; - ifs >> n; - - SetSize(n); - STLEdgeData ed; - for (i = 1; i <= n; i++) - { - ed.Read(ifs); - Add(ed,i); - } -} - -int STLEdgeDataList :: GetNEPPStat(int p, int status) const -{ - int i; - int cnt = 0; - for (i = 1; i <= GetNEPP(p); i++) - { - if (Get(GetEdgePP(p,i)).GetStatus() == status) - { - cnt++; - } - } - return cnt; -} - -int STLEdgeDataList :: GetNConfCandEPP(int p) const -{ - int i; - int cnt = 0; - for (i = 1; i <= GetNEPP(p); i++) - { - if (Get(GetEdgePP(p,i)).ConfCand()) - { - cnt++; - } - } - return cnt; -} - - -void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line) -{ - int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); - - int found, pstart, p, en, pnew, ennew; - int closed = 0; - int j, i; - for (j = 1; j <= 2; j++) - { - if (j == 1) {p = ep1;} - if (j == 2) {p = ep2;} - - pstart = p; - en = GetEdgeNum(ep1,ep2); - - found = 1; - while (found && !closed) - { - found = 0; - - if (GetNEPPStat(p,status) == 2) - { - for (i = 1; i <= GetNEPP(p); i++) - { - const STLEdgeData& e = Get(GetEdgePP(p,i)); - if (GetEdgePP(p,i) != en && e.GetStatus() == status) - { - if (e.p1 == p) - {pnew = e.p2;} - else - {pnew = e.p1;} - - ennew = GetEdgePP(p,i); - } - } - if (pnew == pstart) {closed = 1;} - else - { - line.Append(twoint(p,pnew)); - p = pnew; - en = ennew; - found = 1; - } - } - } - } - -} -*/ - - - - -STLEdgeDataList :: STLEdgeDataList (STLTopology & ageom) - : geom(ageom) -{ - ; -} - -STLEdgeDataList :: ~STLEdgeDataList() -{ - ; -} - - -void STLEdgeDataList :: Store () -{ - int i, ne = geom.GetNTE(); - storedstatus.SetSize(ne); - for (i = 1; i <= ne; i++) - { - storedstatus.Elem(i) = Get(i).GetStatus(); - } -} - -void STLEdgeDataList :: Restore () -{ - int i, ne = geom.GetNTE(); - if (storedstatus.Size() == ne) - for (i = 1; i <= ne; i++) - geom.GetTopEdge(i).SetStatus (storedstatus.Elem(i)); -} - - -void STLEdgeDataList :: ResetAll() -{ - int i, ne = geom.GetNTE(); - for (i = 1; i <= ne; i++) - geom.GetTopEdge (i).SetStatus (ED_UNDEFINED); -} - -int STLEdgeDataList :: GetNConfEdges() const -{ - int i, ne = geom.GetNTE(); - int cnt = 0; - for (i = 1; i <= ne; i++) - if (geom.GetTopEdge (i).GetStatus() == ED_CONFIRMED) - cnt++; - return cnt; -} - -void STLEdgeDataList :: ChangeStatus(int status1, int status2) -{ - int i, ne = geom.GetNTE(); - for (i = 1; i <= ne; i++) - if (geom.GetTopEdge (i).GetStatus() == status1) - geom.GetTopEdge (i).SetStatus (status2); -} - -/* -void STLEdgeDataList :: Add(const STLEdgeData& ed, int i) -{ - INDEX_2 edge(ed.p1,ed.p2); - edge.Sort(); - hashtab.Set(edge, i); - Elem(i) = ed; - AddEdgePP(ed.p1,i); - AddEdgePP(ed.p2,i); -} -*/ - -void STLEdgeDataList :: Write(ofstream& of) const -{ - - /* - of.precision(16); - int i; - of << Size() << endl; - - for (i = 1; i <= Size(); i++) - { - Get(i).Write(of); - } - - */ - of.precision(16); - int i, ne = geom.GetNTE(); - //of << GetNConfEdges() << endl; - of << geom.GetNTE() << endl; - - for (i = 1; i <= ne; i++) - { - const STLTopEdge & edge = geom.GetTopEdge(i); - //if (edge.GetStatus() == ED_CONFIRMED) - of << edge.GetStatus() << " "; - - const Point3d & p1 = geom.GetPoint (edge.PNum(1)); - const Point3d & p2 = geom.GetPoint (edge.PNum(2)); - of << p1.X() << " " - << p1.Y() << " " - << p1.Z() << " " - << p2.X() << " " - << p2.Y() << " " - << p2.Z() << endl; - } - -} - -void STLEdgeDataList :: Read(ifstream& ifs) -{ - int i, nce; - Point3d p1, p2; - int pi1, pi2; - int status, ednum; - - ifs >> nce; - for (i = 1; i <= nce; i++) - { - ifs >> status; - ifs >> p1.X() >> p1.Y() >> p1.Z(); - ifs >> p2.X() >> p2.Y() >> p2.Z(); - - pi1 = geom.GetPointNum (p1); - pi2 = geom.GetPointNum (p2); - ednum = geom.GetTopEdgeNum (pi1, pi2); - - - if (ednum) - { - geom.GetTopEdge(ednum).SetStatus (status); - // geom.GetTopEdge (ednum).SetStatus (ED_CONFIRMED); - } - } - /* - int i,n; - ifs >> n; - - SetSize(n); - STLEdgeData ed; - for (i = 1; i <= n; i++) - { - ed.Read(ifs); - Add(ed,i); - } - */ -} - -int STLEdgeDataList :: GetNEPPStat(int p, int status) const -{ - int i; - int cnt = 0; - for (i = 1; i <= GetNEPP(p); i++) - { - if (Get(GetEdgePP(p,i)).GetStatus() == status) - { - cnt++; - } - } - return cnt; -} - -int STLEdgeDataList :: GetNConfCandEPP(int p) const -{ - int i; - int cnt = 0; - for (i = 1; i <= GetNEPP(p); i++) - { - if (Get(GetEdgePP(p,i)).GetStatus() == ED_CANDIDATE || - Get(GetEdgePP(p,i)).GetStatus() == ED_CONFIRMED) - { - cnt++; - } - } - return cnt; -} - - -void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line) -{ - int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); - - int found, pstart, p, en, pnew, ennew; - int closed = 0; - int j, i; - for (j = 1; j <= 2; j++) - { - if (j == 1) {p = ep1;} - if (j == 2) {p = ep2;} - - pstart = p; - en = GetEdgeNum(ep1,ep2); - - found = 1; - while (found && !closed) - { - found = 0; - - if (GetNEPPStat(p,status) == 2) - { - for (i = 1; i <= GetNEPP(p); i++) - { - const STLTopEdge & e = Get(GetEdgePP(p,i)); - if (GetEdgePP(p,i) != en && e.GetStatus() == status) - { - if (e.PNum(1) == p) - {pnew = e.PNum(2);} - else - {pnew = e.PNum(1);} - - ennew = GetEdgePP(p,i); - } - } - if (pnew == pstart) {closed = 1;} - else - { - line.Append(twoint(p,pnew)); - p = pnew; - en = ennew; - found = 1; - } - } - } - } - -} - -int Exists(int p1, int p2, const ARRAY<twoint>& line) -{ - int i; - for (i = 1; i <= line.Size(); i++) - { - if (line.Get(i).i1 == p1 && line.Get(i).i2 == p2 || - line.Get(i).i1 == p2 && line.Get(i).i2 == p1) {return 1;} - } - return 0; -} - -void STLEdgeDataList :: BuildClusterWithEdge(int ep1, int ep2, ARRAY<twoint>& line) -{ - int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); - - int p, en; - int j, i, k; - int oldend; - int newend = 1; - int pnew, ennew; - - int changed = 1; - while (changed) - { - changed = 0; - for (j = 1; j <= 2; j++) - { - oldend = newend; - newend = line.Size(); - for (k = oldend; k <= line.Size(); k++) - { - if (j == 1) p = line.Get(k).i1; - if (j == 2) p = line.Get(k).i2; - en = GetEdgeNum(line.Get(k).i1, line.Get(k).i2); - - for (i = 1; i <= GetNEPP(p); i++) - { - pnew = 0; - const STLTopEdge & e = Get(GetEdgePP(p,i)); - if (GetEdgePP(p,i) != en && e.GetStatus() == status) - { - if (e.PNum(1) == p) - {pnew = e.PNum(2);} - else - {pnew = e.PNum(1);} - - ennew = GetEdgePP(p,i); - } - if (pnew && !Exists(p,pnew,line)) - { - changed = 1; - line.Append(twoint(p,pnew)); - p = pnew; - en = ennew; - } - } - - } - } - - } - -} - - - - - - - - - - -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -//+++++++++++++++++++ STL LINE +++++++++++++++++++++++++++++++ -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -STLLine :: STLLine(const STLGeometry * ageometry) - : pts(), lefttrigs(), righttrigs() -{ - geometry = ageometry; - split = 0; -} - -int STLLine :: GetNS() const -{ - if (pts.Size() <= 1) {return 0;} - return pts.Size()-1; -} -void STLLine :: GetSeg(int nr, int& p1, int& p2) const -{ - p1 = pts.Get(nr); - p2 = pts.Get(nr+1); -} - -int STLLine :: GetLeftTrig(int nr) const -{ - if (nr > lefttrigs.Size()) {PrintSysError("In STLLine::GetLeftTrig!!!"); return 0;} - return lefttrigs.Get(nr); -} - -int STLLine :: GetRightTrig(int nr) const -{ - if (nr > righttrigs.Size()) {PrintSysError("In STLLine::GetRightTrig!!!"); return 0;} - return righttrigs.Get(nr); -} - -double STLLine :: GetSegLen(const ARRAY<Point<3> >& ap, int nr) const -{ - return Dist(ap.Get(PNum(nr)),ap.Get(PNum(nr+1))); -} - -double STLLine :: GetLength(const ARRAY<Point<3> >& ap) const -{ - double len = 0; - for (int i = 2; i <= pts.Size(); i++) - { - len += (ap.Get(pts.Get(i)) - ap.Get(pts.Get(i-1))).Length(); - } - return len; -} - -void STLLine :: GetBoundingBox (const ARRAY<Point<3> > & ap, Box<3> & box) const -{ - box.Set (ap.Get (pts[0])); - for (int i = 1; i < pts.Size(); i++) - box.Add (ap.Get(pts[i])); -} - - - -Point<3> STLLine :: -GetPointInDist(const ARRAY<Point<3> >& ap, double dist, int& index) const -{ - if (dist <= 0) - { - index = 1; - return ap.Get(StartP()); - } - - double len = 0; - int i; - for (i = 1; i < pts.Size(); i++) - { - double seglen = Dist (ap.Get(pts.Get(i)), - ap.Get(pts.Get(i+1))); - - if (len + seglen > dist) - { - index = i; - double relval = (dist - len) / (seglen + 1e-16); - Vec3d v (ap.Get(pts.Get(i)), ap.Get(pts.Get(i+1))); - return ap.Get(pts.Get(i)) + relval * v; - } - - len += seglen; - } - - index = pts.Size() - 1; - return ap.Get(EndP()); -} - - -/* -double stlgh; -double GetH(const Point3d& p, double x) -{ - return stlgh;//+0.5)*(x+0.5); -} -*/ -STLLine* STLLine :: Mesh(const ARRAY<Point<3> >& ap, - ARRAY<Point3d>& mp, double ghi, - class Mesh& mesh) const -{ - STLLine* line = new STLLine(geometry); - - //stlgh = ghi; //uebergangsloesung!!!! - - double len = GetLength(ap); - double inthl = 0; //integral of 1/h - double dist = 0; - double h; - int ind; - Point3d p; - - int i, j; - - Box<3> bbox; - GetBoundingBox (ap, bbox); - double diam = bbox.Diam(); - - double minh = mesh.LocalHFunction().GetMinH (bbox.PMin(), bbox.PMax()); - - double maxseglen = 0; - for (i = 1; i <= GetNS(); i++) - maxseglen = max2 (maxseglen, GetSegLen (ap, i)); - - int nph = 10+int(maxseglen / minh); //anzahl der integralauswertungen pro segment - - ARRAY<double> inthi(GetNS()*nph); - ARRAY<double> curvelen(GetNS()*nph); - - - for (i = 1; i <= GetNS(); i++) - { - double seglen = GetSegLen(ap,i); - for (j = 1; j <= nph; j++) - { - p = GetPointInDist(ap,dist,ind); - //h = GetH(p,dist/len); - h = mesh.GetH(p); - - - dist += GetSegLen(ap,i)/(double)nph; - - inthl += GetSegLen(ap,i)/nph/(h); - inthi.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph/h; - curvelen.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph; - } - } - - - int inthlint = int(inthl+1); - - if ( (inthlint < 3) && (StartP() == EndP())) - { - inthlint = 3; - } - if ( (inthlint == 1) && ShouldSplit()) - { - inthlint = 2; - } - - double fact = inthl/(double)inthlint; - dist = 0; - j = 1; - - - p = ap.Get(StartP()); - int pn = AddPointIfNotExists(mp, p, 1e-10*diam); - - int segn = 1; - line->AddPoint(pn); - line->AddLeftTrig(GetLeftTrig(segn)); - line->AddRightTrig(GetRightTrig(segn)); - line->AddDist(dist); - - inthl = 0; //restart each meshseg - for (i = 1; i <= inthlint; i++) - { - while (inthl < 1.000000001 && j <= inthi.Size()) - // while (inthl-1. < 1e-9) && j <= inthi.Size()) - { - inthl += inthi.Get(j)/fact; - dist += curvelen.Get(j); - j++; - } - - //went to far: - j--; - double tofar = (inthl - 1)/inthi.Get(j); - inthl -= tofar*inthi.Get(j); - dist -= tofar*curvelen.Get(j)*fact; - - if (i == inthlint && fabs(dist - len) >= 1E-8) - { - PrintSysError("meshline failed!!!"); - } - - if (i != inthlint) - { - p = GetPointInDist(ap,dist,ind); - pn = AddPointIfNotExists(mp, p, 1e-10*diam); - segn = ind; - line->AddPoint(pn); - line->AddLeftTrig(GetLeftTrig(segn)); - line->AddRightTrig(GetRightTrig(segn)); - line->AddDist(dist); - } - - inthl = tofar*inthi.Get(j); - dist += tofar*curvelen.Get(j)*fact; - j++; - } - - p = ap.Get(EndP()); - pn = AddPointIfNotExists(mp, p, 1e-10*diam); - segn = GetNS(); - line->AddPoint(pn); - line->AddLeftTrig(GetLeftTrig(segn)); - line->AddRightTrig(GetRightTrig(segn)); - line->AddDist(dist); - - for (int ii = 1; ii <= line->GetNS(); ii++) - { - int p1, p2; - line->GetSeg(ii,p1,p2); - } - /* - (*testout) << "line, " << ap.Get(StartP()) << "-" << ap.Get(EndP()) - << " len = " << Dist (ap.Get(StartP()), ap.Get(EndP())) << endl; - */ - return line; -} -} diff --git a/Netgen/libsrc/stlgeom/stlline.hpp b/Netgen/libsrc/stlgeom/stlline.hpp deleted file mode 100644 index 70393ca060..0000000000 --- a/Netgen/libsrc/stlgeom/stlline.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef FILE_STLLINE -#define FILE_STLLINE - - -/**************************************************************************/ -/* File: stlline.hh */ -/* Author: Joachim Schoeberl */ -/* Author2: Johannes Gerstmayr */ -/* Date: 20. Nov. 99 */ -/**************************************************************************/ - -class STLGeometry; -class STLTopology; - -class STLEdge -{ -public: - int pts[2]; - int trigs[2]; //left and right trig - - STLEdge (const int * apts) {pts[0] = apts[0]; pts[1] = apts[1];} - STLEdge (int v1, int v2) {pts[0] = v1; pts[1] = v2;} - STLEdge () {pts[0]=0;pts[1]=0;} - int PNum(int i) const {return pts[(i-1)];} - - int LeftTrig() const {return trigs[0];} - int RightTrig() const {return trigs[1];} - void SetLeftTrig(int i) {trigs[0] = i;} - void SetRightTrig(int i) {trigs[1] = i;} -}; - -enum STL_ED_STATUS { ED_EXCLUDED, ED_CONFIRMED, ED_CANDIDATE, ED_UNDEFINED }; - - -/* - -class STLEdgeData -{ -public: - // float angle; - int p1; - int p2; - int lt; //left trig - int rt; //right trig - // int status; - - STLTopology * top; // pointer to stl topology - int topedgenr; // number of corresponding topology edge - - STLEdgeData() {}; - STLEdgeData(float anglei, int p1i, int p2i, int lti, int rti) -{ -// angle = anglei; -p1 = p1i; p2 = p2i; - lt = lti; rt = rti; - } - - int GetStatus () const; - void SetStatus (int stat); - - void SetExcluded() { SetStatus (ED_EXCLUDED); } - void SetConfirmed() { SetStatus (ED_CONFIRMED); } - void SetCandidate() { SetStatus (ED_CANDIDATE); } - void SetUndefined() { SetStatus (ED_UNDEFINED); } - - int Excluded() const {return GetStatus() == ED_EXCLUDED;} - int Confirmed() const {return GetStatus() == ED_CONFIRMED;} - int Candidate() const {return GetStatus() == ED_CANDIDATE;} - int Undefined() const {return GetStatus() == ED_UNDEFINED;} - int ConfCand() const {return GetStatus() == ED_CONFIRMED || GetStatus() == ED_CANDIDATE;} - - float CosAngle() const; - - void Write(ofstream& of) const; - void Read(ifstream& ifs); -}; - -class STLEdgeDataList -{ -private: - INDEX_2_HASHTABLE<int> hashtab; - ARRAY<STLEdgeData> edgedata; - TABLE<int> edgesperpoint; - -public: - - STLEdgeDataList():edgedata(),hashtab(1),edgesperpoint() {}; - const STLEdgeDataList& operator=(const STLEdgeDataList& edl); - void SetSize(int size) - { - edgedata.SetSize(size); - hashtab.SetSize(size); - edgesperpoint.SetSize(size); - } - void Clear() {SetSize(0);} - int Size() const {return edgedata.Size();} - const STLEdgeData& Get(int i) const {return edgedata.Get(i);} - STLEdgeData& Elem(int i) {return edgedata.Elem(i);} - void Add(const STLEdgeData& ed, int i); - - int GetNEPP(int pn) const - { - return edgesperpoint.EntrySize(pn); - }; - int GetEdgePP(int pn, int vi) const - { - return edgesperpoint.Get(pn,vi); - }; - void AddEdgePP(int pn, int vn) {edgesperpoint.Add(pn,vn);}; - - void ResetAll(); - void ResetCandidates(); - void ConfirmCandidates(); - int GetEdgeNum(int np1, int np2) const; - - int GetNConfEdges() const; - - void Write(ofstream& of) const; - void Read(ifstream& ifs); - - void BuildLineWithEdge(int ep1, int ep2, ARRAY<twoint>& line); - - int GetNEPPStat(int p, int status) const; - int GetNConfCandEPP(int p) const; -}; -*/ - - - - - - - - - - - - - - - - -//a line defined by several points (polyline) -class STLLine -{ -private: - const STLGeometry * geometry; - ARRAY<int> pts; - ARRAY<int> lefttrigs; - ARRAY<int> righttrigs; - ARRAY<double> dists; - int split; - -public: - STLLine(const STLGeometry * ageometry); - void AddPoint(int i) {pts.Append(i);} - int PNum(int i) const {return pts.Get(i);} - int NP() const {return pts.Size();} - int GetNS() const; - void GetSeg(int nr, int& p1, int& p2) const; - double GetSegLen(const ARRAY<Point<3> >& ap, int nr) const; - int GetLeftTrig(int nr) const; - int GetRightTrig(int nr) const; - double GetDist(int nr) const { return dists.Get(nr);}; - void GetBoundingBox (const ARRAY<Point<3> > & ap, Box<3> & box) const; - - void AddLeftTrig(int nr) {lefttrigs.Append(nr);} - void AddRightTrig(int nr) {righttrigs.Append(nr);} - void AddDist (double dist) {dists.Append(dist); } - int StartP() const {return pts.Get(1);} - int EndP() const {return pts.Get(pts.Size());} - - double GetLength(const ARRAY<Point<3> >& ap) const; - - //suche punkt in entfernung (in linienkoordinaten) dist - //in index ist letzter punkt VOR dist (d.h. max pts.Size()-1) - Point<3> GetPointInDist(const ARRAY<Point<3> >& ap, double dist, int& index) const; - - //return a meshed polyline - STLLine* Mesh(const ARRAY<Point<3> >& ap, - ARRAY<Point3d>& mp, double ghi, - class Mesh& mesh) const; - - void DoSplit() {split = 1;} - int ShouldSplit() const {return split;} -}; - -#endif diff --git a/Netgen/libsrc/stlgeom/stltool.cpp b/Netgen/libsrc/stlgeom/stltool.cpp deleted file mode 100644 index c19fed4ca0..0000000000 --- a/Netgen/libsrc/stlgeom/stltool.cpp +++ /dev/null @@ -1,1288 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - -#include "stlgeom.hpp" - -namespace netgen -{ - - -//add a point into a pointlist, return pointnumber -int AddPointIfNotExists(ARRAY<Point3d>& ap, const Point3d& p, double eps) -{ - int i; - for (i = 1; i <= ap.Size(); i++) - { - if (Dist(ap.Get(i),p) <= eps ) {return i;} - } - return ap.Append(p); -} - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -double GetDistFromLine(const Point<3> & lp1, const Point<3> & lp2, - Point<3> & p) -{ - Vec3d vn = lp2 - lp1; - Vec3d v1 = p - lp1; - Vec3d v2 = lp2 - p; - - Point3d pold = p; - - if (v2 * vn <= 0) {p = lp2; return (pold - p).Length();} - if (v1 * vn <= 0) {p = lp1; return (pold - p).Length();} - - double vnl = vn.Length(); - if (vnl == 0) {return Dist(lp1,p);} - - vn /= vnl; - p = lp1 + (v1 * vn) * vn; - return (pold - p).Length(); -} - -double GetDistFromInfiniteLine(const Point<3>& lp1, const Point<3>& lp2, const Point<3>& p) -{ - Vec3d vn(lp1, lp2); - Vec3d v1(lp1, p); - - double vnl = vn.Length(); - - if (vnl == 0) - { - return Dist (lp1, p); - } - else - { - return Cross (vn, v1).Length() / vnl; - } -} - - - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -//Binary IO-Manipulation - - - -void FIOReadInt(istream& ios, int& i) -{ - const int ilen = sizeof(int); - - char buf[ilen]; - int j; - for (j = 0; j < ilen; j++) - { - ios.get(buf[j]); - } - memcpy(&i, &buf, ilen); -} - -void FIOWriteInt(ostream& ios, const int& i) -{ - const int ilen = sizeof(int); - - char buf[ilen]; - memcpy(&buf, &i, ilen); - - int j; - for (j = 0; j < ilen; j++) - { - ios << buf[j]; - } -} - -void FIOReadDouble(istream& ios, double& i) -{ - const int ilen = sizeof(double); - - char buf[ilen]; - int j; - for (j = 0; j < ilen; j++) - { - ios.get(buf[j]); - } - memcpy(&i, &buf, ilen); -} - -void FIOWriteDouble(ostream& ios, const double& i) -{ - const int ilen = sizeof(double); - - char buf[ilen]; - memcpy(&buf, &i, ilen); - - int j; - for (j = 0; j < ilen; j++) - { - ios << buf[j]; - } -} - -void FIOReadFloat(istream& ios, float& i) -{ - const int ilen = sizeof(float); - - char buf[ilen]; - int j; - for (j = 0; j < ilen; j++) - { - ios.get(buf[j]); - } - memcpy(&i, &buf, ilen); -} - -void FIOWriteFloat(ostream& ios, const float& i) -{ - const int ilen = sizeof(float); - - char buf[ilen]; - memcpy(&buf, &i, ilen); - - int j; - for (j = 0; j < ilen; j++) - { - ios << buf[j]; - } -} - -void FIOReadString(istream& ios, char* str, int len) -{ - int j; - for (j = 0; j < len; j++) - { - ios.get(str[j]); - } -} - -//read string and add terminating 0 -void FIOReadStringE(istream& ios, char* str, int len) -{ - int j; - for (j = 0; j < len; j++) - { - ios.get(str[j]); - } - str[len] = 0; -} - -void FIOWriteString(ostream& ios, char* str, int len) -{ - int j; - for (j = 0; j < len; j++) - { - ios << str[j]; - } -} - - -/* -void FIOReadInt(istream& ios, int& i) -{ - const int ilen = sizeof(int); - - char buf[ilen]; - int j; - for (j = 0; j < ilen; j++) - { - ios.get(buf[ilen-j-1]); - } - memcpy(&i, &buf, ilen); -} - -void FIOWriteInt(ostream& ios, const int& i) -{ - const int ilen = sizeof(int); - - char buf[ilen]; - memcpy(&buf, &i, ilen); - - int j; - for (j = 0; j < ilen; j++) - { - ios << buf[ilen-j-1]; - } -} - -void FIOReadDouble(istream& ios, double& i) -{ - const int ilen = sizeof(double); - - char buf[ilen]; - int j; - for (j = 0; j < ilen; j++) - { - ios.get(buf[ilen-j-1]); - } - memcpy(&i, &buf, ilen); -} - -void FIOWriteDouble(ostream& ios, const double& i) -{ - const int ilen = sizeof(double); - - char buf[ilen]; - memcpy(&buf, &i, ilen); - - int j; - for (j = 0; j < ilen; j++) - { - ios << buf[ilen-j-1]; - } -} - -void FIOReadFloat(istream& ios, float& i) -{ - const int ilen = sizeof(float); - - char buf[ilen]; - int j; - for (j = 0; j < ilen; j++) - { - ios.get(buf[ilen-j-1]); - } - memcpy(&i, &buf, ilen); -} - -void FIOWriteFloat(ostream& ios, const float& i) -{ - const int ilen = sizeof(float); - - char buf[ilen]; - memcpy(&buf, &i, ilen); - - int j; - for (j = 0; j < ilen; j++) - { - ios << buf[ilen-j-1]; - } -} - -void FIOReadString(istream& ios, char* str, int len) -{ - int j; - for (j = 0; j < len; j++) - { - ios.get(str[j]); - } -} - -//read string and add terminating 0 -void FIOReadStringE(istream& ios, char* str, int len) -{ - int j; - for (j = 0; j < len; j++) - { - ios.get(str[j]); - } - str[len] = 0; -} - -void FIOWriteString(ostream& ios, char* str, int len) -{ - int j; - for (j = 0; j < len; j++) - { - ios << str[j]; - } -} -*/ - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -STLReadTriangle :: STLReadTriangle (const Point<3> * apts, - const Vec<3> & anormal) -{ - pts[0] = apts[0]; - pts[1] = apts[1]; - pts[2] = apts[2]; - normal = anormal; -} - - - -STLTriangle :: STLTriangle(const int * apts) -{ - pts[0] = apts[0]; - pts[1] = apts[1]; - pts[2] = apts[2]; - - facenum = 0; -} - -int STLTriangle :: IsNeighbourFrom(const STLTriangle& t) const -{ - //triangles must have same orientation!!! - int i, j; - for(i = 0; i <= 2; i++) - { - for(j = 0; j <= 2; j++) - { - if (t.pts[(i+1)%3] == pts[j] && - t.pts[i] == pts[(j+1)%3]) - {return 1;} - } - } - return 0; -} - -int STLTriangle :: IsWrongNeighbourFrom(const STLTriangle& t) const -{ - //triangles have not same orientation!!! - int i, j; - for(i = 0; i <= 2; i++) - { - for(j = 0; j <= 2; j++) - { - if (t.pts[(i+1)%3] == pts[(j+1)%3] && - t.pts[i] == pts[j]) - {return 1;} - } - } - return 0; -} - -void STLTriangle :: GetNeighbourPoints(const STLTriangle& t, int& p1, int& p2) const -{ - int i, j; - for(i = 1; i <= 3; i++) - { - for(j = 1; j <= 3; j++) - { - if (t.PNumMod(i+1) == PNumMod(j) && - t.PNumMod(i) == PNumMod(j+1)) - {p1 = PNumMod(j); p2 = PNumMod(j+1); return;} - } - } - PrintSysError("Get neighbourpoints failed!"); -} - -int STLTriangle :: GetNeighbourPointsAndOpposite(const STLTriangle& t, int& p1, int& p2, int& po) const -{ - int i, j; - for(i = 1; i <= 3; i++) - { - for(j = 1; j <= 3; j++) - { - if (t.PNumMod(i+1) == PNumMod(j) && - t.PNumMod(i) == PNumMod(j+1)) - {p1 = PNumMod(j); p2 = PNumMod(j+1); po = PNumMod(j+2); return 1;} - } - } - return 0; -} - -Vec<3> STLTriangle :: GeomNormal(const ARRAY<Point<3> >& ap) const -{ - const Point<3> & p1 = ap.Get(PNum(1)); - const Point<3> & p2 = ap.Get(PNum(2)); - const Point<3> & p3 = ap.Get(PNum(3)); - - return Cross(p2-p1, p3-p1); -} - - -void STLTriangle :: SetNormal (const Vec<3> & n) -{ - double len = n.Length(); - if (len > 0) - { - normal = n; - normal.Normalize(); - } - else - { - normal = Vec<3> (1, 0, 0); - } -} - - -void STLTriangle :: ChangeOrientation() -{ - normal *= -1; - Swap(pts[0],pts[1]); -} - - - -double STLTriangle :: Area(const ARRAY<Point<3> >& ap) const -{ - return 0.5 * Cross(ap.Get(PNum(2))-ap.Get(PNum(1)), - ap.Get(PNum(3))-ap.Get(PNum(1))).Length(); -} - -double STLTriangle :: MinHeight(const ARRAY<Point<3> >& ap) const -{ - double ml = MaxLength(ap); - if (ml != 0) {return 2.*Area(ap)/ml;} - PrintWarning("max Side Length of a triangle = 0!!!"); - return 0; -} - -double STLTriangle :: MaxLength(const ARRAY<Point<3> >& ap) const -{ - return max3(Dist(ap.Get(PNum(1)),ap.Get(PNum(2))), - Dist(ap.Get(PNum(2)),ap.Get(PNum(3))), - Dist(ap.Get(PNum(3)),ap.Get(PNum(1)))); -} - -void STLTriangle :: ProjectInPlain(const ARRAY<Point<3> >& ap, - const Vec<3> & n, Point<3> & pp) const -{ - const Point<3> & p1 = ap.Get(PNum(1)); - const Point<3> & p2 = ap.Get(PNum(2)); - const Point<3> & p3 = ap.Get(PNum(3)); - - Vec<3> v1 = p2 - p1; - Vec<3> v2 = p3 - p1; - Vec<3> nt = Cross(v1, v2); - - double c = - (p1(0)*nt(0) + p1(1)*nt(1) + p1(2)*nt(2)); - - double prod = n * nt; - - if (fabs(prod) == 0) - { - pp = Point<3>(1.E20,1.E20,1.E20); - return; - } - - double nfact = -(pp(0)*nt(0) + pp(1)*nt(1) + pp(2)*nt(2) + c) / (prod); - pp = pp + (nfact) * n; - -} - - -int STLTriangle :: ProjectInPlain (const ARRAY<Point<3> >& ap, - const Vec<3> & nproj, - Point<3> & pp, Vec<3> & lam) const -{ - const Point<3> & p1 = ap.Get(PNum(1)); - const Point<3> & p2 = ap.Get(PNum(2)); - const Point<3> & p3 = ap.Get(PNum(3)); - - Vec<3> v1 = p2-p1; - Vec<3> v2 = p3-p1; - - Mat<3> mat; - for (int i = 0; i < 3; i++) - { - mat(i,0) = v1(i); - mat(i,1) = v2(i); - mat(i,2) = nproj(i); - } - - int err = 0; - mat.Solve (pp-p1, lam); - // int err = SolveLinearSystem (v1, v2, nproj, pp-p1, lam); - - if (!err) - { - // pp = p1 + lam(0) * v1 + lam(1) * v2; - - pp(0) = p1(0) + lam(0) * v1(0) + lam(1) * v2(0); - pp(1) = p1(1) + lam(0) * v1(1) + lam(1) * v2(1); - pp(2) = p1(2) + lam(0) * v1(2) + lam(1) * v2(2); - } - return err; -} - - - - - -void STLTriangle :: ProjectInPlain(const ARRAY<Point<3> >& ap, - Point<3> & pp) const -{ - const Point<3> & p1 = ap.Get(PNum(1)); - const Point<3> & p2 = ap.Get(PNum(2)); - const Point<3> & p3 = ap.Get(PNum(3)); - - Vec<3> v1 = p2 - p1; - Vec<3> v2 = p3 - p1; - Vec<3> nt = Cross(v1, v2); - - double c = - (p1(0)*nt(0) + p1(1)*nt(1) + p1(2)*nt(2)); - - double prod = nt * nt; - - double nfact = -(pp(0)*nt(0) + pp(1)*nt(1) + pp(2)*nt(2) + c) / (prod); - - pp = pp + (nfact) * nt; -} - -int STLTriangle :: PointInside(const ARRAY<Point<3> > & ap, - const Point<3> & pp) const -{ - const Point<3> & p1 = ap.Get(PNum(1)); - const Point<3> & p2 = ap.Get(PNum(2)); - const Point<3> & p3 = ap.Get(PNum(3)); - - Vec<3> v1 = p2 - p1; - Vec<3> v2 = p3 - p1; - Vec<3> v = pp - p1; - double det, l1, l2; - Vec<3> ex, ey, ez; - - - ez = GeomNormal(ap); - ez /= ez.Length(); - ex = v1; - ex /= ex.Length(); - ey = Cross (ez, ex); - - Vec<2> v1p(v1*ex, v1*ey); - Vec<2> v2p(v2*ex, v2*ey); - Vec<2> vp(v*ex, v*ey); - - det = v2p(1) * v1p(0) - v2p(0) * v1p(1); - - if (fabs(det) == 0) {return 0;} - - l2 = (vp(1) * v1p(0) - vp(0) * v1p(1)) / det; - - if (v1p(0) != 0.) - { - l1 = (vp(0) - l2 * v2p(0)) / v1p(0); - } - else if (v1p(1) != 0.) - { - l1 = (vp(1) - l2 * v2p(1)) / v1p(1); - } - else {return 0;} - - if (l1 >= -1E-10 && l2 >= -1E-10 && l1 + l2 <= 1.+1E-10) {return 1;} - return 0; -} - -double STLTriangle :: GetNearestPoint(const ARRAY<Point<3> >& ap, - Point<3> & p3d) const -{ - Point<3> p = p3d; - ProjectInPlain(ap, p); - double dist = (p - p3d).Length(); - - if (PointInside(ap, p)) {p3d = p; return dist;} - else - { - Point<3> pf; - double nearest = 1E50; - int fi = 0; - int j; - - for (j = 1; j <= 3; j++) - { - p = p3d; - dist = GetDistFromLine(ap.Get(PNum(j)), ap.Get(PNumMod(j+1)), p); - if (dist < nearest) - { - nearest = dist; - pf = p; - } - } - p3d = pf; - return nearest; - } -} - -int STLTriangle :: HasEdge(int p1, int p2) const -{ - int i; - for (i = 1; i <= 3; i++) - { - if (p1 == PNum(i) && p2 == PNumMod(i+1)) {return 1;} - } - return 0; -} - -ostream& operator<<(ostream& os, const STLTriangle& t) -{ - os << "["; - os << t[0] << ","; - os << t[1] << ","; - os << t[2] << "]"; - - return os; -} - - - -STLTopEdge :: STLTopEdge () -{ - pts[0] = pts[1] = 0; - trigs[0] = trigs[1] = 0; - cosangle = 1; - status = ED_UNDEFINED; -} - -STLTopEdge :: STLTopEdge (int p1, int p2, int trig1, int trig2) -{ - pts[0] = p1; - pts[1] = p2; - trigs[0] = trig1; - trigs[1] = trig2; - cosangle = 1; - status = ED_UNDEFINED; -} - - - - -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -//+++++++++++++++++++ STL CHART +++++++++++++++++++++++++++++++ -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -STLChart :: STLChart(STLGeometry * ageometry) -{ - charttrigs = new ARRAY<int> (0,0); - outertrigs = new ARRAY<int> (0,0); - ilimit = new ARRAY<twoint> (0,0); - olimit = new ARRAY<twoint> (0,0); - - geometry = ageometry; - - if ( (stlparam.usesearchtree == 1)) - searchtree = new Box3dTree (geometry->GetBoundingBox().PMin() - Vec3d(1,1,1), - geometry->GetBoundingBox().PMax() + Vec3d(1,1,1)); - else - searchtree = NULL; -} - -void STLChart :: AddChartTrig(int i) -{ - charttrigs->Append(i); - - const STLTriangle & trig = geometry->GetTriangle(i); - const Point3d & p1 = geometry->GetPoint (trig.PNum(1)); - const Point3d & p2 = geometry->GetPoint (trig.PNum(2)); - const Point3d & p3 = geometry->GetPoint (trig.PNum(3)); - - Point3d pmin(p1), pmax(p1); - pmin.SetToMin (p2); - pmin.SetToMin (p3); - pmax.SetToMax (p2); - pmax.SetToMax (p3); - - if (!geomsearchtreeon && (stlparam.usesearchtree == 1)) - {searchtree->Insert (pmin, pmax, i);} -} - -void STLChart :: AddOuterTrig(int i) -{ - outertrigs->Append(i); - - const STLTriangle & trig = geometry->GetTriangle(i); - const Point3d & p1 = geometry->GetPoint (trig.PNum(1)); - const Point3d & p2 = geometry->GetPoint (trig.PNum(2)); - const Point3d & p3 = geometry->GetPoint (trig.PNum(3)); - - Point3d pmin(p1), pmax(p1); - pmin.SetToMin (p2); - pmin.SetToMin (p3); - pmax.SetToMax (p2); - pmax.SetToMax (p3); - - if (!geomsearchtreeon && (stlparam.usesearchtree==1)) - {searchtree->Insert (pmin, pmax, i);} -} - -int STLChart :: IsInWholeChart(int nr) const -{ - int i; - for (i = 1; i <= charttrigs->Size(); i++) - { - if (charttrigs->Get(i) == nr) {return 1;} - } - for (i = 1; i <= outertrigs->Size(); i++) - { - if (outertrigs->Get(i) == nr) {return 1;} - } - return 0; -} - -void STLChart :: GetTrianglesInBox (const Point3d & pmin, - const Point3d & pmax, - ARRAY<int> & trias) const -{ - if (geomsearchtreeon) {PrintMessage(5,"geomsearchtreeon is set!!!");} - - if (searchtree) - searchtree -> GetIntersecting (pmin, pmax, trias); - else - { - int i; - Box3d box1(pmin, pmax); - box1.Increase (1e-4); - Box3d box2; - - trias.SetSize(0); - - int nt = GetNT(); - for (i = 1; i <= nt; i++) - { - - int trignum = GetTrig(i); - const STLTriangle & trig = geometry->GetTriangle(trignum); - box2.SetPoint (geometry->GetPoint (trig.PNum(1))); - box2.AddPoint (geometry->GetPoint (trig.PNum(2))); - box2.AddPoint (geometry->GetPoint (trig.PNum(3))); - - if (box1.Intersect (box2)) - { - trias.Append (trignum); - } - } - } -} - -//trigs may contain the same triangle double -void STLChart :: MoveToOuterChart(const ARRAY<int>& trigs) -{ - if (!trigs.Size()) {return;} - int i; - for (i = 1; i <= trigs.Size(); i++) - { - if (charttrigs->Get(trigs.Get(i)) != -1) - {AddOuterTrig(charttrigs->Get(trigs.Get(i)));} - charttrigs->Elem(trigs.Get(i)) = -1; - } - DelChartTrigs(trigs); -} - -//trigs may contain the same triangle double -void STLChart :: DelChartTrigs(const ARRAY<int>& trigs) -{ - if (!trigs.Size()) {return;} - - int i; - for (i = 1; i <= trigs.Size(); i++) - { - charttrigs->Elem(trigs.Get(i)) = -1; - } - - int cnt = 0; - for (i = 1; i <= charttrigs->Size(); i++) - { - if (charttrigs->Elem(i) == -1) - { - cnt++; - } - if (cnt != 0 && i < charttrigs->Size()) - { - charttrigs->Elem(i-cnt+1) = charttrigs->Get(i+1); - } - } - i = charttrigs->Size() - trigs.Size(); - charttrigs->SetSize(i); - - if (!geomsearchtreeon && stlparam.usesearchtree == 1) - { - PrintMessage(7, "Warning: unsecure routine due to first use of searchtrees!!!"); - //bould new searchtree!!! - searchtree = new Box3dTree (geometry->GetBoundingBox().PMin() - Vec3d(1,1,1), - geometry->GetBoundingBox().PMax() + Vec3d(1,1,1)); - - for (i = 1; i <= charttrigs->Size(); i++) - { - const STLTriangle & trig = geometry->GetTriangle(i); - const Point3d & p1 = geometry->GetPoint (trig.PNum(1)); - const Point3d & p2 = geometry->GetPoint (trig.PNum(2)); - const Point3d & p3 = geometry->GetPoint (trig.PNum(3)); - - Point3d pmin(p1), pmax(p1); - pmin.SetToMin (p2); - pmin.SetToMin (p3); - pmax.SetToMax (p2); - pmax.SetToMax (p3); - - searchtree->Insert (pmin, pmax, i); - } - } -} - - -void STLChart :: SetNormal (const Point<3> & apref, const Vec<3> & anormal) -{ - pref = apref; - normal = anormal; - double len = normal.Length(); - if (len) normal /= len; - else normal = Vec<3> (1, 0, 0); - - t1 = normal.GetNormal (); - t2 = Cross (normal, t1); -} - -Point<2> STLChart :: Project2d (const Point<3> & p3d) const -{ - Vec<3> v = p3d-pref; - return Point<2> (t1 * v, t2 * v); -} - - - -/* - Point3d p1, p2, center; - double rad; - int i1, i2; -public: -*/ -STLBoundarySeg :: -STLBoundarySeg (int ai1, int ai2, const ARRAY<Point<3> > & points, - const STLChart * chart) -{ - i1 = ai1; - i2 = ai2; - p1 = points.Get(i1); - p2 = points.Get(i2); - center = ::netgen::Center (p1, p2); - rad = Dist (p1, center); - - p2d1 = chart->Project2d (p1); - p2d2 = chart->Project2d (p2); - - boundingbox.Set (p2d1); - boundingbox.Add (p2d2); -} - -void STLBoundarySeg :: Swap () -{ - ::netgen::Swap (i1, i2); - ::netgen::Swap (p1, p2); -} - - - -STLBoundary :: STLBoundary (STLGeometry * ageometry) - : boundary(), geometry(ageometry) -{ - ; -} - - -void STLBoundary :: AddOrDelSegment(const STLBoundarySeg & seg) -{ - int i; - int found = 0; - for (i = 1; i <= boundary.Size(); i++) - { - if (found) {boundary.Elem(i-1) = boundary.Get(i);} - if (boundary.Get(i) == seg) {found = 1;} - } - if (!found) - { - boundary.Append(seg); - } - else - { - boundary.SetSize(boundary.Size()-1); - } -} - -void STLBoundary ::AddTriangle(const STLTriangle & t) -{ - int i; - int found1 = 0; - int found2 = 0; - int found3 = 0; - int offset = 0; - - - STLBoundarySeg seg1(t[0],t[1], geometry->GetPoints(), chart); - STLBoundarySeg seg2(t[1],t[2], geometry->GetPoints(), chart); - STLBoundarySeg seg3(t[2],t[0], geometry->GetPoints(), chart); - - seg1.SetSmoothEdge (geometry->IsSmoothEdge (seg1.I1(), seg1.I2())); - seg2.SetSmoothEdge (geometry->IsSmoothEdge (seg2.I1(), seg2.I2())); - seg3.SetSmoothEdge (geometry->IsSmoothEdge (seg3.I1(), seg3.I2())); - - /* - for (i = 1; i <= boundary.Size(); i++) - { - if (offset) {boundary.Elem(i-offset) = boundary.Get(i);} - if (boundary.Get(i) == seg1) {found1 = 1; offset++;} - if (boundary.Get(i) == seg2) {found2 = 1; offset++;} - if (boundary.Get(i) == seg3) {found3 = 1; offset++;} - } - - if (offset) - { - boundary.SetSize(boundary.Size()-offset); - } - */ - for (i = boundary.Size(); i >= 1; i--) - { - if (boundary.Get(i) == seg1) - { boundary.DeleteElement (i); found1 = 1; } - else if (boundary.Get(i) == seg2) - { boundary.DeleteElement (i); found2 = 1; } - else if (boundary.Get(i) == seg3) - { boundary.DeleteElement (i); found3 = 1; } - } - - if (!found1) {seg1.Swap(); boundary.Append(seg1);} - if (!found2) {seg2.Swap(); boundary.Append(seg2);} - if (!found3) {seg3.Swap(); boundary.Append(seg3);} -} - -int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3> & sn, - double sinchartangle, int divisions, ARRAY<Point<3> >& points, double eps) -{ - - if (usechartnormal) - return TestSegChartNV (p1, p2, sn); - - // for statistics - { - int i; - static ARRAY<int> cntclass; - static int cnt = 0; - static int cnti = 0, cnto = 0; - static long int cntsegs = 0; - if (cntclass.Size() == 0) - { - cntclass.SetSize (20); - for (i = 1; i <= cntclass.Size(); i++) - cntclass.Elem(i) = 0; - } - - cntsegs += NOSegments(); - int cla = int (log (double(NOSegments()+1)) / log(2.0)); - if (cla < 1) cla = 1; - if (cla > cntclass.Size()) cla = cntclass.Size(); - cntclass.Elem(cla)++; - cnt++; - if (divisions) - cnti++; - else - cnto++; - if (cnt > 100000) - { - cnt = 0; - /* - (*testout) << "TestSeg-calls for classes:" << endl; - (*testout) << cnti << " inner calls, " << cnto << " outercalls" << endl; - (*testout) << "total testes segments: " << cntsegs << endl; - for (i = 1; i <= cntclass.Size(); i++) - { - (*testout) << int (exp (i * log(2.0))) << " bnd segs: " << cntclass.Get(i) << endl; - } - */ - } - } - - - int i,j,k; - Point<3> seg1p/*, seg2p*/; - Point<3> sp1,sp2; - double lambda1, lambda2, vlen2; - Vec<3> vptpl; - double sinchartangle2 = sqr(sinchartangle); - double scal; - int possible; - - double maxval = -1; - double maxvalnew = -1; - - - - double scalp1 = p1(0) * sn(0) + p1(1) * sn(1) + p1(2) * sn(2); - double scalp2 = p2(0) * sn(0) + p2(1) * sn(1) + p2(2) * sn(2); - double minl = min2(scalp1, scalp2); - double maxl = max2(scalp1, scalp2); - Point<3> c = Center (p1, p2); - double dist1 = Dist (c, p1); - - int nseg = NOSegments(); - for (j = 1; j <= nseg; j++) - { - const STLBoundarySeg & seg = GetSegment(j); - - - if (seg.IsSmoothEdge()) - continue; - - - sp1 = seg.P1(); - sp2 = seg.P2(); - - // Test, ob Spiral Konfikt moeglich - - possible = 1; - - double scalsp1 = sp1(0) * sn(0) + sp1(1) * sn(1) + sp1(2) * sn(2); - double scalsp2 = sp2(0) * sn(0) + sp2(1) * sn(1) + sp2(2) * sn(2); - - double minsl = min2(scalsp1, scalsp2); - double maxsl = max2(scalsp1, scalsp2); - - double maxdiff = max2 (maxsl - minl, maxl - minsl); - - /* - Point3d sc = Center (sp1, sp2); - double mindist = Dist(c, sc) - dist1 - GetSegment(j).Radius(); - if (maxdiff < sinchartangle * mindist) - { - possible = 0; - } - */ - - double hscal = maxdiff + sinchartangle * (dist1 + seg.Radius()); - if (hscal * hscal < sinchartangle * Dist2(c, seg.center )) - possible = 0; - - - /* - if (possible) - { - double mindist2ex = MinDistLL2 (p1, p2, sp1, sp2); - if (maxdiff * maxdiff < sinchartangle2 * mindist2ex) - possible = 0; - } - */ - - if (possible) - { - LinearPolynomial2V lp (scalp1 - scalsp1, - scalp2 - scalp1, - -(scalsp2 - scalsp1)); - QuadraticPolynomial2V slp; - slp.Square (lp); - - - Vec3d v (p1, sp1); - Vec3d vl (p1, p2); - Vec3d vsl (sp1, sp2); - - QuadraticPolynomial2V qp (v.Length2(), - -2 * (v * vl), - 2 * (v * vsl), - vl.Length2(), - -2 * (vl * vsl), - vsl.Length2()); - - slp.Add (-sinchartangle2, qp); - - double hv = slp.MaxUnitSquare(); - - if (hv > eps) return 0; - /* - if (hv > maxvalnew) - maxvalnew = hv; - */ - } - - - if (possible && 0) - - for (i = 0; i <= divisions; i++) - { - - lambda1 = (double)i/(double)divisions; - seg1p = Point3d(p1(0)*lambda1+p2(0)*(1.-lambda1), - p1(1)*lambda1+p2(1)*(1.-lambda1), - p1(2)*lambda1+p2(2)*(1.-lambda1)); - - - - for (k = 0; k <= divisions; k++) - { - lambda2 = (double)k/(double)divisions; - vptpl = Vec3d(sp1(0)*lambda2+sp2(0)*(1.-lambda2)-seg1p(0), - sp1(1)*lambda2+sp2(1)*(1.-lambda2)-seg1p(1), - sp1(2)*lambda2+sp2(2)*(1.-lambda2)-seg1p(2)); - - vlen2 = vptpl.Length2(); - - // if (vlen2 > 0) - { - scal = vptpl * sn; - double hv = scal*scal - sinchartangle2*vlen2; - - - - /* - if (hv > maxval) - maxval = hv; - */ - if (hv > eps) return 0; - } - } - } - } - - return 1; - // return (maxvalnew < eps); -} - - - -// checks, whether 2d projection intersects -int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2, - const Vec3d& sn) -{ - int i, j; - int nseg = NOSegments(); - - Point<2> p2d1 = chart->Project2d (p1); - Point<2> p2d2 = chart->Project2d (p2); - - Box<2> box2d; - box2d.Set (p2d1); - box2d.Add (p2d2); - /* - Point2d pmin(p2d1); - pmin.SetToMin (p2d2); - Point2d pmax(p2d1); - pmax.SetToMax (p2d2); - */ - - Line2d l1 (p2d1, p2d2); - - double lam1, lam2; - double eps = 1e-3; - - for (j = 1; j <= nseg; j++) - { - const STLBoundarySeg & seg = GetSegment(j); - - if (!box2d.Intersect (seg.BoundingBox())) - continue; - /* - if (seg.P2DMin()(0) > pmax(0)) continue; - if (seg.P2DMin()(1) > pmax(1)) continue; - if (seg.P2DMax()(0) < pmin(0)) continue; - if (seg.P2DMax()(1) < pmin(1)) continue; - */ - - if (seg.IsSmoothEdge()) continue; - - const Point<2> & sp1 = seg.P2D1(); - const Point<2> & sp2 = seg.P2D2(); - - - Line2d l2 (sp1, sp2); - - int err = - CrossPointBarycentric (l1, l2, lam1, lam2); - /* - if (chartdebug) - { - - (*testout) << "lam1 = " << lam1 << ", lam2 = " << lam2 << endl; - (*testout) << "p2d = " << p2d1 << ", " << p2d2 << endl; - (*testout) << "sp2d = " << sp1 << ", " << sp2 << endl; - (*testout) << "i1,2 = " << seg.I1() << ", " << seg.I2() << endl; - - } - */ - if (!err && lam1 > eps && lam1 < 1-eps && - lam2 > eps && lam2 < 1-eps) - return 0; - } - return 1; -} - - - -STLDoctorParams :: STLDoctorParams() -{ - drawmeshededges = 1; - geom_tol_fact = 1E-6; - longlinefact = 0; - showexcluded = 1; - - selectmode = 0; - edgeselectmode = 0; - useexternaledges = 0; - showfaces = 0; - showtouchedtrigchart = 1; - showedgecornerpoints = 1; - conecheck = 1; - spiralcheck = 1; - selecttrig = 0; - nodeofseltrig = 1; - selectwithmouse = 1; - showmarkedtrigs = 1; - dirtytrigfact = 0.001; - smoothangle = 90; - smoothnormalsweight = 0.2; - vicinity = 0; - showvicinity = 0; -} - - - -STLDoctorParams stldoctor; - -void STLDoctorParams :: Print (ostream & ost) const -{ - ost << "STL doctor parameters:" << endl - << "selecttrig = " << selecttrig << endl - << "selectlocalpoint = " << nodeofseltrig << endl - << "selectwithmouse = " << selectwithmouse << endl - << "showmarkedtrigs = " << showmarkedtrigs << endl - << "dirtytrigfact = " << dirtytrigfact << endl - << "smoothangle = " << smoothangle << endl; -} - - -STLParameters :: STLParameters() -{ - yangle = 30; - contyangle = 20; - edgecornerangle = 60; - chartangle = 15; - outerchartangle = 70; - - usesearchtree = 0; - atlasminh = 1E-4; - resthsurfcurvfac = 2; - resthsurfcurvenable = 0; - resthatlasfac = 2; - resthatlasenable = 1; - resthchartdistfac = 1.2; - resthchartdistenable = 1; - resthlinelengthfac = 0.5; - resthlinelengthenable = 1; - resthcloseedgefac = 1; - resthcloseedgeenable = 1; - resthedgeanglefac = 1; - resthedgeangleenable = 0; - resthsurfmeshcurvfac = 1; - resthsurfmeshcurvenable = 0; - recalc_h_opt = 1; -} - -void STLParameters :: Print (ostream & ost) const -{ - ost << "STL parameters:" << endl - << "yellow angle = " << yangle << endl - << "continued yellow angle = " << contyangle << endl - << "edgecornerangle = " << edgecornerangle << endl - << "chartangle = " << chartangle << endl - << "outerchartangle = " << outerchartangle << endl - << "restrict h due to ..., enable and safety factor: " << endl - << "surface curvature: " << resthsurfcurvenable - << ", fac = " << resthsurfcurvfac << endl - << "atlas surface curvature: " << resthatlasenable - << ", fac = " << resthatlasfac << endl - << "chart distance: " << resthchartdistenable - << ", fac = " << resthchartdistfac << endl - << "line length: " << resthlinelengthenable - << ", fac = " << resthlinelengthfac << endl - << "close edges: " << resthcloseedgeenable - << ", fac = " << resthcloseedgefac << endl - << "edge angle: " << resthedgeangleenable - << ", fac = " << resthedgeanglefac << endl; -} - - -STLParameters stlparam; - - -} diff --git a/Netgen/libsrc/stlgeom/stltool.hpp b/Netgen/libsrc/stlgeom/stltool.hpp deleted file mode 100644 index 278a7ce4ee..0000000000 --- a/Netgen/libsrc/stlgeom/stltool.hpp +++ /dev/null @@ -1,271 +0,0 @@ -#ifndef FILE_STLTOOL -#define FILE_STLTOOL - - -//#include "gprim/gprim.hh" - -/**************************************************************************/ -/* File: stlgeom.hh */ -/* Author: Joachim Schoeberl */ -/* Author2: Johannes Gerstmayr */ -/* Date: 20. Nov. 99 */ -/**************************************************************************/ - - - -// use one normal vector for whole chart -extern int usechartnormal; -extern int chartdebug; - -extern int geomsearchtreeon; -extern int AddPointIfNotExists(ARRAY<Point3d>& ap, const Point3d& p, double eps = 1e-8); -//get distance from line lp1-lp2 to point p -extern double GetDistFromLine(const Point<3>& lp1, const Point<3>& lp2, Point<3>& p); -extern double GetDistFromInfiniteLine(const Point<3>& lp1, const Point<3>& lp2, const Point<3>& p); - - -extern void FIOReadInt(istream& ios, int& i); -extern void FIOWriteInt(ostream& ios, const int& i); -extern void FIOReadDouble(istream& ios, double& i); -extern void FIOWriteDouble(ostream& ios, const double& i); -extern void FIOReadFloat(istream& ios, float& i); -extern void FIOWriteFloat(ostream& ios, const float& i); -extern void FIOReadString(istream& ios, char* str, int len); -extern void FIOReadStringE(istream& ios, char* str, int len); -extern void FIOWriteString(ostream& ios, char* str, int len); - - -typedef ARRAY <int> * ARRAYINTPTR; - -class STLGeometry; - -class STLChart -{ -private: - STLGeometry * geometry; - ARRAY<int>* charttrigs; // trigs which only belong to this chart - ARRAY<int>* outertrigs; // trigs which belong to other charts - Box3dTree * searchtree; // ADT containing outer trigs - - ARRAY<twoint>* olimit; //outer limit of outer chart - ARRAY<twoint>* ilimit; //outer limit of inner chart - - -public: - - STLChart(STLGeometry * ageometry); - void AddChartTrig(int i); - void AddOuterTrig(int i); - - int IsInWholeChart(int nr) const; - - int GetChartTrig(int i) const {return charttrigs->Get(i);} - int GetOuterTrig(int i) const {return outertrigs->Get(i);} - //get all trigs: - int GetTrig(int i) const - { - if (i <= charttrigs->Size()) {return charttrigs->Get(i);} - else {return outertrigs->Get(i-charttrigs->Size());} - } - - int GetNChartT() const {return charttrigs->Size();} - int GetNOuterT() const {return outertrigs->Size();} - int GetNT() const {return charttrigs->Size()+outertrigs->Size(); } - - void GetTrianglesInBox (const Point3d & pmin, - const Point3d & pmax, - ARRAY<int> & trias) const; - void AddOLimit(twoint l) {olimit->Append(l);} - void AddILimit(twoint l) {ilimit->Append(l);} - - void ClearOLimit() {olimit->SetSize(0);} - void ClearILimit() {ilimit->SetSize(0);} - - int GetNOLimit() const {return olimit->Size();} - int GetNILimit() const {return ilimit->Size();} - - twoint GetOLimit(int i) const {return olimit->Get(i);} - twoint GetILimit(int i) const {return ilimit->Get(i);} - - //move triangles trigs (local chart-trig numbers) to outer chart - void MoveToOuterChart(const ARRAY<int>& trigs); - void DelChartTrigs(const ARRAY<int>& trigs); - - - // define local coordinate system, JS: -private: - Vec<3> normal; - Point<3> pref; - Vec<3> t1, t2; -public: - void SetNormal (const Point<3> & apref, const Vec<3> & anormal); - const Vec<3> & GetNormal () const { return normal; } - Point<2> Project2d (const Point<3> & p3d) const; -}; - -class STLBoundarySeg -{ - Point<3> p1, p2, center; - Point<2> p2d1, p2d2; - Box<2> boundingbox; - // Point<2> p2dmin, p2dmax; - - double rad; - int i1, i2; - int smoothedge; -public: - STLBoundarySeg () { ; } - STLBoundarySeg (int ai1, int ai2, const ARRAY<Point<3> > & points, - const STLChart * achart); - - int operator== (const STLBoundarySeg & s2) const - { return i1 == s2.i1 && i2 == s2.i2; } - void Swap (); - int I1() const { return i1; } - int I2() const { return i2; } - const Point<3> & P1() const { return p1; } - const Point<3> & P2() const { return p2; } - const Point<2> & P2D1() const { return p2d1; } - const Point<2> & P2D2() const { return p2d2; } - const Point<2> & P2DMin() const { return boundingbox.PMin(); } - const Point<2> & P2DMax() const { return boundingbox.PMax(); } - const Point<3> & Center() const { return center; } - const Box<2> & BoundingBox() const { return boundingbox; } - double Radius () const { return rad; } - - void SetSmoothEdge (int se) { smoothedge = se; } - int IsSmoothEdge () const { return smoothedge; } - friend class STLBoundary; -}; - -class STLBoundary -{ -private: - STLGeometry * geometry; - const STLChart * chart; - ARRAY<STLBoundarySeg> boundary; -public: - STLBoundary(STLGeometry * ageometry); - // : boundary() {}; - - void Clear() {boundary.SetSize(0);}; - void SetChart (const STLChart * achart) { chart = achart; } - //don't check, if already exists! - void AddNewSegment(const STLBoundarySeg & seg) {boundary.Append(seg);}; - //check if segment exists - void AddOrDelSegment(const STLBoundarySeg & seg); - //addordelsegment for all 3 triangle segments! - void AddTriangle(const STLTriangle & t); - int NOSegments() {return boundary.Size();}; - const STLBoundarySeg & GetSegment(int i) {return boundary.Get(i);} - - int TestSeg(const Point<3> & p1, const Point<3> & p2, const Vec<3> & sn, - double sinchartangle, int divisions, ARRAY<Point<3> >& points, - double eps); - - int TestSegChartNV(const Point3d& p1, const Point3d& p2, const Vec3d& sn); -}; - - -class STLDoctorParams -{ -public: - int drawmeshededges; - double geom_tol_fact; - - double longlinefact; - int showexcluded; - - int selectmode; //0==trig, 1==edge, 2==point, 3==multiedge, 4==line cluster - int edgeselectmode; - - int useexternaledges; - int showfaces; - int showedgecornerpoints; - int showtouchedtrigchart; - int conecheck; - int spiralcheck; - int selecttrig; - int nodeofseltrig; - int selectwithmouse; - int showmarkedtrigs; - double dirtytrigfact; - double smoothangle; - - double smoothnormalsweight; - - int showvicinity; - int vicinity; - /// - STLDoctorParams(); - /// - void Print (ostream & ost) const; -}; - -extern STLDoctorParams stldoctor; - - - -class STLParameters -{ -public: - /// angle for edge detection - double yangle; - double contyangle; //edges continued with contyangle - /// angle of geometry edge at which the mesher should set a point - double edgecornerangle; - /// angle inside on chart - double chartangle; - /// angle for overlapping parts of char - double outerchartangle; - /// 0 .. no, 1 .. local, (2 .. global) - int usesearchtree; - /// - double resthatlasfac; - int resthatlasenable; - double atlasminh; - - double resthsurfcurvfac; - int resthsurfcurvenable; - - double resthchartdistfac; - int resthchartdistenable; - - double resthcloseedgefac; - int resthcloseedgeenable; - - double resthedgeanglefac; - int resthedgeangleenable; - - double resthsurfmeshcurvfac; - int resthsurfmeshcurvenable; - - double resthlinelengthfac; - int resthlinelengthenable; - - /// - int recalc_h_opt; - /// - STLParameters(); - /// - void Print (ostream & ost) const; -}; - -extern STLParameters stlparam; - - -void STLMeshing (STLGeometry & geom, - class Mesh & mesh); - - -int STLSurfaceMeshing (STLGeometry & geom, - class Mesh & mesh); - -void STLSurfaceOptimization (STLGeometry & geom, - class Mesh & mesh, - class MeshingParameters & mparam); - - - - -#endif diff --git a/Netgen/libsrc/stlgeom/stltopology.cpp b/Netgen/libsrc/stlgeom/stltopology.cpp deleted file mode 100644 index 1d5315fbec..0000000000 --- a/Netgen/libsrc/stlgeom/stltopology.cpp +++ /dev/null @@ -1,1067 +0,0 @@ -#include <mystdlib.h> - -#include <myadt.hpp> -#include <linalg.hpp> -#include <gprim.hpp> - -#include <meshing.hpp> - -#include "stlgeom.hpp" - -namespace netgen -{ - - -STLTopology :: STLTopology() - : trias(), topedges(), points(), ht_topedges(NULL), - neighbourtrigs(), trigsperpoint() -{ - ; -} - -STLTopology :: ~STLTopology() -{ - ; -} - - - - -STLGeometry * STLTopology :: LoadBinary (istream & ist) -{ - STLGeometry * geom = new STLGeometry(); - ARRAY<STLReadTriangle> readtrigs; - - PrintMessage(1,"Read STL binary file"); - - if (sizeof(int) != 4 || sizeof(float) != 4) - { - PrintWarning("for stl-binary compatibility only use 32 bit compilation!!!"); - } - - //specific settings for stl-binary format - const int namelen = 80; //length of name of header in file - const int nospaces = 2; //number of spaces after a triangle - - //read header: name - char buf[namelen+1]; - FIOReadStringE(ist,buf,namelen); - PrintMessage(5,"header = ",buf); - - //Read Number of facets - int nofacets; - FIOReadInt(ist,nofacets); - PrintMessage(5,"NO facets = ",nofacets); - - Point<3> pts[3]; - Vec<3> normal; - - int cntface, j; - int vertex = 0; - float f; - char spaces[nospaces+1]; - - for (cntface = 0; cntface < nofacets; cntface++) - { - if (cntface % 10000 == 9999) { PrintDot(); } - - FIOReadFloat(ist,f); normal(0) = f; - FIOReadFloat(ist,f); normal(1) = f; - FIOReadFloat(ist,f); normal(2) = f; - - for (j = 0; j < 3; j++) - { - FIOReadFloat(ist,f); pts[j](0) = f; - FIOReadFloat(ist,f); pts[j](1) = f; - FIOReadFloat(ist,f); pts[j](2) = f; - } - - readtrigs.Append (STLReadTriangle (pts, normal)); - FIOReadString(ist,spaces,nospaces); - } - - - geom->InitSTLGeometry(readtrigs); - - return geom; -} - - -void STLTopology :: SaveBinary (const char* filename, const char* aname) -{ - ofstream ost(filename); - PrintFnStart("Write STL binary file '",filename,"'"); - - if (sizeof(int) != 4 || sizeof(float) != 4) - {PrintWarning("for stl-binary compatibility only use 32 bit compilation!!!");} - - //specific settings for stl-binary format - const int namelen = 80; //length of name of header in file - const int nospaces = 2; //number of spaces after a triangle - - //write header: aname - int i, j; - char buf[namelen+1]; - int strend = 0; - for(i = 0; i <= namelen; i++) - { - if (aname[i] == 0) {strend = 1;} - if (!strend) {buf[i] = aname[i];} - else {buf[i] = 0;} - } - - FIOWriteString(ost,buf,namelen); - PrintMessage(5,"header = ",buf); - - //RWrite Number of facets - int nofacets = GetNT(); - FIOWriteInt(ost,nofacets); - PrintMessage(5,"NO facets = ", nofacets); - - float f; - char spaces[nospaces+1]; - for (i = 0; i < nospaces; i++) {spaces[i] = ' ';} - spaces[nospaces] = 0; - - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & t = GetTriangle(i); - - const Vec<3> & n = t.Normal(); - f = n(0); FIOWriteFloat(ost,f); - f = n(1); FIOWriteFloat(ost,f); - f = n(2); FIOWriteFloat(ost,f); - - for (j = 1; j <= 3; j++) - { - const Point3d p = GetPoint(t.PNum(j)); - - f = p.X(); FIOWriteFloat(ost,f); - f = p.Y(); FIOWriteFloat(ost,f); - f = p.Z(); FIOWriteFloat(ost,f); - } - FIOWriteString(ost,spaces,nospaces); - } - PrintMessage(5,"done"); -} - - -void STLTopology :: SaveSTLE (const char* filename) -{ - ofstream outf (filename); - int i, j; - - outf << GetNT() << endl; - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & t = GetTriangle(i); - for (j = 1; j <= 3; j++) - { - const Point3d p = GetPoint(t.PNum(j)); - outf << p.X() << " " << p.Y() << " " << p.Z() << endl; - } - } - - - int ned = 0; - for (i = 1; i <= GetNTE(); i++) - { - if (GetTopEdge (i).GetStatus() == ED_CONFIRMED) - ned++; - } - - outf << ned << endl; - - for (i = 1; i <= GetNTE(); i++) - { - const STLTopEdge & edge = GetTopEdge (i); - if (edge.GetStatus() == ED_CONFIRMED) - for (j = 1; j <= 2; j++) - { - const Point3d p = GetPoint(edge.PNum(j)); - outf << p.X() << " " << p.Y() << " " << p.Z() << endl; - } - } -} - - - -STLGeometry * STLTopology :: LoadNaomi (istream & ist) -{ - int i; - STLGeometry * geom = new STLGeometry(); - ARRAY<STLReadTriangle> readtrigs; - - PrintFnStart("read NAOMI file format"); - - char buf[100]; - Vec<3> normal; - - int cntface = 0; - int cntvertex = 0; - double px, py, pz; - - - int noface, novertex; - ARRAY<Point<3> > readpoints; - - ist >> buf; - if (strcmp (buf, "NODES") == 0) - { - ist >> novertex; - PrintMessage(5,"nuber of vertices = ", novertex); - for (i = 0; i < novertex; i++) - { - ist >> px; - ist >> py; - ist >> pz; - readpoints.Append(Point<3> (px,py,pz)); - } - } - else - { - PrintFileError("no node information"); - } - - - ist >> buf; - if (strcmp (buf, "2D_EDGES") == 0) - { - ist >> noface; - PrintMessage(5,"number of faces=",noface); - int dummy, p1, p2, p3; - Point<3> pts[3]; - - for (i = 0; i < noface; i++) - { - ist >> dummy; //2 - ist >> dummy; //1 - ist >> p1; - ist >> p2; - ist >> p3; - ist >> dummy; //0 - - pts[0] = readpoints.Get(p1); - pts[1] = readpoints.Get(p2); - pts[2] = readpoints.Get(p3); - - normal = Cross (pts[1]-pts[0], pts[2]-pts[0]) . Normalize(); - - readtrigs.Append (STLReadTriangle (pts, normal)); - - } - PrintMessage(5,"read ", readtrigs.Size(), " triangles"); - } - else - { - PrintMessage(5,"read='",buf,"'\n"); - PrintFileError("ERROR: no Triangle information"); - } - - geom->InitSTLGeometry(readtrigs); - - return geom; -} - -void STLTopology :: Save (const char* filename) -{ - PrintFnStart("Write stl-file '",filename, "'"); - - ofstream fout(filename); - fout << "solid\n"; - - char buf1[50]; - char buf2[50]; - char buf3[50]; - - int i, j; - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & t = GetTriangle(i); - - fout << "facet normal "; - const Vec3d& n = GetTriangle(i).Normal(); - - sprintf(buf1,"%1.9g",n.X()); - sprintf(buf2,"%1.9g",n.Y()); - sprintf(buf3,"%1.9g",n.Z()); - - fout << buf1 << " " << buf2 << " " << buf3 << "\n"; - fout << "outer loop\n"; - - for (j = 1; j <= 3; j++) - { - const Point3d p = GetPoint(t.PNum(j)); - - sprintf(buf1,"%1.9g",p.X()); - sprintf(buf2,"%1.9g",p.Y()); - sprintf(buf3,"%1.9g",p.Z()); - - fout << "vertex " << buf1 << " " << buf2 << " " << buf3 << "\n"; - } - - fout << "endloop\n"; - fout << "endfacet\n"; - } - fout << "endsolid\n"; - - - // write also NETGEN surface mesh: - ofstream fout2("geom.surf"); - fout2 << "surfacemesh" << endl; - fout2 << GetNP() << endl; - for (i = 1; i <= GetNP(); i++) - { - for (j = 0; j < 3; j++) - { - fout2.width(8); - fout2 << GetPoint(i)(j); - } - - fout2 << endl; - } - - fout2 << GetNT() << endl; - for (i = 1; i <= GetNT(); i++) - { - const STLTriangle & t = GetTriangle(i); - for (j = 1; j <= 3; j++) - { - fout2.width(8); - fout2 << t.PNum(j); - } - fout2 << endl; - } -} - - -STLGeometry * STLTopology ::Load (istream & ist) -{ - int i; - STLGeometry * geom = new STLGeometry(); - - ARRAY<STLReadTriangle> readtrigs; - - char buf[100]; - Point<3> pts[3]; - Vec<3> normal; - - int cntface = 0; - int vertex = 0; - bool badnormals = 0; - - while (ist.good()) - { - ist >> buf; - - int n = strlen (buf); - for (i = 0; i < n; i++) - buf[i] = tolower (buf[i]); - - if (strcmp (buf, "facet") == 0) - { - cntface++; - } - - if (strcmp (buf, "normal") == 0) - { - ist >> normal(0) - >> normal(1) - >> normal(2); - normal.Normalize(); - } - - if (strcmp (buf, "vertex") == 0) - { - ist >> pts[vertex](0) - >> pts[vertex](1) - >> pts[vertex](2); - - vertex++; - - if (vertex == 3) - { - if (normal.Length() <= 1e-5) - - { - normal = Cross (pts[1]-pts[0], pts[2]-pts[0]); - normal.Normalize(); - } - - else - - { - Vec<3> hnormal; - hnormal = Cross (pts[1]-pts[0], pts[2]-pts[0]); - hnormal.Normalize(); - - if (normal * hnormal < 0.5) - { - badnormals = 1; - } - } - - vertex = 0; - - if ( (Dist2 (pts[0], pts[1]) > 1e-16) && - (Dist2 (pts[0], pts[2]) > 1e-16) && - (Dist2 (pts[1], pts[2]) > 1e-16) ) - - readtrigs.Append (STLReadTriangle (pts, normal)); - } - } - } - - if (badnormals) - { - PrintWarning("File has normal vectors which differ extremly from geometry->correct with stldoctor!!!"); - } - - geom->InitSTLGeometry(readtrigs); - return geom; -} - - - - - - - - - - - - - -void STLTopology :: InitSTLGeometry(const ARRAY<STLReadTriangle> & readtrigs) -{ - int i, j, k; - - // const double geometry_tol_fact = 1E6; - // distances lower than max_box_size/tol are ignored - - trias.SetSize(0); - points.SetSize(0); - - PrintMessage(3,"number of triangles = ", readtrigs.Size()); - - if (!readtrigs.Size()) - return; - - - boundingbox.Set (readtrigs[0][0]); - for (i = 0; i < readtrigs.Size(); i++) - for (k = 0; k < 3; k++) - boundingbox.Add (readtrigs[i][k]); - - PrintMessage(5,"boundingbox: ", Point3d(boundingbox.PMin()), " - ", - Point3d(boundingbox.PMax())); - - Box<3> bb = boundingbox; - bb.Increase (1); - - pointtree = new Point3dTree (bb.PMin(), bb.PMax()); - - - - ARRAY<int> pintersect; - - pointtol = boundingbox.Diam() * stldoctor.geom_tol_fact; - PrintMessage(5,"point tolerance = ", pointtol); - - for(i = 0; i < readtrigs.Size(); i++) - { - const STLReadTriangle & t = readtrigs[i]; - STLTriangle st; - Vec<3> n = t.Normal(); - st.SetNormal (t.Normal()); - - for (k = 0; k < 3; k++) - { - Point<3> p = t[k]; - - Point<3> pmin = p - Vec<3> (pointtol, pointtol, pointtol); - Point<3> pmax = p + Vec<3> (pointtol, pointtol, pointtol); - - pointtree->GetIntersecting (pmin, pmax, pintersect); - - if (pintersect.Size() > 1) - PrintError("too many close points"); - int foundpos = -1; - if (pintersect.Size()) - foundpos = pintersect[0]; - - if (foundpos == -1) - { - foundpos = AddPoint(p); - pointtree->Insert (p, foundpos); - } - st[k] = foundpos; - } - - if ( (st[0] == st[1]) || - (st[0] == st[2]) || - (st[1] == st[2]) ) - { - PrintError("STL Triangle degenerated"); - } - else - { - AddTriangle(st); - } - - } - - FindNeighbourTrigs(); -} - - - - -int STLTopology :: GetPointNum (const Point<3> & p) -{ - Point<3> pmin = p - Vec<3> (pointtol, pointtol, pointtol); - Point<3> pmax = p + Vec<3> (pointtol, pointtol, pointtol); - - ARRAY<int> pintersect; - - pointtree->GetIntersecting (pmin, pmax, pintersect); - if (pintersect.Size() == 1) - return pintersect[0]; - else - return 0; -} - - - -void STLTopology :: FindNeighbourTrigs() -{ - // if (topedges.Size()) return; - - PushStatusF("Find Neighbour Triangles"); - - int i, j, k, l; - - // build up topology tables - - int np = GetNP(); - int nt = GetNT(); - - INDEX_2_HASHTABLE<int> * oldedges = ht_topedges; - ht_topedges = new INDEX_2_HASHTABLE<int> (GetNP()+1); - topedges.SetSize(0); - - for (i = 1; i <= nt; i++) - { - STLTriangle & trig = GetTriangle(i); - - - for (j = 1; j <= 3; j++) - { - int pi1 = trig.PNumMod (j+1); - int pi2 = trig.PNumMod (j+2); - - INDEX_2 i2(pi1, pi2); - i2.Sort(); - - int enr; - int othertn; - - if (ht_topedges->Used(i2)) - { - enr = ht_topedges->Get(i2); - topedges.Elem(enr).TrigNum(2) = i; - - othertn = topedges.Get(enr).TrigNum(1); - STLTriangle & othertrig = GetTriangle(othertn); - - trig.NBTrigNum(j) = othertn; - trig.EdgeNum(j) = enr; - for (k = 1; k <= 3; k++) - if (othertrig.EdgeNum(k) == enr) - othertrig.NBTrigNum(k) = i; - } - else - { - enr = topedges.Append (STLTopEdge (pi1, pi2, i, 0)); - ht_topedges->Set (i2, enr); - trig.EdgeNum(j) = enr; - } - } - } - - - PrintMessage(5,"topology built, checking"); - - topology_ok = 1; - int ne = GetNTE(); - - for (i = 1; i <= nt; i++) - GetTriangle(i).flags.toperror = 0; - - for (i = 1; i <= nt; i++) - for (j = 1; j <= 3; j++) - { - const STLTopEdge & edge = GetTopEdge (GetTriangle(i).EdgeNum(j)); - if (edge.TrigNum(1) != i && edge.TrigNum(2) != i) - { - topology_ok = 0; - GetTriangle(i).flags.toperror = 1; - } - } - - for (i = 1; i <= ne; i++) - { - const STLTopEdge & edge = GetTopEdge (i); - if (!edge.TrigNum(2)) - { - topology_ok = 0; - GetTriangle(edge.TrigNum(1)).flags.toperror = 1; - } - } - - if (topology_ok) - { - orientation_ok = 1; - for (i = 1; i <= nt; i++) - { - const STLTriangle & t = GetTriangle (i); - for (j = 1; j <= 3; j++) - { - const STLTriangle & nbt = GetTriangle (t.NBTrigNum(j)); - if (!t.IsNeighbourFrom (nbt)) - orientation_ok = 0; - } - } - } - else - orientation_ok = 0; - - - - status = STL_GOOD; - statustext = ""; - if (!topology_ok || !orientation_ok) - { - status = STL_ERROR; - if (!topology_ok) - statustext = "Topology not ok"; - else - statustext = "Orientation not ok"; - } - - - PrintMessage(3,"topology_ok = ",topology_ok); - PrintMessage(3,"orientation_ok = ",orientation_ok); - PrintMessage(3,"topology found"); - - // generate point -> trig table - - trigsperpoint.SetSize(GetNP()); - for (i = 1; i <= GetNT(); i++) - for (j = 1; j <= 3; j++) - trigsperpoint.Add1(GetTriangle(i).PNum(j),i); - - - //check trigs per point: - /* - for (i = 1; i <= GetNP(); i++) - { - if (trigsperpoint.EntrySize(i) < 3) - { - (*testout) << "ERROR: Point " << i << " has " << trigsperpoint.EntrySize(i) << " triangles!!!" << endl; - } - } - */ - topedgesperpoint.SetSize (GetNP()); - for (i = 1; i <= ne; i++) - for (j = 1; j <= 2; j++) - topedgesperpoint.Add1 (GetTopEdge (i).PNum(j), i); - - PrintMessage(5,"point -> trig table generated"); - - - - // transfer edge data: - // .. to be done - delete oldedges; - - - - for (STLTrigIndex ti = 0; ti < GetNT(); ti++) - { - STLTriangle & trig = trias[ti]; - for (k = 0; k < 3; k++) - { - STLPointIndex pi = trig[k] - STLBASE; - STLPointIndex pi2 = trig[(k+1)%3] - STLBASE; - STLPointIndex pi3 = trig[(k+2)%3] - STLBASE; - - // vector along edge - Vec<3> ve = points[pi2] - points[pi]; - ve.Normalize(); - - // vector along third point - Vec<3> vt = points[pi3] - points[pi]; - vt -= (vt * ve) * ve; - vt.Normalize(); - - Vec<3> vn = trig.GeomNormal (points); - vn.Normalize(); - - double phimin = 10, phimax = -1; // out of (0, 2 pi) - - for (j = 0; j < trigsperpoint[pi].Size(); j++) - { - STLTrigIndex ti2 = trigsperpoint[pi][j] - STLBASE; - const STLTriangle & trig2 = trias[ti2]; - - if (ti == ti2) continue; - - bool hasboth = 0; - for (l = 0; l < 3; l++) - if (trig2[l] - STLBASE == pi2) - { - hasboth = 1; - break; - } - if (!hasboth) continue; - - STLPointIndex pi4; - for (l = 0; l < 3; l++) - if (trig2[l] - STLBASE != pi && trig2[l] - STLBASE != pi2) - pi4 = trig2[l] - STLBASE; - - Vec<3> vt2 = points[pi4] - points[pi]; - - double phi = atan2 (vt2 * vn, vt2 * vt); - if (phi < 0) phi += 2 * M_PI; - - if (phi < phimin) - { - phimin = phi; - trig.NBTrig (0, (k+2)%3) = ti2 + STLBASE; - } - if (phi > phimax) - { - phimax = phi; - trig.NBTrig (1, (k+2)%3) = ti2 + STLBASE; - } - } - } - } - - - - - if (status == STL_GOOD) - { - // for compatibility: - neighbourtrigs.SetSize(GetNT()); - for (i = 1; i <= GetNT(); i++) - for (k = 1; k <= 3; k++) - AddNeighbourTrig (i, GetTriangle(i).NBTrigNum(k)); - } - else - { - // assemble neighbourtrigs (should be done only for illegal topology): - - neighbourtrigs.SetSize(GetNT()); - - int tr, found; - int wrongneighbourfound = 0; - for (i = 1; i <= GetNT(); i++) - { - SetThreadPercent((double)i/(double)GetNT()*100.); - if (multithread.terminate) - { - PopStatus(); - return; - } - - for (k = 1; k <= 3; k++) - { - for (j = 1; j <= trigsperpoint.EntrySize(GetTriangle(i).PNum(k)); j++) - { - tr = trigsperpoint.Get(GetTriangle(i).PNum(k),j); - if (i != tr && (GetTriangle(i).IsNeighbourFrom(GetTriangle(tr)) - || GetTriangle(i).IsWrongNeighbourFrom(GetTriangle(tr)))) - { - if (GetTriangle(i).IsWrongNeighbourFrom(GetTriangle(tr))) - { - /*(*testout) << "ERROR: triangle " << i << " has a wrong neighbour triangle!!!" << endl;*/ - wrongneighbourfound ++; - } - - found = 0; - for (int ii = 1; ii <= NONeighbourTrigs(i); ii++) - {if (NeighbourTrig(i,ii) == tr) {found = 1;break;};} - if (! found) {AddNeighbourTrig(i,tr);} - } - } - } - if (NONeighbourTrigs(i) != 3) - { - PrintError("TRIG ",i," has ",NONeighbourTrigs(i)," neighbours!!!!"); - for (int kk=1; kk <= NONeighbourTrigs(i); kk++) - { - PrintMessage(5,"neighbour-trig",kk," = ",NeighbourTrig(i,kk)); - } - }; - } - if (wrongneighbourfound) - { - PrintError("++++++++++++++++++++\n"); - PrintError(wrongneighbourfound, " wrong oriented neighbourtriangles found!"); - PrintError("try to correct it (with stldoctor)!"); - PrintError("++++++++++++++++++++\n"); - - status = STL_ERROR; - statustext = "STL Mesh not consistent"; - - multithread.terminate = 1; -#ifdef STAT_STREAM - (*statout) << "non-conform stl geometry \\hline" << endl; -#endif - } - } - - TopologyChanged(); - - PopStatus(); -} - - - - - - - -void STLTopology :: GetTrianglesInBox (/* - const Point<3> & pmin, - const Point<3> & pmax, - */ - const Box<3> & box, - ARRAY<int> & trias) const -{ - if (searchtree) - - searchtree -> GetIntersecting (box.PMin(), box.PMax(), trias); - - else - { - int i; - Box<3> box1 = box; - box1.Increase (1e-4); - - trias.SetSize(0); - - int nt = GetNT(); - for (i = 1; i <= nt; i++) - { - if (box1.Intersect (GetTriangle(i).box)) - { - trias.Append (i); - } - } - } -} - - - -void STLTopology :: AddTriangle(const STLTriangle& t) -{ - trias.Append(t); - - const Point<3> & p1 = GetPoint (t.PNum(1)); - const Point<3> & p2 = GetPoint (t.PNum(2)); - const Point<3> & p3 = GetPoint (t.PNum(3)); - - Box<3> box; - box.Set (p1); - box.Add (p2); - box.Add (p3); - /* - // Point<3> pmin(p1), pmax(p1); - pmin.SetToMin (p2); - pmin.SetToMin (p3); - pmax.SetToMax (p2); - pmax.SetToMax (p3); - */ - - trias.Last().box = box; - trias.Last().center = Center (p1, p2, p3); - double r1 = Dist (p1, trias.Last().center); - double r2 = Dist (p2, trias.Last().center); - double r3 = Dist (p3, trias.Last().center); - trias.Last().rad = max2 (max2 (r1, r2), r3); - - if (geomsearchtreeon) - {searchtree->Insert (box.PMin(), box.PMax(), trias.Size());} -} - - - - -int STLTopology :: GetLeftTrig(int p1, int p2) const -{ - int i; - for (i = 1; i <= trigsperpoint.EntrySize(p1); i++) - { - if (GetTriangle(trigsperpoint.Get(p1,i)).HasEdge(p1,p2)) {return trigsperpoint.Get(p1,i);} - } - PrintSysError("ERROR in GetLeftTrig !!!"); - - return 0; -} - -int STLTopology :: GetRightTrig(int p1, int p2) const -{ - return GetLeftTrig(p2,p1); -} - - -int STLTopology :: NeighbourTrigSorted(int trig, int edgenum) const -{ - int i, p1, p2; - int psearch = GetTriangle(trig).PNum(edgenum); - - for (i = 1; i <= 3; i++) - { - GetTriangle(trig).GetNeighbourPoints(GetTriangle(NeighbourTrig(trig,i)),p1,p2); - if (p1 == psearch) {return NeighbourTrig(trig,i);} - } - - PrintSysError("ERROR in NeighbourTrigSorted"); - return 0; -} - - - - - - -int STLTopology :: GetTopEdgeNum (int pi1, int pi2) const -{ - if (!ht_topedges) return 0; - - INDEX_2 i2(pi1, pi2); - i2.Sort(); - - if (!ht_topedges->Used(i2)) return 0; - return ht_topedges->Get(i2); -} - - - - -void STLTopology :: InvertTrig (int trig) -{ - if (trig >= 1 && trig <= GetNT()) - { - GetTriangle(trig).ChangeOrientation(); - FindNeighbourTrigs(); - } - else - { - PrintUserError("no triangle selected!"); - } -} - - - - -void STLTopology :: DeleteTrig (int trig) -{ - if (trig >= 1 && trig <= GetNT()) - { - trias.DeleteElement(trig); - FindNeighbourTrigs(); - } - else - { - PrintUserError("no triangle selected!"); - } -} - - - -void STLTopology :: OrientAfterTrig (int trig) -{ - int starttrig = trig; - - if (starttrig >= 1 && starttrig <= GetNT()) - { - - ARRAY <int> oriented; - oriented.SetSize(GetNT()); - int i; - for (i = 1; i <= oriented.Size(); i++) - { - oriented.Elem(i) = 0; - } - - oriented.Elem(starttrig) = 1; - - int j = 0,k; - - ARRAY <int> list1; - list1.SetSize(0); - ARRAY <int> list2; - list2.SetSize(0); - list1.Append(starttrig); - - int cnt = 1; - int end = 0; - int nt; - while (!end) - { - end = 1; - for (i = 1; i <= list1.Size(); i++) - { - const STLTriangle& tt = GetTriangle(list1.Get(i)); - for (k = 1; k <= 3; k++) - { - nt = tt.NBTrigNum (k); // NeighbourTrig(list1.Get(i),k); - if (oriented.Get(nt) == 0) - { - if (tt.IsWrongNeighbourFrom(GetTriangle(nt))) - { - GetTriangle(nt).ChangeOrientation(); - } - oriented.Elem(nt) = 1; - list2.Append(nt); - cnt++; - end = 0; - } - } - } - list1.SetSize(0); - for (i = 1; i <= list2.Size(); i++) - { - list1.Append(list2.Get(i)); - } - list2.SetSize(0); - } - - PrintMessage(5,"NO corrected triangles = ",cnt); - if (cnt == GetNT()) - { - PrintMessage(5,"ALL triangles oriented in same way!"); - } - else - { - PrintWarning("NOT ALL triangles oriented in same way!"); - } - - // topedges.SetSize(0); - FindNeighbourTrigs(); - } - else - { - PrintUserError("no triangle selected!"); - } -} - - -} diff --git a/Netgen/libsrc/stlgeom/stltopology.hpp b/Netgen/libsrc/stlgeom/stltopology.hpp deleted file mode 100644 index 80e5a68178..0000000000 --- a/Netgen/libsrc/stlgeom/stltopology.hpp +++ /dev/null @@ -1,362 +0,0 @@ -#ifndef FILE_STLTOPOLOGY -#define FILE_STLTOPOLOGY - -/**************************************************************************/ -/* File: stltopology.hpp */ -/* Author: Joachim Schoeberl */ -/* Author2: Johannes Gerstmayr */ -/* Date: 26. Jul. 99 */ -/**************************************************************************/ - -/* - The STLTopology contains topologic information as - triangle->point, point->triangles, triangle->edge, 2-points->edge,... -*/ - - -class STLGeometry; - -#define STLBASE 1 - -class STLPointIndex -{ - int i; -public: - STLPointIndex () { ; } - STLPointIndex (int ai) : i(ai) { ; } - STLPointIndex & operator= (const STLPointIndex & ai) { i = ai.i; return *this; } - STLPointIndex & operator= (int ai) { i = ai; return *this; } - operator int () const { return i; } - STLPointIndex operator++ (int) { return i++; } - STLPointIndex operator-- (int) { return i--; } -}; - - - -class STLTrigIndex -{ - int i; -public: - STLTrigIndex () { ; } - STLTrigIndex (int ai) : i(ai) { ; } - STLTrigIndex & operator= (const STLTrigIndex & ai) { i = ai.i; return *this; } - STLTrigIndex & operator= (int ai) { i = ai; return *this; } - operator int () const { return i; } - STLTrigIndex operator++ (int) { return i++; } - STLTrigIndex operator-- (int) { return i--; } -}; - - - - - -// triangle structure for loading stl files -class STLReadTriangle -{ - Vec<3> normal; - Point<3> pts[3]; -public: - STLReadTriangle (const Point<3> * apts, const Vec<3> & anormal); - STLReadTriangle () {}; - const Point<3> & operator[] (int i) const { return pts[i]; } - const Vec<3> & Normal() const { return normal; } -}; - - - -class STLTriangle -{ - // topology edges of triangle, edge[i] opposite to point[i] - int topedges[3]; - // neighbour triangles, trig[i] opposite to point[i] - int nbtrigs[2][3]; - // normalized stored normal vector ?? - Vec<3> normal; - // point numbers of triangle - int pts[3]; - // front-side and back-side domains - int domains[2]; - - -public: - - Box<3> box; - Point<3> center; - double rad; - int facenum; - - struct - { - unsigned int toperror : 1; - } flags; - - - - - STLTriangle (const int * apts); - STLTriangle () {pts[0]=0;pts[1]=0;pts[2]=0;} - - int operator[] (int i) const { return pts[i]; } - int & operator[] (int i) { return pts[i]; } - - int EdgeNum(int i) const { return topedges[(i-1)]; } - int & EdgeNum(int i) { return topedges[(i-1)]; } - - int NBTrig (bool side, int i) const { return nbtrigs[side][i]; } - int & NBTrig (bool side, int i) { return nbtrigs[side][i]; } - - - int Domain (bool side) const { return domains[side]; } - int & Domain (bool side) { return domains[side]; } - - - - // obsolete: - int PNum(int i) const { return pts[(i-1)]; } - int & PNum(int i) { return pts[(i-1)]; } - int PNumMod(int i) const { return pts[(i-1)%3]; } - int & PNumMod(int i) { return pts[(i-1)%3]; } - - int EdgeNumMod(int i) const { return topedges[(i-1)%3]; } - int & EdgeNumMod(int i) { return topedges[(i-1)%3]; } - - int NBTrigNum(int i) const { return nbtrigs[0][(i-1)]; } - int & NBTrigNum(int i) { return nbtrigs[0][(i-1)]; } - int NBTrigNumMod(int i) const { return nbtrigs[0][(i-1)%3]; } - int & NBTrigNumMod(int i) { return nbtrigs[0][(i-1)%3]; } - - - // consistently oriented neighbour: - int IsNeighbourFrom(const STLTriangle& t) const; - // opposite to consistently oriented neighbour: - int IsWrongNeighbourFrom(const STLTriangle& t) const; - - ///Get the two points of neighbour-Triangles in orientation of this-Triangle - void GetNeighbourPoints(const STLTriangle& t, int& p1, int& p2) const; - int GetNeighbourPointsAndOpposite(const STLTriangle& t, int& p1, int& p2, int& po) const; - - - - // NON-normalized geometry - normal vector - Vec<3> GeomNormal(const ARRAY<Point<3> >& ap) const; - - // Stored normal vector, normalized - void SetNormal (const Vec<3> & n); - const Vec<3> & Normal () const { return normal; } - - - void ChangeOrientation(); - - //project with a certain normal vector in plane - void ProjectInPlain(const ARRAY<Point<3> >& ap, - const Vec<3> & n, Point<3> & pp) const; - //project with the triangle's normal vector in plane - void ProjectInPlain(const ARRAY<Point<3> > & ap, Point<3> & pp) const; - - - /* - Project the point pp along the nproj into the plane of - the triangle. The triangle normal is given by ntrig to - avoid numerical instabilities. - The local coordinates lam are defined by - - pp(input) = P1 + lam1 v1 + lam2 v2 + lam3 n - - the result is - - pp(output) = P1 + lam1 v1 + lam2 v2 - */ - int ProjectInPlain (const ARRAY<Point<3> >& ap, - const Vec<3> & nproj, - Point<3> & pp, Vec<3> & lam) const; - - int PointInside(const ARRAY<Point<3> >& ap, const Point<3> & pp) const; - - //get nearest point on triangle and distance to it - double GetNearestPoint(const ARRAY<Point<3> >& ap, - Point<3> & p3d) const; - - double Area(const ARRAY<Point<3> >& ap) const; - - double MinHeight(const ARRAY<Point<3> >& ap) const; - double MaxLength(const ARRAY<Point<3> >& ap) const; - //max length of a side of triangle - - int GetFaceNum() {return facenum;} - void SetFaceNum(int i) {facenum = i;} - - int HasEdge(int p1, int p2) const; -}; - - -/** - Topology Edge: - Useful unside a face. - A edges sharing more than 2 faces: trigs are undefined - */ -class STLTopEdge -{ - int pts[2]; - int trigs[2]; - double cosangle; - int status; // excluded, confirmed, candidate, undefined -public: - STLTopEdge (); - STLTopEdge (int p1, int p2, int trig1, int trig2); - - int operator[] (int i) const { return pts[i]; } - int & operator[] (int i) { return pts[i]; } - - - int PNum(int i) const { return pts[(i-1)]; } - int & PNum(int i) { return pts[(i-1)]; } - int PNumMod(int i) const { return pts[(i-1)%2]; } - int & PNumMod(int i) { return pts[(i-1)%2]; } - - int TrigNum(int i) const { return trigs[(i-1)]; } - int & TrigNum(int i) { return trigs[(i-1)]; } - int TrigNumMod(int i) const { return trigs[(i-1)%2]; } - int & TrigNumMod(int i) { return trigs[(i-1)%2]; } - - void SetCosAngle (double ca) { cosangle = ca; } - double CosAngle () const { return cosangle; } - double Angle () const { return acos (cosangle); } - - void SetStatus (int stat) { status = stat; } - int GetStatus () const { return status; } -}; - - - -ostream& operator<<(ostream& os, const STLTriangle& t); - - - - - - - -class STLTopology -{ -protected: - ARRAY<STLTriangle> trias; - ARRAY<STLTopEdge> topedges; - ARRAY<Point<3> > points; - - // mapping of sorted pair of points to topedge - INDEX_2_HASHTABLE<int> * ht_topedges; - // mapping of node to trigs - TABLE<int> trigsperpoint; - // mapping of node to edges - TABLE<int> topedgesperpoint; - - // searchtree for trigs and points - - Box3dTree * searchtree; // ADT - Point3dTree * pointtree; - - Box<3> boundingbox; - double pointtol; - -public: - enum STL_GEOM_STATUS { STL_GOOD, STL_WARNING, STL_ERROR }; - -protected: - STL_GEOM_STATUS status; - string statustext; - - bool topology_ok; - bool orientation_ok; - -public: - STLTopology(); - virtual ~STLTopology(); - - static STLGeometry * LoadNaomi (istream & ist); - static STLGeometry * Load (istream & ist); - static STLGeometry * LoadBinary (istream & ist); - - void Save (const char* filename); - void SaveBinary (const char* filename, const char* aname); - void SaveSTLE (const char * filename); // stores trigs and edges - - virtual void InitSTLGeometry (const ARRAY<STLReadTriangle> & readtrigs); - - virtual void TopologyChanged() {}; //do some things, if topology changed! - - /// Generate topology tables - void FindNeighbourTrigs(); - - - void GetTrianglesInBox (const Box<3> & box, - ARRAY<int> & trias) const; - - - int GetNP() const { return points.Size(); } - int AddPoint(const Point<3> & p) { return points.Append(p); } - const Point<3> & GetPoint(int nr) const { return points.Get(nr); } - int GetPointNum (const Point<3> & p); - void SetPoint(int nr, const Point<3> & p) { points.Elem(nr) = p; } - const ARRAY<Point<3> >& GetPoints() const { return points; } - - const Point<3> & operator[] (STLPointIndex i) const { return points[i]; } - Point<3> & operator[] (STLPointIndex i) { return points[i]; } - - - - - int GetNT() const { return trias.Size(); } - void AddTriangle(const STLTriangle& t); - const STLTriangle & GetTriangle (int nr) const { return trias.Get(nr); } - STLTriangle & GetTriangle (int nr) { return trias.Elem(nr); } - - const STLTriangle & operator[] (STLTrigIndex i) const { return trias[i]; } - STLTriangle & operator[] (STLTrigIndex i) { return trias[i]; } - - - int GetNTE() const { return topedges.Size(); } - const STLTopEdge & GetTopEdge (int nr) const { return topedges.Get(nr); } - STLTopEdge & GetTopEdge (int nr) { return topedges.Elem(nr); } - int GetTopEdgeNum (int pi1, int pi2) const; - - - int NOTrigsPerPoint(int pn) { return trigsperpoint.EntrySize(pn); } - int TrigPerPoint(int pn, int i) { return trigsperpoint.Get(pn, i); } - - - int NTopEdgesPerPoint (int pn) const { return topedgesperpoint.EntrySize(pn); } - int TopEdgePerPoint (int pn, int ei) const { return topedgesperpoint.Get(pn, ei); } - - - bool Topology_Ok() const { return topology_ok; } - bool Orientation_Ok() const { return orientation_ok; } - - STL_GEOM_STATUS GetStatus () const { return status; } - const string & GetStatusText () const { return statustext; } - - void InvertTrig (int trig); - void DeleteTrig (int trig); - void OrientAfterTrig (int trig); - - - // Table will be constructed, if topology is not ok - /// neighbourtrigs for surfacetrigs - TABLE<int> neighbourtrigs; - - /// get nr-th neighbour Triangle for triangle trig - int NONeighbourTrigs(int trig) const { return neighbourtrigs.EntrySize(trig); } - int NeighbourTrig(int trig, int nr) const { return neighbourtrigs.Get(trig,nr); } - int NeighbourTrigSorted(int trig, int nr) const; - void AddNeighbourTrig(int i, int nt) { neighbourtrigs.Add1(i, nt); } - - - - - int GetLeftTrig (int p1, int p2) const; - int GetRightTrig (int p1, int p2) const; - - const Box<3> & GetBoundingBox () const { return boundingbox; } -}; - - -#endif diff --git a/Netgen/libsrc/visualization/Makefile b/Netgen/libsrc/visualization/Makefile deleted file mode 100644 index a6302092d9..0000000000 --- a/Netgen/libsrc/visualization/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for visualization library -# -src = stlmeshing.cpp mvdraw.cpp vscsg.cpp vsmesh.cpp vsocc.cpp vssolution.cpp meshdoc.cpp -# -lib = vis -libpath = libsrc/visualization -# -# -include ../makefile.inc -# - - diff --git a/Netgen/libsrc/visualization/meshdoc.cpp b/Netgen/libsrc/visualization/meshdoc.cpp deleted file mode 100644 index 4c0f064c05..0000000000 --- a/Netgen/libsrc/visualization/meshdoc.cpp +++ /dev/null @@ -1,615 +0,0 @@ -#include <mystdlib.h> - -#include <meshing.hpp> - -#include "incvis.hpp" - - - -namespace netgen -{ -#include "mvdraw.hpp" -#include "meshdoc.hpp" - - -MeshDoctorParameters meshdoctor; -VisualSceneMeshDoctor vsmeshdoc; - -extern AutoPtr<Mesh> mesh; - - int Ng_MeshDoctor (ClientData clientData, - Tcl_Interp * interp, - int argc, tcl_const char *argv[]) -{ - cout << "Mesh Doctor:" << endl; - int i; - for (i = 0; i < argc; i++) - cout << argv[i] << " "; - cout << endl; - - meshdoctor.active = - atoi (Tcl_GetVar (interp, "meshdoctor.active", 0)); - - - if (argc >= 2) - { - if (strcmp (argv[1], "markedgedist") == 0) - { - vsmeshdoc.SetMarkEdgeDist (atoi (argv[2])); - } - - if (strcmp (argv[1], "deletemarkedsegments") == 0) - { - for (i = 1; i <= mesh->GetNSeg(); i++) - if (vsmeshdoc.IsSegmentMarked (i)) - mesh->DeleteSegment (i); - - // for (i = 1; i <= mesh->GetNSE(); i++) - // mesh->SurfaceElement(i).SetIndex (1); - mesh->Compress(); - } - } - - - vsmeshdoc.UpdateTables (); - vsmeshdoc.BuildScene(); - return TCL_OK; -} - - - - - -VisualSceneMeshDoctor :: VisualSceneMeshDoctor () - : VisualScene() -{ - filledlist = 0; - outlinelist = 0; - edgelist = 0; - selelement = 0; - locpi = 1; - selpoint = 0; - selpoint2 = 0; - markedgedist = 1; - - UpdateTables (); -} - -VisualSceneMeshDoctor :: ~VisualSceneMeshDoctor () -{ - ; -} - -void VisualSceneMeshDoctor :: DrawScene () -{ - int i, j, k; - - if (!mesh) return; - - int hchval = mesh->GetNP() + mesh->GetNE() + mesh->GetNSE(); - if (changeval != hchval) - { - changeval = hchval; - BuildScene(); - } - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable (GL_COLOR_MATERIAL); - glColor3f (1.0f, 1.0f, 1.0f); - glLineWidth (1.0f); - - SetLight(); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - glInitNames (); - glPushName (0); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - SetClippingPlane (); - - if (vispar.drawfilledtrigs) - glCallList (filledlist); - - glDisable (GL_POLYGON_OFFSET_FILL); - - if (vispar.drawoutline) - glCallList (outlinelist); - - glPolygonOffset (-1, -1); - glEnable (GL_POLYGON_OFFSET_LINE); - - if (vispar.drawedges) - glCallList (edgelist); - - - glDisable (GL_POLYGON_OFFSET_LINE); - - - - glPopName(); - - if (selpoint > 0 && selpoint <= mesh->GetNP()) - { - GLfloat matcolblue[] = { 0, 0, 1, 1 }; - - glPointSize (10); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolblue); - glBegin (GL_POINTS); - - const Point3d p = mesh->Point(selpoint); - glVertex3f (p.X(), p.Y(), p.Z()); - glEnd(); - } - - glDisable(GL_CLIP_PLANE0); - - - glPopMatrix(); - glFinish(); -} - - - - -void VisualSceneMeshDoctor :: BuildScene (int zoomall) -{ - int i, j, k; - - - if (zoomall) - { - Point3d pmin, pmax; - mesh->GetBox (pmin, pmax, -1); - - if (vispar.centerpoint) - center = mesh->Point (vispar.centerpoint); - else - center = Center (pmin, pmax); - - rad = 0.5 * Dist (pmin, pmax); - - glEnable (GL_NORMALIZE); - - CalcTransformationMatrices(); - } - - - - - if (filledlist) - { - glDeleteLists (filledlist, 1); - glDeleteLists (outlinelist, 1); - glDeleteLists (edgelist, 1); - } - - - filledlist = glGenLists (1); - glNewList (filledlist, GL_COMPILE); - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - static float matcol0[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - static float matcol1[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - static float matcolsel[] = { 1.0f, 0.0f, 0.0f, 1.0f }; - static float matcolnosel[] = { 0.0f, 1.0f, 0.0f, 1.0f }; - - glLineWidth (1.0f); - - glDisable (GL_COLOR_MATERIAL); - - for (i = 1; i <= mesh->GetNSE(); i++) - { - glLoadName (i); - - // copy to be thread-safe - Element2d el = mesh->SurfaceElement (i); - - int drawel = 1; - for (j = 1; j <= el.GetNP(); j++) - { - if (!el.PNum(j)) - drawel = 0; - } - - if (!drawel) - continue; - - GLfloat matcol[] = { 0, 1, 0, 1 }; - GLfloat matcolsel[] = { 1, 0, 0, 1 }; - - if (i == selelement) - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolsel); - else - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol); - - if (el.GetNP() == 3) - { - glBegin (GL_TRIANGLES); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - - if (!vispar.colormeshsize) - { - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - else - { - double h1 = mesh->GetH (lp1); - double h2 = mesh->GetH (lp2); - double h3 = mesh->GetH (lp3); - - SetOpenGlColor (h1, 0.1, 10); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - - SetOpenGlColor (h2, 0.1, 10); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - - SetOpenGlColor (h3, 0.1, 10); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - glEnd(); - } - else if (el.GetNP() == 4) - { - glBegin (GL_QUADS); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(4)); - const Point3d & lp4 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), - Vec3d (lp1, Center (lp3, lp4))); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glEnd(); - } - else if (el.GetNP() == 6) - { - glBegin (GL_TRIANGLES); - static int trigs[4][3] = { - { 1, 6, 5 }, - { 2, 4, 6 }, - { 3, 5, 4 }, - { 4, 5, 6 } }; - - for (j = 0; j < 4; j++) - { - const Point3d & lp1 = mesh->Point (el.PNum(trigs[j][0])); - const Point3d & lp2 = mesh->Point (el.PNum(trigs[j][1])); - const Point3d & lp3 = mesh->Point (el.PNum(trigs[j][2])); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length() + 1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - glEnd(); - } - } - glLoadName (0); - - glEndList (); - - - - outlinelist = glGenLists (1); - glNewList (outlinelist, GL_COMPILE); - - glLineWidth (1.0f); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - glColor3f (0.0f, 0.0f, 0.0f); - glEnable (GL_COLOR_MATERIAL); - - for (i = 1; i <= mesh->GetNSE(); i++) - { - Element2d el = mesh->SurfaceElement(i); - - int drawel = 1; - for (j = 1; j <= el.GetNP(); j++) - { - if (!el.PNum(j)) - drawel = 0; - } - - if (!drawel) - continue; - - - if (el.GetNP() == 3) - { - glBegin (GL_TRIANGLES); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length() + 1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glEnd(); - } - else if (el.GetNP() == 4) - { - glBegin (GL_QUADS); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(4)); - const Point3d & lp4 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), - Vec3d (lp1, Center (lp3, lp4))); - n /= (n.Length() + 1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glEnd(); - } - else if (el.GetNP() == 6) - { - glBegin (GL_LINES); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(3)); - const Point3d & lp4 = mesh->Point (el.PNum(4)); - const Point3d & lp5 = mesh->Point (el.PNum(5)); - const Point3d & lp6 = mesh->Point (el.PNum(6)); - - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp6.X(), lp6.Y(), lp6.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp6.X(), lp6.Y(), lp6.Z()); - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp5.X(), lp5.Y(), lp5.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glVertex3d (lp5.X(), lp5.Y(), lp5.Z()); - - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glEnd(); - } - } - glLoadName (0); - glEndList (); - - - - - - edgelist = glGenLists (1); - glNewList (edgelist, GL_COMPILE); - - glDisable (GL_COLOR_MATERIAL); - - GLfloat matcoledge[] = { 0, 0, 1, 1 }; - GLfloat matcolseledge[] = { 1, 0, 1, 1 }; - - glLineWidth (2.0f); - - for (i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh->LineSegment(i); - const Point3d & p1 = mesh->Point(seg.p1); - const Point3d & p2 = mesh->Point(seg.p2); - - if (edgedist.Get(seg.p1) <= markedgedist && - edgedist.Get(seg.p2) <= markedgedist) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcolseledge); - glLineWidth (4.0f); - } - else - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcoledge); - glLineWidth (2.0f); - } - glBegin (GL_LINES); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glEnd(); - } - - glLineWidth (1.0f); - glEndList (); -} - - - - -void VisualSceneMeshDoctor :: MouseDblClick (int px, int py) -{ - cout << "dblclick: " << px << " - " << py << endl; - - int i, j, k, hits; - - // select surface triangle by mouse click - GLuint selbuf[10000]; - glSelectBuffer (10000, selbuf); - - - glRenderMode (GL_SELECT); - - GLint viewport[4]; - glGetIntegerv (GL_VIEWPORT, viewport); - - glMatrixMode (GL_PROJECTION); - glPushMatrix(); - - GLdouble projmat[16]; - glGetDoublev (GL_PROJECTION_MATRIX, projmat); - - glLoadIdentity(); - gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); - glMultMatrixd (projmat); - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_MODELVIEW); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - glInitNames(); - glPushName (1); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glCallList (filledlist); - - glDisable (GL_POLYGON_OFFSET_FILL); - - glPopName(); - - glMatrixMode (GL_PROJECTION); - glPopMatrix(); - - glMatrixMode (GL_MODELVIEW); - glPopMatrix(); - - glFlush(); - - - hits = glRenderMode (GL_RENDER); - - cout << "hits = " << hits << endl; - - int minname = 0; - GLuint mindepth = 0; - for (i = 0; i < hits; i++) - { - int curname = selbuf[4*i+3]; - GLuint curdepth = selbuf[4*i+1]; - - if (curname && - (curdepth < mindepth || !minname)) - { - mindepth = curdepth; - minname = curname; - } - } - - cout << "clicked element: " << minname << endl; - - ClickElement (minname); - - BuildScene (); -} - - - - -void VisualSceneMeshDoctor :: SetMarkEdgeDist (int dist) -{ - markedgedist = dist; - BuildScene(); -} - -void VisualSceneMeshDoctor :: ClickElement (int elnr) -{ - selelement = elnr; - - int oldlocpi = locpi; - locpi = locpi % 3 + 1; - - if (selelement > 0 && selelement <= mesh->GetNSE()) - { - selpoint = mesh->SurfaceElement(selelement).PNum(locpi); - selpoint2 = mesh->SurfaceElement(selelement).PNum(oldlocpi); - cout << "selpts = " << selpoint << ", " << selpoint2 << endl; - } - - UpdateTables(); -} - - -void VisualSceneMeshDoctor :: UpdateTables () -{ - if (!mesh) return; - - edgedist.SetSize(mesh->GetNP()); - int i, changed; - - for (i = 1; i <= mesh->GetNP(); i++) - edgedist.Elem(i) = 10000; - - for (i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh->LineSegment(i); - if (seg.p1 == selpoint && seg.p2 == selpoint2 || - seg.p2 == selpoint && seg.p1 == selpoint2) - { - edgedist.Elem(selpoint) = 1; - edgedist.Elem(selpoint2) = 1; - } - } - - do - { - changed = 0; - - for (i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh->LineSegment(i); - - int edist = min2 (edgedist.Get(seg.p1), edgedist.Get(seg.p2)); - edist++; - - if (edgedist.Get(seg.p1) > edist) - { - edgedist.Elem(seg.p1) = edist; - changed = 1; - } - if (edgedist.Get(seg.p2) > edist) - { - edgedist.Elem(seg.p2) = edist; - changed = 1; - } - } - } - while (changed); -} - -int VisualSceneMeshDoctor :: IsSegmentMarked (int segnr) const -{ - const Segment & seg = mesh->LineSegment(segnr); - return (edgedist.Get(seg.p1) <= markedgedist && - edgedist.Get(seg.p2) <= markedgedist); -} -} diff --git a/Netgen/libsrc/visualization/meshdoc.hpp b/Netgen/libsrc/visualization/meshdoc.hpp deleted file mode 100644 index 5cc11aef78..0000000000 --- a/Netgen/libsrc/visualization/meshdoc.hpp +++ /dev/null @@ -1,37 +0,0 @@ - -class VisualSceneMeshDoctor : public VisualScene -{ - int filledlist; - int outlinelist; - int edgelist; - - int selelement, locpi; - int selpoint, selpoint2; - - // for edgemarking: - ARRAY<int> edgedist; - int markedgedist; - - -public: - VisualSceneMeshDoctor (); - virtual ~VisualSceneMeshDoctor (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - virtual void MouseDblClick (int px, int py); - - void SetMarkEdgeDist (int dist); - void ClickElement (int elnr); - void UpdateTables (); - int IsSegmentMarked (int segnr) const; -}; - -class MeshDoctorParameters -{ -public: - int active; -}; - - -extern MeshDoctorParameters meshdoctor; diff --git a/Netgen/libsrc/visualization/mvdraw.cpp b/Netgen/libsrc/visualization/mvdraw.cpp deleted file mode 100644 index 265dc970b4..0000000000 --- a/Netgen/libsrc/visualization/mvdraw.cpp +++ /dev/null @@ -1,1335 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> -#include <meshing.hpp> -#include <csg.hpp> -#include <geometry2d.hpp> -#include <stlgeom.hpp> - -#include "incvis.hpp" - - - -namespace netgen -{ - -#include "mvdraw.hpp" - - Point3d VisualScene :: center; - double VisualScene :: rad; - GLdouble VisualScene :: backcolor; - GLuint VisualScene :: fontbase = 0; - - // texture for color decoding - GLubyte * VisualScene :: colortexture = NULL; - GLuint VisualScene :: coltexname = 1; - int VisualScene :: ntexcols = -1; - - - float VisualScene :: lookatmat[16]; - float VisualScene :: transmat[16]; - float VisualScene :: rotmat[16]; - float VisualScene :: centermat[16]; - float VisualScene :: transformationmat[16]; - - - - VisualizationParameters :: VisualizationParameters() - { - lightamb = 0.3; - lightdiff = 0.7; - lightspec = 1; - shininess = 50; - transp = 0.3; - locviewer = 0; - showstltrias = 0; - centerpoint = 0; - usedispllists = 1; - strcpy (selectvisual, "cross"); - - use_center_coords = false; - }; - VisualizationParameters vispar; - - - - double dist = 0; - // double dist = 6; - // vorher: pnear = 2; - double pnear = 0.1; - double pfar = 10; - - - - extern STLGeometry * stlgeometry; - extern AutoPtr<SplineGeometry2d> geometry2d; - extern AutoPtr<Mesh> mesh; - extern ARRAY<SpecialPoint> specpoints; - - - VisualScene :: VisualScene () - { - changeval = -1; - backcolor = 0; - } - - - VisualScene :: ~VisualScene() - { - ; - } - - - void Render () - { - multithread.redraw = 1; - } - - - void VisualScene :: BuildScene (int zoomall) - { - center = Point3d (0,0,0); - rad = 1; - - CalcTransformationMatrices(); - - glEnable(GL_DEPTH_TEST); - glDisable (GL_DITHER); - - GLfloat ambvals[] = { 0.4f, 0.4f, 0.4f, 1.0f }; - GLfloat diffvals[] = { 0.5f, 0.5f, 0.5f, 1.0f }; - GLfloat specvals[] = { 0.7f, 0.7f, 0.7f, 1.0f }; - glLightfv(GL_LIGHT0, GL_AMBIENT, ambvals); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffvals); - glLightfv(GL_LIGHT0, GL_SPECULAR, specvals); - - GLfloat light_position[] = { 1, 3, 3, 0 }; - glLightfv(GL_LIGHT0, GL_POSITION, light_position); - - glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, 0); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - } - - - void VisualScene :: DrawScene () - { - if (changeval == -1) - BuildScene(); - changeval = 0; - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable (GL_COLOR_MATERIAL); - glColor3f (1.0f, 1.0f, 1.0f); - glLineWidth (1.0f); - - DrawCoordinateCross (); - DrawNetgenLogo (); - glFinish(); - } - - - void VisualScene :: CalcTransformationMatrices() - { - - // prepare model view matrix - - glPushMatrix(); - - glLoadIdentity(); - gluLookAt (0, 0, 6, 0, 0, 0, 0, 1, 0); - glGetFloatv (GL_MODELVIEW_MATRIX, lookatmat); - - glLoadIdentity(); - glTranslatef(0.0f, 0.0f, -dist); - glGetFloatv (GL_MODELVIEW_MATRIX, transmat); - - glLoadIdentity(); - glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); - - glScalef (1/rad, 1/rad, 1/rad); - glTranslated (-center.X(), -center.Y(), -center.Z()); - glGetFloatv (GL_MODELVIEW_MATRIX, centermat); - - glLoadIdentity(); - glMultMatrixf (lookatmat); - glMultMatrixf (transmat); - glMultMatrixf (rotmat); - glMultMatrixf (centermat); - glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); - - glPopMatrix(); - } - - - void VisualScene :: ArbitraryRotation (const ARRAY<double> & alpha, const ARRAY<Vec3d> & vec) - { - glPushMatrix(); - - glLoadIdentity(); - - for(int i=0; i<alpha.Size() && i<vec.Size(); i++) - { - glRotatef(alpha[i], vec[i].X(), vec[i].Y(), vec[i].Z()); - } - - glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); - - glLoadIdentity(); - glMultMatrixf (lookatmat); - glMultMatrixf (transmat); - glMultMatrixf (rotmat); - glMultMatrixf (centermat); - glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); - - glPopMatrix(); - } - - - - void VisualScene :: ArbitraryRotation (const double alpha, const Vec3d & vec) - { - ARRAY<double> a(1); a[0] = alpha; - ARRAY<Vec3d> v(1); v[0] = vec; - - ArbitraryRotation(a,v); - } - - void VisualScene :: StandardRotation (const char * dir) - { - glPushMatrix(); - - glLoadIdentity(); - - if (strcmp (dir, "xy") == 0) - ; - else if (strcmp (dir, "yx") == 0) - glRotatef(180.0, 1.0f, 1.0f, 0.0f); - else if (strcmp (dir, "xz") == 0) - glRotatef(-90.0, 1.0f, 0.0f, 0.0f); - else if (strcmp (dir, "zx") == 0) - { - glRotatef(180.0, 1.0f, 1.0f, 0.0f); - glRotatef(-90.0, 1.0f, 0.0f, 0.0f); - } - else if (strcmp (dir, "yz") == 0) - { - glRotatef(-90.0, 0.0f, 0.0f, 1.0f); - glRotatef(-90.0, 0.0f, 1.0f, 0.0f); - } - else if (strcmp (dir, "zy") == 0) - glRotatef(90.0, 0.0f, 1.0f, 0.0f); - - - glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); - - glLoadIdentity(); - glMultMatrixf (lookatmat); - glMultMatrixf (transmat); - glMultMatrixf (rotmat); - glMultMatrixf (centermat); - glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); - - glPopMatrix(); - } - - void VisualScene :: MouseMove(int oldx, int oldy, - int newx, int newy, - char mode) - { - int deltax = newx - oldx; - int deltay = newy - oldy; - - glPushMatrix(); - glLoadIdentity (); - - switch (mode) - { - case 'r': - { - glRotatef(float(deltax)/2, 0.0f, 1.0f, 0.0f); - glRotatef(float(deltay)/2, 1.0f, 0.0f, 0.0f); - glMultMatrixf (rotmat); - glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); - break; - } - case 'm': - { - GLdouble projmat[16], modelviewmat[16]; - GLint viewport[4]; - glGetDoublev (GL_PROJECTION_MATRIX, projmat); - glGetDoublev (GL_MODELVIEW_MATRIX, modelviewmat); - glGetIntegerv (GL_VIEWPORT, viewport); - - // vorher pvz1/2 = 0 - GLdouble pvx1 = 0, pvy1 = 0, pvz1 = 0.95; - GLdouble pvx2 = deltax, pvy2 = -deltay, pvz2 = 0.95; - - GLdouble px1, py1, pz1; - GLdouble px2, py2, pz2; - - gluUnProject (pvx1, pvy1, pvz1, - modelviewmat, projmat, viewport, - &px1, &py1, &pz1); - gluUnProject (pvx2, pvy2, pvz2, - modelviewmat, projmat, viewport, - &px2, &py2, &pz2); - /* - gluUnProject (oldx, oldy, 1, - modelviewmat, projmat, viewport, - &px1, &py1, &pz1); - gluUnProject (newx, newy, 1, - modelviewmat, projmat, viewport, - &px2, &py2, &pz2); - */ - - /* - cout << "pv1 = " << pvx1 << ", " << pvy1 << ", " << pvz1 << endl; - cout << "p1 = " << px1 << ", " << py1 << ", " << pz1 << endl; - */ - - glTranslated (px2-px1, py2-py1, pz2-pz1); - - glMultMatrixf (transmat); - glGetFloatv (GL_MODELVIEW_MATRIX, transmat); - break; - } - case 'z': - { - // glTranslatef(0.0f, 0.0f, -dist); - glScaled (exp (float (-deltay)/100), - exp (float (-deltay)/100), - exp (float (-deltay)/100)); - // glTranslatef(0.0f, 0.0f, dist); - glMultMatrixf (transmat); - glGetFloatv (GL_MODELVIEW_MATRIX, transmat); - break; - } - } - - glLoadIdentity(); - glMultMatrixf (lookatmat); - glMultMatrixf (transmat); - glMultMatrixf (rotmat); - glMultMatrixf (centermat); - glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); - - glPopMatrix(); - } - - - void VisualScene :: LookAt (const Point<3> & cam, const Point<3> & obj, - const Point<3> & camup) - { - glPushMatrix(); - glLoadIdentity (); - gluLookAt (cam(0), cam(1), cam(2), - obj(0), obj(1), obj(2), - camup(0), camup(1), camup(2)); - glMultMatrixf (centermat); - glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); - glPopMatrix(); - } - - - void VisualScene :: SetClippingPlane () - { - if (vispar.clipenable) - { - Vec3d n = vispar.clipnormal; - n /= (n.Length()+1e-10); - clipplane[0] = n.X(); - clipplane[1] = n.Y(); - clipplane[2] = n.Z(); - clipplane[3] = -(Vec3d(center) * n) + rad * vispar.clipdist; - - glClipPlane(GL_CLIP_PLANE0, clipplane); - glEnable(GL_CLIP_PLANE0); - } - else - glDisable (GL_CLIP_PLANE0); - } - - - - - void VisualScene :: MouseDblClick (int /* px */, int /* py */) - { - ; - } - - - - void VisualScene :: SetLight() - { - GLfloat vals[3]; - double lightamb = vispar.lightamb; - vals[0] = vals[1] = vals[2] = lightamb; - glLightfv(GL_LIGHT0, GL_AMBIENT, vals); - - double lightdiff = vispar.lightdiff; - vals[0] = vals[1] = vals[2] = lightdiff; - glLightfv(GL_LIGHT0, GL_DIFFUSE, vals); - - double lightspec = vispar.lightspec; - vals[0] = vals[1] = vals[2] = lightspec; - glLightfv(GL_LIGHT0, GL_SPECULAR, vals); - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, vispar.shininess); - glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, vispar.locviewer); - - float mat_spec_col[] = { 1, 1, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); - - glEnable (GL_LIGHTING); - glEnable (GL_LIGHT0); - } - - - - - void VisualScene :: SetOpenGlColor(double h, double hmin, double hmax, - int logscale) - { - double value; - - if (!logscale) - value = (h - hmin) / (hmax - hmin); - else - { - if (hmax <= 0) hmax = 1; - if (hmin <= 0) hmin = 1e-4 * hmax; - value = (log(fabs(h)) - log(hmin)) / (log(hmax) - log(hmin)); - } - - if (!invcolor) - value = 1 - value; - - glTexCoord1f ( 0.999 * value + 0.001); - // glTexCoord1f ( value ); - - if (value > 1) value = 1; - if (value < 0) value = 0; - - value *= 4; - - static const double colp[][3] = - { - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 1 }, - { 0, 0, 1 }, - // { 1, 0, 1 }, - // { 1, 0, 0 }, - }; - - int i = int(value); - double r = value - i; - - GLdouble col[3]; - for (int j = 0; j < 3; j++) - col[j] = (1-r) * colp[i][j] + r * colp[i+1][j]; - - glColor3d (col[0], col[1], col[2]); - } - - - /* - void VisualScene :: CreateTexture (int ncols, int linear, int typ) - { - - static const double colp[][3] = - { - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 1 }, - { 0, 0, 1 }, - }; - - - - if (ntexcols != 1024) - { - ntexcols = 1024; - - // glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - glGenTextures (1, &coltexname); - glBindTexture (GL_TEXTURE_1D, coltexname); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - - for (int level = 0; level <= 11; level++) - { - ncols = 2048 >> level; - cout << "ncols = " << ncols << endl; - - colortexture = new GLubyte[4*ncols+12]; - - for (int i = 0; i < ncols; i++) - { - double value = 4.0 * i / (ncols-1); - - int iv = int(value); - double r = value - iv; - - GLdouble col[3]; - for (int j = 0; j < 3; j++) - col[j] = (1-r) * colp[iv][j] + r * colp[iv+1][j]; - - colortexture[4*i] = GLubyte (255 * col[0]); - colortexture[4*i+1] = GLubyte (255 * col[1]); - colortexture[4*i+2] = GLubyte (255 * col[2]); - colortexture[4*i+3] = GLubyte(255); - - if (ncols > 20) - if ( i % (ncols / 10) == 0) - { - colortexture[4*i] = GLubyte (0); - colortexture[4*i+1] = GLubyte (0); - colortexture[4*i+2] = GLubyte (0); - colortexture[4*i+4] = GLubyte (0); - colortexture[4*i+5] = GLubyte (0); - colortexture[4*i+6] = GLubyte (0); - } - } - - glTexImage1D (GL_TEXTURE_1D, level, 4, ncols, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture); - } - } - - glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, typ); // DECAL or MODULATE - glBindTexture (GL_TEXTURE_1D, coltexname); - } - */ - - - void VisualScene :: CreateTexture (int ncols, int linear, int typ) - { - if (ncols < 2) ncols = 2; - - if (linear) ncols = 32; - else ncols = 8; - - if (ntexcols != ncols) - { - if (colortexture) - { - glDeleteTextures (1, &coltexname); - delete colortexture; - } - - ntexcols = ncols; - - colortexture = new GLubyte[4*ncols+12]; - - const double colp[][3] = - { - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 1 }, - { 0, 0, 1 }, - }; - - for (int i = 0; i < ncols; i++) - { - double value = 4.0 * i / (ncols-1); - - int iv = int(value); - double r = value - iv; - - GLdouble col[3]; - for (int j = 0; j < 3; j++) - col[j] = (1-r) * colp[iv][j] + r * colp[iv+1][j]; - - colortexture[4*i] = GLubyte (255 * col[0]); - colortexture[4*i+1] = GLubyte (255 * col[1]); - colortexture[4*i+2] = GLubyte (255 * col[2]); - colortexture[4*i+3] = GLubyte(255); - } - - // glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - - glGenTextures (1, &coltexname); - glBindTexture (GL_TEXTURE_1D, coltexname); - - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexImage1D (GL_TEXTURE_1D, 0, 4, ncols, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture); - } - - glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, typ); // DECAL or MODULATE - - glBindTexture (GL_TEXTURE_1D, coltexname); - if (linear) - { - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - } - - - - - - /* - void VisualScene :: CreateTexture (int ncols, int linear, int typ) - { - if (ncols < 2) ncols = 2; - - if (linear) ncols = 32; - else ncols = 8; - - if (ntexcols != ncols) - { - if (colortexture) - { - glDeleteTextures (1, &coltexname); - delete colortexture; - } - - ntexcols = ncols; - - colortexture = new GLubyte[4*ncols+12]; - - const double colp[][3] = - { - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 1 }, - { 0, 0, 1 }, - }; - - for (int i = 0; i < ncols; i++) - { - double value = 4.0 * i / (ncols-1); - - int iv = int(value); - double r = value - iv; - - GLdouble col[3]; - for (int j = 0; j < 3; j++) - col[j] = (1-r) * colp[iv][j] + r * colp[iv+1][j]; - - colortexture[4*i+4] = GLubyte (255 * col[0]); - colortexture[4*i+5] = GLubyte (255 * col[1]); - colortexture[4*i+6] = GLubyte (255 * col[2]); - colortexture[4*i+7] = GLubyte(255); - } - for (int j = 0; j < 4; j++) - { - colortexture[j] = colortexture[4+j]; - colortexture[ncols*4+4+j] = colortexture[ncols*4+j]; - } - - // glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - - glGenTextures (1, &coltexname); - glBindTexture (GL_TEXTURE_1D, coltexname); - - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexImage1D (GL_TEXTURE_1D, 0, 4, ncols, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture+4); - int bcol[] = { 0, 0, -1, -1 }; - glTexParameteriv (GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR, bcol); - } - - glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, typ); // DECAL or MODULATE - - glBindTexture (GL_TEXTURE_1D, coltexname); - if (linear) - { - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - } - */ - - - - - - void VisualScene :: DrawColorBar (double minval, double maxval, int logscale, bool linear) - { - if (!vispar.drawcolorbar) return; - - CreateTexture (8, linear, GL_DECAL); - - if (logscale && maxval <= 0) maxval = 1; - if (logscale && minval <= 0) minval = 1e-4 * maxval; - - double minx = -1; - double maxx = 1; - double miny = 0.75; - double maxy = 0.8; - - glEnable (GL_COLOR_MATERIAL); - glEnable (GL_TEXTURE_1D); - glNormal3d (0, 0, 1); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glDisable (GL_DEPTH_TEST); - glBegin (GL_QUAD_STRIP); - - for (double x = minx; x <= maxx; x += (maxx - minx) / 50) - { - SetOpenGlColor (x, minx, maxx); - // glTexCoord1f ( 0.999 * (x-minx) / (maxx-minx) + 0.001); - - glVertex3d (x, miny, -5); - glVertex3d (x, maxy, -5); - } - glEnd(); - - glDisable (GL_TEXTURE_1D); - - - glEnable (GL_COLOR_MATERIAL); - GLfloat textcol[3] = { 1 - backcolor, 1 - backcolor, 1 - backcolor }; - glColor3fv (textcol); - - glPushAttrib (GL_LIST_BIT); - glListBase (fontbase); - - char buf[20]; - for (int i = 0; i <= 4; i++) - { - double x = minx + i * (maxx-minx) / 4; - glRasterPos3d (x, 0.7,-5); - - double val; - if (logscale) - val = minval * pow (maxval / minval, i / 4.0); - else - val = minval + i * (maxval-minval) / 4; - - sprintf (buf, "%8.3e", val); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - } - - glPopAttrib (); - glEnable (GL_DEPTH_TEST); - } - - - void VisualScene :: DrawCoordinateCross () - { - if (!vispar.drawcoordinatecross) return; - - glDisable (GL_DEPTH_TEST); - glMatrixMode (GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode (GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - GLint viewport[4]; - glGetIntegerv (GL_VIEWPORT, viewport); - - glTranslatef (-1, -1, 0.0); - glScalef (40.0 / viewport[2], 40.0 / viewport[3], 1); - glTranslatef (2.0, 2.0, 0.0); - glMultMatrixf (rotmat); - - glEnable (GL_COLOR_MATERIAL); - glDisable (GL_LIGHTING); - - GLfloat textcol[3] = { 1 - backcolor, - 1 - backcolor, - 1 - backcolor }; - glColor3fv (textcol); - - glLineWidth (1.0f); - - float len = 1; - glBegin(GL_LINES); - glVertex3f (0.0f, 0.0f, 0.0f); - glVertex3f (len, 0.0f, 0.0f); - glVertex3f (0.0f, 0.0f, 0.0f); - glVertex3f (0.0f, len, 0.0f); - glVertex3f (0.0f, 0.0f, 0.0f); - glVertex3f (0.0f, 0.0f, len); - glEnd (); - - - glPushAttrib (GL_LIST_BIT); - glListBase (fontbase); - - char buf[20]; - - glRasterPos3d (len, 0.0f, 0.0f); - sprintf (buf, "x"); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - glRasterPos3d (0.0f, len, 0.0f); - sprintf (buf, "y"); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - glRasterPos3d (0.0f, 0.0f, len); - sprintf (buf, "z"); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - - glPopAttrib (); - glEnable (GL_LIGHTING); - - glMatrixMode (GL_PROJECTION); - glPopMatrix(); - glMatrixMode (GL_MODELVIEW); - glPopMatrix(); - glEnable (GL_DEPTH_TEST); - } - - - void VisualScene :: DrawNetgenLogo () - { - if (!vispar.drawnetgenlogo) return; - - glDisable (GL_DEPTH_TEST); - glMatrixMode (GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode (GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - GLint viewport[4]; - glGetIntegerv (GL_VIEWPORT, viewport); - - - - glTranslatef (1, -1, 0.0); - glScalef (40.0 / viewport[2], 40.0 / viewport[3], 1); - glTranslatef (-6.0, 2.0, 0.0); - - glDisable (GL_CLIP_PLANE0); - // glDisable (GL_LIGHTING); - - glEnable (GL_COLOR_MATERIAL); - GLfloat textcol[3] = { 1 - backcolor, - 1 - backcolor, - 1 - backcolor }; - glColor3fv (textcol); - - glLineWidth (1.0f); - - glPushAttrib (GL_LIST_BIT); - glListBase (fontbase); - - char buf[20]; - - glRasterPos3d (0.0f, 0.0f, 0.0f); - sprintf (buf, "Netgen 4.4"); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - - glPopAttrib (); - - glMatrixMode (GL_PROJECTION); - glPopMatrix(); - glMatrixMode (GL_MODELVIEW); - glPopMatrix(); - glEnable (GL_DEPTH_TEST); - } - - - - - - /* *********************** Draw 2D Geometry **************** */ - - - VisualSceneGeometry2d :: VisualSceneGeometry2d () - : VisualScene() - { - ; - } - - VisualSceneGeometry2d :: ~VisualSceneGeometry2d () - { - ; - } - - - - void VisualSceneGeometry2d :: DrawScene () - { - if (changeval != geometry2d->GetSplines().Size()) - BuildScene(); - changeval = geometry2d->GetSplines().Size(); - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - SetLight(); - - // glEnable (GL_LIGHT0); - glDisable (GL_LIGHTING); - glPushMatrix(); - glMultMatrixf (transformationmat); - - // SetClippingPlane (); - - glShadeModel (GL_SMOOTH); - glEnable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - // float mat_col[] = { 0, 0, 1, 1 }; - // glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - glColor3f (0, 0, 1); - - - ARRAY<Point<2> > points, otherpoints; - - for (int i = 1; i <= geometry2d->GetSplines().Size(); i++) - { - geometry2d->GetSplines().Get(i)->GetPoints (20, points); - - glBegin (GL_LINE_STRIP); - for (int j = 0; j < points.Size(); j++) - glVertex3f (points[j](0), points[j](1), 0); - glEnd(); - } - - glColor3f (1, 0, 0); - - for (int i = 1; i <= geometry2d->GetSplines().Size(); i++) - { - int other = geometry2d->GetSplines().Get(i)->copyfrom; - if (other != -1) - { - geometry2d->GetSplines().Get(i)->GetPoints (6, points); - geometry2d->GetSplines().Get(other)->GetPoints (6, otherpoints); - glBegin (GL_LINES); - for (int j = 1; j < 5; j++) - { - glVertex3f (points[j](0), points[j](1), 0); - glVertex3f (otherpoints[j](0), otherpoints[j](1), 0); - } - glEnd (); - } - } - - - - glPopMatrix(); - - DrawCoordinateCross (); - DrawNetgenLogo (); - - glFinish(); - } - - - void VisualSceneGeometry2d :: BuildScene (int zoomall) - { - Box<2> bbox; - - geometry2d->GetBoundingBox (bbox); - - Point<2> c = Center (bbox.PMin(), bbox.PMax()); - - center = Point3d (c(0), c(1), 0); - rad = Dist (bbox.PMin(), bbox.PMax()) / 2; - - CalcTransformationMatrices(); - } - - - - - - - - - - - /* *********************** Draw STL Geometry **************** */ - - - VisualSceneSTLGeometry :: VisualSceneSTLGeometry () - : VisualScene() - { - ; - } - - VisualSceneSTLGeometry :: ~VisualSceneSTLGeometry () - { - ; - } - - void VisualSceneSTLGeometry :: DrawScene () - { - if (changeval != stlgeometry->GetNT()) - BuildScene(); - - changeval = stlgeometry->GetNT(); - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - SetLight(); - - - glPushMatrix(); - glMultMatrixf (transformationmat); - - - - - glShadeModel (GL_SMOOTH); - glDisable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - - double shine = vispar.shininess; - // double transp = vispar.transp; - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); - glLogicOp (GL_COPY); - - - float mat_col[] = { 0.2f, 0.2f, 0.8f, 1.0f}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glCallList (trilists.Get(1)); - - glDisable (GL_POLYGON_OFFSET_FILL); - - - int showtrias = vispar.showstltrias; - - if (showtrias) - { - float mat_coll[] = { 0.2f, 0.2f, 0.2f, 1.0f }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_coll); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - glCallList (trilists.Get(1)); - } - - /* - - glBegin (GL_TRIANGLES); - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - const STLTriangle & tria = stlgeometry -> GetTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - - for (k = 0; k < 3; k++) - { - glVertex3f (tria.pts[k].X(), - tria.pts[k].Y(), - tria.pts[k].Z()); - } - } - glEnd (); - */ - - - - - glPopMatrix(); - glFinish(); - } - - - void VisualSceneSTLGeometry :: BuildScene (int zoomall) - { - // cout << "rebuild stl geometry scene" << endl; - - center = stlgeometry -> GetBoundingBox().Center(); - rad = stlgeometry -> GetBoundingBox().Diam() / 2; - - - CalcTransformationMatrices(); - - for (int i = 1; i <= trilists.Size(); i++) - glDeleteLists (trilists.Elem(i), 1); - trilists.SetSize(0); - - - trilists.Append (glGenLists (1)); - glNewList (trilists.Last(), GL_COMPILE); - - glEnable (GL_NORMALIZE); - - glBegin (GL_TRIANGLES); - for (int j = 1; j <= stlgeometry -> GetNT(); j++) - { - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - - for (int k = 1; k <= 3; k++) - { - const Point3d & p = - stlgeometry->GetPoint (stlgeometry -> GetTriangle(j).PNum(k)); - glVertex3f (p.X(),p.Y(), p.Z()); - } - } - glEnd (); - - glEndList (); - } - - - - - - - - - - - - - VisualSceneSpecPoints :: VisualSceneSpecPoints () - : VisualScene() - { - ; - } - - VisualSceneSpecPoints :: ~VisualSceneSpecPoints () - { - ; - } - - - void VisualSceneSpecPoints :: DrawScene () - { - if (!mesh) - { - VisualScene::DrawScene(); - return; - } - - if (changeval != specpoints.Size()) - BuildScene(); - changeval = specpoints.Size(); - - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable (GL_COLOR_MATERIAL); - glColor3f (1.0f, 1.0f, 1.0f); - glLineWidth (1.0f); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - // glEnable (GL_COLOR); - // glDisable (GL_COLOR_MATERIAL); - if (vispar.drawedtangents) - { - glColor3d (1, 0, 0); - glBegin (GL_LINES); - for (int i = 1; i <= specpoints.Size(); i++) - { - const Point3d p1 = specpoints.Get(i).p; - const Point3d p2 = specpoints.Get(i).p + len * specpoints.Get(i).v; - glVertex3d (p1.X(), p1.Y(), p1.Z()); - glVertex3d (p2.X(), p2.Y(), p2.Z()); - } - glEnd(); - } - - if (vispar.drawededges) - { - glColor3d (1, 0, 0); - glBegin (GL_LINES); - for (int i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh -> LineSegment (i); - glVertex3dv ( &(*mesh)[seg.p1].X() ); - glVertex3dv ( &(*mesh)[seg.p2].X() ); - } - glEnd(); - } - - if (vispar.drawededgenrs) - { - glEnable (GL_COLOR_MATERIAL); - GLfloat textcol[3] = { 1 - backcolor, - 1 - backcolor, - 1 - backcolor }; - glColor3fv (textcol); - glNormal3d (0, 0, 1); - glPushAttrib (GL_LIST_BIT); - glListBase (fontbase); - - char buf[20]; - for (int i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh -> LineSegment (i); - const Point3d p1 = mesh -> Point (seg.p1); - const Point3d p2 = mesh -> Point (seg.p2); - - const Point3d p = Center (p1, p2); - glRasterPos3d (p.X(), p.Y(), p.Z()); - - sprintf (buf, "%d", seg.edgenr); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - } - - glPopAttrib (); - glDisable (GL_COLOR_MATERIAL); - } - - - if (vispar.drawedpoints) - { - glColor3d (0, 0, 1); - glPointSize( 3.0 ); - - /* - float range[2]; - glGetFloatv(GL_POINT_SIZE_RANGE, &range[0]); - cout << "max ptsize = " << range[0] << "-" << range[1] << endl; - */ - - - glBegin( GL_POINTS ); - for (int i = 1; i <= mesh -> GetNP(); i++) - { - const Point3d & p = mesh -> Point(i); - if (i % 2) - glVertex3f( p.X(), p.Y(), p.Z()); - } - glEnd(); - - static GLubyte knoedel[] = - { - 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - }; - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glDisable (GL_COLOR_MATERIAL); - glDisable (GL_LIGHTING); - glDisable (GL_CLIP_PLANE0); - - for (int i = 1; i <= mesh -> GetNP(); i++) - { - const Point3d & p = mesh -> Point(i); - glRasterPos3d (p.X(), p.Y(), p.Z()); - glBitmap (7, 7, 3, 3, 0, 0, &knoedel[0]); - } - - } - - if (vispar.drawedpointnrs) - { - glEnable (GL_COLOR_MATERIAL); - GLfloat textcol[3] = { 1 - backcolor, - 1 - backcolor, - 1 - backcolor }; - glColor3fv (textcol); - glNormal3d (0, 0, 1); - glPushAttrib (GL_LIST_BIT); - glListBase (fontbase); - - char buf[20]; - for (int i = 1; i <= mesh->GetNP(); i++) - { - const Point3d & p = mesh->Point(i); - glRasterPos3d (p.X(), p.Y(), p.Z()); - - sprintf (buf, "%d", i); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - } - - glPopAttrib (); - glDisable (GL_COLOR_MATERIAL); - } - - - glPopMatrix(); - - if (vispar.drawcoordinatecross) - DrawCoordinateCross (); - DrawNetgenLogo (); - - glFinish(); - } - - - void VisualSceneSpecPoints :: BuildScene (int zoomall) - { - if (!mesh) - { - VisualScene::BuildScene(zoomall); - return; - } - - Box3d box; - - if (mesh->GetNSeg()) - { - box.SetPoint (mesh->Point (mesh->LineSegment(1).p1)); - for (int i = 1; i <= mesh->GetNSeg(); i++) - { - box.AddPoint (mesh->Point (mesh->LineSegment(i).p1)); - box.AddPoint (mesh->Point (mesh->LineSegment(i).p2)); - } - } - else if (specpoints.Size() >= 2) - { - box.SetPoint (specpoints.Get(1).p); - for (int i = 2; i <= specpoints.Size(); i++) - box.AddPoint (specpoints.Get(i).p); - } - else - { - box = Box3d (Point3d (0,0,0), Point3d (1,1,1)); - } - - if (zoomall == 2 && ((vispar.centerpoint >= 1 && vispar.centerpoint <= mesh->GetNP()) || - vispar.use_center_coords)) - { - if (vispar.use_center_coords) - { - center.X() = vispar.centerx; center.Y() = vispar.centery; center.Z() = vispar.centerz; - } - else - center = mesh->Point (vispar.centerpoint); - } - else - center = Center (box.PMin(), box.PMax()); - - - rad = 0.5 * Dist (box.PMin(), box.PMax()); - - - CalcTransformationMatrices(); - } - -} diff --git a/Netgen/libsrc/visualization/mvdraw.hpp b/Netgen/libsrc/visualization/mvdraw.hpp deleted file mode 100644 index 5665533979..0000000000 --- a/Netgen/libsrc/visualization/mvdraw.hpp +++ /dev/null @@ -1,370 +0,0 @@ -#ifndef FILE_MVDRAW -#define FILE_MVDRAW - -#include "vispar.hpp" - -/* - -class VisualizationParameters -{ -public: - double lightamb; - double lightdiff; - double lightspec; - double shininess; - double transp; - int locviewer; - char selectvisual[20]; - int showstltrias; - - Vec3d clipnormal; - double clipdist; - int clipenable; - int clipplanetimestamp; - - int colormeshsize; - - int drawfilledtrigs; - int drawbadels; - int drawoutline; - int drawedges; - int subdivisions; - - int drawprisms; - int drawpyramids; - int drawhexes; - double shrink; - int drawidentified; - int drawpointnumbers; - int drawedgenumbers; - int drawfacenumbers; - int drawelementnumbers; - int drawdomainsurf; - int drawtets; - int drawtetsdomain; - - int drawededges; - int drawedpoints; - int drawedpointnrs; - int drawedtangents; - int drawededgenrs; - - int drawcurveproj; - int drawcurveprojedge; - - - int centerpoint; - int drawelement; - - // stl: - int stlshowtrias; - int stlshowfilledtrias; - int stlshowedges; - int stlshowmarktrias; - int stlshowactivechart; - int stlchartnumber; - int stlchartnumberoffset; - - // occ: - int occshowvolumenr; - bool occshowsurfaces; - bool occshowedges; - bool occvisproblemfaces; - bool occzoomtohighlightedentity; - - bool whitebackground; - int stereo; - bool usedispllists; - bool drawcoordinatecross; - bool drawcolorbar; - bool drawnetgenlogo; - - -public: - VisualizationParameters(); -}; -extern VisualizationParameters vispar; -*/ - - - - - - -extern void InitDrawMesh (); -extern void DrawMesh (); -extern void MouseMove(int oldx, int oldy, - int newx, int newy, - char mode); - -extern void Render (); - - -class VisualScene -{ -protected: - static Point3d center; - static double rad; - - static float lookatmat[16]; - static float transmat[16]; - static float rotmat[16]; - static float centermat[16]; - static float transformationmat[16]; - - GLdouble clipplane[4]; - - int changeval; - static GLdouble backcolor; - -public: - static GLuint fontbase; - static GLubyte * colortexture; - static GLuint coltexname; - static int ntexcols; - // static bool linear_colors; - int invcolor; - - -public: - VisualScene (); - virtual ~VisualScene(); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - - void CalcTransformationMatrices(); - void StandardRotation (const char * dir); - void ArbitraryRotation (const ARRAY<double> & alpha, const ARRAY<Vec3d> & vec); - void ArbitraryRotation (const double alpha, const Vec3d & vec); - - void MouseMove(int oldx, int oldy, - int newx, int newy, - char mode); - - void LookAt (const Point<3> & cam, const Point<3> & obj, - const Point<3> & camup); - - void SetClippingPlane (); - - virtual void MouseDblClick (int px, int py); - - void SetLight (); - static void SetBackGroundColor (double col) - { backcolor = col; } - - void CreateTexture (int ncols, int linear, int typ = GL_DECAL); - void DrawColorBar (double minval, double maxval, int logscale = 0, bool linear = 1); - void DrawCoordinateCross (); - void DrawNetgenLogo (); - void SetOpenGlColor(double val, double valmin, double valmax, int logscale = 0); -}; - - -class VisualSceneGeometry : public VisualScene -{ - ARRAY<int> trilists; - int selsurf; -public: - VisualSceneGeometry (); - virtual ~VisualSceneGeometry (); - - virtual void SelectSurface (int aselsurf); - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); -}; - - - -class VisualSceneSTLGeometry : public VisualScene -{ - ARRAY<int> trilists; - -public: - VisualSceneSTLGeometry (); - virtual ~VisualSceneSTLGeometry (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); -}; - - -class VisualSceneGeometry2d : public VisualScene -{ -public: - VisualSceneGeometry2d (); - virtual ~VisualSceneGeometry2d (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); -}; - - -#ifdef OCCGEOMETRY -class VisualSceneOCCGeometry : public VisualScene -{ - ARRAY<int> trilists; - ARRAY<int> linelists; - int selsurf; -public: - VisualSceneOCCGeometry (); - virtual ~VisualSceneOCCGeometry (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - virtual void MouseDblClick (int px, int py); -}; -#endif - - - - -#ifdef STEP -class VisualSceneSTEPGeometry : public VisualScene -{ - ARRAY<int> gllists; - -public: - VisualSceneSTEPGeometry (); - virtual ~VisualSceneSTEPGeometry (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); -}; -#endif - - -class VisualSceneSTLMeshing : public VisualScene -{ - ARRAY<int> trilists; - int selecttrig, nodeofseltrig; - -public: - VisualSceneSTLMeshing (); - virtual ~VisualSceneSTLMeshing (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - virtual void MouseDblClick (int px, int py); - - int seltria; -}; - - - - -class VisualSceneSurfaceMeshing : public VisualScene -{ -public: - VisualSceneSurfaceMeshing (); - virtual ~VisualSceneSurfaceMeshing (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); -}; - - - - - - - -class VisualSceneMesh : public VisualScene -{ - int filledlist; - int linelist; - int pointnumberlist; - - int tetlist; - int prismlist; - int pyramidlist; - int hexlist; - - int badellist; - int identifiedlist; - int domainsurflist; - - int vstimestamp, selecttimestamp; - int filledtimestamp; - int linetimestamp; - int pointnumbertimestamp; - - int tettimestamp; - int prismtimestamp; - int pyramidtimestamp; - int hextimestamp; - - int badeltimestamp; - int identifiedtimestamp; - int domainsurftimestamp; - - NgLock *lock; - - int selface, selelement; - int selpoint, selpoint2, locpi; - int seledge; - - double minh, maxh; // for meshsize coloring - -public: - VisualSceneMesh (); - virtual ~VisualSceneMesh (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - virtual void MouseDblClick (int px, int py); - - int SelectedFace () const - { return selface; } - void SetSelectedFace (int asf) - { selface = asf; selecttimestamp = GetTimeStamp(); } - - int SelectedEdge () const - { return seledge; } - int SelectedElement () const - { return selelement; } - int SelectedPoint () const - { return selpoint; } -private: - void BuildFilledList(); - void BuildLineList(); - void BuildPointNumberList(); - - void BuildTetList(); - void BuildPrismList(); - void BuildPyramidList(); - void BuildHexList(); - - void BuildBadelList(); - void BuildIdentifiedList(); - void BuildDomainSurfList(); -}; - - - - - - - -class VisualSceneSpecPoints : public VisualScene -{ -public: - VisualSceneSpecPoints (); - virtual ~VisualSceneSpecPoints (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - - double len; -}; - -// extern struct Tcl_Interp * hinterp; - - -extern void AddVisualizationScene (const string & name, - VisualScene * vs); - - - -#endif - diff --git a/Netgen/libsrc/visualization/soldata.hpp b/Netgen/libsrc/visualization/soldata.hpp deleted file mode 100644 index 44e0d0a56e..0000000000 --- a/Netgen/libsrc/visualization/soldata.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef FILE_SOLDATA -#define FILE_SOLDATA - - -using namespace std; - -class SolutionData -{ -protected: - - string name; - int components; - bool iscomplex; - - int multidimcomponent; - -public: - SolutionData (const string & aname, - int acomponents = 1, bool aiscomplex = 0) - : name(aname), components(acomponents), iscomplex(aiscomplex) - { ; } - - virtual ~SolutionData () - { ; } - - int GetComponents() { return components; } - bool IsComplex() { return iscomplex; } - - virtual bool GetValue (int /* elnr */, - double /* lam1 */, double /* lam2 */, double /* lam3 */, - double * /* values */) - { return false; } - - virtual bool GetSurfValue (int /* selnr */, - double /* lam1 */, double /* lam2 */, - double * /* values */) - { return false; } - - void SetMultiDimComponent (int mc) - { multidimcomponent = mc; } -}; - - -#endif - diff --git a/Netgen/libsrc/visualization/stlmeshing.cpp b/Netgen/libsrc/visualization/stlmeshing.cpp deleted file mode 100644 index 45adac9d75..0000000000 --- a/Netgen/libsrc/visualization/stlmeshing.cpp +++ /dev/null @@ -1,1074 +0,0 @@ -#include <mystdlib.h> -#include <myadt.hpp> - -#include <linalg.hpp> -#include <stlgeom.hpp> - -#include <meshing.hpp> -#include <visual.hpp> - -namespace netgen -{ - -/* -//mmm -#include "stlgeom/modeller.hpp" -*/ - -/* *********************** Draw STL Geometry **************** */ - -extern STLGeometry * stlgeometry; -extern AutoPtr<Mesh> mesh; - - -#ifdef OPENGL - -// #include "../../ngtcltk/mvdraw.hpp" - - -VisualSceneSTLMeshing :: VisualSceneSTLMeshing () - : VisualScene() -{ - selecttrig = 0; - nodeofseltrig = 1; - stlgeometry->SetSelectTrig(selecttrig); - stlgeometry->SetNodeOfSelTrig(nodeofseltrig); -} - -VisualSceneSTLMeshing :: ~VisualSceneSTLMeshing () -{ - ; -} - -void VisualSceneSTLMeshing :: DrawScene () -{ - int i, j, k; - - if (changeval != stlgeometry->GetNT()) - BuildScene(); - changeval = stlgeometry->GetNT(); - - int colormeshsize = vispar.colormeshsize; - - double hmin, hmax; - - if (colormeshsize) - { - hmax = -1E50; - hmin = +1E50; - double ms; - - for (i = 1; i <= stlgeometry->GetNP(); i++) - { - ms = mesh->GetH (stlgeometry->GetPoint(i)); - hmin = min2(hmin,ms); - hmax = max2(hmax,ms); - } - - //hmax = mparam.maxh; - //hmin = mesh->GetMinH (stlgeometry->GetBoundingBox().PMin(), - // stlgeometry->GetBoundingBox().PMax()); - - if (hmin == 0) hmin = 0.1 * hmax; - //hmax *= 1.1; - } - - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - SetLight(); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - SetClippingPlane (); - - glShadeModel (GL_SMOOTH); - glDisable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - float mat_spec_col[] = { 1, 1, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); - - double shine = vispar.shininess; - double transp = vispar.transp; - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); - glLogicOp (GL_COPY); - - float mat_colred[] = { 0.9f, 0.0f, 0.0f, 1.0f }; - float mat_colgreen[] = { 0.0f, 0.9f, 0.0f, 1.0f }; - float mat_colblue[] = { 0.1f, 0.1f, 1.0f, 1.0f }; - - float mat_colbluegreen[] = { 0.1f, 0.5f, 0.9f, 1.0f }; - float mat_colpink[] = { 1.0f, 0.1f, 0.5f, 1.0f }; - float mat_colviolet[] = { 1.0f, 0.1f, 1.0f, 1.0f }; - float mat_colbrown[] = { 0.8f, 0.6f, 0.1f, 1.0f }; - float mat_colorange[] = { 0.9f, 0.7f, 0.1f, 1.0f }; - float mat_colturquis[] = { 0.0f, 1.0f, 0.8f, 1.0f }; - - float mat_colgrey[] = { 0.3f, 0.3f, 0.3f, 1.0f }; - - float mat_collred[] = { 1.0f, 0.5f, 0.5f, 1.0f }; - float mat_collgreen[] = { 0.2f, 1.9f, 0.2f, 1.0f }; - float mat_collbrown[] = { 1.0f, 0.8f, 0.3f, 1.0f }; - - float mat_collgrey[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - float mat_colmgrey[] = { 0.4f, 0.4f, 0.4f, 1.0f }; - - float mat_colstlbody[] = { 0.0f, 0.0f, 0.8f, 1.0f }; - float mat_colseltrig[] = { 0.7f, 0.7f, 0.3f, 1.0f }; - float mat_colseledge[] = { 0.7f, 0.7f, 1.0f, 1.0f }; - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colblue); - - float pgoff = 0.5f; - - glPolygonOffset (pgoff*1, pgoff*1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glEnable (GL_NORMALIZE); - - /* - { - //mmm - //test modeller - Modeller model; - - //MoZylinder z1(Point3d(0,0,0),Vec3d(100,0,0),20,0.01); - //model.Add(&z1); - //MoZylinder z2(Point3d(50,50,0),Vec3d(0,-100,0),20,0.01); - //model.Add(&z2); - - MoZylinder z1(Point3d(0,0,0),Vec3d(100,0,0),20,0.01); - MoZylinder z2(Point3d(50,50,0),Vec3d(0,-100,0),20,0.01); - MoCombine cb1(&z1,&z2); - model.Add(&cb1); - - ARRAY<MoTriangle> trigs; - model.GetTriangles(trigs); - int i, k; - glBegin (GL_TRIANGLES); - for (i = 1; i <= trigs.Size(); i++) - { - const MoTriangle & tria = trigs.Get(i); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - - for (k = 0; k < 3; k++) - { - glVertex3f (tria.pts[k].X(), - tria.pts[k].Y(), - tria.pts[k].Z()); - } - } - glEnd (); - - - } - -*/ - - - - - if (!stlgeometry->trigsconverted) - { - glBegin (GL_TRIANGLES); - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - /* - if (j % 10 == seltria) - glMaterialfv (GL_FRONT_AND_BACK, - GL_AMBIENT_AND_DIFFUSE, mat_colred); - */ - - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - /* - const STLReadTriangle & tria = stlgeometry -> GetReadTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - - - for (k = 1; k <= 3; k++) - { - const Point3d & tp = stlgeometry->GetPoint(stlgeometry->GetTriangle(j).PNum(k)); - glVertex3f (tp.X(), tp.Y(), tp.Z()); - - } - /* - if (j%10 == seltria) - glMaterialfv (GL_FRONT_AND_BACK, - GL_AMBIENT_AND_DIFFUSE, mat_colblue); - */ - } - glEnd (); - - glDisable (GL_POLYGON_OFFSET_FILL); - - int showtrias = vispar.stlshowtrias; - - if (showtrias) - { - float mat_coll[] = { 0.2, 0.2, 0.2, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_coll); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - glEnable (GL_NORMALIZE); - - glBegin (GL_TRIANGLES); - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - /* - const STLReadTriangle & tria = stlgeometry -> GetReadTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - - for (k = 1; k <= 3; k++) - { - const Point3d & tp = - stlgeometry->GetPoint(stlgeometry->GetTriangle(j).PNum(k)); - glVertex3f (tp.X(), tp.Y(), tp.Z()); - - } - - /* - for (k = 0; k < 3; k++) - { - glVertex3f (tria.pts[k].X(), - tria.pts[k].Y(), - tria.pts[k].Z()); - } - */ - } - glEnd (); - } - } - else - { - int showfilledtrias = vispar.stlshowfilledtrias; - - //(*mycout) << "in " << showfilledtrias << ", NT=" << stlgeometry -> GetNT() << endl; - - int chartnumber; - if (vispar.stlshowmarktrias) - chartnumber = vispar.stlchartnumber + vispar.stlchartnumberoffset; - else - chartnumber = stlgeometry->GetMeshChartNr(); - - if (showfilledtrias) - { - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - if (colormeshsize) - glEnable (GL_COLOR_MATERIAL); - - glPolygonOffset (pgoff*4, pgoff*4); - glEnable (GL_POLYGON_OFFSET_FILL); - glEnable (GL_NORMALIZE); - - - glBegin (GL_TRIANGLES); - - int selt = stlgeometry -> GetSelectTrig(); - if (stldoctor.selectmode != 0) - {selt = 0; } //do not show selected triangle!!!! - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colstlbody); - - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) {continue;} - - if (j == selt) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colseltrig); - } - else if (j == selt+1) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colstlbody); - } - - const STLTriangle& st = stlgeometry -> GetTriangle(j); - - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - - /* - const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - for (k = 0; k < 3; k++) - { - const Point3d & p = stlgeometry->GetPoint(st[k]); - if (colormeshsize) - { - SetOpenGlColor (mesh->GetH (p), hmin, hmax, 1); - } - - glVertex3f (p.X(), p.Y(), p.Z()); - } - } - - glEnd (); - } - - int foundseltrig = stlgeometry -> GetSelectTrig(); - if (foundseltrig == 0 || foundseltrig > stlgeometry->GetNT() || - (stldoctor.showvicinity && !stlgeometry->Vicinity(foundseltrig))) - {foundseltrig = 0;} - - if (foundseltrig) - { - - glPolygonOffset (pgoff*0, 0); - glEnable (GL_POLYGON_OFFSET_FILL); - - //glDisable (GL_POLYGON_OFFSET_FILL); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colseledge); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - glEnable (GL_NORMALIZE); - - if (stldoctor.selectmode == 2) - { - //point - const STLTriangle& st = stlgeometry -> GetTriangle(foundseltrig); - const Point3d & p1 = stlgeometry->GetPoint(st[0]); - const Point3d & p2 = stlgeometry->GetPoint(st[1]); - const Point3d & p3 = stlgeometry->GetPoint(st[2]); - - double cs = (Dist(p1,p2)+Dist(p2,p3)+Dist(p3,p1))/100.; - - const Point3d & p = stlgeometry->GetPoint(st[nodeofseltrig-1]); - - glLineWidth (4); - glBegin (GL_LINES); - glVertex3f(p.X()+cs, p.Y()+cs, p.Z()+cs); - glVertex3f(p.X()-cs, p.Y()-cs, p.Z()-cs); - - glVertex3f(p.X()-cs, p.Y()+cs, p.Z()+cs); - glVertex3f(p.X()+cs, p.Y()-cs, p.Z()-cs); - - glVertex3f(p.X()-cs, p.Y()+cs, p.Z()+cs); - glVertex3f(p.X()+cs, p.Y()-cs, p.Z()-cs); - - glVertex3f(p.X()+cs, p.Y()-cs, p.Z()+cs); - glVertex3f(p.X()-cs, p.Y()+cs, p.Z()-cs); - - glEnd (); - glLineWidth (1); - } - else if (stldoctor.selectmode == 1 || - stldoctor.selectmode == 3 || - stldoctor.selectmode == 4) - { - //multiedge - - const ARRAY<twoint>& me = stlgeometry->SelectedMultiEdge(); - if (stlgeometry->GetSelectTrig() > 0 && - stlgeometry->GetSelectTrig() <= stlgeometry->GetNT() && - me.Size()) - { - - int en = stlgeometry->EdgeDataList().GetEdgeNum(me.Get(1).i1,me.Get(1).i2); - int status = stlgeometry->EdgeDataList().Get(en).GetStatus(); - - switch (status) - { - case ED_CONFIRMED: - glMaterialfv (GL_FRONT_AND_BACK, - GL_AMBIENT_AND_DIFFUSE, mat_collgreen); - break; - case ED_CANDIDATE: - glMaterialfv (GL_FRONT_AND_BACK, - GL_AMBIENT_AND_DIFFUSE, mat_collbrown); - break; - case ED_EXCLUDED: - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_collred); - break; - } - - glLineWidth (2); - glBegin (GL_LINES); - for (j = 1; j <= me.Size(); j++) - { - Point3d p1 = stlgeometry->GetPoint(me.Get(j).i1); - Point3d p2 = stlgeometry->GetPoint(me.Get(j).i2); - - glVertex3f(p1.X(), p1.Y(), p1.Z()); - glVertex3f(p2.X(), p2.Y(), p2.Z()); - } - glEnd (); - glLineWidth (1); - } - } - } - - int showmarktrias = vispar.stlshowmarktrias || vispar.stlshowactivechart; - - if (stldoctor.showmarkedtrigs) - { - //(*mycout) << "marked" << endl; - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); //GL_LINE - glPolygonOffset (pgoff*1, pgoff*1); - glEnable (GL_POLYGON_OFFSET_FILL); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbluegreen); - glEnable (GL_NORMALIZE); - - glBegin (GL_TRIANGLES); - - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) - {continue;} - - if (!stlgeometry->IsMarkedTrig(j)) - {continue;} - - const STLTriangle& st = stlgeometry -> GetTriangle(j); - - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - /* - const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - for (k = 0; k < 3; k++) - { - const Point3d & p = stlgeometry->GetPoint(st[k]); - glVertex3f (p.X(), p.Y(), p.Z()); - } - } - glEnd (); - - //show OpenSegments on original geometry - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colviolet); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - glPolygonOffset (pgoff*1, 1); - - glEnable (GL_NORMALIZE); - - glBegin (GL_LINES); - - if (stlgeometry->GetNMarkedSegs()) - { - Point<3> p1,p2; - for (j = 1; j <= stlgeometry -> GetNMarkedSegs(); j++) - { - stlgeometry->GetMarkedSeg(j,p1,p2); - glVertex3dv(&p1(0)); - glVertex3dv(&p2(0)); - } - } - glEnd (); - } - - - if (stldoctor.showfaces) - { - int facenumber = vispar.stlchartnumber + vispar.stlchartnumberoffset; - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - glPolygonOffset (pgoff*3, 3); - glEnable (GL_POLYGON_OFFSET_FILL); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_collgrey); - glEnable (GL_NORMALIZE); - - glBegin (GL_TRIANGLES); - - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) - {continue;} - - //(*mycout) << " facenum = " << stlgeometry->GetTriangle(j).GetFaceNum() << " "; - if (stlgeometry->GetTriangle(j).GetFaceNum() != facenumber) - {continue;} - - const STLTriangle& st = stlgeometry -> GetTriangle(j); - - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - /* - const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - for (k = 0; k < 3; k++) - { - Point3d p = stlgeometry->GetPoint(st[k]); - glVertex3f (p.X(), p.Y(), p.Z()); - } - } - glEnd (); - } - - if (showmarktrias && stlgeometry->AtlasMade()) - { - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - glPolygonOffset (pgoff*3, 3); - glEnable (GL_POLYGON_OFFSET_FILL); - - glBegin (GL_TRIANGLES); - - if (chartnumber >= 1 && chartnumber <= stlgeometry->GetNOCharts()) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbrown); - const STLChart& chart = stlgeometry->GetChart(chartnumber); - for (j = 1; j <= chart.GetNChartT(); j++) - { - /* - if (j == charttrignumber) - {glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred);} - else - {glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbrown);} - */ - const STLTriangle& st = stlgeometry -> GetTriangle(chart.GetChartTrig(j)); - - - const Vec3d & n = stlgeometry->GetTriangle(chart.GetChartTrig(j)).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - /* - const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(chart.GetChartTrig(j)); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - for (k = 0; k < 3; k++) - { - glVertex3f (stlgeometry->GetPoint(st[k])(0), - stlgeometry->GetPoint(st[k])(1), - stlgeometry->GetPoint(st[k])(2)); - } - } - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); - - for (j = 1; j <= chart.GetNOuterT(); j++) - { - - const STLTriangle& st = stlgeometry -> GetTriangle(chart.GetOuterTrig(j)); - - const Vec3d & n = stlgeometry->GetTriangle(chart.GetOuterTrig(j)).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - - - /* - const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(chart.GetOuterTrig(j)); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - for (k = 0; k < 3; k++) - { - glVertex3f (stlgeometry->GetPoint(st[k])(0), - stlgeometry->GetPoint(st[k])(1), - stlgeometry->GetPoint(st[k])(2)); - } - } - } - glEnd (); - } - - int showtrias = vispar.stlshowtrias; - - if (showtrias) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgrey); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - glPolygonOffset (pgoff*2, 2); - glEnable (GL_POLYGON_OFFSET_FILL); - glEnable (GL_NORMALIZE); - - glBegin (GL_TRIANGLES); - - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) {continue;} - - const STLTriangle& st = stlgeometry -> GetTriangle(j); - - const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); - glNormal3f (n.X(), n.Y(), n.Z()); - /* - const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); - glNormal3f (tria.normal.X(), - tria.normal.Y(), - tria.normal.Z()); - */ - for (k = 0; k < 3; k++) - { - glVertex3f (stlgeometry->GetPoint(st[k])(0), - stlgeometry->GetPoint(st[k])(1), - stlgeometry->GetPoint(st[k])(2)); - } - } - glEnd (); - } - - int showedges = vispar.stlshowedges; - - if (showedges) - { - glPolygonOffset (pgoff*1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - //glDisable (GL_POLYGON_OFFSET_FILL); - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - - glEnable (GL_NORMALIZE); - - glBegin (GL_LINES); - - /* - if (stldoctor.useexternaledges) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colorange); - for (j = 1; j <= stlgeometry -> NOExternalEdges(); j++) - { - twoint v = stlgeometry->GetExternalEdge(j); - Point3d p1 = stlgeometry->GetPoint(v.i1); - Point3d p2 = stlgeometry->GetPoint(v.i2); - - Vec3d n1 = stlgeometry->GetNormal(v.i1); - Vec3d n2 = stlgeometry->GetNormal(v.i2); - - glNormal3f(n1.X(), n1.Y(), n1.Z()); - glVertex3f(p1.X(), p1.Y(), p1.Z()); - glNormal3f(n2.X(), n2.Y(), n2.Z()); - glVertex3f(p2.X(), p2.Y(), p2.Z()); - } - } - */ - - - if (!stlgeometry->meshlines.Size() || !stldoctor.drawmeshededges) - { - /* - for (j = 1; j <= stlgeometry -> GetNE(); j++) - { - STLEdge v = stlgeometry->GetEdge(j); - Point3d p1 = stlgeometry->GetPoint(v.pts[0]); - Point3d p2 = stlgeometry->GetPoint(v.pts[1]); - - Vec3d n1 = stlgeometry->GetNormal(v.pts[0]); - Vec3d n2 = stlgeometry->GetNormal(v.pts[1]); - - glNormal3f(n1.X(), n1.Y(), n1.Z()); - glVertex3f(p1.X(), p1.Y(), p1.Z()); - glNormal3f(n2.X(), n2.Y(), n2.Z()); - glVertex3f(p2.X(), p2.Y(), p2.Z()); - } - */ - const STLEdgeDataList& ed = stlgeometry->EdgeDataList(); - for (i = 1; i <= ed.Size(); i++) - { - if (ed.Get(i).GetStatus() != ED_UNDEFINED) - { - switch (ed.Get(i).GetStatus()) - { - case ED_CONFIRMED: - glMaterialfv (GL_FRONT_AND_BACK, - GL_AMBIENT_AND_DIFFUSE, mat_colgreen); - break; - case ED_CANDIDATE: - glMaterialfv (GL_FRONT_AND_BACK, - GL_AMBIENT_AND_DIFFUSE, mat_colbrown); - break; - case ED_EXCLUDED: - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred); - break; - } - - if (ed.Get(i).GetStatus() == ED_EXCLUDED && !stldoctor.showexcluded) continue; - - Point3d p1 = stlgeometry->GetPoint(ed.Get(i).PNum(1)); - Point3d p2 = stlgeometry->GetPoint(ed.Get(i).PNum(2)); - glVertex3f(p1.X(), p1.Y(), p1.Z()); - glVertex3f(p2.X(), p2.Y(), p2.Z()); - } - } - } - - /* - else - if (stlgeometry->meshlines.Size() == 0) - { - for (j = 1; j <= stlgeometry->GetNLines(); j++) - { - STLLine* line = stlgeometry->GetLine(j); - int pn1, pn2; - for (int k = 1; k <= line->NP()-1; k++) - { - pn1 = line->PNum(k); - pn2 = line->PNum(k+1); - - Point3d p1 = stlgeometry->GetPoint(pn1); - Point3d p2 = stlgeometry->GetPoint(pn2); - - Vec3d n1 = stlgeometry->GetNormal(pn1); - Vec3d n2 = stlgeometry->GetNormal(pn2); - - glNormal3f(n1.X(), n1.Y(), n1.Z()); - glVertex3f(p1.X(), p1.Y(), p1.Z()); - glNormal3f(n2.X(), n2.Y(), n2.Z()); - glVertex3f(p2.X(), p2.Y(), p2.Z()); - } - } - } - */ - - else if (stlgeometry->meshlines.Size() != 0) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); - for (j = 1; j <= stlgeometry->meshlines.Size(); j++) - { - STLLine* line = stlgeometry->meshlines.Get(j); - int pn1, pn2; - for (int k = 1; k <= line->NP()-1; k++) - { - pn1 = line->PNum(k); - pn2 = line->PNum(k+1); - - Point3d p1 = stlgeometry->meshpoints.Get(pn1); - Point3d p2 = stlgeometry->meshpoints.Get(pn2); - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); - glVertex3f(p1.X(), p1.Y(), p1.Z()); - glVertex3f(p2.X(), p2.Y(), p2.Z()); - - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred); - double cs = 0.02*Dist(p1,p2); - glVertex3f(p1.X()+cs, p1.Y()+cs, p1.Z()+cs); - glVertex3f(p1.X()-cs, p1.Y()-cs, p1.Z()-cs); - glVertex3f(p2.X()+cs, p2.Y()+cs, p2.Z()+cs); - glVertex3f(p2.X()-cs, p2.Y()-cs, p2.Z()-cs); - - glVertex3f(p1.X()-cs, p1.Y()+cs, p1.Z()+cs); - glVertex3f(p1.X()+cs, p1.Y()-cs, p1.Z()-cs); - glVertex3f(p2.X()-cs, p2.Y()+cs, p2.Z()+cs); - glVertex3f(p2.X()+cs, p2.Y()-cs, p2.Z()-cs); - - } - } - } - - - glEnd (); - } - - if (stldoctor.showedgecornerpoints && stlgeometry->LineEndPointsSet()) - { - glPointSize (5); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred); - glBegin (GL_POINTS); - for (i = 1; i <= stlgeometry->GetNP(); i++) - { - if (stlgeometry->IsLineEndPoint(i)) - { - const Point3d p = stlgeometry->GetPoint(i); - glVertex3f (p.X(), p.Y(), p.Z()); - } - } - glEnd(); - - } - - - } - - - glPopMatrix(); - - if (vispar.colormeshsize) - DrawColorBar (hmin, hmax, 1); - - glFinish(); -} - - -void VisualSceneSTLMeshing :: BuildScene (int zoomall) -{ - if (selecttrig && zoomall == 2) - center = stlgeometry -> GetPoint ( stlgeometry->GetTriangle(selecttrig).PNum(nodeofseltrig)); - else - center = stlgeometry -> GetBoundingBox().Center(); - - rad = stlgeometry -> GetBoundingBox().Diam() / 2; - - CalcTransformationMatrices(); -} - - - -void VisualSceneSTLMeshing :: MouseDblClick (int px, int py) -{ - // (*mycout) << "dblclick: " << px << " - " << py << endl; - - - int i, j, k, hits; - - // select surface triangle by mouse click - - GLuint selbuf[10000]; - glSelectBuffer (10000, selbuf); - - - glRenderMode (GL_SELECT); - - GLint viewport[4]; - glGetIntegerv (GL_VIEWPORT, viewport); - - /* - (*mycout) << "viewport = " << viewport[0] << " " - << viewport[1] << " " << viewport[2] << " " << viewport[3] << endl; - */ - - glMatrixMode (GL_PROJECTION); - glPushMatrix(); - - - GLdouble projmat[16]; - glGetDoublev (GL_PROJECTION_MATRIX, projmat); - - glLoadIdentity(); - gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); - glMultMatrixd (projmat); - - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_MODELVIEW); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - - glInitNames(); - glPushName (1); - - - glEnable (GL_POLYGON_OFFSET_FILL); - for (j = 1; j <= stlgeometry -> GetNT(); j++) - { - if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) {continue;} - - const STLTriangle& st = stlgeometry -> GetTriangle(j); - - //const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); - //glNormal3f (tria.normal.X(), tria.normal.Y(), tria.normal.Z()); - - if (stldoctor.selectmode == 0) - { - glLoadName (j); - glBegin (GL_TRIANGLES); - for (k = 0; k < 3; k++) - { - Point3d p = stlgeometry->GetPoint(st[k]); - glVertex3f (p.X(), p.Y(), p.Z()); - } - glEnd (); - } - else if (stldoctor.selectmode == 1 || stldoctor.selectmode == 3 - || stldoctor.selectmode == 4) - { - Point3d pm = Center(stlgeometry->GetPoint(st[0]), - stlgeometry->GetPoint(st[1]), - stlgeometry->GetPoint(st[2])); - - for (k = 0; k < 3; k++) - { - glLoadName (j*3+k-2); - glBegin (GL_TRIANGLES); - - Point3d p1 = stlgeometry->GetPoint(st[k]); - Point3d p2 = stlgeometry->GetPoint(st[(k+1)%3]); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glVertex3f (pm.X(), pm.Y(), pm.Z()); - - glEnd (); - } - } - else - { - Point3d pm1 = Center(stlgeometry->GetPoint(st[0]), - stlgeometry->GetPoint(st[1])); - Point3d pm2 = Center(stlgeometry->GetPoint(st[1]), - stlgeometry->GetPoint(st[2])); - Point3d pm3 = Center(stlgeometry->GetPoint(st[2]), - stlgeometry->GetPoint(st[0])); - - Point3d p1 = stlgeometry->GetPoint(st[0]); - Point3d p2 = stlgeometry->GetPoint(st[1]); - Point3d p3 = stlgeometry->GetPoint(st[2]); - - glLoadName (j*4-3); - glBegin (GL_TRIANGLES); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (pm1.X(), pm1.Y(), pm1.Z()); - glVertex3f (pm3.X(), pm3.Y(), pm3.Z()); - glEnd (); - - glLoadName (j*4-2); - glBegin (GL_TRIANGLES); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glVertex3f (pm2.X(), pm2.Y(), pm2.Z()); - glVertex3f (pm1.X(), pm1.Y(), pm1.Z()); - glEnd (); - - glLoadName (j*4-1); - glBegin (GL_TRIANGLES); - glVertex3f (p3.X(), p3.Y(), p3.Z()); - glVertex3f (pm3.X(), pm3.Y(), pm3.Z()); - glVertex3f (pm2.X(), pm2.Y(), pm2.Z()); - glEnd (); - - glLoadName (j*4); - glBegin (GL_TRIANGLES); - glVertex3f (pm1.X(), pm1.Y(), pm1.Z()); - glVertex3f (pm2.X(), pm2.Y(), pm2.Z()); - glVertex3f (pm3.X(), pm3.Y(), pm3.Z()); - glEnd (); - } - } - - glPopName(); - - glMatrixMode (GL_PROJECTION); - glPopMatrix(); - - glMatrixMode (GL_MODELVIEW); - glPopMatrix(); - - glFlush(); - - - hits = glRenderMode (GL_RENDER); - - // (*mycout) << "hits = " << hits << endl; - - //int minrec = -1; - int minname = 0; - GLuint mindepth = 0; - for (i = 0; i < hits; i++) - { - int curname = selbuf[4*i+3]; - GLuint curdepth = selbuf[4*i+1]; - - /* - (*mycout) << selbuf[4*i] << " " << selbuf[4*i+1] << " " - << selbuf[4*i+2] << " " << selbuf[4*i+3] << endl; - */ - if (curname && - (curdepth < mindepth || !minname)) - { - //minrec = i; - mindepth = curdepth; - minname = curname; - } - } - - if (!minname) {return;} - - if (stldoctor.selectmode == 0) - { - int oldtrig = selecttrig; - selecttrig = minname; - if (selecttrig == oldtrig) - nodeofseltrig = (nodeofseltrig % 3) + 1; - else - nodeofseltrig = 1; - - stlgeometry->SetSelectTrig(selecttrig); - stlgeometry->SetNodeOfSelTrig(nodeofseltrig); - stlgeometry->PrintSelectInfo(); - - } - else if (stldoctor.selectmode == 1 || stldoctor.selectmode == 3 || stldoctor.selectmode == 4) - { - selecttrig = (minname-1) / 3 + 1; - nodeofseltrig = minname-selecttrig*3+3; - - stlgeometry->SetSelectTrig(selecttrig); - stlgeometry->SetNodeOfSelTrig(nodeofseltrig); - stlgeometry->PrintSelectInfo(); - - if (stldoctor.selectmode == 1) - { - stlgeometry->BuildSelectedEdge(twoint(stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig), - stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig+1))); - } - if (stldoctor.selectmode == 3) - { - stlgeometry->BuildSelectedMultiEdge(twoint(stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig), - stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig+1))); - } - else if (stldoctor.selectmode == 4) - { - stlgeometry->BuildSelectedCluster(twoint(stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig), - stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig+1))); - } - - switch (stldoctor.edgeselectmode) - { - case 1: stlgeometry->STLDoctorUndefinedEdge(); break; - case 2: stlgeometry->STLDoctorConfirmEdge(); break; - case 3: stlgeometry->STLDoctorCandidateEdge(); break; - case 4: stlgeometry->STLDoctorExcludeEdge(); break; - default: break; - } - } - else if (stldoctor.selectmode == 2) - { - selecttrig = (minname-1) / 4 + 1; - nodeofseltrig = minname-selecttrig*4+4; - if (nodeofseltrig == 4) {nodeofseltrig = 1;} - - stlgeometry->SetSelectTrig(selecttrig); - stlgeometry->SetNodeOfSelTrig(nodeofseltrig); - stlgeometry->PrintSelectInfo(); - - } - - if (stldoctor.showtouchedtrigchart && stlgeometry->AtlasMade() && stlgeometry->GetSelectTrig()) - { - vispar.stlchartnumber = stlgeometry->GetChartNr(stlgeometry->GetSelectTrig()); - vispar.stlchartnumberoffset = 0; - } - -} - - - - -VisualSceneSTLMeshing vsstlmeshing; - -#endif - - - - -} diff --git a/Netgen/libsrc/visualization/vispar.hpp b/Netgen/libsrc/visualization/vispar.hpp deleted file mode 100644 index 3a35294182..0000000000 --- a/Netgen/libsrc/visualization/vispar.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef FILE_VISPAR -#define FILE_VISPAR - -class VisualizationParameters -{ -public: - double lightamb; - double lightdiff; - double lightspec; - double shininess; - double transp; - int locviewer; - char selectvisual[20]; - int showstltrias; - - Vec3d clipnormal; - double clipdist; - int clipenable; - int clipplanetimestamp; - - int colormeshsize; - - int drawfilledtrigs; - int drawbadels; - int drawoutline; - int drawedges; - int subdivisions; - - int drawprisms; - int drawpyramids; - int drawhexes; - double shrink; - int drawidentified; - int drawpointnumbers; - int drawedgenumbers; - int drawfacenumbers; - int drawelementnumbers; - int drawdomainsurf; - int drawtets; - int drawtetsdomain; - - int drawededges; - int drawedpoints; - int drawedpointnrs; - int drawedtangents; - int drawededgenrs; - int drawmetispartition; - - int drawcurveproj; - int drawcurveprojedge; - - - int centerpoint; - int drawelement; - - // stl: - int stlshowtrias; - int stlshowfilledtrias; - int stlshowedges; - int stlshowmarktrias; - int stlshowactivechart; - int stlchartnumber; - int stlchartnumberoffset; - - // occ: - int occshowvolumenr; - bool occshowsurfaces; - bool occshowedges; - bool occvisproblemfaces; - bool occzoomtohighlightedentity; - double occdeflection; - - bool whitebackground; - int stereo; - bool usedispllists; - bool drawcoordinatecross; - bool drawcolorbar; - bool drawnetgenlogo; - - bool use_center_coords; - double centerx,centery,centerz; - - -public: - VisualizationParameters(); -}; -extern VisualizationParameters vispar; - -#endif diff --git a/Netgen/libsrc/visualization/visual.hpp b/Netgen/libsrc/visualization/visual.hpp deleted file mode 100644 index 3e5910b351..0000000000 --- a/Netgen/libsrc/visualization/visual.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef FILE_VISUAL -#define FILE_VISUAL - -/* *************************************************************************/ -/* File: visual.hpp */ -/* Author: Joachim Schoeberl */ -/* Date: 02. Dec. 01 */ -/* *************************************************************************/ - -/* - -Visualization - -*/ - -#include <incvis.hpp> - -namespace netgen -{ -#include "mvdraw.hpp" -#include "soldata.hpp" -#include "vssolution.hpp" -#include "meshdoc.hpp" -} - -#endif diff --git a/Netgen/libsrc/visualization/vscsg.cpp b/Netgen/libsrc/visualization/vscsg.cpp deleted file mode 100644 index d17c0c38e2..0000000000 --- a/Netgen/libsrc/visualization/vscsg.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include <mystdlib.h> -#include "incvis.hpp" - -#include <myadt.hpp> -#include <meshing.hpp> -#include <csg.hpp> -#include <stlgeom.hpp> - - -namespace netgen -{ -#include "mvdraw.hpp" - -/* *********************** Draw Geometry **************** */ - - - - -extern AutoPtr<CSGeometry> geometry; - - -VisualSceneGeometry :: VisualSceneGeometry () - : VisualScene() -{ - selsurf = 0; -} - -VisualSceneGeometry :: ~VisualSceneGeometry () -{ - ; -} - -void VisualSceneGeometry :: SelectSurface (int aselsurf) -{ - selsurf = aselsurf; - DrawScene(); -} - - -void VisualSceneGeometry :: DrawScene () -{ - int i; - - if (changeval != geometry->GetChangeVal()) - BuildScene(); - changeval = geometry->GetChangeVal(); - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - SetLight(); - - - glPushMatrix(); - glMultMatrixf (transformationmat); - - SetClippingPlane (); - - glShadeModel (GL_SMOOTH); - glDisable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* - float mat_spec_col[] = { 1, 1, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); - */ - - double shine = vispar.shininess; - double transp = vispar.transp; - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); - glLogicOp (GL_COPY); - - glEnable (GL_NORMALIZE); - - for (i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - const TopLevelObject * tlo = geometry -> GetTopLevelObject (i); - if (tlo->GetVisible() && !tlo->GetTransparent()) - { - float mat_col[] = { tlo->GetRed(), tlo->GetGreen(), tlo->GetBlue(), 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - glCallList (trilists[i]); - } - } - - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glLogicOp (GL_NOOP); - for (i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - const TopLevelObject * tlo = geometry -> GetTopLevelObject (i); - if (tlo->GetVisible() && tlo->GetTransparent()) - { - float mat_col[] = { tlo->GetRed(), tlo->GetGreen(), tlo->GetBlue(), transp }; - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - glCallList (trilists[i]); - } - } - - glDisable (GL_POLYGON_OFFSET_FILL); - - glPopMatrix(); - - glDisable(GL_CLIP_PLANE0); - - DrawCoordinateCross (); - DrawNetgenLogo (); - - glFinish(); - -} - - -void VisualSceneGeometry :: BuildScene (int zoomall) -{ - int i, j, k; - - Box<3> box; - int hasp = 0; - for (i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - const TriangleApproximation & ta = - *geometry->GetTriApprox(i); - if (!&ta) continue; - - for (j = 0; j < ta.GetNP(); j++) - { - if (hasp) - box.Add (ta.GetPoint(j)); - else - { - hasp = 1; - box.Set (ta.GetPoint(j)); - } - } - } - if (hasp) - { - center = box.Center(); - rad = box.Diam() / 2; - } - else - { - center = Point3d(0,0,0); - rad = 1; - } - - CalcTransformationMatrices(); - - for (i = 0; i < trilists.Size(); i++) - glDeleteLists (trilists[i], 1); - trilists.SetSize(0); - - for (i = 0; i < geometry->GetNTopLevelObjects(); i++) - { - trilists.Append (glGenLists (1)); - glNewList (trilists.Last(), GL_COMPILE); - - glEnable (GL_NORMALIZE); - const TriangleApproximation & ta = - *geometry->GetTriApprox(i); - if (&ta) - { - glBegin (GL_TRIANGLES); - for (j = 0; j < ta.GetNT(); j++) - { - - for (k = 0; k < 3; k++) - { - int pi = ta.GetTriangle(j)[k]; - glNormal3f (ta.GetNormal (pi)(0), - ta.GetNormal (pi)(1), - ta.GetNormal (pi)(2)); - glVertex3f (ta.GetPoint(pi)(0), - ta.GetPoint(pi)(1), - ta.GetPoint(pi)(2)); - } - } - glEnd (); - } - glEndList (); - } - -} - - - - - -} diff --git a/Netgen/libsrc/visualization/vsmesh.cpp b/Netgen/libsrc/visualization/vsmesh.cpp deleted file mode 100644 index c53e5223be..0000000000 --- a/Netgen/libsrc/visualization/vsmesh.cpp +++ /dev/null @@ -1,3114 +0,0 @@ -#include <mystdlib.h> -#include "incvis.hpp" - - -#include <myadt.hpp> -#include <meshing.hpp> -#include <csg.hpp> -#include <stlgeom.hpp> - -namespace netgen -{ - -#include "mvdraw.hpp" - - - // #define FAST3DELEMENTS - - - - extern AutoPtr<Mesh> mesh; - extern STLGeometry * stlgeometry; - VisualSceneMesh vsmesh; - - - - VisualSceneMesh :: VisualSceneMesh () - : VisualScene() - { - filledlist = 0; - linelist = 0; - badellist = 0; - tetlist = 0; - prismlist = 0; - hexlist = 0; - pyramidlist = 0; - identifiedlist = 0; - pointnumberlist = 0; - domainsurflist = 0; - - vstimestamp = GetTimeStamp(); - selecttimestamp = GetTimeStamp(); - filledtimestamp = GetTimeStamp(); - linetimestamp = GetTimeStamp(); - pointnumbertimestamp = GetTimeStamp(); - - tettimestamp = GetTimeStamp(); - prismtimestamp = GetTimeStamp(); - hextimestamp = GetTimeStamp(); - pyramidtimestamp = GetTimeStamp(); - - badeltimestamp = GetTimeStamp(); - identifiedtimestamp = GetTimeStamp(); - domainsurftimestamp = GetTimeStamp(); - - - selface = -1; - selelement = -1; - locpi = 1; - selpoint = -1; - selpoint2 = -1; - seledge = -1; - } - - VisualSceneMesh :: ~VisualSceneMesh () - { - ; - } - - - // ARRAY<Point3d> drawel; - - void VisualSceneMesh :: DrawScene () - { - if (!mesh) - { - VisualScene::DrawScene(); - return; - } - - lock = NULL; - - BuildScene(); - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable (GL_COLOR_MATERIAL); - glColor3f (1.0f, 1.0f, 1.0f); - glLineWidth (1.0f); - - SetLight(); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - GLdouble projmat[16]; - glGetDoublev (GL_PROJECTION_MATRIX, projmat); - - - glInitNames (); - glPushName (0); - - // glEnable (GL_LINE_SMOOTH); - // glEnable (GL_BLEND); - // glEnable (GL_POLYGON_SMOOTH); - // glDisable (GL_DEPTH_TEST); - // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); - - glDisable (GL_COLOR_MATERIAL); - - GLfloat matcol0[] = { 0, 0, 0, 1 }; - GLfloat matcol1[] = { 1, 1, 1, 1 }; - GLfloat matcolf[] = { 0, 1, 0, 1 }; - GLfloat matcolb[] = { 0.5, 0, 0, 1 }; - GLfloat matcolblue[] = { 0, 0, 1, 1 }; - - glMatrixMode (GL_MODELVIEW); - - glMaterialfv(GL_FRONT, GL_EMISSION, matcol0); - glMaterialfv(GL_BACK, GL_EMISSION, matcol0); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matcol1); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolf); - glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, matcolb); - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - // glPolygonOffset (1,10); - glPolygonOffset (2,2); - glEnable (GL_POLYGON_OFFSET_FILL); - - SetClippingPlane (); - - if (vispar.drawfilledtrigs) - { - if (filledtimestamp < mesh->GetTimeStamp () || - filledtimestamp < selecttimestamp) - { - BuildFilledList (); - } - glCallList (filledlist); - } - - if (vispar.drawbadels) - glCallList (badellist); - - if (vispar.drawprisms) - { - BuildPrismList (); - static float prismcol[] = { 1.0f, 1.0f, 0.0f, 1.0f }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, prismcol); - glLineWidth (1.0f); - glCallList (prismlist); - } - - if (vispar.drawpyramids) - { - BuildPyramidList (); - static float pyramidcol[] = { 1.0f, 1.0f, 0.0f, 1.0f }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pyramidcol); - glLineWidth (1.0f); - glCallList (pyramidlist); - } - - if (vispar.drawhexes) - { - BuildHexList (); - static float hexcol[] = { 1.0f, 0.0f, 0.0f, 1.0f }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, hexcol); - glLineWidth (1.0f); - glCallList (hexlist); - } - - if (vispar.drawtets) - { - BuildTetList (); - static float tetcol[] = { 1.0f, 1.0f, 0.0f, 1.0f }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcol); - glLineWidth (1.0f); - glCallList (tetlist); - } - - if (vispar.drawdomainsurf) - { - BuildDomainSurfList(); - glCallList (domainsurflist); - } - - glDisable (GL_POLYGON_OFFSET_FILL); - - // draw lines - - glMatrixMode (GL_MODELVIEW); - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol0); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, matcol0); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matcol0); - - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - glLineWidth (1.0f); - glColor3f (0.0f, 0.0f, 0.0f); - glDisable (GL_LINE_SMOOTH); - - if (vispar.drawoutline) - { - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_LINE); - - if (linetimestamp < mesh->GetTimeStamp ()) - BuildLineList (); - - glCallList (linelist); - glDisable (GL_POLYGON_OFFSET_LINE); - } - - if (vispar.drawidentified) - { - glPolygonOffset (1, -1); - glEnable (GL_POLYGON_OFFSET_LINE); - glCallList (identifiedlist); - glDisable (GL_POLYGON_OFFSET_LINE); - } - - if (vispar.drawpointnumbers || - vispar.drawedgenumbers || - vispar.drawfacenumbers || - vispar.drawelementnumbers) - glCallList (pointnumberlist); - - - glPopName(); - - if (vispar.drawedges) - { - GLfloat matcoledge[] = { 0, 0, 1, 1 }; - GLfloat matcolsingedge[] = { 1, 0, 1, 1 }; - - glEnable (GL_POLYGON_OFFSET_LINE); - glPolygonOffset (1, -1); - glLineWidth (2); - - - for (int i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh->LineSegment(i); - const Point3d & p1 = (*mesh)[seg.p1]; - const Point3d & p2 = (*mesh)[seg.p2]; - - if (seg.singedge_left || seg.singedge_right) - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcolsingedge); - else - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcoledge); - - if (seg.edgenr == seledge) - glLineWidth(5); - else - glLineWidth(2); - - if (mesh->GetCurvedElements().IsHighOrder()) { - - int j; - int hoplotn = 1 << vispar.subdivisions; - // mesh->GetCurvedElements().GetNVisualSubsecs(); - - Point<3> x; - glBegin (GL_LINE_STRIP); - - for (int j = 0; j <= hoplotn; j++) - { - mesh->GetCurvedElements().CalcSegmentTransformation ((double) j/hoplotn, i-1, x); - glVertex3d (x(0), x(1), x(2)); - } - - glEnd(); - - } else { - - glBegin (GL_LINES); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glEnd(); - - } - } - - glLineWidth (2); - glDisable (GL_POLYGON_OFFSET_LINE); - } - - - if (selpoint > 0 && selpoint <= mesh->GetNP()) - { - glPointSize (10); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolblue); - glBegin (GL_POINTS); - - const Point3d p = mesh->Point(selpoint); - glVertex3f (p.X(), p.Y(), p.Z()); - glEnd(); - } - - - glDisable(GL_CLIP_PLANE0); - - glPopMatrix(); - - if (vispar.colormeshsize) - DrawColorBar (minh, maxh, 1); - - DrawCoordinateCross (); - DrawNetgenLogo (); - - if (lock) - { - lock -> UnLock(); - delete lock; - } - - glFinish(); - } - - - void VisualSceneMesh :: BuildScene (int zoomall) - { - if (!mesh) - { - VisualScene::BuildScene (zoomall); - return; - } - - int i, j; - - - Point3d pmin, pmax; - static double oldrad = 0; - - ARRAY<Element2d> faces; - - int meshtimestamp = mesh->GetTimeStamp(); - if (meshtimestamp > vstimestamp || zoomall) - { - mesh->GetBox (pmin, pmax, SURFACEPOINT); - - - if (selpoint >= 1 && zoomall == 2) - center = mesh->Point (selpoint); - else if (vispar.use_center_coords && zoomall == 2) - { - center.X() = vispar.centerx; center.Y() = vispar.centery; center.Z() = vispar.centerz; - } - else if (vispar.centerpoint >= 1 && zoomall == 2) - center = mesh->Point (vispar.centerpoint); - else - center = Center (pmin, pmax); - - rad = 0.5 * Dist (pmin, pmax); - - - if (rad > 1.5 * oldrad || - mesh->GetMajorTimeStamp() > vstimestamp || - zoomall) - { - CalcTransformationMatrices(); - oldrad = rad; - } - } - - glEnable (GL_NORMALIZE); - - if (pointnumberlist) - { - glDeleteLists (pointnumberlist, 1); - pointnumberlist = 0; - } - - if (badellist) - { - glDeleteLists (badellist, 1); - badellist = 0; - } - /* - if (prismlist) - { - glDeleteLists (prismlist, 1); - prismlist = 0; - } - - if (pyramidlist) - { - glDeleteLists (pyramidlist, 1); - pyramidlist = 0; - } - - if (hexlist) - { - glDeleteLists (hexlist, 1); - hexlist = 0; - } - */ - if (identifiedlist) - { - glDeleteLists (identifiedlist, 1); - identifiedlist = 0; - } - - - pointnumberlist = glGenLists (1); - glNewList (pointnumberlist, GL_COMPILE); - - if (vispar.drawpointnumbers || - vispar.drawedgenumbers || - vispar.drawfacenumbers || - vispar.drawelementnumbers) - { - glEnable (GL_COLOR_MATERIAL); - GLfloat textcol[3] = { 1 - backcolor, - 1 - backcolor, - 1 - backcolor }; - glColor3fv (textcol); - glNormal3d (0, 0, 1); - glPushAttrib (GL_LIST_BIT); - glListBase (fontbase); - - char buf[30]; - - if (vispar.drawpointnumbers) - for (i = 1; i <= mesh->GetNP(); i++) - { - const Point3d & p = mesh->Point(i); - glRasterPos3d (p.X(), p.Y(), p.Z()); - - sprintf (buf, "%d", i); - - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - } - - if (vispar.drawedgenumbers) - { - const MeshTopology & top = mesh->GetTopology(); - for (i = 1; i <= top.GetNEdges(); i++) - { - int v1, v2; - top.GetEdgeVertices (i, v1, v2); - const Point3d & p1 = mesh->Point(v1); - const Point3d & p2 = mesh->Point(v2); - const Point3d p = Center (p1, p2); - glRasterPos3d (p.X(), p.Y(), p.Z()); - - sprintf (buf, "%d", i); - - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - } - } - - - if (vispar.drawfacenumbers) - { - const MeshTopology & top = mesh->GetTopology(); - ARRAY<int> v; - for (i = 1; i <= top.GetNFaces(); i++) - { - top.GetFaceVertices (i, v); - const Point3d & p1 = mesh->Point(v.Elem(1)); - const Point3d & p2 = mesh->Point(v.Elem(2)); - const Point3d & p3 = mesh->Point(v.Elem(3)); - Point3d p; - if (v.Elem(4) == 0) - { - p = Center (p1, p2, p3); - } - else - { - const Point3d & p4 = mesh->Point(v.Elem(4)); - Point3d hp1 = Center (p1, p2); - Point3d hp2 = Center (p3, p4); - p = Center (hp1, hp2); - } - - glRasterPos3d (p.X(), p.Y(), p.Z()); - sprintf (buf, "%d", i); - glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); - } - } - - - glPopAttrib (); - glDisable (GL_COLOR_MATERIAL); - } - glEndList (); - - - - - - - - - - - - - - badellist = glGenLists (1); - glNewList (badellist, GL_COMPILE); - - if (vispar.drawbadels) - { - // SetClippingPlane (); - - static float badelcol[] = { 1.0f, 0.0f, 1.0f, 1.0f }; - glLineWidth (1.0f); - - for (i = 1; i <= mesh->GetNE(); i++) - { - if (mesh->VolumeElement(i).flags.badel || - mesh->VolumeElement(i).flags.illegal || - (i == vispar.drawelement)) - { - // copy to be thread-safe - Element el = mesh->VolumeElement (i); - el.GetSurfaceTriangles (faces); - - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, badelcol); - - - // if ( (el.GetNP() == 4) || (el.GetNP() == 10)) - if (el.PNum(1)) - { - glBegin (GL_TRIANGLES); - - for (j = 1; j <= faces.Size(); j++) - { - Element2d & face = faces.Elem(j); - const Point3d & lp1 = mesh->Point (el.PNum(face.PNum(1))); - const Point3d & lp2 = mesh->Point (el.PNum(face.PNum(2))); - const Point3d & lp3 = mesh->Point (el.PNum(face.PNum(3))); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - - glEnd(); - } - } - } - - - - for (i = 1; i <= mesh->GetNE(); i++) - { - if (mesh->VolumeElement(i).flags.badel) - { - // copy to be thread-safe - Element el = mesh->VolumeElement (i); - if ( (el.GetNP() == 4) || (el.GetNP() == 10)) - { - glBegin (GL_LINES); - glVertex3d (0,0,0); - const Point3d & p = mesh->Point(el.PNum(1)); - glVertex3d (p.X(), p.Y(), p.Z()); - glEnd(); - } - } - } - - - for (i = 1; i <= mesh->GetNE(); i++) - { - Element el = mesh->VolumeElement (i); - int hascp = 0; - for (j = 1; j <= el.GetNP(); j++) - if (el.PNum(j) == vispar.centerpoint) - hascp = 1; - - if (hascp) - { - (*testout) << "draw el " << i << " : "; - for (j = 1; j <= el.GetNP(); j++) - (*testout) << el.PNum(j) << " "; - (*testout) << endl; - - if (el.GetNP() == 4) - { - int et[6][2] = - { { 1, 2 }, - { 1, 3 }, - { 1, 4 }, - { 2, 3 }, - { 2, 4 }, - { 3, 4 } } ; - - for (j = 0; j < 6; j++) - { - glBegin (GL_LINES); - const Point3d & p1 = mesh->Point (el.PNum(et[j][0])); - const Point3d & p2 = mesh->Point (el.PNum(et[j][1])); - glVertex3d (p1.X(), p1.Y(), p1.Z()); - glVertex3d (p2.X(), p2.Y(), p2.Z()); - glEnd (); - } - } - - - if (el.GetNP() == 10) - { - int et[12][2] = - { { 1, 5 }, - { 2, 5 }, - { 1, 6 }, - { 3, 6 }, - { 1, 7 }, - { 4, 7 }, - { 2, 8 }, - { 3, 8 }, - { 2, 9 }, - { 4, 9 }, - { 3, 10 }, - { 4, 10 } }; - - for (j = 0; j < 12; j++) - { - glBegin (GL_LINES); - const Point3d & p1 = mesh->Point (el.PNum(et[j][0])); - const Point3d & p2 = mesh->Point (el.PNum(et[j][1])); - glVertex3d (p1.X(), p1.Y(), p1.Z()); - glVertex3d (p2.X(), p2.Y(), p2.Z()); - glEnd (); - } - } - } - } - - - for (i = 1; i <= mesh->GetNSE(); i++) - { - Element2d el = mesh->SurfaceElement(i); - if (!el.BadElement()) - continue; - - int drawel = 1; - for (j = 1; j <= el.GetNP(); j++) - if (!el.PNum(j)) - drawel = 0; - - if (!drawel) - continue; - - cout << int (el.GetType()) << " " << flush; - switch (el.GetType()) - { - case TRIG: - { - glBegin (GL_TRIANGLES); - - Point3d & lp1 = mesh->Point (el.PNum(1)); - Point3d & lp2 = mesh->Point (el.PNum(2)); - Point3d & lp3 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length() + 1e-12); - glNormal3dv (&n.X()); - glVertex3dv (&lp1.X()); - glVertex3dv (&lp2.X()); - glVertex3dv (&lp3.X()); - glEnd(); - break; - } - case QUAD: - { - glBegin (GL_QUADS); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(4)); - const Point3d & lp4 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), - Vec3d (lp1, Center (lp3, lp4))); - n /= (n.Length() + 1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glEnd(); - break; - } - case TRIG6: - { - int lines[6][2] = { - { 1, 6 }, { 2, 6 }, - { 1, 5 }, { 3, 5 }, - { 2, 4 }, { 3, 4 } }; - - glBegin (GL_LINES); - for (j = 0; j < 6; j++) - { - glVertex3dv (&mesh->Point (el.PNum(lines[j][0])).X()); - glVertex3dv (&mesh->Point (el.PNum(lines[j][0])).X()); - } - glEnd(); - break; - } - - case QUAD6: - { - int lines[6][2] = { - { 1, 5 }, { 2, 5 }, - { 3, 6 }, { 4, 6 }, - { 1, 4 }, { 2, 3 } }; - - glBegin (GL_LINES); - - for (j = 0; j < 6; j++) - { - const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); - const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - } - glEnd (); - break; - } - default: - PrintSysError ("Cannot draw surface element of type ", - int(el.GetType())); - } - } - glLoadName (0); - - } - glEndList (); - - - - - - if (1) - { - - identifiedlist = glGenLists (1); - glNewList (identifiedlist, GL_COMPILE); - - GLfloat identifiedcol[] = { 1, 0, 1, 1 }; - - glLineWidth (3); - - - // for (i = 1; i <= mesh->GetNSeg(); i++) - INDEX_2_HASHTABLE<int> & idpts = - mesh->GetIdentifications().GetIdentifiedPoints(); - if (&idpts) - for (i = 1; i <= idpts.GetNBags(); i++) - for (j = 1; j <= idpts.GetBagSize(i); j++) - { - INDEX_2 pts; - int val; - - idpts.GetData (i, j, pts, val); - const Point3d & p1 = mesh->Point(pts.I1()); - const Point3d & p2 = mesh->Point(pts.I2()); - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - identifiedcol); - - glBegin (GL_LINES); - glVertex3f (p1.X(), p1.Y(), p1.Z()); - glVertex3f (p2.X(), p2.Y(), p2.Z()); - glEnd(); - } - - glEndList (); - } - - vstimestamp = meshtimestamp; - } - - - - - void VisualSceneMesh :: BuildFilledList() - { - // clock_t starttime, endtime; - // starttime = clock(); - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - filledtimestamp = NextTimeStamp(); - - if (filledlist) - glDeleteLists (filledlist, 1); - - filledlist = glGenLists (1); - glNewList (filledlist, GL_COMPILE); - - - bool checkvicinity = (stlgeometry != NULL) && stldoctor.showvicinity; - - glEnable (GL_NORMALIZE); - - glLineWidth (1.0f); - - Vector locms; - - if (vispar.colormeshsize) - { - glEnable (GL_COLOR_MATERIAL); - locms.SetSize (mesh->GetNP()); - double maxh = -1; - double minh = 1e99; - for (int i = 1; i <= locms.Size(); i++) - { - Point3d p = mesh->Point(i); - locms.Elem(i) = mesh->GetH (p); - if (locms.Elem(i) > maxh) maxh = locms.Elem(i); - if (locms.Elem(i) < minh) minh = locms.Elem(i); - } - if (!locms.Size()) - { minh = 1; maxh = 10; } - } - else - glDisable (GL_COLOR_MATERIAL); - - - GLfloat matcol[] = { 0, 1, 0, 1 }; - GLfloat matcolsel[] = { 1, 0, 0, 1 }; - - CurvedElements & curv = mesh->GetCurvedElements(); - int hoplotn = 1 << vispar.subdivisions; - - - for (int col = 1; col <= 2; col++) - { - if (col == 2) - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolsel); - else - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol); - - - for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) - { - const Element2d & el = (*mesh)[sei]; - - bool drawel = !el.IsDeleted(); - - if (checkvicinity) - for (int j = 0; j < el.GetNP(); j++) - if (!stlgeometry->Vicinity(el.GeomInfoPi(j+1).trignum)) - drawel = 0; - - if (!drawel) - continue; - - if (vispar.colormeshsize && col == 2) - continue; - if (!vispar.colormeshsize && - (col == 2) != (el.GetIndex() == selface)) - continue; - - glLoadName (sei+1); - - switch (el.GetType()) - { - case TRIG: - { - if (curv.IsHighOrder() && curv.IsSurfaceElementCurved(sei)) - { - Point<2> xr[3]; - Point<3> xg; - Vec<3> dx, dy, n; - - glBegin (GL_TRIANGLES); - - for (int i = 0; i < hoplotn; i++) - for (int j = 0; j < hoplotn-i; j++) - for (int k = 0; k < 2; k++) - { - if (k == 0) - { - xr[0](0) = (double) i/hoplotn; xr[0](1) = (double) j/hoplotn; - xr[1](0) = (double)(i+1)/hoplotn; xr[1](1) = (double) j/hoplotn; - xr[2](0) = (double) i/hoplotn; xr[2](1) = (double)(j+1)/hoplotn; - } - else - { - if (j == hoplotn-i-1) continue; - xr[0](0) = (double)(i+1)/hoplotn; xr[0](1) = (double) j/hoplotn; - xr[1](0) = (double)(i+1)/hoplotn; xr[1](1) = (double)(j+1)/hoplotn; - xr[2](0) = (double) i/hoplotn; xr[2](1) = (double)(j+1)/hoplotn; - }; - - for (int l=0; l<3; l++) - { - Mat<3,2> dxdxi; - - curv.CalcSurfaceTransformation (xr[l], sei, xg, dxdxi); - for (int i = 0; i < 3; i++) - { - dx(i) = dxdxi(i,0); - dy(i) = dxdxi(i,1); - } - n = Cross (dx, dy); - n.Normalize(); - glNormal3d (n(0), n(1), n(2)); - glVertex3d (xg(0), xg(1), xg(2)); - } - } - - glEnd(); - } - else // not high order - { - glBegin (GL_TRIANGLES); - - const Point<3> & lp0 = (*mesh) [el[0]]; - const Point<3> & lp1 = (*mesh) [el[1]]; - const Point<3> & lp2 = (*mesh) [el[2]]; - - Vec<3> n = Cross (lp1-lp0, lp2-lp0); - glNormal3dv (n); - - if (vispar.colormeshsize) - { - SetOpenGlColor (locms.Get(el[0]), minh, maxh, 1); - glVertex3dv (lp0); - SetOpenGlColor (locms.Get(el[1]), minh, maxh, 1); - glVertex3dv (lp1); - SetOpenGlColor (locms.Get(el[2]), minh, maxh, 1); - glVertex3dv (lp2); - } - else - { - glVertex3dv (lp0); - glVertex3dv (lp1); - glVertex3dv (lp2); - } - - glEnd(); - } - - break; - } - case QUAD: - { - // cout << "BuildFilledList: QUAD" << endl; - // CurvedElements & curv = mesh->GetCurvedElements(); - if (curv.IsHighOrder() && curv.IsSurfaceElementCurved(sei)) - { - Point<2> xr[4]; - Point<3> xg; - Vec<3> dx, dy, n; - - glBegin (GL_QUADS); - - for (int i = 0; i < hoplotn; i++) - for (int j = 0; j < hoplotn; j++) - { - xr[0](0) = (double) i/hoplotn; xr[0](1) = (double) j/hoplotn; - xr[1](0) = (double)(i+1)/hoplotn; xr[1](1) = (double) j/hoplotn; - xr[2](0) = (double)(i+1)/hoplotn; xr[2](1) = (double)(j+1)/hoplotn; - xr[3](0) = (double) i/hoplotn; xr[3](1) = (double)(j+1)/hoplotn; - - for (int l=0; l<4; l++) - { - Mat<3,2> dxdxi; - - curv.CalcSurfaceTransformation (xr[l], sei, xg, dxdxi); - for (int i = 0; i < 3; i++) - { - dx(i) = dxdxi(i,0); - dy(i) = dxdxi(i,1); - } - - n = Cross (dx, dy); - n.Normalize(); - glNormal3d (n(0), n(1), n(2)); - glVertex3d (xg(0), xg(1), xg(2)); - } - - } - - glEnd(); - } - - else // not high order - - { - glBegin (GL_QUADS); - - const Point<3> & lp1 = mesh->Point (el.PNum(1)); - const Point<3> & lp2 = mesh->Point (el.PNum(2)); - const Point<3> & lp3 = mesh->Point (el.PNum(4)); - const Point<3> & lp4 = mesh->Point (el.PNum(3)); - - Vec<3> n = Cross (lp2-lp1, Center (lp3, lp4)-lp1); - glNormal3dv (n); - - glVertex3dv (lp1); - glVertex3dv (lp2); - glVertex3dv (lp4); - glVertex3dv (lp3); - - glEnd (); - } - break; - } - - case TRIG6: - { - glBegin (GL_TRIANGLES); - - static int trigs[4][3] = { - { 1, 6, 5 }, - { 2, 4, 6 }, - { 3, 5, 4 }, - { 4, 5, 6 } }; - - for (int j = 0; j < 4; j++) - { - Point3d & lp1 = mesh->Point (el.PNum(trigs[j][0])); - Point3d & lp2 = mesh->Point (el.PNum(trigs[j][1])); - Point3d & lp3 = mesh->Point (el.PNum(trigs[j][2])); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - glNormal3dv (&n.X()); - - glVertex3dv (&lp1.X()); - glVertex3dv (&lp2.X()); - glVertex3dv (&lp3.X()); - } - glEnd(); - break; - } - - case QUAD6: - { - glBegin (GL_QUADS); - static int quads[2][4] = { - { 1, 5, 6, 4 }, - { 5, 2, 3, 6 } }; - - for (int j = 0; j < 2; j++) - { - Point3d & lp1 = mesh->Point (el.PNum(quads[j][0])); - Point3d & lp2 = mesh->Point (el.PNum(quads[j][1])); - Point3d & lp3 = mesh->Point (el.PNum(quads[j][2])); - Point3d & lp4 = mesh->Point (el.PNum(quads[j][3])); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length() + 1e-12); - glNormal3dv (&n.X()); - glVertex3dv (&lp1.X()); - glVertex3dv (&lp2.X()); - glVertex3dv (&lp3.X()); - glVertex3dv (&lp4.X()); - } - glEnd(); - break; - } - - case QUAD8: - { - glBegin (GL_TRIANGLES); - static int boundary[] = - { 1, 5, 2, 8, 3, 6, 4, 7, 1 }; - - Point3d c(0,0,0); - for (int j = 0; j < 4; j++) - { - Point3d & hp = mesh->Point (el[j]); - c.X() -= 0.25 * hp.X(); - c.Y() -= 0.25 * hp.Y(); - c.Z() -= 0.25 * hp.Z(); - } - for (int j = 4; j < 8; j++) - { - Point3d & hp = mesh->Point (el[j]); - c.X() += 0.5 * hp.X(); - c.Y() += 0.5 * hp.Y(); - c.Z() += 0.5 * hp.Z(); - } - - for (int j = 0; j < 8; j++) - { - Point3d & lp1 = mesh->Point (el.PNum(boundary[j])); - Point3d & lp2 = mesh->Point (el.PNum(boundary[j+1])); - - Vec3d n = Cross (Vec3d (c, lp1), Vec3d (c, lp2)); - n /= (n.Length() + 1e-12); - glNormal3dv (&n.X()); - glVertex3dv (&lp1.X()); - glVertex3dv (&lp2.X()); - glVertex3dv (&c.X()); - } - glEnd(); - break; - } - - - default: - PrintSysError ("Cannot draw (2) surface element of type ", - int(el.GetType())); - } - } - } - glLoadName (0); - glEndList (); - - // endtime = clock(); - // cout << "BuildFillList time = " << double(endtime - starttime)/CLOCKS_PER_SEC << endl; - } - - - void VisualSceneMesh :: BuildLineList() - { - SurfaceElementIndex sei; - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - linetimestamp = NextTimeStamp(); - - - bool checkvicinity = (stlgeometry != NULL) && stldoctor.showvicinity; - - if (linelist) - glDeleteLists (linelist, 1); - - linelist = glGenLists (1); - glNewList (linelist, GL_COMPILE); - - - glLineWidth (1.0f); - - int hoplotn = 1 << vispar.subdivisions; - - for (sei = 0; sei < mesh->GetNSE(); sei++) - { - const Element2d & el = (*mesh)[sei]; - - bool drawel = !el.IsDeleted(); - if (checkvicinity) - for (int j = 0; j < el.GetNP(); j++) - if (!stlgeometry->Vicinity(el.GeomInfoPi(j+1).trignum)) - drawel = 0; - - if (!drawel) - continue; - - switch (el.GetType()) - { - case TRIG: - { - CurvedElements & curv = mesh->GetCurvedElements(); - if (curv.IsHighOrder() && curv.IsSurfaceElementCurved(sei)) - { - Point<3> xg; - glBegin (GL_LINE_LOOP); - - for (int i = 0; i < hoplotn; i++) - { - Point<2> xr (double(i) / hoplotn, 0); - curv.CalcSurfaceTransformation (xr, sei, xg); - glVertex3dv (xg); - } - for (int i = 0; i < hoplotn; i++) - { - Point<2> xr (double(hoplotn-i) / hoplotn, double(i)/hoplotn); - curv.CalcSurfaceTransformation (xr, sei, xg); - glVertex3dv (xg); - } - for (int i = 0; i < hoplotn; i++) - { - Point<2> xr (0, double(hoplotn-i) / hoplotn); - curv.CalcSurfaceTransformation (xr, sei, xg); - glVertex3dv (xg); - } - - glEnd(); - } - else - { - glBegin (GL_TRIANGLES); - - const Point<3> & lp0 = (*mesh) [el[0]]; - const Point<3> & lp1 = (*mesh) [el[1]]; - const Point<3> & lp2 = (*mesh) [el[2]]; - - glVertex3dv (lp0); - glVertex3dv (lp1); - glVertex3dv (lp2); - - glEnd(); - } - - break; - - } - - case QUAD: - { - CurvedElements & curv = mesh->GetCurvedElements(); - if (curv.IsHighOrder() && curv.IsSurfaceElementCurved(sei)) - { - Point<2> xr; - Point<3> xg; - - glBegin (GL_LINE_STRIP); - - for (int side = 0; side < 4; side++) - { - for (int i = 0; i <= hoplotn; i++) - { - switch (side) - { - case 0: - xr(0) = (double) i/hoplotn; - xr(1) = 0.; - break; - case 1: - xr(0) = 1.; - xr(1) = (double) i/hoplotn; - break; - case 2: - xr(0) = (double) (hoplotn-i)/hoplotn; - xr(1) = 1.; - break; - case 3: - xr(0) = 0.; - xr(1) = (double) (hoplotn-i)/hoplotn; - break; - } - - curv.CalcSurfaceTransformation (xr, sei, xg); - glVertex3d (xg(0), xg(1), xg(2)); - - } - - } - glEnd(); - - } else { - - glBegin (GL_QUADS); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(4)); - const Point3d & lp4 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), - Vec3d (lp1, Center (lp3, lp4))); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glEnd(); - - } - - break; - - } - - case TRIG6: - { - int lines[6][2] = { - { 1, 6 }, { 2, 6 }, - { 1, 5 }, { 3, 5 }, - { 2, 4 }, { 3, 4 } }; - - glBegin (GL_LINES); - for (int j = 0; j < 6; j++) - { - const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); - const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - } - - glEnd(); - break; - } - - case QUAD6: - { - int lines[6][2] = { - { 1, 5 }, { 2, 5 }, - { 3, 6 }, { 4, 6 }, - { 1, 4 }, { 2, 3 } }; - - glBegin (GL_LINES); - - for (int j = 0; j < 6; j++) - { - const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); - const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - } - glEnd (); - break; - } - - case QUAD8: - { - int lines[8][2] = { - { 1, 5 }, { 2, 5 }, { 3, 6 }, { 4, 6 }, - { 1, 7 }, { 4, 7 }, { 2, 8 }, { 3, 8 } - }; - - glBegin (GL_LINES); - - for (int j = 0; j < 8; j++) - { - const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); - const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - } - glEnd (); - break; - } - - - - default: - PrintSysError ("Cannot draw (4) surface element of type ", - int(el.GetType())); - } - } - - glEndList (); - } - - void VisualSceneMesh :: BuildPointNumberList() - { - ; - } - - - - - - - inline long int Fact (int n) - { - long int res = 1; - for (int i = 2; i <= n; i++) - res *= i; - return res; - } - inline int Binom (int n, int i) - { - return Fact(n) / Fact(i) / Fact(n-i); - } - - void ToBernstein (int order, Point<3> * pts, int stride) - { - static DenseMatrix mat, inv; - static Vector vec1, vec2; - - if (mat.Height () != order+1) - { - mat.SetSize (order+1); - inv.SetSize (order+1); - vec1.SetSize (order+1); - vec2.SetSize (order+1); - for (int i = 0; i <= order; i++) - { - double x = double(i) / order; - for (int j = 0; j <= order; j++) - mat(i,j) = Binom (order, j) * pow (x, j) * pow (1-x, order-j); - } - - CalcInverse (mat, inv); - } - - for (int i = 0; i < 3; i++) - { - for (int j = 0; j <= order; j++) - vec1(j) = pts[j*stride](i); - - inv.Mult (vec1, vec2); - - for (int j = 0; j <= order; j++) - pts[j*stride](i) = vec2(j); - } - } - - - - - - - - - - - - - - - void VisualSceneMesh :: BuildTetList() - { - - -#ifdef FAST3DELEMENTS - - - cout << "start fast test" << endl; - - int i, j; - ARRAY<Element2d> faces; - - if (tettimestamp > mesh->GetTimeStamp () && - tettimestamp > vispar.clipplanetimestamp ) - return; - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - tettimestamp = NextTimeStamp(); - - if (tetlist) - glDeleteLists (tetlist, 1); - - - tetlist = glGenLists (1); - glNewList (tetlist, GL_COMPILE); - - - BitArray shownode(mesh->GetNP()); - if (vispar.clipenable) - { - shownode.Clear(); - for (i = 1; i <= shownode.Size(); i++) - { - Point3d p = mesh->Point(i); - - double val = - p.X() * clipplane[0] + - p.Y() * clipplane[1] + - p.Z() * clipplane[2] + - clipplane[3]; - - if (val > 0) - shownode.Set (i); - } - } - else - shownode.Set(); - - - static float tetcols[][4] = - { - { 1.0f, 1.0f, 0.0f, 1.0f }, - { 1.0f, 0.0f, 0.0f, 1.0f }, - { 0.0f, 1.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f, 1.0f } - }; - - - ARRAY<int> elfaces; - - const MeshTopology & top = mesh->GetTopology(); - CurvedElements & curv = mesh->GetCurvedElements(); - - ARRAY<int> displayface(top.GetNFaces()); - for (i = 0; i < top.GetNFaces(); i++) - displayface[i] = -1; - - - for (i = 1; i <= mesh->GetNE(); i++) - { - if (vispar.drawtetsdomain > 0 && - vispar.drawtetsdomain != mesh->VolumeElement(i).GetIndex()) - continue; - - Element el = (*mesh)[(ElementIndex) (i-1)]; - - if (el.GetType() == TET) - { - if (el.PNum(1)) - { - bool drawtet = 1; - for (j = 1; j <= el.GetNP(); j++) - if (!shownode.Test(el.PNum(j))) - drawtet = 0; - if (!drawtet) continue; - - { - top.GetElementFaces (i, elfaces); - - for (j = 0; j < 4; j++) - displayface[elfaces[j]-1] *= -1; - } - } - } - } - - - for (i = 1; i <= mesh->GetNE(); i++) - { - if (vispar.drawtetsdomain > 0 && - vispar.drawtetsdomain != mesh->VolumeElement(i).GetIndex()) - continue; - - if (mesh->VolumeElement(i).GetType() == TET) - { - // copy to be thread-safe - Element el = mesh->VolumeElement (i); - el.GetSurfaceTriangles (faces); - - if (el.PNum(1)) - { - bool drawtet = 1; - for (j = 1; j <= el.GetNP(); j++) - if (!shownode.Test(el.PNum(j))) - drawtet = 0; - if (!drawtet) continue; - - int ind = el.GetIndex() % 4; - if (vispar.drawmetispartition && (el.GetPartition()!=-1)) - ind = el.GetPartition() % 4; - (*testout) << "ind = " << ind << endl; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); - - - top.GetElementFaces (i, elfaces); - - glBegin (GL_TRIANGLES); - - for (j = 0; j < faces.Size(); j++) - { - if (displayface[elfaces[j]-1] == -1) continue; - - Element2d & face = faces.Elem(j+1); - - if (curv.IsHighOrder() && curv.IsElementCurved(i-1)) - { - int hoplotn = 1 << vispar.subdivisions; - // int hoplotn = curv.GetNVisualSubsecs(); - - const Point3d * facepoint = MeshTopology :: GetVertices (TET); - const ELEMENT_FACE * elface = MeshTopology :: GetFaces(TET); - - Vec<3> x0,x1,d0,d1; - Point<3> xg; - x0 = facepoint[face.PNum(3)-1] - facepoint[face.PNum(1)-1]; - x1 = facepoint[face.PNum(2)-1] - facepoint[face.PNum(1)-1]; - x0.Normalize(); - x1.Normalize(); - - for (int m0 = 0; m0 < hoplotn; m0++) - for (int m1 = 0; m1 < hoplotn-m0; m1++) - for (int k = 0; k < 2; k++) - { - Vec<3> dx, dy, dz, n; - Point<4> la[3]; - int l; - for (l = 0; l<3; l++) la[l] = Point<4>(0.,0.,0.,0.); - - if (k == 0) - { - la[0](face.PNum(1)-1) = (m0 )/(double)hoplotn; - la[0](face.PNum(2)-1) = (m1 )/(double)hoplotn; - la[0](face.PNum(3)-1) = 1-la[0](face.PNum(1)-1)-la[0](face.PNum(2)-1); - - la[1](face.PNum(1)-1) = (m0+1)/(double)hoplotn; - la[1](face.PNum(2)-1) = (m1 )/(double)hoplotn; - la[1](face.PNum(3)-1) = 1-la[1](face.PNum(1)-1)-la[1](face.PNum(2)-1); - - la[2](face.PNum(1)-1) = (m0 )/(double)hoplotn; - la[2](face.PNum(2)-1) = (m1+1)/(double)hoplotn; - la[2](face.PNum(3)-1) = 1-la[2](face.PNum(1)-1)-la[2](face.PNum(2)-1); - } else - { - if (m1 == hoplotn-m0-1) continue; - la[0](face.PNum(1)-1) = (m0+1)/(double)hoplotn; - la[0](face.PNum(2)-1) = (m1+1)/(double)hoplotn; - la[0](face.PNum(3)-1) = 1-la[0](face.PNum(1)-1)-la[0](face.PNum(2)-1); - - la[1](face.PNum(1)-1) = (m0 )/(double)hoplotn; - la[1](face.PNum(2)-1) = (m1+1)/(double)hoplotn; - la[1](face.PNum(3)-1) = 1-la[1](face.PNum(1)-1)-la[1](face.PNum(2)-1); - - la[2](face.PNum(1)-1) = (m0+1)/(double)hoplotn; - la[2](face.PNum(2)-1) = (m1 )/(double)hoplotn; - la[2](face.PNum(3)-1) = 1-la[2](face.PNum(1)-1)-la[2](face.PNum(2)-1); - } - - for (l = 0; l<3; l++) - { - Mat<3,3> dxdxi; - Point<3> xr( la[l](0), la[l](1), la[l](2) ); - curv.CalcElementTransformation (xr, i-1, xg, dxdxi); - for (int i = 0; i < 3; i++) - { - dx(i) = dxdxi(i,0); - dy(i) = dxdxi(i,1); - dz(i) = dxdxi(i,2); - } - - d0 = x0(0)*dx + x0(1)*dy + x0(2)*dz; - d1 = x1(0)*dx + x1(1)*dy + x1(2)*dz; - n = Cross (d0, d1); - glNormal3d ( n(0), n(1), n(2)); - glVertex3d (xg(0), xg(1), xg(2)); - } - } - - } else { - const Point3d & lp1 = mesh->Point (el.PNum(face.PNum(1))); - const Point3d & lp2 = mesh->Point (el.PNum(face.PNum(2))); - const Point3d & lp3 = mesh->Point (el.PNum(face.PNum(3))); - Vec3d n = Cross (Vec3d (lp1, lp3), Vec3d (lp1, lp2)); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - } - - glEnd(); - } - - } - } - glEndList (); - - - - -#else - - if (tettimestamp > mesh->GetTimeStamp () && - tettimestamp > vispar.clipplanetimestamp ) - return; - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - tettimestamp = NextTimeStamp(); - - if (tetlist) - glDeleteLists (tetlist, 1); - - - tetlist = glGenLists (1); - glNewList (tetlist, GL_COMPILE); - - - - int i, j, k, l; - ARRAY<Element2d> faces; - - - BitArray shownode(mesh->GetNP()); - if (vispar.clipenable) - { - shownode.Clear(); - for (i = 1; i <= shownode.Size(); i++) - { - Point3d p = mesh->Point(i); - - double val = - p.X() * clipplane[0] + - p.Y() * clipplane[1] + - p.Z() * clipplane[2] + - clipplane[3]; - - if (val > 0) - shownode.Set (i); - } - } - else - shownode.Set(); - - - static float tetcols[][4] = - { - { 1.0f, 1.0f, 0.0f, 1.0f }, - { 1.0f, 0.0f, 0.0f, 1.0f }, - { 0.0f, 1.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f, 1.0f } - }; - - - CurvedElements & curv = mesh->GetCurvedElements(); - - for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) - { - i = ei + 1; - - if (vispar.drawtetsdomain > 0 && - vispar.drawtetsdomain != mesh->VolumeElement(i).GetIndex()) - continue; - - const Element & el = (*mesh)[ei]; - - if (el.GetType() == TET && !el.IsDeleted()) - { - - bool drawtet = 1; - for (j = 0; j < 4; j++) - if (!shownode.Test(el[j])) - drawtet = 0; - if (!drawtet) continue; - - - int ind = el.GetIndex() % 4; - if (vispar.drawmetispartition && (el.GetPartition()!=-1)) - ind = el.GetPartition() % 4; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); - - - if (curv.IsHighOrder() && curv.IsElementCurved(ei)) - { - const ELEMENT_FACE * faces = MeshTopology :: GetFaces (TET); - const Point3d * vertices = MeshTopology :: GetVertices (TET); - - Point<3> grid[11][11]; - Point<3> fpts[3]; - int order = vispar.subdivisions+1; - - for (int trig = 0; trig < 4; trig++) - { - for (int j = 0; j < 3; j++) - fpts[j] = vertices[faces[trig][j]-1]; - - static Point<3> c(0.25, 0.25, 0.25); - if (vispar.shrink < 1) - for (int j = 0; j < 3; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - for (int ix = 0; ix <= order; ix++) - for (int iy = 0; iy <= order; iy++) - { - double lami[3] = - { (1-double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * (1-double(iy)/order), - double(iy)/order }; - - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l); - - curv.CalcElementTransformation (xl, i-1, grid[ix][iy]); - } - - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); - - glMap2d(GL_MAP2_VERTEX_3, - 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, - 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, - &grid[0][0](0)); - glEnable(GL_MAP2_VERTEX_3); - glEnable(GL_AUTO_NORMAL); - - glMapGrid2f(8, 0.0, 0.999, 8, 0.0, 1.0); - glEvalMesh2(GL_FILL, 0, 8, 0, 8); - - glDisable (GL_AUTO_NORMAL); - glDisable (GL_MAP2_VERTEX_3); - } - } - - - else - - { - el.GetSurfaceTriangles (faces); - - Point3d c; - if (vispar.shrink < 1) - c = Center (Center (mesh->Point (el.PNum(1)), - mesh->Point (el.PNum(2))), - Center (mesh->Point (el.PNum(3)), - mesh->Point (el.PNum(4)))); - - - glBegin (GL_TRIANGLES); - - for (j = 0; j < faces.Size(); j++) - { - const Element2d & face = faces[j]; - - /* - if (curv.IsHighOrder() && curv.IsElementCurved(i-1)) - { - int hoplotn = 1 << vispar.subdivisions; - // int hoplotn = curv.GetNVisualSubsecs(); - - const Point3d * facepoint = MeshTopology :: GetVertices (TET); - const ELEMENT_FACE * elface = MeshTopology :: GetFaces(TET); - - Vec<3> x0,x1,d0,d1; - Point<3> xg; - x0 = facepoint[face.PNum(3)-1] - facepoint[face.PNum(1)-1]; - x1 = facepoint[face.PNum(2)-1] - facepoint[face.PNum(1)-1]; - x0.Normalize(); - x1.Normalize(); - - for (int m0 = 0; m0 < hoplotn; m0++) - for (int m1 = 0; m1 < hoplotn-m0; m1++) - for (k = 0; k < 2; k++) - { - Vec<3> dx, dy, dz, n; - Point<4> la[3]; - - for (l = 0; l<3; l++) la[l] = Point<4>(0.,0.,0.,0.); - - if (k == 0) - { - la[0](face.PNum(1)-1) = (m0 )/(double)hoplotn; - la[0](face.PNum(2)-1) = (m1 )/(double)hoplotn; - la[0](face.PNum(3)-1) = 1-la[0](face.PNum(1)-1)-la[0](face.PNum(2)-1); - - la[1](face.PNum(1)-1) = (m0+1)/(double)hoplotn; - la[1](face.PNum(2)-1) = (m1 )/(double)hoplotn; - la[1](face.PNum(3)-1) = 1-la[1](face.PNum(1)-1)-la[1](face.PNum(2)-1); - - la[2](face.PNum(1)-1) = (m0 )/(double)hoplotn; - la[2](face.PNum(2)-1) = (m1+1)/(double)hoplotn; - la[2](face.PNum(3)-1) = 1-la[2](face.PNum(1)-1)-la[2](face.PNum(2)-1); - } else - { - if (m1 == hoplotn-m0-1) continue; - la[0](face.PNum(1)-1) = (m0+1)/(double)hoplotn; - la[0](face.PNum(2)-1) = (m1+1)/(double)hoplotn; - la[0](face.PNum(3)-1) = 1-la[0](face.PNum(1)-1)-la[0](face.PNum(2)-1); - - la[1](face.PNum(1)-1) = (m0 )/(double)hoplotn; - la[1](face.PNum(2)-1) = (m1+1)/(double)hoplotn; - la[1](face.PNum(3)-1) = 1-la[1](face.PNum(1)-1)-la[1](face.PNum(2)-1); - - la[2](face.PNum(1)-1) = (m0+1)/(double)hoplotn; - la[2](face.PNum(2)-1) = (m1 )/(double)hoplotn; - la[2](face.PNum(3)-1) = 1-la[2](face.PNum(1)-1)-la[2](face.PNum(2)-1); - } - - for (l = 0; l<3; l++) - { - Mat<3,3> dxdxi; - Point<3> xr( la[l](0), la[l](1), la[l](2) ); - curv.CalcElementTransformation (xr, i-1, xg, dxdxi); - for (int i = 0; i < 3; i++) - { - dx(i) = dxdxi(i,0); - dy(i) = dxdxi(i,1); - dz(i) = dxdxi(i,2); - } - - d0 = x0(0)*dx + x0(1)*dy + x0(2)*dz; - d1 = x1(0)*dx + x1(1)*dy + x1(2)*dz; - n = Cross (d0, d1); - glNormal3d ( n(0), n(1), n(2)); - glVertex3d (xg(0), xg(1), xg(2)); - } - } - - } else - */ - { - Point3d lp1 = mesh->Point (el.PNum(face.PNum(1))); - Point3d lp2 = mesh->Point (el.PNum(face.PNum(2))); - Point3d lp3 = mesh->Point (el.PNum(face.PNum(3))); - Vec3d n = Cross (Vec3d (lp1, lp3), Vec3d (lp1, lp2)); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - - if (vispar.shrink < 1) - { - lp1 = c + vispar.shrink * (lp1 - c); - lp2 = c + vispar.shrink * (lp2 - c); - lp3 = c + vispar.shrink * (lp3 - c); - } - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - } - - glEnd(); - } - } - } - - glEndList (); - -#endif - } - - - - - void VisualSceneMesh :: BuildPrismList() - { - if (prismtimestamp > mesh->GetTimeStamp () && - prismtimestamp > vispar.clipplanetimestamp ) - return; - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - prismtimestamp = NextTimeStamp(); - - - - if (prismlist) - glDeleteLists (prismlist, 1); - - prismlist = glGenLists (1); - glNewList (prismlist, GL_COMPILE); - - static float prismcol[] = { 0.0f, 1.0f, 1.0f, 1.0f }; - glLineWidth (1.0f); - - ARRAY<Element2d> faces; - - - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, prismcol); - - for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) - { - const Element & el = (*mesh)[ei]; - if (el.GetType() == PRISM && !el.IsDeleted()) - { - int j; - int i = ei + 1; - - CurvedElements & curv = mesh->GetCurvedElements(); - if (curv.IsHighOrder() && curv.IsElementCurved(ei)) - { - const ELEMENT_FACE * faces = MeshTopology :: GetFaces (PRISM); - const Point3d * vertices = MeshTopology :: GetVertices (PRISM); - - Point<3> grid[11][11]; - Point<3> fpts[4]; - int order = vispar.subdivisions+1; - - for (int trig = 0; trig < 2; trig++) - { - for (int j = 0; j < 3; j++) - fpts[j] = vertices[faces[trig][j]-1]; - - static Point<3> c(1.0/3.0, 1.0/3.0, 0.5); - if (vispar.shrink < 1) - for (int j = 0; j < 3; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - for (int ix = 0; ix <= order; ix++) - for (int iy = 0; iy <= order; iy++) - { - double lami[3] = - { (1-double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * (1-double(iy)/order), - double(iy)/order }; - - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l); - - curv.CalcElementTransformation (xl, i-1, grid[ix][iy]); - } - - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); - - glMap2d(GL_MAP2_VERTEX_3, - 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, - 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, - &grid[0][0](0)); - glEnable(GL_MAP2_VERTEX_3); - glEnable(GL_AUTO_NORMAL); - - glMapGrid2f(8, 0.0, 0.999, 8, 0.0, 1.0); - glEvalMesh2(GL_FILL, 0, 8, 0, 8); - - glDisable (GL_AUTO_NORMAL); - glDisable (GL_MAP2_VERTEX_3); - } - - for (int quad = 2; quad < 5; quad++) - { - for (int j = 0; j < 4; j++) - fpts[j] = vertices[faces[quad][j]-1]; - - static Point<3> c(1.0/3.0, 1.0/3.0, 0.5); - if (vispar.shrink < 1) - for (int j = 0; j < 4; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - for (int ix = 0; ix <= order; ix++) - for (int iy = 0; iy <= order; iy++) - { - double lami[4] = - { (1-double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * ( double(iy)/order), - (1-double(ix)/order) * ( double(iy)/order) }; - - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = - lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l) + lami[3] * fpts[3](l); - - curv.CalcElementTransformation (xl, ei, grid[ix][iy]); - } - - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); - - glMap2d(GL_MAP2_VERTEX_3, - 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, - 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, - &grid[0][0](0)); - glEnable(GL_MAP2_VERTEX_3); - glEnable(GL_AUTO_NORMAL); - - glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0); - glEvalMesh2(GL_FILL, 0, 8, 0, 8); - - glDisable (GL_AUTO_NORMAL); - glDisable (GL_MAP2_VERTEX_3); - } - - - - - - /* - int hoplotn = 1 << vispar.subdivisions; - // int hoplotn = curv.GetNVisualSubsecs(); - - const Point3d * facepoint = MeshTopology :: GetVertices (TRIG); - const ELEMENT_FACE * elface = MeshTopology :: GetFaces(TRIG); - - glBegin (GL_TRIANGLES); - - for (int trig = 0; trig<2; trig++) - { - - Vec<3> x0,x1,d0,d1; - x0 = facepoint[1] - facepoint[2]; - x1 = facepoint[0] - facepoint[2]; - x0.Normalize(); - x1.Normalize(); - if (trig == 1) swap (x0,x1); - - Point<3> xr[3]; - Point<3> xg; - Vec<3> dx, dy, dz, n; - - for (int i1 = 0; i1 < hoplotn; i1++) - for (int j1 = 0; j1 < hoplotn-i1; j1++) - for (int k = 0; k < 2; k++) - { - if (k == 0) - { - xr[0](0) = (double) i1/hoplotn; xr[0](1) = (double) j1/hoplotn; - xr[1](0) = (double)(i1+1)/hoplotn; xr[1](1) = (double) j1/hoplotn; - xr[2](0) = (double) i1/hoplotn; xr[2](1) = (double)(j1+1)/hoplotn; - } else - { - if (j1 == hoplotn-i1-1) continue; - xr[0](0) = (double)(i1+1)/hoplotn; xr[0](1) = (double) j1/hoplotn; - xr[1](0) = (double)(i1+1)/hoplotn; xr[1](1) = (double)(j1+1)/hoplotn; - xr[2](0) = (double) i1/hoplotn; xr[2](1) = (double)(j1+1)/hoplotn; - }; - - for (int l=0; l<3; l++) - { - Mat<3,3> dxdxi; - xr[l](2) = (double) trig; - curv.CalcElementTransformation (xr[l], i-1, xg, dxdxi); - for (int i = 0; i < 3; i++) - { - dx(i) = dxdxi(i,0); - dy(i) = dxdxi(i,1); - dz(i) = dxdxi(i,2); - } - - Vec<3> d0 = x0(0)*dx + x0(1)*dy + x0(2)*dz; - Vec<3> d1 = x1(0)*dx + x1(1)*dy + x1(2)*dz; - n = Cross (d1, d0); - glNormal3d (n(0), n(1), n(2)); - glVertex3d (xg(0), xg(1), xg(2)); - } - } - - } - - glEnd (); - - glBegin (GL_QUADS); - - for (int quad = 0; quad<3; quad++) - { - const Point3d * facepoint = MeshTopology :: GetVertices (PRISM); - - Vec<3> x0,x1; - int xyz; - - switch (quad) - { - case 0: - x0 = facepoint[5] - facepoint[2]; - x1 = facepoint[0] - facepoint[2]; - xyz = 0; - break; - case 1: - x0 = facepoint[4] - facepoint[0]; - x1 = facepoint[1] - facepoint[0]; - xyz = 0; - break; - case 2: - x0 = facepoint[1] - facepoint[2]; - x1 = facepoint[5] - facepoint[2]; - xyz = 1; - break; - } - - x0.Normalize(); - x1.Normalize(); - - swap (x0,x1); - - Point<3> xr[4]; - Point<3> xg; - Vec<3> dx, dy, dz, n; - - for (int i1 = 0; i1 < hoplotn; i1++) - for (int j1 = 0; j1 < hoplotn; j1++) - { - xr[0](xyz) = (double) i1/hoplotn; xr[0](2) = (double) j1/hoplotn; - xr[1](xyz) = (double)(i1+1)/hoplotn; xr[1](2) = (double) j1/hoplotn; - xr[2](xyz) = (double)(i1+1)/hoplotn; xr[2](2) = (double)(j1+1)/hoplotn; - xr[3](xyz) = (double) i1/hoplotn; xr[3](2) = (double)(j1+1)/hoplotn; - - for (int l=0; l<4; l++) - { - switch (quad) - { - case 0: xr[l](1) = 0; break; - case 1: xr[l](1) = 1-xr[l](0); break; - case 2: xr[l](0) = 0; break; - } - - Mat<3,3> dxdxi; - curv.CalcElementTransformation (xr[l], i-1, xg, dxdxi); - for (int i = 0; i < 3; i++) - { - dx(i) = dxdxi(i,0); - dy(i) = dxdxi(i,1); - dz(i) = dxdxi(i,2); - } - - Vec<3> d0 = x0(0)*dx + x0(1)*dy + x0(2)*dz; - Vec<3> d1 = x1(0)*dx + x1(1)*dy + x1(2)*dz; - n = Cross (d1, d0); - glNormal3d (n(0), n(1), n(2)); - glVertex3d (xg(0), xg(1), xg(2)); - } - } - } - glEnd (); - */ - } - else - { - Point3d c(0,0,0); - if (vispar.shrink < 1) - { - for (j = 1; j <= 6; j++) - { - Point3d p = mesh->Point(el.PNum(j)); - c.X() += p.X() / 6; - c.Y() += p.Y() / 6; - c.Z() += p.Z() / 6; - } - } - - el.GetSurfaceTriangles (faces); - glBegin (GL_TRIANGLES); - for (j = 1; j <= faces.Size(); j++) - { - Element2d & face = faces.Elem(j); - Point3d lp1 = mesh->Point (el.PNum(face.PNum(1))); - Point3d lp2 = mesh->Point (el.PNum(face.PNum(2))); - Point3d lp3 = mesh->Point (el.PNum(face.PNum(3))); - Vec3d n = Cross (Vec3d (lp1, lp3), Vec3d (lp1, lp2)); - n /= (n.Length()+1e-12); - glNormal3d (n.X(), n.Y(), n.Z()); - if (vispar.shrink < 1) - { - lp1 = c + vispar.shrink * (lp1 - c); - lp2 = c + vispar.shrink * (lp2 - c); - lp3 = c + vispar.shrink * (lp3 - c); - } - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - - glEnd(); - } - } - } - glEndList (); - } - - - - - void VisualSceneMesh :: BuildHexList() - { - if (hextimestamp > mesh->GetTimeStamp () && - hextimestamp > vispar.clipplanetimestamp ) - return; - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - hextimestamp = NextTimeStamp(); - - if (hexlist) glDeleteLists (hexlist, 1); - - hexlist = glGenLists (1); - glNewList (hexlist, GL_COMPILE); - - - static float hexcol[] = { 1.0f, 1.0f, 0.0f, 1.0f }; - glLineWidth (1.0f); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, hexcol); - - ARRAY<Element2d> faces; - int hoplotn = 1 << vispar.subdivisions; - - for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) - { - const Element & el = (*mesh)[ei]; - if (el.GetType() == HEX && !el.IsDeleted()) - { - CurvedElements & curv = mesh->GetCurvedElements(); - if (curv.IsHighOrder() && curv.IsElementCurved(ei)) - { - /* // classical - glBegin (GL_QUADS); - - const ELEMENT_FACE * faces = MeshTopology :: GetFaces (HEX); - const Point3d * vertices = MeshTopology :: GetVertices (HEX); - - Point<3> grid[33][33]; - Vec<3> gridn[33][33]; - Point<3> fpts[4]; - for (int quad = 0; quad<6; quad++) - { - for (int j = 0; j < 4; j++) - fpts[j] = vertices[faces[quad][j]-1]; - - static Point<3> c(0.5, 0.5, 0.5); - if (vispar.shrink < 1) - for (int j = 0; j < 4; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - Vec<3> taux = fpts[1]-fpts[0]; - Vec<3> tauy = fpts[3]-fpts[0]; - - for (int ix = 0; ix <= hoplotn; ix++) - for (int iy = 0; iy <= hoplotn; iy++) - { - Point<3> xl; - Mat<3,3> dxdxi; - double lami[4] = - { (1-double(ix)/hoplotn) * (1-double(iy)/hoplotn), - ( double(ix)/hoplotn) * (1-double(iy)/hoplotn), - ( double(ix)/hoplotn) * ( double(iy)/hoplotn), - (1-double(ix)/hoplotn) * ( double(iy)/hoplotn) }; - for (int l = 0; l < 3; l++) - xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l) + lami[3] * fpts[3](l); - - curv.CalcElementTransformation (xl, ei, grid[ix][iy], dxdxi); - - Vec<3> gtaux = dxdxi * taux; - Vec<3> gtauy = dxdxi * tauy; - gridn[ix][iy] = Cross (gtauy, gtaux).Normalize(); - } - - for (int ix = 0; ix < hoplotn; ix++) - for (int iy = 0; iy < hoplotn; iy++) - { - glNormal3dv (gridn[ix][iy]); - glVertex3dv (grid[ix][iy]); - - glNormal3dv (gridn[ix+1][iy]); - glVertex3dv (grid[ix+1][iy]); - - glNormal3dv (gridn[ix+1][iy+1]); - glVertex3dv (grid[ix+1][iy+1]); - - glNormal3dv (gridn[ix][iy+1]); - glVertex3dv (grid[ix][iy+1]); - } - } - - glEnd (); - */ - - const ELEMENT_FACE * faces = MeshTopology :: GetFaces (HEX); - const Point3d * vertices = MeshTopology :: GetVertices (HEX); - - Point<3> grid[11][11]; - Point<3> fpts[4]; - int order = vispar.subdivisions+1; - - for (int quad = 0; quad<6; quad++) - { - for (int j = 0; j < 4; j++) - fpts[j] = vertices[faces[quad][j]-1]; - - static Point<3> c(0.5, 0.5, 0.5); - if (vispar.shrink < 1) - for (int j = 0; j < 4; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - for (int ix = 0; ix <= order; ix++) - for (int iy = 0; iy <= order; iy++) - { - double lami[4] = - { (1-double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * ( double(iy)/order), - (1-double(ix)/order) * ( double(iy)/order) }; - - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l) + lami[3] * fpts[3](l); - - curv.CalcElementTransformation (xl, ei, grid[ix][iy]); - } - - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); - - glMap2d(GL_MAP2_VERTEX_3, - 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, - 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, - &grid[0][0](0)); - glEnable(GL_MAP2_VERTEX_3); - glEnable(GL_AUTO_NORMAL); - - glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0); - glEvalMesh2(GL_FILL, 0, 8, 0, 8); - - glDisable (GL_AUTO_NORMAL); - glDisable (GL_MAP2_VERTEX_3); - } - } - else - { - Point3d c(0,0,0); - if (vispar.shrink < 1) - { - for (int j = 1; j <= 8; j++) - { - Point3d p = mesh->Point(el.PNum(j)); - c.X() += p.X(); - c.Y() += p.Y(); - c.Z() += p.Z(); - } - c.X() /= 8; - c.Y() /= 8; - c.Z() /= 8; - } - - glBegin (GL_TRIANGLES); - - el.GetSurfaceTriangles (faces); - for (int j = 1; j <= faces.Size(); j++) - { - Element2d & face = faces.Elem(j); - Point<3> lp1 = mesh->Point (el.PNum(face.PNum(1))); - Point<3> lp2 = mesh->Point (el.PNum(face.PNum(2))); - Point<3> lp3 = mesh->Point (el.PNum(face.PNum(3))); - Vec<3> n = Cross (lp3-lp1, lp2-lp1); - n.Normalize(); - glNormal3dv (n); - - if (vispar.shrink < 1) - { - lp1 = c + vispar.shrink * (lp1 - c); - lp2 = c + vispar.shrink * (lp2 - c); - lp3 = c + vispar.shrink * (lp3 - c); - } - - glVertex3dv (lp1); - glVertex3dv (lp2); - glVertex3dv (lp3); - } - - glEnd(); - } - } - } - glEndList (); - } - - - - - - - - - - void VisualSceneMesh :: BuildPyramidList() - { - if (pyramidtimestamp > mesh->GetTimeStamp () && - pyramidtimestamp > vispar.clipplanetimestamp ) - return; - - if (!lock) - { - lock = new NgLock (mesh->Mutex()); - lock -> Lock(); - } - - pyramidtimestamp = NextTimeStamp(); - - - if (pyramidlist) - glDeleteLists (pyramidlist, 1); - - - - - pyramidlist = glGenLists (1); - glNewList (pyramidlist, GL_COMPILE); - - static float pyramidcol[] = { 1.0f, 0.0f, 1.0f, 1.0f }; - glLineWidth (1.0f); - ARRAY<Element2d> faces; - - for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) - { - const Element & el = (*mesh)[ei]; - if (el.GetType() == PYRAMID && !el.IsDeleted()) - { - int j; - int i = ei + 1; - - CurvedElements & curv = mesh->GetCurvedElements(); - if (curv.IsHighOrder() && curv.IsElementCurved(ei)) - { - - const ELEMENT_FACE * faces = MeshTopology :: GetFaces (PYRAMID); - const Point3d * vertices = MeshTopology :: GetVertices (PYRAMID); - - Point<3> grid[11][11]; - Point<3> fpts[4]; - int order = vispar.subdivisions+1; - - for (int trig = 0; trig < 4; trig++) - { - for (int j = 0; j < 3; j++) - fpts[j] = vertices[faces[trig][j]-1]; - - static Point<3> c(0.375, 0.375, 0.25); - if (vispar.shrink < 1) - for (int j = 0; j < 3; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - for (int ix = 0; ix <= order; ix++) - for (int iy = 0; iy <= order; iy++) - { - double lami[3] = - { (1-double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * (1-double(iy)/order), - double(iy)/order }; - - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l); - - curv.CalcElementTransformation (xl, i-1, grid[ix][iy]); - } - - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); - - glMap2d(GL_MAP2_VERTEX_3, - 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, - 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, - &grid[0][0](0)); - glEnable(GL_MAP2_VERTEX_3); - glEnable(GL_AUTO_NORMAL); - - glMapGrid2f(8, 0.0, 0.999, 8, 0.0, 1.0); - glEvalMesh2(GL_FILL, 0, 8, 0, 8); - - glDisable (GL_AUTO_NORMAL); - glDisable (GL_MAP2_VERTEX_3); - } - - for (int quad = 4; quad < 5; quad++) - { - for (int j = 0; j < 4; j++) - fpts[j] = vertices[faces[quad][j]-1]; - - static Point<3> c(0.375, 0.375, 0.25); - if (vispar.shrink < 1) - for (int j = 0; j < 4; j++) - fpts[j] += (1-vispar.shrink) * (c-fpts[j]); - - for (int ix = 0; ix <= order; ix++) - for (int iy = 0; iy <= order; iy++) - { - double lami[4] = - { (1-double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * (1-double(iy)/order), - ( double(ix)/order) * ( double(iy)/order), - (1-double(ix)/order) * ( double(iy)/order) }; - - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = - lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + - lami[2] * fpts[2](l) + lami[3] * fpts[3](l); - - curv.CalcElementTransformation (xl, ei, grid[ix][iy]); - } - - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); - for (int j = 0; j <= order; j++) - ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); - - glMap2d(GL_MAP2_VERTEX_3, - 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, - 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, - &grid[0][0](0)); - glEnable(GL_MAP2_VERTEX_3); - glEnable(GL_AUTO_NORMAL); - - glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0); - glEvalMesh2(GL_FILL, 0, 8, 0, 8); - - glDisable (GL_AUTO_NORMAL); - glDisable (GL_MAP2_VERTEX_3); - } - - - - - - - /* - int hoplotn = 1 << vispar.subdivisions; - - const ELEMENT_FACE * faces = MeshTopology :: GetFaces (PYRAMID); - const Point3d * vertices = MeshTopology :: GetVertices (PYRAMID); - - Point<3> grid[33][33]; - Vec<3> gridn[33][33]; - - - glBegin (GL_TRIANGLES); - - for (int trig = 0; trig < 4; trig++) - { - Point<3> p0 = vertices[faces[trig][0]-1]; - Point<3> p1 = vertices[faces[trig][1]-1]; - Point<3> p2 = vertices[faces[trig][2]-1]; - - if (vispar.shrink < 1) - { - static Point<3> c(0.375, 0.375, 0.25); - p0 = c + vispar.shrink * (p0 - c); - p1 = c + vispar.shrink * (p1 - c); - p2 = c + vispar.shrink * (p2 - c); - } - - - Vec<3> taux = p0-p2; - Vec<3> tauy = p1-p2; - Vec<3> gtaux, gtauy; - - Point<3> xl; - Mat<3,3> dxdxi; - - for (int ix = 0; ix <= hoplotn; ix++) - for (int iy = 0; iy <= hoplotn-ix; iy++) - { - for (int l = 0; l < 3; l++) - xl(l) = - (1-double(ix+iy)/hoplotn) * p2(l) + - (double(ix)/hoplotn) * p0(l) + - (double(iy)/hoplotn) * p1(l); - - curv.CalcElementTransformation (xl, i-1, grid[ix][iy], dxdxi); - - gtaux = dxdxi * taux; - gtauy = dxdxi * tauy; - gridn[ix][iy] = Cross (gtauy, gtaux).Normalize(); - } - - for (int ix = 0; ix < hoplotn; ix++) - for (int iy = 0; iy < hoplotn-ix; iy++) - { - glNormal3dv (gridn[ix][iy]); - glVertex3dv (grid[ix][iy]); - - glNormal3dv (gridn[ix+1][iy]); - glVertex3dv (grid[ix+1][iy]); - - glNormal3dv (gridn[ix][iy+1]); - glVertex3dv (grid[ix][iy+1]); - - if (iy < hoplotn-ix-1) - { - glNormal3dv (gridn[ix][iy+1]); - glVertex3dv (grid[ix][iy+1]); - - glNormal3dv (gridn[ix+1][iy]); - glVertex3dv (grid[ix+1][iy]); - - glNormal3dv (gridn[ix+1][iy+1]); - glVertex3dv (grid[ix+1][iy+1]); - } - } - } - - glEnd (); - - - - - glBegin (GL_QUADS); - - for (int quad = 4; quad < 5; quad++) - { - Point<3> p0 = vertices[faces[quad][0]-1]; - Point<3> p1 = vertices[faces[quad][1]-1]; - Point<3> p2 = vertices[faces[quad][2]-1]; - Point<3> p3 = vertices[faces[quad][3]-1]; - - if (vispar.shrink < 1) - { - static Point<3> c(0.375, 0.375, 0.25); - p0 = c + vispar.shrink * (p0 - c); - p1 = c + vispar.shrink * (p1 - c); - p2 = c + vispar.shrink * (p2 - c); - p3 = c + vispar.shrink * (p3 - c); - } - - Vec<3> taux = p1-p0; - Vec<3> tauy = p3-p0; - Vec<3> gtaux, gtauy; - - Point<3> xl, xg; - Mat<3,3> dxdxi; - - for (int ix = 0; ix <= hoplotn; ix++) - for (int iy = 0; iy <= hoplotn; iy++) - { - Point<3> xl; - for (int l = 0; l < 3; l++) - xl(l) = - (1-double(ix)/hoplotn)*(1-double(iy)/hoplotn) * p0(l) + - ( double(ix)/hoplotn)*(1-double(iy)/hoplotn) * p1(l) + - ( double(ix)/hoplotn)*( double(iy)/hoplotn) * p2(l) + - (1-double(ix)/hoplotn)*( double(iy)/hoplotn) * p3(l); - - curv.CalcElementTransformation (xl, i-1, grid[ix][iy], dxdxi); - - gtaux = dxdxi * taux; - gtauy = dxdxi * tauy; - gridn[ix][iy] = Cross (gtauy, gtaux).Normalize(); - } - - for (int ix = 0; ix < hoplotn; ix++) - for (int iy = 0; iy < hoplotn; iy++) - { - glNormal3dv (gridn[ix][iy]); - glVertex3dv (grid[ix][iy]); - - glNormal3dv (gridn[ix+1][iy]); - glVertex3dv (grid[ix+1][iy]); - - glNormal3dv (gridn[ix+1][iy+1]); - glVertex3dv (grid[ix+1][iy+1]); - - glNormal3dv (gridn[ix][iy+1]); - glVertex3dv (grid[ix][iy+1]); - } - } - - glEnd (); - */ - - - } - else - { - - - - Point3d c(0,0,0); - if (vispar.shrink < 1) - { - for (int j = 1; j <= 5; j++) - { - Point3d p = mesh->Point(el.PNum(j)); - c.X() += p.X() / 5; - c.Y() += p.Y() / 5; - c.Z() += p.Z() / 5; - } - } - - - el.GetSurfaceTriangles (faces); - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, pyramidcol); - if (el.PNum(1)) - { - glBegin (GL_TRIANGLES); - - for (int j = 1; j <= faces.Size(); j++) - { - Element2d & face = faces.Elem(j); - Point3d lp1 = mesh->Point (el.PNum(face.PNum(1))); - Point3d lp2 = mesh->Point (el.PNum(face.PNum(2))); - Point3d lp3 = mesh->Point (el.PNum(face.PNum(3))); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (n.Length()+1e-12); - n *= -1; - glNormal3d (n.X(), n.Y(), n.Z()); - - if (vispar.shrink < 1) - { - lp1 = c + vispar.shrink * (lp1 - c); - lp2 = c + vispar.shrink * (lp2 - c); - lp3 = c + vispar.shrink * (lp3 - c); - } - - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - - glEnd(); - } - } - } - } - glEndList (); - } - - void VisualSceneMesh :: BuildBadelList() - { - ; - } - - void VisualSceneMesh :: BuildIdentifiedList() - { - ; - } - - void VisualSceneMesh :: BuildDomainSurfList() - { - if (domainsurflist) - glDeleteLists (domainsurflist, 1); - - domainsurflist = glGenLists (1); - glNewList (domainsurflist, GL_COMPILE); - - int i, j; - glLineWidth (1.0f); - - glDisable (GL_COLOR_MATERIAL); - - for (i = 1; i <= mesh->GetNSE(); i++) - { - Element2d el = mesh->SurfaceElement (i); - - int drawel = 1; - for (j = 1; j <= el.GetNP(); j++) - { - if (!el.PNum(j)) - drawel = 0; - } - - if (!drawel) - continue; - - if (el.GetIndex() < 1 || el.GetIndex() > mesh->GetNFD()) - continue; - int domin = mesh->GetFaceDescriptor(el.GetIndex()).DomainIn(); - int domout = mesh->GetFaceDescriptor(el.GetIndex()).DomainOut(); - - int fac; - if (domin == vispar.drawdomainsurf) - fac = 1; - else if (domout == vispar.drawdomainsurf) - fac = -1; - else - continue; - - - GLfloat matcol[] = { 1, 0, 0, 1 }; - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol); - - - if (el.GetNP() == 3) - { - glBegin (GL_TRIANGLES); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= ( fac * (n.Length()+1e-12)); - glNormal3d (n.X(), n.Y(), n.Z()); - - if (!vispar.colormeshsize) - { - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - glEnd(); - } - else if (el.GetNP() == 4) - { - glBegin (GL_QUADS); - - const Point3d & lp1 = mesh->Point (el.PNum(1)); - const Point3d & lp2 = mesh->Point (el.PNum(2)); - const Point3d & lp3 = mesh->Point (el.PNum(4)); - const Point3d & lp4 = mesh->Point (el.PNum(3)); - Vec3d n = Cross (Vec3d (lp1, lp2), - Vec3d (lp1, Center (lp3, lp4))); - n /= (fac * (n.Length()+1e-12)); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - glEnd(); - } - else if (el.GetNP() == 6) - { - glBegin (GL_TRIANGLES); - static int trigs[4][3] = { - { 1, 6, 5 }, - { 2, 4, 6 }, - { 3, 5, 4 }, - { 4, 5, 6 } }; - - for (j = 0; j < 4; j++) - { - const Point3d & lp1 = mesh->Point (el.PNum(trigs[j][0])); - const Point3d & lp2 = mesh->Point (el.PNum(trigs[j][1])); - const Point3d & lp3 = mesh->Point (el.PNum(trigs[j][2])); - Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); - n /= (fac * (n.Length() + 1e-12)); - glNormal3d (n.X(), n.Y(), n.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); - } - glEnd(); - } - } - glEndList (); - } - - - - - - - - - - - - - void VisualSceneMesh :: MouseDblClick (int px, int py) - { - int i, hits; - - // select surface triangle by mouse click - - GLuint selbuf[10000]; - glSelectBuffer (10000, selbuf); - - - glRenderMode (GL_SELECT); - - GLint viewport[4]; - glGetIntegerv (GL_VIEWPORT, viewport); - - - glMatrixMode (GL_PROJECTION); - glPushMatrix(); - - GLdouble projmat[16]; - glGetDoublev (GL_PROJECTION_MATRIX, projmat); - - glLoadIdentity(); - gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); - glMultMatrixd (projmat); - - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_MODELVIEW); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - - // SetClippingPlane(); - - glInitNames(); - glPushName (1); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glDisable(GL_CLIP_PLANE0); - - if (vispar.clipenable) - { - Vec<3> n(clipplane[0], clipplane[1], clipplane[2]); - double len = Abs(n); - double mu = -clipplane[3] / (len*len); - Point<3> p (mu * n); - n /= len; - Vec<3> t1 = n.GetNormal (); - Vec<3> t2 = Cross (n, t1); - - double xi1mid = (center - p) * t1; - double xi2mid = (center - p) * t2; - - glLoadName (0); - glBegin (GL_QUADS); - glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2); - glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2); - glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2); - glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2); - glEnd (); - } - - // SetClippingPlane(); - - glCallList (filledlist); - - glDisable (GL_POLYGON_OFFSET_FILL); - - glPopName(); - - glMatrixMode (GL_PROJECTION); - glPopMatrix(); - - glMatrixMode (GL_MODELVIEW); - glPopMatrix(); - - glFlush(); - - - hits = glRenderMode (GL_RENDER); - - // cout << "hits = " << hits << endl; - - int minname = 0; - GLuint mindepth = 0; - - // find clippingplane - GLuint clipdepth = 0; // GLuint(-1); - - for (i = 0; i < hits; i++) - { - int curname = selbuf[4*i+3]; - if (!curname) clipdepth = selbuf[4*i+1]; - } - - for (i = 0; i < hits; i++) - { - int curname = selbuf[4*i+3]; - GLuint curdepth = selbuf[4*i+1]; - /* - cout << selbuf[4*i] << " " << selbuf[4*i+1] << " " - << selbuf[4*i+2] << " " << selbuf[4*i+3] << endl; - */ - if (curname && (curdepth > clipdepth) && - (curdepth < mindepth || !minname)) - { - mindepth = curdepth; - minname = curname; - } - } - - seledge = -1; - if (minname) - { - const Element2d & sel = mesh->SurfaceElement(minname); - - - cout << "select element " << minname - << " on face " << sel.GetIndex() << endl; - cout << "Nodes: "; - for (i = 1; i <= sel.GetNP(); i++) - cout << sel.PNum(i) << " "; - cout << endl; - - selelement = minname; - selface = mesh->SurfaceElement(minname).GetIndex(); - - locpi = (locpi % sel.GetNP()) + 1; - selpoint2 = selpoint; - selpoint = sel.PNum(locpi); - cout << "selected point " << selpoint - << ", pos = " << mesh->Point (selpoint) - << endl; - - for (i = 1; i <= mesh->GetNSeg(); i++) - { - const Segment & seg = mesh->LineSegment(i); - if (seg.p1 == selpoint && seg.p2 == selpoint2 || - seg.p2 == selpoint && seg.p1 == selpoint2) - { - seledge = seg.edgenr; - cout << "seledge = " << seledge << endl; - } - } - - } - else - { - selface = -1; - selelement = -1; - selpoint = -1; - selpoint2 = -1; - } - - glDisable(GL_CLIP_PLANE0); - - selecttimestamp = NextTimeStamp(); - } - - - - - -} - - - - - - - - - - diff --git a/Netgen/libsrc/visualization/vsocc.cpp b/Netgen/libsrc/visualization/vsocc.cpp deleted file mode 100644 index 12cfc5e179..0000000000 --- a/Netgen/libsrc/visualization/vsocc.cpp +++ /dev/null @@ -1,743 +0,0 @@ -#ifdef OCCGEOMETRY - - -#include <mystdlib.h> -#include <myadt.hpp> -#include <meshing.hpp> - -// #include <csg.hpp> -// #include <stlgeom.hpp> - -#include <occgeom.hpp> - -#include "TopoDS_Shape.hxx" -#include "TopoDS_Vertex.hxx" -#include "TopExp_Explorer.hxx" -#include "BRep_Tool.hxx" -#include "TopoDS.hxx" -#include "gp_Pnt.hxx" -#include "Geom_Curve.hxx" -#include "Poly_Triangulation.hxx" -#include "Poly_Array1OfTriangle.hxx" -#include "TColgp_Array1OfPnt2d.hxx" -#include "Poly_Triangle.hxx" -#include "Poly_Polygon3D.hxx" -#include "Poly_PolygonOnTriangulation.hxx" -// #include "BRepMesh.hxx" -// #include "BRepMesh_IncrementalMesh.hxx" - -#include "incvis.hpp" - - -namespace netgen -{ -#include "mvdraw.hpp" - - -extern OCCGeometry * occgeometry; - - - - -/* *********************** Draw OCC Geometry **************** */ - - -VisualSceneOCCGeometry :: VisualSceneOCCGeometry () - : VisualScene() -{ - trilists.SetSize(0); - linelists.SetSize(1); - -} - -VisualSceneOCCGeometry :: ~VisualSceneOCCGeometry () -{ - ; -} - -void VisualSceneOCCGeometry :: DrawScene () -{ - // int i, j, k; - - if ( occgeometry->changed ) - { - BuildScene(); - occgeometry -> changed = 0; - } - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - SetLight(); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - glShadeModel (GL_SMOOTH); - glDisable (GL_COLOR_MATERIAL); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // glEnable (GL_LIGHTING); - - double shine = vispar.shininess; - // double transp = vispar.transp; - - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); - glLogicOp (GL_COPY); - - - float mat_col[] = { 0.2f, 0.2f, 0.8f, 1.0f }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - GLfloat matcoledge[] = { 0, 0, 1, 1 }; - GLfloat matcolhiedge[] = { 1, 0, 0, 1 }; - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcoledge); - glLineWidth (1.0f); - - if (vispar.occshowedges) glCallList (linelists.Get(1)); - if (vispar.occshowsurfaces) glCallList (trilists.Get(1)); - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcolhiedge); - glLineWidth (5.0f); - - if (vispar.occshowedges) glCallList (linelists.Get(2)); - - for (int i = 1; i <= occgeometry->vmap.Extent(); i++) - if (occgeometry->vvispar[i-1].IsHighlighted()) - { - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - matcolhiedge); - glLineWidth (5.0f); - - glBegin (GL_LINES); - - gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(occgeometry->vmap(i))); - double d = rad/100; - glVertex3f (p.X()-d, p.Y(), p.Z()); - glVertex3f (p.X()+d, p.Y(), p.Z()); - glVertex3f (p.X(), p.Y()-d, p.Z()); - glVertex3f (p.X(), p.Y()+d, p.Z()); - glVertex3f (p.X(), p.Y(), p.Z()-d); - glVertex3f (p.X(), p.Y(), p.Z()+d); - glEnd(); - } - - glDisable (GL_POLYGON_OFFSET_FILL); - - glPopMatrix(); - // DrawCoordinateCross (); - // DrawNetgenLogo (); - glFinish(); - - glDisable (GL_POLYGON_OFFSET_FILL); -} - - -/* -void VisualSceneOCCGeometry :: BuildScene (int zoomall) -{ - int i = 0, j, k; - - TopExp_Explorer ex, ex_edge; - - if (vispar.occvisproblemfaces || (occgeometry -> changed != 2)) - { - Box<3> bb = occgeometry -> GetBoundingBox(); - - center = bb.Center(); - rad = bb.Diam() / 2; - - - - if (vispar.occvisproblemfaces) - { - for (i = 1; i <= occgeometry->fmap.Extent(); i++) - if (occgeometry->facemeshstatus[i-1] == -1) - { - GProp_GProps system; - BRepGProp::LinearProperties(occgeometry->fmap(i), system); - gp_Pnt pnt = system.CentreOfMass(); - center = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); - cout << "Setting center to mid of face " << i << " = " << center << endl; - } - } - - - CalcTransformationMatrices(); - } - - - for (i = 1; i <= linelists.Size(); i++) - glDeleteLists (linelists.Elem(i), 1); - linelists.SetSize(0); - - linelists.Append (glGenLists (1)); - glNewList (linelists.Last(), GL_COMPILE); - - i = 0; - for (ex_edge.Init(occgeometry -> shape, TopAbs_EDGE); - ex_edge.More(); ex_edge.Next()) - { - if (BRep_Tool::Degenerated(TopoDS::Edge(ex_edge.Current()))) continue; - i++; - - - TopoDS_Edge edge = TopoDS::Edge(ex_edge.Current()); - - Handle(Poly_PolygonOnTriangulation) aEdgePoly; - Handle(Poly_Triangulation) T; - TopLoc_Location aEdgeLoc; - BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc); - - if(aEdgePoly.IsNull()) - { - cout << "cannot visualize edge " << i << endl; - continue; - } - - glBegin (GL_LINE_STRIP); - - int nbnodes = aEdgePoly -> NbNodes(); - for (j = 1; j <= nbnodes; j++) - { - gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); - glVertex3f (p.X(), p.Y(), p.Z()); - } - - glEnd (); - - - } - - glEndList (); - - for (i = 1; i <= trilists.Size(); i++) - glDeleteLists (trilists.Elem(i), 1); - trilists.SetSize(0); - - - trilists.Append (glGenLists (1)); - glNewList (trilists.Last(), GL_COMPILE); - - i = 0; - - TopExp_Explorer exp0, exp1, exp2, exp3; - int shapenr = 0; - for (exp0.Init(occgeometry -> shape, TopAbs_SOLID); exp0.More(); exp0.Next()) - { - shapenr++; - - if (vispar.occshowvolumenr != 0 && - vispar.occshowvolumenr != shapenr) continue; - - float mat_col[4]; - mat_col[3] = 1; - switch (shapenr) - { - case 1: - mat_col[0] = 0.2; - mat_col[1] = 0.2; - mat_col[2] = 0.8; - break; - case 2: - mat_col[0] = 0.8; - mat_col[1] = 0.2; - mat_col[2] = 0.8; - break; - case 3: - mat_col[0] = 0.2; - mat_col[1] = 0.8; - mat_col[2] = 0.8; - break; - case 4: - mat_col[0] = 0.8; - mat_col[1] = 0.2; - mat_col[2] = 0.2; - break; - case 5: - mat_col[0] = 0.8; - mat_col[1] = 0.8; - mat_col[2] = 0.8; - break; - case 6: - mat_col[0] = 0.6; - mat_col[1] = 0.6; - mat_col[2] = 0.6; - break; - case 7: - mat_col[0] = 0.2; - mat_col[1] = 0.8; - mat_col[2] = 0.2; - break; - case 8: - mat_col[0] = 0.8; - mat_col[1] = 0.8; - mat_col[2] = 0.2; - break; - default: - // mat_col[0] = 1-(1.0/double(shapenr)); - // mat_col[1] = 0.5; - mat_col[0] = 0.5+double((shapenr*shapenr*shapenr*shapenr) % 10)/20.0; - mat_col[1] = 0.5+double(int(shapenr*shapenr*shapenr*shapenr*sin(double(shapenr))) % 10)/20.0; - mat_col[2] = 0.5+double((shapenr*shapenr*shapenr) % 10)/20.0; - } - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - for (exp1.Init(exp0.Current(), TopAbs_SHELL); exp1.More(); exp1.Next()) - for (exp2.Init(exp1.Current().Composed(exp0.Current().Orientation()), TopAbs_FACE); exp2.More(); exp2.Next()) - { - TopoDS_Face face = TopoDS::Face (exp2.Current().Composed(exp1.Current().Orientation())); - - i = occgeometry->fmap.FindIndex(face); - - TopLoc_Location loc; - Handle(Geom_Surface) surf = BRep_Tool::Surface (face); - BRepAdaptor_Surface sf(face, Standard_False); - BRepLProp_SLProps prop(sf, 1, 1e-5); - Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); - - if (triangulation.IsNull()) - { - cout << "cannot visualize face " << i << endl; - continue; - } - - if (vispar.occvisproblemfaces) - { - switch (occgeometry->facemeshstatus[i-1]) - { - case 0: - mat_col[0] = 0.2; - mat_col[1] = 0.2; - mat_col[2] = 0.8; - break; - case 1: - mat_col[0] = 0.2; - mat_col[1] = 0.8; - mat_col[2] = 0.2; - break; - case -1: - mat_col[0] = 0.8; - mat_col[1] = 0.2; - mat_col[2] = 0.2; - break; - } - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - } - glBegin (GL_TRIANGLES); - - int ntriangles = triangulation -> NbTriangles(); - for (j = 1; j <= ntriangles; j++) - { - Poly_Triangle triangle = (triangulation -> Triangles())(j); - for (k = 1; k <= 3; k++) - { - gp_Pnt2d uv = (triangulation -> UVNodes())(triangle(k)); - gp_Pnt pnt; - gp_Vec du, dv; - prop.SetParameters (uv.X(), uv.Y()); - surf->D0 (uv.X(), uv.Y(), pnt); - gp_Vec n; - - if (prop.IsNormalDefined()) - n = prop.Normal(); - else - n = gp_Vec (0,0,0); - - if (face.Orientation() == TopAbs_REVERSED) n *= -1; - glNormal3f (n.X(), n.Y(), n.Z()); - glVertex3f (pnt.X(), pnt.Y(), pnt.Z()); - } - } - glEnd (); - - } - } - - - glEndList (); - -} -*/ - - -void VisualSceneOCCGeometry :: BuildScene (int zoomall) -{ - if (occgeometry -> changed == OCCGEOMETRYVISUALIZATIONFULLCHANGE) - { - center = occgeometry -> Center(); - rad = occgeometry -> GetBoundingBox().Diam() / 2; - - if (vispar.occzoomtohighlightedentity) - { - bool hilite = false; - bool hiliteonepoint = false; - Bnd_Box bb; - - for (int i = 1; i <= occgeometry->fmap.Extent(); i++) - if (occgeometry->fvispar[i-1].IsHighlighted()) - { - hilite = true; - BRepBndLib::Add (occgeometry->fmap(i), bb); - } - - for (int i = 1; i <= occgeometry->emap.Extent(); i++) - if (occgeometry->evispar[i-1].IsHighlighted()) - { - hilite = true; - BRepBndLib::Add (occgeometry->emap(i), bb); - } - - for (int i = 1; i <= occgeometry->vmap.Extent(); i++) - if (occgeometry->vvispar[i-1].IsHighlighted()) - { - hiliteonepoint = true; - BRepBndLib::Add (occgeometry->vmap(i), bb); - } - - if (hilite || hiliteonepoint) - { - double x1,y1,z1,x2,y2,z2; - bb.Get (x1,y1,z1,x2,y2,z2); - Point<3> p1 = Point<3> (x1,y1,z1); - Point<3> p2 = Point<3> (x2,y2,z2); - Box<3> boundingbox(p1,p2); - - center = boundingbox.Center(); - if (hiliteonepoint) - rad = occgeometry -> GetBoundingBox().Diam() / 100; - else - rad = boundingbox.Diam() / 2; - } - } - - CalcTransformationMatrices(); - } - - - // Clear lists - - for (int i = 1; i <= linelists.Size(); i++) - glDeleteLists (linelists.Elem(i), 1); - linelists.SetSize(0); - - for (int i = 1; i <= trilists.Size(); i++) - glDeleteLists (trilists.Elem(i), 1); - trilists.SetSize(0); - - - // Total wireframe - - linelists.Append (glGenLists (1)); - glNewList (linelists.Last(), GL_COMPILE); - - for (int i = 1; i <= occgeometry->emap.Extent(); i++) - { - TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i)); - if (BRep_Tool::Degenerated(edge)) continue; - if (occgeometry->evispar[i-1].IsHighlighted()) continue; - - Handle(Poly_PolygonOnTriangulation) aEdgePoly; - Handle(Poly_Triangulation) T; - TopLoc_Location aEdgeLoc; - BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc); - - if(aEdgePoly.IsNull()) - { - (*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge) - << " without using the occ visualization triangulation" << endl; - - double s0, s1; - Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); - - glBegin (GL_LINE_STRIP); - for (int i = 0; i<=50; i++) - { - gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0); - glVertex3f (p.X(),p.Y(),p.Z()); - } - glEnd (); - - continue; - } - - int nbnodes = aEdgePoly -> NbNodes(); - glBegin (GL_LINE_STRIP); - for (int j = 1; j <= nbnodes; j++) - { - gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); - glVertex3f (p.X(), p.Y(), p.Z()); - } - glEnd (); - } - - glEndList (); - - - // Highlighted edge list - - linelists.Append (glGenLists (1)); - glNewList (linelists.Last(), GL_COMPILE); - - for (int i = 1; i <= occgeometry->emap.Extent(); i++) - if (occgeometry->evispar[i-1].IsHighlighted()) - { - TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i)); - if (BRep_Tool::Degenerated(edge)) continue; - - Handle(Poly_PolygonOnTriangulation) aEdgePoly; - Handle(Poly_Triangulation) T; - TopLoc_Location aEdgeLoc; - BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc); - - if(aEdgePoly.IsNull()) - { - (*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge) - << " without using the occ visualization triangulation" << endl; - - double s0, s1; - Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); - - glBegin (GL_LINE_STRIP); - for (int i = 0; i<=50; i++) - { - gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0); - glVertex3f (p.X(),p.Y(),p.Z()); - } - glEnd (); - - continue; - } - - int nbnodes = aEdgePoly -> NbNodes(); - glBegin (GL_LINE_STRIP); - for (int j = 1; j <= nbnodes; j++) - { - gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); - glVertex3f (p.X(), p.Y(), p.Z()); - } - glEnd (); - } - - glEndList (); - - - - - - // display faces - - trilists.Append (glGenLists (1)); - glNewList (trilists.Last(), GL_COMPILE); - - for (int i = 1; i <= occgeometry->fmap.Extent(); i++) - { - glLoadName (i); - float mat_col[4]; - mat_col[3] = 1; - - if (!occgeometry->fvispar[i-1].IsHighlighted()) - { - mat_col[0] = 0.2; - mat_col[1] = 0.2; - mat_col[2] = 0.8; - } - else - { - mat_col[0] = 0.8; - mat_col[1] = 0.2; - mat_col[2] = 0.2; - } - - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); - - TopoDS_Face face = TopoDS::Face(occgeometry->fmap(i)); - TopLoc_Location loc; - Handle(Geom_Surface) surf = BRep_Tool::Surface (face); - BRepAdaptor_Surface sf(face, Standard_False); - BRepLProp_SLProps prop(sf, 1, 1e-5); - Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); - - if (triangulation.IsNull()) - { - cout << "cannot visualize face " << i << endl; - occgeometry->fvispar[i-1].SetNotDrawable(); - continue; - } - - gp_Pnt2d uv; - gp_Pnt pnt; - gp_Vec n; - - glBegin (GL_TRIANGLES); - - int ntriangles = triangulation -> NbTriangles(); - for (int j = 1; j <= ntriangles; j++) - { - Poly_Triangle triangle = (triangulation -> Triangles())(j); - for (int k = 1; k <= 3; k++) - { - uv = (triangulation -> UVNodes())(triangle(k)); - prop.SetParameters (uv.X(), uv.Y()); - - pnt = (triangulation -> Nodes())(triangle(k)).Transformed(loc); - - // surf->D0 (uv.X(), uv.Y(), pnt); - - if (prop.IsNormalDefined()) - n = prop.Normal(); - else - { - (*testout) << "Visualization of face " << i - << ": Normal vector not defined" << endl; - n = gp_Vec (0,0,0); - } - - if (face.Orientation() == TopAbs_REVERSED) n *= -1; - glNormal3f (n.X(), n.Y(), n.Z()); - glVertex3f (pnt.X(), pnt.Y(), pnt.Z()); - } - } - glEnd (); - - } - glEndList (); - -} - -void SelectFaceInOCCDialogTree (int facenr); - -void VisualSceneOCCGeometry :: MouseDblClick (int px, int py) -{ - int hits; - - // select surface triangle by mouse click - - GLuint selbuf[10000]; - glSelectBuffer (10000, selbuf); - - - glRenderMode (GL_SELECT); - - GLint viewport[4]; - glGetIntegerv (GL_VIEWPORT, viewport); - - - glMatrixMode (GL_PROJECTION); - glPushMatrix(); - - GLdouble projmat[16]; - glGetDoublev (GL_PROJECTION_MATRIX, projmat); - - glLoadIdentity(); - gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); - glMultMatrixd (projmat); - - - - glClearColor(backcolor, backcolor, backcolor, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode (GL_MODELVIEW); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - - - glInitNames(); - glPushName (1); - - glPolygonOffset (1, 1); - glEnable (GL_POLYGON_OFFSET_FILL); - - glDisable(GL_CLIP_PLANE0); - - glCallList (trilists.Get(1)); - - glDisable (GL_POLYGON_OFFSET_FILL); - - glPopName(); - - glMatrixMode (GL_PROJECTION); - glPopMatrix(); - - glMatrixMode (GL_MODELVIEW); - glPopMatrix(); - - glFlush(); - - - hits = glRenderMode (GL_RENDER); - - int minname = 0; - GLuint mindepth = 0; - - // find clippingplane - GLuint clipdepth = 0; // GLuint(-1); - - for (int i = 0; i < hits; i++) - { - int curname = selbuf[4*i+3]; - if (!curname) clipdepth = selbuf[4*i+1]; - } - - for (int i = 0; i < hits; i++) - { - int curname = selbuf[4*i+3]; - GLuint curdepth = selbuf[4*i+1]; - if (curname && (curdepth > clipdepth) && - (curdepth < mindepth || !minname)) - { - mindepth = curdepth; - minname = curname; - } - } - - occgeometry->LowLightAll(); - - if (minname) - { - occgeometry->fvispar[minname-1].Highlight(); - - if (vispar.occzoomtohighlightedentity) - occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; - else - occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; - cout << "Selected face: " << minname << endl; - } - else - { - occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; - } - - glDisable(GL_CLIP_PLANE0); - - SelectFaceInOCCDialogTree (minname); - - - // selecttimestamp = NextTimeStamp(); -} - - - - - - -} - - - -#endif - - diff --git a/Netgen/libsrc/visualization/vssolution.cpp b/Netgen/libsrc/visualization/vssolution.cpp deleted file mode 100644 index 62b6faab83..0000000000 --- a/Netgen/libsrc/visualization/vssolution.cpp +++ /dev/null @@ -1,3005 +0,0 @@ -#include <mystdlib.h> -#include "incvis.hpp" - - -#include <myadt.hpp> -#include <meshing.hpp> -#include <csg.hpp> -#include <stlgeom.hpp> - -#include <visual.hpp> - - -namespace netgen -{ - - extern AutoPtr<Mesh> mesh; - - - VisualSceneSolution :: SolData :: SolData () - : name (0), data (0), solclass(0) - { ; } - - VisualSceneSolution :: SolData :: ~SolData () - { - delete [] name; - delete data; - delete solclass; - } - - - VisualSceneSolution :: VisualSceneSolution () - : VisualScene() - { - surfellist = 0; - linelist = 0; - clipplanelist = 0; - isolinelist = 0; - clipplane_isolinelist = 0; - surface_vector_list = 0; - cone_list = 0; - - surfeltimestamp = GetTimeStamp(); - surfellinetimestamp = GetTimeStamp(); - clipplanetimestamp = GetTimeStamp(); - solutiontimestamp = GetTimeStamp(); - fieldlinestimestamp = GetTimeStamp(); - surface_vector_timestamp = GetTimeStamp(); - AddVisualizationScene ("solution", &vssolution); - } - - VisualSceneSolution :: ~VisualSceneSolution () - { - ClearSolutionData(); - } - - void VisualSceneSolution :: AddSolutionData (SolData * sd) - { - int funcnr = -1; - for (int i = 0; i < soldata.Size(); i++) - { - if (strcmp (soldata[i]->name, sd->name) == 0) - { - delete soldata[i]; - soldata[i] = sd; - funcnr = i; - break; - } - } - - if (funcnr == -1) - { - soldata.Append (sd); - funcnr = soldata.Size()-1; - } - - SolData * nsd = soldata[funcnr]; - - nsd->size = 0; - if (mesh) - { - switch (nsd->soltype) - { - case SOL_NODAL: nsd->size = mesh->GetNV(); break; - case SOL_ELEMENT: nsd->size = mesh->GetNE(); break; - case SOL_SURFACE_ELEMENT: nsd->size = mesh->GetNSE(); break; - case SOL_NONCONTINUOUS: - { - switch (nsd->order) - { - case 0: nsd->size = mesh->GetNE(); break; - case 1: nsd->size = 6 * mesh->GetNE(); break; - case 2: nsd->size = 18 * mesh->GetNE(); break; - } - break; - } - case SOL_SURFACE_NONCONTINUOUS: - { - switch (nsd->order) - { - case 0: nsd->size = mesh->GetNSE(); break; - case 1: nsd->size = 4 * mesh->GetNSE(); break; - case 2: nsd->size = 9 * mesh->GetNSE(); break; - } - break; - } - } - solutiontimestamp = NextTimeStamp(); - } - } - - - void VisualSceneSolution :: ClearSolutionData () - { - for (int i = 0; i < soldata.Size(); i++) - delete soldata[i]; - soldata.SetSize (0); - } - - void VisualSceneSolution :: UpdateSolutionTimeStamp () - { - solutiontimestamp = NextTimeStamp(); - } - - VisualSceneSolution::SolData * VisualSceneSolution :: GetSolData (int i) - { - if (i >= 0 && i < soldata.Size()) - return soldata[i]; - else - return NULL; - } - - - - - void VisualSceneSolution :: SaveSolutionData (const char * filename) - { - PrintMessage (1, "Write solution data to file ", filename); - int i, j, k; - - ofstream ost(filename); - for (i = 0; i < soldata.Size(); i++) - { - const SolData & sol = *soldata[i]; - - ost << "solution " - << sol.name - << " -size=" << sol.size - << " -components=" << sol.components - << " -order=" << sol.order; - if (sol.iscomplex) - ost << " -complex"; - - switch (sol.soltype) - { - case SOL_NODAL: - ost << " -type=nodal"; break; - case SOL_ELEMENT: - ost << " -type=element"; break; - case SOL_SURFACE_ELEMENT: - ost << " -type=surfaceelement"; break; - case SOL_NONCONTINUOUS: - ost << " -type=noncontinuous"; break; - case SOL_SURFACE_NONCONTINUOUS: - ost << " -type=surfacenoncontinuous"; break; - } - - ost << endl; - for (j = 0; j < sol.size; j++) - { - for (k = 0; k < sol.components; k++) - ost << sol.data[j*sol.dist+k] << " "; - ost << "\n"; - } - } - } - - - - - void VisualSceneSolution :: DrawScene () - { - if (!mesh) - { - VisualScene::DrawScene(); - return; - } - - static NgLock mem_lock(mem_mutex); - mem_lock.Lock(); - - NgLock meshlock (mesh->Mutex(), 1); - - BuildScene(); - - CreateTexture (numtexturecols, lineartexture, GL_MODULATE); - - glClearColor(backcolor, backcolor, backcolor, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - SetLight(); - - glPushMatrix(); - glMultMatrixf (transformationmat); - - - - glMatrixMode (GL_MODELVIEW); - - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - - // glPolygonOffset (1, 1); - glPolygonOffset (2, 10); - glEnable (GL_POLYGON_OFFSET_FILL); - - glEnable (GL_COLOR_MATERIAL); - - - if (usetexture) - glEnable (GL_TEXTURE_1D); - - - if (vispar.drawfilledtrigs || vispar.drawtetsdomain > 0 || vispar.drawdomainsurf > 0) - { - SetClippingPlane (); - - glCallList (surfellist); - glCallList (surface_vector_list); - - glDisable(GL_CLIP_PLANE0); - } - - if (showclipsolution) - glCallList (clipplanelist); - - - if (draw_fieldlines) - { - BuildFieldLinesPlot (); - - if (num_fieldlineslists <= 1) - glCallList (fieldlineslist); - else - { // animated - int start = int (time / 10 * num_fieldlineslists); - for (int ln = 0; ln < 10; ln++) - { - int nr = fieldlineslist + (start + ln) % num_fieldlineslists; - glCallList (nr); - } - } - } - - if (usetexture) - glDisable (GL_TEXTURE_1D); - - - - glDisable (GL_POLYGON_OFFSET_FILL); - - glDisable (GL_COLOR_MATERIAL); - - - GLfloat matcol0[] = { 0, 0, 0, 1 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol0); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, matcol0); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matcol0); - - glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - glLineWidth (1.0f); - glColor3f (0.0f, 0.0f, 0.0f); - glDisable (GL_LINE_SMOOTH); - - - if (vispar.drawoutline && !numisolines) - { - SetClippingPlane (); - glCallList (linelist); - glDisable(GL_CLIP_PLANE0); - } - - if (numisolines) - { - SetClippingPlane (); - glCallList (isolinelist); - - glDisable(GL_CLIP_PLANE0); - glCallList (clipplane_isolinelist); - } - - glPopMatrix(); - - glDisable(GL_CLIP_PLANE0); - DrawColorBar (minval, maxval, logscale, lineartexture); - - if (vispar.drawcoordinatecross) - DrawCoordinateCross (); - DrawNetgenLogo (); - - glFinish(); - - - // delete lock; - mem_lock.UnLock(); - } - - - - static void RealVec3d (const double * values, Vec3d & v, - bool iscomplex, bool imag) - { - if (!iscomplex) - { - v.X() = values[0]; - v.Y() = values[1]; - v.Z() = values[2]; - } - else - { - if (!imag) - { - v.X() = values[0]; - v.Y() = values[2]; - v.Z() = values[4]; - } - else - { - v.X() = values[1]; - v.Y() = values[3]; - v.Z() = values[5]; - } - } - } - - - static void RealVec3d (const double * values, Vec3d & v, - bool iscomplex, double phaser, double phasei) - { - if (!iscomplex) - { - v.X() = values[0]; - v.Y() = values[1]; - v.Z() = values[2]; - } - else - { - for (int i = 0; i < 3; i++) - v.X(i+1) = phaser * values[2*i] + phasei * values[2*i+1]; - } - } - - - - - void VisualSceneSolution :: BuildScene (int zoomall) - { - int i, j, k; - - if (!mesh) - { - VisualScene::BuildScene (zoomall); - return; - } - - if (!cone_list) - { - cone_list = glGenLists (1); - glNewList (cone_list, GL_COMPILE); - DrawCone (Point<3> (0,0,0), Point<3> (0,0,1), 0.4); - glEndList(); - } - - - vispar.colormeshsize = 1; - - // recalc clipping plane - SetClippingPlane (); - glDisable(GL_CLIP_PLANE0); - - - SolData * sol = NULL; - SolData * vsol = NULL; - - if (scalfunction != -1) - sol = soldata[scalfunction]; - if (vecfunction != -1) - vsol = soldata[vecfunction]; - - if (mesh->GetTimeStamp () > solutiontimestamp) - { - sol = NULL; - vsol = NULL; - } - - - if (sol && sol->solclass) sol->solclass->SetMultiDimComponent (multidimcomponent); - if (vsol && vsol->solclass) vsol->solclass->SetMultiDimComponent (multidimcomponent); - - if (!autoscale || scalfunction == -1) - { - minval = mminval; - maxval = mmaxval; - } - else - { - if (mesh->GetTimeStamp () > surfeltimestamp || - vispar.clipplanetimestamp > clipplanetimestamp || - solutiontimestamp > surfeltimestamp) - { - GetMinMax (scalfunction, scalcomp, minval, maxval); - } - } - - - if (mesh->GetTimeStamp() > surfeltimestamp || - solutiontimestamp > surfeltimestamp || - zoomall) - { - if (mesh->GetTimeStamp() > surfeltimestamp || - zoomall) - { - // mesh has changed - - Point3d pmin, pmax; - static double oldrad = 0; - - mesh->GetBox (pmin, pmax, -1); - center = Center (pmin, pmax); - rad = 0.5 * Dist (pmin, pmax); - - glEnable (GL_NORMALIZE); - - if (rad > 1.5 * oldrad || - mesh->GetMajorTimeStamp() > surfeltimestamp || - zoomall) - { - CalcTransformationMatrices(); - oldrad = rad; - } - } - - if (surfellist) - glDeleteLists (surfellist, 1); - - surfellist = glGenLists (1); - glNewList (surfellist, GL_COMPILE); - - DrawSurfaceElements(); - - glEndList (); - - surfeltimestamp = max2 (solutiontimestamp, mesh->GetTimeStamp()); - } - - - if (mesh->GetTimeStamp() > surfellinetimestamp || - solutiontimestamp > surfellinetimestamp || - zoomall) - { - if (linelist) - glDeleteLists (linelist, 1); - - linelist = glGenLists (1); - glNewList (linelist, GL_COMPILE); - - DrawSurfaceElementLines(); - - glEndList (); - - surfellinetimestamp = max2 (solutiontimestamp, mesh->GetTimeStamp()); - } - - - - if (mesh->GetTimeStamp() > surface_vector_timestamp || - solutiontimestamp > surface_vector_timestamp || - zoomall) - { - if (surface_vector_list) - glDeleteLists (surface_vector_list, 1); - - surface_vector_list = glGenLists (1); - glNewList (surface_vector_list, GL_COMPILE); - - glEnable (GL_NORMALIZE); - DrawSurfaceVectors(); - - glEndList (); - - surface_vector_timestamp = - max2 (mesh->GetTimeStamp(), solutiontimestamp); - } - - - if (clipplanetimestamp < vispar.clipplanetimestamp || - clipplanetimestamp < solutiontimestamp) - { - - // cout << "clipsolution = " << clipsolution << endl; - if (vispar.clipenable && clipsolution) - { - // lock->UnLock(); - NgLock mlock (mesh->Mutex(), 0); - mlock.UnLock(); - mesh->BuildElementSearchTree(); - mlock.Lock(); - - // lock->Lock(); - } - - if (clipplanelist) - glDeleteLists (clipplanelist, 1); - - - clipplanelist = glGenLists (1); - glNewList (clipplanelist, GL_COMPILE); - - if (vispar.clipenable && clipsolution == 1 && sol) - { - glDisable(GL_CLIP_PLANE0); - - ARRAY<ClipPlaneTrig> cpt; - GetClippingPlaneTrigs (cpt); - - glNormal3d (-clipplane[0], -clipplane[1], -clipplane[2]); - - glBegin (GL_TRIANGLES); - for (i = 0; i < cpt.Size(); i++) - DrawClipPlaneTrig (sol, scalcomp, cpt[i], 0); // 2*subdivisions); - glEnd(); - - glEnable(GL_CLIP_PLANE0); - } - - - if (vispar.clipenable && clipsolution == 2 && vsol) - { - if (autoscale) - GetMinMax (vecfunction, 0, minval, maxval); - - - bool drawelem; - ARRAY<ClipPlanePoint> cpp; - GetClippingPlaneGrid (cpp); - - for (i = 0; i < cpp.Size(); i++) - { - const ClipPlanePoint & p = cpp[i]; - double values[6]; - Vec3d v; - - drawelem = GetValues (vsol, p.elnr, p.lam1, p.lam2, p.lam3, values); - RealVec3d (values, v, vsol->iscomplex, imag_part); - - double val = v.Length(); - - // "drawelem": added 07.04.2004 (FB) - if (drawelem && val > 1e-10 * maxval) - { - v *= (rad / val / gridsize * 0.5); - - SetOpenGlColor (val, minval, maxval, logscale); - DrawCone (p.p, p.p+v, rad / gridsize * 0.2); - } - } - } - - glEndList (); - } - - if ( - numisolines && - (clipplanetimestamp < vispar.clipplanetimestamp || - clipplanetimestamp < solutiontimestamp) - ) - { - if (isolinelist) glDeleteLists (isolinelist, 1); - - isolinelist = glGenLists (1); - glNewList (isolinelist, GL_COMPILE); - - Point<3> points[1100]; - double values[1100]; - - int nse = mesh->GetNSE(); - - if (sol) - { - glBegin (GL_LINES); - - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = (*mesh)[sei]; - - if (el.GetType() == TRIG || el.GetType() == TRIG6) - { - Point<3> lp1, lp2, lp3; - if (!mesh->GetCurvedElements().IsHighOrder()) - { - GetPointDeformation (el[0]-1, lp1); - GetPointDeformation (el[1]-1, lp2); - GetPointDeformation (el[2]-1, lp3); - } - - int n = 1 << subdivisions; - int ii = 0; - int ix, iy; - for (iy = 0; iy <= n; iy++) - for (ix = 0; ix <= n-iy; ix++) - { - double x = double(ix) / n; - double y = double(iy) / n; - - // TODO: consider return value (bool: draw/don't draw element) - GetSurfValue (sol, sei, x, y, scalcomp, values[ii]); - Point<2> xref(x,y); - - if (mesh->GetCurvedElements().IsHighOrder()) - mesh->GetCurvedElements(). - CalcSurfaceTransformation (xref, sei, points[ii]); - else - points[ii] = lp3 + x * (lp1-lp3) + y * (lp2-lp3); - - if (deform) - { - Vec<3> def; - GetSurfDeformation (sei, x, y, def); - points[ii] += def; - } - ii++; - } - - ii = 0; - for (iy = 0; iy < n; iy++, ii++) - for (ix = 0; ix < n-iy; ix++, ii++) - { - int index[] = { ii, ii+1, ii+n-iy+1, - ii+1, ii+n-iy+2, ii+n-iy+1 }; - - DrawIsoLines (points[index[0]], points[index[1]], points[index[2]], - values[index[0]], values[index[1]], values[index[2]], - minval, maxval, numisolines); - if (ix < n-iy-1) - DrawIsoLines (points[index[3]], points[index[4]], points[index[5]], - values[index[3]], values[index[4]], values[index[5]], - minval, maxval, numisolines); - } - } - - - if (el.GetType() == QUAD || el.GetType() == QUAD6 || el.GetType() == QUAD8 ) - { - Point<3> lpi[4]; - Vec<3> vx, vy, vtwist, def; - if (!mesh->GetCurvedElements().IsHighOrder()) - { - for (int j = 0; j < 4; j++) - GetPointDeformation (el[j]-1, lpi[j]); - vx = lpi[1]-lpi[0]; - vy = lpi[3]-lpi[0]; - vtwist = (lpi[0]-lpi[1]) + (lpi[2]-lpi[3]); - } - - int n = 1 << subdivisions; - int ix, iy, ii = 0; - for (iy = 0; iy <= n; iy++) - for (ix = 0; ix <= n; ix++, ii++) - { - double x = double(ix) / n; - double y = double(iy) / n; - - // TODO: consider return value (bool: draw/don't draw element) - GetSurfValue (sol, sei, x, y, scalcomp, values[ii]); - Point<2> xref(x,y); - - if (mesh->GetCurvedElements().IsHighOrder()) - mesh->GetCurvedElements(). - CalcSurfaceTransformation (xref, sei, points[ii]); - else - points[ii] = lpi[0] + x * vx + y * vy + x*y * vtwist; - - if (deform) - { - GetSurfDeformation (sei, x, y, def); - points[ii] += def; - } - } - - ii = 0; - for (iy = 0; iy < n; iy++, ii++) - for (ix = 0; ix < n; ix++, ii++) - { - DrawIsoLines (points[ii], points[ii+1], points[ii+n+1], - values[ii], values[ii+1], values[ii+n+1], - minval, maxval, numisolines); - DrawIsoLines (points[ii+1], points[ii+n+2], points[ii+n+1], - values[ii+1], values[ii+n+2], values[ii+n+1], - minval, maxval, numisolines); - } - } - } - glEnd(); - } - glEndList (); - - if (clipplane_isolinelist) glDeleteLists (clipplane_isolinelist, 1); - - if (vispar.clipenable && clipsolution == 1 && sol) - { - clipplane_isolinelist = glGenLists (1); - glNewList (clipplane_isolinelist, GL_COMPILE); - - ARRAY<ClipPlaneTrig> cpt; - GetClippingPlaneTrigs (cpt); - bool drawelem; - - glNormal3d (-clipplane[0], -clipplane[1], -clipplane[2]); - - if (numisolines) - for (i = 0; i < cpt.Size(); i++) - { - const ClipPlaneTrig & trig = cpt[i]; - double vali[3]; - for (j = 0; j < 3; j++) - drawelem = GetValue (sol, trig.elnr, - trig.points[j].lami(0), - trig.points[j].lami(1), - trig.points[j].lami(2), scalcomp, vali[j]); - - if ( drawelem ) - DrawIsoLines (trig.points[0].p, - trig.points[1].p, - trig.points[2].p, - vali[0], vali[1], vali[2], minval, maxval, numisolines); - } - glEndList (); - } - glEnd(); - - - } - - clipplanetimestamp = max2 (vispar.clipplanetimestamp, solutiontimestamp); - } - - - void VisualSceneSolution :: BuildFieldLinesPlot () - { - if (fieldlinestimestamp >= solutiontimestamp) - return; - fieldlinestimestamp = solutiontimestamp; - - - if (fieldlineslist) - glDeleteLists (fieldlineslist, num_fieldlineslists); - - if (vecfunction == -1) - return; - - - const SolData * vsol = soldata[vecfunction]; - - num_fieldlineslists = (vsol -> iscomplex) ? 100 : 1; - - Point3d pmin, pmax; - mesh->GetBox (pmin, pmax); - double lami[3]; - int i; - bool drawelem; - - fieldlineslist = glGenLists (num_fieldlineslists); - - for (int ln = 0; ln < num_fieldlineslists; ln++) - { - glNewList (fieldlineslist + ln, GL_COMPILE); - - double phi = 2*M_PI*ln / num_fieldlineslists; - double phaser = cos(phi); - double phasei = sin(phi); - - for (i = 1; i <= num_fieldlines / num_fieldlineslists+1; i++) - { - Point3d p (pmin.X() + double (rand()) / RAND_MAX * (pmax.X()-pmin.X()), - pmin.Y() + double (rand()) / RAND_MAX * (pmax.Y()-pmin.Y()), - pmin.Z() + double (rand()) / RAND_MAX * (pmax.Z()-pmin.Z())); - - ElementIndex elnr = mesh->GetElementOfPoint (p, lami)-1; - (*testout) << "p = " << p << "; elnr = " << elnr << endl; - if (elnr != -1) - { - Vec3d v; - double values[6]; - drawelem = GetValues (vsol, elnr, lami[0], lami[1], lami[2], values); - RealVec3d (values, v, vsol->iscomplex, phaser, phasei); - - double val = v.Length(); - - if (!fieldlines_randomstart || - (double (rand()) / RAND_MAX) < (val / maxval)) - { - int i; - Point3d p0 = p; - v *= (rad / val * 0.02); - SetOpenGlColor (val, minval, maxval, logscale); - - Point3d p2 = p + v; - cout << " p " << p << endl; - // "drawelem": added 07.04.2004 (FB) - if ( drawelem ) DrawCylinder (p, p2, rad * 0.003); - p = p2; - - for(i=0;i<20;i++) - { - ElementIndex elnr = mesh->GetElementOfPoint (p, lami)-1; - - if (elnr != -1) - { - drawelem = GetValues (vsol, elnr, lami[0], lami[1], lami[2], values); - RealVec3d (values, v, vsol->iscomplex, phaser, phasei); - val = v.Length(); - v *= (rad / val * 0.02); - - SetOpenGlColor (val, minval, maxval, logscale); - p2 = p +v; - // "drawelem": added 07.04.2004 (FB) - if ( drawelem ) DrawCylinder (p, p2, rad * 0.003); - p = p2; - } - else break; - } - p=p0; - for(i=0;i<20;i++) - { - ElementIndex elnr = mesh->GetElementOfPoint (p, lami)-1; - - if (elnr != -1) - { - drawelem = GetValues (vsol, elnr, lami[0], lami[1], lami[2], values); - RealVec3d (values, v, vsol->iscomplex, phaser, phasei); - - val = v.Length(); - v *= (rad / val * 0.02); - - SetOpenGlColor (val, minval, maxval, logscale); - p2 = p - v; - // "drawelem": added 07.04.2004 (FB) - if ( drawelem ) DrawCylinder (p, p2, rad * 0.003); - p = p2; - } - else break; - } - } - } - } - glEndList (); - } - } - - - - - void VisualSceneSolution :: DrawSurfaceElements () - { - const SolData * sol = NULL; - const SolData * vsol = NULL; - bool drawelem = 0; - - if (scalfunction != -1) - sol = soldata[scalfunction]; - if (vecfunction != -1) - vsol = soldata[vecfunction]; - - if (mesh->GetTimeStamp () > solutiontimestamp) - { - sol = NULL; - vsol = NULL; - } - - glLineWidth (1.0f); - - if (!sol || !sol->draw_surface) - glDisable (GL_TEXTURE_1D); - - Point<3> points[1100]; - Vec<3> nvs[1100]; - double values[1100]; - - int nse = mesh->GetNSE(); - - glBegin (GL_TRIANGLES); - - // glColor3f (0.4, 0.4, 0.4); - // glColor3d (0.8, 0.8, 0.8); - glColor3d (1.0, 1.0, 1.0); - - for(SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = (*mesh)[sei]; - - if(vispar.drawdomainsurf > 0 && - ((mesh->GetDimension() == 3 && - vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainIn() && - vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainOut()) || - (mesh->GetDimension() == 2 && el.GetIndex() != vispar.drawdomainsurf))) continue; - - - if ( el.GetType() == TRIG || el.GetType() == TRIG6 ) - { - Point<3> p1, p2, p3; - if (!mesh->GetCurvedElements().IsHighOrder()) - { - GetPointDeformation (el[0]-1, p1, sei); - GetPointDeformation (el[1]-1, p2, sei); - GetPointDeformation (el[2]-1, p3, sei); - } - - int n = 1 << subdivisions; - int ii = 0; - for (int iy = 0; iy <= n; iy++) - for (int ix = 0; ix <= n-iy; ix++) - { - double x = double(ix) / n; - double y = double(iy) / n; - - if (sol && sol->draw_surface) - drawelem = GetSurfValue (sol, sei, x, y, scalcomp, values[ii]); - - Point<2> xref(x,y); - Mat<3,2> dxdxi; - - if (mesh->GetCurvedElements().IsHighOrder()) - { - mesh->GetCurvedElements(). - CalcSurfaceTransformation (xref, sei, points[ii], dxdxi); - nvs[ii] = Cross (dxdxi.Col(0), dxdxi.Col(1)); - nvs[ii].Normalize(); - } - else - { - points[ii] = p3 + x * (p1-p3) + y * (p2-p3); - nvs[ii] = Cross (p2-p1, p3-p1); - nvs[ii].Normalize(); - } - - if (deform) - { - Vec<3> def; - GetSurfDeformation (sei, x, y, def); - points[ii] += def; - } - ii++; - } - - ii = 0; - for (int iy = 0; iy < n; iy++, ii++) - for (int ix = 0; ix < n-iy; ix++, ii++) - { - double x = double(ix) / n; - double y = double(iy) / n; - - int index[] = { ii, ii+1, ii+n-iy+1, - ii+1, ii+n-iy+2, ii+n-iy+1 }; - - int np = (ix == n-iy-1) ? 3 : 6; - for (int j = 0; j < np; j++) - { - if (sol && sol->draw_surface && drawelem) - SetOpenGlColor (values[index[j]], minval, maxval, logscale); - else - glColor3f (0.4f, 0.4f, 0.4f); - - glNormal3dv (nvs[index[j]]); - glVertex3dv (points[index[j]]); - } - } - } - } - glEnd (); - - - - - - glBegin (GL_QUADS); - for (SurfaceElementIndex sei = 0; sei < nse; sei++) - { - const Element2d & el = (*mesh)[sei]; - - if(vispar.drawdomainsurf > 0 && - ((mesh->GetDimension() == 3 && - vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainIn() && - vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainOut()) || - (mesh->GetDimension() == 2 && el.GetIndex() != vispar.drawdomainsurf))) continue; - - if ( el.GetType() == QUAD || el.GetType() == QUAD6 ) - { - Point<3> lpi[4]; - Vec<3> vx, vy, vtwist; - - if (!mesh->GetCurvedElements().IsHighOrder()) - { - for (int k = 0; k < 4; k++) - GetPointDeformation (el[k]-1, lpi[k]); - - vx = lpi[1]-lpi[0]; - vy = lpi[3]-lpi[0]; - vtwist = (lpi[0]-lpi[1]) + (lpi[2]-lpi[3]); - } - Vec<3> nv = Cross (lpi[1]-lpi[0], Center (lpi[2],lpi[3]) - lpi[0]); - nv.Normalize(); - glNormal3dv (nv); - - int n = 1 << subdivisions; - int ii = 0; - int ix, iy; - for (iy = 0; iy <= n; iy++) - for (ix = 0; ix <= n; ix++) - { - double x = double(ix) / n; - double y = double(iy) / n; - - Point<2> xref(x,y); - Mat<3,2> dxdxi; - - if (sol && sol->draw_surface) - drawelem = GetSurfValue (sol, sei, x, y, scalcomp, values[ii]); - - if (mesh->GetCurvedElements().IsHighOrder()) - { - mesh->GetCurvedElements(). - CalcSurfaceTransformation (xref, sei, points[ii], dxdxi); - nvs[ii] = Cross (dxdxi.Col(0), dxdxi.Col(1)); - nvs[ii].Normalize(); - } - else - { - points[ii] = lpi[0] + x * vx + y * vy + x*y * vtwist; - nvs[ii] = Cross (vx, vy); - nvs[ii].Normalize(); - } - - if (deform) - { - Vec<3> def; - GetSurfDeformation (sei, x, y, def); - points[ii] += def; - } - - ii++; - } - - ii = 0; - for (iy = 0; iy < n; iy++, ii++) - for (ix = 0; ix < n; ix++, ii++) - { - double x = double(ix) / n; - double y = double(iy) / n; - - int index[] = { ii, ii+1, ii+n+2, ii+n+1 }; - - for (int j = 0; j < 4; j++) - { - if (sol && sol->draw_surface && drawelem) - SetOpenGlColor (values[index[j]], minval, maxval, logscale); - else - glColor3f (0.4f, 0.4f, 0.4f); - - glNormal3dv (nvs[index[j]]); - glVertex3dv (points[index[j]]); - } - } - } - } - glEnd(); - - if (usetexture) - glEnable (GL_TEXTURE_1D); - } - - - // Bernstein Pol B_{n,i}(x) = n! / i! / (n-i)! (1-x)^{n-i} x^i - static double Bernstein (int n, int i, double x) - { - int j; - double val = 1; - for (j = 1; j <= i; j++) - val *= x / j; - for (j = 1; j <= n-i; j++) - val *= (1-x) / j; - for (j = 1; j <= n; j++) - val *= j; - return val; - } - - void VisualSceneSolution :: DrawSurfaceElementLines () - { - int i, j, k, l; - SurfaceElementIndex sei; - - /* - int p = 4; - DenseMatrix mat(p+1,p+1), invmat(p+1,p+1); - for (i = 0; i <= p; i++) - for (j = 0; j <= p; j++) - mat.Elem(i+1,j+1) = Bernstein(p, i, double(j)/p); - CalcIo -nverse (mat, invmat); - */ - - glLineWidth (1.0f); - glNormal3d (1, 0, 0); - - int nse = mesh->GetNSE(); - - for (sei = 0; sei < nse; sei++) - { - Element2d & el = (*mesh)[sei]; - - int nv; - if (el.GetType() == TRIG || el.GetType() == TRIG6) - nv = 3; - else - nv = 4; - - Point<3> p1, p2, p3, p4; - if (!mesh->GetCurvedElements().IsHighOrder()) - { - p1 = (*mesh)[el[0]]; - p2 = (*mesh)[el[1]]; - p3 = (*mesh)[el[2]]; - if (nv == 4) - p4 = (*mesh)[el[3]]; - } - - - // glBegin (GL_LINE_LOOP); - int n = 1 << subdivisions; - // n = p; - - Point<3> pnt; - for (k = 0; k < nv; k++) - { - Point<2> p0; - Vec<2> vtau; - if (nv == 3) - switch (k) - { - case 0: - p0 = Point<2> (0,0); - vtau = Vec<2> (1,0); - break; - case 1: - p0 = Point<2> (1,0); - vtau = Vec<2> (-1,1); - break; - case 2: - p0 = Point<2> (0,1); - vtau = Vec<2> (0,-1); - break; - } - else - switch (k) - { - case 0: - p0 = Point<2> (0,0); - vtau = Vec<2> (1,0); - break; - case 1: - p0 = Point<2> (1,0); - vtau = Vec<2> (0,1); - break; - case 2: - p0 = Point<2> (1,1); - vtau = Vec<2> (-1,0); - break; - case 3: - p0 = Point<2> (0,1); - vtau = Vec<2> (0,-1); - break; - } - - - glBegin (GL_LINE_STRIP); - Point<3> pts[33], pts2[33]; - if (n > 32) cerr << "too many subdivisions, code 433425" << endl; - - for (int ix = 0; ix <= n; ix++) - { - Point<2> p = p0 + (double(ix) / n) * vtau; - double x = p(0); - double y = p(1); - - if (mesh->GetCurvedElements().IsHighOrder()) - mesh->GetCurvedElements(). - CalcSurfaceTransformation (p, sei, pnt); - else - { - if (nv == 3) - pnt = p3 + x * (p1-p3) + y * (p2-p3); - else - pnt = p1 + x * (p2-p1) + y * (p4-p1) + x*y * ( (p1-p2)+(p3-p4) ); - } - - if (deform) - { - Vec<3> def; - GetSurfDeformation (sei, x, y, def); - pnt += def; - } - - glVertex3dv (pnt); - - pts[ix] = pnt; - } - glEnd (); - - - - - - /* - // convert from point-values to Bernstein basis - for (i = 0; i < 3; i++) - for (j = 0; j <= p; j++) - { - pts2[j](i) = 0; - for (l = 0; l <= p; l++) - pts2[j](i) += invmat(l,j) * pts[l](i); - } - - - glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, n+1, &pts2[0](0)); - glEnable(GL_MAP1_VERTEX_3); - - int steps = 1 << subdivisions; - -// glBegin (GL_LINE_STRIP); -// for (int hi = 0; hi <= 10; hi++) -// glEvalCoord1d (double(hi)/10.0); -// glEnd (); - - glMapGrid1d (steps, 0.0, 1.0); - glEvalMesh1(GL_LINE, 0, steps); - glDisable(GL_MAP1_VERTEX_3); - */ - } - - } - - } - - - - - - - - - - - - - - - - - - - - -void VisualSceneSolution :: DrawSurfaceVectors () -{ - int j, k; - int dir, dir1, dir2; - SurfaceElementIndex sei; - - const SolData * vsol = NULL; - bool drawelem; - - if (vecfunction != -1) - vsol = soldata[vecfunction]; - - if (mesh->GetTimeStamp () > solutiontimestamp) - { - vsol = NULL; - } - - if (!vsol) return; - - - Point<3> pmin = center - Vec3d (rad, rad, rad); - Point<3> pmax = center - Vec3d (rad, rad, rad); - - double s, t; - - // draw surface cones - // if (0) - /* - if (vsol->soltype==SOL_SURFACE_ELEMENT || - vsol->soltype==SOL_SURFACE_NONCONTINUOUS || - vsol->soltype==SOL_VIRTUALFUNCTION) - */ - - if (vsol->draw_surface && showsurfacesolution) - { - int nse = mesh->GetNSE(); - for (sei = 0; sei < nse; sei++) - { - const Element2d & el = (*mesh)[sei]; - - if (el.GetType() != TRIG && el.GetType() != TRIG6) continue; - - Point<3> lp[3]; - Point<2> p2d[3]; - /* - for (k = 0; k < 3; k++) - lp[k] = mesh->Point (el[k]); - */ - lp[0] = mesh->Point(el[2]); - lp[1] = mesh->Point(el[0]); - lp[2] = mesh->Point(el[1]); - - - Vec<3> n = Cross (lp[1]-lp[0], lp[2]-lp[0]); - Vec<3> na (fabs (n(0)), fabs(n(1)), fabs(n(2))); - if (na(0) > na(1) && na(0) > na(2)) - dir = 1; - else if (na(1) > na(2)) - dir = 2; - else - dir = 3; - - dir1 = (dir % 3) + 1; - dir2 = (dir1 % 3) + 1; - - for (k = 0; k < 3; k++) - { - p2d[k] = Point<2> ((lp[k](dir1-1) - pmin(dir1-1)) / (2*rad), - (lp[k](dir2-1) - pmin(dir2-1)) / (2*rad)); - } - - double minx2d, maxx2d, miny2d, maxy2d; - minx2d = maxx2d = p2d[0](0); - miny2d = maxy2d = p2d[0](1); - for (k = 1; k < 3; k++) - { - minx2d = min2 (minx2d, p2d[k](0)); - maxx2d = max2 (maxx2d, p2d[k](0)); - miny2d = min2 (miny2d, p2d[k](1)); - maxy2d = max2 (maxy2d, p2d[k](1)); - } - - double mat11 = p2d[1](0) - p2d[0](0); - double mat21 = p2d[1](1) - p2d[0](1); - double mat12 = p2d[2](0) - p2d[0](0); - double mat22 = p2d[2](1) - p2d[0](1); - - double det = mat11*mat22-mat21*mat12; - double inv11 = mat22/det; - double inv21 = -mat21/det; - double inv12 = -mat12/det; - double inv22 = mat11/det; - - // cout << "drawsurfacevectors. xoffset = " << xoffset << ", yoffset = "; - // cout << yoffset << endl; - - for (s = xoffset/gridsize; s <= 1+xoffset/gridsize; s += 1.0 / gridsize) - if (s >= minx2d && s <= maxx2d) - for (t = yoffset/gridsize; t <= 1+yoffset/gridsize; t += 1.0 / gridsize) - if (t >= miny2d && t <= maxy2d) - { - double lam1 = inv11 * (s - p2d[0](0)) + inv12 * (t-p2d[0](1)); - double lam2 = inv21 * (s - p2d[0](0)) + inv22 * (t-p2d[0](1)); - - if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1) - { - Point<3> cp; - for (k = 0; k < 3; k++) - cp(k) = lp[0](k) + - lam1 * (lp[1](k)-lp[0](k)) + - lam2 * (lp[2](k)-lp[0](k)); - - Vec<3> v; - double values[6]; - drawelem = GetSurfValues (vsol, sei, lam1, lam2, values); - - if (!vsol->iscomplex) - for (k = 0; k < 3; k++) - v(k) = values[k]; - else - { - if (!imag_part) - for (k = 0; k < 3; k++) - v(k) = values[2*k]; - else - for (k = 0; k < 3; k++) - v(k) = values[2*k+1]; - } - - if (mesh->GetDimension() == 2) - if ( (!vsol->iscomplex && vsol->components != 3) || - (vsol->iscomplex && vsol->components != 6) ) - v(2) = 0; - - double val = v.Length(); - SetOpenGlColor (val, minval, maxval, logscale); - - if (val > 1e-10 * maxval) - v *= (rad / val / gridsize * 0.5); - // "drawelem": added 07.04.2004 (FB) - if ( drawelem ) DrawCone (cp, cp+4*v, 0.8*rad / gridsize); - - - /* - v /= val; - - glPushMatrix(); - glTranslated (cp(0), cp(1), cp(2)); - - double l = 2*rad/gridsize; - double r = 0.8*rad/gridsize; - glScaled (l, l, l); - - double phi = acos (v(2)); - glRotated (-180/M_PI*phi, v(1), -v(0), 0); - - glCallList (cone_list); - glPopMatrix(); - */ - } - } - } - } -} - - - - -void VisualSceneSolution :: -DrawIsoLines (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - double val1, double val2, double val3, - double minval, double maxval, int n) -{ - DrawIsoLines2 (p1, p2, p1, p3, val1, val2, val1, val3, minval, maxval, n); - DrawIsoLines2 (p2, p1, p2, p3, val2, val1, val2, val3, minval, maxval, n); - DrawIsoLines2 (p3, p1, p3, p2, val3, val1, val3, val2, minval, maxval, n); -} - -void VisualSceneSolution :: -DrawIsoLines2 (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Point3d & p4, - double val1, double val2, double val3, double val4, - double minval, double maxval, int n) -{ - if (val1 > val2) - DrawIsoLines2 (p2, p1, p3, p4, val2, val1, val3, val4, minval, maxval, n); - if (val3 > val4) - DrawIsoLines2 (p1, p2, p4, p3, val1, val2, val4, val3, minval, maxval, n); - - val2 += 1e-10; - val4 += 1e-10; - - double fac = (maxval-minval) / n; - double idelta1 = 1.0 / (val2 - val1); - double idelta2 = 1.0 / (val4 - val3); - - int mini = int ((max2 (val1, val3) - minval) / fac); - int maxi = int ((min2 (val2, val4) - minval) / fac); - if (mini < 0) mini = 0; - if (maxi > n-1) maxi = n-1; - - for (int i = mini; i <= maxi+1; i++) - { - double val = minval + i * fac; - double lam1 = (val - val1) * idelta1; - double lam2 = (val - val3) * idelta2; - if (lam1 >= 0 && lam1 <= 1 && lam2 >= 0 && lam2 <= 1) - { - Point3d lp1 = p1 + lam1 * Vec3d (p1, p2); - Point3d lp2 = p3 + lam2 * Vec3d (p3, p4); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); - glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); - } - } -} - - - - - - - -void VisualSceneSolution :: -GetMinMax (int funcnr, int comp, double & minv, double & maxv) const -{ - int i, j; - const SolData * sol; - double val; - bool considerElem; - - bool hasit = false; - minv = 0; maxv = 1; - if (funcnr != -1) - { - sol = soldata[funcnr]; - if (sol->draw_volume) - { - int ne = mesh->GetNE(); - for (int i = 0; i < ne; i++) - { - // "considerElem": added 07.04.2004 (FB) - considerElem = GetValue (sol, i, 0.333, 0.333, 0.333, comp, val); - if (considerElem) - { - if (val > maxv || !hasit) - maxv = val; - if (val < minv || !hasit) - minv = val; - hasit = true; - } - } - } - if (sol->draw_surface) - { - int nse = mesh->GetNSE(); - for (int i = 0; i < nse; i++) - { - // "considerElem": added 07.04.2004 (FB) - considerElem = GetSurfValue (sol, i, 0.333, 0.333, comp, val); - if (considerElem) - { - if (val > maxv || !hasit) - maxv = val; - if (val < minv || !hasit) - minv = val; - hasit = true; - } - } - } - } -} - - - - - -bool VisualSceneSolution :: -GetValues (const SolData * data, ElementIndex elnr, - double lam1, double lam2, double lam3, - double * values) const -{ - bool ok; - switch (data->soltype) - { - case SOL_VIRTUALFUNCTION: - { - ok = data->solclass->GetValue (elnr, lam1, lam2, lam3, values); - break; - } - default: - { - for (int i = 0; i < data->components; i++) - ok = GetValue (data, elnr, lam1, lam2, lam3, i+1, values[i]); - } - } - return ok; -} - - -bool VisualSceneSolution :: -GetValue (const SolData * data, ElementIndex elnr, - double lam1, double lam2, double lam3, - int comp, double & val) const -{ - val = 0; - bool ok = 0; - - if (comp == 0) - { - ArrayMem<double,20> values(data->components); - ok = GetValues (data, elnr, lam1, lam2, lam3, &values[0]); - - switch (evalfunc) - { - case FUNC_ABS: - { - for (int ci = 0; ci < data->components; ci++) - val += sqr (values[ci]); - val = sqrt (val); - break; - } - case FUNC_ABS_TENSOR: - { - int d; - switch (data->components) - { - case 1: d = 1; break; - case 3: d = 2; break; - case 6: d = 3; break; - } - int ci; - for (ci = 0; ci < d; ci++) - val += sqr (values[ci]); - for (ci = d; ci < data->components; ci++) - val += 2*sqr (values[ci]); - val = sqrt (val); - break; - } - - case FUNC_MISES: - { - int d; - switch(data->components) - { - case 1: d = 1; break; - case 3: d = 2; break; - case 6: d = 3; break; - } - int ci; - double trace = 0.; - for (ci = 0; ci < d; ci++) - trace += 1./3.*(values[ci]); - for (ci = 0; ci < d; ci++) - val += sqr (values[ci]-trace); - for (ci = d; ci < data->components; ci++) - val += 2.*sqr (values[ci]); - val = sqrt (val); - break; - } - case FUNC_MAIN: - { - int d; - switch(data->components) - { - case 1: d = 1; break; - case 3: d = 2; break; - case 6: d = 3; break; - } - Mat<3,3> m ; - Vec<3> ev; - int ci; - for (ci = 0; ci < d; ci++) - m(ci,ci) = (values[ci]); - m(0,1) = m(1,0) = values[3]; - m(0,2) = m(2,0) = values[4]; - m(1,2) = m(2,1) = values[5]; - - EigenValues (m, ev); - double help; - for (int i=0; i<d; i++) - { - for (int j=d-1; i<j; j--) - { - if ( abs(ev(j)) > abs(ev(j-1)) ) - { - help = ev(j); - ev(j) = ev(j-1); - ev(j-1) = help; - } - } - } - val = (ev(0)); - break; - } - } - - return ok; - } - - - switch (data->soltype) - { - case SOL_VIRTUALFUNCTION: - { - double values[20]; - ok = data->solclass->GetValue (elnr, lam1, lam2, lam3, values); - - val = values[comp-1]; - return ok; - } - case SOL_NODAL: - { - const Element & el = (*mesh)[elnr]; - - double lami[8]; - int np, i; - - switch (el.GetType()) - { - case TET: - case TET10: - { - lami[1] = lam1; - lami[2] = lam2; - lami[3] = lam3; - lami[0] = 1-lam1-lam2-lam3; - np = 4; - break; - } - case PRISM: - case PRISM12: - { - lami[0] = (1-lam3) * (1-lam1-lam2); - lami[1] = (1-lam3) * lam1; - lami[2] = (1-lam3) * lam2; - lami[3] = (lam3) * (1-lam1-lam2); - lami[4] = (lam3) * lam1; - lami[5] = (lam3) * lam2; - np = 6; - break; - } - } - - for (i = 0; i < np; i++) - val += lami[i] * data->data[(el[i]-1) * data->dist + comp-1]; - - return 1; - } - - case SOL_ELEMENT: - { - val = data->data[elnr * data->dist + comp-1]; - return 1; - } - - case SOL_SURFACE_ELEMENT: - return 0; - - case SOL_NONCONTINUOUS: - { - const Element & el = (*mesh)[elnr]; - - double lami[8]; - int np, i; - - switch (el.GetType()) - { - case TET: - case TET10: - { - lami[1] = lam1; - lami[2] = lam2; - lami[3] = lam3; - lami[0] = 1-lam1-lam2-lam3; - np = 4; - break; - } - case PRISM: - case PRISM12: - { - lami[0] = (1-lam3) * (1-lam1-lam2); - lami[1] = (1-lam3) * lam1; - lami[2] = (1-lam3) * lam2; - lami[3] = (lam3) * (1-lam1-lam2); - lami[4] = (lam3) * lam1; - lami[5] = (lam3) * lam2; - np = 6; - break; - } - case PYRAMID: - { - if (lam3 > 1-1e-5) - { - lami[0] = lami[1] = lami[2] = lami[3] = 0; - lami[4] = 1; - } - else - { - double x0 = lam1 / (1-lam3); - double y0 = lam2 / (1-lam3); - lami[0] = (1-x0) * (1-y0) * (1-lam3); - lami[1] = ( x0) * (1-y0) * (1-lam3); - lami[2] = ( x0) * ( y0) * (1-lam3); - lami[3] = (1-x0) * ( y0) * (1-lam3); - lami[4] = lam3; - np = 5; - } - break; - } - default: - np = 0; - } - - int base; - if (data->order == 1) - base = 6 * elnr; - else - base = 10 * elnr; - - - for (i = 0; i < np; i++) - val += lami[i] * data->data[(base+i) * data->dist + comp-1]; - - return 1; - } - - case SOL_MARKED_ELEMENTS: - { - val = (*mesh)[elnr].TestRefinementFlag(); - return 1; - } - - case SOL_ELEMENT_ORDER: - { - val = (*mesh)[elnr].GetOrder(); - return 1; - } - } - return 0; -} - - - - -bool VisualSceneSolution :: -GetSurfValues (const SolData * data, SurfaceElementIndex selnr, - double lam1, double lam2, - double * values) const -{ - bool ok; - switch (data->soltype) - { - case SOL_VIRTUALFUNCTION: - { - ok = data->solclass->GetSurfValue (selnr, lam1, lam2, values); - break; - } - default: - { - for (int i = 0; i < data->components; i++) - ok = GetSurfValue (data, selnr, lam1, lam2, i+1, values[i]); - } - } - return ok; -} - - - -bool VisualSceneSolution :: -GetSurfValue (const SolData * data, SurfaceElementIndex selnr, - double lam1, double lam2, - int comp, double & val) const -{ - bool ok; - if (comp == 0) - { - val = 0; - ArrayMem<double,20> values(data->components); - ok = GetSurfValues (data, selnr, lam1, lam2, &values[0]); - - switch (evalfunc) - { - case FUNC_ABS: - { - for (int ci = 0; ci < data->components; ci++) - val += sqr (values[ci]); - val = sqrt (val); - break; - } - case FUNC_ABS_TENSOR: - { - int d; - switch (data->components) - { - case 1: d = 1; break; - case 3: d = 2; break; - case 6: d = 3; break; - } - int ci; - for (ci = 0; ci < d; ci++) - val += sqr (values[ci]); - for (ci = d; ci < data->components; ci++) - val += 2*sqr (values[ci]); - val = sqrt (val); - break; - } - - case FUNC_MISES: - { - int d; - switch(data->components) - { - case 1: d = 1; break; - case 3: d = 2; break; - case 6: d = 3; break; - } - int ci; - double trace = 0.; - for (ci = 0; ci < d; ci++) - trace += 1./3.*(values[ci]); - for (ci = 0; ci < d; ci++) - val += sqr (values[ci]-trace); - for (ci = d; ci < data->components; ci++) - val += 2.*sqr (values[ci]); - val = sqrt (val); - break; - } - case FUNC_MAIN: - { - int d; - switch(data->components) - { - case 1: d = 1; break; - case 3: d = 2; break; - case 6: d = 3; break; - } - Mat<3,3> m ; - Vec<3> ev; - int ci; - for (ci = 0; ci < d; ci++) - m(ci,ci) = (values[ci]); - m(0,1) = m(1,0) = values[3]; - m(0,2) = m(2,0) = values[4]; - m(1,2) = m(2,1) = values[5]; - - EigenValues (m, ev); - double help; - for (int i=0; i<d; i++) - { - for (int j=d-1; i<j; j--) - { - if ( abs(ev(j)) > abs(ev(j-1)) ) - { - help = ev(j); - ev(j) = ev(j-1); - ev(j-1) = help; - } - } - } - val = (ev(0)); - break; - } - } - - return ok; - - - /* - int ci; - double val = 0; - for (ci = 1; ci <= data->components; ci++) - val += sqr (GetSurfValue (data, selnr, lam1, lam2, ci)); - return sqrt (val); - */ - } - - - switch (data->soltype) - { - case SOL_VIRTUALFUNCTION: - { - ArrayMem<double,20> values(data->components); - bool ok; - - ok = data->solclass->GetSurfValue (selnr, lam1, lam2, &values[0]); - - if (ok) - { - if (!data->iscomplex) - val = values[comp-1]; - else - { - // cout << "time = " << time << ", cos = " << cos(time) << endl; - val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); - } - } - - return ok; - } - - - case SOL_NODAL: - { - const Element2d & el = (*mesh)[selnr]; - - double lami[8]; - int np, i; - val = 0; - double lam3 = 1-lam1-lam2; - - switch (el.GetType()) - { - case TRIG: - /* - lami[0] = lam3; - lami[1] = lam1; - lami[2] = lam2; - */ - lami[0] = lam1; - lami[1] = lam2; - lami[2] = lam3; - np = 3; - break; - - case TRIG6: - /* - lami[0] = lam3*(2*lam3-1); - lami[1] = lam1*(2*lam1-1); - lami[2] = lam2*(2*lam2-1); - */ - // hierarchical basis: - lami[0] = lam3; - lami[1] = lam1; - lami[2] = lam2; - lami[3] = 4*lam1*lam2; - lami[4] = 4*lam2*lam3; - lami[5] = 4*lam1*lam3; - np = 6; - break; - - case QUAD: - case QUAD6: - lami[0] = (1-lam1)*(1-lam2); - lami[1] = lam1 * (1-lam2); - lami[2] = lam1 * lam2; - lami[3] = (1-lam1) * lam2; - np = 4; - break; - - default: - np = 0; - } - - for (i = 0; i < np; i++) - val += lami[i] * data->data[(el[i]-1) * data->dist + comp-1]; - - return 1; - } - - case SOL_ELEMENT: - { - int el1, el2; - mesh->GetTopology().GetSurface2VolumeElement (selnr+1, el1, el2); - el1--; - - val = data->data[el1 * data->dist+comp-1]; - return 1; - } - - case SOL_NONCONTINUOUS: - { - val = 0; - // ????? - return 0; - } - - case SOL_SURFACE_ELEMENT: - { - val = data->data[selnr * data->dist + comp-1]; - return 1; - } - - case SOL_SURFACE_NONCONTINUOUS: - { - const Element2d & el = (*mesh)[selnr]; - - double lami[8]; - int np, i; - val = 0; - int order = data->order; - - switch (order) - { - case 0: - return data->data[selnr * data->dist + comp-1]; - case 1: - { - switch (el.GetType()) - { - case TRIG: - case TRIG6: - { - lami[1] = lam1; - lami[2] = lam2; - lami[0] = 1-lam1-lam2; - np = 3; - break; - } - } - break; - } - case 2: - { - switch (el.GetType()) - { - case TRIG: - { - lami[1] = lam1; - lami[2] = lam2; - lami[0] = 1-lam1-lam2; - np = 3; - break; - } - case TRIG6: - { - double lam3 = 1-lam1-lam2; - lami[1] = 2*lam1 * (lam1-0.5); - lami[2] = 2*lam2 * (lam2-0.5); - lami[0] = 2*lam3 * (lam3-0.5); - lami[3] = 4*lam1*lam2; - lami[4] = 4*lam2*lam3; - lami[5] = 4*lam1*lam3; - np = 6; - break; - } - } - break; - } - } - - int base; - if (order == 1) - base = 4 * selnr; - else - base = 9 * selnr; - - for (i = 0; i < np; i++) - { - val += lami[i] * data->data[(base+i) * data->dist + comp-1]; - } - return 1; - } - - case SOL_MARKED_ELEMENTS: - { - val = (*mesh)[selnr].TestRefinementFlag(); - return 1; - } - - case SOL_ELEMENT_ORDER: - { - val = (*mesh)[selnr].GetOrder(); - return 1; - } - - } - return 0; -} - - -void VisualSceneSolution :: -GetDeformation (ElementIndex elnr, double lam1, double lam2, double lam3, - Vec<3> & def) const -{ - if (deform && vecfunction != -1) - { - GetValues (soldata[vecfunction], elnr, lam1, lam2, lam3, &def(0)); - def *= scaledeform; - - if (soldata[vecfunction]->dist == 2) def(2) = 0; - } - else - def = 0; -} - - -void VisualSceneSolution :: -GetSurfDeformation (SurfaceElementIndex elnr, double lam1, double lam2, - Vec<3> & def) const -{ - if (deform && vecfunction != -1) - { - GetSurfValues (soldata[vecfunction], elnr, lam1, lam2, &def(0)); - def *= scaledeform; - - if (soldata[vecfunction]->dist == 2) def(2) = 0; - } - else - def = 0; -} - -void VisualSceneSolution :: GetPointDeformation (int pnum, Point<3> & p, - SurfaceElementIndex elnr) const -{ - p = mesh->Point (pnum+1); - - if (deform && vecfunction != -1) - { - const SolData * vsol = soldata[vecfunction]; - - Vec<3> v(0,0,0); - if (vsol->soltype == SOL_NODAL) - { - v = Vec3d(vsol->data[pnum * vsol->dist], - vsol->data[pnum * vsol->dist+1], - vsol->data[pnum * vsol->dist+2]); - } - else if (vsol->soltype == SOL_SURFACE_NONCONTINUOUS) - { - const Element2d & el = (*mesh)[elnr]; - for (int j = 0; j < el.GetNP(); j++) - if (el[j] == pnum+1) - { - int base = (4*elnr+j-1) * vsol->dist; - v = Vec3d(vsol->data[base], - vsol->data[base+1], - vsol->data[base+2]); - } - } - - if (vsol->dist == 2) v(2) = 0; - - v *= scaledeform; - p += v; - } -} - - - - - - - - -void VisualSceneSolution :: GetClippingPlaneTrigs (ARRAY<ClipPlaneTrig> & trigs) -{ - // cout << "get clipplane trigs" << endl; - - int ii, j, k, l; - ElementIndex ei; - - int np = mesh->GetNP(); - int ne = mesh->GetNE(); - - ARRAY<double> nodevals(np); - - for (int i = 0; i < np; i++) - { - Point<3> p; - GetPointDeformation(i, p); - nodevals[i] = - p(0) * clipplane[0] + - p(1) * clipplane[1] + - p(2) * clipplane[2] + - clipplane[3]; - } - - const int edgei[6][2] = - { - { 0, 1 }, - { 0, 2 }, - { 0, 3 }, - { 1, 2 }, - { 1, 3 }, - { 2, 3 } - }; - double edgelam[6]; - Point<3> edgep[6]; - double nodevali[4]; - - int cntce; - int cpe1 = 0, cpe2 = 0, cpe3 = 0; - - ARRAY<Element> loctets; - ARRAY<Element> loctetsloc; - ARRAY<Point3d> pointsloc; - - - int n = 1 << subdivisions; - ARRAY<Point<3> > grid((n+1)*(n+1)*(n+1)); - ARRAY<Point<3> > locgrid((n+1)*(n+1)*(n+1)); - ARRAY<double> val((n+1)*(n+1)*(n+1)); - - - for (ei = 0; ei < ne; ei++) - { - ELEMENT_TYPE type = (*mesh)[ei].GetType(); - if (type == HEX || type == PRISM || type == TET || type == PYRAMID) - { - const Element & el = (*mesh)[ei]; - - Vector shape(el.GetNP()); - - int ii = 0; - for (int ix = 0; ix <= n; ix++) - for (int iy = 0; iy <= n; iy++) - for (int iz = 0; iz <= n; iz++, ii++) - { - Point<3> ploc; - if (type == PRISM) - ploc = Point<3> (double(ix) / n * (1-double(iy)/n), double(iy) / n, double(iz) / n); - if (type == TET) - ploc = Point<3> (double(ix) / n * (1-double(iy)/n) * (1-double(iz)/n), - double(iy) / n * (1-double(iz)/n), - double(iz) / n); - if (type == HEX) - ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); - if (type == PYRAMID) - ploc = Point<3> (double(ix) / n * (1-double(iz)/n), - double(iy) / n * (1-double(iz)/n), - double(iz)/n); - - Point<3> pglob; - - if (mesh->GetCurvedElements().IsHighOrder()) - { - mesh->GetCurvedElements(). - CalcElementTransformation (ploc, ei, pglob); - } - else - { - el.GetShapeNew (ploc, shape); - for (int j = 0; j < 3; j++) - { - pglob(j) = 0; - for (int k = 0; k < el.GetNP(); k++) - pglob(j) += shape(k) * (*mesh)[el[k]].X(j+1); - } - } - - locgrid[ii] = ploc; - grid[ii] = pglob; - val[ii] = - pglob(0) * clipplane[0] + - pglob(1) * clipplane[1] + - pglob(2) * clipplane[2] + - clipplane[3]; - } - - for (int ix = 0; ix < n; ix++) - for (int iy = 0; iy < n; iy++) - for (int iz = 0; iz < n; iz++) - { - int base = iz + (n+1)*iy + (n+1)*(n+1)*ix; - int pi[8] = - { base, base+(n+1)*(n+1), base+(n+1)*(n+1)+(n+1), base+(n+1), - base+1, base+(n+1)*(n+1)+1, base+(n+1)*(n+1)+(n+1)+1, base+(n+1)+1 }; - - int tets[6][4] = - { { 1, 7, 2, 3 }, - { 1, 7, 3, 4 }, - { 1, 7, 4, 8 }, - { 1, 7, 8, 5 }, - { 1, 7, 5, 6 }, - { 1, 7, 6, 2 } - }; - - - for (int ii = 0; ii < 6; ii++) - { - int teti[4]; - for (int k = 0; k < 4; k++) - teti[k] = pi[tets[ii][k]-1]; - - for (j = 0; j < 4; j++) - nodevali[j] = val[teti[j]]; - - cntce = 0; - for (j = 0; j < 6; j++) - { - int lpi1 = edgei[j][0]; - int lpi2 = edgei[j][1]; - if ( (nodevali[lpi1] > 0) != - (nodevali[lpi2] > 0) ) - { - edgelam[j] = nodevali[lpi2] / (nodevali[lpi2] - nodevali[lpi1]); - Point<3> p1 = grid[teti[lpi1]]; - Point<3> p2 = grid[teti[lpi2]]; - - edgep[j] = p1 + (1-edgelam[j]) * (p2-p1); - - cntce++; - cpe3 = cpe2; - cpe2 = cpe1; - cpe1 = j; - if (cntce >= 3) - { - ClipPlaneTrig cpt; - cpt.elnr = ei; - - for (int k = 0; k < 3; k++) - { - int ednr; - switch (k) - { - case 0: ednr = cpe1; break; - case 1: ednr = cpe2; break; - case 2: ednr = cpe3; break; - } - cpt.points[k].p = edgep[ednr]; - - int pi1 = edgei[ednr][0]; - int pi2 = edgei[ednr][1]; - Point<3> p1 = locgrid[teti[pi1]]; - Point<3> p2 = locgrid[teti[pi2]]; - for (l = 0; l < 3; l++) - cpt.points[k].lami(l) = - edgelam[ednr] * p1(l) + - (1-edgelam[ednr]) * p2(l); - } - - trigs.Append (cpt); - } - } - } - } - } - } - - else - { - - // const Element & el = mesh->VolumeElement(i); - - (*mesh)[ei].GetTets (loctets); - (*mesh)[ei].GetTetsLocal (loctetsloc); - // (*mesh)[ei].GetNodesLocal (pointsloc); - (*mesh)[ei].GetNodesLocalNew (pointsloc); - - for (ii = 0; ii < loctets.Size(); ii++) - { - const Element & el = loctets[ii]; - - for (j = 0; j < 4; j++) - nodevali[j] = nodevals.Get(el[j]); - - cntce = 0; - for (j = 0; j < 6; j++) - { - int lpi1 = edgei[j][0]; - int lpi2 = edgei[j][1]; - if ( (nodevali[lpi1] > 0) != - (nodevali[lpi2] > 0) ) - { - edgelam[j] = nodevali[lpi2] / (nodevali[lpi2] - nodevali[lpi1]); - Point<3> p1, p2; - GetPointDeformation (el[lpi1]-1, p1); - GetPointDeformation (el[lpi2]-1, p2); - - edgep[j] = p1 + (1-edgelam[j]) * (p2-p1); - - cntce++; - cpe3 = cpe2; - cpe2 = cpe1; - cpe1 = j; - if (cntce >= 3) - { - ClipPlaneTrig cpt; - cpt.elnr = ei; - - for (k = 0; k < 3; k++) - { - int ednr; - switch (k) - { - case 0: ednr = cpe1; break; - case 1: ednr = cpe2; break; - case 2: ednr = cpe3; break; - } - cpt.points[k].p = edgep[ednr]; - - int pi1 = edgei[ednr][0]; - int pi2 = edgei[ednr][1]; - Point<3> p1 = pointsloc.Get (loctetsloc[ii][pi1]); - Point<3> p2 = pointsloc.Get (loctetsloc[ii][pi2]); - for (l = 0; l < 3; l++) - cpt.points[k].lami(l) = - edgelam[ednr] * p1(l) + - (1-edgelam[ednr]) * p2(l); - } - - trigs.Append (cpt); - } - } - } - } - } - - } -} - -void VisualSceneSolution :: GetClippingPlaneGrid (ARRAY<ClipPlanePoint> & pts) -{ - int i, j, k; - int np = mesh->GetNV(); - int ne = mesh->GetNE(); - - Vec3d n(clipplane[0], clipplane[1], clipplane[2]); - - double mu = -clipplane[3] / n.Length2(); - Point3d p(mu*n.X(), mu * n.Y(), mu * n.Z()); - - n /= n.Length(); - Vec3d t1, t2; - n.GetNormal (t1); - t2 = Cross (n, t1); - - double xi1, xi2; - - double xi1mid = (center - p) * t1; - double xi2mid = (center - p) * t2; - - pts.SetSize(0); - - int elnr; - double lami[3]; - - // cout << "getclippingplanegrid. xoffset = " << xoffset << ", yoffset = "; - // cout << yoffset << endl; - - for (xi1 = xi1mid-rad+xoffset/gridsize; xi1 <= xi1mid+rad+xoffset/gridsize; xi1 += rad / gridsize) - for (xi2 = xi2mid-rad+yoffset/gridsize; xi2 <= xi2mid+rad+yoffset/gridsize; xi2 += rad / gridsize) - // for (xi1 = xi1mid-rad; xi1 <= xi1mid+rad; xi1 += rad / gridsize) - // for (xi2 = xi2mid-rad; xi2 <= xi2mid+rad; xi2 += rad / gridsize) - { - Point3d hp = p + xi1 * t1 + xi2 * t2; - - elnr = mesh->GetElementOfPoint (hp, lami)-1; - - if (elnr != -1) - { - ClipPlanePoint cpp; - cpp.p = hp; - cpp.elnr = elnr; - cpp.lam1 = lami[0]; - cpp.lam2 = lami[1]; - cpp.lam3 = lami[2]; - pts.Append (cpp); - } - } -}; - - - -void VisualSceneSolution :: -SetOpenGlColor(double h, double hmin, double hmax, int logscale) -{ - double value; - - if (!logscale) - value = (h - hmin) / (hmax - hmin); - else - { - if (hmax <= 0) hmax = 1; - if (hmin <= 0) hmin = 1e-4 * hmax; - value = (log(fabs(h)) - log(hmin)) / (log(hmax) - log(hmin)); - } - - if (!invcolor) - value = 1 - value; - - if (usetexture) - { - glTexCoord1f ( 0.999 * value + 0.001); - return; - }; - - if (value > 1) value = 1; - if (value < 0) value = 0; - - value *= 4; - - static const double colp[][3] = - { - { 1, 0, 0 }, - { 1, 1, 0 }, - { 0, 1, 0 }, - { 0, 1, 1 }, - { 0, 0, 1 }, - { 1, 0, 1 }, - { 1, 0, 0 }, - }; - - int i = int(value); - double r = value - i; - - GLdouble col[3]; - for (int j = 0; j < 3; j++) - col[j] = (1-r) * colp[i][j] + r * colp[i+1][j]; - - glColor3d (col[0], col[1], col[2]); -} - - - - -void VisualSceneSolution :: -DrawCone (const Point<3> & p1, const Point<3> & p2, double r) -{ - int n = 10, i; - Vec<3> p1p2 = p2 - p1; - - p1p2.Normalize(); - Vec<3> p2p1 = -p1p2; - - Vec<3> t1 = p1p2.GetNormal(); - Vec<3> t2 = Cross (p1p2, t1); - - Point<3> oldp = p1 + r * t1; - Vec<3> oldn = t1; - - Point<3> p; - Vec<3> normal; - - Mat<2> rotmat; - Vec<2> cs, newcs; - cs(0) = 1; - cs(1) = 0; - rotmat(0,0) = rotmat(1,1) = cos(2*M_PI/n); - rotmat(1,0) = sin(2*M_PI/n); - rotmat(0,1) = -rotmat(1,0); - - glBegin (GL_TRIANGLES); - double phi; - for (i = 1; i <= n; i++) - { - /* - phi = 2 * M_PI * i / n; - normal = cos(phi) * t1 + sin(phi) * t2; - */ - newcs = rotmat * cs; - cs = newcs; - normal = cs(0) * t1 + cs(1) * t2; - - p = p1 + r * normal; - - // cone - glNormal3dv (normal); - glVertex3dv (p); - glVertex3dv (p2); - glNormal3dv (oldn); - glVertex3dv (oldp); - - // base-circle - glNormal3dv (p2p1); - glVertex3dv (p); - glVertex3dv (p1); - glVertex3dv (oldp); - - oldp = p; - oldn = normal; - } - glEnd (); -} - - - -void VisualSceneSolution :: -DrawCylinder (const Point<3> & p1, const Point<3> & p2, double r) -{ - int n = 10, i; - Vec<3> p1p2 = p2 - p1; - - p1p2.Normalize(); - Vec<3> p2p1 = -p1p2; - - Vec<3> t1 = p1p2.GetNormal(); - Vec<3> t2 = Cross (p1p2, t1); - - Point<3> oldhp1 = p1 + r * t1; - Point<3> oldhp2 = p2 + r * t1; - Vec<3> oldn = t1; - - Point<3> hp1, hp2; - Vec<3> normal; - - Mat<2> rotmat; - Vec<2> cs, newcs; - cs(0) = 1; - cs(1) = 0; - rotmat(0,0) = rotmat(1,1) = cos(2*M_PI/n); - rotmat(1,0) = sin(2*M_PI/n); - rotmat(0,1) = -rotmat(1,0); - - glBegin (GL_QUADS); - double phi; - for (i = 1; i <= n; i++) - { - newcs = rotmat * cs; - cs = newcs; - normal = cs(0) * t1 + cs(1) * t2; - - hp1 = p1 + r * normal; - hp2 = p2 + r * normal; - - // cylinder - glNormal3dv (normal); - - glVertex3dv (hp1); - glVertex3dv (hp2); - glVertex3dv (oldhp2); - glVertex3dv (oldhp1); - - oldhp1 = hp1; - oldhp2 = hp2; - oldn = normal; - } - glEnd (); -} - - - - - - - - - - - - - -void VisualSceneSolution :: MouseDblClick (int px, int py) -{ - ; -} - - -void VisualSceneSolution :: -DrawClipPlaneTrig (const SolData * sol, - int comp, - const ClipPlaneTrig & trig, - int level) -{ - int j; - double val; - if (level <= 0) - for (j = 0; j < 3; j++) - { - Point<3> p; - if (mesh->GetCurvedElements().IsHighOrder()) - { - mesh->GetCurvedElements(). - CalcElementTransformation (trig.points[j].lami, trig.elnr, p); - } - else - p = trig.points[j].p; - - if (deform) - { - Vec<3> def; - GetDeformation (trig.elnr, - trig.points[j].lami(0), - trig.points[j].lami(1), - trig.points[j].lami(2), def); - p += def; - } - - - // TODO: consider return value (bool: draw/don't draw element) - GetValue (sol, trig.elnr, - trig.points[j].lami(0), - trig.points[j].lami(1), - trig.points[j].lami(2), scalcomp, val); - - SetOpenGlColor (val, minval, maxval, logscale); - glVertex3dv (p); - } - else - { - Point<3> newp = Center (trig.points[1].p, trig.points[2].p); - Point<3> newlami = Center (trig.points[1].lami, trig.points[2].lami); - ClipPlaneTrig t1, t2; - t1.elnr = t2.elnr = trig.elnr; - t1.points[0].p = newp; - t1.points[0].lami = newlami; - t1.points[1] = trig.points[2]; - t1.points[2] = trig.points[0]; - t2.points[0].p = newp; - t2.points[0].lami = newlami; - t2.points[1] = trig.points[0]; - t2.points[2] = trig.points[1]; - DrawClipPlaneTrig (sol, comp, t1, level-1); - DrawClipPlaneTrig (sol, comp, t2, level-1); - } -} - - - - - -int Ng_Vis_Set (ClientData clientData, - Tcl_Interp * interp, - int argc, tcl_const char *argv[]) - -{ - int i; - if (argc >= 2) - { - if (strcmp (argv[1], "parameters") == 0) - { - vssolution.imag_part = - atoi (Tcl_GetVar (interp, "visoptions.imaginary", 0)); - vssolution.usetexture = - atoi (Tcl_GetVar (interp, "visoptions.usetexture", 0)); - vssolution.invcolor = - atoi (Tcl_GetVar (interp, "visoptions.invcolor", 0)); - - vssolution.clipsolution = 0; - - if (strcmp (Tcl_GetVar (interp, "visoptions.clipsolution", 0), - "scal") == 0) - vssolution.clipsolution = 1; - if (strcmp (Tcl_GetVar (interp, "visoptions.clipsolution", 0), - "vec") == 0) - vssolution.clipsolution = 2; - - // SZ const -> tcl_const - tcl_const char * scalname = - Tcl_GetVar (interp, "visoptions.scalfunction", 0); - // SZ const -> tcl_const - tcl_const char * vecname = - Tcl_GetVar (interp, "visoptions.vecfunction", 0); - - vssolution.scalfunction = -1; - vssolution.vecfunction = -1; - - int pointpos; // SZ - char * pch; - pch=strchr(scalname,'.'); - pointpos = int(pch-scalname+1); - - for (i = 0; i < vssolution.soldata.Size(); i++) - { - if (strlen (vssolution.soldata[i]->name) == - pointpos-1 && - strncmp (vssolution.soldata[i]->name, scalname, - pointpos-1) == 0) - { - vssolution.scalfunction = i; - vssolution.scalcomp = atoi (scalname + pointpos); - } - if (strcmp (vssolution.soldata[i]->name, vecname) == 0) - vssolution.vecfunction = i; - } - - - tcl_const char * evalname = - Tcl_GetVar (interp, "visoptions.evaluate", 0); - - if (strcmp(evalname, "abs") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_ABS; - if (strcmp(evalname, "abstens") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_ABS_TENSOR; - if (strcmp(evalname, "mises") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_MISES; - if (strcmp(evalname, "main") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_MAIN; - - vssolution.gridsize = - atoi (Tcl_GetVar (interp, "visoptions.gridsize", 0)); - - vssolution.xoffset = - atof (Tcl_GetVar (interp, "visoptions.xoffset", 0)); - - // cout << "x-offset:" << vssolution.xoffset << endl; - - vssolution.yoffset = - atof (Tcl_GetVar (interp, "visoptions.yoffset", 0)); - - vssolution.autoscale = - atoi (Tcl_GetVar (interp, "visoptions.autoscale", 0)); - - /* - vssolution.linear_colors = - atoi (Tcl_GetVar (interp, "visoptions.lineartexture", 0)); - */ - vssolution.logscale = - atoi (Tcl_GetVar (interp, "visoptions.logscale", 0)); - - vssolution.mminval = - atof (Tcl_GetVar (interp, "visoptions.mminval", 0)); - vssolution.mmaxval = - atof (Tcl_GetVar (interp, "visoptions.mmaxval", 0)); - - vssolution.showclipsolution = - atoi (Tcl_GetVar (interp, "visoptions.showclipsolution", 0)); - vssolution.showsurfacesolution = - atoi (Tcl_GetVar (interp, "visoptions.showsurfacesolution", 0)); - vssolution.lineartexture = - atoi (Tcl_GetVar (interp, "visoptions.lineartexture", 0)); - vssolution.numtexturecols = - atoi (Tcl_GetVar (interp, "visoptions.numtexturecols", 0)); - - vssolution.multidimcomponent = - atoi (Tcl_GetVar (interp, "visoptions.multidimcomponent", 0)); - - vssolution.draw_fieldlines = - atoi (Tcl_GetVar (interp, "visoptions.drawfieldlines", 0)); - vssolution.num_fieldlines = - atoi (Tcl_GetVar (interp, "visoptions.numfieldlines", 0)); - vssolution.fieldlines_randomstart = - atoi (Tcl_GetVar (interp, "visoptions.fieldlinesrandomstart", 0)); - - - vssolution.deform = - atoi (Tcl_GetVar (interp, "visoptions.deformation", 0)); - vssolution.scaledeform = - atof (Tcl_GetVar (interp, "visoptions.scaledeform1", 0)) * - atof (Tcl_GetVar (interp, "visoptions.scaledeform2", 0)); - - - if (atoi (Tcl_GetVar (interp, "visoptions.isolines", 0))) - vssolution.numisolines = atoi (Tcl_GetVar (interp, "visoptions.numiso", 0)); - else - vssolution.numisolines = 0; - - vssolution.subdivisions = - atoi (Tcl_GetVar (interp, "visoptions.subdivisions", 0)); - vssolution.UpdateSolutionTimeStamp(); - } - - if (argc >= 3 && strcmp (argv[1], "time") == 0) - { - vssolution.time = double (atoi (argv[2])) / 1000; - vssolution.solutiontimestamp = NextTimeStamp(); - // cout << "time = " << vssolution.time << endl; - } - - } - return TCL_OK; -} - -int Ng_Vis_Field (ClientData clientData, - Tcl_Interp * interp, - int argc, tcl_const char *argv[]) -{ - int i; - static char buf[1000]; - buf[0] = 0; - - if (argc >= 2) - { - if (strcmp (argv[1], "setfield") == 0) - { - if (argc < 3) - return TCL_ERROR; - - for (i = 0; i < vssolution.GetNSolData(); i++) - if (strcmp (vssolution.GetSolData(i)->name, argv[2]) == 0) - { - cout << "found soldata " << i << endl; - } - } - - if (strcmp (argv[1], "getnfieldnames") == 0) - { - sprintf (buf, "%d", vssolution.GetNSolData()); - } - - if (strcmp (argv[1], "getfieldname") == 0) - { - sprintf (buf, "%s", vssolution.GetSolData(atoi(argv[2])-1)->name); - } - - if (strcmp (argv[1], "iscomplex") == 0) - { - sprintf (buf, "%d", vssolution.GetSolData(atoi(argv[2])-1)->iscomplex); - } - - if (strcmp (argv[1], "getfieldcomponents") == 0) - { - sprintf (buf, "%d", vssolution.GetSolData(atoi(argv[2])-1)->components); - } - - - if (strcmp (argv[1], "getfieldnames") == 0) - { - for (i = 0; i < vssolution.GetNSolData(); i++) - { - strcat (buf, vssolution.GetSolData(i)->name); - strcat (buf, " "); - } - strcat (buf, "var1 var2 var3"); - Tcl_SetResult (interp, buf, TCL_STATIC); - } - - if (strcmp (argv[1], "setcomponent") == 0) - { - cout << "set component " << argv[2] << endl; - } - - if (strcmp (argv[1], "getactivefield") == 0) - { - sprintf (buf, "1"); - } - - if (strcmp (argv[1], "getdimension") == 0) - { - sprintf (buf, "%d", mesh->GetDimension()); - } - } - - Tcl_SetResult (interp, buf, TCL_STATIC); - return TCL_OK; -} - - -extern "C" int Ng_Vis_Init (Tcl_Interp * interp); - -int Ng_Vis_Init (Tcl_Interp * interp) -{ - Tcl_CreateCommand (interp, "Ng_Vis_Set", Ng_Vis_Set, - (ClientData)NULL, - (Tcl_CmdDeleteProc*) NULL); - - Tcl_CreateCommand (interp, "Ng_Vis_Field", Ng_Vis_Field, - (ClientData)NULL, - (Tcl_CmdDeleteProc*) NULL); - - - return TCL_OK; -} -} diff --git a/Netgen/libsrc/visualization/vssolution.hpp b/Netgen/libsrc/visualization/vssolution.hpp deleted file mode 100644 index d20654b5fc..0000000000 --- a/Netgen/libsrc/visualization/vssolution.hpp +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef FILE_VSSOLUTION -#define FILE_VSSOLUTION - - - - - -extern int Ng_Vis_Set (ClientData clientData, - Tcl_Interp * interp, - int argc, tcl_const char *argv[]); - -class VisualSceneSolution : public VisualScene -{ - class ClipPlaneTrig - { - public: - struct ps - { - Point<3> lami; - Point<3> p; - }; - ps points[3]; - ElementIndex elnr; - }; - - class ClipPlanePoint - { - public: - ElementIndex elnr; - double lam1, lam2, lam3; - Point<3> p; - }; - - - int surfellist; - int linelist; - int clipplanelist; - int isolinelist; - int clipplane_isolinelist; - int surface_vector_list; - int cone_list; - - bool draw_fieldlines; - int num_fieldlines; - bool fieldlines_randomstart; - int fieldlineslist; - int num_fieldlineslists; - - int surfeltimestamp, clipplanetimestamp, solutiontimestamp; - int surfellinetimestamp; - int fieldlinestimestamp, surface_vector_timestamp; - double minval, maxval; - - - - NgLock *lock; - -public: - - enum EvalFunc { - FUNC_ABS = 1, - FUNC_ABS_TENSOR = 2, - FUNC_MISES = 3, - FUNC_MAIN = 4 - }; - EvalFunc evalfunc; - - enum SolType - { - SOL_NODAL = 1, - SOL_ELEMENT = 2, - SOL_SURFACE_ELEMENT = 3, - SOL_NONCONTINUOUS = 4, - SOL_SURFACE_NONCONTINUOUS = 5, - SOL_VIRTUALFUNCTION = 6, - SOL_MARKED_ELEMENTS = 10, - SOL_ELEMENT_ORDER = 11, - }; - - class SolData - { - public: - SolData (); - ~SolData (); - - char * name; - double * data; - int components; - int dist; - int order; - bool iscomplex; - bool draw_volume; - bool draw_surface; - SolType soltype; - SolutionData * solclass; - - // internal variables: - int size; - }; - - ARRAY<SolData*> soldata; - - - - int usetexture; - int clipsolution; // 0..no, 1..scal, 2..vec - int scalfunction, scalcomp, vecfunction; - int gridsize; - double xoffset, yoffset; - - int autoscale, logscale; - double mminval, mmaxval; - int numisolines; - int subdivisions; - - bool showclipsolution; - bool showsurfacesolution; - bool lineartexture; - int numtexturecols; - - int multidimcomponent; - - // bool fieldlineplot; - double time; - - int deform; - double scaledeform; - bool imag_part; - -public: - VisualSceneSolution (); - virtual ~VisualSceneSolution (); - - virtual void BuildScene (int zoomall = 0); - virtual void DrawScene (); - virtual void MouseDblClick (int px, int py); - - void BuildFieldLinesPlot (); - - void AddSolutionData (SolData * soldata); - void ClearSolutionData (); - void UpdateSolutionTimeStamp (); - SolData * GetSolData (int i); - int GetNSolData () { return soldata.Size(); } - - void SaveSolutionData (const char * filename); -private: - void GetMinMax (int funcnr, int comp, double & minv, double & maxv) const; - - void GetClippingPlaneTrigs (ARRAY<ClipPlaneTrig> & trigs); - void GetClippingPlaneGrid (ARRAY<ClipPlanePoint> & pts); - void DrawCone (const Point<3> & p1, const Point<3> & p2, double r); - void DrawCylinder (const Point<3> & p1, const Point<3> & p2, double r); - - - // Get Function Value, local coordinates lam1, lam2, lam3, - bool GetValue (const SolData * data, ElementIndex elnr, - double lam1, double lam2, double lam3, - int comp, double & val) const; - bool GetSurfValue (const SolData * data, SurfaceElementIndex elnr, - double lam1, double lam2, - int comp, double & val) const; - bool GetValues (const SolData * data, ElementIndex elnr, - double lam1, double lam2, double lam3, - double * values) const; - bool GetSurfValues (const SolData * data, SurfaceElementIndex elnr, - double lam1, double lam2, - double * values) const; - - void GetDeformation (ElementIndex elnr, double lam1, double lam2, double lam3, - Vec<3> & def) const; - void GetSurfDeformation (SurfaceElementIndex selnr, double lam1, double lam2, - Vec<3> & def) const; - - void GetPointDeformation (int pnum, Point<3> & p, SurfaceElementIndex elnr = -1) const; - - /// draw elements (build lists) - void DrawSurfaceElements (); - void DrawSurfaceElementLines (); - void DrawSurfaceVectors (); - - void DrawIsoLines (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - double val1, double val2, double val3, - double minval, double maxval, int n); - - // draw isolines between lines (p1,p2) and (p3,p4) - void DrawIsoLines2 (const Point3d & p1, - const Point3d & p2, - const Point3d & p3, - const Point3d & p4, - double val1, double val2, double val3, double val4, - double minval, double maxval, int n); - - - void DrawClipPlaneTrig (const SolData * sol, - int comp, - const ClipPlaneTrig & trig, - int level); - - void SetOpenGlColor(double val, double valmin, double valmax, int logscale = 0); - - - friend int Ng_Vis_Set (ClientData clientData, - Tcl_Interp * interp, - int argc, tcl_const char *argv[]); - - - -}; - - -extern VisualSceneSolution vssolution; - - - - -#endif - diff --git a/Netgen/nglib_addon.cpp b/Netgen/nglib_addon.cpp deleted file mode 100644 index 391e036012..0000000000 --- a/Netgen/nglib_addon.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// small additions to the netgen interface library for Gmsh - -#include "meshing.hpp" -#include "mystdlib.h" - -namespace nglib { -#include "nglib.h" -} - -using namespace netgen; - -#include <iostream> -#include "Message.h" - -namespace nglib -{ - -class mystreambuf: public streambuf -{ - int index; - char txt[1024]; - public: - mystreambuf() { - index = 0; - } - int sync(){ - txt[index] = '\0'; - if(!index || - (index == 1 && (txt[0] == '.' || txt[0] == '+' || txt[0] == ' '))){ - // ignore these messages - } - else{ - if(!strncmp(txt, "ERROR", 5)) - Msg(FATAL, txt); - else - Msg(INFO, txt); - } - index = 0; - return 0; - } - int overflow(int ch){ - if(index < 1023){ - txt[index] = ch; - if(txt[index] == '\n') txt[index] = ' '; - if(!index && txt[0] == ' '){ - // skip initial spaces - } - else{ - index++; - } - } - return 0; - } -}; - -// replaces the standard Ng_Init -void NgAddOn_Init () -{ - //mycout = &cout; - //myerr = &cerr; - //testout = new ofstream ("test.out"); - - mycout = new ostream(new mystreambuf()); - myerr = new ostream(new mystreambuf()); - testout = new ofstream ("/dev/null"); -} - -// generates volume mesh from surface mesh, without optimization -Ng_Result NgAddOn_GenerateVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp) -{ - Mesh * m = (Mesh*)mesh; - - - MeshingParameters mparam; - mparam.maxh = mp->maxh; - mparam.meshsizefilename = mp->meshsize_filename; - - m->CalcLocalH(); - - MeshVolume (mparam, *m); - //RemoveIllegalElements (*m); - //OptimizeVolume (mparam, *m); - - return NG_OK; -} - -// optimizes an existing 3D mesh -Ng_Result NgAddOn_OptimizeVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp) -{ - Mesh * m = (Mesh*)mesh; - - MeshingParameters mparam; - mparam.maxh = mp->maxh; - mparam.meshsizefilename = mp->meshsize_filename; - - m->CalcLocalH(); - - //MeshVolume (mparam, *m); - RemoveIllegalElements (*m); - OptimizeVolume (mparam, *m); - - return NG_OK; -} - -} diff --git a/Netgen/nglib_addon.h b/Netgen/nglib_addon.h deleted file mode 100644 index 32c39b147f..0000000000 --- a/Netgen/nglib_addon.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _NGLIB_ADDON_H_ -#define _NGLIB_ADDON_H_ - -void NgAddOn_Init(); -Ng_Result NgAddOn_GenerateVolumeMesh(Ng_Mesh * mesh, Ng_Meshing_Parameters * mp); -Ng_Result NgAddOn_OptimizeVolumeMesh(Ng_Mesh * mesh, Ng_Meshing_Parameters * mp); - -#endif diff --git a/Plugin/Makefile b/Plugin/Makefile index a1102f133a..b6f680e5bd 100644 --- a/Plugin/Makefile +++ b/Plugin/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.84 2005-09-21 17:29:37 geuzaine Exp $ +# $Id: Makefile,v 1.85 2005-09-21 17:49:22 geuzaine Exp $ # # Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle # @@ -23,8 +23,8 @@ include ../variables LIB = ../lib/libGmshPlugin.a INCLUDE = -I../Common -I../Graphics -I../DataStr -I../Geo -I../Fltk\ - -I../Mesh -I../Numeric -I../Triangle\ - -I../contrib/MathEval + -I../Mesh -I../Numeric\ + -I../contrib/Triangle -I../contrib/MathEval CFLAGS = ${OPTIM} ${FLAGS} ${INCLUDE} SRC = Plugin.cpp\ diff --git a/Tetgen/LICENSE b/Tetgen/LICENSE deleted file mode 100644 index 456b0bbe48..0000000000 --- a/Tetgen/LICENSE +++ /dev/null @@ -1,65 +0,0 @@ -TetGen License --------------- - -The software (TetGen) is licensed under the terms of the MIT license -with the following exceptions: - -Distribution of modified versions of this code is permissible UNDER -THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE -SAME SOURCE FILES tetgen.h AND tetgen.cxx REMAIN UNDER COPYRIGHT OF -THE ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE MADE FREELY -AVAILABLE WITHOUT CHARGE, AND CLEAR NOTICE IS GIVEN OF THE -MODIFICATIONS. - -Distribution of this code for any commercial purpose is permissible -ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNER. - -The full license text is reproduced below. - -This means that TetGen is no free software, but for private, research, -and educational purposes it can be used at absolutely no cost and -without further arrangements. - - -For details, see http://tetgen.berlios.de - -============================================================================== - -TetGen -A Quality Tetrahedral Mesh Generator and 3D Delaunay Triangulator -Version 1.3 (Released on June 13, 2004). - -Copyright 2002, 2004 Hang Si -Rathausstr. 9, 10178 Berlin, Germany -si@wias-berlin.de - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -Distribution of modified versions of this code is permissible UNDER -THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE -SAME SOURCE FILES tetgen.h AND tetgen.cxx REMAIN UNDER COPYRIGHT OF -THE ORIGINAL AUTHOR, BOTH SOURCE AND OBJECT CODE ARE MADE FREELY -AVAILABLE WITHOUT CHARGE, AND CLEAR NOTICE IS GIVEN OF THE -MODIFICATIONS. - -Distribution of this code for any commercial purpose is permissible -ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNER. - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -============================================================================== \ No newline at end of file diff --git a/Tetgen/Makefile b/Tetgen/Makefile deleted file mode 100644 index 606d759c5c..0000000000 --- a/Tetgen/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# $Id: Makefile,v 1.4 2005-07-03 08:02:24 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshTetgen.a -# Do not optimize (same as Triangle...) -CFLAGS = ${FLAGS} -DTETLIBRARY - -SRC = predicates.cxx tetgen.cxx -OBJ = ${SRC:.cxx=.o} - -.SUFFIXES: .o .cxx - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.cxx.o: - ${CXX} ${CFLAGS} -c $< - -clean: - rm -f *.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CXX} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -predicates.o: predicates.cxx tetgen.h -tetgen.o: tetgen.cxx tetgen.h diff --git a/Tetgen/predicates.cxx b/Tetgen/predicates.cxx deleted file mode 100644 index e3dd38ae48..0000000000 --- a/Tetgen/predicates.cxx +++ /dev/null @@ -1,4176 +0,0 @@ -/*****************************************************************************/ -/* */ -/* Routines for Arbitrary Precision Floating-point Arithmetic */ -/* and Fast Robust Geometric Predicates */ -/* (predicates.c) */ -/* */ -/* May 18, 1996 */ -/* */ -/* Placed in the public domain by */ -/* Jonathan Richard Shewchuk */ -/* School of Computer Science */ -/* Carnegie Mellon University */ -/* 5000 Forbes Avenue */ -/* Pittsburgh, Pennsylvania 15213-3891 */ -/* jrs@cs.cmu.edu */ -/* */ -/* This file contains C implementation of algorithms for exact addition */ -/* and multiplication of floating-point numbers, and predicates for */ -/* robustly performing the orientation and incircle tests used in */ -/* computational geometry. The algorithms and underlying theory are */ -/* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ -/* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ -/* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ -/* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ -/* Discrete & Computational Geometry.) */ -/* */ -/* This file, the paper listed above, and other information are available */ -/* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* Using this code: */ -/* */ -/* First, read the short or long version of the paper (from the Web page */ -/* above). */ -/* */ -/* Be sure to call exactinit() once, before calling any of the arithmetic */ -/* functions or geometric predicates. Also be sure to turn on the */ -/* optimizer when compiling this file. */ -/* */ -/* */ -/* Several geometric predicates are defined. Their parameters are all */ -/* points. Each point is an array of two or three floating-point */ -/* numbers. The geometric predicates, described in the papers, are */ -/* */ -/* orient2d(pa, pb, pc) */ -/* orient2dfast(pa, pb, pc) */ -/* orient3d(pa, pb, pc, pd) */ -/* orient3dfast(pa, pb, pc, pd) */ -/* incircle(pa, pb, pc, pd) */ -/* incirclefast(pa, pb, pc, pd) */ -/* insphere(pa, pb, pc, pd, pe) */ -/* inspherefast(pa, pb, pc, pd, pe) */ -/* */ -/* Those with suffix "fast" are approximate, non-robust versions. Those */ -/* without the suffix are adaptive precision, robust versions. There */ -/* are also versions with the suffices "exact" and "slow", which are */ -/* non-adaptive, exact arithmetic versions, which I use only for timings */ -/* in my arithmetic papers. */ -/* */ -/* */ -/* An expansion is represented by an array of floating-point numbers, */ -/* sorted from smallest to largest magnitude (possibly with interspersed */ -/* zeros). The length of each expansion is stored as a separate integer, */ -/* and each arithmetic function returns an integer which is the length */ -/* of the expansion it created. */ -/* */ -/* Several arithmetic functions are defined. Their parameters are */ -/* */ -/* e, f Input expansions */ -/* elen, flen Lengths of input expansions (must be >= 1) */ -/* h Output expansion */ -/* b Input scalar */ -/* */ -/* The arithmetic functions are */ -/* */ -/* grow_expansion(elen, e, b, h) */ -/* grow_expansion_zeroelim(elen, e, b, h) */ -/* expansion_sum(elen, e, flen, f, h) */ -/* expansion_sum_zeroelim1(elen, e, flen, f, h) */ -/* expansion_sum_zeroelim2(elen, e, flen, f, h) */ -/* fast_expansion_sum(elen, e, flen, f, h) */ -/* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ -/* linear_expansion_sum(elen, e, flen, f, h) */ -/* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ -/* scale_expansion(elen, e, b, h) */ -/* scale_expansion_zeroelim(elen, e, b, h) */ -/* compress(elen, e, h) */ -/* */ -/* All of these are described in the long version of the paper; some are */ -/* described in the short version. All return an integer that is the */ -/* length of h. Those with suffix _zeroelim perform zero elimination, */ -/* and are recommended over their counterparts. The procedure */ -/* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ -/* processors that do not use the round-to-even tiebreaking rule) is */ -/* recommended over expansion_sum_zeroelim(). Each procedure has a */ -/* little note next to it (in the code below) that tells you whether or */ -/* not the output expansion may be the same array as one of the input */ -/* expansions. */ -/* */ -/* */ -/* If you look around below, you'll also find macros for a bunch of */ -/* simple unrolled arithmetic operations, and procedures for printing */ -/* expansions (commented out because they don't work with all C */ -/* compilers) and for generating random floating-point numbers whose */ -/* significand bits are all random. Most of the macros have undocumented */ -/* requirements that certain of their parameters should not be the same */ -/* variable; for safety, better to make sure all the parameters are */ -/* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ -/* have questions. */ -/* */ -/*****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#ifdef CPU86 -#include <float.h> -#endif /* CPU86 */ -#ifdef LINUX -#include <fpu_control.h> -#endif /* LINUX */ - -#include "tetgen.h" // Defines the symbol REAL (float or double). - -/* On some machines, the exact arithmetic routines might be defeated by the */ -/* use of internal extended precision floating-point registers. Sometimes */ -/* this problem can be fixed by defining certain values to be volatile, */ -/* thus forcing them to be stored to memory and rounded off. This isn't */ -/* a great solution, though, as it slows the arithmetic down. */ -/* */ -/* To try this out, write "#define INEXACT volatile" below. Normally, */ -/* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */ - -#define INEXACT /* Nothing */ -/* #define INEXACT volatile */ - -/* #define REAL double */ /* float or double */ -#define REALPRINT doubleprint -#define REALRAND doublerand -#define NARROWRAND narrowdoublerand -#define UNIFORMRAND uniformdoublerand - -/* Which of the following two methods of finding the absolute values is */ -/* fastest is compiler-dependent. A few compilers can inline and optimize */ -/* the fabs() call; but most will incur the overhead of a function call, */ -/* which is disastrously slow. A faster way on IEEE machines might be to */ -/* mask the appropriate bit, but that's difficult to do in C. */ - -#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) -/* #define Absolute(a) fabs(a) */ - -/* Many of the operations are broken up into two pieces, a main part that */ -/* performs an approximate operation, and a "tail" that computes the */ -/* roundoff error of that operation. */ -/* */ -/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ -/* Split(), and Two_Product() are all implemented as described in the */ -/* reference. Each of these macros requires certain variables to be */ -/* defined in the calling routine. The variables `bvirt', `c', `abig', */ -/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ -/* they store the result of an operation that may incur roundoff error. */ -/* The input parameter `x' (or the highest numbered `x_' parameter) must */ -/* also be declared `INEXACT'. */ - -#define Fast_Two_Sum_Tail(a, b, x, y) \ - bvirt = x - a; \ - y = b - bvirt - -#define Fast_Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Fast_Two_Sum_Tail(a, b, x, y) - -#define Fast_Two_Diff_Tail(a, b, x, y) \ - bvirt = a - x; \ - y = bvirt - b - -#define Fast_Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Fast_Two_Diff_Tail(a, b, x, y) - -#define Two_Sum_Tail(a, b, x, y) \ - bvirt = (REAL) (x - a); \ - avirt = x - bvirt; \ - bround = b - bvirt; \ - around = a - avirt; \ - y = around + bround - -#define Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Two_Sum_Tail(a, b, x, y) - -#define Two_Diff_Tail(a, b, x, y) \ - bvirt = (REAL) (a - x); \ - avirt = x + bvirt; \ - bround = bvirt - b; \ - around = a - avirt; \ - y = around + bround - -#define Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Two_Diff_Tail(a, b, x, y) - -#define Split(a, ahi, alo) \ - c = (REAL) (splitter * a); \ - abig = (REAL) (c - a); \ - ahi = c - abig; \ - alo = a - ahi - -#define Two_Product_Tail(a, b, x, y) \ - Split(a, ahi, alo); \ - Split(b, bhi, blo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -#define Two_Product(a, b, x, y) \ - x = (REAL) (a * b); \ - Two_Product_Tail(a, b, x, y) - -/* Two_Product_Presplit() is Two_Product() where one of the inputs has */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_Presplit(a, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - Split(a, ahi, alo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Square() can be done more quickly than Two_Product(). */ - -#define Square_Tail(a, x, y) \ - Split(a, ahi, alo); \ - err1 = x - (ahi * ahi); \ - err3 = err1 - ((ahi + ahi) * alo); \ - y = (alo * alo) - err3 - -#define Square(a, x, y) \ - x = (REAL) (a * a); \ - Square_Tail(a, x, y) - -/* Macros for summing expansions of various fixed lengths. These are all */ -/* unrolled versions of Expansion_Sum(). */ - -#define Two_One_Sum(a1, a0, b, x2, x1, x0) \ - Two_Sum(a0, b , _i, x0); \ - Two_Sum(a1, _i, x2, x1) - -#define Two_One_Diff(a1, a0, b, x2, x1, x0) \ - Two_Diff(a0, b , _i, x0); \ - Two_Sum( a1, _i, x2, x1) - -#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b0, _j, _0, x0); \ - Two_One_Sum(_j, _0, b1, x3, x2, x1) - -#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Diff(a1, a0, b0, _j, _0, x0); \ - Two_One_Diff(_j, _0, b1, x3, x2, x1) - -#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b , _j, x1, x0); \ - Two_One_Sum(a3, a2, _j, x4, x3, x2) - -#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ - Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ - Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) - -#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ - x1, x0) \ - Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ - Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) - -#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ - x3, x2, x1, x0) \ - Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ - Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) - -#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ - x6, x5, x4, x3, x2, x1, x0) \ - Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ - _1, _0, x0); \ - Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ - x3, x2, x1) - -#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ - x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ - Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ - _2, _1, _0, x1, x0); \ - Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ - x7, x6, x5, x4, x3, x2) - -/* Macros for multiplying expansions of various fixed lengths. */ - -#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, x3, x2) - -#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, _i, x2); \ - Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x3); \ - Fast_Two_Sum(_j, _k, _i, x4); \ - Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x5); \ - Fast_Two_Sum(_j, _k, x7, x6) - -#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ - Split(a0, a0hi, a0lo); \ - Split(b0, bhi, blo); \ - Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ - Split(a1, a1hi, a1lo); \ - Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, _1); \ - Fast_Two_Sum(_j, _k, _l, _2); \ - Split(b1, bhi, blo); \ - Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ - Two_Sum(_1, _0, _k, x1); \ - Two_Sum(_2, _k, _j, _1); \ - Two_Sum(_l, _j, _m, _2); \ - Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _n, _0); \ - Two_Sum(_1, _0, _i, x2); \ - Two_Sum(_2, _i, _k, _1); \ - Two_Sum(_m, _k, _l, _2); \ - Two_Sum(_j, _n, _k, _0); \ - Two_Sum(_1, _0, _j, x3); \ - Two_Sum(_2, _j, _i, _1); \ - Two_Sum(_l, _i, _m, _2); \ - Two_Sum(_1, _k, _i, x4); \ - Two_Sum(_2, _i, _k, x5); \ - Two_Sum(_m, _k, x7, x6) - -/* An expansion of length two can be squared more quickly than finding the */ -/* product of two different expansions of length two, and the result is */ -/* guaranteed to have no more than six (rather than eight) components. */ - -#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ - Square(a0, _j, x0); \ - _0 = a0 + a0; \ - Two_Product(a1, _0, _k, _1); \ - Two_One_Sum(_k, _1, _j, _l, _2, x1); \ - Square(a1, _j, _1); \ - Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) - -/* splitter = 2^ceiling(p / 2) + 1. Used to split floats in half. */ -static REAL splitter; -static REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ -/* A set of coefficients used to calculate maximum roundoff errors. */ -static REAL resulterrbound; -static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC; -static REAL o3derrboundA, o3derrboundB, o3derrboundC; -static REAL iccerrboundA, iccerrboundB, iccerrboundC; -static REAL isperrboundA, isperrboundB, isperrboundC; - -/*****************************************************************************/ -/* */ -/* doubleprint() Print the bit representation of a double. */ -/* */ -/* Useful for debugging exact arithmetic routines. */ -/* */ -/*****************************************************************************/ - -/* -void doubleprint(number) -double number; -{ - unsigned long long no; - unsigned long long sign, expo; - int exponent; - int i, bottomi; - - no = *(unsigned long long *) &number; - sign = no & 0x8000000000000000ll; - expo = (no >> 52) & 0x7ffll; - exponent = (int) expo; - exponent = exponent - 1023; - if (sign) { - printf("-"); - } else { - printf(" "); - } - if (exponent == -1023) { - printf( - "0.0000000000000000000000000000000000000000000000000000_ ( )"); - } else { - printf("1."); - bottomi = -1; - for (i = 0; i < 52; i++) { - if (no & 0x0008000000000000ll) { - printf("1"); - bottomi = i; - } else { - printf("0"); - } - no <<= 1; - } - printf("_%d (%d)", exponent, exponent - 1 - bottomi); - } -} -*/ - -/*****************************************************************************/ -/* */ -/* floatprint() Print the bit representation of a float. */ -/* */ -/* Useful for debugging exact arithmetic routines. */ -/* */ -/*****************************************************************************/ - -/* -void floatprint(number) -float number; -{ - unsigned no; - unsigned sign, expo; - int exponent; - int i, bottomi; - - no = *(unsigned *) &number; - sign = no & 0x80000000; - expo = (no >> 23) & 0xff; - exponent = (int) expo; - exponent = exponent - 127; - if (sign) { - printf("-"); - } else { - printf(" "); - } - if (exponent == -127) { - printf("0.00000000000000000000000_ ( )"); - } else { - printf("1."); - bottomi = -1; - for (i = 0; i < 23; i++) { - if (no & 0x00400000) { - printf("1"); - bottomi = i; - } else { - printf("0"); - } - no <<= 1; - } - printf("_%3d (%3d)", exponent, exponent - 1 - bottomi); - } -} -*/ - -/*****************************************************************************/ -/* */ -/* expansion_print() Print the bit representation of an expansion. */ -/* */ -/* Useful for debugging exact arithmetic routines. */ -/* */ -/*****************************************************************************/ - -/* -void expansion_print(elen, e) -int elen; -REAL *e; -{ - int i; - - for (i = elen - 1; i >= 0; i--) { - REALPRINT(e[i]); - if (i > 0) { - printf(" +\n"); - } else { - printf("\n"); - } - } -} -*/ - -/*****************************************************************************/ -/* */ -/* doublerand() Generate a double with random 53-bit significand and a */ -/* random exponent in [0, 511]. */ -/* */ -/*****************************************************************************/ - -/* -double doublerand() -{ - double result; - double expo; - long a, b, c; - long i; - - a = random(); - b = random(); - c = random(); - result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); - for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} -*/ - -/*****************************************************************************/ -/* */ -/* narrowdoublerand() Generate a double with random 53-bit significand */ -/* and a random exponent in [0, 7]. */ -/* */ -/*****************************************************************************/ - -/* -double narrowdoublerand() -{ - double result; - double expo; - long a, b, c; - long i; - - a = random(); - b = random(); - c = random(); - result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); - for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} -*/ - -/*****************************************************************************/ -/* */ -/* uniformdoublerand() Generate a double with random 53-bit significand. */ -/* */ -/*****************************************************************************/ - -/* -double uniformdoublerand() -{ - double result; - long a, b; - - a = random(); - b = random(); - result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); - return result; -} -*/ - -/*****************************************************************************/ -/* */ -/* floatrand() Generate a float with random 24-bit significand and a */ -/* random exponent in [0, 63]. */ -/* */ -/*****************************************************************************/ - -/* -float floatrand() -{ - float result; - float expo; - long a, c; - long i; - - a = random(); - c = random(); - result = (float) ((a - 1073741824) >> 6); - for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} -*/ - -/*****************************************************************************/ -/* */ -/* narrowfloatrand() Generate a float with random 24-bit significand and */ -/* a random exponent in [0, 7]. */ -/* */ -/*****************************************************************************/ - -/* -float narrowfloatrand() -{ - float result; - float expo; - long a, c; - long i; - - a = random(); - c = random(); - result = (float) ((a - 1073741824) >> 6); - for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { - if (c & i) { - result *= expo; - } - } - return result; -} -*/ - -/*****************************************************************************/ -/* */ -/* uniformfloatrand() Generate a float with random 24-bit significand. */ -/* */ -/*****************************************************************************/ - -/* -float uniformfloatrand() -{ - float result; - long a; - - a = random(); - result = (float) ((a - 1073741824) >> 6); - return result; -} -*/ - -/*****************************************************************************/ -/* */ -/* exactinit() Initialize the variables used for exact arithmetic. */ -/* */ -/* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ -/* floating-point arithmetic. `epsilon' bounds the relative roundoff */ -/* error. It is used for floating-point error analysis. */ -/* */ -/* `splitter' is used to split floating-point numbers into two half- */ -/* length significands for exact multiplication. */ -/* */ -/* I imagine that a highly optimizing compiler might be too smart for its */ -/* own good, and somehow cause this routine to fail, if it pretends that */ -/* floating-point arithmetic is too much like real arithmetic. */ -/* */ -/* Don't change this routine unless you fully understand it. */ -/* */ -/*****************************************************************************/ - -REAL exactinit() -{ - REAL half; - REAL check, lastcheck; - int every_other; -#ifdef LINUX - int cword; -#endif /* LINUX */ - -#ifdef CPU86 -#ifdef SINGLE - _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */ -#else /* not SINGLE */ - _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */ -#endif /* not SINGLE */ -#endif /* CPU86 */ -#ifdef LINUX -#ifdef SINGLE - /* cword = 4223; */ - cword = 4210; /* set FPU control word for single precision */ -#else /* not SINGLE */ - /* cword = 4735; */ - cword = 4722; /* set FPU control word for double precision */ -#endif /* not SINGLE */ - _FPU_SETCW(cword); -#endif /* LINUX */ - - every_other = 1; - half = 0.5; - epsilon = 1.0; - splitter = 1.0; - check = 1.0; - /* Repeatedly divide `epsilon' by two until it is too small to add to */ - /* one without causing roundoff. (Also check if the sum is equal to */ - /* the previous sum, for machines that round up instead of using exact */ - /* rounding. Not that this library will work on such machines anyway. */ - do { - lastcheck = check; - epsilon *= half; - if (every_other) { - splitter *= 2.0; - } - every_other = !every_other; - check = 1.0 + epsilon; - } while ((check != 1.0) && (check != lastcheck)); - splitter += 1.0; - - /* Error bounds for orientation and incircle tests. */ - resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; - ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; - ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; - ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; - o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; - o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; - o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; - iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; - iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; - iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; - isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; - isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; - isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; - - return epsilon; /* Added by H. Si 30 Juli, 2004. */ -} - -/*****************************************************************************/ -/* */ -/* grow_expansion() Add a scalar to an expansion. */ -/* */ -/* Sets h = e + b. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int grow_expansion(int elen, REAL *e, REAL b, REAL *h) -/* e and h can be the same. */ -{ - REAL Q; - INEXACT REAL Qnew; - int eindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - Q = b; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, h[eindex]); - Q = Qnew; - } - h[eindex] = Q; - return eindex + 1; -} - -/*****************************************************************************/ -/* */ -/* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */ -/* zero components from the output expansion. */ -/* */ -/* Sets h = e + b. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int grow_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) -/* e and h can be the same. */ -{ - REAL Q, hh; - INEXACT REAL Qnew; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - hindex = 0; - Q = b; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) -/* e and h can be the same, but f and h cannot. */ -{ - REAL Q; - INEXACT REAL Qnew; - int findex, hindex, hlast; - REAL hnow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - Q = f[0]; - for (hindex = 0; hindex < elen; hindex++) { - hnow = e[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - Q = f[findex]; - for (hindex = findex; hindex <= hlast; hindex++) { - hnow = h[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[++hlast] = Q; - } - return hlast + 1; -} - -/*****************************************************************************/ -/* */ -/* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum_zeroelim1(int elen, REAL *e, int flen, REAL *f, REAL *h) -/* e and h can be the same, but f and h cannot. */ -{ - REAL Q; - INEXACT REAL Qnew; - int index, findex, hindex, hlast; - REAL hnow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - Q = f[0]; - for (hindex = 0; hindex < elen; hindex++) { - hnow = e[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - Q = f[findex]; - for (hindex = findex; hindex <= hlast; hindex++) { - hnow = h[hindex]; - Two_Sum(Q, hnow, Qnew, h[hindex]); - Q = Qnew; - } - h[++hlast] = Q; - } - hindex = -1; - for (index = 0; index <= hlast; index++) { - hnow = h[index]; - if (hnow != 0.0) { - h[++hindex] = hnow; - } - } - if (hindex == -1) { - return 1; - } else { - return hindex + 1; - } -} - -/*****************************************************************************/ -/* */ -/* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the nonadjacent property as well. (That is, */ -/* if e has one of these properties, so will h.) Does NOT maintain the */ -/* strongly nonoverlapping property. */ -/* */ -/*****************************************************************************/ - -int expansion_sum_zeroelim2(int elen, REAL *e, int flen, REAL *f, REAL *h) -/* e and h can be the same, but f and h cannot. */ -{ - REAL Q, hh; - INEXACT REAL Qnew; - int eindex, findex, hindex, hlast; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - - hindex = 0; - Q = f[0]; - for (eindex = 0; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - h[hindex] = Q; - hlast = hindex; - for (findex = 1; findex < flen; findex++) { - hindex = 0; - Q = f[findex]; - for (eindex = 0; eindex <= hlast; eindex++) { - enow = h[eindex]; - Two_Sum(Q, enow, Qnew, hh); - Q = Qnew; - if (hh != 0) { - h[hindex++] = hh; - } - } - h[hindex] = Q; - hlast = hindex; - } - return hlast + 1; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -int fast_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) -/* h cannot be e or f. */ -{ - REAL Q; - INEXACT REAL Qnew; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, h[0]); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, h[0]); - fnow = f[++findex]; - } - Q = Qnew; - hindex = 1; - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, h[hindex]); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, h[hindex]); - fnow = f[++findex]; - } - Q = Qnew; - hindex++; - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, h[hindex]); - enow = e[++eindex]; - Q = Qnew; - hindex++; - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, h[hindex]); - fnow = f[++findex]; - Q = Qnew; - hindex++; - } - h[hindex] = Q; - return hindex + 1; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See the long version of my paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h) -/* h cannot be e or f. */ -{ - REAL Q; - INEXACT REAL Qnew; - INEXACT REAL hh; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* linear_expansion_sum() Sum two expansions. */ -/* */ -/* Sets h = e + f. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. (That is, if e is */ -/* nonoverlapping, h will be also.) */ -/* */ -/*****************************************************************************/ - -int linear_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) -/* h cannot be e or f. */ -{ - REAL Q, q; - INEXACT REAL Qnew; - INEXACT REAL R; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - REAL g0; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - g0 = enow; - enow = e[++eindex]; - } else { - g0 = fnow; - fnow = f[++findex]; - } - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, g0, Qnew, q); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, g0, Qnew, q); - fnow = f[++findex]; - } - Q = Qnew; - for (hindex = 0; hindex < elen + flen - 2; hindex++) { - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, q, R, h[hindex]); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, q, R, h[hindex]); - fnow = f[++findex]; - } - Two_Sum(Q, R, Qnew, q); - Q = Qnew; - } - h[hindex] = q; - h[hindex + 1] = Q; - return hindex + 2; -} - -/*****************************************************************************/ -/* */ -/* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. (That is, if e is */ -/* nonoverlapping, h will be also.) */ -/* */ -/*****************************************************************************/ - -int linear_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, - REAL *h) -/* h cannot be e or f. */ -{ - REAL Q, q, hh; - INEXACT REAL Qnew; - INEXACT REAL R; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - int count; - REAL enow, fnow; - REAL g0; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - hindex = 0; - if ((fnow > enow) == (fnow > -enow)) { - g0 = enow; - enow = e[++eindex]; - } else { - g0 = fnow; - fnow = f[++findex]; - } - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, g0, Qnew, q); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, g0, Qnew, q); - fnow = f[++findex]; - } - Q = Qnew; - for (count = 2; count < elen + flen; count++) { - if ((eindex < elen) && ((findex >= flen) - || ((fnow > enow) == (fnow > -enow)))) { - Fast_Two_Sum(enow, q, R, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, q, R, hh); - fnow = f[++findex]; - } - Two_Sum(Q, R, Qnew, q); - Q = Qnew; - if (hh != 0) { - h[hindex++] = hh; - } - } - if (q != 0) { - h[hindex++] = q; - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion() Multiply an expansion by a scalar. */ -/* */ -/* Sets h = be. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int scale_expansion(int elen, REAL *e, REAL b, REAL *h) -/* e and h cannot be the same. */ -{ - INEXACT REAL Q; - INEXACT REAL sum; - INEXACT REAL product1; - REAL product0; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]); - hindex = 1; - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, h[hindex]); - hindex++; - Two_Sum(product1, sum, Q, h[hindex]); - hindex++; - } - h[hindex] = Q; - return elen + elen; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ -/* eliminating zero components from the */ -/* output expansion. */ -/* */ -/* Sets h = be. See either version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) -/* e and h cannot be the same. */ -{ - INEXACT REAL Q, sum; - REAL hh; - INEXACT REAL product1; - REAL product0; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); - hindex = 0; - if (hh != 0) { - h[hindex++] = hh; - } - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, hh); - if (hh != 0) { - h[hindex++] = hh; - } - Fast_Two_Sum(product1, sum, Q, hh); - if (hh != 0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* compress() Compress an expansion. */ -/* */ -/* See the long version of my paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), then any nonoverlapping expansion is converted to a */ -/* nonadjacent expansion. */ -/* */ -/*****************************************************************************/ - -int compress(int elen, REAL *e, REAL *h) -/* e and h may be the same. */ -{ - REAL Q, q; - INEXACT REAL Qnew; - int eindex, hindex; - INEXACT REAL bvirt; - REAL enow, hnow; - int top, bottom; - - bottom = elen - 1; - Q = e[bottom]; - for (eindex = elen - 2; eindex >= 0; eindex--) { - enow = e[eindex]; - Fast_Two_Sum(Q, enow, Qnew, q); - if (q != 0) { - h[bottom--] = Qnew; - Q = q; - } else { - Q = Qnew; - } - } - top = 0; - for (hindex = bottom + 1; hindex < elen; hindex++) { - hnow = h[hindex]; - Fast_Two_Sum(hnow, Q, Qnew, q); - if (q != 0) { - h[top++] = q; - } - Q = Qnew; - } - h[top] = Q; - return top + 1; -} - -/*****************************************************************************/ -/* */ -/* estimate() Produce a one-word estimate of an expansion's value. */ -/* */ -/* See either version of my paper for details. */ -/* */ -/*****************************************************************************/ - -REAL estimate(int elen, REAL *e) -{ - REAL Q; - int eindex; - - Q = e[0]; - for (eindex = 1; eindex < elen; eindex++) { - Q += e[eindex]; - } - return Q; -} - -/*****************************************************************************/ -/* */ -/* orient2dfast() Approximate 2D orientation test. Nonrobust. */ -/* orient2dexact() Exact 2D orientation test. Robust. */ -/* orient2dslow() Another exact 2D orientation test. Robust. */ -/* orient2d() Adaptive exact 2D orientation test. Robust. */ -/* */ -/* Return a positive value if the points pa, pb, and pc occur */ -/* in counterclockwise order; a negative value if they occur */ -/* in clockwise order; and zero if they are collinear. The */ -/* result is also a rough approximation of twice the signed */ -/* area of the triangle defined by the three points. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In orient2d() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, orient2d() is usually quite */ -/* fast, but will run more slowly when the input points are collinear or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL orient2dfast(REAL *pa, REAL *pb, REAL *pc) -{ - REAL acx, bcx, acy, bcy; - - acx = pa[0] - pc[0]; - bcx = pb[0] - pc[0]; - acy = pa[1] - pc[1]; - bcy = pb[1] - pc[1]; - return acx * bcy - acy * bcx; -} - -REAL orient2dexact(REAL *pa, REAL *pb, REAL *pc) -{ - INEXACT REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1; - REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0; - REAL aterms[4], bterms[4], cterms[4]; - INEXACT REAL aterms3, bterms3, cterms3; - REAL v[8], w[12]; - int vlength, wlength; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Two_Diff(axby1, axby0, axcy1, axcy0, - aterms3, aterms[2], aterms[1], aterms[0]); - aterms[3] = aterms3; - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0, - bterms3, bterms[2], bterms[1], bterms[0]); - bterms[3] = bterms3; - - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(cxay1, cxay0, cxby1, cxby0, - cterms3, cterms[2], cterms[1], cterms[0]); - cterms[3] = cterms3; - - vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v); - wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w); - - return w[wlength - 1]; -} - -REAL orient2dslow(REAL *pa, REAL *pb, REAL *pc) -{ - INEXACT REAL acx, acy, bcx, bcy; - REAL acxtail, acytail; - REAL bcxtail, bcytail; - REAL negate, negatetail; - REAL axby[8], bxay[8]; - INEXACT REAL axby7, bxay7; - REAL deter[16]; - int deterlen; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pc[0], acx, acxtail); - Two_Diff(pa[1], pc[1], acy, acytail); - Two_Diff(pb[0], pc[0], bcx, bcxtail); - Two_Diff(pb[1], pc[1], bcy, bcytail); - - Two_Two_Product(acx, acxtail, bcy, bcytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -acy; - negatetail = -acytail; - Two_Two_Product(bcx, bcxtail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - - deterlen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, deter); - - return deter[deterlen - 1]; -} - -REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum) -{ - INEXACT REAL acx, acy, bcx, bcy; - REAL acxtail, acytail, bcxtail, bcytail; - INEXACT REAL detleft, detright; - REAL detlefttail, detrighttail; - REAL det, errbound; - REAL B[4], C1[8], C2[12], D[16]; - INEXACT REAL B3; - int C1length, C2length, Dlength; - REAL u[4]; - INEXACT REAL u3; - INEXACT REAL s1, t1; - REAL s0, t0; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - acx = (REAL) (pa[0] - pc[0]); - bcx = (REAL) (pb[0] - pc[0]); - acy = (REAL) (pa[1] - pc[1]); - bcy = (REAL) (pb[1] - pc[1]); - - Two_Product(acx, bcy, detleft, detlefttail); - Two_Product(acy, bcx, detright, detrighttail); - - Two_Two_Diff(detleft, detlefttail, detright, detrighttail, - B3, B[2], B[1], B[0]); - B[3] = B3; - - det = estimate(4, B); - errbound = ccwerrboundB * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pc[0], acx, acxtail); - Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); - Two_Diff_Tail(pa[1], pc[1], acy, acytail); - Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); - - if ((acxtail == 0.0) && (acytail == 0.0) - && (bcxtail == 0.0) && (bcytail == 0.0)) { - return det; - } - - errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det); - det += (acx * bcytail + bcy * acxtail) - - (acy * bcxtail + bcx * acytail); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Product(acxtail, bcy, s1, s0); - Two_Product(acytail, bcx, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); - - Two_Product(acx, bcytail, s1, s0); - Two_Product(acy, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); - - Two_Product(acxtail, bcytail, s1, s0); - Two_Product(acytail, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); - - return(D[Dlength - 1]); -} - -REAL orient2d(REAL *pa, REAL *pb, REAL *pc) -{ - REAL detleft, detright, det; - REAL detsum, errbound; - - detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); - detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); - det = detleft - detright; - - if (detleft > 0.0) { - if (detright <= 0.0) { - return det; - } else { - detsum = detleft + detright; - } - } else if (detleft < 0.0) { - if (detright >= 0.0) { - return det; - } else { - detsum = -detleft - detright; - } - } else { - return det; - } - - errbound = ccwerrboundA * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return orient2dadapt(pa, pb, pc, detsum); -} - -/*****************************************************************************/ -/* */ -/* orient3dfast() Approximate 3D orientation test. Nonrobust. */ -/* orient3dexact() Exact 3D orientation test. Robust. */ -/* orient3dslow() Another exact 3D orientation test. Robust. */ -/* orient3d() Adaptive exact 3D orientation test. Robust. */ -/* */ -/* Return a positive value if the point pd lies below the */ -/* plane passing through pa, pb, and pc; "below" is defined so */ -/* that pa, pb, and pc appear in counterclockwise order when */ -/* viewed from above the plane. Returns a negative value if */ -/* pd lies above the plane. Returns zero if the points are */ -/* coplanar. The result is also a rough approximation of six */ -/* times the signed volume of the tetrahedron defined by the */ -/* four points. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In orient3d() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, orient3d() is usually quite */ -/* fast, but will run more slowly when the input points are coplanar or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL orient3dfast(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - REAL adx, bdx, cdx; - REAL ady, bdy, cdy; - REAL adz, bdz, cdz; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - adz = pa[2] - pd[2]; - bdz = pb[2] - pd[2]; - cdz = pc[2] - pd[2]; - - return adx * (bdy * cdz - bdz * cdy) - + bdx * (cdy * adz - cdz * ady) - + cdx * (ady * bdz - adz * bdy); -} - -REAL orient3dexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; - INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; - REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; - REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL temp8[8]; - int templen; - REAL abc[12], bcd[12], cda[12], dab[12]; - int abclen, bcdlen, cdalen, dablen; - REAL adet[24], bdet[24], cdet[24], ddet[24]; - int alen, blen, clen, dlen; - REAL abdet[48], cddet[48]; - int ablen, cdlen; - REAL deter[96]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); - cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); - templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); - dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); - for (i = 0; i < 4; i++) { - bd[i] = -bd[i]; - ac[i] = -ac[i]; - } - templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); - abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); - templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); - bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); - - alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet); - blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet); - clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet); - dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL orient3dslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - INEXACT REAL adx, ady, adz, bdx, bdy, bdz, cdx, cdy, cdz; - REAL adxtail, adytail, adztail; - REAL bdxtail, bdytail, bdztail; - REAL cdxtail, cdytail, cdztail; - REAL negate, negatetail; - INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; - REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; - REAL temp16[16], temp32[32], temp32t[32]; - int temp16len, temp32len, temp32tlen; - REAL adet[64], bdet[64], cdet[64]; - int alen, blen, clen; - REAL abdet[128]; - int ablen; - REAL deter[192]; - int deterlen; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pd[0], adx, adxtail); - Two_Diff(pa[1], pd[1], ady, adytail); - Two_Diff(pa[2], pd[2], adz, adztail); - Two_Diff(pb[0], pd[0], bdx, bdxtail); - Two_Diff(pb[1], pd[1], bdy, bdytail); - Two_Diff(pb[2], pd[2], bdz, bdztail); - Two_Diff(pc[0], pd[0], cdx, cdxtail); - Two_Diff(pc[1], pd[1], cdy, cdytail); - Two_Diff(pc[2], pd[2], cdz, cdztail); - - Two_Two_Product(adx, adxtail, bdy, bdytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -ady; - negatetail = -adytail; - Two_Two_Product(bdx, bdxtail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - Two_Two_Product(bdx, bdxtail, cdy, cdytail, - bxcy7, bxcy[6], bxcy[5], bxcy[4], - bxcy[3], bxcy[2], bxcy[1], bxcy[0]); - bxcy[7] = bxcy7; - negate = -bdy; - negatetail = -bdytail; - Two_Two_Product(cdx, cdxtail, negate, negatetail, - cxby7, cxby[6], cxby[5], cxby[4], - cxby[3], cxby[2], cxby[1], cxby[0]); - cxby[7] = cxby7; - Two_Two_Product(cdx, cdxtail, ady, adytail, - cxay7, cxay[6], cxay[5], cxay[4], - cxay[3], cxay[2], cxay[1], cxay[0]); - cxay[7] = cxay7; - negate = -cdy; - negatetail = -cdytail; - Two_Two_Product(adx, adxtail, negate, negatetail, - axcy7, axcy[6], axcy[5], axcy[4], - axcy[3], axcy[2], axcy[1], axcy[0]); - axcy[7] = axcy7; - - temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); - temp32len = scale_expansion_zeroelim(temp16len, temp16, adz, temp32); - temp32tlen = scale_expansion_zeroelim(temp16len, temp16, adztail, temp32t); - alen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, - adet); - - temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); - temp32len = scale_expansion_zeroelim(temp16len, temp16, bdz, temp32); - temp32tlen = scale_expansion_zeroelim(temp16len, temp16, bdztail, temp32t); - blen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, - bdet); - - temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); - temp32len = scale_expansion_zeroelim(temp16len, temp16, cdz, temp32); - temp32tlen = scale_expansion_zeroelim(temp16len, temp16, cdztail, temp32t); - clen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, - cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); - - return deter[deterlen - 1]; -} - -REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL permanent) -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; - REAL det, errbound; - - INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - INEXACT REAL bc3, ca3, ab3; - REAL adet[8], bdet[8], cdet[8]; - int alen, blen, clen; - REAL abdet[16]; - int ablen; - REAL *finnow, *finother, *finswap; - REAL fin1[192], fin2[192]; - int finlength; - - REAL adxtail, bdxtail, cdxtail; - REAL adytail, bdytail, cdytail; - REAL adztail, bdztail, cdztail; - INEXACT REAL at_blarge, at_clarge; - INEXACT REAL bt_clarge, bt_alarge; - INEXACT REAL ct_alarge, ct_blarge; - REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; - int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen; - INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; - INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; - REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; - REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; - INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; - INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; - REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; - REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; - REAL bct[8], cat[8], abt[8]; - int bctlen, catlen, abtlen; - INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; - INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; - REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; - REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; - REAL u[4], v[12], w[16]; - INEXACT REAL u3; - int vlength, wlength; - REAL negate; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k; - REAL _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - adz = (REAL) (pa[2] - pd[2]); - bdz = (REAL) (pb[2] - pd[2]); - cdz = (REAL) (pc[2] - pd[2]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - alen = scale_expansion_zeroelim(4, bc, adz, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - blen = scale_expansion_zeroelim(4, ca, bdz, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - clen = scale_expansion_zeroelim(4, ab, cdz, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = o3derrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - Two_Diff_Tail(pa[2], pd[2], adz, adztail); - Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); - Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); - - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) - && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { - return det; - } - - errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); - det += (adz * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + adztail * (bdx * cdy - bdy * cdx)) - + (bdz * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + bdztail * (cdx * ady - cdy * adx)) - + (cdz * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + cdztail * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if (adxtail == 0.0) { - if (adytail == 0.0) { - at_b[0] = 0.0; - at_blen = 1; - at_c[0] = 0.0; - at_clen = 1; - } else { - negate = -adytail; - Two_Product(negate, bdx, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - Two_Product(adytail, cdx, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } - } else { - if (adytail == 0.0) { - Two_Product(adxtail, bdy, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - negate = -adxtail; - Two_Product(negate, cdy, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } else { - Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); - Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); - Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, - at_blarge, at_b[2], at_b[1], at_b[0]); - at_b[3] = at_blarge; - at_blen = 4; - Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); - Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); - Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, - at_clarge, at_c[2], at_c[1], at_c[0]); - at_c[3] = at_clarge; - at_clen = 4; - } - } - if (bdxtail == 0.0) { - if (bdytail == 0.0) { - bt_c[0] = 0.0; - bt_clen = 1; - bt_a[0] = 0.0; - bt_alen = 1; - } else { - negate = -bdytail; - Two_Product(negate, cdx, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - Two_Product(bdytail, adx, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } - } else { - if (bdytail == 0.0) { - Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - negate = -bdxtail; - Two_Product(negate, ady, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } else { - Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); - Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); - Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, - bt_clarge, bt_c[2], bt_c[1], bt_c[0]); - bt_c[3] = bt_clarge; - bt_clen = 4; - Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); - Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); - Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, - bt_alarge, bt_a[2], bt_a[1], bt_a[0]); - bt_a[3] = bt_alarge; - bt_alen = 4; - } - } - if (cdxtail == 0.0) { - if (cdytail == 0.0) { - ct_a[0] = 0.0; - ct_alen = 1; - ct_b[0] = 0.0; - ct_blen = 1; - } else { - negate = -cdytail; - Two_Product(negate, adx, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } - } else { - if (cdytail == 0.0) { - Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - negate = -cdxtail; - Two_Product(negate, bdy, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } else { - Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); - Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); - Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, - ct_alarge, ct_a[2], ct_a[1], ct_a[0]); - ct_a[3] = ct_alarge; - ct_alen = 4; - Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); - Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); - Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, - ct_blarge, ct_b[2], ct_b[1], ct_b[0]); - ct_b[3] = ct_blarge; - ct_blen = 4; - } - } - - bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); - wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); - wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); - wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - if (adztail != 0.0) { - vlength = scale_expansion_zeroelim(4, bc, adztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdztail != 0.0) { - vlength = scale_expansion_zeroelim(4, ca, bdztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdztail != 0.0) { - vlength = scale_expansion_zeroelim(4, ab, cdztail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if (adxtail != 0.0) { - if (bdytail != 0.0) { - Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdztail != 0.0) { - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (cdytail != 0.0) { - negate = -adxtail; - Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdztail != 0.0) { - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (bdxtail != 0.0) { - if (cdytail != 0.0) { - Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adztail != 0.0) { - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (adytail != 0.0) { - negate = -bdxtail; - Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdztail != 0.0) { - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (cdxtail != 0.0) { - if (adytail != 0.0) { - Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdztail != 0.0) { - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (bdytail != 0.0) { - negate = -cdxtail; - Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adztail != 0.0) { - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - - if (adztail != 0.0) { - wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdztail != 0.0) { - wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdztail != 0.0) { - wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - return finnow[finlength - 1]; -} - -REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL det; - REAL permanent, errbound; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - adz = pa[2] - pd[2]; - bdz = pb[2] - pd[2]; - cdz = pc[2] - pd[2]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - - det = adz * (bdxcdy - cdxbdy) - + bdz * (cdxady - adxcdy) - + cdz * (adxbdy - bdxady); - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) - + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) - + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); - errbound = o3derrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return orient3dadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* incirclefast() Approximate 2D incircle test. Nonrobust. */ -/* incircleexact() Exact 2D incircle test. Robust. */ -/* incircleslow() Another exact 2D incircle test. Robust. */ -/* incircle() Adaptive exact 2D incircle test. Robust. */ -/* */ -/* Return a positive value if the point pd lies inside the */ -/* circle passing through pa, pb, and pc; a negative value if */ -/* it lies outside; and zero if the four points are cocircular.*/ -/* The points pa, pb, and pc must be in counterclockwise */ -/* order, or the sign of the result will be reversed. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In incircle() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, incircle() is usually quite */ -/* fast, but will run more slowly when the input points are cocircular or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL incirclefast(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - REAL adx, ady, bdx, bdy, cdx, cdy; - REAL abdet, bcdet, cadet; - REAL alift, blift, clift; - - adx = pa[0] - pd[0]; - ady = pa[1] - pd[1]; - bdx = pb[0] - pd[0]; - bdy = pb[1] - pd[1]; - cdx = pc[0] - pd[0]; - cdy = pc[1] - pd[1]; - - abdet = adx * bdy - bdx * ady; - bcdet = bdx * cdy - cdx * bdy; - cadet = cdx * ady - adx * cdy; - alift = adx * adx + ady * ady; - blift = bdx * bdx + bdy * bdy; - clift = cdx * cdx + cdy * cdy; - - return alift * bcdet + blift * cadet + clift * abdet; -} - -REAL incircleexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; - INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; - REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; - REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - REAL temp8[8]; - int templen; - REAL abc[12], bcd[12], cda[12], dab[12]; - int abclen, bcdlen, cdalen, dablen; - REAL det24x[24], det24y[24], det48x[48], det48y[48]; - int xlen, ylen; - REAL adet[96], bdet[96], cdet[96], ddet[96]; - int alen, blen, clen, dlen; - REAL abdet[192], cddet[192]; - int ablen, cdlen; - REAL deter[384]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); - cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); - templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); - dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); - for (i = 0; i < 4; i++) { - bd[i] = -bd[i]; - ac[i] = -ac[i]; - } - templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); - abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); - templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); - bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); - - xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x); - ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y); - alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet); - - xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x); - ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y); - blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet); - - xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x); - ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y); - clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet); - - xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x); - xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x); - ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y); - ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y); - dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL incircleslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; - REAL adxtail, bdxtail, cdxtail; - REAL adytail, bdytail, cdytail; - REAL negate, negatetail; - INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; - REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; - REAL temp16[16]; - int temp16len; - REAL detx[32], detxx[64], detxt[32], detxxt[64], detxtxt[64]; - int xlen, xxlen, xtlen, xxtlen, xtxtlen; - REAL x1[128], x2[192]; - int x1len, x2len; - REAL dety[32], detyy[64], detyt[32], detyyt[64], detytyt[64]; - int ylen, yylen, ytlen, yytlen, ytytlen; - REAL y1[128], y2[192]; - int y1len, y2len; - REAL adet[384], bdet[384], cdet[384], abdet[768], deter[1152]; - int alen, blen, clen, ablen, deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pd[0], adx, adxtail); - Two_Diff(pa[1], pd[1], ady, adytail); - Two_Diff(pb[0], pd[0], bdx, bdxtail); - Two_Diff(pb[1], pd[1], bdy, bdytail); - Two_Diff(pc[0], pd[0], cdx, cdxtail); - Two_Diff(pc[1], pd[1], cdy, cdytail); - - Two_Two_Product(adx, adxtail, bdy, bdytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -ady; - negatetail = -adytail; - Two_Two_Product(bdx, bdxtail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - Two_Two_Product(bdx, bdxtail, cdy, cdytail, - bxcy7, bxcy[6], bxcy[5], bxcy[4], - bxcy[3], bxcy[2], bxcy[1], bxcy[0]); - bxcy[7] = bxcy7; - negate = -bdy; - negatetail = -bdytail; - Two_Two_Product(cdx, cdxtail, negate, negatetail, - cxby7, cxby[6], cxby[5], cxby[4], - cxby[3], cxby[2], cxby[1], cxby[0]); - cxby[7] = cxby7; - Two_Two_Product(cdx, cdxtail, ady, adytail, - cxay7, cxay[6], cxay[5], cxay[4], - cxay[3], cxay[2], cxay[1], cxay[0]); - cxay[7] = cxay7; - negate = -cdy; - negatetail = -cdytail; - Two_Two_Product(adx, adxtail, negate, negatetail, - axcy7, axcy[6], axcy[5], axcy[4], - axcy[3], axcy[2], axcy[1], axcy[0]); - axcy[7] = axcy7; - - - temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); - - xlen = scale_expansion_zeroelim(temp16len, temp16, adx, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, adx, detxx); - xtlen = scale_expansion_zeroelim(temp16len, temp16, adxtail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, adx, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, adxtail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - - ylen = scale_expansion_zeroelim(temp16len, temp16, ady, dety); - yylen = scale_expansion_zeroelim(ylen, dety, ady, detyy); - ytlen = scale_expansion_zeroelim(temp16len, temp16, adytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, ady, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, adytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - - alen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, adet); - - - temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); - - xlen = scale_expansion_zeroelim(temp16len, temp16, bdx, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, bdx, detxx); - xtlen = scale_expansion_zeroelim(temp16len, temp16, bdxtail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, bdx, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bdxtail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - - ylen = scale_expansion_zeroelim(temp16len, temp16, bdy, dety); - yylen = scale_expansion_zeroelim(ylen, dety, bdy, detyy); - ytlen = scale_expansion_zeroelim(temp16len, temp16, bdytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, bdy, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, bdytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - - blen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, bdet); - - - temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); - - xlen = scale_expansion_zeroelim(temp16len, temp16, cdx, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, cdx, detxx); - xtlen = scale_expansion_zeroelim(temp16len, temp16, cdxtail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, cdx, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cdxtail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - - ylen = scale_expansion_zeroelim(temp16len, temp16, cdy, dety); - yylen = scale_expansion_zeroelim(ylen, dety, cdy, detyy); - ytlen = scale_expansion_zeroelim(temp16len, temp16, cdytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, cdy, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, cdytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - - clen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); - - return deter[deterlen - 1]; -} - -REAL incircleadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL permanent) -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; - REAL det, errbound; - - INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - INEXACT REAL bc3, ca3, ab3; - REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; - int axbclen, axxbclen, aybclen, ayybclen, alen; - REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; - int bxcalen, bxxcalen, bycalen, byycalen, blen; - REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; - int cxablen, cxxablen, cyablen, cyyablen, clen; - REAL abdet[64]; - int ablen; - REAL fin1[1152], fin2[1152]; - REAL *finnow, *finother, *finswap; - int finlength; - - REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; - INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; - REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; - REAL aa[4], bb[4], cc[4]; - INEXACT REAL aa3, bb3, cc3; - INEXACT REAL ti1, tj1; - REAL ti0, tj0; - REAL u[4], v[4]; - INEXACT REAL u3, v3; - REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; - REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; - int temp8len, temp16alen, temp16blen, temp16clen; - int temp32alen, temp32blen, temp48len, temp64len; - REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; - int axtbblen, axtcclen, aytbblen, aytcclen; - REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; - int bxtaalen, bxtcclen, bytaalen, bytcclen; - REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; - int cxtaalen, cxtbblen, cytaalen, cytbblen; - REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; - int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen; - REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; - int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen; - REAL axtbctt[8], aytbctt[8], bxtcatt[8]; - REAL bytcatt[8], cxtabtt[8], cytabtt[8]; - int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen; - REAL abt[8], bct[8], cat[8]; - int abtlen, bctlen, catlen; - REAL abtt[4], bctt[4], catt[4]; - int abttlen, bcttlen, cattlen; - INEXACT REAL abtt3, bctt3, catt3; - REAL negate; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); - axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); - aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); - ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); - alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); - bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); - bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); - byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); - blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); - cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); - cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); - cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); - clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = iccerrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { - return det; - } - - errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); - det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) - + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) - + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Square(adx, adxadx1, adxadx0); - Square(ady, adyady1, adyady0); - Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); - aa[3] = aa3; - } - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Square(bdx, bdxbdx1, bdxbdx0); - Square(bdy, bdybdy1, bdybdy0); - Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); - bb[3] = bb3; - } - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Square(cdx, cdxcdx1, cdxcdx0); - Square(cdy, cdycdy1, cdycdy0); - Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); - cc[3] = cc3; - } - - if (adxtail != 0.0) { - axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, - temp16a); - - axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); - temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); - - axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); - temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, - temp16a); - - aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); - temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); - - aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); - temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdxtail != 0.0) { - bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, - temp16a); - - bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); - temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); - - bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); - temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, - temp16a); - - bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); - temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); - - bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); - temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdxtail != 0.0) { - cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, - temp16a); - - cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); - temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); - - cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); - temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); - temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, - temp16a); - - cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); - temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); - - cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); - temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if ((adxtail != 0.0) || (adytail != 0.0)) { - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Two_Product(bdxtail, cdy, ti1, ti0); - Two_Product(bdx, cdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -bdy; - Two_Product(cdxtail, negate, ti1, ti0); - negate = -bdytail; - Two_Product(cdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); - - Two_Product(bdxtail, cdytail, ti1, ti0); - Two_Product(cdxtail, bdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); - bctt[3] = bctt3; - bcttlen = 4; - } else { - bct[0] = 0.0; - bctlen = 1; - bctt[0] = 0.0; - bcttlen = 1; - } - - if (adxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); - axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, - temp32a); - axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); - temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, - temp16a); - temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); - aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, - temp32a); - aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); - temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, - temp16a); - temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((bdxtail != 0.0) || (bdytail != 0.0)) { - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Two_Product(cdxtail, ady, ti1, ti0); - Two_Product(cdx, adytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -cdy; - Two_Product(adxtail, negate, ti1, ti0); - negate = -cdytail; - Two_Product(adx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); - - Two_Product(cdxtail, adytail, ti1, ti0); - Two_Product(adxtail, cdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); - catt[3] = catt3; - cattlen = 4; - } else { - cat[0] = 0.0; - catlen = 1; - catt[0] = 0.0; - cattlen = 1; - } - - if (bdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); - bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, - temp32a); - bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); - temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, - temp16a); - temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); - bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, - temp32a); - bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); - temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, - temp16a); - temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((cdxtail != 0.0) || (cdytail != 0.0)) { - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Two_Product(adxtail, bdy, ti1, ti0); - Two_Product(adx, bdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -ady; - Two_Product(bdxtail, negate, ti1, ti0); - negate = -adytail; - Two_Product(bdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); - - Two_Product(adxtail, bdytail, ti1, ti0); - Two_Product(bdxtail, adytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); - abtt[3] = abtt3; - abttlen = 4; - } else { - abt[0] = 0.0; - abtlen = 1; - abtt[0] = 0.0; - abttlen = 1; - } - - if (cdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); - cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, - temp32a); - cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); - temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, - temp16a); - temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); - cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, - temp32a); - cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); - temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, - temp16a); - temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - - return finnow[finlength - 1]; -} - -REAL incircle(REAL *pa, REAL *pb, REAL *pc, REAL *pd) -{ - REAL adx, bdx, cdx, ady, bdy, cdy; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL alift, blift, clift; - REAL det; - REAL permanent, errbound; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - alift = adx * adx + ady * ady; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - blift = bdx * bdx + bdy * bdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - clift = cdx * cdx + cdy * cdy; - - det = alift * (bdxcdy - cdxbdy) - + blift * (cdxady - adxcdy) - + clift * (adxbdy - bdxady); - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift - + (Absolute(cdxady) + Absolute(adxcdy)) * blift - + (Absolute(adxbdy) + Absolute(bdxady)) * clift; - errbound = iccerrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return incircleadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* inspherefast() Approximate 3D insphere test. Nonrobust. */ -/* insphereexact() Exact 3D insphere test. Robust. */ -/* insphereslow() Another exact 3D insphere test. Robust. */ -/* insphere() Adaptive exact 3D insphere test. Robust. */ -/* */ -/* Return a positive value if the point pe lies inside the */ -/* sphere passing through pa, pb, pc, and pd; a negative value */ -/* if it lies outside; and zero if the five points are */ -/* cospherical. The points pa, pb, pc, and pd must be ordered */ -/* so that they have a positive orientation (as defined by */ -/* orient3d()), or the sign of the result will be reversed. */ -/* */ -/* Only the first and last routine should be used; the middle two are for */ -/* timings. */ -/* */ -/* The last three use exact arithmetic to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. In insphere() only, */ -/* this determinant is computed adaptively, in the sense that exact */ -/* arithmetic is used only to the degree it is needed to ensure that the */ -/* returned value has the correct sign. Hence, insphere() is usually quite */ -/* fast, but will run more slowly when the input points are cospherical or */ -/* nearly so. */ -/* */ -/*****************************************************************************/ - -REAL inspherefast(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) -{ - REAL aex, bex, cex, dex; - REAL aey, bey, cey, dey; - REAL aez, bez, cez, dez; - REAL alift, blift, clift, dlift; - REAL ab, bc, cd, da, ac, bd; - REAL abc, bcd, cda, dab; - - aex = pa[0] - pe[0]; - bex = pb[0] - pe[0]; - cex = pc[0] - pe[0]; - dex = pd[0] - pe[0]; - aey = pa[1] - pe[1]; - bey = pb[1] - pe[1]; - cey = pc[1] - pe[1]; - dey = pd[1] - pe[1]; - aez = pa[2] - pe[2]; - bez = pb[2] - pe[2]; - cez = pc[2] - pe[2]; - dez = pd[2] - pe[2]; - - ab = aex * bey - bex * aey; - bc = bex * cey - cex * bey; - cd = cex * dey - dex * cey; - da = dex * aey - aex * dey; - - ac = aex * cey - cex * aey; - bd = bex * dey - dex * bey; - - abc = aez * bc - bez * ac + cez * ab; - bcd = bez * cd - cez * bd + dez * bc; - cda = cez * da + dez * ac + aez * cd; - dab = dez * ab + aez * bd + bez * da; - - alift = aex * aex + aey * aey + aez * aez; - blift = bex * bex + bey * bey + bez * bez; - clift = cex * cex + cey * cey + cez * cez; - dlift = dex * dex + dey * dey + dez * dez; - - return (dlift * abc - clift * dab) + (blift * cda - alift * bcd); -} - -REAL insphereexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) -{ - INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1; - INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1; - INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1; - INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1; - REAL axby0, bxcy0, cxdy0, dxey0, exay0; - REAL bxay0, cxby0, dxcy0, exdy0, axey0; - REAL axcy0, bxdy0, cxey0, dxay0, exby0; - REAL cxay0, dxby0, excy0, axdy0, bxey0; - REAL ab[4], bc[4], cd[4], de[4], ea[4]; - REAL ac[4], bd[4], ce[4], da[4], eb[4]; - REAL temp8a[8], temp8b[8], temp16[16]; - int temp8alen, temp8blen, temp16len; - REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; - REAL abd[24], bce[24], cda[24], deb[24], eac[24]; - int abclen, bcdlen, cdelen, dealen, eablen; - int abdlen, bcelen, cdalen, deblen, eaclen; - REAL temp48a[48], temp48b[48]; - int temp48alen, temp48blen; - REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; - int abcdlen, bcdelen, cdealen, deablen, eabclen; - REAL temp192[192]; - REAL det384x[384], det384y[384], det384z[384]; - int xlen, ylen, zlen; - REAL detxy[768]; - int xylen; - REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; - int alen, blen, clen, dlen, elen; - REAL abdet[2304], cddet[2304], cdedet[3456]; - int ablen, cdlen; - REAL deter[5760]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - Two_Product(pa[0], pb[1], axby1, axby0); - Two_Product(pb[0], pa[1], bxay1, bxay0); - Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); - - Two_Product(pb[0], pc[1], bxcy1, bxcy0); - Two_Product(pc[0], pb[1], cxby1, cxby0); - Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); - - Two_Product(pc[0], pd[1], cxdy1, cxdy0); - Two_Product(pd[0], pc[1], dxcy1, dxcy0); - Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); - - Two_Product(pd[0], pe[1], dxey1, dxey0); - Two_Product(pe[0], pd[1], exdy1, exdy0); - Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); - - Two_Product(pe[0], pa[1], exay1, exay0); - Two_Product(pa[0], pe[1], axey1, axey0); - Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); - - Two_Product(pa[0], pc[1], axcy1, axcy0); - Two_Product(pc[0], pa[1], cxay1, cxay0); - Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); - - Two_Product(pb[0], pd[1], bxdy1, bxdy0); - Two_Product(pd[0], pb[1], dxby1, dxby0); - Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); - - Two_Product(pc[0], pe[1], cxey1, cxey0); - Two_Product(pe[0], pc[1], excy1, excy0); - Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); - - Two_Product(pd[0], pa[1], dxay1, dxay0); - Two_Product(pa[0], pd[1], axdy1, axdy0); - Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); - - Two_Product(pe[0], pb[1], exby1, exby0); - Two_Product(pb[0], pe[1], bxey1, bxey0); - Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); - - temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); - abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abc); - - temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); - bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bcd); - - temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); - cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cde); - - temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); - dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - dea); - - temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); - eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eab); - - temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); - abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - abd); - - temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); - bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - bce); - - temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); - cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - cda); - - temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); - deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - deb); - - temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); - temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, - temp16); - temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); - eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, - eac); - - temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); - temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, bcde); - xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); - ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); - zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); - - temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); - temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, cdea); - xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); - ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); - zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); - - temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); - temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, deab); - xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); - ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); - zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); - - temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); - temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, eabc); - xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); - ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); - zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); - - temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); - temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); - for (i = 0; i < temp48blen; i++) { - temp48b[i] = -temp48b[i]; - } - abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, - temp48blen, temp48b, abcd); - xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); - xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); - ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); - ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); - zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); - zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); - xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); - elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); - - return deter[deterlen - 1]; -} - -REAL insphereslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) -{ - INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; - REAL aextail, bextail, cextail, dextail; - REAL aeytail, beytail, ceytail, deytail; - REAL aeztail, beztail, ceztail, deztail; - REAL negate, negatetail; - INEXACT REAL axby7, bxcy7, cxdy7, dxay7, axcy7, bxdy7; - INEXACT REAL bxay7, cxby7, dxcy7, axdy7, cxay7, dxby7; - REAL axby[8], bxcy[8], cxdy[8], dxay[8], axcy[8], bxdy[8]; - REAL bxay[8], cxby[8], dxcy[8], axdy[8], cxay[8], dxby[8]; - REAL ab[16], bc[16], cd[16], da[16], ac[16], bd[16]; - int ablen, bclen, cdlen, dalen, aclen, bdlen; - REAL temp32a[32], temp32b[32], temp64a[64], temp64b[64], temp64c[64]; - int temp32alen, temp32blen, temp64alen, temp64blen, temp64clen; - REAL temp128[128], temp192[192]; - int temp128len, temp192len; - REAL detx[384], detxx[768], detxt[384], detxxt[768], detxtxt[768]; - int xlen, xxlen, xtlen, xxtlen, xtxtlen; - REAL x1[1536], x2[2304]; - int x1len, x2len; - REAL dety[384], detyy[768], detyt[384], detyyt[768], detytyt[768]; - int ylen, yylen, ytlen, yytlen, ytytlen; - REAL y1[1536], y2[2304]; - int y1len, y2len; - REAL detz[384], detzz[768], detzt[384], detzzt[768], detztzt[768]; - int zlen, zzlen, ztlen, zztlen, ztztlen; - REAL z1[1536], z2[2304]; - int z1len, z2len; - REAL detxy[4608]; - int xylen; - REAL adet[6912], bdet[6912], cdet[6912], ddet[6912]; - int alen, blen, clen, dlen; - REAL abdet[13824], cddet[13824], deter[27648]; - int deterlen; - int i; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k, _l, _m, _n; - REAL _0, _1, _2; - - Two_Diff(pa[0], pe[0], aex, aextail); - Two_Diff(pa[1], pe[1], aey, aeytail); - Two_Diff(pa[2], pe[2], aez, aeztail); - Two_Diff(pb[0], pe[0], bex, bextail); - Two_Diff(pb[1], pe[1], bey, beytail); - Two_Diff(pb[2], pe[2], bez, beztail); - Two_Diff(pc[0], pe[0], cex, cextail); - Two_Diff(pc[1], pe[1], cey, ceytail); - Two_Diff(pc[2], pe[2], cez, ceztail); - Two_Diff(pd[0], pe[0], dex, dextail); - Two_Diff(pd[1], pe[1], dey, deytail); - Two_Diff(pd[2], pe[2], dez, deztail); - - Two_Two_Product(aex, aextail, bey, beytail, - axby7, axby[6], axby[5], axby[4], - axby[3], axby[2], axby[1], axby[0]); - axby[7] = axby7; - negate = -aey; - negatetail = -aeytail; - Two_Two_Product(bex, bextail, negate, negatetail, - bxay7, bxay[6], bxay[5], bxay[4], - bxay[3], bxay[2], bxay[1], bxay[0]); - bxay[7] = bxay7; - ablen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, ab); - Two_Two_Product(bex, bextail, cey, ceytail, - bxcy7, bxcy[6], bxcy[5], bxcy[4], - bxcy[3], bxcy[2], bxcy[1], bxcy[0]); - bxcy[7] = bxcy7; - negate = -bey; - negatetail = -beytail; - Two_Two_Product(cex, cextail, negate, negatetail, - cxby7, cxby[6], cxby[5], cxby[4], - cxby[3], cxby[2], cxby[1], cxby[0]); - cxby[7] = cxby7; - bclen = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, bc); - Two_Two_Product(cex, cextail, dey, deytail, - cxdy7, cxdy[6], cxdy[5], cxdy[4], - cxdy[3], cxdy[2], cxdy[1], cxdy[0]); - cxdy[7] = cxdy7; - negate = -cey; - negatetail = -ceytail; - Two_Two_Product(dex, dextail, negate, negatetail, - dxcy7, dxcy[6], dxcy[5], dxcy[4], - dxcy[3], dxcy[2], dxcy[1], dxcy[0]); - dxcy[7] = dxcy7; - cdlen = fast_expansion_sum_zeroelim(8, cxdy, 8, dxcy, cd); - Two_Two_Product(dex, dextail, aey, aeytail, - dxay7, dxay[6], dxay[5], dxay[4], - dxay[3], dxay[2], dxay[1], dxay[0]); - dxay[7] = dxay7; - negate = -dey; - negatetail = -deytail; - Two_Two_Product(aex, aextail, negate, negatetail, - axdy7, axdy[6], axdy[5], axdy[4], - axdy[3], axdy[2], axdy[1], axdy[0]); - axdy[7] = axdy7; - dalen = fast_expansion_sum_zeroelim(8, dxay, 8, axdy, da); - Two_Two_Product(aex, aextail, cey, ceytail, - axcy7, axcy[6], axcy[5], axcy[4], - axcy[3], axcy[2], axcy[1], axcy[0]); - axcy[7] = axcy7; - negate = -aey; - negatetail = -aeytail; - Two_Two_Product(cex, cextail, negate, negatetail, - cxay7, cxay[6], cxay[5], cxay[4], - cxay[3], cxay[2], cxay[1], cxay[0]); - cxay[7] = cxay7; - aclen = fast_expansion_sum_zeroelim(8, axcy, 8, cxay, ac); - Two_Two_Product(bex, bextail, dey, deytail, - bxdy7, bxdy[6], bxdy[5], bxdy[4], - bxdy[3], bxdy[2], bxdy[1], bxdy[0]); - bxdy[7] = bxdy7; - negate = -bey; - negatetail = -beytail; - Two_Two_Product(dex, dextail, negate, negatetail, - dxby7, dxby[6], dxby[5], dxby[4], - dxby[3], dxby[2], dxby[1], dxby[0]); - dxby[7] = dxby7; - bdlen = fast_expansion_sum_zeroelim(8, bxdy, 8, dxby, bd); - - temp32alen = scale_expansion_zeroelim(cdlen, cd, -bez, temp32a); - temp32blen = scale_expansion_zeroelim(cdlen, cd, -beztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(bdlen, bd, cez, temp32a); - temp32blen = scale_expansion_zeroelim(bdlen, bd, ceztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(bclen, bc, -dez, temp32a); - temp32blen = scale_expansion_zeroelim(bclen, bc, -deztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, aex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, aex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, aextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, aex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, aextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, aey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, aey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, aeytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, aey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, aeytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, aez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, aez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, aeztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, aez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, aeztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - alen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, adet); - - temp32alen = scale_expansion_zeroelim(dalen, da, cez, temp32a); - temp32blen = scale_expansion_zeroelim(dalen, da, ceztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(aclen, ac, dez, temp32a); - temp32blen = scale_expansion_zeroelim(aclen, ac, deztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(cdlen, cd, aez, temp32a); - temp32blen = scale_expansion_zeroelim(cdlen, cd, aeztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, bex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, bex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, bextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, bex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, bey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, bey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, beytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, bey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, beytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, bez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, bez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, beztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, bez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, beztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - blen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, bdet); - - temp32alen = scale_expansion_zeroelim(ablen, ab, -dez, temp32a); - temp32blen = scale_expansion_zeroelim(ablen, ab, -deztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(bdlen, bd, -aez, temp32a); - temp32blen = scale_expansion_zeroelim(bdlen, bd, -aeztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(dalen, da, -bez, temp32a); - temp32blen = scale_expansion_zeroelim(dalen, da, -beztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, cex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, cex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, cextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, cex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, cey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, cey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, ceytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, cey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, ceytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, cez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, cez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, ceztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, cez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, ceztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - clen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, cdet); - - temp32alen = scale_expansion_zeroelim(bclen, bc, aez, temp32a); - temp32blen = scale_expansion_zeroelim(bclen, bc, aeztail, temp32b); - temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64a); - temp32alen = scale_expansion_zeroelim(aclen, ac, -bez, temp32a); - temp32blen = scale_expansion_zeroelim(aclen, ac, -beztail, temp32b); - temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64b); - temp32alen = scale_expansion_zeroelim(ablen, ab, cez, temp32a); - temp32blen = scale_expansion_zeroelim(ablen, ab, ceztail, temp32b); - temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64c); - temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, - temp64blen, temp64b, temp128); - temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, - temp128len, temp128, temp192); - xlen = scale_expansion_zeroelim(temp192len, temp192, dex, detx); - xxlen = scale_expansion_zeroelim(xlen, detx, dex, detxx); - xtlen = scale_expansion_zeroelim(temp192len, temp192, dextail, detxt); - xxtlen = scale_expansion_zeroelim(xtlen, detxt, dex, detxxt); - for (i = 0; i < xxtlen; i++) { - detxxt[i] *= 2.0; - } - xtxtlen = scale_expansion_zeroelim(xtlen, detxt, dextail, detxtxt); - x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); - x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); - ylen = scale_expansion_zeroelim(temp192len, temp192, dey, dety); - yylen = scale_expansion_zeroelim(ylen, dety, dey, detyy); - ytlen = scale_expansion_zeroelim(temp192len, temp192, deytail, detyt); - yytlen = scale_expansion_zeroelim(ytlen, detyt, dey, detyyt); - for (i = 0; i < yytlen; i++) { - detyyt[i] *= 2.0; - } - ytytlen = scale_expansion_zeroelim(ytlen, detyt, deytail, detytyt); - y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); - y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); - zlen = scale_expansion_zeroelim(temp192len, temp192, dez, detz); - zzlen = scale_expansion_zeroelim(zlen, detz, dez, detzz); - ztlen = scale_expansion_zeroelim(temp192len, temp192, deztail, detzt); - zztlen = scale_expansion_zeroelim(ztlen, detzt, dez, detzzt); - for (i = 0; i < zztlen; i++) { - detzzt[i] *= 2.0; - } - ztztlen = scale_expansion_zeroelim(ztlen, detzt, deztail, detztzt); - z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); - z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); - xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); - dlen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); - - return deter[deterlen - 1]; -} - -REAL insphereadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe, - REAL permanent) -{ - INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; - REAL det, errbound; - - INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1; - INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1; - INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1; - REAL aexbey0, bexaey0, bexcey0, cexbey0; - REAL cexdey0, dexcey0, dexaey0, aexdey0; - REAL aexcey0, cexaey0, bexdey0, dexbey0; - REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; - INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3; - REAL abeps, bceps, cdeps, daeps, aceps, bdeps; - REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; - int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len; - REAL xdet[96], ydet[96], zdet[96], xydet[192]; - int xlen, ylen, zlen, xylen; - REAL adet[288], bdet[288], cdet[288], ddet[288]; - int alen, blen, clen, dlen; - REAL abdet[576], cddet[576]; - int ablen, cdlen; - REAL fin1[1152]; - int finlength; - - REAL aextail, bextail, cextail, dextail; - REAL aeytail, beytail, ceytail, deytail; - REAL aeztail, beztail, ceztail, deztail; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - aex = (REAL) (pa[0] - pe[0]); - bex = (REAL) (pb[0] - pe[0]); - cex = (REAL) (pc[0] - pe[0]); - dex = (REAL) (pd[0] - pe[0]); - aey = (REAL) (pa[1] - pe[1]); - bey = (REAL) (pb[1] - pe[1]); - cey = (REAL) (pc[1] - pe[1]); - dey = (REAL) (pd[1] - pe[1]); - aez = (REAL) (pa[2] - pe[2]); - bez = (REAL) (pb[2] - pe[2]); - cez = (REAL) (pc[2] - pe[2]); - dez = (REAL) (pd[2] - pe[2]); - - Two_Product(aex, bey, aexbey1, aexbey0); - Two_Product(bex, aey, bexaey1, bexaey0); - Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - - Two_Product(bex, cey, bexcey1, bexcey0); - Two_Product(cex, bey, cexbey1, cexbey0); - Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - - Two_Product(cex, dey, cexdey1, cexdey0); - Two_Product(dex, cey, dexcey1, dexcey0); - Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); - cd[3] = cd3; - - Two_Product(dex, aey, dexaey1, dexaey0); - Two_Product(aex, dey, aexdey1, aexdey0); - Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); - da[3] = da3; - - Two_Product(aex, cey, aexcey1, aexcey0); - Two_Product(cex, aey, cexaey1, cexaey0); - Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); - ac[3] = ac3; - - Two_Product(bex, dey, bexdey1, bexdey0); - Two_Product(dex, bey, dexbey1, dexbey0); - Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); - bd[3] = bd3; - - temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); - temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); - - temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); - temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); - - temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); - temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); - temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); - - temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); - temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); - temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); - temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, - temp8blen, temp8b, temp16); - temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, - temp16len, temp16, temp24); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); - xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); - ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); - temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); - zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); - xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); - dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); - - det = estimate(finlength, fin1); - errbound = isperrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pe[0], aex, aextail); - Two_Diff_Tail(pa[1], pe[1], aey, aeytail); - Two_Diff_Tail(pa[2], pe[2], aez, aeztail); - Two_Diff_Tail(pb[0], pe[0], bex, bextail); - Two_Diff_Tail(pb[1], pe[1], bey, beytail); - Two_Diff_Tail(pb[2], pe[2], bez, beztail); - Two_Diff_Tail(pc[0], pe[0], cex, cextail); - Two_Diff_Tail(pc[1], pe[1], cey, ceytail); - Two_Diff_Tail(pc[2], pe[2], cez, ceztail); - Two_Diff_Tail(pd[0], pe[0], dex, dextail); - Two_Diff_Tail(pd[1], pe[1], dey, deytail); - Two_Diff_Tail(pd[2], pe[2], dez, deztail); - if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) - && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) - && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) - && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { - return det; - } - - errbound = isperrboundC * permanent + resulterrbound * Absolute(det); - abeps = (aex * beytail + bey * aextail) - - (aey * bextail + bex * aeytail); - bceps = (bex * ceytail + cey * bextail) - - (bey * cextail + cex * beytail); - cdeps = (cex * deytail + dey * cextail) - - (cey * dextail + dex * ceytail); - daeps = (dex * aeytail + aey * dextail) - - (dey * aextail + aex * deytail); - aceps = (aex * ceytail + cey * aextail) - - (aey * cextail + cex * aeytail); - bdeps = (bex * deytail + dey * bextail) - - (bey * dextail + dex * beytail); - det += (((bex * bex + bey * bey + bez * bez) - * ((cez * daeps + dez * aceps + aez * cdeps) - + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) - + (dex * dex + dey * dey + dez * dez) - * ((aez * bceps - bez * aceps + cez * abeps) - + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) - - ((aex * aex + aey * aey + aez * aez) - * ((bez * cdeps - cez * bdeps + dez * bceps) - + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) - + (cex * cex + cey * cey + cez * cez) - * ((dez * abeps + aez * bdeps + bez * daeps) - + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) - + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) - * (cez * da3 + dez * ac3 + aez * cd3) - + (dex * dextail + dey * deytail + dez * deztail) - * (aez * bc3 - bez * ac3 + cez * ab3)) - - ((aex * aextail + aey * aeytail + aez * aeztail) - * (bez * cd3 - cez * bd3 + dez * bc3) - + (cex * cextail + cey * ceytail + cez * ceztail) - * (dez * ab3 + aez * bd3 + bez * da3))); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return insphereexact(pa, pb, pc, pd, pe); -} - -REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) -{ - REAL aex, bex, cex, dex; - REAL aey, bey, cey, dey; - REAL aez, bez, cez, dez; - REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; - REAL aexcey, cexaey, bexdey, dexbey; - REAL alift, blift, clift, dlift; - REAL ab, bc, cd, da, ac, bd; - REAL abc, bcd, cda, dab; - REAL aezplus, bezplus, cezplus, dezplus; - REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; - REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; - REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; - REAL det; - REAL permanent, errbound; - - aex = pa[0] - pe[0]; - bex = pb[0] - pe[0]; - cex = pc[0] - pe[0]; - dex = pd[0] - pe[0]; - aey = pa[1] - pe[1]; - bey = pb[1] - pe[1]; - cey = pc[1] - pe[1]; - dey = pd[1] - pe[1]; - aez = pa[2] - pe[2]; - bez = pb[2] - pe[2]; - cez = pc[2] - pe[2]; - dez = pd[2] - pe[2]; - - aexbey = aex * bey; - bexaey = bex * aey; - ab = aexbey - bexaey; - bexcey = bex * cey; - cexbey = cex * bey; - bc = bexcey - cexbey; - cexdey = cex * dey; - dexcey = dex * cey; - cd = cexdey - dexcey; - dexaey = dex * aey; - aexdey = aex * dey; - da = dexaey - aexdey; - - aexcey = aex * cey; - cexaey = cex * aey; - ac = aexcey - cexaey; - bexdey = bex * dey; - dexbey = dex * bey; - bd = bexdey - dexbey; - - abc = aez * bc - bez * ac + cez * ab; - bcd = bez * cd - cez * bd + dez * bc; - cda = cez * da + dez * ac + aez * cd; - dab = dez * ab + aez * bd + bez * da; - - alift = aex * aex + aey * aey + aez * aez; - blift = bex * bex + bey * bey + bez * bez; - clift = cex * cex + cey * cey + cez * cez; - dlift = dex * dex + dey * dey + dez * dez; - - det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); - - aezplus = Absolute(aez); - bezplus = Absolute(bez); - cezplus = Absolute(cez); - dezplus = Absolute(dez); - aexbeyplus = Absolute(aexbey); - bexaeyplus = Absolute(bexaey); - bexceyplus = Absolute(bexcey); - cexbeyplus = Absolute(cexbey); - cexdeyplus = Absolute(cexdey); - dexceyplus = Absolute(dexcey); - dexaeyplus = Absolute(dexaey); - aexdeyplus = Absolute(aexdey); - aexceyplus = Absolute(aexcey); - cexaeyplus = Absolute(cexaey); - bexdeyplus = Absolute(bexdey); - dexbeyplus = Absolute(dexbey); - permanent = ((cexdeyplus + dexceyplus) * bezplus - + (dexbeyplus + bexdeyplus) * cezplus - + (bexceyplus + cexbeyplus) * dezplus) - * alift - + ((dexaeyplus + aexdeyplus) * cezplus - + (aexceyplus + cexaeyplus) * dezplus - + (cexdeyplus + dexceyplus) * aezplus) - * blift - + ((aexbeyplus + bexaeyplus) * dezplus - + (bexdeyplus + dexbeyplus) * aezplus - + (dexaeyplus + aexdeyplus) * bezplus) - * clift - + ((bexceyplus + cexbeyplus) * aezplus - + (cexaeyplus + aexceyplus) * bezplus - + (aexbeyplus + bexaeyplus) * cezplus) - * dlift; - errbound = isperrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return insphereadapt(pa, pb, pc, pd, pe, permanent); -} diff --git a/Tetgen/tetgen.cxx b/Tetgen/tetgen.cxx deleted file mode 100644 index 34721f2b83..0000000000 --- a/Tetgen/tetgen.cxx +++ /dev/null @@ -1,22807 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// // -// TetGen // -// // -// A Quality Tetrahedral Mesh Generator and 3D Delaunay Triangulator // -// // -// Version 1.3 // -// June 13, 2004 // -// // -// Copyright 2002, 2004 // -// Hang Si // -// Rathausstr. 9, 10178 Berlin, Germany // -// si@wias-berlin.de // -// // -// You can obtain TetGen via internet: http://tetgen.berlios.de. It may be // -// freely copied, modified, and redistributed under the copyright notices // -// given in the file LICENSE. // -// // -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetgen.cxx // -// // -// The C++ implementation file of the TetGen library. // -// // -/////////////////////////////////////////////////////////////////////////////// - -#include "tetgen.h" - -// -// Begin of class 'tetgenio' implementation -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// initialize() Initialize all variables of 'tetgenio'. // -// // -// It is called by the only class constructor 'tetgenio()' implicitly. Thus, // -// all variables are guaranteed to be initialized. Each array is initialized // -// to be a 'NULL' pointer, and its length is equal zero. Some variables have // -// their default value, 'firstnumber' equals zero, 'mesh_dim' equals 3, and // -// 'numberofcorners' equals 4. Another possible use of this routine is to // -// call it before to re-use an object. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::initialize() -{ - firstnumber = 0; // Default item index is numbered from Zero. - mesh_dim = 3; // Default mesh dimension is 3. - - pointlist = (REAL *) NULL; - pointattributelist = (REAL *) NULL; - addpointlist = (REAL *) NULL; - pointmarkerlist = (int *) NULL; - numberofpoints = 0; - numberofpointattributes = 0; - numberofaddpoints = 0; - - tetrahedronlist = (int *) NULL; - tetrahedronattributelist = (REAL *) NULL; - tetrahedronvolumelist = (REAL *) NULL; - neighborlist = (int *) NULL; - numberoftetrahedra = 0; - numberofcorners = 4; // Default is 4 nodes per element. - numberoftetrahedronattributes = 0; - - trifacelist = (int *) NULL; - trifacemarkerlist = (int *) NULL; - numberoftrifaces = 0; - - facetlist = (facet *) NULL; - facetmarkerlist = (int *) NULL; - numberoffacets = 0; - - edgelist = (int *) NULL; - edgemarkerlist = (int *) NULL; - numberofedges = 0; - - holelist = (REAL *) NULL; - numberofholes = 0; - - regionlist = (REAL *) NULL; - numberofregions = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// deinitialize() Free the memory allocated in 'tetgenio'. // -// // -// It is called by the class destructor '~tetgenio()' implicitly. Hence, the // -// occupied memory by arrays of an object will be automatically released on // -// the deletion of the object. However, this routine assumes that the memory // -// is allocated by C++ memory allocation operator 'new', thus it is freed by // -// the C++ array deletor 'delete []'. If one uses the C/C++ library function // -// 'malloc()' to allocate memory for arrays, one has to free them with the // -// 'free()' function, and call routine 'initialize()' once to disable this // -// routine on deletion of the object. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::deinitialize() -{ - if (pointlist != (REAL *) NULL) { - delete [] pointlist; - } - if (pointattributelist != (REAL *) NULL) { - delete [] pointattributelist; - } - if (addpointlist != (REAL *) NULL) { - delete [] addpointlist; - } - if (pointmarkerlist != (int *) NULL) { - delete [] pointmarkerlist; - } - - if (tetrahedronlist != (int *) NULL) { - delete [] tetrahedronlist; - } - if (tetrahedronattributelist != (REAL *) NULL) { - delete [] tetrahedronattributelist; - } - if (tetrahedronvolumelist != (REAL *) NULL) { - delete [] tetrahedronvolumelist; - } - if (neighborlist != (int *) NULL) { - delete [] neighborlist; - } - - if (trifacelist != (int *) NULL) { - delete [] trifacelist; - } - if (trifacemarkerlist != (int *) NULL) { - delete [] trifacemarkerlist; - } - - if (edgelist != (int *) NULL) { - delete [] edgelist; - } - if (edgemarkerlist != (int *) NULL) { - delete [] edgemarkerlist; - } - - if (facetlist != (facet *) NULL) { - facet *f; - polygon *p; - int i, j; - for (i = 0; i < numberoffacets; i++) { - f = &facetlist[i]; - for (j = 0; j < f->numberofpolygons; j++) { - p = &f->polygonlist[j]; - delete [] p->vertexlist; - } - delete [] f->polygonlist; - if (f->holelist != (REAL *) NULL) { - delete [] f->holelist; - } - } - delete [] facetlist; - } - if (facetmarkerlist != (int *) NULL) { - delete [] facetmarkerlist; - } - - if (holelist != (REAL *) NULL) { - delete [] holelist; - } - - if (regionlist != (REAL *) NULL) { - delete [] regionlist; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_node_call() Load a list of nodes. // -// // -// It is a support routine for routines: 'load_nodes()', 'load_poly()', and // -// 'load_tetmesh()'. 'infile' is the file handle contains the node list. It // -// may point to a .node, or .poly or .smesh file. 'markers' indicates each // -// node contains an additional marker (integer) or not. 'infilename' is the // -// name of the file being read, it is only appeared in error message. // -// // -// The 'firstnumber' (0 or 1) is automatically determined by the number of // -// the first index of the first point. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_node_call(FILE* infile, int markers, char* infilename) -{ - char inputline[INPUTLINESIZE]; - char *stringptr; - REAL x, y, z, attrib; - int firstnode, currentmarker; - int index, attribindex; - int i, j; - - // Initialize 'pointlist', 'pointattributelist', and 'pointmarkerlist'. - pointlist = new REAL[numberofpoints * mesh_dim]; - if (pointlist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - if (numberofpointattributes > 0) { - pointattributelist = new REAL[numberofpoints * numberofpointattributes]; - if (pointattributelist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - if (markers) { - pointmarkerlist = new int[numberofpoints]; - if (pointmarkerlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - - // Read the point section. - index = 0; - attribindex = 0; - for (i = 0; i < numberofpoints; i++) { - stringptr = readnumberline(inputline, infile, infilename); - if (i == 0) { - firstnode = (int) strtol (stringptr, &stringptr, 0); - if ((firstnode == 0) || (firstnode == 1)) { - firstnumber = firstnode; - } - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Point %d has no x coordinate.\n", firstnumber + i); - break; - } - x = (REAL) strtod(stringptr, &stringptr); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Point %d has no y coordinate.\n", firstnumber + i); - break; - } - y = (REAL) strtod(stringptr, &stringptr); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Point %d has no z coordinate.\n", firstnumber + i); - break; - } - z = (REAL) strtod(stringptr, &stringptr); - pointlist[index++] = x; - pointlist[index++] = y; - pointlist[index++] = z; - // Read the point attributes. - for (j = 0; j < numberofpointattributes; j++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - attrib = 0.0; - } else { - attrib = (REAL) strtod(stringptr, &stringptr); - } - pointattributelist[attribindex++] = attrib; - } - if (markers) { - // Read a point marker. - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - currentmarker = 0; - } else { - currentmarker = (int) strtol (stringptr, &stringptr, 0); - } - pointmarkerlist[i] = currentmarker; - } - } - if (i < numberofpoints) { - // Failed to read points due to some error. - delete [] pointlist; - pointlist = (REAL *) NULL; - if (markers) { - delete [] pointmarkerlist; - pointmarkerlist = (int *) NULL; - } - if (numberofpointattributes > 0) { - delete [] pointattributelist; - pointattributelist = (REAL *) NULL; - } - numberofpoints = 0; - return false; - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_node() Load a list of nodes from a .node file. // -// // -// 'filename' is the inputfile without suffix. The node list is in 'filename.// -// node'. On completion, the node list is returned in 'pointlist'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_node(char* filename) -{ - FILE *infile; - char innodefilename[FILENAMESIZE]; - char inputline[INPUTLINESIZE]; - char *stringptr; - int markers; - - // Assembling the actual file names we want to open. - strcpy(innodefilename, filename); - strcat(innodefilename, ".node"); - - // Try to open a .node file. - infile = fopen(innodefilename, "r"); - if (infile == (FILE *) NULL) { - printf("File I/O Error: Cannot access file %s.\n", innodefilename); - return false; - } - printf("Opening %s.\n", innodefilename); - // Read number of points, number of dimensions, number of point - // attributes, and number of boundary markers. - stringptr = readnumberline(inputline, infile, innodefilename); - numberofpoints = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - mesh_dim = 3; - } else { - mesh_dim = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - numberofpointattributes = 0; - } else { - numberofpointattributes = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - markers = 0; - } else { - markers = (int) strtol (stringptr, &stringptr, 0); - } - - if (mesh_dim != 3) { - printf("Error: load_node() only works for 3D points.\n"); - fclose(infile); - return false; - } - if (numberofpoints < 4) { - printf("File I/O error: There should have at least 4 points.\n"); - fclose(infile); - return false; - } - - // Load the list of nodes. - if (!load_node_call(infile, markers, innodefilename)) { - fclose(infile); - return false; - } - fclose(infile); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_addnodes() Load a list of additional nodes into 'addpointlists'. // -// // -// 'filename' is the filename of the original inputfile without suffix. The // -// additional nodes are found in file 'filename-a.node'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_addnodes(char* filename) -{ - FILE *infile; - char addnodefilename[FILENAMESIZE]; - char inputline[INPUTLINESIZE]; - char *stringptr; - REAL x, y, z; - int index; - int i; - - // Additional nodes are saved in file "filename-a.node". - strcpy(addnodefilename, filename); - strcat(addnodefilename, "-a.node"); - infile = fopen(addnodefilename, "r"); - if (infile != (FILE *) NULL) { - printf("Opening %s.\n", addnodefilename); - } else { - // Strange! However, it is not a fatal error. - printf("Warning: Can't opening %s. Skipped.\n", addnodefilename); - numberofaddpoints = 0; - return false; - } - - // Read the number of additional points. - stringptr = readnumberline(inputline, infile, addnodefilename); - numberofaddpoints = (int) strtol (stringptr, &stringptr, 0); - if (numberofaddpoints == 0) { - // It looks this file contains no point. - fclose(infile); - return false; - } - // Initialize 'addpointlist'; - addpointlist = new REAL[numberofaddpoints * mesh_dim]; - if (addpointlist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - - // Read the list of additional points. - index = 0; - for (i = 0; i < numberofaddpoints; i++) { - stringptr = readnumberline(inputline, infile, addnodefilename); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Point %d has no x coordinate.\n", firstnumber + i); - break; - } - x = (REAL) strtod(stringptr, &stringptr); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Point %d has no y coordinate.\n", firstnumber + i); - break; - } - y = (REAL) strtod(stringptr, &stringptr); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Point %d has no z coordinate.\n", firstnumber + i); - break; - } - z = (REAL) strtod(stringptr, &stringptr); - addpointlist[index++] = x; - addpointlist[index++] = y; - addpointlist[index++] = z; - } - fclose(infile); - - if (i < numberofaddpoints) { - // Failed to read to additional points due to some error. - delete [] addpointlist; - addpointlist = (REAL *) NULL; - numberofaddpoints = 0; - return false; - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_poly() Load a piecewise linear complex described in a .poly or // -// .smesh file. // -// // -// 'filename' is the inputfile without suffix. The PLC is in 'filename.poly' // -// or 'filename.smesh', and possibly plus 'filename.node' (when the first // -// line of the file starts with a zero). On completion, the PLC is returned // -// in 'pointlist', 'facetlist', 'holelist' and 'regionlist'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_poly(char* filename) -{ - FILE *infile, *polyfile; - char innodefilename[FILENAMESIZE]; - char inpolyfilename[FILENAMESIZE]; - char insmeshfilename[FILENAMESIZE]; - char inputline[INPUTLINESIZE]; - char *stringptr, *infilename; - int smesh, markers, currentmarker; - int readnodefile, index; - int i, j, k; - - // Assembling the actual file names we want to open. - strcpy(innodefilename, filename); - strcpy(inpolyfilename, filename); - strcpy(insmeshfilename, filename); - strcat(innodefilename, ".node"); - strcat(inpolyfilename, ".poly"); - strcat(insmeshfilename, ".smesh"); - - // First assume it is a .poly file. - smesh = 0; - // Try to open a .poly file. - polyfile = fopen(inpolyfilename, "r"); - if (polyfile == (FILE *) NULL) { - // .poly doesn't exist! Try to open a .smesh file. - polyfile = fopen(insmeshfilename, "r"); - if (polyfile == (FILE *) NULL) { - printf("File I/O Error: Cannot access file %s and %s.\n", - inpolyfilename, insmeshfilename); - return false; - } else { - printf("Opening %s.\n", insmeshfilename); - } - smesh = 1; - } else { - printf("Opening %s.\n", inpolyfilename); - } - // Read number of points, number of dimensions, number of point - // attributes, and number of boundary markers. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - numberofpoints = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - mesh_dim = 3; // If it is not provided, set the default value. - } else { - mesh_dim = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - numberofpointattributes = 0; // The default value. - } else { - numberofpointattributes = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - markers = 0; // If it is not provided, set the default value. - } else { - markers = (int) strtol (stringptr, &stringptr, 0); - } - if (numberofpoints > 0) { - readnodefile = 0; - if (smesh) { - infilename = insmeshfilename; - } else { - infilename = inpolyfilename; - } - infile = polyfile; - } else { - // If the .poly or .smesh file claims there are zero points, that - // means the points should be read from a separate .node file. - readnodefile = 1; - infilename = innodefilename; - } - - if (readnodefile) { - // Read the points from the .node file. - printf("Opening %s.\n", innodefilename); - infile = fopen(innodefilename, "r"); - if (infile == (FILE *) NULL) { - printf("File I/O Error: Cannot access file %s.\n", innodefilename); - return false; - } - // Read number of points, number of dimensions, number of point - // attributes, and number of boundary markers. - stringptr = readnumberline(inputline, infile, innodefilename); - numberofpoints = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - mesh_dim = 3; - } else { - mesh_dim = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - numberofpointattributes = 0; - } else { - numberofpointattributes = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - markers = 0; - } else { - markers = (int) strtol (stringptr, &stringptr, 0); - } - } - - if (mesh_dim != 3) { - printf("Error: load_poly() only works for 3D points.\n"); - fclose(infile); - return false; - } - if (numberofpoints < 4) { - printf("File I/O error: There should have at least 4 points.\n"); - fclose(infile); - return false; - } - - // Load the list of nodes. - if (!load_node_call(infile, markers, infilename)) { - fclose(infile); - return false; - } - - if (readnodefile) { - fclose(infile); - } - - // Read number of facets and number of boundary markers. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - numberoffacets = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - markers = 0; - } else { - markers = (int) strtol (stringptr, &stringptr, 0); - } - - if (numberoffacets <= 0) { - // This input file is trivial, return anyway. - fclose(polyfile); - return true; - } - - // Initialize the 'facetlist', 'facetmarkerlist'. - facetlist = new facet[numberoffacets]; - if (markers == 1) { - facetmarkerlist = new int[numberoffacets]; - } - - facet *f; - polygon *p; - - // Read data into 'facetlist', 'facetmarkerlist'. - if (smesh == 0) { - // Facets are in .poly file format. - for (i = 1; i <= numberoffacets; i++) { - f = &(facetlist[i - 1]); - init(f); - f->numberofholes = 0; - currentmarker = 0; - // Read number of polygons, number of holes, and a boundary marker. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - f->numberofpolygons = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr != '\0') { - f->numberofholes = (int) strtol (stringptr, &stringptr, 0); - if (markers == 1) { - stringptr = findnextnumber(stringptr); - if (*stringptr != '\0') { - currentmarker = (int) strtol(stringptr, &stringptr, 0); - } - } - } - // Initialize facetmarker if it needs. - if (markers == 1) { - facetmarkerlist[i - 1] = currentmarker; - } - // Each facet should has at least one polygon. - if (f->numberofpolygons <= 0) { - printf("Error: Wrong number of polygon in %d facet.\n", i); - break; - } - // Initialize the 'f->polygonlist'. - f->polygonlist = new polygon[f->numberofpolygons]; - // Go through all polygons, read in their vertices. - for (j = 1; j <= f->numberofpolygons; j++) { - p = &(f->polygonlist[j - 1]); - init(p); - // Read number of vertices of this polygon. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - p->numberofvertices = (int) strtol(stringptr, &stringptr, 0); - if (p->numberofvertices < 1) { - printf("Error: Wrong polygon %d in facet %d\n", j, i); - break; - } - // Initialize 'p->vertexlist'. - p->vertexlist = new int[p->numberofvertices]; - // Read all vertices of this polygon. - for (k = 1; k <= p->numberofvertices; k++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - // Try to load another non-empty line and continue to read the - // rest of vertices. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - if (*stringptr == '\0') { - printf("Error: Missing %d endpoints of polygon %d in facet %d", - p->numberofvertices - k, j, i); - break; - } - } - p->vertexlist[k - 1] = (int) strtol (stringptr, &stringptr, 0); - } - } - if (j <= f->numberofpolygons) { - // This must be caused by an error. However, there're j - 1 polygons - // have been read. Reset the 'f->numberofpolygon'. - if (j == 1) { - // This is the first polygon. - delete [] f->polygonlist; - } - f->numberofpolygons = j - 1; - // No hole will be read even it exists. - f->numberofholes = 0; - break; - } - // If this facet has holes pints defined, read them. - if (f->numberofholes > 0) { - // Initialize 'f->holelist'. - f->holelist = new REAL[f->numberofholes * 3]; - // Read the holes' coordinates. - index = 0; - for (j = 1; j <= f->numberofholes; j++) { - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - for (k = 1; k <= 3; k++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Hole %d in facet %d has no coordinates", j, i); - break; - } - f->holelist[index++] = (REAL) strtod (stringptr, &stringptr); - } - if (k <= 3) { - // This must be caused by an error. - break; - } - } - if (j <= f->numberofholes) { - // This must be caused by an error. - break; - } - } - } - if (i <= numberoffacets) { - // This must be caused by an error. - numberoffacets = i - 1; - fclose(polyfile); - return false; - } - } else { // poly == 0 - // Read the facets from a .smesh file. - for (i = 1; i <= numberoffacets; i++) { - f = &(facetlist[i - 1]); - init(f); - // Initialize 'f->facetlist'. In a .smesh file, each facetlist only - // contains exactly one polygon, no hole. - f->numberofpolygons = 1; - f->polygonlist = new polygon[f->numberofpolygons]; - p = &(f->polygonlist[0]); - init(p); - // Read number of vertices of this polygon. - stringptr = readnumberline(inputline, polyfile, insmeshfilename); - p->numberofvertices = (int) strtol (stringptr, &stringptr, 0); - if (p->numberofvertices < 1) { - printf("Error: Wrong number of vertex in facet %d\n", i); - break; - } - // Initialize 'p->vertexlist'. - p->vertexlist = new int[p->numberofvertices]; - for (k = 1; k <= p->numberofvertices; k++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - // Try to load another non-empty line and continue to read the - // rest of vertices. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - if (*stringptr == '\0') { - printf("Error: Missing %d endpoints in facet %d", - p->numberofvertices - k, i); - break; - } - } - p->vertexlist[k - 1] = (int) strtol (stringptr, &stringptr, 0); - } - if (k <= p->numberofvertices) { - // This must be caused by an error. - break; - } - // Read facet's boundary marker at last. - if (markers == 1) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - currentmarker = 0; - } else { - currentmarker = (int) strtol(stringptr, &stringptr, 0); - } - facetmarkerlist[i - 1] = currentmarker; - } - } - if (i <= numberoffacets) { - // This must be caused by an error. - numberoffacets = i - 1; - fclose(polyfile); - return false; - } - } - - // Read the hole section. - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - if (*stringptr != '\0') { - numberofholes = (int) strtol (stringptr, &stringptr, 0); - } else { - numberofholes = 0; - } - if (numberofholes > 0) { - // Initialize 'holelist'. - holelist = new REAL[numberofholes * 3]; - for (i = 0; i < 3 * numberofholes; i += 3) { - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Hole %d has no x coord.\n", firstnumber + (i / 3)); - break; - } else { - holelist[i] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Hole %d has no y coord.\n", firstnumber + (i / 3)); - break; - } else { - holelist[i + 1] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Hole %d has no z coord.\n", firstnumber + (i / 3)); - break; - } else { - holelist[i + 2] = (REAL) strtod(stringptr, &stringptr); - } - } - if (i < 3 * numberofholes) { - // This must be caused by an error. - fclose(polyfile); - return false; - } - } - - // Read the region section. The 'region' section is optional, if we don't - // reach the end of the file, try read it in. - do { - stringptr = fgets(inputline, INPUTLINESIZE, polyfile); - if (stringptr == (char *) NULL) { - break; - } - // Skip anything that doesn't look like a number, a comment, - // or the end of a line. - while ((*stringptr != '\0') && (*stringptr != '#') - && (*stringptr != '.') && (*stringptr != '+') && (*stringptr != '-') - && ((*stringptr < '0') || (*stringptr > '9'))) { - stringptr++; - } - // If it's a comment or end of line, read another line and try again. - } while ((*stringptr == '#') || (*stringptr == '\0')); - - if (stringptr != (char *) NULL && *stringptr != '\0') { - numberofregions = (int) strtol (stringptr, &stringptr, 0); - } else { - numberofregions = 0; - } - if (numberofregions > 0) { - // Initialize 'regionlist'. - regionlist = new REAL[numberofregions * 5]; - index = 0; - for (i = 0; i < numberofregions; i++) { - stringptr = readnumberline(inputline, polyfile, inpolyfilename); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Region %d has no x coordinate.\n", firstnumber + i); - break; - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Region %d has no y coordinate.\n", firstnumber + i); - break; - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Region %d has no z coordinate.\n", firstnumber + i); - break; - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Region %d has no region attrib.\n", firstnumber + i); - break; - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - regionlist[index] = regionlist[index - 1]; - } else { - regionlist[index] = (REAL) strtod(stringptr, &stringptr); - } - index++; - } - if (i < numberofregions) { - // This must be caused by an error. - fclose(polyfile); - return false; - } - } - - // End of reading poly/smesh file. - fclose(polyfile); - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_off() Load a polyhedron described in a .off file. // -// // -// The .off format is one of file formats of the Geomview, an interactive // -// program for viewing and manipulating geometric objects. More information // -// is available form: http://www.geomview.org. // -// // -// 'filename' is a input filename with extension .off or without extension ( // -// the .off will be added in this case). On completion, the polyhedron is // -// returned in 'pointlist' and 'facetlist'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_off(char* filename) -{ - FILE *fp; - tetgenio::facet *f; - tetgenio::polygon *p; - char infilename[FILENAMESIZE]; - char buffer[INPUTLINESIZE]; - char *bufferp; - double *coord; - int nverts = 0, iverts = 0; - int nfaces = 0, ifaces = 0; - int nedges = 0; - int line_count = 0, i; - - strncpy(infilename, filename, 1024 - 1); - infilename[FILENAMESIZE - 1] = '\0'; - if (infilename[0] == '\0') { - printf("Error: No filename.\n"); - return false; - } - if (strcmp(&infilename[strlen(infilename) - 4], ".off") != 0) { - strcat(infilename, ".off"); - } - - if (!(fp = fopen(infilename, "r"))) { - printf("File I/O Error: Unable to open file %s\n", infilename); - return false; - } - printf("Opening %s.\n", infilename); - - // OFF requires the index starts from '0'. - firstnumber = 0; - - while ((bufferp = readline(buffer, fp, &line_count)) != NULL) { - // Check section - if (nverts == 0) { - // Read header - bufferp = strstr(bufferp, "OFF"); - if (bufferp != NULL) { - // Read mesh counts - bufferp = findnextnumber(bufferp); // Skip field "OFF". - if (*bufferp == '\0') { - // Read a non-empty line. - bufferp = readline(buffer, fp, &line_count); - } - if ((sscanf(bufferp, "%d%d%d", &nverts, &nfaces, &nedges) != 3) - || (nverts == 0)) { - printf("Syntax error reading header on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - // Allocate memory for 'tetgenio' - if (nverts > 0) { - numberofpoints = nverts; - pointlist = new REAL[nverts * 3]; - assert(pointlist != NULL); - } - if (nfaces > 0) { - numberoffacets = nfaces; - facetlist = new tetgenio::facet[nfaces]; - assert(facetlist); - } - } - } else if (iverts < nverts) { - // Read vertex coordinates - coord = &pointlist[iverts * 3]; - for (i = 0; i < 3; i++) { - if (*bufferp == '\0') { - printf("Syntax error reading vertex coords on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - coord[i] = (REAL) strtod(bufferp, &bufferp); - bufferp = findnextnumber(bufferp); - } - iverts++; - } else if (ifaces < nfaces) { - // Get next face - f = &facetlist[ifaces]; - init(f); - // In .off format, each facet has one polygon, no hole. - f->numberofpolygons = 1; - f->polygonlist = new tetgenio::polygon[1]; - p = &f->polygonlist[0]; - init(p); - // Read the number of vertices, it should be greater than 0. - p->numberofvertices = (int) strtol(bufferp, &bufferp, 0); - if (p->numberofvertices == 0) { - printf("Syntax error reading polygon on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - // Allocate memory for face vertices - p->vertexlist = new int[p->numberofvertices]; - for (i = 0; i < p->numberofvertices; i++) { - bufferp = findnextnumber(bufferp); - if (*bufferp == '\0') { - printf("Syntax error reading polygon on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - p->vertexlist[i] = (int) strtol(bufferp, &bufferp, 0); - } - ifaces++; - } else { - // Should never get here - printf("Found extra text starting at line %d in file %s\n", line_count, - infilename); - break; - } - } - - // Close file - fclose(fp); - - // Check whether read all points - if (iverts != nverts) { - printf("Expected %d vertices, but read only %d vertices in file %s\n", - nverts, iverts, infilename); - return false; - } - - // Check whether read all faces - if (ifaces != nfaces) { - printf("Expected %d faces, but read only %d faces in file %s\n", - nfaces, ifaces, infilename); - return false; - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_ply() Load a polyhedron described in a .ply file. // -// // -// 'filename' is the file name with extension .ply or without extension (the // -// .ply will be added in this case). // -// // -// This is a simplified version of reading .ply files, which only reads the // -// set of vertices and the set of faces. Other informations (such as color, // -// material, texture, etc) in .ply file are ignored. Complete routines for // -// reading and writing ,ply files are available from: http://www.cc.gatech. // -// edu/projects/large_models/ply.html. Except the header section, ply file // -// format has exactly the same format for listing vertices and polygons as // -// off file format. // -// // -// On completion, 'pointlist' and 'facetlist' together return the polyhedron.// -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_ply(char* filename) -{ - FILE *fp; - tetgenio::facet *f; - tetgenio::polygon *p; - char infilename[FILENAMESIZE]; - char buffer[INPUTLINESIZE]; - char *bufferp, *str; - double *coord; - int endheader = 0, format = 0; - int nverts = 0, iverts = 0; - int nfaces = 0, ifaces = 0; - int line_count = 0, i; - - strncpy(infilename, filename, FILENAMESIZE - 1); - infilename[FILENAMESIZE - 1] = '\0'; - if (infilename[0] == '\0') { - printf("Error: No filename.\n"); - return false; - } - if (strcmp(&infilename[strlen(infilename) - 4], ".ply") != 0) { - strcat(infilename, ".ply"); - } - - if (!(fp = fopen(infilename, "r"))) { - printf("Error: Unable to open file %s\n", infilename); - return false; - } - printf("Opening %s.\n", infilename); - - // PLY requires the index starts from '0'. - firstnumber = 0; - - while ((bufferp = readline(buffer, fp, &line_count)) != NULL) { - if (!endheader) { - // Find if it is the keyword "end_header". - str = strstr(bufferp, "end_header"); - // strstr() is case sensitive. - if (!str) str = strstr(bufferp, "End_header"); - if (!str) str = strstr(bufferp, "End_Header"); - if (str) { - // This is the end of the header section. - endheader = 1; - continue; - } - // Parse the number of vertices and the number of faces. - if (nverts == 0 || nfaces == 0) { - // Find if it si the keyword "element". - str = strstr(bufferp, "element"); - if (!str) str = strstr(bufferp, "Element"); - if (str) { - bufferp = findnextfield(str); - if (*bufferp == '\0') { - printf("Syntax error reading element type on line%d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - if (nverts == 0) { - // Find if it is the keyword "vertex". - str = strstr(bufferp, "vertex"); - if (!str) str = strstr(bufferp, "Vertex"); - if (str) { - bufferp = findnextnumber(str); - if (*bufferp == '\0') { - printf("Syntax error reading vertex number on line"); - printf(" %d in file %s\n", line_count, infilename); - fclose(fp); - return false; - } - nverts = (int) strtol(bufferp, &bufferp, 0); - // Allocate memory for 'tetgenio' - if (nverts > 0) { - numberofpoints = nverts; - pointlist = new REAL[nverts * 3]; - assert(pointlist != NULL); - } - } - } - if (nfaces == 0) { - // Find if it is the keyword "face". - str = strstr(bufferp, "face"); - if (!str) str = strstr(bufferp, "Face"); - if (str) { - bufferp = findnextnumber(str); - if (*bufferp == '\0') { - printf("Syntax error reading face number on line"); - printf(" %d in file %s\n", line_count, infilename); - fclose(fp); - return false; - } - nfaces = (int) strtol(bufferp, &bufferp, 0); - // Allocate memory for 'tetgenio' - if (nfaces > 0) { - numberoffacets = nfaces; - facetlist = new tetgenio::facet[nfaces]; - assert(facetlist); - } - } - } - } // It is not the string "element". - } - if (format == 0) { - // Find the keyword "format". - str = strstr(bufferp, "format"); - if (!str) str = strstr(bufferp, "Format"); - if (str) { - format = 1; - bufferp = findnextfield(str); - // Find if it is the string "ascii". - str = strstr(bufferp, "ascii"); - if (!str) str = strstr(bufferp, "ASCII"); - if (!str) { - printf("This routine only reads ascii format of ply files.\n"); - printf("Hint: You can convert the binary to ascii format by\n"); - printf(" using the provided ply tools:\n"); - printf(" ply2ascii < %s > ascii_%s\n", infilename, infilename); - fclose(fp); - return false; - } - } - } - } else if (iverts < nverts) { - // Read vertex coordinates - coord = &pointlist[iverts * 3]; - for (i = 0; i < 3; i++) { - if (*bufferp == '\0') { - printf("Syntax error reading vertex coords on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - coord[i] = (REAL) strtod(bufferp, &bufferp); - bufferp = findnextnumber(bufferp); - } - iverts++; - } else if (ifaces < nfaces) { - // Get next face - f = &facetlist[ifaces]; - init(f); - // In .off format, each facet has one polygon, no hole. - f->numberofpolygons = 1; - f->polygonlist = new tetgenio::polygon[1]; - p = &f->polygonlist[0]; - init(p); - // Read the number of vertices, it should be greater than 0. - p->numberofvertices = (int) strtol(bufferp, &bufferp, 0); - if (p->numberofvertices == 0) { - printf("Syntax error reading polygon on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - // Allocate memory for face vertices - p->vertexlist = new int[p->numberofvertices]; - for (i = 0; i < p->numberofvertices; i++) { - bufferp = findnextnumber(bufferp); - if (*bufferp == '\0') { - printf("Syntax error reading polygon on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - p->vertexlist[i] = (int) strtol(bufferp, &bufferp, 0); - } - ifaces++; - } else { - // Should never get here - printf("Found extra text starting at line %d in file %s\n", line_count, - infilename); - break; - } - } - - // Close file - fclose(fp); - - // Check whether read all points - if (iverts != nverts) { - printf("Expected %d vertices, but read only %d vertices in file %s\n", - nverts, iverts, infilename); - return false; - } - - // Check whether read all faces - if (ifaces != nfaces) { - printf("Expected %d faces, but read only %d faces in file %s\n", - nfaces, ifaces, infilename); - return false; - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_stl() Load a surface mesh described in a .stl file. // -// // -// 'filename' is the file name with extension .stl or without extension (the // -// .stl will be added in this case). // -// // -// The .stl or stereolithography format is an ASCII or binary file used in // -// manufacturing. It is a list of the triangular surfaces that describe a // -// computer generated solid model. This is the standard input for most rapid // -// prototyping machines. // -// // -// On completion, 'pointlist' and 'facetlist' together return the polyhedron.// -// Note: After load_stl(), there exist many duplicated points in 'pointlist'.// -// They will be unified during the Delaunay tetrahedralization process. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_stl(char* filename) -{ - FILE *fp; - tetgenmesh::list *plist; - tetgenio::facet *f; - tetgenio::polygon *p; - char infilename[FILENAMESIZE]; - char buffer[INPUTLINESIZE]; - char *bufferp, *str; - double *coord; - int solid = 0; - int nverts = 0, iverts = 0; - int nfaces = 0; - int line_count = 0, i; - - strncpy(infilename, filename, FILENAMESIZE - 1); - infilename[FILENAMESIZE - 1] = '\0'; - if (infilename[0] == '\0') { - printf("Error: No filename.\n"); - return false; - } - if (strcmp(&infilename[strlen(infilename) - 4], ".stl") != 0) { - strcat(infilename, ".stl"); - } - - if (!(fp = fopen(infilename, "r"))) { - printf("Error: Unable to open file %s\n", infilename); - return false; - } - printf("Opening %s.\n", infilename); - - // STL file has no number of points available. Use a list to read points. - plist = new tetgenmesh::list(sizeof(double) * 3, NULL, 1024); - - while ((bufferp = readline(buffer, fp, &line_count)) != NULL) { - // The ASCII .stl file must start with the lower case keyword solid and - // end with endsolid. - if (solid == 0) { - // Read header - bufferp = strstr(bufferp, "solid"); - if (bufferp != NULL) { - solid = 1; - } - } else { - // We're inside the block of the solid. - str = bufferp; - // Is this the end of the solid. - bufferp = strstr(bufferp, "endsolid"); - if (bufferp != NULL) { - solid = 0; - } else { - // Read the XYZ coordinates if it is a vertex. - bufferp = str; - bufferp = strstr(bufferp, "vertex"); - if (bufferp != NULL) { - coord = (double *) plist->append(NULL); - for (i = 0; i < 3; i++) { - bufferp = findnextnumber(bufferp); - if (*bufferp == '\0') { - printf("Syntax error reading vertex coords on line %d\n", - line_count); - delete plist; - fclose(fp); - return false; - } - coord[i] = (REAL) strtod(bufferp, &bufferp); - } - } - } - } - } - fclose(fp); - - nverts = plist->len(); - // nverts should be an integer times 3 (every 3 vertices denote a face). - if (nverts == 0 || (nverts % 3 != 0)) { - printf("Error: Wrong number of vertices in file %s.\n", infilename); - delete plist; - return false; - } - numberofpoints = nverts; - pointlist = new REAL[nverts * 3]; - assert(pointlist != NULL); - for (i = 0; i < nverts; i++) { - coord = (double *) (* plist)[i]; - iverts = i * 3; - pointlist[iverts] = (REAL) coord[0]; - pointlist[iverts + 1] = (REAL) coord[1]; - pointlist[iverts + 2] = (REAL) coord[2]; - } - - nfaces = (int) (nverts / 3); - numberoffacets = nfaces; - facetlist = new tetgenio::facet[nfaces]; - assert(facetlist != NULL); - - // Default use '1' as the array starting index. - firstnumber = 1; - iverts = firstnumber; - for (i = 0; i < nfaces; i++) { - f = &facetlist[i]; - init(f); - // In .stl format, each facet has one polygon, no hole. - f->numberofpolygons = 1; - f->polygonlist = new tetgenio::polygon[1]; - p = &f->polygonlist[0]; - init(p); - // Each polygon has three vertices. - p->numberofvertices = 3; - p->vertexlist = new int[p->numberofvertices]; - p->vertexlist[0] = iverts; - p->vertexlist[1] = iverts + 1; - p->vertexlist[2] = iverts + 2; - iverts += 3; - } - - delete plist; - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_medit() Load a surface mesh described in .mesh file. // -// // -// 'filename' is the file name with extension .mesh or without entension ( // -// the .mesh will be added in this case). .mesh is the file format of Medit, // -// a user-friendly interactive mesh viewing program. // -// // -// This routine ONLY reads the sections containing vertices and triangles, // -// other sections (such as tetrahedra, edges, ...) are ignored. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_medit(char* filename) -{ - FILE *fp; - tetgenio::facet *f; - tetgenio::polygon *p; - char infilename[FILENAMESIZE]; - char buffer[INPUTLINESIZE]; - char *bufferp, *str; - double *coord; - int nverts = 0; - int nfaces = 0; - int line_count = 0; - int corners = 0; // 3 (triangle) or 4 (quad). - int i, j; - - strncpy(infilename, filename, FILENAMESIZE - 1); - infilename[FILENAMESIZE - 1] = '\0'; - if (infilename[0] == '\0') { - printf("Error: No filename.\n"); - return false; - } - if (strcmp(&infilename[strlen(infilename) - 5], ".mesh") != 0) { - strcat(infilename, ".mesh"); - } - - if (!(fp = fopen(infilename, "r"))) { - printf("Error: Unable to open file %s\n", infilename); - return false; - } - printf("Opening %s.\n", infilename); - - // Default uses the index starts from '1'. - firstnumber = 1; - - while ((bufferp = readline(buffer, fp, &line_count)) != NULL) { - if (*bufferp == '#') continue; // A comment line is skipped. - if (nverts == 0) { - // Find if it is the keyword "Vertices". - str = strstr(bufferp, "Vertices"); - if (!str) str = strstr(bufferp, "vertices"); - if (!str) str = strstr(bufferp, "VERTICES"); - if (str) { - // Read the number of vertices. - bufferp = findnextnumber(str); // Skip field "Vertices". - if (*bufferp == '\0') { - // Read a non-empty line. - bufferp = readline(buffer, fp, &line_count); - } - nverts = (int) strtol(bufferp, &bufferp, 0); - // Allocate memory for 'tetgenio' - if (nverts > 0) { - numberofpoints = nverts; - pointlist = new REAL[nverts * 3]; - assert(pointlist != NULL); - } - // Read the follwoing node list. - for (i = 0; i < nverts; i++) { - bufferp = readline(buffer, fp, &line_count); - if (bufferp == NULL) { - printf("Unexpected end of file on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - // Read vertex coordinates - coord = &pointlist[i * 3]; - for (j = 0; j < 3; j++) { - if (*bufferp == '\0') { - printf("Syntax error reading vertex coords on line"); - printf(" %d in file %s\n", line_count, infilename); - fclose(fp); - return false; - } - coord[j] = (REAL) strtod(bufferp, &bufferp); - bufferp = findnextnumber(bufferp); - } - } - continue; - } - } - if (nfaces == 0) { - // Find if it is the keyword "Triangles" or "Quadrilaterals". - str = strstr(bufferp, "Triangles"); - if (!str) str = strstr(bufferp, "triangles"); - if (!str) str = strstr(bufferp, "TRIANGLES"); - if (str) { - corners = 3; - } else { - str = strstr(bufferp, "Quadrilaterals"); - if (!str) str = strstr(bufferp, "quadrilaterals"); - if (!str) str = strstr(bufferp, "QUADRILATERALS"); - if (str) { - corners = 4; - } - } - if (corners == 3 || corners == 4) { - // Read the number of triangles (or quadrilaterals). - bufferp = findnextnumber(str); // Skip field "Triangles". - if (*bufferp == '\0') { - // Read a non-empty line. - bufferp = readline(buffer, fp, &line_count); - } - nfaces = strtol(bufferp, &bufferp, 0); - // Allocate memory for 'tetgenio' - if (nfaces > 0) { - numberoffacets = nfaces; - facetlist = new tetgenio::facet[nfaces]; - assert(facetlist != NULL); - facetmarkerlist = new int[nfaces]; - assert(facetmarkerlist != NULL); - } - // Read the following list of faces. - for (i = 0; i < nfaces; i++) { - bufferp = readline(buffer, fp, &line_count); - if (bufferp == NULL) { - printf("Unexpected end of file on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - f = &facetlist[i]; - tetgenio::init(f); - // In .mesh format, each facet has one polygon, no hole. - f->numberofpolygons = 1; - f->polygonlist = new tetgenio::polygon[1]; - p = &f->polygonlist[0]; - tetgenio::init(p); - p->numberofvertices = corners; - // Allocate memory for face vertices - p->vertexlist = new int[p->numberofvertices]; - assert(p->vertexlist != NULL); - // Read the vertices of the face. - for (j = 0; j < corners; j++) { - if (*bufferp == '\0') { - printf("Syntax error reading face on line %d in file %s\n", - line_count, infilename); - fclose(fp); - return false; - } - p->vertexlist[j] = (int) strtol(bufferp, &bufferp, 0); - if (firstnumber == 1) { - // Check if a '0' index appears. - if (p->vertexlist[j] == 0) { - // The first index is set to be 0. - firstnumber = 0; - } - } - bufferp = findnextnumber(bufferp); - } - // Read the marker of the face if it exists. - facetmarkerlist[i] = 0; - if (*bufferp != '\0') { - facetmarkerlist[i] = (int) strtol(bufferp, &bufferp, 0); - } - } - continue; - } - } - if (nverts > 0 && nfaces > 0) break; // Ignore other data. - } - - // Close file - fclose(fp); - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_plc() Load a piecewise linear complex from file. // -// // -// This is main entrance for loading plcs from different file formats into // -// tetgenio. 'filename' is the input file name without extention. 'object' // -// indicates which file format is used to describ the plc. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_plc(char* filename, int object) -{ - enum tetgenbehavior::objecttype type; - - type = (enum tetgenbehavior::objecttype) object; - switch (type) { - case tetgenbehavior::NODES: - return load_node(filename); - case tetgenbehavior::POLY: - return load_poly(filename); - case tetgenbehavior::OFF: - return load_off(filename); - case tetgenbehavior::PLY: - return load_ply(filename); - case tetgenbehavior::STL: - return load_stl(filename); - case tetgenbehavior::MEDIT: - return load_medit(filename); - default: - return load_poly(filename); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// load_tetmesh() Load a tetrahedral mesh from files. // -// // -// 'filename' is the inputfile without suffix. The nodes of the tetrahedral // -// mesh is in "filename.node", the elements is in "filename.ele", if the // -// "filename.face" and "filename.vol" exists, they will also be read. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenio::load_tetmesh(char* filename) -{ - FILE *infile; - char innodefilename[FILENAMESIZE]; - char inelefilename[FILENAMESIZE]; - char infacefilename[FILENAMESIZE]; - char inedgefilename[FILENAMESIZE]; - char involfilename[FILENAMESIZE]; - char inputline[INPUTLINESIZE]; - char *stringptr, *infilename; - REAL attrib, volume; - int volelements; - int markers, corner; - int index, attribindex; - int i, j; - - // Assembling the actual file names we want to open. - strcpy(innodefilename, filename); - strcpy(inelefilename, filename); - strcpy(infacefilename, filename); - strcpy(inedgefilename, filename); - strcpy(involfilename, filename); - strcat(innodefilename, ".node"); - strcat(inelefilename, ".ele"); - strcat(infacefilename, ".face"); - strcat(inedgefilename, ".edge"); - strcat(involfilename, ".vol"); - - // Read the points from a .node file. - infilename = innodefilename; - printf("Opening %s.\n", infilename); - infile = fopen(infilename, "r"); - if (infile == (FILE *) NULL) { - printf("File I/O Error: Cannot access file %s.\n", infilename); - return false; - } - // Read number of points, number of dimensions, number of point - // attributes, and number of boundary markers. - stringptr = readnumberline(inputline, infile, infilename); - numberofpoints = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - mesh_dim = 3; - } else { - mesh_dim = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - numberofpointattributes = 0; - } else { - numberofpointattributes = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - markers = 0; // Default value. - } else { - markers = (int) strtol (stringptr, &stringptr, 0); - } - - if (mesh_dim != 3) { - printf("Error: load_tetmesh() only works for 3D points.\n"); - fclose(infile); - return false; - } - if (numberofpoints < 4) { - printf("File I/O error: Input should has at least 4 points.\n"); - fclose(infile); - return false; - } - - // Load the list of nodes. - if (!load_node_call(infile, markers, infilename)) { - fclose(infile); - return false; - } - - // Read the elements from a .ele file. - infilename = inelefilename; - printf("Opening %s.\n", infilename); - infile = fopen(infilename, "r"); - if (infile != (FILE *) NULL) { - // Read number of elements, number of corners (4 or 10), number of - // element attributes. - stringptr = readnumberline(inputline, infile, infilename); - numberoftetrahedra = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - numberofcorners = 4; // Default read 4 nodes per element. - } else { - numberofcorners = (int) strtol (stringptr, &stringptr, 0); - } - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - numberoftetrahedronattributes = 0; // Default no attribute. - } else { - numberoftetrahedronattributes = (int) strtol (stringptr, &stringptr, 0); - } - if (numberofcorners != 4 && numberofcorners != 10) { - printf("Error: Wrong number of corners %d (should be 4 or 10).\n", - numberofcorners); - fclose(infile); - return false; - } - // Allocate memory for tetrahedra. - if (numberoftetrahedra > 0) { - tetrahedronlist = new int[numberoftetrahedra * numberofcorners]; - if (tetrahedronlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - // Allocate memory for output tetrahedron attributes if necessary. - if (numberoftetrahedronattributes > 0) { - tetrahedronattributelist = new REAL[numberoftetrahedra * - numberoftetrahedronattributes]; - if (tetrahedronattributelist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - } - // Read the list of tetrahedra. - index = 0; - attribindex = 0; - for (i = 0; i < numberoftetrahedra; i++) { - // Read tetrahedron index and the tetrahedron's corners. - stringptr = readnumberline(inputline, infile, infilename); - for (j = 0; j < numberofcorners; j++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Tetrahedron %d is missing vertex %d in %s.\n", - i + firstnumber, j + 1, infilename); - exit(1); - } - corner = (int) strtol(stringptr, &stringptr, 0); - if (corner < firstnumber || corner >= numberofpoints + firstnumber) { - printf("Error: Tetrahedron %d has an invalid vertex index.\n", - i + firstnumber); - exit(1); - } - tetrahedronlist[index++] = corner; - } - // Read the tetrahedron's attributes. - for (j = 0; j < numberoftetrahedronattributes; j++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - attrib = 0.0; - } else { - attrib = (REAL) strtod(stringptr, &stringptr); - } - tetrahedronattributelist[attribindex++] = attrib; - } - } - fclose(infile); - } - - // Read the hullfaces or subfaces from a .face file if it exists. - infilename = infacefilename; - infile = fopen(infilename, "r"); - if (infile != (FILE *) NULL) { - printf("Opening %s.\n", infilename); - // Read number of faces, boundary markers. - stringptr = readnumberline(inputline, infile, infilename); - numberoftrifaces = (int) strtol (stringptr, &stringptr, 0); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - markers = 0; // Default there is no marker per face. - } else { - markers = (int) strtol (stringptr, &stringptr, 0); - } - if (numberoftrifaces > 0) { - trifacelist = new int[numberoftrifaces * 3]; - if (trifacelist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - if (markers) { - trifacemarkerlist = new int[numberoftrifaces * 3]; - if (trifacemarkerlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - } - // Read the list of faces. - index = 0; - for (i = 0; i < numberoftrifaces; i++) { - // Read face index and the face's three corners. - stringptr = readnumberline(inputline, infile, infilename); - for (j = 0; j < 3; j++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Face %d is missing vertex %d in %s.\n", - i + firstnumber, j + 1, infilename); - exit(1); - } - corner = (int) strtol(stringptr, &stringptr, 0); - if (corner < firstnumber || corner >= numberofpoints + firstnumber) { - printf("Error: Face %d has an invalid vertex index.\n", - i + firstnumber); - exit(1); - } - trifacelist[index++] = corner; - } - // Read the boundary marker if it exists. - if (markers) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - attrib = 0.0; - } else { - attrib = (REAL) strtod(stringptr, &stringptr); - } - trifacemarkerlist[i] = (int) attrib; - } - } - fclose(infile); - } - - // Read the boundary edges from a .edge file if it exists. - infilename = inedgefilename; - infile = fopen(infilename, "r"); - if (infile != (FILE *) NULL) { - printf("Opening %s.\n", infilename); - // Read number of boundary edges. - stringptr = readnumberline(inputline, infile, infilename); - numberofedges = (int) strtol (stringptr, &stringptr, 0); - if (numberofedges > 0) { - edgelist = new int[numberofedges * 2]; - if (edgelist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - // Read the list of faces. - index = 0; - for (i = 0; i < numberofedges; i++) { - // Read face index and the edge's two endpoints. - stringptr = readnumberline(inputline, infile, infilename); - for (j = 0; j < 2; j++) { - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - printf("Error: Edge %d is missing vertex %d in %s.\n", - i + firstnumber, j + 1, infilename); - exit(1); - } - corner = (int) strtol(stringptr, &stringptr, 0); - if (corner < firstnumber || corner >= numberofpoints + firstnumber) { - printf("Error: Edge %d has an invalid vertex index.\n", - i + firstnumber); - exit(1); - } - edgelist[index++] = corner; - } - } - fclose(infile); - } - - // Read the volume constraints from a .vol file if it exists. - infilename = involfilename; - infile = fopen(infilename, "r"); - if (infile != (FILE *) NULL) { - printf("Opening %s.\n", infilename); - // Read number of tetrahedra. - stringptr = readnumberline(inputline, infile, infilename); - volelements = (int) strtol (stringptr, &stringptr, 0); - if (volelements != numberoftetrahedra) { - printf("Warning: %s and %s disagree on number of tetrahedra.\n", - inelefilename, involfilename); - volelements = 0; - } - if (volelements > 0) { - tetrahedronvolumelist = new REAL[volelements]; - if (tetrahedronvolumelist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - // Read the list of volume constraints. - for (i = 0; i < volelements; i++) { - stringptr = readnumberline(inputline, infile, infilename); - stringptr = findnextnumber(stringptr); - if (*stringptr == '\0') { - volume = -1.0; // No constraint on this tetrahedron. - } else { - volume = (REAL) strtod(stringptr, &stringptr); - } - tetrahedronvolumelist[i] = volume; - } - fclose(infile); - } - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// save_nodes() Save points to a .node file. // -// // -// 'filename' is a string containing the file name without suffix. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::save_nodes(char* filename) -{ - FILE *fout; - char outnodefilename[FILENAMESIZE]; - int i, j; - - sprintf(outnodefilename, "%s.node", filename); - printf("Saving nodes to %s\n", outnodefilename); - fout = fopen(outnodefilename, "w"); - fprintf(fout, "%d %d %d %d\n", numberofpoints, mesh_dim, - numberofpointattributes, pointmarkerlist != NULL ? 1 : 0); - for (i = 0; i < numberofpoints; i++) { - if (mesh_dim == 2) { - fprintf(fout, "%d %.16g %.16g", i + firstnumber, pointlist[i * 2], - pointlist[i * 2 + 1]); - } else { - fprintf(fout, "%d %.16g %.16g %.16g", i + firstnumber, - pointlist[i * 3], pointlist[i * 3 + 1], pointlist[i * 3 + 2]); - } - for (j = 0; j < numberofpointattributes; j++) { - fprintf(fout, " %.16g", - pointattributelist[i * numberofpointattributes+j]); - } - if (pointmarkerlist != NULL) { - fprintf(fout, " %d", pointmarkerlist[i]); - } - fprintf(fout, "\n"); - } - - fclose(fout); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// save_elements() Save elements to a .ele file. // -// // -// 'filename' is a string containing the file name without suffix. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::save_elements(char* filename) -{ - FILE *fout; - char outelefilename[FILENAMESIZE]; - int i, j; - - sprintf(outelefilename, "%s.ele", filename); - printf("Saving elements to %s\n", outelefilename); - fout = fopen(outelefilename, "w"); - fprintf(fout, "%d %d %d\n", numberoftetrahedra, numberofcorners, - numberoftetrahedronattributes); - for (i = 0; i < numberoftetrahedra; i++) { - fprintf(fout, "%d", i + firstnumber); - for (j = 0; j < numberofcorners; j++) { - fprintf(fout, " %5d", tetrahedronlist[i * numberofcorners + j]); - } - for (j = 0; j < numberoftetrahedronattributes; j++) { - fprintf(fout, " %g", - tetrahedronattributelist[i * numberoftetrahedronattributes + j]); - } - fprintf(fout, "\n"); - } - - fclose(fout); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// save_faces() Save faces to a .face file. // -// // -// 'filename' is a string containing the file name without suffix. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::save_faces(char* filename) -{ - FILE *fout; - char outfacefilename[FILENAMESIZE]; - int i; - - sprintf(outfacefilename, "%s.face", filename); - printf("Saving faces to %s\n", outfacefilename); - fout = fopen(outfacefilename, "w"); - fprintf(fout, "%d %d\n", numberoftrifaces, - trifacemarkerlist != NULL ? 1 : 0); - for (i = 0; i < numberoftrifaces; i++) { - fprintf(fout, "%d %5d %5d %5d", i + firstnumber, trifacelist[i * 3], - trifacelist[i * 3 + 1], trifacelist[i * 3 +2]); - if (trifacemarkerlist != NULL) { - fprintf(fout, " %d", trifacemarkerlist[i]); - } - fprintf(fout, "\n"); - } - - fclose(fout); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// save_edges() Save egdes to a .edge file. // -// // -// 'filename' is a string containing the file name without suffix. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::save_edges(char* filename) -{ - FILE *fout; - char outedgefilename[FILENAMESIZE]; - int i; - - sprintf(outedgefilename, "%s.edge", filename); - printf("Saving edges to %s\n", outedgefilename); - fout = fopen(outedgefilename, "w"); - fprintf(fout, "%d %d\n", numberofedges, edgemarkerlist != NULL ? 1 : 0); - for (i = 0; i < numberofedges; i++) { - fprintf(fout, "%d %4d %4d", i + firstnumber, edgelist[i * 2], - edgelist[i * 2 + 1]); - if (edgemarkerlist != NULL) { - fprintf(fout, " %d", edgemarkerlist[i]); - } - fprintf(fout, "\n"); - } - - fclose(fout); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// save_neighbors() Save egdes to a .neigh file. // -// // -// 'filename' is a string containing the file name without suffix. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::save_neighbors(char* filename) -{ - FILE *fout; - char outneighborfilename[FILENAMESIZE]; - int i; - - sprintf(outneighborfilename, "%s.neigh", filename); - printf("Saving neighbors to %s\n", outneighborfilename); - fout = fopen(outneighborfilename, "w"); - fprintf(fout, "%d %d\n", numberoftetrahedra, mesh_dim + 1); - for (i = 0; i < numberoftetrahedra; i++) { - if (mesh_dim == 2) { - fprintf(fout, "%d %5d %5d %5d", i + firstnumber, neighborlist[i * 3], - neighborlist[i * 3 + 1], neighborlist[i * 3 + 2]); - } else { - fprintf(fout, "%d %5d %5d %5d %5d", i + firstnumber, - neighborlist[i * 4], neighborlist[i * 4 + 1], - neighborlist[i * 4 + 2], neighborlist[i * 4 + 3]); - } - fprintf(fout, "\n"); - } - - fclose(fout); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// save_poly() Save segments or facets to a .poly file. // -// // -// 'filename' is a string containing the file name without suffix. It only // -// save the facets, holes and regions. The nodes are saved in a .node file // -// by routine save_nodes(). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenio::save_poly(char* filename) -{ - FILE *fout; - facet *f; - polygon *p; - char outpolyfilename[FILENAMESIZE]; - int i, j, k; - - sprintf(outpolyfilename, "%s.poly", filename); - printf("Saving poly to %s\n", outpolyfilename); - fout = fopen(outpolyfilename, "w"); - - // The zero indicates that the vertices are in a separate .node file. - // Followed by number of dimensions, number of vertex attributes, - // and number of boundary markers (zero or one). - fprintf(fout, "%d %d %d %d\n", 0, mesh_dim, numberofpointattributes, - pointmarkerlist != NULL ? 1 : 0); - - // Save segments or facets. - if (mesh_dim == 2) { - // Number of segments, number of boundary markers (zero or one). - fprintf(fout, "%d %d\n", numberofedges, edgemarkerlist != NULL ? 1 : 0); - for (i = 0; i < numberofedges; i++) { - fprintf(fout, "%d %4d %4d", i + firstnumber, edgelist[i * 2], - edgelist[i * 2 + 1]); - if (edgemarkerlist != NULL) { - fprintf(fout, " %d", edgemarkerlist[i]); - } - fprintf(fout, "\n"); - } - } else { - // Number of facets, number of boundary markers (zero or one). - fprintf(fout, "%d %d\n", numberoffacets, facetmarkerlist != NULL ? 1 : 0); - for (i = 0; i < numberoffacets; i++) { - f = &(facetlist[i]); - fprintf(fout, "%d %d %d # %d\n", f->numberofpolygons,f->numberofholes, - facetmarkerlist != NULL ? facetmarkerlist[i] : 0, i + firstnumber); - // Output polygons of this facet. - for (j = 0; j < f->numberofpolygons; j++) { - p = &(f->polygonlist[j]); - fprintf(fout, "%d ", p->numberofvertices); - for (k = 0; k < p->numberofvertices; k++) { - if (((k + 1) % 10) == 0) { - fprintf(fout, "\n "); - } - fprintf(fout, " %d", p->vertexlist[k]); - } - fprintf(fout, "\n"); - } - // Output holes of this facet. - for (j = 0; j < f->numberofholes; j++) { - fprintf(fout, "%d %.12g %.12g %.12g\n", j + firstnumber, - f->holelist[j * 3], f->holelist[j * 3 + 1], f->holelist[j * 3 + 2]); - } - } - } - - // Save holes. - fprintf(fout, "%d\n", numberofholes); - for (i = 0; i < numberofholes; i++) { - // Output x, y coordinates. - fprintf(fout, "%d %.12g %.12g", i + firstnumber, holelist[i * mesh_dim], - holelist[i * mesh_dim + 1]); - if (mesh_dim == 3) { - // Output z coordinate. - fprintf(fout, " %.12g", holelist[i * mesh_dim + 2]); - } - fprintf(fout, "\n"); - } - - // Save regions. - fprintf(fout, "%d\n", numberofregions); - for (i = 0; i < numberofregions; i++) { - if (mesh_dim == 2) { - // Output the index, x, y coordinates, attribute (region number) - // and maximum area constraint (maybe -1). - fprintf(fout, "%d %.12g %.12g %.12g %.12g\n", i + firstnumber, - regionlist[i * 4], regionlist[i * 4 + 1], - regionlist[i * 4 + 2], regionlist[i * 4 + 3]); - } else { - // Output the index, x, y, z coordinates, attribute (region number) - // and maximum volume constraint (maybe -1). - fprintf(fout, "%d %.12g %.12g %.12g %.12g %.12g\n", i + firstnumber, - regionlist[i * 5], regionlist[i * 5 + 1], - regionlist[i * 5 + 2], regionlist[i * 5 + 3], - regionlist[i * 5 + 4]); - } - } - - fclose(fout); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// readline() Read a nonempty line from a file. // -// // -// A line is considered "nonempty" if it contains something more than white // -// spaces. If a line is considered empty, it will be dropped and the next // -// line will be read, this process ends until reaching the end-of-file or a // -// non-empty line. Return NULL if it is the end-of-file, otherwise, return // -// a pointer to the first non-whitespace character of the line. // -// // -/////////////////////////////////////////////////////////////////////////////// - -char* tetgenio::readline(char *string, FILE *infile, int *linenumber) -{ - char *result; - - // Search for a non-empty line. - do { - result = fgets(string, INPUTLINESIZE - 1, infile); - (*linenumber)++; - if (result == (char *) NULL) { - return (char *) NULL; - } - // Skip white spaces. - while ((*result == ' ') || (*result == '\t')) result++; - // If it's end of line, read another line and try again. - } while (*result == '\0'); - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// findnextfield() Find the next field of a string. // -// // -// Jumps past the current field by searching for whitespace or a comma, then // -// jumps past the whitespace or the comma to find the next field. // -// // -/////////////////////////////////////////////////////////////////////////////// - -char* tetgenio::findnextfield(char *string) -{ - char *result; - - result = string; - // Skip the current field. Stop upon reaching whitespace or a comma. - while ((*result != '\0') && (*result != ' ') && (*result != '\t') && - (*result != ',')) { - result++; - } - // Now skip the whitespace or the comma, stop at anything else that looks - // like a character, or the end of a line. - while ((*result == ' ') || (*result == '\t') || (*result == ',')) { - result++; - } - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// readnumberline() Read a nonempty number line from a file. // -// // -// A line is considered "nonempty" if it contains something that looks like // -// a number. Comments (prefaced by `#') are ignored. // -// // -/////////////////////////////////////////////////////////////////////////////// - -char* tetgenio::readnumberline(char *string, FILE *infile, char *infilename) -{ - char *result; - - // Search for something that looks like a number. - do { - result = fgets(string, INPUTLINESIZE, infile); - if (result == (char *) NULL) { - printf(" Error: Unexpected end of file in %s.\n", infilename); - exit(1); - } - // Skip anything that doesn't look like a number, a comment, - // or the end of a line. - while ((*result != '\0') && (*result != '#') - && (*result != '.') && (*result != '+') && (*result != '-') - && ((*result < '0') || (*result > '9'))) { - result++; - } - // If it's a comment or end of line, read another line and try again. - } while ((*result == '#') || (*result == '\0')); - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// findnextnumber() Find the next field of a number string. // -// // -// Jumps past the current field by searching for whitespace or a comma, then // -// jumps past the whitespace or the comma to find the next field that looks // -// like a number. // -// // -/////////////////////////////////////////////////////////////////////////////// - -char* tetgenio::findnextnumber(char *string) -{ - char *result; - - result = string; - // Skip the current field. Stop upon reaching whitespace or a comma. - while ((*result != '\0') && (*result != '#') && (*result != ' ') && - (*result != '\t') && (*result != ',')) { - result++; - } - // Now skip the whitespace and anything else that doesn't look like a - // number, a comment, or the end of a line. - while ((*result != '\0') && (*result != '#') - && (*result != '.') && (*result != '+') && (*result != '-') - && ((*result < '0') || (*result > '9'))) { - result++; - } - // Check for a comment (prefixed with `#'). - if (*result == '#') { - *result = '\0'; - } - return result; -} - -// -// End of class 'tetgenio' implementation -// - -static REAL PI = 3.14159265358979323846264338327950288419716939937510582; - -// -// Begin of class 'tetgenbehavior' implementation -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetgenbehavior() Initialize veriables of 'tetgenbehavior'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenbehavior::tetgenbehavior() -{ - // Initialize command line switches. - plc = 0; - refine = 0; - quality = 0; - minratio = 2.0; - goodratio = 0.0; - minangle = 20.0; - goodangle = 0.0; - varvolume = 0; - fixedvolume = 0; - maxvolume = -1.0; - regionattrib = 0; - insertaddpoints = 0; - removesliver = 0; - maxdihedral = 0.0; - detectinter = 0; - checkclosure = 0; - zeroindex = 0; - jettison = 0; - facesout = 0; - edgesout = 0; - neighout = 0; - meditview = 0; - gidview = 0; - geomview = 0; - order = 1; - nobound = 0; - nonodewritten = 0; - noelewritten = 0; - nofacewritten = 0; - noiterationnum = 0; - nobisect = 0; - noflip = 0; - steiner = -1; - dopermute = 0; - srandseed = 1; - nomerge = 0; - docheck = 0; - quiet = 0; - verbose = 0; - useshelles = 0; - epsilon = 1.0e-8; - object = NONE; - // Initialize strings - commandline[0] = '\0'; - infilename[0] = '\0'; - outfilename[0] = '\0'; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// versioninfo() Print the version information of TetGen. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenbehavior::versioninfo() -{ - printf("Version 1.3.2 (Released on December 13, 2004).\n"); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// syntax() Print list of command line switches and exit the program. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenbehavior::syntax() -{ - printf(" tetgen [-pq__a__AriMS__T__dzo_fengGOBNEFICQVvh] input_file\n"); - printf(" -p Tetrahedralizes a piecewise linear complex.\n"); - printf(" -q Quality mesh generation. A minimum radius-edge ratio may\n"); - printf(" be specified (default 2.0).\n"); - printf(" -a Applies a maximum tetrahedron volume constraint.\n"); - printf(" -A Assigns attributes to identify tetrahedra in certain "); - printf("regions.\n"); - printf(" -r Reconstructs/Refines a previously generated mesh.\n"); - printf(" -i Inserts a list of additional points into mesh.\n"); - printf(" -M Does not merge coplanar facets.\n"); - printf(" -S Specifies maximum number of added Steiner points.\n"); - printf(" -T Set a tolerance for coplanar test (default 1e-8).\n"); - printf(" -d Detect intersections of PLC facets.\n"); - printf(" -z Numbers all output items starting from zero.\n"); - printf(" -j Jettison unused vertices from output .node file.\n"); - printf(" -o2 Generates second-order subparametric elements.\n"); - printf(" -f Outputs faces (including non-boundary faces) to .face "); - printf("file.\n"); - printf(" -e Outputs subsegments to .edge file.\n"); - printf(" -n Outputs tetrahedra neighbors to .neigh file.\n"); - printf(" -g Outputs mesh to .mesh file for viewing by Medit.\n"); - printf(" -G Outputs mesh to .msh file for viewing by Gid.\n"); - printf(" -O Outputs mesh to .off file for viewing by Geomview.\n"); - printf(" -B Suppresses output of boundary information.\n"); - printf(" -N Suppresses output of .node file.\n"); - printf(" -E Suppresses output of .ele file.\n"); - printf(" -F Suppresses output of .face file.\n"); - printf(" -I Suppresses mesh iteration numbers.\n"); - printf(" -C Checks the consistency of the final mesh.\n"); - printf(" -Q Quiet: No terminal output except errors.\n"); - printf(" -V Verbose: Detailed information, more terminal output.\n"); - printf(" -v Prints the version information.\n"); - printf(" -h Help: A brief instruction for using TetGen.\n"); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// usage() Print a brief instruction for using TetGen. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenbehavior::usage() -{ - printf("TetGen\n"); - printf("A Quality Tetrahedral Mesh Generator and 3D Delaunay "); - printf("Triangulator\n"); - versioninfo(); - printf("\n"); - printf("Copyright 2002, 2004\n"); - printf("Hang Si\n"); - printf("Rathausstr. 9, 10178 Berlin, Germany\n"); - printf("si@wias-berlin.de\n"); - printf("\n"); - printf("What Can TetGen Do?\n"); - printf("\n"); - printf(" TetGen generates exact Delaunay tetrahedralizations, exact\n"); - printf(" constrained Delaunay tetrahedralizations, and quality "); - printf("tetrahedral\n meshes. The latter are nicely graded and whose "); - printf("tetrahedra have\n radius-edge ratio bounded, thus are suitable "); - printf("for finite element and\n finite volume analysis.\n"); - printf("\n"); - printf("Command Line Syntax:\n"); - printf("\n"); - printf(" Below is the command line syntax of TetGen with a list of "); - printf("short\n"); - printf(" descriptions. Underscores indicate that numbers may optionally\n"); - printf(" follow certain switches. Do not leave any space between a "); - printf("switch\n"); - printf(" and its numeric parameter. \'input_file\' contains input data\n"); - printf(" depending on the switches you supplied which may be a "); - printf(" piecewise\n"); - printf(" linear complex or a list of nodes. File formats and detailed\n"); - printf(" description of command line switches are found in user's "); - printf("manual.\n"); - printf("\n"); - syntax(); - printf("\n"); - printf("Examples of How to Use TetGen:\n"); - printf("\n"); - printf(" \'tetgen object\' reads vertices from object.node, and writes "); - printf("their\n Delaunay tetrahedralization to object.1.node and "); - printf("object.1.ele.\n"); - printf("\n"); - printf(" \'tetgen -p object\' reads a PLC from object.poly or object."); - printf("smesh (and\n possibly object.node) and writes its constrained "); - printf("Delaunay\n tetrahedralization to object.1.node, object.1.ele and "); - printf("object.1.face.\n"); - printf("\n"); - printf(" \'tetgen -pq1.414a.1 object\' reads a PLC from object.poly or\n"); - printf(" object.smesh (and possibly object.node), generates a mesh "); - printf("whose\n tetrahedra have radius-edge ratio smaller than 1.414 and "); - printf("have volume\n of 0.1 or less, and writes the mesh to "); - printf("object.1.node, object.1.ele\n and object.1.face.\n"); - printf("\n"); - printf("Please send bugs/comments to Hang Si <si@wias-berlin.de>\n"); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// parse_commandline() Read the command line, identify switches, and set // -// up options and file names. // -// // -// 'argc' and 'argv' are the same parameters passed to the function main() // -// of a C/C++ program. They together represent the command line user invoked // -// from an environment in which TetGen is running. // -// // -// When TetGen is invoked from an environment. 'argc' is nonzero, switches // -// and input filename should be supplied as zero-terminated strings in // -// argv[0] through argv[argc - 1] and argv[0] shall be the name used to // -// invoke TetGen, i.e. "tetgen". Switches are previously started with a // -// dash '-' to identify them from the input filename. // -// // -// When TetGen is called from within another program. 'argc' is set to zero. // -// switches are given in one zero-terminated string (no previous dash is // -// required.), and 'argv' is a pointer points to this string. No input // -// filename is required (usually the input data has been directly created by // -// user in the 'tetgenio' structure). A default filename 'tetgen-tmpfile' // -// will be created for debugging output purpose. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenbehavior::parse_commandline(int argc, char **argv) -{ - int startindex; - int increment; - int meshnumber; - int i, j, k; - char workstring[1024]; - - // First determine the input style of the switches. - if (argc == 0) { - startindex = 0; // Switches are given without a dash. - argc = 1; // For running the following for-loop once. - commandline[0] = '\0'; - } else { - startindex = 1; - strcpy(commandline, argv[0]); - strcat(commandline, " "); - } - - for (i = startindex; i < argc; i++) { - // Remember the command line switches. - strcat(commandline, argv[i]); - strcat(commandline, " "); - if (startindex == 1) { - // Is this string a filename? - if (argv[i][0] != '-') { - strncpy(infilename, argv[i], 1024 - 1); - infilename[1024 - 1] = '\0'; - // Go to the next string directly. - continue; - } - } - // Parse the individual switch from the string. - for (j = startindex; argv[i][j] != '\0'; j++) { - if (argv[i][j] == 'p') { - plc = 1; - } else if (argv[i][j] == 'r') { - refine = 1; - } else if (argv[i][j] == 'q') { - quality = 1; - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - minratio = (REAL) strtod(workstring, (char **) NULL); - } - } else if (argv[i][j] == 'a') { - quality = 1; - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - fixedvolume = 1; - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') || - (argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - maxvolume = (REAL) strtod(workstring, (char **) NULL); - if (maxvolume <= 0.0) { - printf("Error: Number after -a must be greater than zero.\n"); - return false; - } - } else { - varvolume = 1; - } - } else if (argv[i][j] == 'A') { - regionattrib = 1; - } else if (argv[i][j] == 'i') { - insertaddpoints = 1; - } else if (argv[i][j] == 's') { - removesliver = 1; - if ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) { - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - maxdihedral = (REAL) strtod(workstring, (char **) NULL); - if (maxdihedral <= 0.0 || maxdihedral >= 180.0) { - printf("Error: Number after -s must between 0 and 180.\n"); - return false; - } - } else { - maxdihedral = 175.0; - } - maxdihedral = maxdihedral * 3.1415926535897932 / 180.; - } else if (argv[i][j] == 'd') { - detectinter = 1; - } else if (argv[i][j] == 'c') { - checkclosure = 1; - } else if (argv[i][j] == 'z') { - zeroindex = 1; - } else if (argv[i][j] == 'j') { - jettison = 1; - } else if (argv[i][j] == 'e') { - edgesout = 1; - } else if (argv[i][j] == 'n') { - neighout = 1; - } else if (argv[i][j] == 'g') { - meditview = 1; - } else if (argv[i][j] == 'G') { - gidview = 1; - } else if (argv[i][j] == 'O') { - geomview = 1; - } else if (argv[i][j] == 'B') { - nobound = 1; - } else if (argv[i][j] == 'N') { - nonodewritten = 1; - } else if (argv[i][j] == 'E') { - noelewritten = 1; - } else if (argv[i][j] == 'F') { - nofacewritten = 1; - } else if (argv[i][j] == 'I') { - noiterationnum = 1; - } else if (argv[i][j] == 'o') { - if (argv[i][j + 1] == '2') { - j++; - order = 2; - } - } else if (argv[i][j] == 'Y') { - noflip = 1; // nobisect++; - } else if (argv[i][j] == 'S') { - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') || - (argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - steiner = (int) strtol(workstring, (char **) NULL, 0); - } - } else if (argv[i][j] == 'P') { - dopermute = 1; - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') || - (argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - srandseed = (int) strtol(workstring, (char **) NULL, 0); - } - } else if (argv[i][j] == 'M') { - nomerge = 1; - } else if (argv[i][j] == 'T') { - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.') || (argv[i][j + 1] == 'e') || - (argv[i][j + 1] == '-') || (argv[i][j + 1] == '+')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - epsilon = (REAL) strtod(workstring, (char **) NULL); - } - if (epsilon <= 0.0) { - printf("Error: Number after -T must be greater than zero.\n"); - return false; - } - } else if (argv[i][j] == 'C') { - docheck++; - } else if (argv[i][j] == 'Q') { - quiet = 1; - } else if (argv[i][j] == 'V') { - verbose++; - } else if (argv[i][j] == 'v') { - versioninfo(); - exit(0); - } else if ((argv[i][j] == 'h') || (argv[i][j] == 'H') || - (argv[i][j] == '?')) { - usage(); - exit(0); - } else { - printf("Warning: Unknown switch -%c.\n", argv[i][j]); - } - } - } - - if (startindex == 0) { - // Set a temporary filename for debugging output. - strcpy(infilename, "tetgen-tmpfile"); - } else { - if (infilename[0] == '\0') { - // No input file name. Print the syntax and exit. - syntax(); - exit(0); - } - // Recognize the object from file extension if it is available. - if (!strcmp(&infilename[strlen(infilename) - 5], ".node")) { - infilename[strlen(infilename) - 5] = '\0'; - object = NODES; - } else if (!strcmp(&infilename[strlen(infilename) - 5], ".poly")) { - infilename[strlen(infilename) - 5] = '\0'; - object = POLY; - plc = 1; - } else if (!strcmp(&infilename[strlen(infilename) - 6], ".smesh")) { - infilename[strlen(infilename) - 6] = '\0'; - object = POLY; - plc = 1; - } else if (!strcmp(&infilename[strlen(infilename) - 4], ".off")) { - infilename[strlen(infilename) - 4] = '\0'; - object = OFF; - plc = 1; - } else if (!strcmp(&infilename[strlen(infilename) - 4], ".ply")) { - infilename[strlen(infilename) - 4] = '\0'; - object = PLY; - plc = 1; - } else if (!strcmp(&infilename[strlen(infilename) - 4], ".stl")) { - infilename[strlen(infilename) - 4] = '\0'; - object = STL; - plc = 1; - } else if (!strcmp(&infilename[strlen(infilename) - 5], ".mesh")) { - infilename[strlen(infilename) - 5] = '\0'; - object = MEDIT; - plc = 1; - } else if (!strcmp(&infilename[strlen(infilename) - 4], ".ele")) { - infilename[strlen(infilename) - 4] = '\0'; - object = MESH; - refine = 1; - } - } - plc = plc || detectinter || checkclosure; - useshelles = plc || refine || quality; - goodratio = minratio; - goodratio *= goodratio; - - // Detect improper combinations of switches. - if (plc && refine) { - printf("Error: Switch -r cannot use together with -p.\n"); - return false; - } - if (refine && (plc || noiterationnum)) { - printf("Error: Switches %s cannot use together with -r.\n", - "-p, -d, -c, and -I"); - return false; - } - if (detectinter && (quality || insertaddpoints || (order == 2) || neighout - || checkclosure || docheck)) { - printf("Error: Switches %s cannot use together with -d.\n", - "-c, -q, -i, -o2, -n, and -C"); - return false; - } - if (checkclosure && (quality || insertaddpoints || (order == 2) || neighout - || detectinter || docheck)) { - printf("Error: Switches %s cannot use together with -c.\n", - "-d, -q, -i, -o2, -n, and -C"); - return false; - } - - // Be careful not to allocate space for element area constraints that - // will never be assigned any value (other than the default -1.0). - if (!refine && !plc) { - varvolume = 0; - } - // Be careful not to add an extra attribute to each element unless the - // input supports it (PLC in, but not refining a preexisting mesh). - if (refine || !plc) { - regionattrib = 0; - } - // Calculate the goodangle for testing bad subfaces. - goodangle = cos(minangle * PI / 180.0); - goodangle *= goodangle; - - increment = 0; - strcpy(workstring, infilename); - j = 1; - while (workstring[j] != '\0') { - if ((workstring[j] == '.') && (workstring[j + 1] != '\0')) { - increment = j + 1; - } - j++; - } - meshnumber = 0; - if (increment > 0) { - j = increment; - do { - if ((workstring[j] >= '0') && (workstring[j] <= '9')) { - meshnumber = meshnumber * 10 + (int) (workstring[j] - '0'); - } else { - increment = 0; - } - j++; - } while (workstring[j] != '\0'); - } - if (noiterationnum) { - strcpy(outfilename, infilename); - } else if (increment == 0) { - strcpy(outfilename, infilename); - strcat(outfilename, ".1"); - } else { - workstring[increment] = '%'; - workstring[increment + 1] = 'd'; - workstring[increment + 2] = '\0'; - sprintf(outfilename, workstring, meshnumber + 1); - } - - return true; -} - -// -// End of class 'tetgenbehavior' implementation -// - -// -// Begin of class 'tetgenmesh' implementation -// - -// -// Begin of class 'list', 'memorypool' and 'link' implementation -// - -// Following are predefined compare functions for primitive data types. -// These functions take two pointers of the corresponding date type, -// perform the comparation. Return -1, 0 or 1 indicating the default -// linear order of two operators. - -// Compare two 'integers'. -int tetgenmesh::compare_2_ints(const void* x, const void* y) { - if (* (int *) x < * (int *) y) { - return -1; - } else if (* (int *) x > * (int *) y) { - return 1; - } else { - return 0; - } -} - -// Compare two 'longs'. Note: in 64-bit machine the 'long' type is 64-bit -// (8-byte) where the 'int' only 32-bit (4-byte). -int tetgenmesh::compare_2_longs(const void* x, const void* y) { - if (* (long *) x < * (long *) y) { - return -1; - } else if (* (long *) x > * (long *) y) { - return 1; - } else { - return 0; - } -} - -// Compare two 'unsigned longs'. -int tetgenmesh::compare_2_unsignedlongs(const void* x, const void* y) { - if (* (unsigned long *) x < * (unsigned long *) y) { - return -1; - } else if (* (unsigned long *) x > * (unsigned long *) y) { - return 1; - } else { - return 0; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// set_compfunc() Determine the size of primitive data types and set the // -// corresponding predefined linear order functions. // -// // -// 'str' is a zero-end string indicating a primitive data type, like 'int', // -// 'long' or 'unsigned long'. Every string ending with a '*' is though as a // -// type of pointer and the type 'unsign long' is used for it. // -// // -// When the type of 'str' is determined, the size of this type (in byte) is // -// returned in 'itbytes', and the pointer of corresponding predefined linear // -// order functions is returned in 'pcomp'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::set_compfunc(char* str, int* itbytes, compfunc* pcomp) -{ - // First figure out whether it is a pointer or not. - if (str[strlen(str) - 1] == '*') { - *itbytes = sizeof(unsigned long); - *pcomp = &compare_2_unsignedlongs; - return; - } - // Then determine other types. - if (strcmp(str, "int") == 0) { - *itbytes = sizeof(int); - *pcomp = &compare_2_ints; - } else if (strcmp(str, "long") == 0) { - *itbytes = sizeof(long); - *pcomp = &compare_2_longs; - } else if (strcmp(str, "unsigned long") == 0) { - *itbytes = sizeof(unsigned long); - *pcomp = &compare_2_unsignedlongs; - } else { - // It is an unknown type. - printf("Error in set_compfunc(): unknown type %s.\n", str); - exit(1); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// listinit() Initialize a list for storing a data type. // -// // -// Determine the size of each item, set the maximum size allocated at onece, // -// set the expand size in case the list is full, and set the linear order // -// function if it is provided (default is NULL). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::list:: -listinit(int itbytes, compfunc pcomp, int mitems,int exsize) -{ - assert(itbytes > 0 && mitems > 0 && exsize > 0); - - itembytes = itbytes; - comp = pcomp; - maxitems = mitems; - expandsize = exsize; - base = (char *) malloc(maxitems * itembytes); - if (base == (char *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - items = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// append() Add a new item at the end of the list. // -// // -// A new space at the end of this list will be allocated for storing the new // -// item. If the memory is not sufficient, reallocation will be performed. If // -// 'appitem' is not NULL, the contents of this pointer will be copied to the // -// new allocated space. Returns the pointer to the new allocated space. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::list::append(void *appitem) -{ - // Do we have enough space? - if (items == maxitems) { - char* newbase = (char *) realloc(base, (maxitems + expandsize) * - itembytes); - if (newbase == (char *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - base = newbase; - maxitems += expandsize; - } - if (appitem != (void *) NULL) { - memcpy(base + items * itembytes, appitem, itembytes); - } - items++; - return (void *) (base + (items - 1) * itembytes); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// insert() Insert an item before 'pos' (range from 0 to items - 1). // -// // -// A new space will be inserted at the position 'pos', that is, items lie // -// after pos (including the item at pos) will be moved one space downwords. // -// If 'insitem' is not NULL, its contents will be copied into the new // -// inserted space. Return a pointer to the new inserted space. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::list::insert(int pos, void* insitem) -{ - if (pos >= items) { - return append(insitem); - } - // Do we have enough space. - if (items == maxitems) { - char* newbase = (char *) realloc(base, (maxitems + expandsize) * - itembytes); - if (newbase == (char *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - base = newbase; - maxitems += expandsize; - } - // Do block move. - memmove(base + (pos + 1) * itembytes, // dest - base + pos * itembytes, // src - (items - pos) * itembytes); // size in bytes - // Insert the item. - if (insitem != (void *) NULL) { - memcpy(base + pos * itembytes, insitem, itembytes); - } - items++; - return (void *) (base + pos * itembytes); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// del() Delete an item at 'pos' (range from 0 to items - 1). // -// // -// The space at 'pos' will be overlapped by other items, that is, items lie // -// after pos will be moved one space upwords. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::list::del(int pos) -{ - // If 'pos' is the last itemof the list, nothing need to do. - if (pos >= 0 && pos < items - 1) { - // Do block move. - memmove(base + pos * itembytes, // dest - base + (pos + 1) * itembytes, // src - (items - pos - 1) * itembytes); - } - if (items > 0) { - items--; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// hasitem() Search in this list to find if 'checkitem' exists. // -// // -// This routine assumes that a linear order function has been set. It loops // -// through the entire list, compares each item to 'checkitem'. If it exists, // -// return its position (between 0 to items - 1), otherwise, return -1. // -// // -/////////////////////////////////////////////////////////////////////////////// - -int tetgenmesh::list::hasitem(void* checkitem) -{ - int i; - - for (i = 0; i < items; i++) { - if (comp != (compfunc) NULL) { - if ((* comp)((void *)(base + i * itembytes), checkitem) == 0) { - return i; - } - } - } - return -1; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// remove() Remove an item (indicated by its pointer) from the list. // -// // -// If the list contains more than one copy of the pointer, only the first // -// copy is removed. The returned value is the index of the removed item. // -// // -/////////////////////////////////////////////////////////////////////////////// - -int tetgenmesh::list::remove(void* remitem) -{ - int pos = hasitem(remitem); - if (pos != -1) { - del(pos); - } - return pos; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// sort() Sort the items with respect to a linear order function. // -// // -// Uses QuickSort routines (qsort) of the standard C/C++ library (stdlib.h). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::list::sort() -{ - qsort((void *) base, (size_t) items, (size_t) itembytes, comp); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// memorypool() The constructors of memorypool. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::memorypool::memorypool() -{ - firstblock = nowblock = (void **) NULL; - nextitem = (void *) NULL; - deaditemstack = (void *) NULL; - pathblock = (void **) NULL; - pathitem = (void *) NULL; - itemwordtype = POINTER; - alignbytes = 0; - itembytes = itemwords = 0; - itemsperblock = 0; - items = maxitems = 0l; - unallocateditems = 0; - pathitemsleft = 0; -} - -tetgenmesh::memorypool:: -memorypool(int bytecount, int itemcount, enum wordtype wtype, int alignment) -{ - poolinit(bytecount, itemcount, wtype, alignment); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// ~memorypool() Free to the operating system all memory taken by a pool. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::memorypool::~memorypool() -{ - while (firstblock != (void **) NULL) { - nowblock = (void **) *(firstblock); - free(firstblock); - firstblock = nowblock; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// poolinit() Initialize a pool of memory for allocation of items. // -// // -// A `pool' is created whose records have size at least `bytecount'. Items // -// will be allocated in `itemcount'-item blocks. Each item is assumed to be // -// a collection of words, and either pointers or floating-point values are // -// assumed to be the "primary" word type. (The "primary" word type is used // -// to determine alignment of items.) If `alignment' isn't zero, all items // -// will be `alignment'-byte aligned in memory. `alignment' must be either a // -// multiple or a factor of the primary word size; powers of two are safe. // -// `alignment' is normally used to create a few unused bits at the bottom of // -// each item's pointer, in which information may be stored. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::memorypool:: -poolinit(int bytecount, int itemcount, enum wordtype wtype, int alignment) -{ - int wordsize; - - // Initialize values in the pool. - itemwordtype = wtype; - wordsize = (itemwordtype == POINTER) ? sizeof(void *) : sizeof(REAL); - // Find the proper alignment, which must be at least as large as: - // - The parameter `alignment'. - // - The primary word type, to avoid unaligned accesses. - // - sizeof(void *), so the stack of dead items can be maintained - // without unaligned accesses. - if (alignment > wordsize) { - alignbytes = alignment; - } else { - alignbytes = wordsize; - } - if (sizeof(void *) > alignbytes) { - alignbytes = sizeof(void *); - } - itemwords = ((bytecount + alignbytes - 1) / alignbytes) - * (alignbytes / wordsize); - itembytes = itemwords * wordsize; - itemsperblock = itemcount; - - // Allocate a block of items. Space for `itemsperblock' items and one - // pointer (to point to the next block) are allocated, as well as space - // to ensure alignment of the items. - firstblock = (void **) malloc(itemsperblock * itembytes + sizeof(void *) - + alignbytes); - if (firstblock == (void **) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - // Set the next block pointer to NULL. - *(firstblock) = (void *) NULL; - restart(); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// restart() Deallocate all items in this pool. // -// // -// The pool is returned to its starting state, except that no memory is // -// freed to the operating system. Rather, the previously allocated blocks // -// are ready to be reused. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::memorypool::restart() -{ - unsigned long alignptr; - - items = 0; - maxitems = 0; - - // Set the currently active block. - nowblock = firstblock; - // Find the first item in the pool. Increment by the size of (void *). - alignptr = (unsigned long) (nowblock + 1); - // Align the item on an `alignbytes'-byte boundary. - nextitem = (void *) - (alignptr + (unsigned long) alignbytes - - (alignptr % (unsigned long) alignbytes)); - // There are lots of unallocated items left in this block. - unallocateditems = itemsperblock; - // The stack of deallocated items is empty. - deaditemstack = (void *) NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// alloc() Allocate space for an item. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::memorypool::alloc() -{ - void *newitem; - void **newblock; - unsigned long alignptr; - - // First check the linked list of dead items. If the list is not - // empty, allocate an item from the list rather than a fresh one. - if (deaditemstack != (void *) NULL) { - newitem = deaditemstack; // Take first item in list. - deaditemstack = * (void **) deaditemstack; - } else { - // Check if there are any free items left in the current block. - if (unallocateditems == 0) { - // Check if another block must be allocated. - if (*nowblock == (void *) NULL) { - // Allocate a new block of items, pointed to by the previous block. - newblock = (void **) malloc(itemsperblock * itembytes + sizeof(void *) - + alignbytes); - if (newblock == (void **) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - *nowblock = (void *) newblock; - // The next block pointer is NULL. - *newblock = (void *) NULL; - } - // Move to the new block. - nowblock = (void **) *nowblock; - // Find the first item in the block. - // Increment by the size of (void *). - alignptr = (unsigned long) (nowblock + 1); - // Align the item on an `alignbytes'-byte boundary. - nextitem = (void *) - (alignptr + (unsigned long) alignbytes - - (alignptr % (unsigned long) alignbytes)); - // There are lots of unallocated items left in this block. - unallocateditems = itemsperblock; - } - // Allocate a new item. - newitem = nextitem; - // Advance `nextitem' pointer to next free item in block. - if (itemwordtype == POINTER) { - nextitem = (void *) ((void **) nextitem + itemwords); - } else { - nextitem = (void *) ((REAL *) nextitem + itemwords); - } - unallocateditems--; - maxitems++; - } - items++; - return newitem; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// dealloc() Deallocate space for an item. // -// // -// The deallocated space is stored in a queue for later reuse. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::memorypool::dealloc(void *dyingitem) -{ - // Push freshly killed item onto stack. - *((void **) dyingitem) = deaditemstack; - deaditemstack = dyingitem; - items--; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// traversalinit() Prepare to traverse the entire list of items. // -// // -// This routine is used in conjunction with traverse(). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::memorypool::traversalinit() -{ - unsigned long alignptr; - - // Begin the traversal in the first block. - pathblock = firstblock; - // Find the first item in the block. Increment by the size of (void *). - alignptr = (unsigned long) (pathblock + 1); - // Align with item on an `alignbytes'-byte boundary. - pathitem = (void *) - (alignptr + (unsigned long) alignbytes - - (alignptr % (unsigned long) alignbytes)); - // Set the number of items left in the current block. - pathitemsleft = itemsperblock; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// traverse() Find the next item in the list. // -// // -// This routine is used in conjunction with traversalinit(). Be forewarned // -// that this routine successively returns all items in the list, including // -// deallocated ones on the deaditemqueue. It's up to you to figure out which // -// ones are actually dead. It can usually be done more space-efficiently by // -// a routine that knows something about the structure of the item. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::memorypool::traverse() -{ - void *newitem; - unsigned long alignptr; - - // Stop upon exhausting the list of items. - if (pathitem == nextitem) { - return (void *) NULL; - } - // Check whether any untraversed items remain in the current block. - if (pathitemsleft == 0) { - // Find the next block. - pathblock = (void **) *pathblock; - // Find the first item in the block. Increment by the size of (void *). - alignptr = (unsigned long) (pathblock + 1); - // Align with item on an `alignbytes'-byte boundary. - pathitem = (void *) - (alignptr + (unsigned long) alignbytes - - (alignptr % (unsigned long) alignbytes)); - // Set the number of items left in the current block. - pathitemsleft = itemsperblock; - } - newitem = pathitem; - // Find the next item in the block. - if (itemwordtype == POINTER) { - pathitem = (void *) ((void **) pathitem + itemwords); - } else { - pathitem = (void *) ((REAL *) pathitem + itemwords); - } - pathitemsleft--; - return newitem; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// linkinit() Initialize a link for storing items. // -// // -// The input parameters are the size of each item, a pointer of a linear // -// order function and the number of items allocating in one memory bulk. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::link::linkinit(int bytecount, compfunc pcomp, int itemcount) -{ - assert(bytecount > 0 && itemcount > 0); - - // Remember the real size of each item. - linkitembytes = bytecount; - // Set the linear order function for this link. - comp = pcomp; - - // Call the constructor of 'memorypool' to initialize its variables. - // like: itembytes, itemwords, items, ... Each node has size - // bytecount + 2 * sizeof(void **), and total 'itemcount + 2' (because - // link has additional two nodes 'head' and 'tail'). - poolinit(bytecount + 2 * sizeof(void **), itemcount + 2, POINTER, 0); - - // Initial state of this link. - head = (void **) alloc(); - tail = (void **) alloc(); - *head = (void *) tail; - *(head + 1) = NULL; - *tail = NULL; - *(tail + 1) = (void *) head; - nextlinkitem = *head; - curpos = 1; - linkitems = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// clear() Deallocate all nodes in this link. // -// // -// The link is returned to its starting state, except that no memory is // -// freed to the operating system. Rather, the previously allocated blocks // -// are ready to be reused. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::link::clear() -{ - // Reset the pool. - restart(); - - // Initial state of this link. - head = (void **) alloc(); - tail = (void **) alloc(); - *head = (void *) tail; - *(head + 1) = NULL; - *tail = NULL; - *(tail + 1) = (void *) head; - nextlinkitem = *head; - curpos = 1; - linkitems = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// move() Causes 'nextlinkitem' to traverse the specified number of nodes,// -// updates 'curpos' to be the node to which 'nextlinkitem' points. // -// // -// 'numberofnodes' is a number indicating how many nodes need be traversed // -// (not counter the current node) need be traversed. It may be positive(move // -// forward) or negative (move backward). Return TRUE if it is successful. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::link::move(int numberofnodes) -{ - void **nownode; - int i; - - nownode = (void **) nextlinkitem; - if (numberofnodes > 0) { - // Move forward. - i = 0; - while ((i < numberofnodes) && *nownode) { - nownode = (void **) *nownode; - i++; - } - if (*nownode == NULL) return false; - nextlinkitem = (void *) nownode; - curpos += numberofnodes; - } else if (numberofnodes < 0) { - // Move backward. - i = 0; - numberofnodes = -numberofnodes; - while ((i < numberofnodes) && *(nownode + 1)) { - nownode = (void **) *(nownode + 1); - i++; - } - if (*(nownode + 1) == NULL) return false; - nextlinkitem = (void *) nownode; - curpos -= numberofnodes; - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// locate() Locates the node at the specified position. // -// // -// The number 'pos' (between 1 and 'linkitems') indicates the location. This // -// routine first decides the shortest path traversing from 'curpos' to 'pos',// -// i.e., from head, tail or 'curpos'. Routine 'move()' is called to really // -// traverse the link. If success, 'nextlinkitem' points to the node, 'curpos'// -// and 'pos' are equal. Otherwise, return FALSE. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::link::locate(int pos) -{ - int headdist, taildist, curdist; - int abscurdist, mindist; - - if (pos < 1 || pos > linkitems) return false; - - headdist = pos - 1; - taildist = linkitems - pos; - curdist = pos - curpos; - abscurdist = curdist >= 0 ? curdist : -curdist; - - if (headdist > taildist) { - if (taildist > abscurdist) { - mindist = curdist; - } else { - // taildist <= abs(curdist) - mindist = -taildist; - goend(); - } - } else { - // headdist <= taildist - if (headdist > abscurdist) { - mindist = curdist; - } else { - // headdist <= abs(curdist) - mindist = headdist; - rewind(); - } - } - - return move(mindist); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// add() Add a node at the end of this link. // -// // -// A new node is appended to the end of the link. If 'newitem' is not NULL, // -// its conents will be copied to the data slot of the new node. Returns the // -// pointer to the newest added node. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::link::add(void* newitem) -{ - void **newnode = tail; - if (newitem != (void *) NULL) { - memcpy((void *)(newnode + 2), newitem, linkitembytes); - } - tail = (void **) alloc(); - *tail = NULL; - *newnode = (void*) tail; - *(tail + 1) = (void*) newnode; - linkitems++; - return (void *)(newnode + 2); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// insert() Inserts a node before the specified position. // -// // -// 'pos' (between 1 and 'linkitems') indicates the inserting position. This // -// routine inserts a new node before the node of 'pos'. If 'newitem' is not // -// NULL, its conents will be copied into the data slot of the new node. If // -// 'pos' is larger than 'linkitems', it is equal as 'add()'. A pointer to // -// the newest inserted item is returned. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::link::insert(int pos, void* insitem) -{ - if (!locate(pos)) { - return add(insitem); - } - - void **nownode = (void **) nextlinkitem; - - // Insert a node before 'nownode'. - void **newnode = (void **) alloc(); - if (insitem != (void *) NULL) { - memcpy((void *)(newnode + 2), insitem, linkitembytes); - } - - *(void **)(*(nownode + 1)) = (void *) newnode; - *newnode = (void *) nownode; - *(newnode + 1) = *(nownode + 1); - *(nownode + 1) = (void *) newnode; - - linkitems++; - - nextlinkitem = (void *) newnode; - return (void *)(newnode + 2); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// del() Delete a node containing the given pointer. // -// // -// Returns a pointer of the deleted data. If you try to delete a non-existed // -// node (e.g. link is empty or a wrong index is given) return NULL. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::link::del(void* delitem) -{ - void **deadnode = (void **) ((void **) delitem - 2); - - // now delete the nownode - void **nextnode = (void **) *deadnode; - void **prevnode = (void **) *(deadnode + 1); - *prevnode = (void *) nextnode; - *(nextnode + 1) = (void *) prevnode; - - dealloc((void *) deadnode); - linkitems--; - - nextlinkitem = (void *) nextnode; - return (void *)(deadnode + 2); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// del() Delete a node at the specified position. // -// // -// 'pos' between 1 and 'linkitems'. Returns a pointer of the deleted data. // -// If you try to delete a non-existed node (e.g. link is empty or a wrong // -// index is given) return NULL. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::link::del(int pos) -{ - if (!locate(pos) || (linkitems == 0)) { - return (void *) NULL; - } - return del((void *) ((void **) nextlinkitem + 2)); - /* - void **deadnode = (void **)nextlinkitem; - - // now delete the nownode - void **nextnode = (void **) *deadnode; - void **prevnode = (void **) *(deadnode + 1); - *prevnode = (void *) nextnode; - *(nextnode + 1) = (void *) prevnode; - - dealloc((void *) deadnode); - linkitems--; - - nextlinkitem = (void *) nextnode; - return (void *)(deadnode + 2); - */ -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getitem() The link traversal routine. // -// // -// Returns the node to which 'nextlinkitem' points. Returns a 'NULL' if the // -// end of the link is reaching. Both 'nextlinkitem' and 'curpos' will be // -// updated after this operation. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::link::getitem() -{ - if (nextlinkitem == (void *) tail) return NULL; - void **nownode = (void **) nextlinkitem; - nextlinkitem = *nownode; - curpos += 1; - return (void *)(nownode + 2); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getnitem() Returns the node at a specified position. // -// // -// 'pos' between 1 and 'linkitems'. After this operation, 'nextlinkitem' and // -// 'curpos' will be updated to indicate this node. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void* tetgenmesh::link::getnitem(int pos) -{ - if (!locate(pos)) return NULL; - return (void *)((void **) nextlinkitem + 2); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// hasitem() Search in this link to find if 'checkitem' exists. // -// // -// If 'checkitem' exists, return its position (between 1 to 'linkitems'), // -// otherwise, return -1. This routine requires the linear order function has // -// been set. // -// // -/////////////////////////////////////////////////////////////////////////////// - -int tetgenmesh::link::hasitem(void* checkitem) -{ - void *pathitem; - int count; - - rewind(); - pathitem = getitem(); - count = 0; - while (pathitem) { - count ++; - if (comp) { - if ((* comp)(pathitem, checkitem) == 0) { - return count; - } - } - pathitem = getitem(); - } - return -1; -} - -// -// End of class 'list', 'memorypool' and 'link' implementation -// - -// -// Begin of mesh manipulation primitives -// - -// -// Begin of tables initialization. -// - -// For enumerating three edges of a triangle. - -int tetgenmesh::plus1mod3[3] = {1, 2, 0}; -int tetgenmesh::minus1mod3[3] = {2, 0, 1}; - -// Table 've' takes an edge version as input, returns the next edge version -// in the same edge ring. - -int tetgenmesh::ve[6] = { 2, 5, 4, 1, 0, 3 }; - -// Tables 'vo', 'vd' and 'va' take an edge version, return the positions of -// the origin, destination and apex in the triangle. - -int tetgenmesh::vo[6] = { 0, 1, 1, 2, 2, 0 }; -int tetgenmesh::vd[6] = { 1, 0, 2, 1, 0, 2 }; -int tetgenmesh::va[6] = { 2, 2, 0, 0, 1, 1 }; - -// The following tables are for tetrahedron primitives (operate on trifaces). - -// For 'org()', 'dest()' and 'apex()'. Use 'loc' as the first index and -// 'ver' as the second index. - -int tetgenmesh::locver2org[4][6] = { - 0, 1, 1, 2, 2, 0, - 0, 3, 3, 1, 1, 0, - 1, 3, 3, 2, 2, 1, - 2, 3, 3, 0, 0, 2 -}; -int tetgenmesh::locver2dest[4][6] = { - 1, 0, 2, 1, 0, 2, - 3, 0, 1, 3, 0, 1, - 3, 1, 2, 3, 1, 2, - 3, 2, 0, 3, 2, 0 -}; -int tetgenmesh::locver2apex[4][6] = { - 2, 2, 0, 0, 1, 1, - 1, 1, 0, 0, 3, 3, - 2, 2, 1, 1, 3, 3, - 0, 0, 2, 2, 3, 3 -}; - -// For oppo() primitives, use 'loc' as the index. - -int tetgenmesh::loc2oppo[4] = { 3, 2, 0, 1 }; - -// For fnext() primitive. Use 'loc' as the first index and 'ver' as the -// second index. Returns a new 'loc' and new 'ver' in an array. (It is -// only valid for edge version equals one of {0, 2, 4}.) - -int tetgenmesh::locver2nextf[4][6][2] = { - { {1, 5}, {-1, -1}, {2, 5}, {-1, -1}, {3, 5}, {-1, -1} }, - { {3, 3}, {-1, -1}, {2, 1}, {-1, -1}, {0, 1}, {-1, -1} }, - { {1, 3}, {-1, -1}, {3, 1}, {-1, -1}, {0, 3}, {-1, -1} }, - { {2, 3}, {-1, -1}, {1, 1}, {-1, -1}, {0, 5}, {-1, -1} } -}; - -// -// End of tables initialization. -// - -// Some macros for convenience - -#define Div2 >> 1 -#define Mod2 & 01 - -// NOTE: These bit operators should only be used in macros below. - -// Get orient(Range from 0 to 2) from face version(Range from 0 to 5). - -#define Orient(V) ((V) Div2) - -// Determine edge ring(0 or 1) from face version(Range from 0 to 5). - -#define EdgeRing(V) ((V) Mod2) - -// -// Begin of primitives for tetrahedra -// - -// Each tetrahedron contains four pointers to its neighboring tetrahedra, -// with face indices. To save memory, both information are kept in a -// single pointer. To make this possible, all tetrahedra are aligned to -// eight-byte boundaries, so that the last three bits of each pointer are -// zeros. A face index (in the range 0 to 3) is compressed into the last -// two bits of each pointer by the function 'encode()'. The function -// 'decode()' decodes a pointer, extracting a face index and a pointer to -// the beginning of a tetrahedron. - -inline void tetgenmesh::decode(tetrahedron ptr, triface& t) { - t.loc = (int) ((unsigned long) (ptr) & (unsigned long) 3l); - t.tet = (tetrahedron *) ((unsigned long) (ptr) & ~(unsigned long) 7l); -} - -inline tetgenmesh::tetrahedron tetgenmesh::encode(triface& t) { - return (tetrahedron) ((unsigned long) t.tet | (unsigned long) t.loc); -} - -// sym() finds the abutting tetrahedron on the same face. - -inline void tetgenmesh::sym(triface& t1, triface& t2) { - tetrahedron ptr = t1.tet[t1.loc]; - decode(ptr, t2); -} - -inline void tetgenmesh::symself(triface& t) { - tetrahedron ptr = t.tet[t.loc]; - decode(ptr, t); -} - -// Bond two tetrahedra together at their faces. - -inline void tetgenmesh::bond(triface& t1, triface& t2) { - t1.tet[t1.loc] = encode(t2); - t2.tet[t2.loc] = encode(t1); -} - -// Dissolve a bond (from one side). Note that the other tetrahedron will -// still think it is connected to this tetrahedron. Usually, however, -// the other tetrahedron is being deleted entirely, or bonded to another -// tetrahedron, so it doesn't matter. - -inline void tetgenmesh::dissolve(triface& t) { - t.tet[t.loc] = (tetrahedron) dummytet; -} - -// These primitives determine or set the origin, destination, apex or -// opposition of a tetrahedron with respect to 'loc' and 'ver'. - -inline tetgenmesh::point tetgenmesh::org(triface& t) { - return (point) t.tet[locver2org[t.loc][t.ver] + 4]; -} - -inline tetgenmesh::point tetgenmesh::dest(triface& t) { - return (point) t.tet[locver2dest[t.loc][t.ver] + 4]; -} - -inline tetgenmesh::point tetgenmesh::apex(triface& t) { - return (point) t.tet[locver2apex[t.loc][t.ver] + 4]; -} - -inline tetgenmesh::point tetgenmesh::oppo(triface& t) { - return (point) t.tet[loc2oppo[t.loc] + 4]; -} - -inline void tetgenmesh::setorg(triface& t, point pointptr) { - t.tet[locver2org[t.loc][t.ver] + 4] = (tetrahedron) pointptr; -} - -inline void tetgenmesh::setdest(triface& t, point pointptr) { - t.tet[locver2dest[t.loc][t.ver] + 4] = (tetrahedron) pointptr; -} - -inline void tetgenmesh::setapex(triface& t, point pointptr) { - t.tet[locver2apex[t.loc][t.ver] + 4] = (tetrahedron) pointptr; -} - -inline void tetgenmesh::setoppo(triface& t, point pointptr) { - t.tet[loc2oppo[t.loc] + 4] = (tetrahedron) pointptr; -} - -// These primitives were drived from Mucke's triangle-edge data structure -// to change face-edge relation in a tetrahedron (esym, enext and enext2) -// or between two tetrahedra (fnext). - -// If e0 = e(i, j), e1 = e(j, i), that is e0 and e1 are the two directions -// of the same undirected edge of a face. e0.sym() = e1 and vice versa. - -inline void tetgenmesh::esym(triface& t1, triface& t2) { - t2.tet = t1.tet; - t2.loc = t1.loc; - t2.ver = t1.ver + (EdgeRing(t1.ver) ? -1 : 1); -} - -inline void tetgenmesh::esymself(triface& t) { - t.ver += (EdgeRing(t.ver) ? -1 : 1); -} - -// If e0 and e1 are both in the same edge ring of a face, e1 = e0.enext(). - -inline void tetgenmesh::enext(triface& t1, triface& t2) { - t2.tet = t1.tet; - t2.loc = t1.loc; - t2.ver = ve[t1.ver]; -} - -inline void tetgenmesh::enextself(triface& t) { - t.ver = ve[t.ver]; -} - -// enext2() is equal to e2 = e0.enext().enext() - -inline void tetgenmesh::enext2(triface& t1, triface& t2) { - t2.tet = t1.tet; - t2.loc = t1.loc; - t2.ver = ve[ve[t1.ver]]; -} - -inline void tetgenmesh::enext2self(triface& t) { - t.ver = ve[ve[t.ver]]; -} - -// If f0 and f1 are both in the same face ring of a face, f1 = f0.fnext(). -// If f1 exists, return true. Otherwise, return false, i.e., f0 is a -// boundary or hull face. - -inline bool tetgenmesh::fnext(triface& t1, triface& t2) { - return getnextface(&t1, &t2); -} - -inline bool tetgenmesh::fnextself(triface& t) { - return getnextface(&t, NULL); -} - -// enextfnext() and enext2fnext() are combination primitives of enext(), -// enext2() and fnext(). - -inline void tetgenmesh::enextfnext(triface& t1, triface& t2) { - enext(t1, t2); - fnextself(t2); -} - -inline void tetgenmesh::enextfnextself(triface& t) { - enextself(t); - fnextself(t); -} - -inline void tetgenmesh::enext2fnext(triface& t1, triface& t2) { - enext2(t1, t2); - fnextself(t2); -} - -inline void tetgenmesh::enext2fnextself(triface& t) { - enext2self(t); - fnextself(t); -} - -// Primitives to infect or cure a tetrahedron with the virus. The last -// third bit of the pointer is marked for infection. These rely on the -// assumption that all tetrahedron are aligned to eight-byte boundaries. - -inline void tetgenmesh::infect(triface& t) { - t.tet[0] = (tetrahedron) ((unsigned long) t.tet[0] | (unsigned long) 4l); -} - -inline void tetgenmesh::uninfect(triface& t) { - t.tet[0] = (tetrahedron) ((unsigned long) t.tet[0] & ~ (unsigned long) 4l); -} - -// Test a tetrahedron for viral infection. - -inline bool tetgenmesh::infected(triface& t) { - return (((unsigned long) t.tet[0] & (unsigned long) 4l) != 0); -} - -// Check or set a tetrahedron's attributes. - -inline REAL tetgenmesh::elemattribute(tetrahedron* ptr, int attnum) { - return ((REAL *) (ptr))[elemattribindex + attnum]; -} - -inline void tetgenmesh:: -setelemattribute(tetrahedron* ptr, int attnum, REAL value){ - ((REAL *) (ptr))[elemattribindex + attnum] = value; -} - -// Check or set a tetrahedron's maximum volume bound. - -inline REAL tetgenmesh::volumebound(tetrahedron* ptr) { - return ((REAL *) (ptr))[volumeboundindex]; -} - -inline void tetgenmesh::setvolumebound(tetrahedron* ptr, REAL value) { - ((REAL *) (ptr))[volumeboundindex] = value; -} - -// -// End of primitives for tetrahedra -// - -// -// Begin of primitives for subfaces/subsegments -// - -// Each subface contains three pointers to its neighboring subfaces, with -// edge versions. To save memory, both information are kept in a single -// pointer. To make this possible, all subfaces are aligned to eight-byte -// boundaries, so that the last three bits of each pointer are zeros. An -// edge version (in the range 0 to 5) is compressed into the last three -// bits of each pointer by 'sencode()'. 'sdecode()' decodes a pointer, -// extracting an edge version and a pointer to the beginning of a subface. - -inline void tetgenmesh::sdecode(shellface sptr, face& s) { - s.shver = (int) ((unsigned long) (sptr) & (unsigned long) 7l); - s.sh = (shellface *) ((unsigned long) (sptr) & ~ (unsigned long) 7l); -} - -inline tetgenmesh::shellface tetgenmesh::sencode(face& s) { - return (shellface) ((unsigned long) s.sh | (unsigned long) s.shver); -} - -// spivot() finds the other subface (from this subface) that shares the -// same edge. - -inline void tetgenmesh::spivot(face& s1, face& s2) { - shellface sptr = s1.sh[Orient(s1.shver)]; - sdecode(sptr, s2); -} - -inline void tetgenmesh::spivotself(face& s) { - shellface sptr = s.sh[Orient(s.shver)]; - sdecode(sptr, s); -} - -// sbond() bonds two subfaces together, i.e., after bonding, both faces -// are pointing to each other. - -inline void tetgenmesh::sbond(face& s1, face& s2) { - s1.sh[Orient(s1.shver)] = sencode(s2); - s2.sh[Orient(s2.shver)] = sencode(s1); -} - -// sbond1() only bonds s2 to s1, i.e., after bonding, s1 is pointing to s2, -// but s2 is not pointing to s1. - -inline void tetgenmesh::sbond1(face& s1, face& s2) { - s1.sh[Orient(s1.shver)] = sencode(s2); -} - -// Dissolve a subface bond (from one side). Note that the other subface -// will still think it's connected to this subface. - -inline void tetgenmesh::sdissolve(face& s) { - s.sh[Orient(s.shver)] = (shellface) dummysh; -} - -// These primitives determine or set the origin, destination, or apex -// of a subface with respect to the edge version. - -inline tetgenmesh::point tetgenmesh::sorg(face& s) { - return (point) s.sh[3 + vo[s.shver]]; -} - -inline tetgenmesh::point tetgenmesh::sdest(face& s) { - return (point) s.sh[3 + vd[s.shver]]; -} - -inline tetgenmesh::point tetgenmesh::sapex(face& s) { - return (point) s.sh[3 + va[s.shver]]; -} - -inline void tetgenmesh::setsorg(face& s, point pointptr) { - s.sh[3 + vo[s.shver]] = (shellface) pointptr; -} - -inline void tetgenmesh::setsdest(face& s, point pointptr) { - s.sh[3 + vd[s.shver]] = (shellface) pointptr; -} - -inline void tetgenmesh::setsapex(face& s, point pointptr) { - s.sh[3 + va[s.shver]] = (shellface) pointptr; -} - -// These primitives were drived from Mucke[2]'s triangle-edge data structure -// to change face-edge relation in a subface (sesym, senext and senext2). - -inline void tetgenmesh::sesym(face& s1, face& s2) { - s2.sh = s1.sh; - s2.shver = s1.shver + (EdgeRing(s1.shver) ? -1 : 1); -} - -inline void tetgenmesh::sesymself(face& s) { - s.shver += (EdgeRing(s.shver) ? -1 : 1); -} - -inline void tetgenmesh::senext(face& s1, face& s2) { - s2.sh = s1.sh; - s2.shver = ve[s1.shver]; -} - -inline void tetgenmesh::senextself(face& s) { - s.shver = ve[s.shver]; -} - -inline void tetgenmesh::senext2(face& s1, face& s2) { - s2.sh = s1.sh; - s2.shver = ve[ve[s1.shver]]; -} - -inline void tetgenmesh::senext2self(face& s) { - s.shver = ve[ve[s.shver]]; -} - -// If f0 and f1 are both in the same face ring, then f1 = f0.fnext(), - -inline void tetgenmesh::sfnext(face& s1, face& s2) { - getnextsface(&s1, &s2); -} - -inline void tetgenmesh::sfnextself(face& s) { - getnextsface(&s, NULL); -} - -// These primitives read or set a pointer of the badface structure. The -// pointer is stored sh[11]. - -inline tetgenmesh::badface* tetgenmesh::shell2badface(face& s) { - return (badface*) s.sh[11]; -} - -inline void tetgenmesh::setshell2badface(face& s, badface* value) { - s.sh[11] = (shellface) value; -} - -// Check or set a subface's maximum area bound. - -inline REAL tetgenmesh::areabound(face& s) { - return ((REAL *) (s.sh))[areaboundindex]; -} - -inline void tetgenmesh::setareabound(face& s, REAL value) { - ((REAL *) (s.sh))[areaboundindex] = value; -} - -// These primitives read or set a shell marker. Shell markers are used -// to hold user boundary information. - -inline int tetgenmesh::shellmark(face& s) { - return ((int *) (s.sh))[shmarkindex]; -} - -inline void tetgenmesh::setshellmark(face& s, int value) { - ((int *) (s.sh))[shmarkindex] = value; -} - -// These primitives set or read the type of the subface or subsegment. - -inline enum tetgenmesh::shestype tetgenmesh::shelltype(face& s) { - return (enum shestype) ((int *) (s.sh))[shmarkindex + 1]; -} - -inline void tetgenmesh::setshelltype(face& s, enum shestype value) { - ((int *) (s.sh))[shmarkindex + 1] = (int) value; -} - -// Primitives to infect or cure a subface with the virus. These rely on the -// assumption that all tetrahedra are aligned to eight-byte boundaries. - -inline void tetgenmesh::sinfect(face& s) { - s.sh[6] = (shellface) ((unsigned long) s.sh[6] | (unsigned long) 4l); -} - -inline void tetgenmesh::suninfect(face& s) { - s.sh[6] = (shellface)((unsigned long) s.sh[6] & ~(unsigned long) 4l); -} - -// Test a subface for viral infection. - -inline bool tetgenmesh::sinfected(face& s) { - return (((unsigned long) s.sh[6] & (unsigned long) 4l) != 0); -} - -// -// End of primitives for subfaces/subsegments -// - -// -// Begin of primitives for interacting between tetrahedra and subfaces -// - -// tspivot() finds a subface abutting on this tetrahdera. - -inline void tetgenmesh::tspivot(triface& t, face& s) { - shellface sptr = (shellface) t.tet[8 + t.loc]; - sdecode(sptr, s); -} - -// stpivot() finds a tetrahedron abutting a subface. - -inline void tetgenmesh::stpivot(face& s, triface& t) { - tetrahedron ptr = (tetrahedron) s.sh[6 + EdgeRing(s.shver)]; - decode(ptr, t); -} - -// tsbond() bond a tetrahedron to a subface. - -inline void tetgenmesh::tsbond(triface& t, face& s) { - t.tet[8 + t.loc] = (tetrahedron) sencode(s); - s.sh[6 + EdgeRing(s.shver)] = (shellface) encode(t); -} - -// tsdissolve() dissolve a bond (from the tetrahedron side). - -inline void tetgenmesh::tsdissolve(triface& t) { - t.tet[8 + t.loc] = (tetrahedron) dummysh; -} - -// stdissolve() dissolve a bond (from the subface side). - -inline void tetgenmesh::stdissolve(face& s) { - s.sh[6 + EdgeRing(s.shver)] = (shellface) dummytet; -} - -// -// End of primitives for interacting between tetrahedra and subfaces -// - -// -// Begin of primitives for interacting between subfaces and subsegs -// - -// sspivot() finds a subsegment abutting a subface. - -inline void tetgenmesh::sspivot(face& s, face& edge) { - shellface sptr = (shellface) s.sh[8 + Orient(s.shver)]; - sdecode(sptr, edge); -} - -// ssbond() bond a subface to a subsegment. - -inline void tetgenmesh::ssbond(face& s, face& edge) { - s.sh[8 + Orient(s.shver)] = sencode(edge); - edge.sh[0] = sencode(s); -} - -// ssdisolve() dissolve a bond (from the subface side) - -inline void tetgenmesh::ssdissolve(face& s) { - s.sh[8 + Orient(s.shver)] = (shellface) dummysh; -} - -// -// End of primitives for interacting between subfaces and subsegs -// - -// -// Begin of primitives for points -// - -inline int tetgenmesh::pointmark(point pt) { - return ((int *) (pt))[pointmarkindex]; -} - -inline void tetgenmesh::setpointmark(point pt, int value) { - ((int *) (pt))[pointmarkindex] = value; -} - -// These two primitives set and read the type of the point. - -inline enum tetgenmesh::verttype tetgenmesh::pointtype(point pt) { - return (enum verttype) ((int *) (pt))[pointmarkindex + 1]; -} - -inline void tetgenmesh::setpointtype(point pt, enum verttype value) { - ((int *) (pt))[pointmarkindex + 1] = (int) value; -} - -// These two primitives set and read a pointer to a tetrahedron. - -inline tetgenmesh::tetrahedron tetgenmesh::point2tet(point pt) { - return ((tetrahedron *) (pt))[point2simindex]; -} - -inline void tetgenmesh::setpoint2tet(point pt, tetrahedron value) { - ((tetrahedron *) (pt))[point2simindex] = value; -} - -// These two primitives set and read a pointer to a subface/subsegment. -// Note: they use the same field as the above. Don't use them together. - -inline tetgenmesh::shellface tetgenmesh::point2sh(point pt) { - return (shellface) ((tetrahedron *) (pt))[point2simindex]; -} - -inline void tetgenmesh::setpoint2sh(point pt, shellface value) { - ((tetrahedron *) (pt))[point2simindex] = (tetrahedron) value; -} - -// These two primitives set and read a pointer to a point. -// Note: they use the same field as the above. Don't use them together. - -inline tetgenmesh::point tetgenmesh::point2pt(point pt) { - return (point) ((tetrahedron *) (pt))[point2simindex]; -} - -inline void tetgenmesh::setpoint2pt(point pt, point value) { - ((tetrahedron *) (pt))[point2simindex] = (tetrahedron) value; -} - -// These primitives set and read a pointer to its parent point. They're used -// only in qulaity conforming Delaunay mesh algorithm. - -inline tetgenmesh::point tetgenmesh::point2ppt(point pt) { - return (point) ((tetrahedron *) (pt))[point2simindex + 1]; -} - -inline void tetgenmesh::setpoint2ppt(point pt, point value) { - ((tetrahedron *) (pt))[point2simindex + 1] = (tetrahedron) value; -} - -// Get the pre-calculated lifting point of a facet (specified by its mark). - -inline tetgenmesh::point tetgenmesh::getliftpoint(int facetmark) { - return (point) &liftpointarray[(facetmark - 1) * 3]; -} - -// -// End of primitives for points -// - -// -// Begin of advanced primitives -// - -// adjustedgering() adjusts the edge version so that it belongs to the -// indicated edge ring. The 'direction' only can be 0(CCW) or 1(CW). -// If the edge is not in the wanted edge ring, reverse it. - -inline void tetgenmesh::adjustedgering(triface& t, int direction) { - if (EdgeRing(t.ver) != direction) { - esymself(t); - } -} - -inline void tetgenmesh::adjustedgering(face& s, int direction) { - if (EdgeRing(s.shver) != direction) { - sesymself(s); - } -} - -// isdead() returns TRUE if the tetrahedron or subface has been dealloced. - -inline bool tetgenmesh::isdead(triface* t) { - if (t->tet == (tetrahedron *) NULL) return true; - else return t->tet[4] == (tetrahedron) NULL; -} - -inline bool tetgenmesh::isdead(face* s) { - if (s->sh == (shellface *) NULL) return true; - else return s->sh[3] == (shellface) NULL; -} - -// isfacehaspoint() returns TRUE if the 'testpoint' is one of the vertices -// of the subface 's'. - -inline bool tetgenmesh::isfacehaspoint(face* s, point testpoint) { - return (s->sh[3] == (shellface) testpoint) || - (s->sh[4] == (shellface) testpoint) || - (s->sh[5] == (shellface) testpoint); -} - -// isfacehasedge() returns TRUE if the edge (given by its two endpoints) is -// one of the three edges of the subface 's'. - -inline bool tetgenmesh::isfacehasedge(face* s, point tend1, point tend2) { - return (isfacehaspoint(s, tend1) && isfacehaspoint(s, tend2)); -} - -// issymexist() returns TRUE if the adjoining tetrahedron is not 'duumytet'. - -inline bool tetgenmesh::issymexist(triface* t) { - tetrahedron *ptr = (tetrahedron *) - ((unsigned long)(t->tet[t->loc]) & ~(unsigned long)7l); - return ptr != dummytet; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getnextface() Get the successor of 'tface1' in the face ring. // -// // -// If 'tface1' is not a boundary (or hull) face, then its successor in the // -// face ring exists. The successor is returned in 'tface2' if it is not a // -// NULL, or the 'tface1' itself is used to return this face. On finish, the // -// function returns TRUE. // -// // -// If 'tface1' is a boundary (or hull) face, its successor does not exist. // -// This case, return FALSE and 'tface1' remains unchanged. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::getnextface(triface* tface1, triface* tface2) -{ - point torg, tdest; - int tloc, tver; - - // Where the next face locates, in 'tface1' or in its neigbhour? It can be - // quickly determined by checking the edge ring of 'tface1'. - if (EdgeRing(tface1->ver) == CW) { - // The next face is in the neigbhour of 'tface1'. - if (!issymexist(tface1)) { - // Hit outer space - The next face does not exist. - return false; - } - torg = org(*tface1); - tdest = dest(*tface1); - if (tface2) { - sym(*tface1, *tface2); - findedge(tface2, torg, tdest); - } else { - symself(*tface1); - findedge(tface1, torg, tdest); - } - } else { - // The next face is in 'tface1'. - if (tface2) { - *tface2 = *tface1; - } - } - - if (tface2) { - tloc = tface2->loc; - tver = tface2->ver; - tface2->loc = locver2nextf[tloc][tver][0]; - tface2->ver = locver2nextf[tloc][tver][1]; - } else { - tloc = tface1->loc; - tver = tface1->ver; - tface1->loc = locver2nextf[tloc][tver][0]; - tface1->ver = locver2nextf[tloc][tver][1]; - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getnextsface() Finds the next subface in the face ring. // -// // -// For saving space in the data structure of subface, there only exists one // -// face ring around a segment (see programming manual). This routine imple- // -// ments the double face ring as desired in Muecke's data structure. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::getnextsface(face* s1, face* s2) -{ - face neighsh, spinsh; - face testseg; - - sspivot(*s1, testseg); - if (testseg.sh != dummysh) { - testseg.shver = 0; - if (sorg(testseg) == sorg(*s1)) { - spivot(*s1, neighsh); - } else { - spinsh = *s1; - do { - neighsh = spinsh; - spivotself(spinsh); - } while (spinsh.sh != s1->sh); - } - } else { - spivot(*s1, neighsh); - } - if (sorg(neighsh) != sorg(*s1)) { - sesymself(neighsh); - } - if (s2 != (face *) NULL) { - *s2 = neighsh; - } else { - *s1 = neighsh; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tsspivot() Finds a subsegment abutting on a tetrahderon's edge. // -// // -// The edge is represented in the primary edge of 'checkedge'. If there is a // -// subsegment bonded at this edge, it is returned in handle 'checkseg', the // -// edge direction of 'checkseg' is conformed to 'checkedge'. If there isn't, // -// set 'checkseg.sh = dummysh' to indicate it is not a subsegment. // -// // -// To find whether an edge of a tetrahedron is a subsegment or not. First we // -// need find a subface around this edge to see if it contains a subsegment. // -// The reason is there is no direct connection between a tetrahedron and its // -// adjoining subsegments. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::tsspivot(triface* checkedge, face* checkseg) -{ - triface spintet; - face parentsh; - point tapex; - int hitbdry; - - spintet = *checkedge; - tapex = apex(*checkedge); - hitbdry = 0; - do { - tspivot(spintet, parentsh); - if (parentsh.sh != dummysh) { - // Find a subface! - findedge(&parentsh, org(*checkedge), dest(*checkedge)); - sspivot(parentsh, *checkseg); - if (checkseg->sh != dummysh) { - // Find a subsegment! Correct its edge direction before return. - if (sorg(*checkseg) != sorg(parentsh)) { - sesymself(*checkseg); - } - } - return; - } - if (!fnextself(spintet)) { - hitbdry++; - if (hitbdry < 2) { - esym(*checkedge, spintet); - if (!fnextself(spintet)) { - hitbdry++; - } - } - } - } while ((apex(spintet) != tapex) && (hitbdry < 2)); - // Not find. - checkseg->sh = dummysh; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// sstpivot() Finds a tetrahedron abutting a subsegment. // -// // -// This is the inverse operation of 'tsspivot()'. One subsegment shared by // -// arbitrary number of tetrahedron, the returned tetrahedron is not unique. // -// The edge direction of the returned tetrahedron is conformed to the given // -// subsegment. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::sstpivot(face* checkseg, triface* retedge) -{ - face parentsh; - - // Get the subface which holds the subsegment. - sdecode(checkseg->sh[0], parentsh); - assert(parentsh.sh != dummysh); - // Get a tetraheron to which the subface attches. - stpivot(parentsh, *retedge); - if (retedge->tet == dummytet) { - sesymself(parentsh); - stpivot(parentsh, *retedge); - assert(retedge->tet != dummytet); - } - // Correct the edge direction before return. - findedge(retedge, sorg(*checkseg), sdest(*checkseg)); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// findorg() Finds a point in the given handle (tetrahedron or subface). // -// // -// If 'dorg' is a one of vertices of the given handle, set the origin of // -// this handle be that point and return TRUE. Otherwise, return FALSE and // -// 'tface' remains unchanged. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::findorg(triface* tface, point dorg) -{ - if (org(*tface) == dorg) { - return true; - } else { - if (dest(*tface) == dorg) { - enextself(*tface); - return true; - } else { - if (apex(*tface) == dorg) { - enext2self(*tface); - return true; - } else { - if (oppo(*tface) == dorg) { - // Keep 'tface' referring to the same tet after fnext(). - adjustedgering(*tface, CCW); - fnextself(*tface); - enext2self(*tface); - return true; - } - } - } - } - return false; -} - -bool tetgenmesh::findorg(face* sface, point dorg) -{ - if (sorg(*sface) == dorg) { - return true; - } else { - if (sdest(*sface) == dorg) { - senextself(*sface); - return true; - } else { - if (sapex(*sface) == dorg) { - senext2self(*sface); - return true; - } - } - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// findedge() Find an edge in the given handle (tetrahedron or subface). // -// // -// The edge is given in two points 'eorg' and 'edest'. It is assumed that // -// the edge must exist in the given handle (tetrahedron or subface). This // -// routine sets the right edge version for the input handle. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::findedge(triface* tface, point eorg, point edest) -{ - int i; - - for (i = 0; i < 3; i++) { - if (org(*tface) == eorg) { - if (dest(*tface) == edest) { - // Edge is found, return. - return; - } - } else { - if (org(*tface) == edest) { - if (dest(*tface) == eorg) { - // Edge is found, but need to inverse the direction. - esymself(*tface); - return; - } - } - } - enextself(*tface); - } - // It should not be here. - assert(i < 3); -} - -void tetgenmesh::findedge(face* sface, point eorg, point edest) -{ - int i; - - for (i = 0; i < 3; i++) { - if (sorg(*sface) == eorg) { - if (sdest(*sface) == edest) { - // Edge is found, return. - return; - } - } else { - if (sorg(*sface) == edest) { - if (sdest(*sface) == eorg) { - // Edge is found, but need to inverse the direction. - sesymself(*sface); - return; - } - } - } - senextself(*sface); - } - // It should not be here. - assert(i < 3); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// findface() Find the face has the given origin, destination and apex. // -// // -// On input, 'fface' is a handle which may contain the three corners or may // -// not or may be dead. On return, it represents exactly the face with the // -// given origin, destination and apex. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::findface(triface *fface, point forg, point fdest, point fapex) -{ - triface spintet; - enum finddirectionresult collinear; - int hitbdry; - - if (!isdead(fface)) { - // First check the easiest case, that 'fface' is just the right one. - if (org(*fface) == forg && dest(*fface) == fdest && - apex(*fface) == fapex) return; - } else { - // The input handle is dead, use the 'recenttet' if it is alive. - if (!isdead(&recenttet)) *fface = recenttet; - } - - if (!isdead(fface)) { - if (!findorg(fface, forg)) { - // 'forg' is not a corner of 'fface', locate it. - preciselocate(forg, fface); - } - // It is possible that forg is not found in a non-convex mesh. - if (org(*fface) == forg) { - collinear = finddirection(fface, fdest); - if (collinear == RIGHTCOLLINEAR) { - // fdest is just the destination. - } else if (collinear == LEFTCOLLINEAR) { - enext2self(*fface); - esymself(*fface); - } else if (collinear == TOPCOLLINEAR) { - fnextself(*fface); - enext2self(*fface); - esymself(*fface); - } - } - // It is possible taht fdest is not found in a non-convex mesh. - if ((org(*fface) == forg) && (dest(*fface) == fdest)) { - // Find the apex of 'fapex'. - spintet = *fface; - hitbdry = 0; - do { - if (apex(spintet) == fapex) { - // We have done. Be careful the edge direction of 'spintet', - // it may reversed because of hitting boundary once. - if (org(spintet) != org(*fface)) { - esymself(spintet); - } - *fface = spintet; - return; - } - if (!fnextself(spintet)) { - hitbdry ++; - if (hitbdry < 2) { - esym(*fface, spintet); - if (!fnextself(spintet)) { - hitbdry ++; - } - } - } - } while (hitbdry < 2 && apex(spintet) != apex(*fface)); - // It is possible that fapex is not found in a non-convex mesh. - } - } - - if (isdead(fface) || (org(*fface) != forg) || (dest(*fface) != fdest) || - (apex(*fface) != fapex)) { - // Too bad, the input handle is useless. We have to find a handle - // for 'fface' contains the 'forg' and 'fdest'. Here a brute force - // search is performed. - if (b->verbose > 1) { - printf("Warning in findface(): Perform a brute-force searching.\n"); - } - enum verttype forgty, fdestty, fapexty; - int share, i; - forgty = pointtype(forg); - fdestty = pointtype(fdest); - fapexty = pointtype(fapex); - setpointtype(forg, DEADVERTEX); - setpointtype(fdest, DEADVERTEX); - setpointtype(fapex, DEADVERTEX); - tetrahedrons->traversalinit(); - fface->tet = tetrahedrontraverse(); - while (fface->tet != (tetrahedron *) NULL) { - share = 0; - for (i = 0; i < 4; i++) { - if (pointtype((point) fface->tet[4 + i]) == DEADVERTEX) share ++; - } - if (share == 3) { - // Found! Set the correct face and desired corners. - if (pointtype((point) fface->tet[4]) != DEADVERTEX) { - fface->loc = 2; - } else if (pointtype((point) fface->tet[5]) != DEADVERTEX) { - fface->loc = 3; - } else if (pointtype((point) fface->tet[6]) != DEADVERTEX) { - fface->loc = 1; - } else { // pointtype((point) fface->tet[7]) != DEADVERTEX - fface->loc = 0; - } - findedge(fface, forg, fdest); - break; - } - fface->tet = tetrahedrontraverse(); - } - setpointtype(forg, forgty); - setpointtype(fdest, fdestty); - setpointtype(fapex, fapexty); - if (fface->tet == (tetrahedron *) NULL) { - // It is impossible to reach here. - printf("Internal error: Fail to find the indicated face.\n"); - internalerror(); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getonextseg() Get the next SEGMENT counterclockwise with the same org. // -// // -// 's' is a subface. This routine reteuns the segment which is counterclock- // -// wise with the origin of s. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::getonextseg(face* s, face* lseg) -{ - face checksh, checkseg; - point forg; - - forg = sorg(*s); - checksh = *s; - do { - // Go to the edge at forg's left side. - senext2self(checksh); - // Check if there is a segment attaching this edge. - sspivot(checksh, checkseg); - if (checkseg.sh != dummysh) break; - // No segment! Go to the neighbor of this subface. - spivotself(checksh); - // It should always meet a segment before come back. - assert(checksh.sh != s->sh); - if (sorg(checksh) != forg) { - sesymself(checksh); - assert(sorg(checksh) == forg); - } - } while (true); - assert(checkseg.sh != dummysh); - if (sorg(checkseg) != forg) sesymself(checkseg); - *lseg = checkseg; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getseghasorg() Get the segment containing the given point. // -// // -// On input we know 'dorg' is an endpoint of the segment containing 'sseg'. // -// This routine search along 'sseg' for the vertex 'dorg'. On return, 'sseg' // -// contains 'dorg' as its origin. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::getseghasorg(face* sseg, point dorg) -{ - face nextseg; - point checkpt; - - nextseg = *sseg; - checkpt = sorg(nextseg); - while ((checkpt != dorg) && (pointtype(checkpt) == FREESEGVERTEX)) { - // Search dorg along the original direction of sseg. - senext2self(nextseg); - spivotself(nextseg); - nextseg.shver = 0; - if (sdest(nextseg) != checkpt) sesymself(nextseg); - checkpt = sorg(nextseg); - } - if (checkpt == dorg) { - *sseg = nextseg; - return; - } - nextseg = *sseg; - checkpt = sdest(nextseg); - while ((checkpt != dorg) && (pointtype(checkpt) == FREESEGVERTEX)) { - // Search dorg along the destinational direction of sseg. - senextself(nextseg); - spivotself(nextseg); - nextseg.shver = 0; - if (sorg(nextseg) != checkpt) sesymself(nextseg); - checkpt = sdest(nextseg); - } - if (checkpt == dorg) { - sesym(nextseg, *sseg); - return; - } - // Should not be here. - assert(0); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getsubsegfarorg() Get the origin of the parent segment of a subseg. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::point tetgenmesh::getsubsegfarorg(face* sseg) -{ - face prevseg; - point checkpt; - - checkpt = sorg(*sseg); - senext2(*sseg, prevseg); - spivotself(prevseg); - // Search dorg along the original direction of sseg. - while (prevseg.sh != dummysh) { - prevseg.shver = 0; - if (sdest(prevseg) != checkpt) sesymself(prevseg); - checkpt = sorg(prevseg); - senext2self(prevseg); - spivotself(prevseg); - } - return checkpt; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getsubsegfardest() Get the dest. of the parent segment of a subseg. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::point tetgenmesh::getsubsegfardest(face* sseg) -{ - face nextseg; - point checkpt; - - checkpt = sdest(*sseg); - senext(*sseg, nextseg); - spivotself(nextseg); - // Search dorg along the destinational direction of sseg. - while (nextseg.sh != dummysh) { - nextseg.shver = 0; - if (sorg(nextseg) != checkpt) sesymself(nextseg); - checkpt = sdest(nextseg); - senextself(nextseg); - spivotself(nextseg); - } - return checkpt; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// printtet() Print out the details of a tetrahedron on screen. // -// // -// It's also used when the highest level of verbosity (`-VVV') is specified. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::printtet(triface* tface) -{ - triface tmpface, prtface; - point tmppt; - face tmpsh; - int facecount; - - printf("Tetra x%lx with loc(%i) and ver(%i):", - (unsigned long)(tface->tet), tface->loc, tface->ver); - if (infected(*tface)) { - printf(" (infected)"); - } - printf("\n"); - - tmpface = *tface; - facecount = 0; - while(facecount < 4) { - tmpface.loc = facecount; - sym(tmpface, prtface); - if(prtface.tet == dummytet) { - printf(" [%i] Outer space.\n", facecount); - } else { - printf(" [%i] x%lx loc(%i).", facecount, - (unsigned long)(prtface.tet), prtface.loc); - if (infected(prtface)) { - printf(" (infected)"); - } - printf("\n"); - } - facecount ++; - } - - tmppt = org(*tface); - if(tmppt == (point) NULL) { - printf(" Org [%i] NULL\n", locver2org[tface->loc][tface->ver]); - } else { - printf(" Org [%i] x%lx (%.12g,%.12g,%.12g) %d\n", - locver2org[tface->loc][tface->ver], (unsigned long)(tmppt), - tmppt[0], tmppt[1], tmppt[2], pointmark(tmppt)); - } - tmppt = dest(*tface); - if(tmppt == (point) NULL) { - printf(" Dest[%i] NULL\n", locver2dest[tface->loc][tface->ver]); - } else { - printf(" Dest[%i] x%lx (%.12g,%.12g,%.12g) %d\n", - locver2dest[tface->loc][tface->ver], (unsigned long)(tmppt), - tmppt[0], tmppt[1], tmppt[2], pointmark(tmppt)); - } - tmppt = apex(*tface); - if(tmppt == (point) NULL) { - printf(" Apex[%i] NULL\n", locver2apex[tface->loc][tface->ver]); - } else { - printf(" Apex[%i] x%lx (%.12g,%.12g,%.12g) %d\n", - locver2apex[tface->loc][tface->ver], (unsigned long)(tmppt), - tmppt[0], tmppt[1], tmppt[2], pointmark(tmppt)); - } - tmppt = oppo(*tface); - if(tmppt == (point) NULL) { - printf(" Oppo[%i] NULL\n", loc2oppo[tface->loc]); - } else { - printf(" Oppo[%i] x%lx (%.12g,%.12g,%.12g) %d\n", - loc2oppo[tface->loc], (unsigned long)(tmppt), - tmppt[0], tmppt[1], tmppt[2], pointmark(tmppt)); - } - - if (b->useshelles) { - tmpface = *tface; - facecount = 0; - while(facecount < 4) { - tmpface.loc = facecount; - tspivot(tmpface, tmpsh); - if(tmpsh.sh != dummysh) { - printf(" [%i] x%lx ID(%i).\n", facecount, - (unsigned long)(tmpsh.sh), shellmark(tmpsh)); - } - facecount ++; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// printsh() Print out the details of a subface or subsegment on screen. // -// // -// It's also used when the highest level of verbosity (`-VVV') is specified. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::printsh(face* sface) -{ - face prtsh; - triface prttet; - point printpoint; - - if (sapex(*sface) != NULL) { - printf("subface x%lx, ver %d, mark %d:", - (unsigned long)(sface->sh), sface->shver, shellmark(*sface)); - } else { - printf("Subsegment x%lx, ver %d, mark %d:", - (unsigned long)(sface->sh), sface->shver, shellmark(*sface)); - } - if (sinfected(*sface)) { - printf(" (infected)"); - } - if (shell2badface(*sface)) { - printf(" (queued)"); - } - if (sapex(*sface) != NULL) { - if (shelltype(*sface) == PROTCYLSUBFACE) { - printf(" (cyls)"); - } else if (shelltype(*sface) == PROTSPHSUBFACE) { - printf(" (sphs)"); - } - } else { - if (shelltype(*sface) == SHARPSEGMENT) { - printf(" (sharp)"); - } else if (shelltype(*sface) == PROTCYLSEGMENT) { - printf(" (cyls)"); - } else if (shelltype(*sface) == PROTSPHSEGMENT) { - printf(" (sphs)"); - } - } - printf("\n"); - - sdecode(sface->sh[0], prtsh); - if (prtsh.sh == dummysh) { - printf(" [0] = No shell\n"); - } else { - printf(" [0] = x%lx %d\n", (unsigned long)(prtsh.sh), prtsh.shver); - } - sdecode(sface->sh[1], prtsh); - if (prtsh.sh == dummysh) { - printf(" [1] = No shell\n"); - } else { - printf(" [1] = x%lx %d\n", (unsigned long)(prtsh.sh), prtsh.shver); - } - sdecode(sface->sh[2], prtsh); - if (prtsh.sh == dummysh) { - printf(" [2] = No shell\n"); - } else { - printf(" [2] = x%lx %d\n", (unsigned long)(prtsh.sh), prtsh.shver); - } - - printpoint = sorg(*sface); - if (printpoint == (point) NULL) - printf(" Org [%d] = NULL\n", vo[sface->shver]); - else - printf(" Org [%d] = x%lx (%.12g,%.12g,%.12g) %d\n", - vo[sface->shver], (unsigned long)(printpoint), printpoint[0], - printpoint[1], printpoint[2], pointmark(printpoint)); - printpoint = sdest(*sface); - if (printpoint == (point) NULL) - printf(" Dest[%d] = NULL\n", vd[sface->shver]); - else - printf(" Dest[%d] = x%lx (%.12g,%.12g,%.12g) %d\n", - vd[sface->shver], (unsigned long)(printpoint), printpoint[0], - printpoint[1], printpoint[2], pointmark(printpoint)); - - if (sapex(*sface) != NULL) { - printpoint = sapex(*sface); - if (printpoint == (point) NULL) - printf(" Apex[%d] = NULL\n", va[sface->shver]); - else - printf(" Apex[%d] = x%lx (%.12g,%.12g,%.12g) %d\n", - va[sface->shver], (unsigned long)(printpoint), printpoint[0], - printpoint[1], printpoint[2], pointmark(printpoint)); - - decode(sface->sh[6], prttet); - if (prttet.tet == dummytet) { - printf(" [6] = Outer space\n"); - } else { - printf(" [6] = x%lx %d\n", - (unsigned long)(prttet.tet), prttet.loc); - } - decode(sface->sh[7], prttet); - if (prttet.tet == dummytet) { - printf(" [7] = Outer space\n"); - } else { - printf(" [7] = x%lx %d\n", - (unsigned long)(prttet.tet), prttet.loc); - } - - sdecode(sface->sh[8], prtsh); - if (prtsh.sh == dummysh) { - printf(" [8] = No subsegment\n"); - } else { - printf(" [8] = x%lx %d\n", - (unsigned long)(prtsh.sh), prtsh.shver); - } - sdecode(sface->sh[9], prtsh); - if (prtsh.sh == dummysh) { - printf(" [9] = No subsegment\n"); - } else { - printf(" [9] = x%lx %d\n", - (unsigned long)(prtsh.sh), prtsh.shver); - } - sdecode(sface->sh[10], prtsh); - if (prtsh.sh == dummysh) { - printf(" [10]= No subsegment\n"); - } else { - printf(" [10]= x%lx %d\n", - (unsigned long)(prtsh.sh), prtsh.shver); - } - } -} - -// -// End of advanced primitives -// - -// -// End of mesh manipulation primitives -// - -// -// Begin of mesh items searching routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// makepoint2tetmap() Construct a mapping from points to tetrahedra. // -// // -// Traverses all the tetrahedra, provides each corner of each tetrahedron // -// with a pointer to that tetrahedera. Some pointers will be overwritten by // -// other pointers because each point may be a corner of several tetrahedra, // -// but in the end every point will point to a tetrahedron that contains it. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::makepoint2tetmap() -{ - triface tetloop; - point pointptr; - - if (b->verbose) { - printf(" Constructing mapping from points to tetrahedra.\n"); - } - - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - // Check all four points of the tetrahedron. - pointptr = org(tetloop); - setpoint2tet(pointptr, encode(tetloop)); - pointptr = dest(tetloop); - setpoint2tet(pointptr, encode(tetloop)); - pointptr = apex(tetloop); - setpoint2tet(pointptr, encode(tetloop)); - pointptr = oppo(tetloop); - setpoint2tet(pointptr, encode(tetloop)); - // Get the next tetrahedron in the list. - tetloop.tet = tetrahedrontraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// makeindex2pointmap() Create a map from index to vertices. // -// // -// 'idx2verlist' returns the created map. Traverse all vertices, a pointer // -// to each vertex is set into the array. The pointer to the first vertex is // -// saved in 'idx2verlist[0]'. Don't forget to minus 'in->firstnumber' when // -// to get the vertex form its index. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::makeindex2pointmap(point*& idx2verlist) -{ - point pointloop; - int idx; - - if (b->verbose) { - printf(" Constructing mapping from indices to points.\n"); - } - - idx2verlist = new point[points->items]; - - points->traversalinit(); - pointloop = pointtraverse(); - idx = 0; - while (pointloop != (point) NULL) { - idx2verlist[idx] = pointloop; - idx++; - pointloop = pointtraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// makesegmentmap() Create a map from vertices (their indices) to // -// segments incident at the same vertices. // -// // -// Two arrays 'idx2seglist' and 'segsperverlist' together return the map. // -// They form a sparse matrix structure with size (n + 1) x (n + 1), n is the // -// number of segments. idx2seglist contains row information and // -// segsperverlist contains all (non-zero) elements. The i-th entry of // -// idx2seglist is the starting position of i-th row's (non-zero) elements in // -// segsperverlist. The number of elements of i-th row is calculated by the // -// (i+1)-th entry minus i-th entry of idx2seglist. // -// // -// NOTE: These two arrays will be created inside this routine, don't forget // -// to free them after using. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -makesegmentmap(int*& idx2seglist, shellface**& segsperverlist) -{ - shellface *shloop; - int i, j, k; - - if (b->verbose) { - printf(" Constructing mapping from points to segments.\n"); - } - - // Create and initialize 'idx2seglist'. - idx2seglist = new int[points->items + 1]; - for (i = 0; i < points->items + 1; i++) { - idx2seglist[i] = 0; - } - - // Loop the set of segments once, counter the number of segments sharing - // each vertex. - subsegs->traversalinit(); - shloop = shellfacetraverse(subsegs); - while (shloop != (shellface *) NULL) { - // Increment the number of sharing segments for each endpoint. - for (i = 0; i < 2; i++) { - j = pointmark((point) shloop[3 + i]) - in->firstnumber; - idx2seglist[j]++; - } - shloop = shellfacetraverse(subsegs); - } - - // Calculate the total length of array 'facesperverlist'. - j = idx2seglist[0]; - idx2seglist[0] = 0; // Array starts from 0 element. - for (i = 0; i < points->items; i++) { - k = idx2seglist[i + 1]; - idx2seglist[i + 1] = idx2seglist[i] + j; - j = k; - } - // The total length is in the last unit of idx2seglist. - segsperverlist = new shellface*[idx2seglist[i]]; - // Loop the set of segments again, set the info. of segments per vertex. - subsegs->traversalinit(); - shloop = shellfacetraverse(subsegs); - while (shloop != (shellface *) NULL) { - for (i = 0; i < 2; i++) { - j = pointmark((point) shloop[3 + i]) - in->firstnumber; - segsperverlist[idx2seglist[j]] = shloop; - idx2seglist[j]++; - } - shloop = shellfacetraverse(subsegs); - } - // Contents in 'idx2seglist' are shifted, now shift them back. - for (i = points->items - 1; i >= 0; i--) { - idx2seglist[i + 1] = idx2seglist[i]; - } - idx2seglist[0] = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// makesubfacemap() Create a map from vertices (their indices) to // -// subfaces incident at the same vertices. // -// // -// Two arrays 'idx2facelist' and 'facesperverlist' together return the map. // -// They form a sparse matrix structure with size (n + 1) x (n + 1), n is the // -// number of subfaces. idx2facelist contains row information and // -// facesperverlist contains all (non-zero) elements. The i-th entry of // -// idx2facelist is the starting position of i-th row's(non-zero) elements in // -// facesperverlist. The number of elements of i-th row is calculated by the // -// (i+1)-th entry minus i-th entry of idx2facelist. // -// // -// NOTE: These two arrays will be created inside this routine, don't forget // -// to free them after using. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -makesubfacemap(int*& idx2facelist, shellface**& facesperverlist) -{ - shellface *shloop; - int i, j, k; - - if (b->verbose) { - printf(" Constructing mapping from points to subfaces.\n"); - } - - // Create and initialize 'idx2facelist'. - idx2facelist = new int[points->items + 1]; - for (i = 0; i < points->items + 1; i++) { - idx2facelist[i] = 0; - } - - // Loop the set of subfaces once, counter the number of subfaces sharing - // each vertex. - subfaces->traversalinit(); - shloop = shellfacetraverse(subfaces); - while (shloop != (shellface *) NULL) { - // Increment the number of sharing segments for each endpoint. - for (i = 0; i < 3; i++) { - j = pointmark((point) shloop[3 + i]) - in->firstnumber; - idx2facelist[j]++; - } - shloop = shellfacetraverse(subfaces); - } - - // Calculate the total length of array 'facesperverlist'. - j = idx2facelist[0]; - idx2facelist[0] = 0; // Array starts from 0 element. - for (i = 0; i < points->items; i++) { - k = idx2facelist[i + 1]; - idx2facelist[i + 1] = idx2facelist[i] + j; - j = k; - } - // The total length is in the last unit of idx2facelist. - facesperverlist = new shellface*[idx2facelist[i]]; - // Loop the set of segments again, set the info. of segments per vertex. - subfaces->traversalinit(); - shloop = shellfacetraverse(subfaces); - while (shloop != (shellface *) NULL) { - for (i = 0; i < 3; i++) { - j = pointmark((point) shloop[3 + i]) - in->firstnumber; - facesperverlist[idx2facelist[j]] = shloop; - idx2facelist[j]++; - } - shloop = shellfacetraverse(subfaces); - } - // Contents in 'idx2facelist' are shifted, now shift them back. - for (i = points->items - 1; i >= 0; i--) { - idx2facelist[i + 1] = idx2facelist[i]; - } - idx2facelist[0] = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// maketetrahedronmap() Create a map from vertices (their indices) to // -// tetrahedra incident at the same vertices. // -// // -// Two arrays 'idx2tetlist' and 'tetsperverlist' together return the map. // -// They form a sparse matrix structure with size (n + 1) x (n + 1), n is the // -// number of tetrahedra. idx2tetlist contains row information and // -// tetsperverlist contains all (non-zero) elements. The i-th entry of // -// idx2tetlist is the starting position of i-th row's (non-zero) elements in // -// tetsperverlist. The number of elements of i-th row is calculated by the // -// (i+1)-th entry minus i-th entry of idx2tetlist. // -// // -// NOTE: These two arrays will be created inside this routine, don't forget // -// to free them after using. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -maketetrahedronmap(int*& idx2tetlist, tetrahedron**& tetsperverlist) -{ - tetrahedron *tetloop; - int i, j, k; - - if (b->verbose) { - printf(" Constructing mapping from points to tetrahedra.\n"); - } - - // Create and initialize 'idx2tetlist'. - idx2tetlist = new int[points->items + 1]; - for (i = 0; i < points->items + 1; i++) { - idx2tetlist[i] = 0; - } - - // Loop the set of tetrahedra once, counter the number of tetrahedra - // sharing each vertex. - tetrahedrons->traversalinit(); - tetloop = tetrahedrontraverse(); - while (tetloop != (tetrahedron *) NULL) { - // Increment the number of sharing tetrahedra for each endpoint. - for (i = 0; i < 4; i++) { - j = pointmark((point) tetloop[4 + i]) - in->firstnumber; - idx2tetlist[j]++; - } - tetloop = tetrahedrontraverse(); - } - - // Calculate the total length of array 'tetsperverlist'. - j = idx2tetlist[0]; - idx2tetlist[0] = 0; // Array starts from 0 element. - for (i = 0; i < points->items; i++) { - k = idx2tetlist[i + 1]; - idx2tetlist[i + 1] = idx2tetlist[i] + j; - j = k; - } - // The total length is in the last unit of idx2tetlist. - tetsperverlist = new tetrahedron*[idx2tetlist[i]]; - // Loop the set of tetrahedra again, set the info. of tet. per vertex. - tetrahedrons->traversalinit(); - tetloop = tetrahedrontraverse(); - while (tetloop != (tetrahedron *) NULL) { - for (i = 0; i < 4; i++) { - j = pointmark((point) tetloop[4 + i]) - in->firstnumber; - tetsperverlist[idx2tetlist[j]] = tetloop; - idx2tetlist[j]++; - } - tetloop = tetrahedrontraverse(); - } - // Contents in 'idx2tetlist' are shifted, now shift them back. - for (i = points->items - 1; i >= 0; i--) { - idx2tetlist[i + 1] = idx2tetlist[i]; - } - idx2tetlist[0] = 0; -} - -// -// End of mesh items searching routines -// - -// -// Begin of linear algebra functions -// - -// dot() returns the dot product: v1 dot v2. - -inline REAL tetgenmesh::dot(REAL* v1, REAL* v2) -{ - return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; -} - -// cross() computes the cross product: n = v1 cross v2. - -inline void tetgenmesh::cross(REAL* v1, REAL* v2, REAL* n) -{ - n[0] = v1[1] * v2[2] - v2[1] * v1[2]; - n[1] = -(v1[0] * v2[2] - v2[0] * v1[2]); - n[2] = v1[0] * v2[1] - v2[0] * v1[1]; -} - -// initm44() initializes a 4x4 matrix. -void tetgenmesh::initm44(REAL a00, REAL a01, REAL a02, REAL a03, - REAL a10, REAL a11, REAL a12, REAL a13, - REAL a20, REAL a21, REAL a22, REAL a23, - REAL a30, REAL a31, REAL a32, REAL a33, - REAL M[4][4]) -{ - M[0][0] = a00; M[0][1] = a01; M[0][2] = a02; M[0][3] = a03; - M[1][0] = a10; M[1][1] = a11; M[1][2] = a12; M[1][3] = a13; - M[2][0] = a20; M[2][1] = a21; M[2][2] = a22; M[2][3] = a23; - M[3][0] = a30; M[3][1] = a31; M[3][2] = a32; M[3][3] = a33; -} - -// m4xm4() multiplies 2 4x4 matrics: m1 = m1 * m2. -void tetgenmesh::m4xm4(REAL m1[4][4], REAL m2[4][4]) -{ - REAL tmp[4]; - int i, j; - - for (i = 0; i < 4; i++) { // i-th row - for (j = 0; j < 4; j++) { // j-th col - tmp[j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] - + m1[i][2] * m2[2][j] + m1[i][3] * m2[3][j]; - } - for (j = 0; j < 4; j++) - m1[i][j] = tmp[j]; - } -} - -// m4xv4() multiplies a 4x4 matrix and 4x1 vector: v2 = m * v1 -void tetgenmesh::m4xv4(REAL v2[4], REAL m[4][4], REAL v1[4]) -{ - v2[0] = m[0][0]*v1[0] + m[0][1]*v1[1] + m[0][2]*v1[2] + m[0][3]*v1[3]; - v2[1] = m[1][0]*v1[0] + m[1][1]*v1[1] + m[1][2]*v1[2] + m[1][3]*v1[3]; - v2[2] = m[2][0]*v1[0] + m[2][1]*v1[1] + m[2][2]*v1[2] + m[2][3]*v1[3]; - v2[3] = m[3][0]*v1[0] + m[3][1]*v1[1] + m[3][2]*v1[2] + m[3][3]*v1[3]; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// lu_decmp() Compute the LU decomposition of a matrix. // -// // -// Compute the LU decomposition of a (non-singular) square matrix A using // -// partial pivoting and implicit row exchanges. The result is: // -// A = P * L * U, // -// where P is a permutation matrix, L is unit lower triangular, and U is // -// upper triangular. The factored form of A is used in combination with // -// 'lu_solve()' to solve linear equations: Ax = b, or invert a matrix. // -// // -// The inputs are a square matrix 'lu[N..n+N-1][N..n+N-1]', it's size is 'n'.// -// On output, 'lu' is replaced by the LU decomposition of a rowwise permuta- // -// tion of itself, 'ps[N..n+N-1]' is an output vector that records the row // -// permutation effected by the partial pivoting, effectively, 'ps' array // -// tells the user what the permutation matrix P is; 'd' is output as +1/-1 // -// depending on whether the number of row interchanges was even or odd, // -// respectively. // -// // -// Return true if the LU decomposition is successfully computed, otherwise, // -// return false in case that A is a singular matrix. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::lu_decmp(REAL lu[3][3], int n, int* ps, REAL* d, int N) -{ - REAL scales[3]; - REAL pivot, biggest, mult, tempf; - int pivotindex = 0; - int i, j, k; - - *d = 1.0; // No row interchanges yet. - - for (i = N; i < n + N; i++) { // For each row. - // Find the largest element in each row for row equilibration - biggest = 0.0; - for (j = N; j < n + N; j++) - if (biggest < (tempf = fabs(lu[i][j]))) - biggest = tempf; - if (biggest != 0.0) - scales[i] = 1.0 / biggest; - else { - scales[i] = 0.0; - return false; // Zero row: singular matrix. - } - ps[i] = i; // Initialize pivot sequence. - } - - for (k = N; k < n + N - 1; k++) { // For each column. - // Find the largest element in each column to pivot around. - biggest = 0.0; - for (i = k; i < n + N; i++) { - if (biggest < (tempf = fabs(lu[ps[i]][k]) * scales[ps[i]])) { - biggest = tempf; - pivotindex = i; - } - } - if (biggest == 0.0) { - return false; // Zero column: singular matrix. - } - if (pivotindex != k) { // Update pivot sequence. - j = ps[k]; - ps[k] = ps[pivotindex]; - ps[pivotindex] = j; - *d = -(*d); // ...and change the parity of d. - } - - // Pivot, eliminating an extra variable each time - pivot = lu[ps[k]][k]; - for (i = k + 1; i < n + N; i++) { - lu[ps[i]][k] = mult = lu[ps[i]][k] / pivot; - if (mult != 0.0) { - for (j = k + 1; j < n + N; j++) - lu[ps[i]][j] -= mult * lu[ps[k]][j]; - } - } - } - - // (lu[ps[n + N - 1]][n + N - 1] == 0.0) ==> A is singular. - return lu[ps[n + N - 1]][n + N - 1] != 0.0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// lu_solve() Solves the linear equation: Ax = b, after the matrix A // -// has been decomposed into the lower and upper triangular // -// matrices L and U, where A = LU. // -// // -// 'lu[N..n+N-1][N..n+N-1]' is input, not as the matrix 'A' but rather as // -// its LU decomposition, computed by the routine 'lu_decmp'; 'ps[N..n+N-1]' // -// is input as the permutation vector returned by 'lu_decmp'; 'b[N..n+N-1]' // -// is input as the right-hand side vector, and returns with the solution // -// vector. 'lu', 'n', and 'ps' are not modified by this routine and can be // -// left in place for successive calls with different right-hand sides 'b'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::lu_solve(REAL lu[3][3], int n, int* ps, REAL* b, int N) -{ - int i, j; - REAL X[3], dot; - - for (i = N; i < n + N; i++) X[i] = 0.0; - - // Vector reduction using U triangular matrix. - for (i = N; i < n + N; i++) { - dot = 0.0; - for (j = N; j < i + N; j++) - dot += lu[ps[i]][j] * X[j]; - X[i] = b[ps[i]] - dot; - } - - // Back substitution, in L triangular matrix. - for (i = n + N - 1; i >= N; i--) { - dot = 0.0; - for (j = i + 1; j < n + N; j++) - dot += lu[ps[i]][j] * X[j]; - X[i] = (X[i] - dot) / lu[ps[i]][i]; - } - - for (i = N; i < n + N; i++) b[i] = X[i]; -} - -// -// End of linear algebra functions -// - -// -// Begin of geometric tests -// - -// All the following routines require the input objects are not degenerate. -// i.e., a triangle must has three non-collinear corners; an edge must -// has two identical endpoints. Degenerate cases should have to detect -// first and then handled as special cases. - -/////////////////////////////////////////////////////////////////////////////// -// // -// edge_vertex_collinear_inter() Test whether an edge (ab) and a vertex // -// (p) are intersecting or not. // -// // -// p and ab are collinear. Possible cases are p is coincident to a (p = a), // -// or coincident to b (p = b), or inside ab (a < p < b), or outside ab (p < // -// a or p > b). These cases can be quickly determined by comparing the // -// homogeneous coordinates of a, b, and p (which are not all equal). // -// // -// The return value indicates one of the three cases: DISJOINT, SHAREVERTEX // -// (p = a or p = b), and INTERSECT (a < p < b). // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -edge_vertex_collinear_inter(REAL* A, REAL* B, REAL* P) -{ - int i = 0; - do { - if (A[i] < B[i]) { - if (P[i] < A[i]) { - return DISJOINT; - } else if (P[i] > A[i]) { - if (P[i] < B[i]) { - return INTERSECT; - } else if (P[i] > B[i]) { - return DISJOINT; - } else { - // assert(P[i] == B[i]); - return SHAREVERTEX; - } - } else { - // assert(P[i] == A[i]); - return SHAREVERTEX; - } - } else if (A[i] > B[i]) { - if (P[i] < B[i]) { - return DISJOINT; - } else if (P[i] > B[i]) { - if (P[i] < A[i]) { - return INTERSECT; - } else if (P[i] > A[i]) { - return DISJOINT; - } else { - // assert(P[i] == A[i]); - return SHAREVERTEX; - } - } else { - // assert(P[i] == B[i]); - return SHAREVERTEX; - } - } - // i-th coordinates are equal, try i+1-th; - i++; - } while (i < 3); - // Should never be here. - assert(i >= 3); - return DISJOINT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// edge_edge_coplanar_inter() Test whether two edges (ab) and (pq) are // -// intersecting or not. // -// // -// ab and pq are coplanar. Possible cases are ab and pq are disjointed, or // -// proper intersecting (intersect at a point other than their vertices), or // -// collinear and intersecting, or sharing at a vertex, or ab and pq are co- // -// incident (i.e., the same edge). // -// // -// A reference point R is required, which is exactly not coplanar with these // -// two edges. Since the caller know these two edges are coplanar, it must // -// be able to provide (or calculate) such a point. // -// // -// The return value indicates one of the four cases: DISJOINT, SHAREVERTEX, // -// SHAREEDGE, and INTERSECT. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -edge_edge_coplanar_inter(REAL* A, REAL* B, REAL* P, REAL* Q, REAL* R) -{ - REAL s1, s2, s3, s4; - - assert(R != NULL); - - s1 = orient3d(A, B, R, P); - s2 = orient3d(A, B, R, Q); - if (s1 * s2 > 0.0) { - // Both p and q are at the same side of ab. - return DISJOINT; - } - s3 = orient3d(P, Q, R, A); - s4 = orient3d(P, Q, R, B); - if (s3 * s4 > 0.0) { - // Both a and b are at the same side of pq. - return DISJOINT; - } - - // Possible degenerate cases are: - // (1) Only one of p and q is collinear with ab; - // (2) Both p and q are collinear with ab; - // (3) Only one of a and b is collinear with pq. - enum intersectresult abp, abq; - enum intersectresult pqa, pqb; - - if (s1 == 0.0) { - // p is collinear with ab. - abp = edge_vertex_collinear_inter(A, B, P); - if (abp == INTERSECT) { - // p is inside ab. - return INTERSECT; - } - if (s2 == 0.0) { - // q is collinear with ab. Case (2). - abq = edge_vertex_collinear_inter(A, B, Q); - if (abq == INTERSECT) { - // q is inside ab. - return INTERSECT; - } - if (abp == SHAREVERTEX && abq == SHAREVERTEX) { - // ab and pq are identical. - return SHAREEDGE; - } - pqa = edge_vertex_collinear_inter(P, Q, A); - if (pqa == INTERSECT) { - // a is inside pq. - return INTERSECT; - } - pqb = edge_vertex_collinear_inter(P, Q, B); - if (pqb == INTERSECT) { - // b is inside pq. - return INTERSECT; - } - if (abp == SHAREVERTEX || abq == SHAREVERTEX) { - // either p or q is coincident with a or b. - // ONLY one case is possible, otherwise, shoule be SHAREEDGE. - assert(abp ^ abq); - return SHAREVERTEX; - } - // The last case. They are disjointed. - assert((abp == DISJOINT) && (abp == abq && abq == pqa && pqa == pqb)); - return DISJOINT; - } else { - // p is collinear with ab. Case (1). - assert(abp == SHAREVERTEX || abp == DISJOINT); - return abp; - } - } - // p is NOT collinear with ab. - if (s2 == 0.0) { - // q is collinear with ab. Case (1). - abq = edge_vertex_collinear_inter(A, B, Q); - assert(abq == SHAREVERTEX || abq == DISJOINT || abq == INTERSECT); - return abq; - } - - // We have found p and q are not collinear with ab. However, it is still - // possible that a or b is collinear with pq (ONLY one of a and b). - if (s3 == 0.0) { - // a is collinear with pq. Case (3). - assert(s4 != 0.0); - pqa = edge_vertex_collinear_inter(P, Q, A); - // This case should have been detected in above. - assert(pqa != SHAREVERTEX); - assert(pqa == INTERSECT || pqa == DISJOINT); - return pqa; - } - if (s4 == 0.0) { - // b is collinear with pq. Case (3). - assert(s3 != 0.0); - pqb = edge_vertex_collinear_inter(P, Q, B); - // This case should have been detected in above. - assert(pqb != SHAREVERTEX); - assert(pqb == INTERSECT || pqb == DISJOINT); - return pqb; - } - - // ab and pq are intersecting properly. - return INTERSECT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// Notations // -// // -// Let ABC be the plane passes through a, b, and c; ABC+ be the halfspace // -// including the set of all points x, such that orient3d(a, b, c, x) > 0; // -// ABC- be the other halfspace, such that for each point x in ABC-, // -// orient3d(a, b, c, x) < 0. For the set of x which are on ABC, orient3d(a, // -// b, c, x) = 0. // -// // -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangle_vertex_coplanar_inter() Test whether a triangle (abc) and a // -// point (p) are intersecting or not. // -// // -// abc and p are coplanar. Possible cases are p is inside abc, or on an edge // -// of, or coincident with a vertex of, or outside abc. // -// // -// A reference point R is required, which is exactly not coplanar with the // -// triangle and the vertex. Since the caller know they are coplanar, it must // -// be able to provide (or calculate) such a point. // -// // -// The return value indicates one of the four cases: DISJOINT, SHAREVERTEX, // -// and INTERSECT. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -triangle_vertex_coplanar_inter(REAL* A, REAL* B, REAL* C, REAL* P, REAL* R) -{ - REAL s1, s2, s3; - int sign; - - assert(R != (REAL *) NULL); - - // Adjust the orientation of a, b, c and r, so that we can assume that - // r is strictly in ABC- (i.e., r is above ABC wrt. right-hand rule). - s1 = orient3d(A, B, C, R); - assert(s1 != 0.0); - sign = s1 < 0.0 ? 1 : -1; - - // Test starts from here. - s1 = orient3d(A, B, R, P) * sign; - if (s1 < 0.0) { - // p is in ABR-. - return DISJOINT; - } - s2 = orient3d(B, C, R, P) * sign; - if (s2 < 0.0) { - // p is in BCR-. - return DISJOINT; - } - s3 = orient3d(C, A, R, P) * sign; - if (s3 < 0.0) { - // p is in CAR-. - return DISJOINT; - } - if (s1 == 0.0) { - // p is on ABR. - if (s2 == 0.0) { - // p is on BCR. - assert(s3 > 0.0); - // p is coincident with b. - return SHAREVERTEX; - } - if (s3 == 0.0) { - // p is on CAR. - // p is coincident with a. - return SHAREVERTEX; - } - // p is on edge ab. - return INTERSECT; - } - // p is in ABR+. - if (s2 == 0.0) { - // p is on BCR. - if (s3 == 0.0) { - // p is on CAR. - // p is coincident with c. - return SHAREVERTEX; - } - // p is on edge bc. - return INTERSECT; - } - if (s3 == 0.0) { - // p is on CAR. - // p is on edge ca. - return INTERSECT; - } - - // p is strictly inside abc. - return INTERSECT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangle_edge_coplanar_inter() Test whether a triangle (abc) and an // -// edge (pq) are intersecting or not. // -// // -// A reference point R is required, which is exactly not coplanar with the // -// triangle and the edge. Since the caller know they are coplanar, it must // -// be able to provide (or calculate) such a point. // -// // -// The return value indicates one of the four cases: DISJOINT, SHAREVERTEX, // -// SHAREEDGE, and INTERSECT. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -triangle_edge_coplanar_inter(REAL* A, REAL* B, REAL* C, REAL* P, REAL* Q, - REAL* R) -{ - enum intersectresult abpq, bcpq, capq; - enum intersectresult abcp, abcq; - - // Test if pq is intersecting one of edges of abc. - abpq = edge_edge_coplanar_inter(A, B, P, Q, R); - if (abpq == INTERSECT || abpq == SHAREEDGE) { - return abpq; - } - bcpq = edge_edge_coplanar_inter(B, C, P, Q, R); - if (bcpq == INTERSECT || bcpq == SHAREEDGE) { - return bcpq; - } - capq = edge_edge_coplanar_inter(C, A, P, Q, R); - if (capq == INTERSECT || capq == SHAREEDGE) { - return capq; - } - - // Test if p and q is inside abc. - abcp = triangle_vertex_coplanar_inter(A, B, C, P, R); - if (abcp == INTERSECT) { - return INTERSECT; - } - abcq = triangle_vertex_coplanar_inter(A, B, C, Q, R); - if (abcq == INTERSECT) { - return INTERSECT; - } - - // Combine the test results of edge intersectings and triangle insides - // to detect whether abc and pq are sharing vertex or disjointed. - if (abpq == SHAREVERTEX) { - // p or q is coincident with a or b. - assert(abcp ^ abcq); - return SHAREVERTEX; - } - if (bcpq == SHAREVERTEX) { - // p or q is coincident with b or c. - assert(abcp ^ abcq); - return SHAREVERTEX; - } - if (capq == SHAREVERTEX) { - // p or q is coincident with c or a. - assert(abcp ^ abcq); - return SHAREVERTEX; - } - - // They are disjointed. - return DISJOINT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangle_edge_inter_tail() Test whether a triangle (abc) and an edge // -// (pq) are intersecting or not. // -// // -// s1 and s2 are results of pre-performed orientation tests. s1 = orient3d( // -// a, b, c, p); s2 = orient3d(a, b, c, q). // -// // -// To separate this routine from triangle_edge_inter() can save two // -// orientation tests in triangle_triangle_inter(). // -// // -// The return value indicates one of the four cases: DISJOINT, SHAREVERTEX, // -// SHAREEDGE, and INTERSECT. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -triangle_edge_inter_tail(REAL* A, REAL* B, REAL* C, REAL* P, REAL* Q, REAL s1, - REAL s2) -{ - REAL s3, s4, s5; - int sign; - - if (s1 * s2 > 0.0) { - // p, q are at the same halfspace of ABC, no intersection. - return DISJOINT; - } - - if (s1 * s2 < 0.0) { - // p, q are both not on ABC (and not sharing vertices, edges of abc). - // Adjust the orientation of a, b, c and p, so that we can assume that - // p is strictly in ABC-, and q is strictly in ABC+. - sign = s1 < 0.0 ? 1 : -1; - s3 = orient3d(A, B, P, Q) * sign; - if (s3 < 0.0) { - // q is at ABP-. - return DISJOINT; - } - s4 = orient3d(B, C, P, Q) * sign; - if (s4 < 0.0) { - // q is at BCP-. - return DISJOINT; - } - s5 = orient3d(C, A, P, Q) * sign; - if (s5 < 0.0) { - // q is at CAP-. - return DISJOINT; - } - if (s3 == 0.0) { - // q is on ABP. - if (s4 == 0.0) { - // q is on BCP (and q must in CAP+). - assert(s5 > 0.0); - // pq intersects abc at vertex b. - return SHAREVERTEX; - } - if (s5 == 0.0) { - // q is on CAP (and q must in BCP+). - // pq intersects abc at vertex a. - return SHAREVERTEX; - } - // q in both BCP+ and CAP+. - // pq crosses ab properly. - return INTERSECT; - } - // q is in ABP+; - if (s4 == 0.0) { - // q is on BCP. - if (s5 == 0.0) { - // q is on CAP. - // pq intersects abc at vertex c. - return SHAREVERTEX; - } - // pq crosses bc properly. - return INTERSECT; - } - // q is in BCP+; - if (s5 == 0.0) { - // q is on CAP. - // pq crosses ca properly. - return INTERSECT; - } - // q is in CAP+; - // pq crosses abc properly. - return INTERSECT; - } - - if (s1 != 0.0 || s2 != 0.0) { - // Either p or q is coplanar with abc. ONLY one of them is possible. - if (s1 == 0.0) { - // p is coplanar with abc, q can be used as reference point. - assert(s2 != 0.0); - return triangle_vertex_coplanar_inter(A, B, C, P, Q); - } else { - // q is coplanar with abc, p can be used as reference point. - assert(s2 == 0.0); - return triangle_vertex_coplanar_inter(A, B, C, Q, P); - } - } - - // pq is coplanar with abc. Calculate a point which is exactly - // non-coplanar with a, b, and c. - REAL R[3], N[3]; - REAL ax, ay, az, bx, by, bz; - - ax = A[0] - B[0]; - ay = A[1] - B[1]; - az = A[2] - B[2]; - bx = A[0] - C[0]; - by = A[1] - C[1]; - bz = A[2] - C[2]; - N[0] = ay * bz - by * az; - N[1] = az * bx - bz * ax; - N[2] = ax * by - bx * ay; - // The normal should not be a zero vector. - assert((fabs(N[0]) + fabs(N[1]) + fabs(N[2])) > 0.0); - // The reference point R is lifted from A to the normal direction with - // a non-zero distance. - R[0] = N[0] + A[0]; - R[1] = N[1] + A[1]; - R[2] = N[2] + A[2]; - // Becareful the case: if the non-zero component(s) in N is smaller than - // the machine epsilon (i.e., 2^(-16) for double), R will exactly equal - // to A due to the round-off error. Do check if it is. - if (R[0] == A[0] && R[1] == A[1] && R[2] == A[2]) { - int i, j; - for (i = 0; i < 3; i++) { - assert (R[i] == A[i]); - j = 2; - do { - if (N[i] > 0.0) { - N[i] += (j * macheps); - } else { - N[i] -= (j * macheps); - } - R[i] = N[i] + A[i]; - j *= 2; - } while (R[i] == A[i]); - } - } - - return triangle_edge_coplanar_inter(A, B, C, P, Q, R); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangle_edge_inter() Test whether a triangle (abc) and an edge (pq) // -// are intersecting or not. // -// // -// The return value indicates one of the four cases: DISJOINT, SHAREVERTEX, // -// SHAREEDGE, and INTERSECT. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -triangle_edge_inter(REAL* A, REAL* B, REAL* C, REAL* P, REAL* Q) -{ - REAL s1, s2; - - // Test the locations of p and q with respect to ABC. - s1 = orient3d(A, B, C, P); - s2 = orient3d(A, B, C, Q); - - return triangle_edge_inter_tail(A, B, C, P, Q, s1, s2); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangle_triangle_inter() Test whether two triangle (abc) and (opq) // -// are intersecting or not. // -// // -// The return value indicates one of the five cases: DISJOINT, SHAREVERTEX, // -// SHAREEDGE, SHAREFACE, and INTERSECT. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::intersectresult tetgenmesh:: -triangle_triangle_inter(REAL* A, REAL* B, REAL* C, REAL* O, REAL* P, REAL* Q) -{ - REAL s_o, s_p, s_q; - REAL s_a, s_b, s_c; - - s_o = orient3d(A, B, C, O); - s_p = orient3d(A, B, C, P); - s_q = orient3d(A, B, C, Q); - if ((s_o * s_p > 0.0) && (s_o * s_q > 0.0)) { - // o, p, q are all in the same halfspace of ABC. - return DISJOINT; - } - - s_a = orient3d(O, P, Q, A); - s_b = orient3d(O, P, Q, B); - s_c = orient3d(O, P, Q, C); - if ((s_a * s_b > 0.0) && (s_a * s_c > 0.0)) { - // a, b, c are all in the same halfspace of OPQ. - return DISJOINT; - } - - enum intersectresult abcop, abcpq, abcqo; - int shareedge = 0; - - abcop = triangle_edge_inter_tail(A, B, C, O, P, s_o, s_p); - if (abcop == INTERSECT) { - return INTERSECT; - } else if (abcop == SHAREEDGE) { - shareedge++; - } - abcpq = triangle_edge_inter_tail(A, B, C, P, Q, s_p, s_q); - if (abcpq == INTERSECT) { - return INTERSECT; - } else if (abcpq == SHAREEDGE) { - shareedge++; - } - abcqo = triangle_edge_inter_tail(A, B, C, Q, O, s_q, s_o); - if (abcqo == INTERSECT) { - return INTERSECT; - } else if (abcqo == SHAREEDGE) { - shareedge++; - } - if (shareedge == 3) { - // opq are coincident with abc. - return SHAREFACE; - } - // It is only possible either no share edge or one. - assert(shareedge == 0 || shareedge == 1); - - // Continue to detect whether opq and abc are intersecting or not. - enum intersectresult opqab, opqbc, opqca; - - opqab = triangle_edge_inter_tail(O, P, Q, A, B, s_a, s_b); - if (opqab == INTERSECT) { - return INTERSECT; - } - opqbc = triangle_edge_inter_tail(O, P, Q, B, C, s_b, s_c); - if (opqbc == INTERSECT) { - return INTERSECT; - } - opqca = triangle_edge_inter_tail(O, P, Q, C, A, s_c, s_a); - if (opqca == INTERSECT) { - return INTERSECT; - } - - // At this point, two triangles are not intersecting and not coincident. - // They may be share an edge, or share a vertex, or disjoint. - if (abcop == SHAREEDGE) { - assert(abcpq == SHAREVERTEX && abcqo == SHAREVERTEX); - // op is coincident with an edge of abc. - return SHAREEDGE; - } - if (abcpq == SHAREEDGE) { - assert(abcop == SHAREVERTEX && abcqo == SHAREVERTEX); - // pq is coincident with an edge of abc. - return SHAREEDGE; - } - if (abcqo == SHAREEDGE) { - assert(abcop == SHAREVERTEX && abcpq == SHAREVERTEX); - // qo is coincident with an edge of abc. - return SHAREEDGE; - } - - // They may share a vertex or disjoint. - if (abcop == SHAREVERTEX) { - // o or p is coincident with a vertex of abc. - if (abcpq == SHAREVERTEX) { - // p is the coincident vertex. - assert(abcqo != SHAREVERTEX); - } else { - // o is the coincident vertex. - assert(abcqo == SHAREVERTEX); - } - return SHAREVERTEX; - } - if (abcpq == SHAREVERTEX) { - // q is the coincident vertex. - assert(abcqo == SHAREVERTEX); - return SHAREVERTEX; - } - - // They are disjoint. - return DISJOINT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// iscollinear() Check if three points are collinear with respect to a // -// given relative tolerance. // -// // -// 'epspp' is the relative tolerance provided by caller. The collinearity is // -// determined by evaluating the angle q between the two vectors formed from // -// thes three points. If q <= epspp, then they are assumed be collinear. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::iscollinear(REAL* A, REAL* B, REAL* C, REAL epspp) -{ - REAL V[3], W[3]; - REAL Lv, Lw, d, q; - - V[0] = A[0] - B[0]; - V[1] = A[1] - B[1]; - V[2] = A[2] - B[2]; - W[0] = A[0] - C[0]; - W[1] = A[1] - C[1]; - W[2] = A[2] - C[2]; - Lv = sqrt(V[0] * V[0] + V[1] * V[1] + V[2] * V[2]); - Lw = sqrt(W[0] * W[0] + W[1] * W[1] + W[2] * W[2]); - - d = (V[0] * W[0] + V[1] * W[1] + V[2] * W[2]) / (Lv * Lw); - if (d > 1.0) { - q = 0.0; - } else if (d < -1.0) { - q = 0.0; // q = PI; - } else { - q = acos(fabs(d)); - } - - return q <= epspp; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// iscoplanar() Check if four points are coplanar with respect to a given // -// relative tolerance. // -// // -// 'vol6' is the six times of the signed volume of the tetrahedron formed by // -// the four points. 'epspp' is the relative tolerance provided by the caller.// -// This coplanarity is determined by evaluating the value: // -// // -// q = fabs(vol6) / L^3 // -// // -// where L is the average edge length of the tetrahedron. If q <= epspp, // -// then these four points are assumed be coplanar. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -iscoplanar(REAL* k, REAL* l, REAL* m, REAL* n, REAL vol6, REAL epspp) -{ - REAL L, q; - REAL x, y, z; - - x = k[0] - l[0]; - y = k[1] - l[1]; - z = k[2] - l[2]; - L = sqrt(x * x + y * y + z * z); - x = l[0] - m[0]; - y = l[1] - m[1]; - z = l[2] - m[2]; - L += sqrt(x * x + y * y + z * z); - x = m[0] - k[0]; - y = m[1] - k[1]; - z = m[2] - k[2]; - L += sqrt(x * x + y * y + z * z); - x = k[0] - n[0]; - y = k[1] - n[1]; - z = k[2] - n[2]; - L += sqrt(x * x + y * y + z * z); - x = l[0] - n[0]; - y = l[1] - n[1]; - z = l[2] - n[2]; - L += sqrt(x * x + y * y + z * z); - x = m[0] - n[0]; - y = m[1] - n[1]; - z = m[2] - n[2]; - L += sqrt(x * x + y * y + z * z); - assert(L > 0.0); - L /= 6.0; - q = fabs(vol6) / (L * L * L); - - return q <= epspp; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// iscospheric() Check if five points are coplanar with respect to a // -// given relative tolerance. // -// // -// The cosphere is determined by comparing the distance between the radius R // -// of the circumsphere S of the first four points and the distance from the // -// circumcenter C of S to the fifth points P, i.e., to calculate the value: // -// // -// q = fabs(P - C) / R // -// // -// If q <= epspp, then these five points are assumed to be cospherical. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -iscospheric(REAL* k, REAL* l, REAL* m, REAL* n, REAL* o, REAL epspp) -{ - REAL ori, *p5; - REAL cent[3], R, D, q; - - ori = orient3d(k, l, m, n); - if (iscoplanar(k, l, m, n, ori, epspp)) { - ori = orient3d(k, l, m, o); - assert(!iscoplanar(k, l, m, o, ori, epspp)); - circumsphere(k, l, m, o, cent, &R); - p5 = n; - } else { - circumsphere(k, l, m, n, cent, &R); - p5 = o; - } - D = distance(p5, cent); - q = fabs(D - R) / R; - - return q <= epspp; -} - -// -// End of geometric tests -// - -// -// Begin of Geometric quantities calculators -// - -// distance() computs the Euclidean distance between two points. -inline REAL tetgenmesh::distance(REAL* p1, REAL* p2) -{ - return sqrt((p2[0] - p1[0]) * (p2[0] - p1[0]) + - (p2[1] - p1[1]) * (p2[1] - p1[1]) + - (p2[2] - p1[2]) * (p2[2] - p1[2])); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// shortdistance() Returns the shortest distance from point p to a line // -// defined by two points e1 and e2. // -// // -// First compute the projection length l_p of the vector v1 = p - e1 along // -// the vector v2 = e2 - e1. Then Pythagoras' Theorem is used to compute the // -// shortest distance. // -// // -// This routine allows that p is collinear with the line. In this case, the // -// return value is zero. The two points e1 and e2 should not be identical. // -// // -/////////////////////////////////////////////////////////////////////////////// - -REAL tetgenmesh::shortdistance(REAL* p, REAL* e1, REAL* e2) -{ - REAL v1[3], v2[3]; - REAL len, l_p; - - v1[0] = e2[0] - e1[0]; - v1[1] = e2[1] - e1[1]; - v1[2] = e2[2] - e1[2]; - v2[0] = p[0] - e1[0]; - v2[1] = p[1] - e1[1]; - v2[2] = p[2] - e1[2]; - - len = sqrt(dot(v1, v1)); - assert(len != 0.0); - v1[0] /= len; - v1[1] /= len; - v1[2] /= len; - l_p = dot(v1, v2); - - return sqrt(dot(v2, v2) - l_p * l_p); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// interiorangle() Return the interior angle (0 - 2 * PI) between vectors // -// o->p1 and o->p2. // -// // -// 'n' is the normal of the plane containing face (o, p1, p2). The interior // -// angle is the total angle rotating from o->p1 around n to o->p2. Exchange // -// the position of p1 and p2 will get the complement angle of the other one. // -// i.e., interiorangle(o, p1, p2) = 2 * PI - interiorangle(o, p2, p1). Set // -// 'n' be NULL if you only want the interior angle between 0 - PI. // -// // -/////////////////////////////////////////////////////////////////////////////// - -REAL tetgenmesh::interiorangle(REAL* o, REAL* p1, REAL* p2, REAL* n) -{ - REAL v1[3], v2[3], np[3]; - REAL theta, costheta, lenlen; - REAL ori, len1, len2; - - // Get the interior angle (0 - PI) between o->p1, and o->p2. - v1[0] = p1[0] - o[0]; - v1[1] = p1[1] - o[1]; - v1[2] = p1[2] - o[2]; - v2[0] = p2[0] - o[0]; - v2[1] = p2[1] - o[1]; - v2[2] = p2[2] - o[2]; - len1 = sqrt(dot(v1, v1)); - len2 = sqrt(dot(v2, v2)); - lenlen = len1 * len2; - assert(lenlen != 0.0); - costheta = dot(v1, v2) / lenlen; - if (costheta > 1.0) { - costheta = 1.0; // Roundoff. - } else if (costheta < -1.0) { - costheta = -1.0; // Roundoff. - } - theta = acos(costheta); - if (n != NULL) { - // Get a point above the face (o, p1, p2); - np[0] = o[0] + n[0]; - np[1] = o[1] + n[1]; - np[2] = o[2] + n[2]; - // Adjust theta (0 - 2 * PI). - ori = orient3d(p1, o, np, p2); - if (ori > 0.0) { - theta = 2 * PI - theta; - } - } - - return theta; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// projpt2edge() Return the projection point from a point to an edge. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::projpt2edge(REAL* p, REAL* e1, REAL* e2, REAL* prj) -{ - REAL v1[3], v2[3]; - REAL len, l_p; - - v1[0] = e2[0] - e1[0]; - v1[1] = e2[1] - e1[1]; - v1[2] = e2[2] - e1[2]; - v2[0] = p[0] - e1[0]; - v2[1] = p[1] - e1[1]; - v2[2] = p[2] - e1[2]; - - len = sqrt(dot(v1, v1)); - assert(len != 0.0); - v1[0] /= len; - v1[1] /= len; - v1[2] /= len; - l_p = dot(v1, v2); - - prj[0] = e1[0] + l_p * v1[0]; - prj[1] = e1[1] + l_p * v1[1]; - prj[2] = e1[2] + l_p * v1[2]; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// projpt2face() Return the projection point from a point to a face. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::projpt2face(REAL* p, REAL* f1, REAL* f2, REAL* f3, REAL* prj) -{ - REAL fnormal[3], v1[3]; - REAL len, dist; - - // Get the unit face normal. - facenormal(f1, f2, f3, fnormal, &len); - assert(len > 0.0); - fnormal[0] /= len; - fnormal[1] /= len; - fnormal[2] /= len; - // Get the vector v1 = |p - f1|. - v1[0] = p[0] - f1[0]; - v1[1] = p[1] - f1[1]; - v1[2] = p[2] - f1[2]; - // Get the project distance. - dist = dot(fnormal, v1); - assert(fabs(dist) >= b->epsilon); - - // Get the project point. - prj[0] = p[0] - dist * fnormal[0]; - prj[1] = p[1] - dist * fnormal[1]; - prj[2] = p[2] - dist * fnormal[2]; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// facenormal() Calculate the normal of a face given by three points. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::facenormal(REAL* pa, REAL* pb, REAL* pc, REAL* n, REAL* nlen) -{ - REAL v1[3], v2[3]; - - v1[0] = pb[0] - pa[0]; - v1[1] = pb[1] - pa[1]; - v1[2] = pb[2] - pa[2]; - v2[0] = pc[0] - pa[0]; - v2[1] = pc[1] - pa[1]; - v2[2] = pc[2] - pa[2]; - - cross(v1, v2, n); - if (nlen != (REAL *) NULL) { - *nlen = sqrt(dot(n, n)); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// edgeorthonormal() Return the unit normal of an edge in a given plane. // -// // -// The edge is from e1 to e2, the plane is defined by given an additional // -// point op, which is non-collinear with the edge. In addition, the side of // -// the edge in which op lies defines the positive position of the normal. // -// // -// Let v1 be the unit vector from e1 to e2, v2 be the unit edge vector from // -// e1 to op, fn be the unit face normal calculated by fn = v1 x v2. Then the // -// unit edge normal of e1e2 pointing to op is n = fn x v1. Note, we should // -// not change the position of fn and v1, otherwise, we get the edge normal // -// pointing to the other side of op. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::edgeorthonormal(REAL* e1, REAL* e2, REAL* op, REAL* n) -{ - REAL v1[3], v2[3], fn[3]; - REAL len; - - // Get the edge vector v1. - v1[0] = e2[0] - e1[0]; - v1[1] = e2[1] - e1[1]; - v1[2] = e2[2] - e1[2]; - // Get the edge vector v2. - v2[0] = op[0] - e1[0]; - v2[1] = op[1] - e1[1]; - v2[2] = op[2] - e1[2]; - // Get the face normal fn = v1 x v2. - cross(v1, v2, fn); - // Get the edge normal n pointing to op. n = fn x v1. - cross(fn, v1, n); - // Normalize the vector. - len = sqrt(dot(n, n)); - n[0] /= len; - n[1] /= len; - n[2] /= len; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// facedihedral() Return the dihedral angle (in radian) between two // -// adjoining faces. // -// // -// 'pa', 'pb' are the shared edge of these two faces, 'pc1', and 'pc2' are // -// apexes of these two faces. Return the angle (between 0 to 2*pi) between // -// the normal of face (pa, pb, pc1) and normal of face (pa, pb, pc2). // -// // -/////////////////////////////////////////////////////////////////////////////// - -REAL tetgenmesh::facedihedral(REAL* pa, REAL* pb, REAL* pc1, REAL* pc2) -{ - REAL n1[3], n2[3]; - REAL n1len, n2len; - REAL costheta, ori; - REAL theta; - - facenormal(pa, pb, pc1, n1, &n1len); - facenormal(pa, pb, pc2, n2, &n2len); - costheta = dot(n1, n2) / (n1len * n2len); - theta = acos(costheta); - ori = orient3d(pa, pb, pc1, pc2); - if (ori > 0.0) { - theta = 2 * PI - theta; - } - - return theta; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetalldihedral() Get all(six) dihedral angles in tetrahedron formed by // -// vertices a, b, c and d. Return by array adDihed[6]. // -// // -// The order in which the dihedrals are assigned matters for computation of // -// solid angles. The way they're currently set up, combining them as (0,1,2),// -// (0,3,4), (1,3,5), (2,4,5) gives (in order) solid angles at vertices a, b, // -// c and d. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -tetalldihedral(point pa, point pb, point pc, point pd, REAL dihed[6]) -{ - REAL n0[3], n1[3], n2[3], n3[3]; - REAL n0len, n1len, n2len, n3len; - REAL dotp; - - facenormal(pc, pb, pd, n0, &n0len); - facenormal(pa, pc, pd, n1, &n1len); - facenormal(pb, pa, pd, n2, &n2len); - facenormal(pa, pb, pc, n3, &n3len); - - n0[0] /= n0len; n0[1] /= n0len; n0[2] /= n0len; - n1[0] /= n1len; n1[1] /= n1len; n1[2] /= n1len; - n2[0] /= n2len; n2[1] /= n2len; n2[2] /= n2len; - n3[0] /= n3len; n3[1] /= n3len; n3[2] /= n3len; - - dotp = -dot(n0, n1); - if (dotp > 1.) dotp = 1.; - else if (dotp < -1.) dotp = -1.; - dihed[5] = acos(dotp); // Edge CD - - dotp = -dot(n0, n2); - if (dotp > 1.) dotp = 1.; - else if (dotp < -1.) dotp = -1.; - dihed[4] = acos(dotp); // Edge BD - - dotp = -dot(n0, n3); - if (dotp > 1.) dotp = 1.; - else if (dotp < -1.) dotp = -1.; - dihed[3] = acos(dotp); // Edge BC - - dotp = -dot(n1, n2); - if (dotp > 1.) dotp = 1.; - else if (dotp < -1.) dotp = -1.; - dihed[2] = acos(dotp); // Edge AD - - dotp = -dot(n1, n3); - if (dotp > 1.) dotp = 1.; - else if (dotp < -1.) dotp = -1.; - dihed[1] = acos(dotp); // Edge AC - - dotp = -dot(n2, n3); - if (dotp > 1.) dotp = 1.; - else if (dotp < -1.) dotp = -1.; - dihed[0] = acos(dotp); // Edge AB -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// circumsphere() Calculate the smallest circumsphere (center and radius) // -// of the given three or four points. // -// // -// The circumsphere of four points (a tetrahedron) is unique if they are not // -// degenerate. If 'pd = NULL', the smallest circumsphere of three points is // -// the diametral sphere of the triangle if they are not degenerate. // -// // -// Return TRUE if the input points are not degenerate and the circumcenter // -// and circumradius are returned in 'cent' and 'radius' respectively if they // -// are not NULLs. Otherwise, return FALSE indicated the points are degenrate.// -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -circumsphere(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* cent, REAL* radius) -{ - REAL A[3][3], rhs[3], D; - int indx[3]; - - // Compute the coefficient matrix A (3x3). - A[0][0] = pb[0] - pa[0]; - A[0][1] = pb[1] - pa[1]; - A[0][2] = pb[2] - pa[2]; - A[1][0] = pc[0] - pa[0]; - A[1][1] = pc[1] - pa[1]; - A[1][2] = pc[2] - pa[2]; - if (pd != NULL) { - A[2][0] = pd[0] - pa[0]; - A[2][1] = pd[1] - pa[1]; - A[2][2] = pd[2] - pa[2]; - } else { - cross(A[0], A[1], A[2]); - } - - // Compute the right hand side vector b (3x1). - rhs[0] = 0.5 * dot(A[0], A[0]); - rhs[1] = 0.5 * dot(A[1], A[1]); - if (pd != NULL) { - rhs[2] = 0.5 * dot(A[2], A[2]); - } else { - rhs[2] = 0.0; - } - - // Solve the 3 by 3 equations use LU decomposition with partial pivoting - // and backward and forward substitute.. - if (!lu_decmp(A, 3, indx, &D, 0)) { - if (radius != (REAL *) NULL) *radius = 0.0; - return false; - } - lu_solve(A, 3, indx, rhs, 0); - if (cent != (REAL *) NULL) { - cent[0] = pa[0] + rhs[0]; - cent[1] = pa[1] + rhs[1]; - cent[2] = pa[2] + rhs[2]; - } - if (radius != (REAL *) NULL) { - *radius = sqrt(rhs[0] * rhs[0] + rhs[1] * rhs[1] + rhs[2] * rhs[2]); - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// inscribedsphere() Compute the radius and center of the biggest // -// inscribed sphere of a given tetrahedron. // -// // -// The tetrahedron is given by its four points, it must not be degenerate. // -// The center and radius are returned in 'cent' and 'radius' respectively if // -// they are not NULLs. // -// // -// Geometrical fact. For any simplex in d dimension, // -// r/h1 + r/h2 + ... r/hn = 1 (n <= d + 1); // -// where r is the radius of inscribed ball, and h is the height of each side // -// of the simplex. The value of 'r/h' is just the barycenter coordinates of // -// each vertex of the simplex. Therefore, we can compute the radius and // -// center of the smallest inscribed ball as following equations: // -// r = 1.0 / (1/h1 + 1/h2 + ... + 1/hn); (1) // -// C = r/h1 * P1 + r/h2 * P2 + ... + r/hn * Pn; (2) // -// where C is the vector of center, P1, P2, .. Pn are vectors of vertices. // -// Here (2) contains n linear equations with n variables. (h, P) must be a // -// pair, h is the height from P to its opposite face. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -inscribedsphere(REAL* pa, REAL* pb, REAL* pc, REAL* pd, REAL* cent, - REAL* radius) -{ - REAL A[3][3], rhs[3], D; - REAL N[3][4], H[4]; // Normals (colume vectors) and heights of each face. - REAL rd; - int indx[3], i, j; - - // Compute the normals of 4 faces. - A[0][0] = pa[0] - pd[0]; - A[0][1] = pa[1] - pd[1]; - A[0][2] = pa[2] - pd[2]; - A[1][0] = pb[0] - pd[0]; - A[1][1] = pb[1] - pd[1]; - A[1][2] = pb[2] - pd[2]; - A[2][0] = pc[0] - pd[0]; - A[2][1] = pc[1] - pd[1]; - A[2][2] = pc[2] - pd[2]; - // Compute inverse of matrix A, to get the 3 normals of 4 faces. - lu_decmp(A, 3, indx, &D, 0); // Decompose the matrix just once. - for (j = 0; j < 3; j++) { - for (i = 0; i < 3; i++) rhs[i] = 0.0; - rhs[j] = -1.0; - lu_solve(A, 3, indx, rhs, 0); - for (i = 0; i < 3; i++) N[i][j] = rhs[i]; - } - // Compute the last normal by summing 3 computed vectors, because sum over - // a closed sufrace is 0. - N[0][3] = - N[0][0] - N[0][1] - N[0][2]; - N[1][3] = - N[1][0] - N[1][1] - N[1][2]; - N[2][3] = - N[2][0] - N[2][1] - N[2][2]; - // Compute the length of normals. - for (i = 0; i < 4; i++) { - // H[i] is the inverse of height of its corresponding face. - H[i] = sqrt(N[0][i] * N[0][i] + N[1][i] * N[1][i] + N[2][i] * N[2][i]); - } - // Compute the radius use eq. (1). - rd = 1.0 / (H[0] + H[1] + H[2] + H[3]); - if (radius != (REAL*) NULL) *radius = rd; - if (cent != (REAL*) NULL) { - // Compute the center use eq. (2). - cent[0] = rd * (H[0] * pa[0] + H[1] * pb[0] + H[2] * pc[0] + H[3] * pd[0]); - cent[1] = rd * (H[0] * pa[1] + H[1] * pb[1] + H[2] * pc[1] + H[3] * pd[1]); - cent[2] = rd * (H[0] * pa[2] + H[1] * pb[2] + H[2] * pc[2] + H[3] * pd[2]); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// rotatepoint() Create a point by rotating an existing point. // -// // -// Create a 3D point by rotating point 'p' with an angle 'rotangle' (in arc // -// degree) around a rotating axis given by a vector from point 'p1' to 'p2'. // -// The rotation is according with right-hand rule, i.e., use your right-hand // -// to grab the axis with your thumber pointing to its positive direction, // -// your fingers indicate the rotating direction. // -// // -// The rotating steps are the following: // -// 1. Translate vector 'p1->p2' to origin, M1; // -// 2. Rotate vector around the Y-axis until it lies in the YZ plane, M2; // -// 3. Rotate vector around the X-axis until it lies on the Z axis, M3; // -// 4. Perform the rotation of 'p' around the z-axis, M4; // -// 5. Undo Step 3, M5; // -// 6. Undo Step 2, M6; // -// 7. Undo Step 1, M7; // -// Use matrix multiplication to combine the above sequences, we get: // -// p0' = T * p0, where T = M7 * M6 * M5 * M4 * M3 * M2 * M1 // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::rotatepoint(REAL* p, REAL rotangle, REAL* p1, REAL* p2) -{ - REAL T[4][4], pp0[4], p0t[4], p2t[4]; - REAL roty, rotx, alphaR, projlen; - REAL dx, dy, dz; - - initm44(1, 0, 0, -p1[0], - 0, 1, 0, -p1[1], - 0, 0, 1, -p1[2], - 0, 0, 0, 1, T); - pp0[0] = p[0]; pp0[1] = p[1]; pp0[2] = p[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 1 - pp0[0] = p2[0]; pp0[1] = p2[1]; pp0[2] = p2[2]; pp0[3] = 1.0; - m4xv4(p2t, T, pp0); // Step 1 - - // Get the rotation angle around y-axis; - dx = p2t[0]; - dz = p2t[2]; - projlen = sqrt(dx * dx + dz * dz); - if (projlen <= (b->epsilon * 1e-2) * longest) { - roty = 0; - } else { - roty = acos(dz / projlen); - if (dx < 0) { - roty = -roty; - } - } - - initm44(cos(-roty), 0, sin(-roty), 0, - 0, 1, 0, 0, - -sin(-roty), 0, cos(-roty), 0, - 0, 0, 0, 1, T); - pp0[0] = p0t[0]; pp0[1] = p0t[1]; pp0[2] = p0t[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 2 - pp0[0] = p2t[0]; pp0[1] = p2t[1]; pp0[2] = p2t[2]; pp0[3] = 1.0; - m4xv4(p2t, T, pp0); // Step 2 - - // Get the rotation angle around x-axis - dy = p2t[1]; - dz = p2t[2]; - projlen = sqrt(dy * dy + dz * dz); - if (projlen <= (b->epsilon * 1e-2) * longest) { - rotx = 0; - } else { - rotx = acos(dz / projlen); - if (dy < 0) { - rotx = -rotx; - } - } - - initm44(1, 0, 0, 0, - 0, cos(rotx), -sin(rotx), 0, - 0, sin(rotx), cos(rotx), 0, - 0, 0, 0, 1, T); - pp0[0] = p0t[0]; pp0[1] = p0t[1]; pp0[2] = p0t[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 3 - // pp0[0] = p2t[0]; pp0[1] = p2t[1]; pp0[2] = p2t[2]; pp0[3] = 1.0; - // m4xv4(p2t, T, pp0); // Step 3 - - alphaR = rotangle; - initm44(cos(alphaR), -sin(alphaR), 0, 0, - sin(alphaR), cos(alphaR), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, T); - pp0[0] = p0t[0]; pp0[1] = p0t[1]; pp0[2] = p0t[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 4 - - initm44(1, 0, 0, 0, - 0, cos(-rotx), -sin(-rotx), 0, - 0, sin(-rotx), cos(-rotx), 0, - 0, 0, 0, 1, T); - pp0[0] = p0t[0]; pp0[1] = p0t[1]; pp0[2] = p0t[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 5 - - initm44(cos(roty), 0, sin(roty), 0, - 0, 1, 0, 0, - -sin(roty), 0, cos(roty), 0, - 0, 0, 0, 1, T); - pp0[0] = p0t[0]; pp0[1] = p0t[1]; pp0[2] = p0t[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 6 - - initm44(1, 0, 0, p1[0], - 0, 1, 0, p1[1], - 0, 0, 1, p1[2], - 0, 0, 0, 1, T); - pp0[0] = p0t[0]; pp0[1] = p0t[1]; pp0[2] = p0t[2]; pp0[3] = 1.0; - m4xv4(p0t, T, pp0); // Step 7 - - p[0] = p0t[0]; - p[1] = p0t[1]; - p[2] = p0t[2]; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// spherelineint() 3D line sphere (or circle) intersection. // -// // -// The line is given by two points p1, and p2, the sphere is centered at c // -// with radius r. This function returns a pointer array p which first index // -// indicates the number of intersection point, followed by coordinate pairs. // -// // -// The following code are adapted from: http://astronomy.swin.edu.au/pbourke // -// /geometry/sphereline. Paul Bourke pbourke@swin.edu.au // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::spherelineint(REAL* p1, REAL* p2, REAL* C, REAL R, REAL p[7]) -{ - REAL x1, y1, z1; // P1 coordinates (point of line) - REAL x2, y2, z2; // P2 coordinates (point of line) - REAL x3, y3, z3, r; // P3 coordinates and radius (sphere) - REAL a, b, c, mu, i ; - - x1 = p1[0]; y1 = p1[1]; z1 = p1[2]; - x2 = p2[0]; y2 = p2[1]; z2 = p2[2]; - x3 = C[0]; y3 = C[1]; z3 = C[2]; - r = R; - - a = (x2 - x1) * (x2 - x1) - + (y2 - y1) * (y2 - y1) - + (z2 - z1) * (z2 - z1); - b = 2 * ( (x2 - x1) * (x1 - x3) - + (y2 - y1) * (y1 - y3) - + (z2 - z1) * (z1 - z3) ) ; - c = (x3 * x3) + (y3 * y3) + (z3 * z3) - + (x1 * x1) + (y1 * y1) + (z1 * z1) - - 2 * (x3 * x1 + y3 * y1 + z3 * z1) - (r * r) ; - i = b * b - 4 * a * c ; - - if (i < 0.0) { - // no intersection - p[0] = 0.0; - } else if (i == 0.0) { - // one intersection - p[0] = 1.0; - mu = -b / (2 * a) ; - p[1] = x1 + mu * (x2 - x1); - p[2] = y1 + mu * (y2 - y1); - p[3] = z1 + mu * (z2 - z1); - } else { - assert(i > 0.0); - // two intersections - p[0] = 2.0; - // first intersection - mu = (-b + sqrt((b * b) - 4 * a * c)) / (2 * a); - p[1] = x1 + mu * (x2 - x1); - p[2] = y1 + mu * (y2 - y1); - p[3] = z1 + mu * (z2 - z1); - // second intersection - mu = (-b - sqrt((b * b) - 4 * a * c)) / (2 * a); - p[4] = x1 + mu * (x2 - x1); - p[5] = y1 + mu * (y2 - y1); - p[6] = z1 + mu * (z2 - z1); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// linelineint() Calculate The shortest line between two lines in 3D. // -// // -// Two 3D lines generally don't intersect at a point, they may be parallel ( // -// no intersections), or they may be coincident (infinite intersections) but // -// most often only their projection onto a plane intersect. When they don't // -// exactly intersect at a point they can be connected by a line segment, the // -// shortest line segment is unique and is often considered to be their inter-// -// section in 3D. // -// // -// The following code are adapted from: http://astronomy.swin.edu.au/pbourke // -// /geometry/lineline3d. Paul Bourke pbourke@swin.edu.au // -// // -// Calculate the line segment PaPb that is the shortest route between two // -// lines P1P2 and P3P4. This function returns a pointer array p which first // -// index indicates there exists solution or not, 0 means no solution, 1 meas // -// has solution followed by two coordinate pairs. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::linelineint(REAL *p1,REAL *p2, REAL *p3, REAL *p4, REAL p[7]) -{ - REAL p13[3], p43[3], p21[3]; - REAL d1343, d4321, d1321, d4343, d2121; - REAL numer, denom; - REAL mua, mub; - - p13[0] = p1[0] - p3[0]; - p13[1] = p1[1] - p3[1]; - p13[2] = p1[2] - p3[2]; - p43[0] = p4[0] - p3[0]; - p43[1] = p4[1] - p3[1]; - p43[2] = p4[2] - p3[2]; - if (p43[0] == 0.0 && p43[1] == 0.0 && p43[2] == 0.0) { - p[0] = 0.0; - return; - } - - p21[0] = p2[0] - p1[0]; - p21[1] = p2[1] - p1[1]; - p21[2] = p2[2] - p1[2]; - if (p21[0] == 0.0 && p21[1] == 0.0 && p21[2] == 0.0) { - p[0] = 0.0; - return; - } - - d1343 = p13[0] * p43[0] + p13[1] * p43[1] + p13[2] * p43[2]; - d4321 = p43[0] * p21[0] + p43[1] * p21[1] + p43[2] * p21[2]; - d1321 = p13[0] * p21[0] + p13[1] * p21[1] + p13[2] * p21[2]; - d4343 = p43[0] * p43[0] + p43[1] * p43[1] + p43[2] * p43[2]; - d2121 = p21[0] * p21[0] + p21[1] * p21[1] + p21[2] * p21[2]; - - denom = d2121 * d4343 - d4321 * d4321; - if (denom == 0.0) { - p[0] = 0.0; - return; - } - numer = d1343 * d4321 - d1321 * d4343; - mua = numer / denom; - mub = (d1343 + d4321 * mua) / d4343; - - p[0] = 1.0; - p[1] = p1[0] + mua * p21[0]; - p[2] = p1[1] + mua * p21[1]; - p[3] = p1[2] + mua * p21[2]; - p[4] = p3[0] + mub * p43[0]; - p[5] = p3[1] + mub * p43[1]; - p[6] = p3[2] + mub * p43[2]; -} - -// -// End of Geometric quantities calculators -// - -// -// Begin of memory management routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// dummyinit() Initialize the tetrahedron that fills "outer space" and // -// the omnipresent subface. // -// // -// The tetrahedron that fills "outer space" called 'dummytet', is pointed to // -// by every tetrahedron and subface on a boundary (be it outer or inner) of // -// the tetrahedralization. Also, 'dummytet' points to one of the tetrahedron // -// on the convex hull(until the holes and concavities are carved), making it // -// possible to find a starting tetrahedron for point location. // -// // -// The omnipresent subface,'dummysh', is pointed to by every tetrahedron or // -// subface that doesn't have a full complement of real subface to point to. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::dummyinit(int tetwords, int shwords) -{ - unsigned long alignptr; - - // Set up 'dummytet', the 'tetrahedron' that occupies "outer space". - dummytetbase = (tetrahedron *) new char[tetwords * sizeof(tetrahedron) - + tetrahedrons->alignbytes]; - // Align 'dummytet' on a 'tetrahedrons->alignbytes'-byte boundary. - alignptr = (unsigned long) dummytetbase; - dummytet = (tetrahedron *) - (alignptr + (unsigned long) tetrahedrons->alignbytes - - (alignptr % (unsigned long) tetrahedrons->alignbytes)); - // Initialize the four adjoining tetrahedra to be "outer space". These - // will eventually be changed by various bonding operations, but their - // values don't really matter, as long as they can legally be - // dereferenced. - dummytet[0] = (tetrahedron) dummytet; - dummytet[1] = (tetrahedron) dummytet; - dummytet[2] = (tetrahedron) dummytet; - dummytet[3] = (tetrahedron) dummytet; - // Four null vertex points. - dummytet[4] = (tetrahedron) NULL; - dummytet[5] = (tetrahedron) NULL; - dummytet[6] = (tetrahedron) NULL; - dummytet[7] = (tetrahedron) NULL; - - if (b->useshelles) { - // Set up 'dummysh', the omnipresent "subface" pointed to by any - // tetrahedron side or subface end that isn't attached to a real - // subface. - dummyshbase = (shellface *) new char[shwords * sizeof(shellface) - + subfaces->alignbytes]; - // Align 'dummysh' on a 'subfaces->alignbytes'-byte boundary. - alignptr = (unsigned long) dummyshbase; - dummysh = (shellface *) - (alignptr + (unsigned long) subfaces->alignbytes - - (alignptr % (unsigned long) subfaces->alignbytes)); - // Initialize the three adjoining subfaces to be the omnipresent - // subface. These will eventually be changed by various bonding - // operations, but their values don't really matter, as long as they - // can legally be dereferenced. - dummysh[0] = (shellface) dummysh; - dummysh[1] = (shellface) dummysh; - dummysh[2] = (shellface) dummysh; - // Three null vertex points. - dummysh[3] = (shellface) NULL; - dummysh[4] = (shellface) NULL; - dummysh[5] = (shellface) NULL; - // Initialize the two adjoining tetrahedra to be "outer space". - dummysh[6] = (shellface) dummytet; - dummysh[7] = (shellface) dummytet; - // Initialize the three adjoining subsegments to be "out boundary". - dummysh[8] = (shellface) dummysh; - dummysh[9] = (shellface) dummysh; - dummysh[10] = (shellface) dummysh; - // Initialize the pointer to badface structure. - dummysh[11] = (shellface) NULL; - // Initialize the four adjoining subfaces of 'dummytet' to be the - // omnipresent subface. - dummytet[8 ] = (tetrahedron) dummysh; - dummytet[9 ] = (tetrahedron) dummysh; - dummytet[10] = (tetrahedron) dummysh; - dummytet[11] = (tetrahedron) dummysh; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// initializepointpool() Calculate the size of the point data structure // -// and initialize its memory pool. // -// // -// This routine also computes the 'pointmarkindex' and 'point2simindex' // -// indices used to find values within each point. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::initializepointpool() -{ - enum wordtype wtype; - int pointsize; - - // The index within each point at which a element pointer is found. Ensure - // the index is aligned to a sizeof(tetrahedron)-byte address. - point2simindex = ((3 + in->numberofpointattributes) * sizeof(REAL) + - sizeof(tetrahedron) - 1) / sizeof(tetrahedron); - if (b->plc || b->refine) { - // Increase the point size by two pointers. One points to a simplex: - // - a tetrahedron containing it, read by point2tet(); - // - a subface containing it, read by point2sh(); - // - a (sharp) subsegment it relates, read by point2sh(); - // - a (duplicated) point of it, read by point2pt(); - // and one points to another point (its parent, used in conforming - // Delaunay meshing algorithm), read by point2ppt(). - pointsize = (point2simindex + 2) * sizeof(tetrahedron); - } else { - pointsize = point2simindex * sizeof(tetrahedron); - } - // The index within each point at which the boundary marker is found, - // Ensure the point marker is aligned to a sizeof(int)-byte address. - pointmarkindex = (pointsize + sizeof(int) - 1) / sizeof(int); - // Now point size is the REALs (inidcated by vertexmarkindex) plus: - // - an integer for boundary marker; - // - an integer for vertex type; - pointsize = (pointmarkindex + 2) * sizeof(int); - // Decide the wordtype used in vertex pool. - wtype = (sizeof(REAL) >= sizeof(tetrahedron)) ? FLOATINGPOINT : POINTER; - // Initialize the pool of vertices. - points = new memorypool(pointsize, VERPERBLOCK, wtype, 0); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// initializetetshpools() Calculate the sizes of the tetrahedron and // -// subface data structures and initialize their // -// memory pools. // -// // -// This routine also computes the 'highorderindex', 'elemattribindex', and // -// 'volumeboundindex' indices used to find values within each tetrahedron. // -// // -// There are two types of boundary elements, whihc are subfaces and subsegs, // -// they are stored in seperate pools. However, the data structures of them // -// are the same. A subsegment can be regarded as a degenerate subface, i.e.,// -// one of its three corners is not used. We set the apex of it be 'NULL' to // -// distinguish it's a subsegment. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::initializetetshpools() -{ - int elesize, shsize; - - // The number of bytes occupied by a tetrahedron. There are four pointers - // to other tetrahedra, four pointers to corners, and possibly four - // pointers to subfaces. - elesize = (8 + b->useshelles * 4) * sizeof(tetrahedron); - // The index within each element at which its attributes are found, where - // the index is measured in REALs. - elemattribindex = (elesize + sizeof(REAL) - 1) / sizeof(REAL); - // The index within each element at which the maximum voulme bound is - // found, where the index is measured in REALs. Note that if the - // `b->regionattrib' flag is set, an additional attribute will be added. - volumeboundindex = elemattribindex + in->numberoftetrahedronattributes - + b->regionattrib; - // If element attributes or an constraint are needed, increase the number - // of bytes occupied by an element. - if (b->varvolume) { - elesize = (volumeboundindex + 1) * sizeof(REAL); - } else if (in->numberoftetrahedronattributes + b->regionattrib > 0) { - elesize = volumeboundindex * sizeof(REAL); - } - // If the high order elements are required (-o2 switch is used), an - // additional pointer pointed to the list of extra nodes is allocated - // for each element. - if (b->order == 2) { - highorderindex = (elesize + sizeof(int) - 1) / sizeof(int); - elesize = (highorderindex + 1) * sizeof(int); - } - // If element neighbor graph is requested, make sure there's room to - // store an integer index in each element. This integer index can - // occupy the same space as the subface pointers. - if (b->neighout && (elesize <= 8 * sizeof(tetrahedron))) { - elesize = 8 * sizeof(tetrahedron) + sizeof(int); - } - // Having determined the memory size of an element, initialize the pool. - tetrahedrons = new memorypool(elesize, ELEPERBLOCK, POINTER, 8); - - if (b->useshelles) { - // The number of bytes occupied by a subface. The list of pointers - // stored in a subface are: three to other subfaces, three to corners, - // three to subsegments, two to tetrahedra, and one to a badface. - shsize = 12 * sizeof(shellface); - // The index within each subface at which the maximum area bound is - // found, where the index is measured in REALs. - areaboundindex = (shsize + sizeof(REAL) - 1) / sizeof(REAL); - // If -q switch is in use, increase the number of bytes occupied by - // a subface for saving maximum area bound. - if (b->quality) { - shsize = (areaboundindex + 1) * sizeof(REAL); - } else { - shsize = areaboundindex * sizeof(REAL); - } - // The index within subface at which the facet marker is found. Ensure - // the marker is aligned to a sizeof(int)-byte address. - shmarkindex = (shsize + sizeof(int) - 1) / sizeof(int); - // Increase the number of bytes by two integers, one for facet marker, - // and one for shellface type. - shsize = (shmarkindex + 2) * sizeof(int); - // Initialize the pool of subfaces. Each subface record is eight-byte - // aligned so it has room to store an edge version (from 0 to 5) in - // the least three bits. - subfaces = new memorypool(shsize, SUBPERBLOCK, POINTER, 8); - // Initialize the pool of subsegments. The subsegment's record is same - // with subface. - subsegs = new memorypool(shsize, SUBPERBLOCK, POINTER, 8); - // Initialize the "outer space" tetrahedron and omnipresent subface. - dummyinit(tetrahedrons->itemwords, subfaces->itemwords); - } else { - // Initialize the "outer space" tetrahedron. - dummyinit(tetrahedrons->itemwords, 0); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetrahedrondealloc() Deallocate space for a tet., marking it dead. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::tetrahedrondealloc(tetrahedron *dyingtetrahedron) -{ - // Set tetrahedron's vertices to NULL. This makes it possible to detect - // dead tetrahedra when traversing the list of all tetrahedra. - dyingtetrahedron[4] = (tetrahedron) NULL; - dyingtetrahedron[5] = (tetrahedron) NULL; - dyingtetrahedron[6] = (tetrahedron) NULL; - dyingtetrahedron[7] = (tetrahedron) NULL; - tetrahedrons->dealloc((void *) dyingtetrahedron); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetrahedrontraverse() Traverse the tetrahedra, skipping dead ones. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::tetrahedron* tetgenmesh::tetrahedrontraverse() -{ - tetrahedron *newtetrahedron; - - do { - newtetrahedron = (tetrahedron *) tetrahedrons->traverse(); - if (newtetrahedron == (tetrahedron *) NULL) { - return (tetrahedron *) NULL; - } - } while (newtetrahedron[7] == (tetrahedron) NULL); // Skip dead ones. - return newtetrahedron; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// shellfacedealloc() Deallocate space for a shellface, marking it dead. // -// Used both for dealloc a subface and subsegment. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::shellfacedealloc(memorypool *pool, shellface *dyingsh) -{ - // Set shellface's vertices to NULL. This makes it possible to detect dead - // shellfaces when traversing the list of all shellfaces. - dyingsh[3] = (shellface) NULL; - dyingsh[4] = (shellface) NULL; - dyingsh[5] = (shellface) NULL; - pool->dealloc((void *) dyingsh); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// shellfacetraverse() Traverse the subfaces, skipping dead ones. Used // -// for both subfaces and subsegments pool traverse. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::shellface* tetgenmesh::shellfacetraverse(memorypool *pool) -{ - shellface *newshellface; - - do { - newshellface = (shellface *) pool->traverse(); - if (newshellface == (shellface *) NULL) { - return (shellface *) NULL; - } - } while (newshellface[3] == (shellface) NULL); // Skip dead ones. - return newshellface; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// badfacedealloc() Deallocate space for a badface, marking it dead. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::badfacedealloc(memorypool *pool, badface *dying) -{ - // Set badface's forg to NULL. This makes it possible to detect dead - // ones when traversing the list of all items. - dying->forg = (point) NULL; - pool->dealloc((void *) dying); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// badfacetraverse() Traverse the pools, skipping dead ones. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::badface* tetgenmesh::badfacetraverse(memorypool *pool) -{ - badface *newsh; - - do { - newsh = (badface *) pool->traverse(); - if (newsh == (badface *) NULL) { - return (badface *) NULL; - } - } while (newsh->forg == (point) NULL); // Skip dead ones. - return newsh; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// pointdealloc() Deallocate space for a point, marking it dead. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::pointdealloc(point dyingpoint) -{ - // Mark the point as dead. This makes it possible to detect dead points - // when traversing the list of all points. - setpointtype(dyingpoint, DEADVERTEX); - points->dealloc((void *) dyingpoint); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// pointtraverse() Traverse the points, skipping dead ones. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::point tetgenmesh::pointtraverse() -{ - point newpoint; - - do { - newpoint = (point) points->traverse(); - if (newpoint == (point) NULL) { - return (point) NULL; - } - } while (pointtype(newpoint) == DEADVERTEX); // Skip dead ones. - return newpoint; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// maketetrahedron() Create a new tetrahedron. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::maketetrahedron(triface *newtet) -{ - newtet->tet = (tetrahedron *) tetrahedrons->alloc(); - // Initialize the four adjoining tetrahedra to be "outer space". - newtet->tet[0] = (tetrahedron) dummytet; - newtet->tet[1] = (tetrahedron) dummytet; - newtet->tet[2] = (tetrahedron) dummytet; - newtet->tet[3] = (tetrahedron) dummytet; - // Four NULL vertices. - newtet->tet[4] = (tetrahedron) NULL; - newtet->tet[5] = (tetrahedron) NULL; - newtet->tet[6] = (tetrahedron) NULL; - newtet->tet[7] = (tetrahedron) NULL; - // Initialize the four adjoining subfaces to be the omnipresent subface. - if (b->useshelles) { - newtet->tet[8 ] = (tetrahedron) dummysh; - newtet->tet[9 ] = (tetrahedron) dummysh; - newtet->tet[10] = (tetrahedron) dummysh; - newtet->tet[11] = (tetrahedron) dummysh; - } - for (int i = 0; i < in->numberoftetrahedronattributes; i++) { - setelemattribute(newtet->tet, i, 0.0); - } - if (b->varvolume) { - setvolumebound(newtet->tet, -1.0); - } - // Initialize the location and version to be Zero. - newtet->loc = 0; - newtet->ver = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// makeshellface() Create a new shellface with version zero. Used for // -// both subfaces and seusegments. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::makeshellface(memorypool *pool, face *newface) -{ - newface->sh = (shellface *) pool->alloc(); - //Initialize the three adjoining subfaces to be the omnipresent subface. - newface->sh[0] = (shellface) dummysh; - newface->sh[1] = (shellface) dummysh; - newface->sh[2] = (shellface) dummysh; - // Three NULL vertices. - newface->sh[3] = (shellface) NULL; - newface->sh[4] = (shellface) NULL; - newface->sh[5] = (shellface) NULL; - // Initialize the two adjoining tetrahedra to be "outer space". - newface->sh[6] = (shellface) dummytet; - newface->sh[7] = (shellface) dummytet; - // Initialize the three adjoining subsegments to be the omnipresent - // subsegments. - newface->sh [8] = (shellface) dummysh; - newface->sh [9] = (shellface) dummysh; - newface->sh[10] = (shellface) dummysh; - // Initialize the pointer to badface structure. - newface->sh[11] = (shellface) NULL; - if (b->quality) { - // Initialize the maximum area bound. - setareabound(*newface, 0.0); - } - // Set the boundary marker to zero. - setshellmark(*newface, 0); - // Set the type be NONPROTSUBFACE. - setshelltype(*newface, NONPROTSUBFACE); - // Initialize the version to be Zero. - newface->shver = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// makepoint() Create a new point. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::makepoint(point* pnewpoint) -{ - int ptmark, i; - - *pnewpoint = (point) points->alloc(); - // Initialize three coordinates. - (*pnewpoint)[0] = 0.0; - (*pnewpoint)[1] = 0.0; - (*pnewpoint)[2] = 0.0; - // Initialize the list of user-defined attributes. - for (i = 0; i < in->numberofpointattributes; i++) { - (*pnewpoint)[3 + i] = 0.0; - } - if (b->plc || b->refine) { - // Initialize the point-to-tetrahedron filed. - setpoint2tet(*pnewpoint, NULL); - // Initialize the other pointer to its parent point. - setpoint2ppt(*pnewpoint, NULL); - } - // Initialize the point marker (starting from in->firstnumber). - ptmark = (int) points->items - (in->firstnumber == 1 ? 0 : 1); - setpointmark(*pnewpoint, ptmark); - // Initialize the point type be UNUSEDVERTEX. - setpointtype(*pnewpoint, UNUSEDVERTEX); -} - -// -// End of memory management routines -// - -// -// Begin of point location routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// randomnation() Generate a random number between 0 and 'choices' - 1. // -// // -/////////////////////////////////////////////////////////////////////////////// - -unsigned long tetgenmesh::randomnation(unsigned int choices) -{ - randomseed = (randomseed * 1366l + 150889l) % 714025l; - return randomseed / (714025l / choices + 1); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// distance2() Returns the square "distance" of a tetrahedron to point p. // -// // -/////////////////////////////////////////////////////////////////////////////// - -REAL tetgenmesh::distance2(tetrahedron* tetptr, point p) -{ - point p1, p2, p3, p4; - REAL dx, dy, dz; - - p1 = (point) tetptr[4]; - p2 = (point) tetptr[5]; - p3 = (point) tetptr[6]; - p4 = (point) tetptr[7]; - - dx = p[0] - 0.25 * (p1[0] + p2[0] + p3[0] + p4[0]); - dy = p[1] - 0.25 * (p1[1] + p2[1] + p3[1] + p4[1]); - dz = p[2] - 0.25 * (p1[2] + p2[2] + p3[2] + p4[2]); - - return dx * dx + dy * dy + dz * dz; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// preciselocate() Find a simplex containing a given point. // -// // -// This routine implements the simple Walk-through point location algorithm. // -// Begins its search from 'searchtet', assume there is a line segment L from // -// a vertex of 'searchtet' to the query point 'searchpoint', and simply walk // -// towards 'searchpoint' by traversing all faces intersected by L. // -// // -// On completion, 'searchtet' is a tetrahedron that contains 'searchpoint'. // -// The returned value indicates one of the following cases: // -// - Returns ONVERTEX if the point lies on an existing vertex. 'searchtet' // -// is a handle whose origin is the existing vertex. // -// - Returns ONEDGE if the point lies on a mesh edge. 'searchtet' is a // -// handle whose primary edge is the edge on which the point lies. // -// - Returns ONFACE if the point lies strictly within a face. 'searchtet' // -// is a handle whose primary face is the face on which the point lies. // -// - Returns INTETRAHEDRON if the point lies strictly in a tetrahededron. // -// 'searchtet' is a handle on the tetrahedron that contains the point. // -// - Returns OUTSIDE if the point lies outside the mesh. 'searchtet' is a // -// handle whose location is the face the point is to 'above' of. // -// // -// WARNING: This routine is designed for convex triangulations, and will not // -// generally work after the holes and concavities have been carved. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::locateresult tetgenmesh:: -preciselocate(point searchpoint, triface* searchtet) -{ - triface backtracetet; - triface walkthroface; - point forg, fdest, fapex, toppo; - REAL ori1, ori2, ori3, ori4; - long tetnumber; - int side; - - // 'searchtet' should be a valid tetrahedron. - if (searchtet->tet == dummytet) { - symself(*searchtet); - assert(searchtet->tet != dummytet); - } - assert(!isdead(searchtet)); - - searchtet->ver = 0; // Keep in CCW edge ring. - // Find a face of 'searchtet' such that the 'searchpoint' lies strictly - // above it. Such face should always exist. - for (searchtet->loc = 0; searchtet->loc < 4; searchtet->loc++) { - forg = org(*searchtet); - fdest = dest(*searchtet); - fapex = apex(*searchtet); - ori1 = orient3d(forg, fdest, fapex, searchpoint); - if (ori1 < 0.0) break; - } - assert(searchtet->loc < 4); - - // Define 'tetnumber' for exit the loop when it's running endless. - tetnumber = 0l; - while (tetnumber <= tetrahedrons->items) { - // Check if we are reaching the boundary of the triangulation. - if (searchtet->tet == dummytet) { - *searchtet = backtracetet; - return OUTSIDE; - } - // Initialize the face for returning the walk-through face. - walkthroface.tet = (tetrahedron *) NULL; - // Adjust the edge ring, so that 'ori1 < 0.0' holds. - searchtet->ver = 0; - // 'toppo' remains unchange for the following orientation tests. - toppo = oppo(*searchtet); - // Check the three sides of 'searchtet' to find the face through which - // we can walk next. - for (side = 0; side < 3; side++) { - forg = org(*searchtet); - fdest = dest(*searchtet); - ori2 = orient3d(forg, fdest, toppo, searchpoint); - if (ori2 == 0.0) { - // They are coplanar, check if 'searchpoint' lies inside, or on an - // edge, or coindice with a vertex of face (forg, fdest, toppo). - fapex = apex(*searchtet); - ori3 = orient3d(fdest, fapex, toppo, searchpoint); - if (ori3 < 0.0) { - // Outside the face (fdest, fapex, toppo), walk through it. - enextself(*searchtet); - fnext(*searchtet, walkthroface); - break; - } - ori4 = orient3d(fapex, forg, toppo, searchpoint); - if (ori4 < 0.0) { - // Outside the face (fapex, forg, toppo), walk through it. - enext2self(*searchtet); - fnext(*searchtet, walkthroface); - break; - } - // Remember, ori1 < 0.0, which means 'searchpoint' will not - // on edge (forg, fdest) or on vertex forg or fdest. - assert(ori1 < 0.0); - // The rest possible cases are: - // (1) 'searchpoint' lies on edge (fdest, toppo); - // (2) 'searchpoint' lies on edge (toppo, forg); - // (3) 'searchpoint' coincident with toppo; - // (4) 'searchpoint' lies inside face (forg, fdest, toppo). - fnextself(*searchtet); - if (ori3 == 0.0) { - if (ori4 == 0.0) { - // Case (4). - enext2self(*searchtet); - return ONVERTEX; - } else { - // Case (1). - enextself(*searchtet); - return ONEDGE; - } - } - if (ori4 == 0.0) { - // Case (2). - enext2self(*searchtet); - return ONEDGE; - } - // Case (4). - return ONFACE; - } else if (ori2 < 0.0) { - // Outside the face (forg, fdest, toppo), walk through it. - fnext(*searchtet, walkthroface); - break; - } - // Go to check next side. - enextself(*searchtet); - } - if (side >= 3) { - // Found! Inside tetrahedron. - return INTETRAHEDRON; - } - // We walk through the face 'walkthroface' and continue the searching. - assert(walkthroface.tet != (tetrahedron *) NULL); - // Store the face handle in 'backtracetet' before we take the real walk. - // So we are able to restore the handle to 'searchtet' if we are - // reaching the outer boundary. - backtracetet = walkthroface; - sym(walkthroface, *searchtet); - tetnumber++; - } - - // Should never be here. - printf("Internal error in preciselocate(): Point location failed.\n"); - internalerror(); - return OUTSIDE; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// locate() Find a simplex containing a given point. // -// // -// This routine implements Muecke's Jump-and-walk point location algorithm. // -// It improves the simple walk-through by "jumping" to a good starting point // -// via random sampling. Searching begins from one of handles: the input // -// 'searchtet', a recently encountered tetrahedron 'recenttet', or from one // -// chosen from a random sample. The choice is made by determining which one // -// 's barycenter is closest to the point we are searcing for. Having chosen // -// the starting tetrahedron, the simple Walk-through algorithm is used to do // -// the real walking. // -// // -// On completion, 'searchtet' is a tetrahedron that contains 'searchpoint'. // -// The returned value indicates one of the following cases: // -// - Returns ONVERTEX if the point lies on an existing vertex. 'searchtet' // -// is a handle whose origin is the existing vertex. // -// - Returns ONEDGE if the point lies on a mesh edge. 'searchtet' is a // -// handle whose primary edge is the edge on which the point lies. // -// - Returns ONFACE if the point lies strictly within a face. 'searchtet' // -// is a handle whose primary face is the face on which the point lies. // -// - Returns INTETRAHEDRON if the point lies strictly in a tetrahededron. // -// 'searchtet' is a handle on the tetrahedron that contains the point. // -// - Returns OUTSIDE if the point lies outside the mesh. 'searchtet' is a // -// handle whose location is the face the point is to 'above' of. // -// // -// WARNING: This routine is designed for convex triangulations, and will not // -// generally work after the holes and concavities have been carved. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::locateresult tetgenmesh:: -locate(point searchpoint, triface *searchtet) -{ - tetrahedron *firsttet, *tetptr; - void **sampleblock; - long sampleblocks, samplesperblock, samplenum; - long tetblocks, i, j; - unsigned long alignptr; - REAL searchdist, dist; - - // 'searchtet' should be a valid tetrahedron. - if (isdead(searchtet)) { - searchtet->tet = dummytet; - } - if (searchtet->tet == dummytet) { - // This is an 'Outer Space' handle, get a hull tetrahedron. - searchtet->loc = 0; - symself(*searchtet); - } - assert(!isdead(searchtet)); - - // Record the distance from the suggested starting tetrahedron to the - // point we seek. - searchdist = distance2(searchtet->tet, searchpoint); - - // If a recently encountered tetrahedron has been recorded and has not - // been deallocated, test it as a good starting point. - if (!isdead(&recenttet) && (recenttet.tet != searchtet->tet)) { - dist = distance2(recenttet.tet, searchpoint); - if (dist < searchdist) { - *searchtet = recenttet; - searchdist = dist; - } - } - - // Select "good" candidate using k random samples, taking the closest one. - // The number of random samples taken is proportional to the cube root - // of the number of tetrahedra in the mesh. The next bit of code assumes - // that the number of tetrahedra increases monotonically. - while (SAMPLEFACTOR * samples * samples * samples < tetrahedrons->items) { - samples++; - } - // Find how much blocks in current tet pool. - tetblocks = (tetrahedrons->maxitems + ELEPERBLOCK - 1) / ELEPERBLOCK; - // Find the average samles per block. Each block at least have 1 sample. - samplesperblock = 1 + (samples / tetblocks); - sampleblocks = samples / samplesperblock; - sampleblock = tetrahedrons->firstblock; - for (i = 0; i < sampleblocks; i++) { - alignptr = (unsigned long) (sampleblock + 1); - firsttet = (tetrahedron *) - (alignptr + (unsigned long) tetrahedrons->alignbytes - - (alignptr % (unsigned long) tetrahedrons->alignbytes)); - for (j = 0; j < samplesperblock; j++) { - if (i == tetblocks - 1) { - // This is the last block. - samplenum = randomnation((int) - (tetrahedrons->maxitems - (i * ELEPERBLOCK))); - } else { - samplenum = randomnation(ELEPERBLOCK); - } - tetptr = (tetrahedron *) - (firsttet + (samplenum * tetrahedrons->itemwords)); - if (tetptr[4] != (tetrahedron) NULL) { - dist = distance2(tetptr, searchpoint); - if (dist < searchdist) { - searchtet->tet = tetptr; - searchdist = dist; - } - } - } - sampleblock = (void **) *sampleblock; - } - - // Call simple walk-through to locate the point. - return preciselocate(searchpoint, searchtet); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// adjustlocate() Adjust the precise location of a vertex with respect to // -// a given tetrahedron using a given relative tolerance. // -// // -// 'precise' is the precise location (returned from preciselocate()) of the // -// point 'searchpoint' with respect to the tetrahedron 'searchtet'. 'epspp' // -// is the given relative tolerance. // -// // -// This routine reevaluates the orientations of searchpoint with respect to // -// the four faces of searchtet. Detects the coplanarities by additinal tests // -// which are based on the given tolerance. If 'precise' is ONFACE or ONEDGE, // -// we can save one or two orientation tests. // -// // -// On completion, 'searchtet' is a tetrahedron that contains 'searchpoint'. // -// The returned value indicates one of the following cases: // -// - Returns ONVERTEX if the point lies on an existing vertex. 'searchtet' // -// is a handle whose origin is the existing vertex. // -// - Returns ONEDGE if the point lies on a mesh edge. 'searchtet' is a // -// handle whose primary edge is the edge on which the point lies. // -// - Returns ONFACE if the point lies strictly within a face. 'searchtet' // -// is a handle whose primary face is the face on which the point lies. // -// - Returns INTETRAHEDRON if the point lies strictly in a tetrahededron. // -// 'searchtet' is a handle on the tetrahedron that contains the point. // -// - Returns OUTSIDE if the point lies outside the mesh. 'searchtet' is a // -// handle whose location is the face the point is to 'above' of. // -// // -// WARNING: This routine detect degenerate case using relative tolerance. // -// It is better used after locate() or preciselocate(). For general inputs, // -// it may not able to tell the correct location. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::locateresult tetgenmesh:: -adjustlocate(point searchpoint, triface* searchtet, enum locateresult precise, - REAL epspp) -{ - point torg, tdest, tapex, toppo; - REAL s1, s2, s3, s4; - - // For the given 'searchtet', the orientations tests are: - // s1: (tdest, torg, tapex, searchpoint); - // s2: (torg, tdest, toppo, searchpoint); - // s3: (tdest, tapex, toppo, searchpoint); - // s4: (tapex, torg, toppo, searchpoint); - adjustedgering(*searchtet, CCW); - torg = org(*searchtet); - tdest = dest(*searchtet); - tapex = apex(*searchtet); - toppo = oppo(*searchtet); - - switch (precise) { - case ONVERTEX: - // This case we don't need do any further test. - return ONVERTEX; - case ONEDGE: - // (torg, tdest); - s1 = 0.0; - s2 = 0.0; - break; - case ONFACE: - // (tdest, torg, tapex); - s1 = 0.0; - s2 = orient3d(torg, tdest, toppo, searchpoint); - break; - default: // INTETRAHEDRON or OUTSIDE - s1 = orient3d(tdest, torg, tapex, searchpoint); - s2 = orient3d(torg, tdest, toppo, searchpoint); - } - - if (s1 != 0.0) { - if (iscoplanar(tdest, torg, tapex, searchpoint, s1, epspp)) { - s1 = 0.0; - } - } - if (s1 < 0.0) { - return OUTSIDE; - } - - if (s2 != 0.0) { - if (iscoplanar(torg, tdest, toppo, searchpoint, s2, epspp)) { - s2 = 0.0; - } - } - if (s2 < 0.0) { - fnextself(*searchtet); - return OUTSIDE; - } - - s3 = orient3d(tdest, tapex, toppo, searchpoint); - if (s3 != 0.0) { - if (iscoplanar(tdest, tapex, toppo, searchpoint, s3, epspp)) { - s3 = 0.0; - } - } - if (s3 < 0.0) { - enextfnextself(*searchtet); - return OUTSIDE; - } - - s4 = orient3d(tapex, torg, toppo, searchpoint); - if (s4 != 0.0) { - if (iscoplanar(tapex, torg, toppo, searchpoint, s4, epspp)) { - s4 = 0.0; - } - } - if (s4 < 0.0) { - enext2fnextself(*searchtet); - return OUTSIDE; - } - - // Determine degenerate cases. - if (s1 == 0.0) { - if (s2 == 0.0) { - if (s3 == 0.0) { - // On tdest. - enextself(*searchtet); - return ONVERTEX; - } - if (s4 == 0.0) { - // On torg. - return ONVERTEX; - } - // On edge (torg, tdest). - return ONEDGE; - } - if (s3 == 0.0) { - if (s4 == 0.0) { - // On tapex. - enext2self(*searchtet); - return ONVERTEX; - } - // On edge (tdest, tapex). - enextself(*searchtet); - return ONEDGE; - } - if (s4 == 0.0) { - // On edge (tapex, torg). - enext2self(*searchtet); - return ONEDGE; - } - // On face (torg, tdest, tapex). - return ONFACE; - } - if (s2 == 0.0) { - fnextself(*searchtet); - if (s3 == 0.0) { - if (s4 == 0.0) { - // On toppo. - enext2self(*searchtet); - return ONVERTEX; - } - // On edge (tdest, toppo). - enextself(*searchtet); - return ONEDGE; - } - if (s4 == 0.0) { - // On edge (toppo, torg). - enext2self(*searchtet); - return ONEDGE; - } - // On face (torg, tdest, toppo). - return ONFACE; - } - if (s3 == 0.0) { - enextfnextself(*searchtet); - if (s4 == 0.0) { - // On edge (tapex, toppo). - enextself(*searchtet); - return ONEDGE; - } - // On face (tdest, tapex, toppo). - return ONFACE; - } - if (s4 == 0.0) { - enext2fnextself(*searchtet); - // On face (tapex, torg, toppo). - return ONFACE; - } - - // Inside tetrahedron. - return INTETRAHEDRON; -} - -// -// End of point location routines -// - -// -// Begin of mesh transformation routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// categorizeface() Determine the flip type of a given face. // -// // -// On input, 'horiz' represents the face we want to flip (you can imagine it // -// is parallel to the horizon). Let the tetrahedron above it be abcd, where // -// abc is 'horiz'. // -// // -// If abc is a hull face, it is unflipable, and is locally Delaunay. In the // -// following, we assume abc is an interior face, and the other tetrahedron // -// adjoining at abc is bace. // -// // -// If the convex hull CH of the set {a, b, c, d, e} only has four vertices, // -// i.e., one vertex lies inside CH, then abc is unflipable, and is locally // -// Delaunay. If CH is the vertex set itself, we have the following cases to // -// determine whether abc is flipable or not. // -// // -// If no four points of {a, b, c, d, e} are coplanar, a 2-to-3 flip can be // -// applied to abc if the edge de crosses the triangle abc; a 3-to-2 flip can // -// be applied to abc if ab crosses cde, and abde exists, otherwise, face abc // -// is unflipable, i.e., the tetrahedron abde is not present. // -// // -// If four points of {a, b, c, d, e} are coplanar (two faces are coplanar). // -// Assume faces abd and abe are coplanar (it is impossible be abc). If a, b, // -// d, e form a non-convex quadrilateral, then abc is unflipable, furthermore,// -// it is locally Delaunay. Assume they are convex quadrilateral, if abd and // -// abe are hull faces, a 2-to-2 flip can be applied to abc; if abd and abe // -// are interior faces, assume two tetrahedra adjoining abd and abe at the // -// opposite sides are abdg and abef, respectively. If g = f, a 4-to-4 flip // -// can be applied to abc, otherwise, abc is unflipable. // -// // -// There are other cases which can cause abc unflipable. If abc is a subface,// -// a 2-to-3 flip is forbidden; if ab is a subsegment, flips 3-to-2, 2-to-2, // -// and 4-to-4 are forbidden. // -// // -// This routine determines the suitable type of flip operation for 'horiz'. // -// - Returns T23 if a 2-to-3 flip is applicable. 'horiz' is same as input. // -// - Returns T32 if a 3-to-2 flip is applicable. 'horiz' is adjusted so // -// that the primary edge of 'horiz' is the flipable edge. // -// - Returns T22 if a 2-to-2 or 4-to-4 flip is applicable. 'horiz' is // -// adjusted so that the primary edge of 'horiz' is the flipable edge. // -// - Returns FORBIDDENFACE indicates although a 2-to-3 flip is applicable, // -// but it is a subface and should not be flipped away. // -// - Returns FORBIDDENEDGE indicates although a 3-to-2, or 2-to-2, or // -// 4-to-4 flip is applicable, but the flipable edge is a subsegment and // -// should not be flipped away. 'horiz' is adjusted so that the primary // -// edge of 'horiz' is the flipable edge. // -// - Returns UNFLIPABLE indicates it is unflipable due to the absence of // -// a tetrahedron. 'horiz' is adjusted so that the primary edge of 'horiz'// -// is the unflipable edge. Possibly, It is a subsegment. // -// - Returns NONCONVEX indicates it is unflipable and is locally Delaunay. // -// // -// Given a face abc, with two adjoining tetrahedra abcd and bace. If abc is // -// flipable, i.e., T23, T32, T22 or T44, its flip type can be determined by // -// doing five orientation tests: two tests for determining that d, e lie on // -// the different sides of abc, three tests for determining if the edge de // -// intersects the face abc. However, if we use the neighbor information of // -// the mesh data structure, we can reduce the five orientation tests to at // -// most three tests, that is, the two tests for determining whether d and e // -// lie on the different sides of abc can be saved. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::fliptype tetgenmesh::categorizeface(triface& horiz) -{ - triface symhoriz, casing; - face checksh, checkseg; - face cassh1, cassh2; - point pa, pb, pc, pd, pe, pf, pg; - point abdoppo, bcdoppo, cadoppo; - REAL ori1, ori2, ori3; - int adjtet; - - sym(horiz, symhoriz); - if (symhoriz.tet == dummytet) { - // A hull face is unflipable and locally Delaunay. - return NONCONVEX; - } - - adjustedgering(horiz, CCW); - findedge(&symhoriz, dest(horiz), org(horiz)); - pa = org(horiz); - pb = dest(horiz); - pc = apex(horiz); - pd = oppo(horiz); - pe = oppo(symhoriz); - - // Find the number of adjacent tetrahedra of abc, which have d, e, and one - // of corners of abc as their corners. This number can be 0, 1 and 2. - abdoppo = bcdoppo = cadoppo = (point) NULL; - adjtet = 0; - fnext(horiz, casing); // at edge 'ab'. - symself(casing); - if (casing.tet != dummytet) { - abdoppo = oppo(casing); - if (abdoppo == pe) adjtet++; - } - enextfnext(horiz, casing); // at edge 'bc'. - symself(casing); - if (casing.tet != dummytet) { - bcdoppo = oppo(casing); - if (bcdoppo == pe) adjtet++; - } - enext2fnext(horiz, casing); // at edge 'ca'. - symself(casing); - if (casing.tet != dummytet) { - cadoppo = oppo(casing); - if (cadoppo == pe) adjtet++; - } - - if (adjtet == 0) { - // No adjacent tetrahedron. Types T23, T22 and T44 are possible. - ori1 = orient3d(pa, pb, pd, pe); - if (checksubfaces && ori1 != 0.0) { - // Are abd and abe subfaces and belong to the same facet? - fnext(horiz, casing); - tspivot(casing, cassh1); - fnext(symhoriz, casing); - tspivot(casing, cassh2); - if (cassh1.sh != dummysh && cassh2.sh != dummysh) { - // Two adjoining boundary faces. If the common edge of them is not - // a subsegment, they belong to the same facet. - findedge(&cassh1, pa, pb); - sspivot(cassh1, checkseg); - if (checkseg.sh == dummysh) { - // The four points are forced to be coplanar. - ori1 = 0.0; - } - } - if (ori1 != 0.0) { - // Check if abd and bae are approximately coplanar. - if (iscoplanar(pa, pb, pd, pe, ori1, b->epsilon)) ori1 = 0.0; - } - } - if (ori1 < 0.0) { - // e lies above abd, unflipable, tet abde is not present. -#ifdef SELF_CHECK - if (!nonconvex) { - // abd and abe should not be hull faces, check it. - fnext(horiz, casing); - symself(casing); - assert(casing.tet != dummytet); - fnext(symhoriz, casing); - symself(casing); - assert(casing.tet != dummytet); - } -#endif - if (checksubfaces) { - // The nonconvexbility may be casued by existing an subsegment. - tsspivot(&horiz, &checkseg); - if (checkseg.sh != dummysh) { - return FORBIDDENEDGE; - } - } - return UNFLIPABLE; - } - ori2 = orient3d(pb, pc, pd, pe); - if (checksubfaces && ori2 != 0.0) { - // Are bcd and cbe subfaces and belong to the same facet? - enextfnext(horiz, casing); - tspivot(casing, cassh1); - enext2fnext(symhoriz, casing); - tspivot(casing, cassh2); - if (cassh1.sh != dummysh && cassh2.sh != dummysh) { - // Two adjoining boundary faces. If the common edge of them is not - // a subsegment, they belong to the same facet. - findedge(&cassh1, pb, pc); - sspivot(cassh1, checkseg); - if (checkseg.sh == dummysh) { - // The four points are forced to be coplanar. - ori2 = 0.0; - } - } - if (ori2 != 0.0) { - // Check if bcd and cbe are approximately coplanar. - if (iscoplanar(pb, pc, pd, pe, ori2, b->epsilon)) ori2 = 0.0; - } - } - if (ori2 < 0.0) { - // e lies above bcd, unflipable, tet bcde is not present. -#ifdef SELF_CHECK - if (!nonconvex) { - // bcd and cbe should not be hull faces, check it. - enextfnext(horiz, casing); - symself(casing); - assert(casing.tet != dummytet); - enext2fnext(symhoriz, casing); - symself(casing); - assert(casing.tet != dummytet); - } -#endif - enextself(horiz); - if (checksubfaces) { - // The nonconvexbility may be casued by existing an subsegment. - tsspivot(&horiz, &checkseg); - if (checkseg.sh != dummysh) { - return FORBIDDENEDGE; - } - } - return UNFLIPABLE; - } - ori3 = orient3d(pc, pa, pd, pe); - if (checksubfaces && ori3 != 0.0) { - // Are cad and ace subfaces and belong to the same facet? - enext2fnext(horiz, casing); - tspivot(casing, cassh1); - enextfnext(symhoriz, casing); - tspivot(casing, cassh2); - if (cassh1.sh != dummysh && cassh2.sh != dummysh) { - // Two adjoining boundary faces. If the common edge of them is not - // a subsegment, they belong to the same facet. - findedge(&cassh1, pc, pa); - sspivot(cassh1, checkseg); - if (checkseg.sh == dummysh) { - // The four points are forced to be coplanar. - ori3 = 0.0; - } - } - if (ori3 != 0.0) { - // Check if cad and ace are approximately coplanar. - if (iscoplanar(pc, pa, pd, pe, ori3, b->epsilon)) ori3 = 0.0; - } - } - if (ori3 < 0.0) { - // e lies above cad, unflipable, tet cade is not present. -#ifdef SELF_CHECK - if (!nonconvex) { - // cad and ace should not be hull faces, check it. - enext2fnext(horiz, casing); - symself(casing); - assert(casing.tet != dummytet); - enextfnext(symhoriz, casing); - symself(casing); - assert(casing.tet != dummytet); - } -#endif - enext2self(horiz); - if (checksubfaces) { - // The nonconvexbility may be casued by existing an subsegment. - tsspivot(&horiz, &checkseg); - if (checkseg.sh != dummysh) { - return FORBIDDENEDGE; - } - } - return UNFLIPABLE; - } - if (ori1 == 0.0) { - // e is coplanar with abd. - if (ori2 * ori3 == 0.0) { - // only one zero is possible. - // assert(!(ori2 == 0.0 && ori3 == 0.0)); - // Three points (d, e, and a or b) are collinear, abc is unflipable - // and locally Delaunay. - return NONCONVEX; - } - } else if (ori2 == 0.0) { - // e is coplanar with bcd. - if (ori1 * ori3 == 0.0) { - // only one zero is possible. - // assert(!(ori1 == 0.0 && ori3 == 0.0)); - // Three points (d, e, and b or c) are collinear, abc is unflipable - // and locally Delaunay. - return NONCONVEX; - } - // Adjust 'horiz' and 'symhoriz' be the edge bc. - enextself(horiz); - enext2self(symhoriz); - } else if (ori3 == 0.0) { - // e is coplanar with cad. - if (ori1 * ori2 == 0.0) { - // only one zero is possible. - // assert(!(ori1 == 0.0 && ori2 == 0.0)); - // Three points (d, e, and c or a) are collinear, abc is unflipable - // and locally Delaunay. - return NONCONVEX; - } - // Adjust 'horiz' and 'symhoriz' be the edge ca. - enext2self(horiz); - enextself(symhoriz); - } else { - // e lies below all three faces, flipable. - if (checksubfaces) { - tspivot(horiz, checksh); - if (checksh.sh != dummysh) { - // To flip a subface is forbidden. - return FORBIDDENFACE; - } - } - return T23; - } - // Four points are coplanar, T22 or T44 is possible. - if (checksubfaces) { - tsspivot(&horiz, &checkseg); - if (checkseg.sh != dummysh) { - // To flip a subsegment is forbidden. - return FORBIDDENEDGE; - } - tspivot(horiz, checksh); - if (checksh.sh != dummysh) { - // To flip a subface is forbidden. - return FORBIDDENFACE; - } - } - // Assume the four coplanar points are a, b, d, e, abd and abe are two - // coplanar faces. If both abd and abe are hull faces, flipable(T22). - // If they are interior faces, get the opposite tetrahedra abdf and - // abeg, if f = g, flipable (T44). Otherwise, unflipable. - pf = pg = (point) NULL; - fnext(horiz, casing); - symself(casing); - if (casing.tet != dummytet) { - pf = oppo(casing); - } - fnext(symhoriz, casing); - symself(casing); - if (casing.tet != dummytet) { - pg = oppo(casing); - } - if (pf == (point) NULL && pg == (point) NULL) { - // abd and abe are hull faces, flipable. - return T22; - } else if (pf == pg) { - // abd and abe are interior faces, flipable. - return T44; - } else { - // ab has more than four faces around it, unflipable. - return UNFLIPABLE; - } - } else if (adjtet == 1) { - // One of its three edges is locally non-convex. Type T32 is possible. - // Adjust current configuration so that edge ab is non-convex. - if (bcdoppo == pe) { - // Edge bc is non-convex. Adjust 'horiz' and 'symhoriz' be edge bc. - enextself(horiz); - enext2self(symhoriz); - pa = org(horiz); - pb = dest(horiz); - pc = apex(horiz); - } else if (cadoppo == pe) { - // Edge ca is non-convex. Adjust 'horiz' and 'symhoriz' be edge ca. - enext2self(horiz); - enextself(symhoriz); - pa = org(horiz); - pb = dest(horiz); - pc = apex(horiz); - } else { - // Edge ab is non-convex. - assert(abdoppo == pe); - } // Now ab is the non-convex edge. - // In order to be flipable, ab should cross face cde. Check it. - ori1 = orient3d(pc, pd, pe, pa); - if (checksubfaces && ori1 != 0.0) { - // Are cad and ace subfaces and belong to the same facet? - enext2fnext(horiz, casing); - tspivot(casing, cassh1); - enextfnext(symhoriz, casing); - tspivot(casing, cassh2); - if (cassh1.sh != dummysh && cassh2.sh != dummysh) { - // Two adjoining boundary faces. If the common edge of them is not - // a subsegment, they belong to the same facet. - findedge(&cassh1, pc, pa); - sspivot(cassh1, checkseg); - if (checkseg.sh == dummysh) { - // The four points are forced to be coplanar. - ori1 = 0.0; - } - } - } - if (ori1 <= 0.0) { - // a lies above cde, unflipable, and abc is locally Delaunay. - return NONCONVEX; - } - ori2 = orient3d(pd, pc, pe, pb); - if (checksubfaces && ori2 != 0.0) { - // Are bcd and cbe subfaces and belong to the same facet? - enextfnext(horiz, casing); - tspivot(casing, cassh1); - enext2fnext(symhoriz, casing); - tspivot(casing, cassh2); - if (cassh1.sh != dummysh && cassh2.sh != dummysh) { - // Two adjoining boundary faces. If the common edge of them is not - // a subsegment, they belong to the same facet. - findedge(&cassh1, pb, pc); - sspivot(cassh1, checkseg); - if (checkseg.sh == dummysh) { - // The four points are forced to be coplanar. - ori2 = 0.0; - } - } - } - if (ori2 <= 0.0) { - // b lies above dce, unflipable, and abc is locally Delaunay. - return NONCONVEX; - } - // Edge ab crosses face cde properly. - if (checksubfaces) { - // If abc is subface, then ab must be a subsegment (because abde is - // a tetrahedron and ab crosses cde properly). - tsspivot(&horiz, &checkseg); - if (checkseg.sh != dummysh) { - // To flip a subsegment is forbidden. - return FORBIDDENEDGE; - } - // Both abd and bae should not be subfaces (because they're not - // coplanar and ab is not a subsegment). However, they may be - // subfaces and belong to a facet (created during facet recovery), - // that is, abde is an invalid tetrahedron. Find this case out. - fnext(horiz, casing); - tspivot(casing, cassh1); - fnext(symhoriz, casing); - tspivot(casing, cassh2); - if (cassh1.sh != dummysh || cassh2.sh != dummysh) { - // Unfortunately, they're subfaces. Corrections need be done here. - printf("Warning: A tetrahedron spans two subfaces of a facet.\n"); - // Temporarily, let it be there. - return NONCONVEX; - } - } - return T32; - } else { - assert(adjtet == 2); - // The convex hull of {a, b, c, d, e} has only four vertices, abc is - // unflipable, furthermore, it is locally Delaunay. - return NONCONVEX; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// enqueueflipface(), enqueueflipedge() Add a face or an edge to the end // -// of a queue. // -// // -// This face or edge may be non-Delaunay and will be checked. Corresponding // -// flip operation will be applied on it if it is non-Delaunay. The vertices // -// of the face or edge are stored seperatly used to ensure the face or edge // -// is still the same one when we save it. Sometimes, other flipping will // -// cause this face or edge be changed or dead. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::enqueueflipface(triface& checkface, queue* flipqueue) -{ - badface *queface; - - queface = (badface *) flipqueue->push((void *) NULL); - queface->tt = checkface; - queface->forg = org(checkface); - queface->fdest = dest(checkface); - queface->fapex = apex(checkface); -} - -void tetgenmesh::enqueueflipedge(face& checkedge, queue* flipqueue) -{ - badface *queface; - - queface = (badface *) flipqueue->push((void *) NULL); - queface->ss = checkedge; - queface->forg = sorg(checkedge); - queface->fdest = sdest(checkedge); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// flip23() Perform a 2-to-3 flip. // -// // -// On input, 'flipface' represents the face will be flipped. Let it is abc, // -// the two tetrahedra sharing abc are abcd, bace. abc is not a subface. // -// // -// A 2-to-3 flip is to change two tetrahedra abcd, bace to three tetrahedra // -// edab, edbc, and edca. As a result, face abc has been removed and three // -// new faces eda, edb and edc have been created. // -// // -// On completion, 'flipface' returns edab. If 'flipqueue' is not NULL, all // -// possibly non-Delaunay faces are added into it. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::flip23(triface* flipface, queue* flipqueue) -{ - triface abcd, bace; // Old configuration. - triface oldabd, oldbcd, oldcad; - triface abdcasing, bcdcasing, cadcasing; - face abdsh, bcdsh, cadsh; - triface oldbae, oldcbe, oldace; - triface baecasing, cbecasing, acecasing; - face baesh, cbesh, acesh; - triface edab, edbc, edca; // New configuration. - point pa, pb, pc, pd, pe; - REAL attrib, volume; - int i; - - abcd = *flipface; - adjustedgering(abcd, CCW); // abcd represents edge ab. - sym(abcd, bace); - findedge(&bace, dest(abcd), org(abcd)); // bace represents edge ba. - pa = org(abcd); - pb = dest(abcd); - pc = apex(abcd); - pd = oppo(abcd); - pe = oppo(bace); - - if (b->verbose > 2) { - printf(" Do T23 on face (%d, %d, %d, %d).\n", pointmark(pa), - pointmark(pb), pointmark(pc), pointmark(pd)); - } - flip23s++; - -#ifdef SELF_CHECK - // Edge de must cross face abc properly. - assert(orient3d(pa, pb, pd, pe) >= 0.0); - assert(orient3d(pb, pc, pd, pe) >= 0.0); - assert(orient3d(pc, pa, pd, pe) >= 0.0); -#endif - - // Storing the old configuration outside the convex hull. - fnext(abcd, oldabd); - enextfnext(abcd, oldbcd); - enext2fnext(abcd, oldcad); - fnext(bace, oldbae); - enext2fnext(bace, oldcbe); - enextfnext(bace, oldace); - sym(oldabd, abdcasing); - sym(oldbcd, bcdcasing); - sym(oldcad, cadcasing); - sym(oldbae, baecasing); - sym(oldcbe, cbecasing); - sym(oldace, acecasing); - if (checksubfaces) { - tspivot(oldabd, abdsh); - tspivot(oldbcd, bcdsh); - tspivot(oldcad, cadsh); - tspivot(oldbae, baesh); - tspivot(oldcbe, cbesh); - tspivot(oldace, acesh); - } - - // Creating the new configuration inside the convex hull. - edab.tet = abcd.tet; // Update abcd to be edab. - setorg (edab, pe); - setdest(edab, pd); - setapex(edab, pa); - setoppo(edab, pb); - edbc.tet = bace.tet; // Update bace to be edbc. - setorg (edbc, pe); - setdest(edbc, pd); - setapex(edbc, pb); - setoppo(edbc, pc); - maketetrahedron(&edca); // Create edca. - setorg (edca, pe); - setdest(edca, pd); - setapex(edca, pc); - setoppo(edca, pa); - // Set the element attributes of the new tetrahedron 'edca'. - for (i = 0; i < in->numberoftetrahedronattributes; i++) { - attrib = elemattribute(abcd.tet, i); - setelemattribute(edca.tet, i, attrib); - } - // Set the volume constraint of the new tetrahedron 'edca' if the -ra - // switches are not used together. In -ra case, the various volume - // constraints can be spreaded very far. - if (b->varvolume && !b->refine) { - volume = volumebound(abcd.tet); - setvolumebound(edca.tet, volume); - } - - // Clear old bonds in edab(was abcd) and edbc(was bace). - for (i = 0; i < 4; i ++) { - edab.loc = i; - dissolve(edab); - edbc.loc = i; - dissolve(edbc); - } - // Bond the faces inside the convex hull. - edab.loc = 0; - edca.loc = 1; - bond(edab, edca); - edab.loc = 1; - edbc.loc = 0; - bond(edab, edbc); - edbc.loc = 1; - edca.loc = 0; - bond(edbc, edca); - // Bond the faces on the convex hull. - edab.loc = 2; - bond(edab, abdcasing); - edab.loc = 3; - bond(edab, baecasing); - edbc.loc = 2; - bond(edbc, bcdcasing); - edbc.loc = 3; - bond(edbc, cbecasing); - edca.loc = 2; - bond(edca, cadcasing); - edca.loc = 3; - bond(edca, acecasing); - // There may exist subfaces that need to be bonded to new configuarton. - if (checksubfaces) { - // Clear old flags in edab(was abcd) and edbc(was bace). - for (i = 0; i < 4; i ++) { - edab.loc = i; - tsdissolve(edab); - edbc.loc = i; - tsdissolve(edbc); - } - if (abdsh.sh != dummysh) { - edab.loc = 2; - tsbond(edab, abdsh); - } - if (baesh.sh != dummysh) { - edab.loc = 3; - tsbond(edab, baesh); - } - if (bcdsh.sh != dummysh) { - edbc.loc = 2; - tsbond(edbc, bcdsh); - } - if (cbesh.sh != dummysh) { - edbc.loc = 3; - tsbond(edbc, cbesh); - } - if (cadsh.sh != dummysh) { - edca.loc = 2; - tsbond(edca, cadsh); - } - if (acesh.sh != dummysh) { - edca.loc = 3; - tsbond(edca, acesh); - } - } - - edab.loc = 0; - edbc.loc = 0; - edca.loc = 0; - if (b->verbose > 3) { - printf(" Updating edab "); - printtet(&edab); - printf(" Updating edbc "); - printtet(&edbc); - printf(" Creating edca "); - printtet(&edca); - } - - if (flipqueue != (queue *) NULL) { - enextfnext(edab, abdcasing); - enqueueflipface(abdcasing, flipqueue); - enext2fnext(edab, baecasing); - enqueueflipface(baecasing, flipqueue); - enextfnext(edbc, bcdcasing); - enqueueflipface(bcdcasing, flipqueue); - enext2fnext(edbc, cbecasing); - enqueueflipface(cbecasing, flipqueue); - enextfnext(edca, cadcasing); - enqueueflipface(cadcasing, flipqueue); - enext2fnext(edca, acecasing); - enqueueflipface(acecasing, flipqueue); - } - - // Save a live handle in 'recenttet'. - recenttet = edbc; - // Set the return handle be edab. - *flipface = edab; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// flip32() Perform a 3-to-2 flip. // -// // -// On input, 'flipface' represents the face will be flipped. Let it is eda, // -// where edge ed is locally non-convex. Three tetrahedra sharing ed are edab,// -// edbc, and edca. ed is not a subsegment. // -// // -// A 3-to-2 flip is to change the three tetrahedra edab, edbc, and edca into // -// another two tetrahedra abcd and bace. As a result, the edge ed has been // -// removed and the face abc has been created. // -// // -// On completion, 'flipface' returns abcd. If 'flipqueue' is not NULL, all // -// possibly non-Delaunay faces are added into it. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::flip32(triface* flipface, queue* flipqueue) -{ - triface edab, edbc, edca; // Old configuration. - triface oldabd, oldbcd, oldcad; - triface abdcasing, bcdcasing, cadcasing; - face abdsh, bcdsh, cadsh; - triface oldbae, oldcbe, oldace; - triface baecasing, cbecasing, acecasing; - face baesh, cbesh, acesh; - triface abcd, bace; // New configuration. - point pa, pb, pc, pd, pe; - int i; - - edab = *flipface; - adjustedgering(edab, CCW); - fnext(edab, edbc); - symself(edbc); - findedge(&edbc, org(edab), dest(edab)); - fnext(edbc, edca); - symself(edca); - findedge(&edca, org(edab), dest(edab)); - pa = apex(edab); - pb = oppo(edab); - pc = oppo(edbc); - pd = dest(edab); - pe = org(edab); - - if (b->verbose > 2) { - printf(" Do T32 on face (%d, %d, %d, %d).\n", - pointmark(pe), pointmark(pd), pointmark(pa), pointmark(pb)); - } - flip32s++; - -#ifdef SELF_CHECK - // Edge de must cross face abc properly. - assert(orient3d(pa, pb, pc, pd) <= 0.0); - assert(orient3d(pb, pa, pc, pe) <= 0.0); -#endif - - // Storing the old configuration outside the convex hull. - enextfnext(edab, oldabd); - enext2fnext(edab, oldbae); - enextfnext(edbc, oldbcd); - enext2fnext(edbc, oldcbe); - enextfnext(edca, oldcad); - enext2fnext(edca, oldace); - sym(oldabd, abdcasing); - sym(oldbcd, bcdcasing); - sym(oldcad, cadcasing); - sym(oldbae, baecasing); - sym(oldcbe, cbecasing); - sym(oldace, acecasing); - if (checksubfaces) { - tspivot(oldabd, abdsh); - tspivot(oldbcd, bcdsh); - tspivot(oldcad, cadsh); - tspivot(oldbae, baesh); - tspivot(oldcbe, cbesh); - tspivot(oldace, acesh); - } - - // Creating the new configuration inside the convex hull. - abcd.tet = edab.tet; // Update edab to be abcd. - setorg (abcd, pa); - setdest(abcd, pb); - setapex(abcd, pc); - setoppo(abcd, pd); - bace.tet = edbc.tet; // Update edbc to be bace. - setorg (bace, pb); - setdest(bace, pa); - setapex(bace, pc); - setoppo(bace, pe); - // Dealloc a redundant tetrahedron (edca). - tetrahedrondealloc(edca.tet); - - // Clear the old bonds in abcd (was edab) and bace (was edbc). - for (i = 0; i < 4; i ++) { - abcd.loc = i; - dissolve(abcd); - bace.loc = i; - dissolve(bace); - } - // Bond the inside face of the convex hull. - abcd.loc = 0; - bace.loc = 0; - bond(abcd, bace); - // Bond the outside faces of the convex hull. - abcd.loc = 1; - bond(abcd, abdcasing); - abcd.loc = 2; - bond(abcd, bcdcasing); - abcd.loc = 3; - bond(abcd, cadcasing); - bace.loc = 1; - bond(bace, baecasing); - bace.loc = 3; - bond(bace, cbecasing); - bace.loc = 2; - bond(bace, acecasing); - if (checksubfaces) { - // Clear old bonds in abcd(was edab) and bace(was edbc). - for (i = 0; i < 4; i ++) { - abcd.loc = i; - tsdissolve(abcd); - bace.loc = i; - tsdissolve(bace); - } - if (abdsh.sh != dummysh) { - abcd.loc = 1; - tsbond(abcd, abdsh); - } - if (baesh.sh != dummysh) { - bace.loc = 1; - tsbond(bace, baesh); - } - if (bcdsh.sh != dummysh) { - abcd.loc = 2; - tsbond(abcd, bcdsh); - } - if (cbesh.sh != dummysh) { - bace.loc = 3; - tsbond(bace, cbesh); - } - if (cadsh.sh != dummysh) { - abcd.loc = 3; - tsbond(abcd, cadsh); - } - if (acesh.sh != dummysh) { - bace.loc = 2; - tsbond(bace, acesh); - } - } - - abcd.loc = 0; - bace.loc = 0; - if (b->verbose > 3) { - printf(" Updating abcd "); - printtet(&abcd); - printf(" Updating bace "); - printtet(&bace); - printf(" Deleting edca "); - printtet(&edca); - } - - if (flipqueue != (queue *) NULL) { - fnext(abcd, abdcasing); - enqueueflipface(abdcasing, flipqueue); - fnext(bace, baecasing); - enqueueflipface(baecasing, flipqueue); - enextfnext(abcd, bcdcasing); - enqueueflipface(bcdcasing, flipqueue); - enextfnext(bace, cbecasing); - enqueueflipface(cbecasing, flipqueue); - enext2fnext(abcd, cadcasing); - enqueueflipface(cadcasing, flipqueue); - enext2fnext(bace, acecasing); - enqueueflipface(acecasing, flipqueue); - } - - // Save a live handle in 'recenttet'. - recenttet = abcd; - // Set the return handle be abcd. - *flipface = abcd; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// flip22() Perform a 2-to-2 (or 4-to-4) flip. // -// // -// On input, 'flipface' represents the face will be flipped. Let it is abe, // -// ab is the flipable edge, the two tetrahedra sharing abe are abce and bade,// -// hence a, b, c and d are coplanar. If abc, bad are interior faces, the two // -// tetrahedra opposite to e are bacf and abdf. ab is not a subsegment. // -// // -// A 2-to-2 flip is to change two tetrahedra abce and bade into another two // -// tetrahedra dcae and cdbe. If bacf and abdf exist, they're changed to cdaf // -// and dcbf, thus a 4-to-4 flip. As a result, two or four tetrahedra have // -// rotated counterclockwise (using right-hand rule with thumb points to e): // -// abce->dcae, bade->cdbe, and bacf->cdaf, abdf->dcbf. // -// // -// If abc and bad are subfaces, a 2-to-2 flip is performed simultaneously by // -// calling routine flip22sub(), hence abc->dca, bad->cdb. The edge rings of // -// the flipped subfaces dca and cdb have the same orientation as abc and bad.// -// Hence, they have the same orientation as other subfaces of the facet with // -// respect to the lift point of this facet. // -// // -// On completion, 'flipface' holds edge dc of tetrahedron dcae. 'flipqueue' // -// contains all possibly non-Delaunay faces if it is not NULL. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::flip22(triface* flipface, queue* flipqueue) -{ - triface abce, bade; - triface oldbce, oldcae, oldade, olddbe; - triface bcecasing, caecasing, adecasing, dbecasing; - face bcesh, caesh, adesh, dbesh; - triface bacf, abdf; - triface oldacf, oldcbf, oldbdf, olddaf; - triface acfcasing, cbfcasing, bdfcasing, dafcasing; - face acfsh, cbfsh, bdfsh, dafsh; - face abc, bad; - point pa, pb, pc, pd, pe, pf; - int mirrorflag; - - adjustedgering(*flipface, CCW); // 'flipface' is bae. - fnext(*flipface, abce); - esymself(abce); - adjustedgering(*flipface, CW); // 'flipface' is abe. - fnext(*flipface, bade); - assert(bade.tet != dummytet); - esymself(bade); - pa = org(abce); - pb = dest(abce); - pc = apex(abce); - pd = apex(bade); - pe = oppo(bade); - assert(oppo(abce) == pe); - sym(abce, bacf); - mirrorflag = bacf.tet != dummytet; - if (mirrorflag) { - findedge(&bacf, pb, pa); - sym(bade, abdf); - assert(abdf.tet != dummytet); - findedge(&abdf, pa, pb); - pf = oppo(bacf); - assert(oppo(abdf) == pf); - } - - if (b->verbose > 2) { - printf(" Do %s on edge (%d, %d).\n", mirrorflag ? "T44" : "T22", - pointmark(pa), pointmark(pb)); - } - mirrorflag ? flip44s++ : flip22s++; - -#ifdef SELF_CHECK - // The quadrilateral formed by a, b, c, and d must be convex. - assert(orient3d(pc, pd, pe, pa) <= 0.0); - assert(orient3d(pd, pc, pe, pb) <= 0.0); -#endif - - // Save the old configuration at the convex hull. - enextfnext(abce, oldbce); - enext2fnext(abce, oldcae); - enextfnext(bade, oldade); - enext2fnext(bade, olddbe); - sym(oldbce, bcecasing); - sym(oldcae, caecasing); - sym(oldade, adecasing); - sym(olddbe, dbecasing); - if (checksubfaces) { - tspivot(oldbce, bcesh); - tspivot(oldcae, caesh); - tspivot(oldade, adesh); - tspivot(olddbe, dbesh); - tspivot(abce, abc); - tspivot(bade, bad); - } - if (mirrorflag) { - enextfnext(bacf, oldacf); - enext2fnext(bacf, oldcbf); - enextfnext(abdf, oldbdf); - enext2fnext(abdf, olddaf); - sym(oldacf, acfcasing); - sym(oldcbf, cbfcasing); - sym(oldbdf, bdfcasing); - sym(olddaf, dafcasing); - if (checksubfaces) { - tspivot(oldacf, acfsh); - tspivot(oldcbf, cbfsh); - tspivot(oldbdf, bdfsh); - tspivot(olddaf, dafsh); - } - } - - // Rotate abce, bade one-quarter turn counterclockwise. - bond(oldbce, caecasing); - bond(oldcae, adecasing); - bond(oldade, dbecasing); - bond(olddbe, bcecasing); - if (checksubfaces) { - // Check for subfaces and rebond them to the rotated tets. - if (caesh.sh == dummysh) { - tsdissolve(oldbce); - } else { - tsbond(oldbce, caesh); - } - if (adesh.sh == dummysh) { - tsdissolve(oldcae); - } else { - tsbond(oldcae, adesh); - } - if (dbesh.sh == dummysh) { - tsdissolve(oldade); - } else { - tsbond(oldade, dbesh); - } - if (bcesh.sh == dummysh) { - tsdissolve(olddbe); - } else { - tsbond(olddbe, bcesh); - } - } - if (mirrorflag) { - // Rotate bacf, abdf one-quarter turn counterclockwise. - bond(oldcbf, acfcasing); - bond(oldacf, dafcasing); - bond(olddaf, bdfcasing); - bond(oldbdf, cbfcasing); - if (checksubfaces) { - // Check for subfaces and rebond them to the rotated tets. - if (acfsh.sh == dummysh) { - tsdissolve(oldcbf); - } else { - tsbond(oldcbf, acfsh); - } - if (dafsh.sh == dummysh) { - tsdissolve(oldacf); - } else { - tsbond(oldacf, dafsh); - } - if (bdfsh.sh == dummysh) { - tsdissolve(olddaf); - } else { - tsbond(olddaf, bdfsh); - } - if (cbfsh.sh == dummysh) { - tsdissolve(oldbdf); - } else { - tsbond(oldbdf, cbfsh); - } - } - } - - // New vertex assignments for the rotated tetrahedra. - setorg(abce, pd); // Update abce to dcae - setdest(abce, pc); - setapex(abce, pa); - setorg(bade, pc); // Update bade to cdbe - setdest(bade, pd); - setapex(bade, pb); - if (mirrorflag) { - setorg(bacf, pc); // Update bacf to cdaf - setdest(bacf, pd); - setapex(bacf, pa); - setorg(abdf, pd); // Update abdf to dcbf - setdest(abdf, pc); - setapex(abdf, pb); - } - - // Are there subfaces need to be flipped? - if (checksubfaces && abc.sh != dummysh) { - assert(bad.sh != dummysh); - // Adjust the edge be ab, so the rotation of subfaces is according with - // the rotation of tetrahedra. - findedge(&abc, pa, pb); - // Flip an edge of two subfaces, ignore non-Delaunay edges. - flip22sub(&abc, NULL); - } - - if (b->verbose > 3) { - printf(" Updating abce "); - printtet(&abce); - printf(" Updating bade "); - printtet(&bade); - if (mirrorflag) { - printf(" Updating bacf "); - printtet(&bacf); - printf(" Updating abdf "); - printtet(&abdf); - } - } - - if (flipqueue != (queue *) NULL) { - enextfnext(abce, bcecasing); - enqueueflipface(bcecasing, flipqueue); - enext2fnext(abce, caecasing); - enqueueflipface(caecasing, flipqueue); - enextfnext(bade, adecasing); - enqueueflipface(adecasing, flipqueue); - enext2fnext(bade, dbecasing); - enqueueflipface(dbecasing, flipqueue); - if (mirrorflag) { - enextfnext(bacf, acfcasing); - enqueueflipface(acfcasing, flipqueue); - enext2fnext(bacf, cbfcasing); - enqueueflipface(cbfcasing, flipqueue); - enextfnext(abdf, bdfcasing); - enqueueflipface(bdfcasing, flipqueue); - enext2fnext(abdf, dafcasing); - enqueueflipface(dafcasing, flipqueue); - } - // The two new faces dcae (abce), cdbe (bade) may still not be locally - // Delaunay, and may need be flipped (flip23). On the other hand, in - // conforming Delaunay algorithm, two new subfaces dca (abc), and cdb - // (bad) may be non-conforming Delaunay, they need be queued if they - // are locally Delaunay but non-conforming Delaunay. - enqueueflipface(abce, flipqueue); - enqueueflipface(bade, flipqueue); - } - - // Save a live handle in 'recenttet'. - recenttet = abce; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// flip22sub() Perform a 2-to-2 flip on a subface edge. // -// // -// The flip edge is given by subface 'flipedge'. Let it is abc, where ab is // -// the flipping edge. The other subface is bad, where a, b, c, d form a // -// convex quadrilateral. ab is not a subsegment. // -// // -// A 2-to-2 subface flip is to change two subfaces abc and bad to another // -// two subfaces dca and cdb. Hence, edge ab has been removed and dc becomes // -// an edge. If a point e is above abc, this flip is equal to rotate abc and // -// bad counterclockwise using right-hand rule with thumb points to e. It is // -// important to know that the edge rings of the flipped subfaces dca and cdb // -// are keeping the same orientation as their original subfaces. So they have // -// the same orientation with respect to the lift point of this facet. // -// // -// During rotating, the face rings of the four edges bc, ca, ad, and de need // -// be re-connected. If the edge is not a subsegment, then its face ring has // -// only two faces, a sbond() will bond them together. If it is a subsegment, // -// one should use sbond1() twice to bond two different handles to the rotat- // -// ing subface, one is predecssor (-casin), another is successor (-casout). // -// // -// If 'flipqueue' is not NULL, it returns four edges bc, ca, ad, de, which // -// may be non-Delaunay. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::flip22sub(face* flipedge, queue* flipqueue) -{ - face abc, bad; - face oldbc, oldca, oldad, olddb; - face bccasin, bccasout, cacasin, cacasout; - face adcasin, adcasout, dbcasin, dbcasout; - face bc, ca, ad, db; - face spinsh; - point pa, pb, pc, pd; - - abc = *flipedge; - spivot(abc, bad); - if (sorg(bad) != sdest(abc)) { - sesymself(bad); - } - pa = sorg(abc); - pb = sdest(abc); - pc = sapex(abc); - pd = sapex(bad); - - if (b->verbose > 2) { - printf(" Flip sub edge (%d, %d).\n", pointmark(pa), pointmark(pb)); - } - - // Save the old configuration outside the quadrilateral. - senext(abc, oldbc); - senext2(abc, oldca); - senext(bad, oldad); - senext2(bad, olddb); - // Get the outside connection. Becareful if there is a subsegment on the - // quadrilateral, two casings (casin and casout) are needed to save for - // keeping the face link. - spivot(oldbc, bccasout); - sspivot(oldbc, bc); - if (bc.sh != dummysh) { - // 'bc' is a subsegment. - assert(bccasout.sh != dummysh); - if (oldbc.sh != bccasout.sh) { - // 'oldbc' is not self-bonded. - spinsh = bccasout; - do { - bccasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != oldbc.sh); - } else { - bccasout.sh = dummysh; - } - ssdissolve(oldbc); - } - spivot(oldca, cacasout); - sspivot(oldca, ca); - if (ca.sh != dummysh) { - // 'ca' is a subsegment. - assert(cacasout.sh != dummysh); - if (oldca.sh != cacasout.sh) { - // 'oldca' is not self-bonded. - spinsh = cacasout; - do { - cacasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != oldca.sh); - } else { - cacasout.sh = dummysh; - } - ssdissolve(oldca); - } - spivot(oldad, adcasout); - sspivot(oldad, ad); - if (ad.sh != dummysh) { - // 'ad' is a subsegment. - assert(adcasout.sh != dummysh); - if (oldad.sh != adcasout.sh) { - // 'adcasout' is not self-bonded. - spinsh = adcasout; - do { - adcasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != oldad.sh); - } else { - adcasout.sh = dummysh; - } - ssdissolve(oldad); - } - spivot(olddb, dbcasout); - sspivot(olddb, db); - if (db.sh != dummysh) { - // 'db' is a subsegment. - assert(dbcasout.sh != dummysh); - if (olddb.sh != dbcasout.sh) { - // 'dbcasout' is not self-bonded. - spinsh = dbcasout; - do { - dbcasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != olddb.sh); - } else { - dbcasout.sh = dummysh; - } - ssdissolve(olddb); - } - - // Rotate abc and bad one-quarter turn counterclockwise. - if (ca.sh != dummysh) { - if (cacasout.sh != dummysh) { - sbond1(cacasin, oldbc); - sbond1(oldbc, cacasout); - } else { - // Bond 'oldbc' to itself. - sbond(oldbc, oldbc); - // Make sure that dummysh always correctly bonded. - dummysh[0] = sencode(oldbc); - } - ssbond(oldbc, ca); - } else { - sbond(oldbc, cacasout); - } - if (ad.sh != dummysh) { - if (adcasout.sh != dummysh) { - sbond1(adcasin, oldca); - sbond1(oldca, adcasout); - } else { - // Bond 'oldca' to itself. - sbond(oldca, oldca); - // Make sure that dummysh always correctly bonded. - dummysh[0] = sencode(oldca); - } - ssbond(oldca, ad); - } else { - sbond(oldca, adcasout); - } - if (db.sh != dummysh) { - if (dbcasout.sh != dummysh) { - sbond1(dbcasin, oldad); - sbond1(oldad, dbcasout); - } else { - // Bond 'oldad' to itself. - sbond(oldad, oldad); - // Make sure that dummysh always correctly bonded. - dummysh[0] = sencode(oldad); - } - ssbond(oldad, db); - } else { - sbond(oldad, dbcasout); - } - if (bc.sh != dummysh) { - if (bccasout.sh != dummysh) { - sbond1(bccasin, olddb); - sbond1(olddb, bccasout); - } else { - // Bond 'olddb' to itself. - sbond(olddb, olddb); - // Make sure that dummysh always correctly bonded. - dummysh[0] = sencode(olddb); - } - ssbond(olddb, bc); - } else { - sbond(olddb, bccasout); - } - - // New vertex assignments for the rotated subfaces. - setsorg(abc, pd); // Update abc to dca. - setsdest(abc, pc); - setsapex(abc, pa); - setsorg(bad, pc); // Update bad to cdb. - setsdest(bad, pd); - setsapex(bad, pb); - - if (flipqueue != (queue *) NULL) { - enqueueflipedge(bccasout, flipqueue); - enqueueflipedge(cacasout, flipqueue); - enqueueflipedge(adcasout, flipqueue); - enqueueflipedge(dbcasout, flipqueue); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// flip() Flips non-locally Delaunay faces in flipqueue until it is empty.// -// // -// Assumpation: Current tetrahedralization is non-Delaunay after inserting // -// a point or performing a flip operation, all possibly non-Delaunay faces // -// are in 'flipqueue'. // -// // -// If 'plastflip' is not NULL, it is used to return a stack of recently // -// flipped faces. This stack will be used to reverse the flips done in this // -// routine later for removing a newly inserted point because it encroaches // -// any subfaces or subsegments. // -// // -// If the quality mesh step is starting, (indicated by pools 'badsubsegs', // -// 'badsubfaces' and 'badtetrahedrons' are not NULLs.) we will check the // -// encroached subface or subsegments of a hull face, and queuing tetrahedra // -// for quality checking. // -// // -// The return value is the total number of flips done during this invocation.// -// // -/////////////////////////////////////////////////////////////////////////////// - -long tetgenmesh::flip(queue* flipqueue, flipstacker **plastflip) -{ - badface *qface; - flipstacker *newflip; - triface flipface, symface; - face checkseg, checksh; - enum fliptype fc; - bool flipped; - REAL sign, bakepsilon; - long flipcount; - int epscount; - int i; - - if (b->verbose > 1) { - printf(" Do flipface queue: %ld faces.\n", flipqueue->len()); - } - - flipcount = flip23s + flip32s + flip22s + flip44s; - - if (plastflip != (flipstacker **) NULL) { - // Initialize the stack of the flip sequence. - flipstackers->restart(); - *plastflip = (flipstacker *) NULL; - } - - // Loop until the queue is empty. - while ((qface = (badface *) flipqueue->pop()) != NULL) { - // Get a face. - flipface = qface->tt; - // Check the validity of this face. - if (isdead(&flipface) || flipface.tet == dummytet || - (org(flipface) != qface->forg) || - (dest(flipface) != qface->fdest) || - (apex(flipface) != qface->fapex) || - (oppo(flipface) == (point) NULL)) continue; - flipped = false; - sym(flipface, symface); - // Only do check when the adjacent tet exists and it's not a "fake" tet. - if (symface.tet != dummytet && oppo(symface) != (point) NULL) { - // For positive orientation that insphere() test requires. - adjustedgering(flipface, CW); - sign = insphere(org(flipface), dest(flipface), apex(flipface), - oppo(flipface), oppo(symface)); - } else { - sign = -1.0; // A hull face is locally Delaunay. - } - if (sign > 0.0) { - // 'flipface' is non-locally Delaunay, try to flip it. - if (checksubfaces) { - bakepsilon = b->epsilon; - epscount = 0; - while (epscount < 16) { - fc = categorizeface(flipface); - if (fc == NONCONVEX) { - b->epsilon *= 1e-2; - epscount++; - continue; - } - break; - } - b->epsilon = bakepsilon; - // assert(epscount < 16); - if (epscount == 16) { - if (b->verbose) { - printf("Warning: Can't flip a degenerate tetrahedron.\n"); - } - fc = NONCONVEX; - } - } else { - fc = categorizeface(flipface); - assert(fc != NONCONVEX); - } - switch (fc) { - // The following face types are flipable. - case T44: - case T22: - flip22(&flipface, flipqueue); - flipped = true; - break; - case T23: - flip23(&flipface, flipqueue); - flipped = true; - break; - case T32: - flip32(&flipface, flipqueue); - flipped = true; - break; - // The following face types are unflipable. - case UNFLIPABLE: - break; - case FORBIDDENFACE: - // Meet an encroaching subface, unflipable. - break; - case FORBIDDENEDGE: - // Meet an encroaching subsegment, unflipable. - break; - // This case is only possible when the domain is nonconvex. - case NONCONVEX: - assert(nonconvex); - break; - } - if (plastflip != (flipstacker **) NULL && flipped) { - // Push the flipped face into stack. - newflip = (flipstacker *) flipstackers->alloc(); - newflip->flippedface = flipface; - newflip->fc = fc; - newflip->forg = org(flipface); - newflip->fdest = dest(flipface); - newflip->fapex = apex(flipface); - newflip->prevflip = *plastflip; - *plastflip = newflip; - } - } - if (!flipped) { - // 'flipface' is locally Delaunay, or it is non-locally Delaunay but - // not flipable because it is a subface or contains a subsegment. - if (badsubsegs != (memorypool *) NULL) { - // Check for encroaching subsegments, add them into list. - for (i = 0; i < 3; i++) { - tsspivot(&flipface, &checkseg); - if ((checkseg.sh != dummysh) && !shell2badface(checkseg)) { - checkseg4encroach(&checkseg, NULL, true); - } - enextself(flipface); - } - } - if (badsubfaces != (memorypool *) NULL) { - // Check for encroaching subface, add it into list. - tspivot(flipface, checksh); - if ((checksh.sh != dummysh) && !shell2badface(checksh)) { - checksub4encroach(&checksh, NULL, true); - } - } - if (badtetrahedrons != (memorypool *) NULL) { - // Put the tetrahedra at both sides into list for quality check. - qualchecktetlist->append(&flipface); - if (symface.tet != dummytet) { - qualchecktetlist->append(&symface); - } - } - } - } - - flipcount = flip23s + flip32s + flip22s + flip44s - flipcount; - if (b->verbose > 1) { - printf(" %ld flips.\n", flipcount); - } - - return flipcount; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// undoflip() Undo the most recent flip sequence induced by flip(). // -// // -// 'lastflip' is the stack of recently flipped faces. Walks through the list // -// of flips, in the reverse of the order in which they were done, and undoes // -// them. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::undoflip(flipstacker *lastflip) -{ - while (lastflip != (flipstacker *) NULL) { - // Get the right flipped face. - findface(&lastflip->flippedface, lastflip->forg, lastflip->fdest, - lastflip->fapex); - switch (lastflip->fc) { - case T23: - // The reverse operation of T23 is T32. - flip32(&lastflip->flippedface, NULL); - break; - case T32: - // The reverse operation of T32 is T23. - flip23(&lastflip->flippedface, NULL); - break; - case T22: - case T44: - // The reverse operation of T22 or T44 is again T22 or T44. - flip22(&lastflip->flippedface, NULL); - break; - } - // Go on and process the next transformation. - lastflip = lastflip->prevflip; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// splittetrahedron() Insert a point into a tetrahedron, split it into // -// four tetrahedra. // -// // -// The tetrahedron is given by 'splittet'. Let it is abcd. The inserting // -// point 'newpoint' v should lie strictly inside abcd. // -// // -// Splitting a tetrahedron is to shrink abcd to abcv, and create three new // -// tetrahedra badv, cbdv, and acdv. // -// // -// On completion, 'splittet' returns abcv. If 'flipqueue' is not NULL, it // -// contains all possibly non-locally Delaunay faces. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -splittetrahedron(point newpoint, triface* splittet, queue* flipqueue) -{ - triface oldabd, oldbcd, oldcad; // Old configuration. - triface abdcasing, bcdcasing, cadcasing; - face abdsh, bcdsh, cadsh; - triface abcv, badv, cbdv, acdv; // New configuration. - point pa, pb, pc, pd; - REAL attrib, volume; - int i; - - abcv = *splittet; - abcv.ver = 0; - // Set the changed vertices and new tetrahedron. - pa = org(abcv); - pb = dest(abcv); - pc = apex(abcv); - pd = oppo(abcv); - - if (b->verbose > 1) { - printf(" Inserting point %d in tetrahedron (%d, %d, %d, %d).\n", - pointmark(newpoint), pointmark(pa), pointmark(pb), pointmark(pc), - pointmark(pd)); - } - - fnext(abcv, oldabd); - enextfnext(abcv, oldbcd); - enext2fnext(abcv, oldcad); - sym(oldabd, abdcasing); - sym(oldbcd, bcdcasing); - sym(oldcad, cadcasing); - maketetrahedron(&badv); - maketetrahedron(&cbdv); - maketetrahedron(&acdv); - - // Set 'badv' vertices. - setorg (badv, pb); - setdest(badv, pa); - setapex(badv, pd); - setoppo(badv, newpoint); - // Set 'cbdv' vertices. - setorg (cbdv, pc); - setdest(cbdv, pb); - setapex(cbdv, pd); - setoppo(cbdv, newpoint); - // Set 'acdv' vertices. - setorg (acdv, pa); - setdest(acdv, pc); - setapex(acdv, pd); - setoppo(acdv, newpoint); - // Set 'abcv' vertices - setoppo(abcv, newpoint); - - // Set the element attributes of the new tetrahedra. - for (i = 0; i < in->numberoftetrahedronattributes; i++) { - attrib = elemattribute(abcv.tet, i); - setelemattribute(badv.tet, i, attrib); - setelemattribute(cbdv.tet, i, attrib); - setelemattribute(acdv.tet, i, attrib); - } - // Set the volume constraint of the new tetrahedra. - if (b->varvolume) { - volume = volumebound(abcv.tet); - setvolumebound(badv.tet, volume); - setvolumebound(cbdv.tet, volume); - setvolumebound(acdv.tet, volume); - } - - // Bond the new triangles to the surrounding tetrahedron. - bond(badv, abdcasing); - bond(cbdv, bcdcasing); - bond(acdv, cadcasing); - // There may exist subfaces need to be bonded to the new tetrahedra. - if (checksubfaces) { - tspivot(oldabd, abdsh); - if (abdsh.sh != dummysh) { - tsdissolve(oldabd); - tsbond(badv, abdsh); - } - tspivot(oldbcd, bcdsh); - if (bcdsh.sh != dummysh) { - tsdissolve(oldbcd); - tsbond(cbdv, bcdsh); - } - tspivot(oldcad, cadsh); - if (cadsh.sh != dummysh) { - tsdissolve(oldcad); - tsbond(acdv, cadsh); - } - } - badv.loc = 3; - cbdv.loc = 2; - bond(badv, cbdv); - cbdv.loc = 3; - acdv.loc = 2; - bond(cbdv, acdv); - acdv.loc = 3; - badv.loc = 2; - bond(acdv, badv); - badv.loc = 1; - bond(badv, oldabd); - cbdv.loc = 1; - bond(cbdv, oldbcd); - acdv.loc = 1; - bond(acdv, oldcad); - - badv.loc = 0; - cbdv.loc = 0; - acdv.loc = 0; - if (b->verbose > 3) { - printf(" Updating abcv "); - printtet(&abcv); - printf(" Creating badv "); - printtet(&badv); - printf(" Creating cbdv "); - printtet(&cbdv); - printf(" Creating acdv "); - printtet(&acdv); - } - - if (flipqueue != (queue *) NULL) { - enqueueflipface(abcv, flipqueue); - enqueueflipface(badv, flipqueue); - enqueueflipface(cbdv, flipqueue); - enqueueflipface(acdv, flipqueue); - } - - // Save a handle for quick point location. - recenttet = abcv; - // Set the return handle be abcv. - *splittet = abcv; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// unsplittetrahedron() Reverse the operation of inserting a point into a // -// tetrahedron, so as to remove the newly inserted // -// point from the mesh. // -// // -// Assume the origional tetrahedron is abcd, it was split by v into four // -// tetrahedra abcv, badv, cbdv, and acdv. 'splittet' represents face abc of // -// abcv (i.e., its opposite is v). // -// // -// Point v is removed by expanding abcv to abcd, deleting three tetrahedra // -// badv, cbdv and acdv. On return, point v is not deleted in this routine. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::unsplittetrahedron(triface* splittet) -{ - triface abcv, badv, cbdv, acdv; - triface oldabv, oldbcv, oldcav; - triface badcasing, cbdcasing, acdcasing; - face badsh, cbdsh, acdsh; - - abcv = *splittet; - adjustedgering(abcv, CCW); // for sure. - fnext(abcv, oldabv); - fnext(oldabv, badv); - esymself(badv); - enextfnext(abcv, oldbcv); - fnext(oldbcv, cbdv); - esymself(cbdv); - enext2fnext(abcv, oldcav); - fnext(oldcav, acdv); - esymself(acdv); - - if (b->verbose > 1) { - printf(" Removing point %d in tetrahedron (%d, %d, %d, %d).\n", - pointmark(oppo(abcv)), pointmark(org(abcv)), pointmark(dest(abcv)), - pointmark(apex(abcv)), pointmark(apex(badv))); - } - - sym(badv, badcasing); - tspivot(badv, badsh); - sym(cbdv, cbdcasing); - tspivot(cbdv, cbdsh); - sym(acdv, acdcasing); - tspivot(acdv, acdsh); - - // Expanding abcv to abcd. - setoppo(abcv, apex(badv)); - bond(oldabv, badcasing); - if (badsh.sh != dummysh) { - tsbond(oldabv, badsh); - } - bond(oldbcv, cbdcasing); - if (cbdsh.sh != dummysh) { - tsbond(oldbcv, cbdsh); - } - bond(oldcav, acdcasing); - if (acdsh.sh != dummysh) { - tsbond(oldcav, acdsh); - } - - // Delete the three split-out tetrahedra. - tetrahedrondealloc(badv.tet); - tetrahedrondealloc(cbdv.tet); - tetrahedrondealloc(acdv.tet); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// splittetface() Insert a point on a face of a mesh. // -// // -// 'splittet' is the splitting face. Let it is abcd, where abc is the face // -// will be split. If abc is not a hull face, abce is the tetrahedron at the // -// opposite of d. // -// // -// To split face abc by a point v is to shrink the tetrahedra abcd to abvd, // -// create two new tetrahedra bcvd, cavd. If abc is not a hull face, shrink // -// the tetrahedra bace to bave, create two new tetrahedra cbve, acve. // -// // -// If abc is a subface, it is split into three subfaces simultaneously by // -// calling routine splitsubface(), hence, abv, bcv, cav. The edge rings of // -// the split subfaces have the same orientation as abc's. // -// // -// On completion, 'splittet' returns abvd. If 'flipqueue' is not NULL, it // -// contains all possibly non-locally Delaunay faces. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -splittetface(point newpoint, triface* splittet, queue* flipqueue) -{ - triface abcd, bace; // Old configuration. - triface oldbcd, oldcad, oldace, oldcbe; - triface bcdcasing, cadcasing, acecasing, cbecasing; - face abcsh, bcdsh, cadsh, acesh, cbesh; - triface abvd, bcvd, cavd, bave, cbve, acve; // New configuration. - point pa, pb, pc, pd, pe; - REAL attrib, volume; - bool mirrorflag; - int i; - - abcd = *splittet; - // abcd.ver = 0; // Adjust to be CCW edge ring. - adjustedgering(abcd, CCW); - pa = org(abcd); - pb = dest(abcd); - pc = apex(abcd); - pd = oppo(abcd); - // Is there a second tetrahderon? - mirrorflag = issymexist(&abcd); - if (mirrorflag) { - // This is an interior face. - sym(abcd, bace); - findedge(&bace, dest(abcd), org(abcd)); - pe = oppo(bace); - } - if (checksubfaces) { - // Is there a subface need to be split together? - tspivot(abcd, abcsh); - if (abcsh.sh != dummysh) { - // Exists! Keep the edge ab of both handles be the same. - findedge(&abcsh, org(abcd), dest(abcd)); - } - } - - if (b->verbose > 1) { - printf(" Inserting point %d on face (%d, %d, %d).\n", pointmark(newpoint), - pointmark(pa), pointmark(pb), pointmark(pc)); - } - -#ifdef SELF_CHECK - // Make sure no inversed tetrahedron has been created. - assert(orient3d(pa, pb, pd, newpoint) >= 0.0); - assert(orient3d(pb, pc, pd, newpoint) >= 0.0); - assert(orient3d(pc, pa, pd, newpoint) >= 0.0); -#endif - - // Save the old configuration at faces bcd and cad. - enextfnext(abcd, oldbcd); - enext2fnext(abcd, oldcad); - sym(oldbcd, bcdcasing); - sym(oldcad, cadcasing); - // Create two new tetrahedra. - maketetrahedron(&bcvd); - maketetrahedron(&cavd); - if (mirrorflag) { - // Save the old configuration at faces bce and cae. - enextfnext(bace, oldace); - enext2fnext(bace, oldcbe); - sym(oldace, acecasing); - sym(oldcbe, cbecasing); - // Create two new tetrahedra. - maketetrahedron(&acve); - maketetrahedron(&cbve); - } else { - // Splitting a boundary face increases the number of boundary faces. - hullsize += 2; - } - - // Set vertices to the changed tetrahedron and new tetrahedra. - abvd = abcd; // Update 'abcd' to 'abvd'. - setapex(abvd, newpoint); - setorg (bcvd, pb); // Set 'bcvd'. - setdest(bcvd, pc); - setapex(bcvd, newpoint); - setoppo(bcvd, pd); - setorg (cavd, pc); // Set 'cavd'. - setdest(cavd, pa); - setapex(cavd, newpoint); - setoppo(cavd, pd); - // Set the element attributes of the new tetrahedra. - for (i = 0; i < in->numberoftetrahedronattributes; i++) { - attrib = elemattribute(abvd.tet, i); - setelemattribute(bcvd.tet, i, attrib); - setelemattribute(cavd.tet, i, attrib); - } - if (b->varvolume) { - // Set the area constraint of the new tetrahedra. - volume = volumebound(abvd.tet); - setvolumebound(bcvd.tet, volume); - setvolumebound(cavd.tet, volume); - } - if (mirrorflag) { - bave = bace; // Update 'bace' to 'bave'. - setapex(bave, newpoint); - setorg (acve, pa); // Set 'acve'. - setdest(acve, pc); - setapex(acve, newpoint); - setoppo(acve, pe); - setorg (cbve, pc); // Set 'cbve'. - setdest(cbve, pb); - setapex(cbve, newpoint); - setoppo(cbve, pe); - // Set the element attributes of the new tetrahedra. - for (i = 0; i < in->numberoftetrahedronattributes; i++) { - attrib = elemattribute(bave.tet, i); - setelemattribute(acve.tet, i, attrib); - setelemattribute(cbve.tet, i, attrib); - } - if (b->varvolume) { - // Set the area constraint of the new tetrahedra. - volume = volumebound(bave.tet); - setvolumebound(acve.tet, volume); - setvolumebound(cbve.tet, volume); - } - } - - // Bond the new tetrahedra to the surrounding tetrahedra. - bcvd.loc = 1; - bond(bcvd, bcdcasing); - cavd.loc = 1; - bond(cavd, cadcasing); - bcvd.loc = 3; - bond(bcvd, oldbcd); - cavd.loc = 2; - bond(cavd, oldcad); - bcvd.loc = 2; - cavd.loc = 3; - bond(bcvd, cavd); - if (mirrorflag) { - acve.loc = 1; - bond(acve, acecasing); - cbve.loc = 1; - bond(cbve, cbecasing); - acve.loc = 3; - bond(acve, oldace); - cbve.loc = 2; - bond(cbve, oldcbe); - acve.loc = 2; - cbve.loc = 3; - bond(acve, cbve); - // Bond two new coplanar facets. - bcvd.loc = 0; - cbve.loc = 0; - bond(bcvd, cbve); - cavd.loc = 0; - acve.loc = 0; - bond(cavd, acve); - } - - // There may exist subface needed to be bonded to the new tetrahedra. - if (checksubfaces) { - tspivot(oldbcd, bcdsh); - if (bcdsh.sh != dummysh) { - tsdissolve(oldbcd); - bcvd.loc = 1; - tsbond(bcvd, bcdsh); - } - tspivot(oldcad, cadsh); - if (cadsh.sh != dummysh) { - tsdissolve(oldcad); - cavd.loc = 1; - tsbond(cavd, cadsh); - } - if (mirrorflag) { - tspivot(oldace, acesh); - if (acesh.sh != dummysh) { - tsdissolve(oldace); - acve.loc = 1; - tsbond(acve, acesh); - } - tspivot(oldcbe, cbesh); - if (cbesh.sh != dummysh) { - tsdissolve(oldcbe); - cbve.loc = 1; - tsbond(cbve, cbesh); - } - } - // Is there a subface needs to be split together? - if (abcsh.sh != dummysh) { - // Split this subface 'abc' into three i.e, abv, bcv, cav. - splitsubface(newpoint, &abcsh, (queue *) NULL); - } - } - - // Save a handle for quick point location. - recenttet = abvd; - // Set the return handle be abvd. - *splittet = abvd; - - bcvd.loc = 0; - cavd.loc = 0; - if (mirrorflag) { - cbve.loc = 0; - acve.loc = 0; - } - if (b->verbose > 3) { - printf(" Updating abvd "); - printtet(&abvd); - printf(" Creating bcvd "); - printtet(&bcvd); - printf(" Creating cavd "); - printtet(&cavd); - if (mirrorflag) { - printf(" Updating bave "); - printtet(&bave); - printf(" Creating cbve "); - printtet(&cbve); - printf(" Creating acve "); - printtet(&acve); - } - } - - if (flipqueue != (queue *) NULL) { - fnextself(abvd); - enqueueflipface(abvd, flipqueue); - fnextself(bcvd); - enqueueflipface(bcvd, flipqueue); - fnextself(cavd); - enqueueflipface(cavd, flipqueue); - if (mirrorflag) { - fnextself(bave); - enqueueflipface(bave, flipqueue); - fnextself(cbve); - enqueueflipface(cbve, flipqueue); - fnextself(acve); - enqueueflipface(acve, flipqueue); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// unsplittetface() Reverse the operation of inserting a point on a face, // -// so as to remove the newly inserted point. // -// // -// Assume the original face is abc, the tetrahedron containing abc is abcd. // -// If abc is not a hull face, bace is the tetrahedron at the opposite of d. // -// After face abc was split by a point v, tetrahedron abcd had been split // -// into three tetrahedra, abvd, bcvd, cavd, and bace (if it exists) had been // -// split into bave, cbve, acve. 'splittet' represents abvd (its apex is v). // -// // -// Point v is removed by expanding abvd to abcd, deleting two tetrahedra // -// bcvd, cavd. Expanding bave(if it exists) to bace, deleting two tetrahedra // -// cbve, acve. If abv is a subface, routine unsplitsubface() will be called // -// to reverse the operation of splitting a subface. On completion, point v // -// is not deleted in this routine. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::unsplittetface(triface* splittet) -{ - triface abvd, bcvd, cavd, bave, cbve, acve; - triface oldbvd, oldvad, oldvbe, oldave; - triface bcdcasing, cadcasing, cbecasing, acecasing; - face bcdsh, cadsh, cbesh, acesh; - face abvsh; - bool mirrorflag; - - abvd = *splittet; - adjustedgering(abvd, CCW); // for sure. - enextfnext(abvd, oldbvd); - fnext(oldbvd, bcvd); - esymself(bcvd); - enextself(bcvd); - enext2fnext(abvd, oldvad); - fnext(oldvad, cavd); - esymself(cavd); - enext2self(cavd); - // Is there a second tetrahedron? - sym(abvd, bave); - mirrorflag = bave.tet != dummytet; - if (mirrorflag) { - findedge(&bave, dest(abvd), org(abvd)); - enextfnext(bave, oldave); - fnext(oldave, acve); - esymself(acve); - enextself(acve); - enext2fnext(bave, oldvbe); - fnext(oldvbe, cbve); - esymself(cbve); - enext2self(cbve); - } else { - // Unsplit a hull face decrease the number of boundary faces. - hullsize -= 2; - } - // Is there a subface at abv. - tspivot(abvd, abvsh); - if (abvsh.sh != dummysh) { - // Exists! Keep the edge ab of both handles be the same. - findedge(&abvsh, org(abvd), dest(abvd)); - } - - if (b->verbose > 1) { - printf(" Removing point %d on face (%d, %d, %d).\n", - pointmark(apex(abvd)), pointmark(org(abvd)), pointmark(dest(abvd)), - pointmark(dest(bcvd))); - } - - fnextself(bcvd); // bcvd has changed to bcdv. - sym(bcvd, bcdcasing); - tspivot(bcvd, bcdsh); - fnextself(cavd); // cavd has changed to cadv. - sym(cavd, cadcasing); - tspivot(cavd, cadsh); - if (mirrorflag) { - fnextself(acve); // acve has changed to acev. - sym(acve, acecasing); - tspivot(acve, acesh); - fnextself(cbve); // cbve has changed to cbev. - sym(cbve, cbecasing); - tspivot(cbve, cbesh); - } - - // Expand abvd to abcd. - setapex(abvd, dest(bcvd)); - bond(oldbvd, bcdcasing); - if (bcdsh.sh != dummysh) { - tsbond(oldbvd, bcdsh); - } - bond(oldvad, cadcasing); - if (cadsh.sh != dummysh) { - tsbond(oldvad, cadsh); - } - if (mirrorflag) { - // Expanding bave to bace. - setapex(bave, dest(acve)); - bond(oldave, acecasing); - if (acesh.sh != dummysh) { - tsbond(oldave, acesh); - } - bond(oldvbe, cbecasing); - if (cbesh.sh != dummysh) { - tsbond(oldvbe, cbesh); - } - } - - // Unsplit a subface if there exists. - if (abvsh.sh != dummysh) { - unsplitsubface(&abvsh); - } - - // Delete the split-out tetrahedra. - tetrahedrondealloc(bcvd.tet); - tetrahedrondealloc(cavd.tet); - if (mirrorflag) { - tetrahedrondealloc(acve.tet); - tetrahedrondealloc(cbve.tet); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// splitsubface() Insert a point on a subface, split it into three. // -// // -// The subface is 'splitface'. Let it is abc. The inserting point 'newpoint'// -// v should lie inside abc. If the neighbor tetrahedra of abc exist, i.e., // -// abcd and bace, they should have been split by routine splittetface() // -// before calling this routine, so the connection between the new tetrahedra // -// and new subfaces can be correctly set. // -// // -// To split subface abc by point v is to shrink abc to abv, create two new // -// subfaces bcv and cav. Set the connection between updated and new created // -// subfaces. If there is a subsegment at edge bc or ca, connection of new // -// subface (bcv or cav) to its casing subfaces is a face link, 'casingin' is // -// the predecessor and 'casingout' is the successor. It is important to keep // -// the orientations of the edge rings of the updated and created subfaces be // -// the same as abc's. So they have the same orientation as other subfaces of // -// this facet with respect to the lift point of this facet. // -// // -// On completion, 'splitface' returns abv. If 'flipqueue' is not NULL, it // -// returns all possibly non-Delaunay edges. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -splitsubface(point newpoint, face* splitface, queue* flipqueue) -{ - triface abvd, bcvd, cavd, bave, cbve, acve; - face abc, oldbc, oldca, bc, ca, spinsh; - face bccasin, bccasout, cacasin, cacasout; - face abv, bcv, cav; - point pa, pb, pc; - - abc = *splitface; - // The newly created subfaces will have the same edge ring as abc. - adjustedgering(abc, CCW); - pa = sorg(abc); - pb = sdest(abc); - pc = sapex(abc); - - if (b->verbose > 1) { - printf(" Inserting point %d on subface (%d, %d, %d).\n", - pointmark(newpoint), pointmark(pa), pointmark(pb), pointmark(pc)); - } - - // Save the old configuration at edge bc and ca. Subsegments may appear - // at both sides, save the face links and dissolve them. - senext(abc, oldbc); - senext2(abc, oldca); - spivot(oldbc, bccasout); - sspivot(oldbc, bc); - if (bc.sh != dummysh) { - if (oldbc.sh != bccasout.sh) { - // 'oldbc' is not self-bonded. - spinsh = bccasout; - do { - bccasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != oldbc.sh); - } else { - bccasout.sh = dummysh; - } - ssdissolve(oldbc); - } - spivot(oldca, cacasout); - sspivot(oldca, ca); - if (ca.sh != dummysh) { - if (oldca.sh != cacasout.sh) { - // 'oldca' is not self-bonded. - spinsh = cacasout; - do { - cacasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != oldca.sh); - } else { - cacasout.sh = dummysh; - } - ssdissolve(oldca); - } - // Create two new subfaces. - makeshellface(subfaces, &bcv); - makeshellface(subfaces, &cav); - - // Set the vertices of changed and new subfaces. - abv = abc; // Update 'abc' to 'abv'. - setsapex(abv, newpoint); - setsorg(bcv, pb); // Set 'bcv'. - setsdest(bcv, pc); - setsapex(bcv, newpoint); - setsorg(cav, pc); // Set 'cav'. - setsdest(cav, pa); - setsapex(cav, newpoint); - if (b->quality) { - // Copy yhr area bound into the new subfaces. - setareabound(bcv, areabound(abv)); - setareabound(cav, areabound(abv)); - } - // Copy the boundary mark into the new subfaces. - setshellmark(bcv, shellmark(abv)); - setshellmark(cav, shellmark(abv)); - // Copy the subface type into the new subfaces. - setshelltype(bcv, shelltype(abv)); - setshelltype(cav, shelltype(abv)); - // Bond the new subfaces to the surrounding subfaces. - if (bc.sh != dummysh) { - if (bccasout.sh != dummysh) { - sbond1(bccasin, bcv); - sbond1(bcv, bccasout); - } else { - // Bond 'bcv' to itsself. - sbond(bcv, bcv); - } - ssbond(bcv, bc); - } else { - sbond(bcv, bccasout); - } - if (ca.sh != dummysh) { - if (cacasout.sh != dummysh) { - sbond1(cacasin, cav); - sbond1(cav, cacasout); - } else { - // Bond 'cav' to itself. - sbond(cav, cav); - } - ssbond(cav, ca); - } else { - sbond(cav, cacasout); - } - senext2self(bcv); - sbond(bcv, oldbc); - senextself(cav); - sbond(cav, oldca); - senext2self(bcv); - senextself(cav); - sbond(bcv, cav); - - // Bond the new subfaces to the new tetrahedra if they exist. - stpivot(abv, abvd); - if (abvd.tet != dummytet) { - // Get two new tetrahedra and their syms. - findedge(&abvd, sorg(abv), sdest(abv)); - enextfnext(abvd, bcvd); - assert(bcvd.tet != dummytet); - fnextself(bcvd); - enext2fnext(abvd, cavd); - assert(cavd.tet != dummytet); - fnextself(cavd); - // Bond two new subfaces to the two new tetrahedra. - tsbond(bcvd, bcv); - tsbond(cavd, cav); - } - // Set the connection at the other sides if the tetrahedra exist. - sesymself(abv); // bav - stpivot(abv, bave); - if (bave.tet != dummytet) { - sesymself(bcv); // cbv - sesymself(cav); // acv - // Get two new tetrahedra and their syms. - findedge(&bave, sorg(abv), sdest(abv)); - enextfnext(bave, acve); - assert(acve.tet != dummytet); - fnextself(acve); - enext2fnext(bave, cbve); - assert(cbve.tet != dummytet); - fnextself(cbve); - // Bond two new subfaces to the two new tetrahedra. - tsbond(acve, cav); - tsbond(cbve, bcv); - } - - bcv.shver = 0; - cav.shver = 0; - if (b->verbose > 3) { - printf(" Updating abv "); - printsh(&abv); - printf(" Creating bcv "); - printsh(&bcv); - printf(" Creating cav "); - printsh(&cav); - } - - if (flipqueue != (queue *) NULL) { - enqueueflipedge(abv, flipqueue); - enqueueflipedge(bcv, flipqueue); - enqueueflipedge(cav, flipqueue); - } - - // Set the return handle be abv. - *splitface = abv; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// unsplitsubface() Reverse the operation of inserting a point on a // -// subface, so as to remove the newly inserted point. // -// // -// Assume the original subface is abc, it was split by a point v into three // -// subfaces abv, bcv and cav. 'splitsh' represents abv. // -// // -// To remove point v is to expand abv to abc, delete bcv and cav. If edge bc // -// or ca is a subsegment, the connection at a subsegment is a subface link, // -// '-casin' and '-casout' are used to save the predecessor and successor of // -// bcv or cav. On completion, point v is not deleted in this routine. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::unsplitsubface(face* splitsh) -{ - face abv, bcv, cav; - face oldbv, oldva, bc, ca, spinsh; - face bccasin, bccasout, cacasin, cacasout; - - abv = *splitsh; - senext(abv, oldbv); - spivot(oldbv, bcv); - if (sorg(bcv) != sdest(oldbv)) { - sesymself(bcv); - } - senextself(bcv); - senext2(abv, oldva); - spivot(oldva, cav); - if (sorg(cav) != sdest(oldva)) { - sesymself(cav); - } - senext2self(cav); - - if (b->verbose > 1) { - printf(" Removing point %d on subface (%d, %d, %d).\n", - pointmark(sapex(abv)), pointmark(sorg(abv)), pointmark(sdest(abv)), - pointmark(sdest(bcv))); - } - - spivot(bcv, bccasout); - sspivot(bcv, bc); - if (bc.sh != dummysh) { - if (bcv.sh != bccasout.sh) { - // 'bcv' is not self-bonded. - spinsh = bccasout; - do { - bccasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != bcv.sh); - } else { - bccasout.sh = dummysh; - } - } - spivot(cav, cacasout); - sspivot(cav, ca); - if (ca.sh != dummysh) { - if (cav.sh != cacasout.sh) { - // 'cav' is not self-bonded. - spinsh = cacasout; - do { - cacasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != cav.sh); - } else { - cacasout.sh = dummysh; - } - } - - // Expand abv to abc. - setsapex(abv, sdest(bcv)); - if (bc.sh != dummysh) { - if (bccasout.sh != dummysh) { - sbond1(bccasin, oldbv); - sbond1(oldbv, bccasout); - } else { - // Bond 'oldbv' to itself. - sbond(oldbv, oldbv); - } - ssbond(oldbv, bc); - } else { - sbond(oldbv, bccasout); - } - if (ca.sh != dummysh) { - if (cacasout.sh != dummysh) { - sbond1(cacasin, oldva); - sbond1(oldva, cacasout); - } else { - // Bond 'oldva' to itself. - sbond(oldva, oldva); - } - ssbond(oldva, ca); - } else { - sbond(oldva, cacasout); - } - - // Delete two split-out subfaces. - shellfacedealloc(subfaces, bcv.sh); - shellfacedealloc(subfaces, cav.sh); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// splittetedge() Insert a point on an edge of the mesh. // -// // -// The edge is given by 'splittet'. Assume its four corners are a, b, n1 and // -// n2, where ab is the edge will be split. Around ab may exist any number of // -// tetrahedra. For convenience, they're ordered in a sequence following the // -// right-hand rule with your thumb points from a to b. Let the vertex set of // -// these tetrahedra be {a, b, n1, n2, ..., n(i)}. NOTE the tetrahedra around // -// ab may not connect to each other (can only happen when ab is a subsegment,// -// hence some faces abn(i) are subfaces). If ab is a subsegment, abn1 must // -// be a subface. // -// // -// To split edge ab by a point v is to split all tetrahedra containing ab by // -// v. More specifically, for each such tetrahedron, an1n2b, it is shrunk to // -// an1n2v, and a new tetrahedra bn2n1v is created. If ab is a subsegment, or // -// some faces of the splitting tetrahedra are subfaces, they must be split // -// either by calling routine 'splitsubedge()'. // -// // -// On completion, 'splittet' returns avn1n2. If 'flipqueue' is not NULL, it // -// returns all faces which may become non-Delaunay after this operation. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -splittetedge(point newpoint, triface* splittet, queue* flipqueue) -{ - triface *bots, *newtops; - triface oldtop, topcasing; - triface spintet, tmpbond0, tmpbond1; - face abseg, splitsh, topsh, spinsh; - point pa, pb, n1, n2; - REAL attrib, volume; - int wrapcount, hitbdry; - int i, j; - - if (checksubfaces) { - // Is there a subsegment need to be split together? - tsspivot(splittet, &abseg); - if (abseg.sh != dummysh) { - abseg.shver = 0; - // Orient the edge direction of 'splittet' be abseg. - if (org(*splittet) != sorg(abseg)) { - esymself(*splittet); - } - } - } - spintet = *splittet; - pa = org(spintet); - pb = dest(spintet); - - if (b->verbose > 1) { - printf(" Inserting point %d on edge (%d, %d).\n", - pointmark(newpoint), pointmark(pa), pointmark(pb)); - } - - // Collect the tetrahedra containing the splitting edge (ab). - n1 = apex(spintet); - hitbdry = 0; - wrapcount = 1; - if (checksubfaces && abseg.sh != dummysh) { - // It may happen that some tetrahedra containing ab (a subsegment) are - // completely disconnected with others. If it happens, use the face - // link of ab to cross the boundary. - while (true) { - if (!fnextself(spintet)) { - // Meet a boundary, walk through it. - hitbdry ++; - tspivot(spintet, spinsh); - assert(spinsh.sh != dummysh); - findedge(&spinsh, pa, pb); - sfnextself(spinsh); - stpivot(spinsh, spintet); - assert(spintet.tet != dummytet); - findedge(&spintet, pa, pb); - // Remember this position (hull face) in 'splittet'. - *splittet = spintet; - // Split two hull faces increase the hull size; - hullsize += 2; - } - if (apex(spintet) == n1) break; - wrapcount ++; - } - if (hitbdry > 0) { - wrapcount -= hitbdry; - } - } else { - // All the tetrahedra containing ab are connected together. If there - // are subfaces, 'splitsh' keeps one of them. - splitsh.sh = dummysh; - while (hitbdry < 2) { - if (checksubfaces && splitsh.sh == dummysh) { - tspivot(spintet, splitsh); - } - if (fnextself(spintet)) { - if (apex(spintet) == n1) break; - wrapcount++; - } else { - hitbdry ++; - if (hitbdry < 2) { - esym(*splittet, spintet); - } - } - } - if (hitbdry > 0) { - // ab is on the hull. - wrapcount -= 1; - // 'spintet' now is a hull face, inverse its edge direction. - esym(spintet, *splittet); - // Split two hull faces increases the number of hull faces. - hullsize += 2; - } - } - - // Make arrays of updating (bot, oldtop) and new (newtop) tetrahedra. - bots = new triface[wrapcount]; - newtops = new triface[wrapcount]; - // Spin around ab, gather tetrahedra and set up new tetrahedra. - spintet = *splittet; - for (i = 0; i < wrapcount; i++) { - // Get 'bots[i] = an1n2b'. - enext2fnext(spintet, bots[i]); - esymself(bots[i]); - // Create 'newtops[i]'. - maketetrahedron(&(newtops[i])); - // Go to the next. - fnextself(spintet); - if (checksubfaces && abseg.sh != dummysh) { - if (!issymexist(&spintet)) { - // We meet a hull face, walk through it. - tspivot(spintet, spinsh); - assert(spinsh.sh != dummysh); - findedge(&spinsh, pa, pb); - sfnextself(spinsh); - stpivot(spinsh, spintet); - assert(spintet.tet != dummytet); - findedge(&spintet, pa, pb); - } - } - } - - // Set the vertices of updated and new tetrahedra. - for (i = 0; i < wrapcount; i++) { - // Update 'bots[i] = an1n2v'. - setoppo(bots[i], newpoint); - // Set 'newtops[i] = bn2n1v'. - n1 = dest(bots[i]); - n2 = apex(bots[i]); - // Set 'newtops[i]'. - setorg(newtops[i], pb); - setdest(newtops[i], n2); - setapex(newtops[i], n1); - setoppo(newtops[i], newpoint); - // Set the element attributes of a new tetrahedron. - for (j = 0; j < in->numberoftetrahedronattributes; j++) { - attrib = elemattribute(bots[i].tet, j); - setelemattribute(newtops[i].tet, j, attrib); - } - if (b->varvolume) { - // Set the area constraint of a new tetrahedron. - volume = volumebound(bots[i].tet); - setvolumebound(newtops[i].tet, volume); - } -#ifdef SELF_CHECK - // Make sure no inversed tetrahedron has been created. - assert(orient3d(pa, n1, n2, newpoint) <= 0.0); - assert(orient3d(pb, n2, n1, newpoint) <= 0.0); -#endif - } - - // Bond newtops to topcasings and bots. - for (i = 0; i < wrapcount; i++) { - // Get 'oldtop = n1n2va' from 'bots[i]'. - enextfnext(bots[i], oldtop); - sym(oldtop, topcasing); - bond(newtops[i], topcasing); - if (checksubfaces) { - tspivot(oldtop, topsh); - if (topsh.sh != dummysh) { - tsdissolve(oldtop); - tsbond(newtops[i], topsh); - } - } - enextfnext(newtops[i], tmpbond0); - bond(oldtop, tmpbond0); - } - // Bond between newtops. - fnext(newtops[0], tmpbond0); - enext2fnext(bots[0], spintet); - for (i = 1; i < wrapcount; i ++) { - if (issymexist(&spintet)) { - enext2fnext(newtops[i], tmpbond1); - bond(tmpbond0, tmpbond1); - } - fnext(newtops[i], tmpbond0); - enext2fnext(bots[i], spintet); - } - // Bond the last to the first if no boundary. - if (issymexist(&spintet)) { - enext2fnext(newtops[0], tmpbond1); - bond(tmpbond0, tmpbond1); - } - - // Is there exist subfaces and subsegment need to be split? - if (checksubfaces) { - if (abseg.sh != dummysh) { - // A subsegment needs be split. - spivot(abseg, splitsh); - assert(splitsh.sh != dummysh); - } - if (splitsh.sh != dummysh) { - // Split subfaces (and subsegment). - findedge(&splitsh, pa, pb); - splitsubedge(newpoint, &splitsh, (queue *) NULL); - } - } - - if (b->verbose > 3) { - for (i = 0; i < wrapcount; i++) { - printf(" Updating bots[%i] ", i); - printtet(&(bots[i])); - printf(" Creating newtops[%i] ", i); - printtet(&(newtops[i])); - } - } - - if (flipqueue != (queue *) NULL) { - for (i = 0; i < wrapcount; i++) { - enqueueflipface(bots[i], flipqueue); - enqueueflipface(newtops[i], flipqueue); - } - } - - // Set the return handle be avn1n2. It is got by transforming from - // 'bots[0]' (which is an1n2v). - fnext(bots[0], spintet); // spintet is an1vn2. - esymself(spintet); // spintet is n1avn2. - enextself(spintet); // spintet is avn1n2. - *splittet = spintet; - - delete [] bots; - delete [] newtops; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// unsplittetedge() Reverse the operation of splitting an edge, so as to // -// remove the newly inserted point. // -// // -// Assume the original edge is ab, the tetrahedron containing ab is abn1n2. // -// After ab was split by a point v, every tetrahedron containing ab (e.g., // -// abn1n2) has been split into two (e.g., an1n2v and bn2n1v). 'splittet' // -// represents avn1n2 (i.e., its destination is v). // -// // -// To remove point v is to expand each split tetrahedron containing ab (e.g.,// -// (avn1n2 to abn1n2), then delete the redundant one(e.g., vbn1n2). If there // -// exists any subface around ab, routine unsplitsubedge() will be called to // -// reverse the operation of splitting a edge (or a subsegment) of subfaces. // -// On completion, point v is not deleted in this routine. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::unsplittetedge(triface* splittet) -{ - triface *bots, *newtops; - triface oldtop, topcasing; - triface spintet; - face avseg, splitsh, topsh, spinsh; - point pa, pv, n1; - int wrapcount, hitbdry; - int i; - - spintet = *splittet; - pa = org(spintet); - pv = dest(spintet); - if (checksubfaces) { - // Is there a subsegment need to be unsplit together? - tsspivot(splittet, &avseg); - if (avseg.sh != dummysh) { - // The subsegment's direction should conform to 'splittet'. - if (sorg(avseg) != pa) { - sesymself(avseg); - } - } - } - - n1 = apex(spintet); - hitbdry = 0; - wrapcount = 1; - if (checksubfaces && avseg.sh != dummysh) { - // It may happen that some tetrahedra containing ab (a subsegment) are - // completely disconnected with others. If it happens, use the face - // link of ab to cross the boundary. - while (true) { - if (!fnextself(spintet)) { - // Meet a boundary, walk through it. - hitbdry ++; - tspivot(spintet, spinsh); - assert(spinsh.sh != dummysh); - findedge(&spinsh, pa, pv); - sfnextself(spinsh); - stpivot(spinsh, spintet); - assert(spintet.tet != dummytet); - findedge(&spintet, pa, pv); - // Remember this position (hull face) in 'splittet'. - *splittet = spintet; - // Split two hull faces increase the hull size; - hullsize += 2; - } - if (apex(spintet) == n1) break; - wrapcount ++; - } - if (hitbdry > 0) { - wrapcount -= hitbdry; - } - } else { - // All the tetrahedra containing ab are connected together. If there - // are subfaces, 'splitsh' keeps one of them. - splitsh.sh = dummysh; - while (hitbdry < 2) { - if (checksubfaces && splitsh.sh == dummysh) { - tspivot(spintet, splitsh); - } - if (fnextself(spintet)) { - if (apex(spintet) == n1) break; - wrapcount++; - } else { - hitbdry ++; - if (hitbdry < 2) { - esym(*splittet, spintet); - } - } - } - if (hitbdry > 0) { - // ab is on the hull. - wrapcount -= 1; - // 'spintet' now is a hull face, inverse its edge direction. - esym(spintet, *splittet); - // Split two hull faces increases the number of hull faces. - hullsize += 2; - } - } - - // Make arrays of updating (bot, oldtop) and new (newtop) tetrahedra. - bots = new triface[wrapcount]; - newtops = new triface[wrapcount]; - // Spin around av, gather tetrahedra and set up new tetrahedra. - spintet = *splittet; - for (i = 0; i < wrapcount; i++) { - // Get 'bots[i] = an1n2v'. - enext2fnext(spintet, bots[i]); - esymself(bots[i]); - // Get 'oldtop = n1n2va'. - enextfnext(bots[i], oldtop); - // Get 'newtops[i] = 'bn1n2v' - fnext(oldtop, newtops[i]); // newtop = n1n2bv - esymself(newtops[i]); // newtop = n2n1bv - enext2self(newtops[i]); // newtop = bn2n1v - // Go to the next. - fnextself(spintet); - if (checksubfaces && avseg.sh != dummysh) { - if (!issymexist(&spintet)) { - // We meet a hull face, walk through it. - tspivot(spintet, spinsh); - assert(spinsh.sh != dummysh); - findedge(&spinsh, pa, pv); - sfnextself(spinsh); - stpivot(spinsh, spintet); - assert(spintet.tet != dummytet); - findedge(&spintet, pa, pv); - } - } - } - - if (b->verbose > 1) { - printf(" Removing point %d from edge (%d, %d).\n", - pointmark(oppo(bots[0])), pointmark(org(bots[0])), - pointmark(org(newtops[0]))); - } - - for (i = 0; i < wrapcount; i++) { - // Expand an1n2v to an1n2b. - setoppo(bots[i], org(newtops[i])); - // Get 'oldtop = n1n2va' from 'bot[i]'. - enextfnext(bots[i], oldtop); - // Get 'topcasing' from 'newtop[i]' - sym(newtops[i], topcasing); - // Bond them. - bond(oldtop, topcasing); - if (checksubfaces) { - tspivot(newtops[i], topsh); - if (topsh.sh != dummysh) { - tsbond(oldtop, topsh); - } - } - // Delete the tetrahedron above an1n2v. - tetrahedrondealloc(newtops[i].tet); - } - - // If there exists any subface, unsplit them. - if (checksubfaces) { - if (avseg.sh != dummysh) { - spivot(avseg, splitsh); - assert(splitsh.sh != dummysh); - } - if (splitsh.sh != dummysh) { - findedge(&splitsh, pa, pv); - unsplitsubedge(&splitsh); - } - } - - delete [] bots; - delete [] newtops; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// splitsubedge() Insert a point on an edge of the surface mesh. // -// // -// The splitting edge is given by 'splitsh'. Assume its three corners are a, // -// b, c, where ab is the edge will be split. ab may be a subsegment. // -// // -// To split edge ab is to split all subfaces conatining ab. If ab is not a // -// subsegment, there are only two subfaces need be split, otherwise, there // -// may have any number of subfaces need be split. Each splitting subface abc // -// is shrunk to avc, a new subface vbc is created. It is important to keep // -// the orientations of edge rings of avc and vbc be the same as abc's. If ab // -// is a subsegment, it is shrunk to av and a new subsegment vb is created. // -// // -// If there are tetrahedra adjoining to the splitting subfaces, they should // -// be split before calling this routine, so the connection between the new // -// tetrahedra and the new subfaces can be correctly set. // -// // -// On completion, 'splitsh' returns avc. If 'flipqueue' is not NULL, it // -// returns all edges which may be non-Delaunay. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::splitsubedge(point newpoint, face* splitsh, queue* flipqueue) -{ - triface abcd, bace, vbcd, bvce; - face startabc, spinabc, spinsh; - face oldbc, bccasin, bccasout; - face ab, bc; - face avc, vbc, vbc1; - face av, vb; - point pa, pb; - - startabc = *splitsh; - // Is there a subsegment? - sspivot(startabc, ab); - if (ab.sh != dummysh) { - ab.shver = 0; - if (sorg(startabc) != sorg(ab)) { - sesymself(startabc); - } - } - pa = sorg(startabc); - pb = sdest(startabc); - - if (b->verbose > 1) { - printf(" Inserting point %d on subedge (%d, %d).\n", - pointmark(newpoint), pointmark(pa), pointmark(pb)); - } - - // Spin arround ab, split every subface containing ab. - spinabc = startabc; - do { - // Adjust spinabc be edge ab. - if (sorg(spinabc) != pa) { - sesymself(spinabc); - } - // Save old configuration at edge bc, if bc has a subsegment, save the - // face link of it and dissolve it from bc. - senext(spinabc, oldbc); - spivot(oldbc, bccasout); - sspivot(oldbc, bc); - if (bc.sh != dummysh) { - if (spinabc.sh != bccasout.sh) { - // 'spinabc' is not self-bonded. - spinsh = bccasout; - do { - bccasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != oldbc.sh); - } else { - bccasout.sh = dummysh; - } - ssdissolve(oldbc); - } - // Create a new subface. - makeshellface(subfaces, &vbc); - // Split abc. - avc = spinabc; // Update 'abc' to 'avc'. - setsdest(avc, newpoint); - // Make 'vbc' be in the same edge ring as 'avc'. - vbc.shver = avc.shver; - setsorg(vbc, newpoint); // Set 'vbc'. - setsdest(vbc, pb); - setsapex(vbc, sapex(avc)); - if (b->quality) { - // Copy yhr area bound into the new subfaces. - setareabound(vbc, areabound(avc)); - } - // Copy the shell marker and shell type into the new subface. - setshellmark(vbc, shellmark(avc)); - setshelltype(vbc, shelltype(avc)); - // Set the connection between updated and new subfaces. - senext2self(vbc); - sbond(vbc, oldbc); - // Set the connection between new subface and casings. - senext2self(vbc); - if (bc.sh != dummysh) { - if (bccasout.sh != dummysh) { - // Insert 'vbc' into face link. - sbond1(bccasin, vbc); - sbond1(vbc, bccasout); - } else { - // Bond 'vbc' to itself. - sbond(vbc, vbc); - } - ssbond(vbc, bc); - } else { - sbond(vbc, bccasout); - } - // Go to next subface at edge ab. - spivotself(spinabc); - if (spinabc.sh == dummysh) { - break; // 'ab' is a hull edge. - } - } while (spinabc.sh != startabc.sh); - - // Get the new subface vbc above the updated subface avc (= startabc). - senext(startabc, oldbc); - spivot(oldbc, vbc); - if (sorg(vbc) == newpoint) { - sesymself(vbc); - } - assert(sorg(vbc) == sdest(oldbc) && sdest(vbc) == sorg(oldbc)); - senextself(vbc); - // Set the face link for the new created subfaces around edge vb. - spinabc = startabc; - do { - // Go to the next subface at edge av. - spivotself(spinabc); - if (spinabc.sh == dummysh) { - break; // 'ab' is a hull edge. - } - if (sorg(spinabc) != pa) { - sesymself(spinabc); - } - // Get the new subface vbc1 above the updated subface avc (= spinabc). - senext(spinabc, oldbc); - spivot(oldbc, vbc1); - if (sorg(vbc1) == newpoint) { - sesymself(vbc1); - } - assert(sorg(vbc1) == sdest(oldbc) && sdest(vbc1) == sorg(oldbc)); - senextself(vbc1); - // Set the connection: vbc->vbc1. - sbond1(vbc, vbc1); - // For the next connection. - vbc = vbc1; - } while (spinabc.sh != startabc.sh); - - // Split ab if it is a subsegment. - if (ab.sh != dummysh) { - // Update subsegment ab to av. - av = ab; - setsdest(av, newpoint); - // Create a new subsegment vb. - makeshellface(subsegs, &vb); - setsorg(vb, newpoint); - setsdest(vb, pb); - // vb gets the same mark and segment type as av. - setshellmark(vb, shellmark(av)); - setshelltype(vb, shelltype(av)); - // Save the old connection at ab (re-use the handles oldbc, bccasout). - senext(av, oldbc); - spivot(oldbc, bccasout); - // Bond av and vb (bonded at their "fake" edges). - senext2(vb, bccasin); - sbond(bccasin, oldbc); - if (bccasout.sh != dummysh) { - // There is a subsegment connecting with ab at b. It will connect - // to vb at b after splitting. - bccasout.shver = 0; - assert(sorg(bccasout) == pb); - senext2self(bccasout); - senext(vb, bccasin); - sbond(bccasin, bccasout); - } - // Bond all new subfaces (vbc) to vb. - spinabc = startabc; - do { - // Adjust spinabc be edge av. - if (sorg(spinabc) != pa) { - sesymself(spinabc); - } - // Get new subface vbc above the updated subface avc (= spinabc). - senext(spinabc, oldbc); - spivot(oldbc, vbc); - if (sorg(vbc) == newpoint) { - sesymself(vbc); - } - senextself(vbc); - // Bond the new subface and the new subsegment. - ssbond(vbc, vb); - // Go to the next. - spivotself(spinabc); - assert(spinabc.sh != dummysh); - } while (spinabc.sh != startabc.sh); - } - - // Bond the new subfaces to new tetrahedra if they exist. New tetrahedra - // should have been created before calling this routine. - spinabc = startabc; - do { - // Adjust spinabc be edge av. - if (sorg(spinabc) != pa) { - sesymself(spinabc); - } - // Get new subface vbc above the updated subface avc (= spinabc). - senext(spinabc, oldbc); - spivot(oldbc, vbc); - if (sorg(vbc) == newpoint) { - sesymself(vbc); - } - senextself(vbc); - // Get the adjacent tetrahedra at 'spinabc'. - stpivot(spinabc, abcd); - if (abcd.tet != dummytet) { - findedge(&abcd, sorg(spinabc), sdest(spinabc)); - enextfnext(abcd, vbcd); - fnextself(vbcd); - assert(vbcd.tet != dummytet); - tsbond(vbcd, vbc); - sym(vbcd, bvce); - sesymself(vbc); - tsbond(bvce, vbc); - } else { - // One side is empty, check the other side. - sesymself(spinabc); - stpivot(spinabc, bace); - if (bace.tet != dummytet) { - findedge(&bace, sorg(spinabc), sdest(spinabc)); - enext2fnext(bace, bvce); - fnextself(bvce); - assert(bvce.tet != dummytet); - sesymself(vbc); - tsbond(bvce, vbc); - } - } - // Go to the next. - spivotself(spinabc); - if (spinabc.sh == dummysh) { - break; // 'ab' is a hull edge. - } - } while (spinabc.sh != startabc.sh); - - if (b->verbose > 3) { - spinabc = startabc; - do { - // Adjust spinabc be edge av. - if (sorg(spinabc) != pa) { - sesymself(spinabc); - } - printf(" Updating abc:\n"); - printsh(&spinabc); - // Get new subface vbc above the updated subface avc (= spinabc). - senext(spinabc, oldbc); - spivot(oldbc, vbc); - if (sorg(vbc) == newpoint) { - sesymself(vbc); - } - senextself(vbc); - printf(" Creating vbc:\n"); - printsh(&vbc); - // Go to the next. - spivotself(spinabc); - if (spinabc.sh == dummysh) { - break; // 'ab' is a hull edge. - } - } while (spinabc.sh != startabc.sh); - } - - if (flipqueue != (queue *) NULL) { - spinabc = startabc; - do { - // Adjust spinabc be edge av. - if (sorg(spinabc) != pa) { - sesymself(spinabc); - } - senext2(spinabc, oldbc); // Re-use oldbc. - enqueueflipedge(oldbc, flipqueue); - // Get new subface vbc above the updated subface avc (= spinabc). - senext(spinabc, oldbc); - spivot(oldbc, vbc); - if (sorg(vbc) == newpoint) { - sesymself(vbc); - } - senextself(vbc); - senext(vbc, oldbc); // Re-use oldbc. - enqueueflipedge(oldbc, flipqueue); - // Go to the next. - spivotself(spinabc); - if (spinabc.sh == dummysh) { - break; // 'ab' is a hull edge. - } - } while (spinabc.sh != startabc.sh); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// unsplitsubedge() Reverse the operation of splitting an edge of subface,// -// so as to remove a point from the edge. // -// // -// Assume the original edge is ab, the subface containing it is abc. It was // -// split by a point v into avc, and vbc. 'splitsh' represents avc, further- // -// more, if av is a subsegment, av should be the zero version of the split // -// subsegment (i.e., av.shver = 0), so we are sure that the destination (v) // -// of both avc and av is the deleting point. // -// // -// To remove point v is to expand avc to abc, delete vbc, do the same for // -// other subfaces containing av and vb. If av and vb are subsegments, expand // -// av to ab, delete vb. On completion, point v is not deleted. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::unsplitsubedge(face* splitsh) -{ - face startavc, spinavc, spinbcv; - face oldvc, bccasin, bccasout, spinsh; - face av, vb, bc; - point pa, pv, pb; - - startavc = *splitsh; - sspivot(startavc, av); - if (av.sh != dummysh) { - // Orient the direction of subsegment to conform the subface. - if (sorg(av) != sorg(startavc)) { - sesymself(av); - } - assert(av.shver == 0); - } - senext(startavc, oldvc); - spivot(oldvc, vb); // vb is subface vbc - if (sorg(vb) != sdest(oldvc)) { - sesymself(vb); - } - senextself(vb); - pa = sorg(startavc); - pv = sdest(startavc); - pb = sdest(vb); - - if (b->verbose > 1) { - printf(" Removing point %d from subedge (%d, %d).\n", - pointmark(pv), pointmark(pa), pointmark(pb)); - } - - // Spin arround av, unsplit every subface containing av. - spinavc = startavc; - do { - // Adjust spinavc be edge av. - if (sorg(spinavc) != pa) { - sesymself(spinavc); - } - // Save old configuration at edge bc, if bc has a subsegment, save the - // face link of it. - senext(spinavc, oldvc); - spivot(oldvc, spinbcv); - if (sorg(spinbcv) != sdest(oldvc)) { - sesymself(spinbcv); - } - senext2self(spinbcv); - spivot(spinbcv, bccasout); - sspivot(spinbcv, bc); - if (bc.sh != dummysh) { - if (spinbcv.sh != bccasout.sh) { - // 'spinbcv' is not self-bonded. - spinsh = bccasout; - do { - bccasin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != spinbcv.sh); - } else { - bccasout.sh = dummysh; - } - } - // Expand avc to abc. - setsdest(spinavc, pb); - if (bc.sh != dummysh) { - if (bccasout.sh != dummysh) { - sbond1(bccasin, oldvc); - sbond1(oldvc, bccasout); - } else { - // Bond 'oldbc' to itself. - sbond(oldvc, oldvc); - } - ssbond(oldvc, bc); - } else { - sbond(oldvc, bccasout); - } - // Delete bcv. - shellfacedealloc(subfaces, spinbcv.sh); - // Go to next subface at edge av. - spivotself(spinavc); - if (spinavc.sh == dummysh) { - break; // 'av' is a hull edge. - } - } while (spinavc.sh != startavc.sh); - - // Is there a subsegment need to be unsplit? - if (av.sh != dummysh) { - senext(av, oldvc); // Re-use oldvc. - spivot(oldvc, vb); - vb.shver = 0; - assert(sdest(av) == sorg(vb)); - senext(vb, spinbcv); // Re-use spinbcv. - spivot(spinbcv, bccasout); - // Expand av to ab. - setsdest(av, pb); - sbond(oldvc, bccasout); - // Delete vb. - shellfacedealloc(subsegs, vb.sh); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// insertsite() Insert a point into the mesh. // -// // -// The 'newpoint' is located. If 'searchtet->tet' is not NULL, the search // -// for the containing tetrahedron begins from 'searchtet', otherwise, a full // -// point location procedure is called. If 'newpoint' is found inside a // -// tetrahedron, the tetrahedron is split into four (by splittetrahedron()); // -// if 'newpoint' lies on a face, the face is split into three, thereby // -// splitting the two adjacent tetrahedra into six (by splittetface()); if // -// 'newpoint' lies on an edge, the edge is split into two, thereby, every // -// tetrahedron containing this edge is split into two. If 'newpoint' lies on // -// an existing vertex, no action is taken, and the value DUPLICATEPOINT is // -// returned and 'searchtet' is set to a handle whose origin is the vertex. // -// // -// If 'flipqueue' is not NULL, after 'newpoint' is inserted, it returns all // -// faces which may become non-Delaunay due to the newly inserted point. Flip // -// operations can be performed as necessary on them to maintain the Delaunay // -// property. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::insertsiteresult tetgenmesh:: -insertsite(point newpoint, triface* searchtet, bool approx, queue* flipqueue) -{ - enum locateresult intersect, exactloc; - point checkpt; - REAL epspp, checklen; - int count; - - if (b->verbose > 1) { - printf(" Insert point to mesh: (%.12g, %.12g, %.12g) %d.\n", - newpoint[0], newpoint[1], newpoint[2], pointmark(newpoint)); - } - - if (searchtet->tet == (tetrahedron *) NULL) { - // Search for a tetrahedron containing 'newpoint'. - searchtet->tet = dummytet; - exactloc = locate(newpoint, searchtet); - } else { - // Start searching from the tetrahedron provided by the caller. - exactloc = preciselocate(newpoint, searchtet); - } - intersect = exactloc; - if (approx && (exactloc != ONVERTEX)) { - // Adjust the exact location to an approx. location wrt. epsilon. - epspp = b->epsilon; - count = 0; - while (count < 16) { - intersect = adjustlocate(newpoint, searchtet, exactloc, epspp); - if (intersect == ONVERTEX) { - checkpt = org(*searchtet); - checklen = distance(checkpt, newpoint); - if (checklen / longest > b->epsilon) { - epspp *= 1e-2; - count++; - continue; - } - } - break; - } - } - // Keep current search state for next searching. - recenttet = *searchtet; - - // Insert the point using the right routine - switch (intersect) { - case ONVERTEX: - // There's already a vertex there. Return in 'searchtet' a tetrahedron - // whose origin is the existing vertex. - if (b->verbose > 1) { - printf(" Not insert for duplicating point.\n"); - } - return DUPLICATEPOINT; - - case OUTSIDE: - if (b->verbose > 1) { - printf(" Not insert for locating outside the mesh.\n"); - } - return OUTSIDEPOINT; - - case ONEDGE: - // 'newpoint' falls on an edge. - splittetedge(newpoint, searchtet, flipqueue); - return SUCCESSONEDGE; - - case ONFACE: - // 'newpoint' falls on a face. - splittetface(newpoint, searchtet, flipqueue); - return SUCCESSONFACE; - - case INTETRAHEDRON: - // 'newpoint' falls inside a tetrahedron. - splittetrahedron(newpoint, searchtet, flipqueue); - return SUCCESSINTET; - } - - // Impossible case. - assert(0); - return OUTSIDEPOINT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// undosite() Undo the most recently point insertion. // -// // -// 'insresult' indicates in where the newpoint has been inserted, i.e., in a // -// tetrahedron, on a face, or on an edge. A correspoding routine will be // -// called to undo the point insertion. 'splittet' is a handle represent one // -// of the resulting tetrahedra, but it may be changed after transformation, // -// even may be dead. Four points 'torg', ... 'toppo' are the corners which // -// 'splittet' should have. On finish, 'newpoint' is not removed. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -undosite(enum insertsiteresult insresult, triface* splittet, point torg, - point tdest, point tapex, point toppo) -{ - // Set the four corners of 'splittet' exactly be 'torg', ... 'toppo'. - findface(splittet, torg, tdest, tapex); - if (oppo(*splittet) != toppo) { - symself(*splittet); - assert(oppo(*splittet) == toppo); - // The sym() operation may inverse the edge, correct it if so. - findedge(splittet, torg, tdest); - } - - // Unsplit the tetrahedron according to 'insresult'. - switch (insresult) { - case SUCCESSINTET: - // 'splittet' should be the face with 'newpoint' as its opposite. - unsplittetrahedron(splittet); - break; - case SUCCESSONFACE: - // 'splittet' should be the one of three splitted face with 'newpoint' - // as its apex. - unsplittetface(splittet); - break; - case SUCCESSONEDGE: - // 'splittet' should be the tet with destination is 'newpoint'. - unsplittetedge(splittet); - break; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// inserthullsite() Insert a point which is outside the convex hull. // -// // -// The inserting point 'inspoint' lies outside the tetrahedralization.'horiz'// -// is one of the convex hull faces which are visible from it. (You can image // -// that is is parallel to the horizon). To insert a point outside the convex // -// hull we have to enlarge current convex hull of the tetrahedralization for // -// including this point. This routine collects convex hull faces which are // -// visible from the inserting point, constructs new tetrahedra from these // -// faces and the inserting point. On return, 'inspoint' has become a vertex // -// of the augmented tetrahedralization. The convex hull has been updated. // -// 'flipcheckqueue' returns the old convex hull faces which may become non- // -// Delaunay and need be flipped. // -// // -// The caller can optionally provide two variables. 'hulllink' is a link for // -// saving newly created hull faces (containing 'inspoint') which may not // -// convex. Non-convex hull faces will be detected and finished by mounting // -// new tetrahedra with other hull vertex near them. 'worklist' is an array, // -// used for face matching. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -inserthullsite(point inspoint, triface* horiz, queue* flipqueue, - link* hulllink, int* worklist) -{ - link *myhulllink; - triface newtet, hullface; - triface oldhull, newhull; - point workpt[3]; - bool finished; - int *myworklist; - int idx, share; - int i, j, k; - - if (b->verbose > 1) { - printf(" Collect visible convex hull faces.\n"); - } - - // Check if the 'hulllink' is provided by the caller. - if (hulllink != (link *) NULL) { - myhulllink = (link *) NULL; - } else { - myhulllink = new link(sizeof(triface), NULL, 256); - hulllink = myhulllink; - } - - // Check if the 'worklist' is provided by the caller. - if (worklist != (int *) NULL) { - myworklist = (int *) NULL; - } else { - myworklist = new int[in->numberofpoints]; - for (i = 0; i < in->numberofpoints; i++) { - myworklist[i] = 0; - } - worklist = myworklist; - } - - adjustedgering(*horiz, CW); - // Create a new tetrahedron from 'horiz' and 'inspoint'. - maketetrahedron(&newtet); - setorg (newtet, org(*horiz)); - setdest(newtet, dest(*horiz)); - setapex(newtet, apex(*horiz)); - setoppo(newtet, inspoint); - // Make the connection of two tets. - bond(newtet, *horiz); - // 'horiz' becomes interior face. - enqueueflipface(*horiz, flipqueue); - // Add the three sides of 'newtet' to 'hulllink'. - fnext(newtet, hullface); - hulllink->add(&hullface); - enextfnext(newtet, hullface); - hulllink->add(&hullface); - enext2fnext(newtet, hullface); - hulllink->add(&hullface); - if (b->verbose > 3) { - printf(" Creating newtet "); - printtet(&newtet); - } - // Hull face number decreased caused by face bond() operation. - hullsize--; - - // Loop untill 'hulllink' is empty. Find other visible convex hull faces, - // create tetrahedra from them and 'inspoint'. Update 'hulllink'. - while (hulllink->len() > 0) { - // Remove the top hull face from the link, its apex is 'inspoint'. - hullface = * (triface *) hulllink->del(1); - // Get the neighbor convex hull face at the edge of 'hullface'. This is - // done by rotating faces around the edge from the inside until reach - // outer space (The rotation of faces should always terminate). - esym(hullface, oldhull); - while (fnextself(oldhull)) ; - // Is 'inspoint' visible from 'oldhull'? - if (orient3d(org(oldhull), dest(oldhull), apex(oldhull), inspoint) < 0.0) { - // 'oldhull' is visible from 'inspoint'. Create a new tetrahedron - // from them. - maketetrahedron(&newtet); - setorg(newtet, org(oldhull)); - setdest(newtet, dest(oldhull)); - setapex(newtet, apex(oldhull)); - setoppo(newtet, inspoint); - // Bond 'newtet' to 'oldhull'. - bond(newtet, oldhull); - // Hull face number decrease caused by bond(). - hullsize--; - // Bond 'newtet' to 'hullface'. - fnext(newtet, newhull); - bond(newhull, hullface); - // 'oldhull' becomes interior face. - enqueueflipface(oldhull, flipqueue); - // Check other two sides of 'newtet'. If one exists in 'hulllink'. - // remove the one in 'hulllink' (it is finished), otherwise, it - // becomes a new hull face, add it into 'hulllink'. - for (i = 0; i < 2; i++) { - // Get 'newhull' and set flags for its vertices. - if (i == 0) { - enextfnext(newtet, newhull); - } else { - enext2fnext(newtet, newhull); - } - workpt[0] = org(newhull); - workpt[1] = dest(newhull); - workpt[2] = apex(newhull); - for (k = 0; k < 3; k++) { - idx = pointmark(workpt[k]) - in->firstnumber; - worklist[idx] = 1; - } - // Search 'newhull' in 'hulllink'. - finished = false; - for (j = 0; j < hulllink->len() && !finished; j++) { - hullface = * (triface *) hulllink->getnitem(j + 1); - workpt[0] = org(hullface); - workpt[1] = dest(hullface); - workpt[2] = apex(hullface); - share = 0; - for (k = 0; k < 3; k++) { - idx = pointmark(workpt[k]) - in->firstnumber; - if (worklist[idx] == 1) { - share++; - } - } - if (share == 3) { - // Two faces are identical. Bond them togther. - bond(newhull, hullface); - // Remove 'hullface' from the link. - hulllink->del(j + 1); - finished = true; - } - } - if (!finished) { - // 'newhull' becomes a hull face, add it into 'hulllink'. - hulllink->add(&newhull); - } - // Clear used flags. - workpt[0] = org(newhull); - workpt[1] = dest(newhull); - workpt[2] = apex(newhull); - for (k = 0; k < 3; k++) { - idx = pointmark(workpt[k]) - in->firstnumber; - worklist[idx] = 0; - } - } - } else { - // 'hullface' becomes a convex hull face. - hullsize++; - // Let 'dummytet[0]' points to it for next point location. - dummytet[0] = encode(hullface); - } - } - - if (myhulllink != (link *) NULL) { - delete myhulllink; - } - if (myworklist != (int *) NULL) { - delete [] myworklist; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// collectcavtets() Collect all tetrahedra whose circumsphere conatining // -// the given point. // -// // -// This routine first locates the newpoint. Note the mesh may not be convex, // -// the locate() function may not find it. However, if we start from a very // -// close neighborhood, the function preciselocate() can be used. Here we // -// assume "recenttet" suggests such a starting point. 'cavtetlist' is a list // -// returns the tetrahedra. It is empty on input. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::collectcavtets(point newpoint, list* cavtetlist) -{ - triface starttet, neightet; - enum locateresult loc; - REAL sign; - int i, j; - - // First locate the newpoint. 'recenttet' suggests the starting point. - starttet = recenttet; - loc = preciselocate(newpoint, &starttet); - if (loc == OUTSIDE) { - // Principlly, the newpoint should lie inside or on the hull. But it - // may happen practically when the newpoint is just slightly lies - // outside the hull due to the rounding error. - loc = ONFACE; // This line is no meaning. - } - - // Now starttet contains newpoint. - infect(starttet); - cavtetlist->append(&starttet); - // Check the adjacent tet. - sym(starttet, neightet); - if (neightet.tet != dummytet) { - // For positive orientation that insphere() test requires. - adjustedgering(neightet, CW); - sign = insphere(org(neightet), dest(neightet), apex(neightet), - oppo(neightet), newpoint); - if (sign >= 0.0) { - // Add neightet into list. - infect(neightet); - cavtetlist->append(&neightet); - } - } - - // Find the other tetrahedra by looping in list. - for (i = 0; i < cavtetlist->len(); i++) { - starttet = * (triface *)(* cavtetlist)[i]; - // Check the other three neighbors of starttet. - adjustedgering(starttet, CCW); - for (j = 0; j < 3; j++) { - fnext(starttet, neightet); - symself(neightet); - if ((neightet.tet != dummytet) && !infected(neightet)) { - // For positive orientation that insphere() test requires. - adjustedgering(neightet, CW); - sign = insphere(org(neightet), dest(neightet), apex(neightet), - oppo(neightet), newpoint); - if (sign >= 0.0) { - // Add neightet into list. - infect(neightet); - cavtetlist->append(&neightet); - } - } - enextself(starttet); - } - } - - // Having find all tetrahedra, uninfect them before return. - for (i = 0; i < cavtetlist->len(); i++) { - starttet = * (triface *)(* cavtetlist)[i]; - assert(infected(starttet)); - uninfect(starttet); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// removetetbypeeloff() Remove a boundary tetrahedron by peeling off it // -// from the mesh. // -// // -// 'badtet' (abcd) is a boundary tetrahedron and going to be peeled off. abc // -// and bad are the outer boundary faces. To remove 'abcd' from the mesh is // -// simply detach its two inner faces (dca and cdb) from the adjoining tets. // -// A 2-to-2 flip is applied to transform subfaces abc and bad to dca and cdb.// -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::removetetbypeeloff(triface *badtet, queue* flipqueue) -{ - triface abcd, badc; - triface dcacasing, cdbcasing; - face abc, bad; - - if (b->verbose > 1) { - printf(" by peeling off it from boundary.\n"); - } - - abcd = *badtet; - adjustedgering(abcd, CCW); - // Get subfaces abc, bad. - fnext(abcd, badc); - esymself(badc); - tspivot(abcd, abc); - tspivot(badc, bad); - assert(abc.sh != dummysh && bad.sh != dummysh); - findedge(&abc, org(abcd), dest(abcd)); - findedge(&bad, org(badc), dest(badc)); - // Get the casing tets at the two inner sides of 'badtet'. - enextfnext(abcd, cdbcasing); - enext2fnext(abcd, dcacasing); - symself(cdbcasing); - symself(dcacasing); - assert(cdbcasing.tet != dummytet && dcacasing.tet != dummytet); - - // Do a 2-to-2 flip on abc and bad, transform abc->dca, bad->cdb. - flip22sub(&abc, NULL); - // Detach abcd from its inner sides. - dissolve(cdbcasing); - dissolve(dcacasing); - // Make its inner sides be boundary. - tsbond(cdbcasing, bad); - tsbond(dcacasing, abc); - // Delete abcd. - tetrahedrondealloc(abcd.tet); - - if (flipqueue != (queue *) NULL) { - // Edge cd maybe non-Delaunay. - adjustedgering(cdbcasing, CCW); - fnextself(cdbcasing); - enqueueflipface(cdbcasing, flipqueue); - adjustedgering(dcacasing, CCW); - fnextself(dcacasing); - enqueueflipface(dcacasing, flipqueue); - // Do flipping. - flip(flipqueue, NULL); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// removetetbyflip32() Remove a tetrahedron by doing a 3-to-2 flip. // -// // -// 'badtet' (abcd) is the bad tetrahedron which is going to be removed by a // -// 3-to-2 flip. abc represents one of the internal faces, bad is another. // -// If abc and bad are subfaces, a 2-to-2 flip is performed to transform abc, // -// bad into dca, cdb, before the 3-to-2 flip is applying. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::removetetbyflip32(triface *badtet, queue* flipqueue) -{ - triface abcd, badc; - triface cdab, dcba; - triface baccasing, abdcasing; - triface dcacasing, cdbcasing; - face abc, bad; - - if (b->verbose > 1) { - printf(" by doing a 3-to-2 flip.\n"); - } - - abcd = *badtet; - adjustedgering(abcd, CCW); - fnext(abcd, badc); - esymself(badc); - sym(abcd, baccasing); - sym(badc, abdcasing); - assert(baccasing.tet != dummytet && abdcasing.tet != dummytet); - assert(oppo(baccasing) == oppo(abdcasing)); - - // Get subfaces abc, bad. - tspivot(abcd, abc); - tspivot(badc, bad); - if (abc.sh != dummysh) { - // Because ab should not be a subsegment. - assert(bad.sh != dummysh); - findedge(&abc, org(abcd), dest(abcd)); - findedge(&bad, org(badc), dest(badc)); - // Detach abc, bad from tetrahedra at both sides. - stdissolve(abc); - stdissolve(bad); - sesymself(abc); - sesymself(bad); - stdissolve(abc); - stdissolve(bad); - sesymself(abc); - sesymself(bad); - // Detach tetrahedra witch hold abc and bad. - tsdissolve(abcd); - tsdissolve(badc); - tsdissolve(baccasing); - tsdissolve(abdcasing); - // Perform a 2-to-2 flip on abc, bad, transform abc->dca, bad->cdb. - flip22sub(&abc, NULL); - // Insert the flipped subfaces abc and bad into tetrahedra. - enextfnext(abcd, dcba); // dcba = bcda - esymself(dcba); // dcba = cbda - enext2fnext(abcd, cdab); // cdab = cadb - esymself(cdab); // cdab = acdb - findedge(&abc, org(cdab), dest(cdab)); - tsbond(cdab, abc); - findedge(&bad, org(dcba), dest(dcba)); - tsbond(dcba, bad); - // Bond the other sides of cdab, dcba, they may outer space. - sym(cdab, dcacasing); - sym(dcba, cdbcasing); - sesymself(abc); - sesymself(bad); - tsbond(dcacasing, abc); - tsbond(cdbcasing, bad); - } - // Do a 3-to-2 flip on face abc to remove tetrahedron abcd. - flip32(&abcd, flipqueue); - // Do flipping if necessary. - if (flipqueue != (queue *) NULL) { - flip(flipqueue, NULL); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// removetetbycflips() Remove a tetrahedron by a combination of flips. // -// // -// 'badtet' (abcd) is the tetrahedron which is going to be removed. It can't // -// be removed simply by a 3-to-2 flip. // -// // -// A flipstack is used for remembering flips have done, in case falure, we // -// can restore the original state. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::removetetbycflips(triface *badtet, queue* flipqueue) -{ - triface abcd; - triface bacd, baec; - triface abdc, abfd; - flipstacker *lastflip, *newflip; - enum fliptype fc; - int flipcount; - - abcd = *badtet; - adjustedgering(abcd, CCW); - esym(abcd, bacd); - if (issymexist(&bacd)) { - fnext(bacd, baec); - assert(baec.tet != dummytet); - } else { - // This side is empty. But the tet can not be peeled off. - return false; - } - fnext(abcd, abdc); - if (issymexist(&abdc)) { - fnext(abdc, abfd); - assert(abfd.tet != dummytet); - } else { - // This side is empty. But the tet can not be peeled off. - return false; - } - assert(apex(baec) != apex(abfd)); - - if (b->verbose > 1) { - printf(" by doing a combination of flips.\n"); - } - - // Initialize the stack of the flip sequence. - flipstackers->restart(); - lastflip = (flipstacker *) NULL; - - // Flip faces above abc. - flipcount = 0; - do { - assert(baec.tet != dummytet); - fc = categorizeface(baec); - if (fc == T23) { - flip23(&baec, NULL); - } else if (fc == T22 || fc == T44) { - flip22(&baec, NULL); - } - if (fc == T23 || fc == T22 || fc == T44) { - // Push the flipped face into stack. - newflip = (flipstacker *) flipstackers->alloc(); - newflip->flippedface = baec; - newflip->fc = fc; - newflip->forg = org(baec); - newflip->fdest = dest(baec); - newflip->fapex = apex(baec); - newflip->prevflip = lastflip; - lastflip = newflip; - // Check the flipped side. - fnext(bacd, baec); - if (apex(baec) == apex(abfd)) { - // We have made 'abcd' flipable. - removetetbyflip32(&abcd, flipqueue); - return true; - } - flipcount++; - } else { - // Face is unflipable, break the loop. - break; - } - } while (flipcount < 16); - - // Flip faces above bad. - fnext(bacd, baec); - assert(apex(abfd) != apex(baec)); - flipcount = 0; - do { - assert(abfd.tet != dummytet); - fc = categorizeface(abfd); - if (fc == T23) { - flip23(&abfd, NULL); - } else if (fc == T22 || fc == T44) { - flip22(&abfd, NULL); - } - if (fc == T23 || fc == T22 || fc == T44) { - // Push the flipped face into stack. - newflip = (flipstacker *) flipstackers->alloc(); - newflip->flippedface = abfd; - newflip->fc = fc; - newflip->forg = org(abfd); - newflip->fdest = dest(abfd); - newflip->fapex = apex(abfd); - newflip->prevflip = lastflip; - lastflip = newflip; - // Check the flipped side. - fnext(abdc, abfd); - if (apex(abfd) == apex(baec)) { - // We have made 'abcd' flipable. - removetetbyflip32(&abcd, flipqueue); - return true; - } - flipcount++; - } else { - // Face is unflipable, break the loop. - break; - } - } while (flipcount < 16); - - // Unable to use a combination of flips. - if (b->verbose > 1) { - printf(" Not success.\n"); - } - // Restore the flips we've done. - undoflip(lastflip); - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// removebadtet() Remove a bad tetrahedron from the mesh. // -// // -// 'bt' indicates the type of the 'badtet', assume it is abcd. If it is a // -// SLIVER, ab and cd are the two diagonal edges; if it is a CAP, abc is the // -// bottom face (the projection of d is inside abc); if it is ILLEGAL, abc, // -// bad are the two boundary subfaces (which are on the same facet). // -// // -// This routine first classifies the type of operation can be used to remove // -// 'badtet', e.g. simpley do a 3-to-2 flip, or combine several flips. Then // -// do the corresponding flip operation. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -removebadtet(enum badtettype bt, triface *badtet, queue* flipqueue) -{ - triface abcd, badc, cdab, dcba; - triface bcdcasing, cadcasing; - triface baccasing, abdcasing; - face ab, cd; - point pa, pb, pc, pd; - - abcd = *badtet; - adjustedgering(abcd, CCW); - pa = org(abcd); - pb = dest(abcd); - pc = apex(abcd); - pd = oppo(abcd); - - if (b->verbose > 1) { - printf(" Remove tetrahedron (%d, %d, %d, %d).\n", pointmark(pa), - pointmark(pb), pointmark(pc), pointmark(pd)); - } - - // Get the casing tets at the four sides of 'badtet'. - fnext(abcd, badc); - esymself(badc); - sym(abcd, baccasing); - sym(badc, abdcasing); - tsspivot(&abcd, &ab); - enextfnext(abcd, dcba); // dcba = bcda - esymself(dcba); // dcba = cbda - enext2self(dcba); - enext2fnext(abcd, cdab); // cdab = cadb - esymself(cdab); // cdab = acdb - enextself(cdab); - sym(dcba, bcdcasing); - sym(cdab, cadcasing); - tsspivot(&dcba, &cd); - - if (ab.sh != dummysh && cd.sh != dummysh) { - printf("Warning: Two subsegments (%d, %d), (%d, %d) cross in one tet.\n", - pointmark(pa), pointmark(pb), pointmark(pc), pointmark(pd)); - return false; - } - - if (bt == ILLEGAL || bt == SLIVER) { - if (cd.sh == dummysh) { - // Test if edge 'cd' is removeable. - if (bcdcasing.tet == dummytet && cadcasing.tet == dummytet) { - removetetbypeeloff(&cdab, flipqueue); - return true; - } - if (oppo(bcdcasing) == oppo(cadcasing)) { - removetetbyflip32(&cdab, flipqueue); - return true; - } - } - if (ab.sh == dummysh) { - // Test if edge 'ab' is removeable. - if (baccasing.tet == dummytet && abdcasing.tet == dummytet) { - removetetbypeeloff(&abcd, flipqueue); - return true; - } - if (oppo(baccasing) == oppo(abdcasing)) { - removetetbyflip32(&abcd, flipqueue); - return true; - } - } - // 'badtet' can not be easily removed, try to remove it by a combination - // of flips. - if (cd.sh == dummysh) { - if (removetetbycflips(&cdab, flipqueue)) { - return true; - } - } - if (ab.sh == dummysh) { - if (removetetbycflips(&abcd, flipqueue)) { - return true; - } - } - if (b->verbose) { - printf("Warning: Unable to remove bad tet (%d, %d, %d, %d).\n", - pointmark(pa), pointmark(pb), pointmark(pc), pointmark(pd)); - } - return false; - } - - return false; -} - -// -// End of mesh transformation routines -// - -// -// Begin of incremental flip Delaunay triangulation routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// incrflipinit() Create an initial tetrahedralization. // -// // -// The initial tetrahedralization only contains one tetrahedron formed from // -// four affinely linear independent vertices from the input point set. // -// // -// 'insertqueue' returns the rest of vertices of the input point set. These // -// vertices will be inserted one by one in the later step. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::incrflipinit(queue* insertqueue) -{ - triface newtet; - point *plist, pointloop; - point pa, pb, pc, pd; - REAL det; - int count; - int i, j; - - if (b->verbose > 1) { - printf(" Constructing an initial tetrahedron.\n"); - } - - // Create a point list and initialize it. - plist = new point[in->numberofpoints]; - i = 0; - points->traversalinit(); - pointloop = pointtraverse(); - while (pointloop != (point) NULL) { - plist[i++] = pointloop; - pointloop = pointtraverse(); - } - assert(i == in->numberofpoints); - - if (b->dopermute) { - // Do permutation. Initialize the random seed. - randomseed = b->srandseed; - for (i = 0; i < in->numberofpoints; i++) { - // Get a index j (from 0 to in->numberofpoints - i - 1). - j = (int) randomnation(in->numberofpoints - i); - // Exchange the i-th point and (j + i)-th point. - pointloop = plist[j + i]; - plist[j + i] = plist[i]; - plist[i] = pointloop; - } - } - - // Set the plist into insertqueue. - if (!insertqueue->empty()) { - insertqueue->clear(); - } - for (i = 0; i < in->numberofpoints; i++) { - pointloop = plist[i]; - insertqueue->push(&pointloop); - } - delete [] plist; - - // Get the first two point 'pa'. - pa = * (point *) insertqueue->pop(); - - // Get the second point 'pb', which is not identical with 'pa'. - count = 0; - pb = * (point *) insertqueue->pop(); - while ((pb != (point) NULL) && (count < in->numberofpoints)) { - if ((pb[0] == pa[0]) && (pb[1] == pa[1]) && (pb[2] == pa[2])) { - // 'pb' is identical to 'pa', skip it. - insertqueue->push(&pb); - } else { - break; - } - pb = * (point *) insertqueue->pop(); - count++; - } - if (pb == (point) NULL) { - printf("\nAll points are identical, no triangulation be constructed.\n"); - exit(1); - } - - // Get the third point 'pc', which is not collinear with 'pa' and 'pb'. - count = 0; - pc = * (point *) insertqueue->pop(); - while ((pc != (point) NULL) && (count < in->numberofpoints)) { - if (iscollinear(pa, pb, pc, (b->epsilon * 1e-2))) { - // They are collinear or identical, put it back to queue. - insertqueue->push(&pc); - } else { - break; - } - pc = * (point *) insertqueue->pop(); - count++; - } - if (pc == (point) NULL) { - printf("\nAll points are collinear, no triangulation be constructed.\n"); - exit(1); - } - - // Get the fourth point which is not coplanar with pa, pb, and pc. - count = 0; - pd = * (point *) insertqueue->pop(); - while ((pd != (point) NULL) && (count < in->numberofpoints)) { - det = orient3d(pa, pb, pc, pd); - if (det == 0.0) { - // They are coplanar or identical, put it back to queue. - insertqueue->push(&pd); - } else { - break; - } - pd = * (point *) insertqueue->pop(); - count++; - } - if (pd == (point) NULL) { - printf("\nAll points are coplanar, no triangulation be constructed.\n"); - exit(1); - } - if (det > 0.0) { - pointloop = pa; pa = pb; pb = pointloop; - } - - // Create the tetrahedron with corners pa, pb, pc and pd. - maketetrahedron(&newtet); - setorg(newtet, pa); - setdest(newtet, pb); - setapex(newtet, pc); - setoppo(newtet, pd); - // Set the vertices be FREEVOLVERTEX to indicate they belong to the mesh. - setpointtype(pa, FREEVOLVERTEX); - setpointtype(pb, FREEVOLVERTEX); - setpointtype(pc, FREEVOLVERTEX); - setpointtype(pd, FREEVOLVERTEX); - // Bond to 'dummytet' for point location. - dummytet[0] = encode(newtet); - if (b->verbose > 3) { - printf(" Creating tetra "); - printtet(&newtet); - } - // At init, all faces of this tet are hull faces. - hullsize = 4; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// incrflipdelaunay() Construct a delaunay tetrahedrization from a set of // -// 3D points using the incremental flip algorithm. // -// // -// The incremental flip algorithm is described in the paper of Edelsbrunner // -// and Shah, "Incremental Topological Flipping Works for Regular Triangulat- // -// ions", Algorithmica 15: 223-241, 1996. It can be described as follows: // -// // -// S be a set of points in 3D, Let 4 <= i <= n and assume that the // -// Delaunay triangulation of the first i-1 points in S is already // -// constructed; call it D(i-1). Add the i-th point p_i (belong to S) to // -// the triangulation,and restore Delaunayhood by flipping; this result // -// in D(i). Repeat this procedure until i = n. // -// // -// This strategy always leads to the Ddelaunay triangulation of a point set. // -// The return value is the number of convex hull faces of this point set. // -// // -/////////////////////////////////////////////////////////////////////////////// - -long tetgenmesh::incrflipdelaunay() -{ - triface starttet; - point pointloop; - queue *flipqueue; - queue *insertqueue; - link *hulllink; - enum insertsiteresult insres; - int *worklist, i; - - if (!b->quiet) { - if (!b->noflip) { - printf("Constructing Delaunay tetrahedrization.\n"); - } else { - printf("Constructing tetrahedrization.\n"); - } - } - - // Initialize 'flipqueue'. - flipqueue = new queue(sizeof(badface)); - // Create a queue for all inserting points. - insertqueue = new queue(sizeof(point*), in->numberofpoints); - // Create a 'hulllink' used in inserthullsite(). - hulllink = new link(sizeof(triface), NULL, 256); - // Create and initialize 'worklist' used in inserthullsite(). - worklist = new int[in->numberofpoints]; - for (i = 0; i < in->numberofpoints; i++) worklist[i] = 0; - // Initialize global counters. - flip23s = flip32s = flip22s = flip44s = 0; - - // Algorithm starts from here. - - // Construct an initial tetrahedralization and fill 'insertqueue'. - incrflipinit(insertqueue); - - // Loop untill all points are inserted. - while (!insertqueue->empty()) { - pointloop = * (point *) insertqueue->pop(); - // It will become a mesh point unless it duplicates an existing point. - setpointtype(pointloop, FREEVOLVERTEX); - // Try to insert the point first. - starttet.tet = (tetrahedron *) NULL; - insres = insertsite(pointloop, &starttet, false, flipqueue); - if (insres == OUTSIDEPOINT) { - // Point locates outside the convex hull. - inserthullsite(pointloop, &starttet, flipqueue, hulllink, worklist); - } else if (insres == DUPLICATEPOINT) { - if (b->object != tetgenbehavior::STL) { - if (!b->quiet) { - printf("Warning: Point %d is identical with point %d.\n", - pointmark(pointloop), pointmark(org(starttet))); - } - // Count the number of duplicated points. - dupverts++; - } - // Remember it is a duplicated point. - setpointtype(pointloop, DUPLICATEDVERTEX); - if (b->plc || b->refine) { - // Set a pointer to the point it duplicates. - setpoint2pt(pointloop, org(starttet)); - } - } - if (!b->noflip) { - // Call flip algorithm to recover Delaunayness. - flip(flipqueue, NULL); - } else { - // Not perform flip. - flipqueue->clear(); - } - } - - delete flipqueue; - delete insertqueue; - delete hulllink; - delete [] worklist; - - if (!b->noflip && b->verbose) { - printf(" Total flips: %ld, where T23 %ld, T32 %ld, T22 %ld, T44 %ld\n", - flip23s + flip32s + flip22s + flip44s, - flip23s, flip32s, flip22s, flip44s); - } - - return hullsize; -} - -// -// End of incremental flip Delaunay triangulation routines -// - -// -// Begin of surface triangulation routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// The lift points // -// // -// A 'lifting point' of a facet is a point which lies exactly non-coplanar // -// with the plane containing that facet. With such an additional point, the // -// three-dimensional geometric predicates (orient3d, insphere) can be used // -// to substitute the lower dimensional predicates (orient2d, incircle). The // -// advantage is there is no need to project 3D points back into 2D, so the // -// rounding error can be avoid. // -// // -// These points are calculated during the initialization of triangulating // -// the facets. It is important to orient subfaces of the same facet to have // -// the same orientation with respect to its lift point. This way guarantees // -// the test results are consistent. We take the convention that the lift // -// point of a facet always lies above the CCW edge rings of subfaces of the // -// same facet. By this convention, given three points a, b, and c in a facet,// -// we say c has the counterclockwise order with ab is corresponding to say // -// that c is below the plane abp, where p is the lift point. // -// // -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// // -// locatesub() Find a point in the surface mesh. // -// // -// Searching begins from the input 'searchsh', it should be a handle on the // -// convex hull of the facet triangulation. // -// // -// On completion, 'searchsh' is a subface that contains 'searchpoint'. // -// - Returns ONVERTEX if the point lies on an existing vertex. 'searchsh' // -// is a handle whose origin is the existing vertex. // -// - Returns ONEDGE if the point lies on a mesh edge. 'searchsh' is a // -// handle whose primary edge is the edge on which the point lies. // -// - Returns ONFACE if the point lies strictly within a subface. // -// 'searchsh' is a handle on which the point lies. // -// - Returns OUTSIDE if the point lies outside the triangulation. // -// // -// WARNING: This routine is designed for convex triangulations, and will not // -// not generally work after the holes and concavities have been carved. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::locateresult tetgenmesh:: -locatesub(point searchpt, face* searchsh, point abovept) -{ - face backtracksh, checkedge; - point forg, fdest, fapex, liftpoint; - REAL orgori, destori; - int moveleft, i; - - if (searchsh->sh == dummysh) { - searchsh->shver = 0; - spivotself(*searchsh); - assert(searchsh->sh != dummysh); - } - - // Set the liftpoint. (Note, the liftpoint is always above the face.) - if (abovept == (point) NULL) { - liftpoint = getliftpoint(shellmark(*searchsh)); - adjustedgering(*searchsh, CCW); - } else { - liftpoint = abovept; - forg = sorg(*searchsh); - fdest = sdest(*searchsh); - fapex = sapex(*searchsh); - orgori = orient3d(forg, fdest, fapex, liftpoint); - assert(orgori != 0.0); - if (orgori > 0.0) { - sesymself(*searchsh); - } - } - - // Orient 'searchsh' so that 'searchpt' is below it (i.e., searchpt has - // CCW orientation with respect to searchsh in plane). Such edge - // should always exist. Save it as (forg, fdest). - for (i = 0; i < 3; i++) { - forg = sorg(*searchsh); - fdest = sdest(*searchsh); - if (orient3d(forg, fdest, liftpoint, searchpt) > 0.0) break; - senextself(*searchsh); - } - assert(i < 3); - - while (1) { - fapex = sapex(*searchsh); - // Check whether the apex is the point we seek. - if (fapex[0] == searchpt[0] && fapex[1] == searchpt[1] && - fapex[2] == searchpt[2]) { - senext2self(*searchsh); - return ONVERTEX; - } - // Does the point lie on the other side of the line defined by the - // triangle edge opposite the triangle's destination? - destori = orient3d(forg, fapex, liftpoint, searchpt); - // Does the point lie on the other side of the line defined by the - // triangle edge opposite the triangle's origin? - orgori = orient3d(fapex, fdest, liftpoint, searchpt); - if (destori > 0.0) { - moveleft = 1; - } else { - if (orgori > 0.0) { - moveleft = 0; - } else { - // The point must be on the boundary of or inside this triangle. - if (destori == 0.0) { - senext2self(*searchsh); - return ONEDGE; - } - if (orgori == 0.0) { - senextself(*searchsh); - return ONEDGE; - } - return ONFACE; - } - } - // Move to another triangle. Leave a trace `backtracksh' in case - // walking off a boundary of the triangulation. - if (moveleft) { - senext2(*searchsh, backtracksh); - fdest = fapex; - } else { - senext(*searchsh, backtracksh); - forg = fapex; - } - spivot(backtracksh, *searchsh); - // Check for walking right out of the triangulation. - if (searchsh->sh == dummysh) { - // Go back to the last triangle. - *searchsh = backtracksh; - return OUTSIDE; - } - // To keep the same orientation wrt. liftpoint. - // adjustedgering(*searchsh, CCW); - if (sorg(*searchsh) != forg) { - sesymself(*searchsh); - } - assert((sorg(*searchsh) == forg) && (sdest(*searchsh) == fdest)); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// flipsub() Flip all non-Delaunay edges in a given queue of subfaces. // -// // -// Assumpation: Current triangulation is non-Delaunay after inserting a // -// point or performing a flip operation, all possibly non-Delaunay edges are // -// in 'facequeue'. The return value is the total number of flips done during // -// this invocation. // -// // -/////////////////////////////////////////////////////////////////////////////// - -long tetgenmesh::flipsub(queue* flipqueue) -{ - badface *qedge; - face flipedge, symedge, bdedge; - point pa, pb, pc, pd, liftpoint; - REAL sign; - int edgeflips; - - if (b->verbose > 1) { - printf(" Start do edge queue: %ld edges.\n", flipqueue->len()); - } - - edgeflips = 0; - - while ((qedge = (badface *) flipqueue->pop()) != NULL) { - flipedge = qedge->ss; - if (flipedge.sh == dummysh) continue; - if ((sorg(flipedge) != qedge->forg) || - (sdest(flipedge) != qedge->fdest)) continue; - sspivot(flipedge, bdedge); - if (bdedge.sh != dummysh) continue; // Can't flip a subsegment. - spivot(flipedge, symedge); - if (symedge.sh == dummysh) continue; // Can't flip a hull edge. - pa = sorg(flipedge); - pb = sdest(flipedge); - pc = sapex(flipedge); - pd = sapex(symedge); - liftpoint = getliftpoint(shellmark(flipedge)); - // Check whether pd lies inside the circumcircle of pa, pb, pc or not. - sign = insphere(pa, pb, pc, liftpoint, pd) - * orient3d(pa, pb, pc, liftpoint); - if (sign > 0.0) { - // Flip the non-Delaunay edge. - flip22sub(&flipedge, flipqueue); - edgeflips++; - } - } - - if (b->verbose > 1) { - printf(" Total %d flips.\n", edgeflips); - } - - return edgeflips; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// incrflipinitsub() Create a initial triangulation. // -// // -// The initial triangulation only consists of one triangle formed by three // -// non-collinear points. 'facetidx' is the index of the facet in 'facetlist' // -// (starts from 1) of the tetgenio structure; 'ptlist' is a list of indices // -// of the facet vertices; 'idx2verlist' is a map from indices to vertices. // -// // -// The 'lift point' of this facet is calculated. If not all vertices of the // -// facet are collinear, such point is found by lifting the centroid of the // -// set of vertices for a certain distance along the normal of this facet. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -incrflipinitsub(int facetidx, list* ptlist, point* idx2verlist) -{ - face newsh; - point pt1, pt2, pt3; - point liftpoint, ptloop; - REAL cent[3], norm[3]; - REAL v1[3], v2[3]; - REAL smallcos, cosa; - REAL liftdist, len, vol; - int smallidx; - int idx, i; - - if (ptlist->len() > 3) { - // Find a (non-degenerate) vector from the vertex set. - idx = * (int *) (* ptlist)[0]; - pt1 = idx2verlist[idx - in->firstnumber]; - len = 0.0; - // Loop the set of vertices until a not too small edge be found. - for (i = 1; i < ptlist->len(); i++) { - idx = * (int *) (* ptlist)[i]; - pt2 = idx2verlist[idx - in->firstnumber]; - v1[0] = pt2[0] - pt1[0]; - v1[1] = pt2[1] - pt1[1]; - v1[2] = pt2[2] - pt1[2]; - len = sqrt(dot(v1, v1)); - if ((len / longest) > (b->epsilon * 1e+2)) break; - } - // Remember this size as lift distance. - liftdist = len; - // 'v1' is a reasonable vector, normalize it. - for (i = 0; i < 3; i++) v1[i] /= len; - // Continue to find another (non-degenerate) vector, which forms an - // angle with v1 most close to 90 degree. - smallcos = 1.0; // The cosine value of 0 degree. - for (i = 1; i < ptlist->len(); i++) { - idx = * (int *) (* ptlist)[i]; - pt3 = idx2verlist[idx - in->firstnumber]; - if (pt3 == pt2) continue; // Skip the same point. - v2[0] = pt3[0] - pt1[0]; - v2[1] = pt3[1] - pt1[1]; - v2[2] = pt3[2] - pt1[2]; - len = sqrt(dot(v2, v2)); - if (len > 0.0) { // v2 is not too small. - cosa = fabs(dot(v1, v2)) / len; - if (cosa < smallcos) { - smallidx = idx; - smallcos = cosa; - } - } else { // len == 0.0, two identical points defined in a facet. - printf("Warning: Facet %d has two identical vertices: %d, %d.\n", - facetidx, pointmark(pt1), pointmark(pt3)); - return false; // Invalid polygon, do not procced. - } - } - if (smallcos == 1.0) { - // The input set of vertices is not a good set (or nearly degenerate). - printf("Warning: Facet %d with vertices: ", facetidx); - for (i = 0; i < 3; i++) { - idx = * (int *) (* ptlist)[i]; - ptloop = idx2verlist[idx - in->firstnumber]; - printf("%d ", pointmark(ptloop)); - } - printf("... is degenerate.\n"); - return false; // Invalid polygon, do not procced. - } - // Get the right point to form v2. - pt3 = idx2verlist[smallidx - in->firstnumber]; - assert(pt3 != pt2); - v2[0] = pt3[0] - pt1[0]; - v2[1] = pt3[1] - pt1[1]; - v2[2] = pt3[2] - pt1[2]; - len = sqrt(dot(v2, v2)); - assert(len > 0.0); - // Remember this size as lift distance. - liftdist = (liftdist > len ? liftdist : len); - // 'v2' is a reasonable vector, normalize it. - for (i = 0; i < 3; i++) v2[i] /= len; - } else { - // There are only three vertices of this facet (a triangle). - idx = * (int *) (* ptlist)[0]; - pt1 = idx2verlist[idx - in->firstnumber]; - idx = * (int *) (* ptlist)[1]; - pt2 = idx2verlist[idx - in->firstnumber]; - idx = * (int *) (* ptlist)[2]; - pt3 = idx2verlist[idx - in->firstnumber]; - v1[0] = pt2[0] - pt1[0]; - v1[1] = pt2[1] - pt1[1]; - v1[2] = pt2[2] - pt1[2]; - len = sqrt(dot(v1, v1)); - if (len == 0.0) { - printf("Warning: Facet %d has two identical vertices: %d, %d.\n", - facetidx, pointmark(pt1), pointmark(pt2)); - return false; // Invalid polygon, do not procced. - } - // Remember this size as lift distance. - liftdist = len; - // 'v1' is a reasonable vector, normalize it. - for (i = 0; i < 3; i++) v1[i] /= len; - v2[0] = pt3[0] - pt1[0]; - v2[1] = pt3[1] - pt1[1]; - v2[2] = pt3[2] - pt1[2]; - len = sqrt(dot(v2, v2)); - if (len == 0.0) { - printf("Warning: Facet %d has two identical vertices: %d, %d.\n", - facetidx, pointmark(pt1), pointmark(pt3)); - return false; // Invalid polygon, do not procced. - } - // Remember this size as lift distance. - liftdist = (liftdist > len ? liftdist : len); - // 'v2' is a reasonable vector, normalize it. - for (i = 0; i < 3; i++) v2[i] /= len; - } - // Calculate the unit normal of this facet. - cross(v1, v2, norm); - - // Calculate the centroid point of the vertex set. At the same time, check - // whether vertices of this facet are roughly coplanar or not. - cent[0] = cent[1] = cent[2] = 0.0; - for (i = 0; i < ptlist->len(); i++) { - idx = * (int *) (* ptlist)[i]; - ptloop = idx2verlist[idx - in->firstnumber]; - if (ptlist->len() > 3) { - vol = orient3d(pt1, pt2, pt3, ptloop); - if (vol != 0.0) { - if (!iscoplanar(pt1, pt2, pt3, ptloop, vol, b->epsilon * 1e+3)) { - printf("Warning: Facet %d has a non-coplanar vertex %d.\n", - facetidx, pointmark(ptloop)); - // This is not a fatal problem, we still can procced. - } - } - } - cent[0] += ptloop[0]; - cent[1] += ptloop[1]; - cent[2] += ptloop[2]; - } - for (i = 0; i < 3; i++) cent[i] /= ptlist->len(); - // Calculate the lifting point of the facet. It is lifted from 'cent' - // along the normal direction with a certain ditance. - liftpoint = getliftpoint(facetidx); - for (i = 0; i < 3; i++) { - liftpoint[i] = cent[i] + liftdist * norm[i]; - } - - // Create the initial triangle. The liftpoint is above (pt1, pt2, pt3). - makeshellface(subfaces, &newsh); - setsorg(newsh, pt1); - setsdest(newsh, pt2); - setsapex(newsh, pt3); - // Remeber the facet it belongs to. - setshellmark(newsh, facetidx); - // Set vertices be type FACETVERTEX to indicate they belong to a facet. - setpointtype(pt1, FACETVERTEX); - setpointtype(pt2, FACETVERTEX); - setpointtype(pt3, FACETVERTEX); - // Bond this subface to 'dummysh' for point location routine. - dummysh[0] = sencode(newsh); - - return true; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// collectvisiblesubs() Collect convex hull edges which are visible from // -// the inserting point. Construct new subfaces from // -// these edges and the point. // -// // -// 'facetidx' is the index of the facet in 'in->facetlist' (starts from 1), // -// 'inspoint' is located outside current triangulation, 'horiz' is the hull // -// edge it is visible. 'flipqueue' returns the visible hull edges which have // -// become interior edges on completion of this routine. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -collectvisiblesubs(int facetidx, point inspoint, face* horiz, queue* flipqueue) -{ - face newsh, hullsh; - face rightsh, leftsh, spinedge; - point horg, hdest, liftpoint; - bool aboveflag; - - liftpoint = getliftpoint(facetidx); - - // Create a new subface above 'horiz'. - adjustedgering(*horiz, CCW); - makeshellface(subfaces, &newsh); - setsorg(newsh, sdest(*horiz)); - setsdest(newsh, sorg(*horiz)); - setsapex(newsh, inspoint); - setshellmark(newsh, facetidx); - // Make the connection. - sbond(newsh, *horiz); - // 'horiz' becomes interior edge. - enqueueflipedge(*horiz, flipqueue); - - // Finish the hull edges at the right side of the newsh. - hullsh = *horiz; - while (1) { - senext(newsh, rightsh); - // Get the right hull edge of 'horiz' by spinning inside edges around - // the origin of 'horiz' until reaching the 'dummysh'. - spinedge = hullsh; - do { - hullsh = spinedge; - senext2self(hullsh); - spivot(hullsh, spinedge); - adjustedgering(spinedge, CCW); - } while (spinedge.sh != dummysh); - // Test whether 'inspoint' is visible from 'hullsh'. - horg = sorg(hullsh); - hdest = sdest(hullsh); - aboveflag = orient3d(horg, hdest, liftpoint, inspoint) < 0.0; - if (aboveflag) { - // It's a visible hull edge. - makeshellface(subfaces, &newsh); - setsorg(newsh, sdest(hullsh)); - setsdest(newsh, sorg(hullsh)); - setsapex(newsh, inspoint); - setshellmark(newsh, facetidx); - // Make the connection. - sbond(newsh, hullsh); - senext2(newsh, leftsh); - sbond(leftsh, rightsh); - // 'horiz' becomes interior edge. - enqueueflipedge(hullsh, flipqueue); - } else { - // 'rightsh' is a new hull edge. - dummysh[0] = sencode(rightsh); - break; - } - } - - // Finish the hull edges at the left side of the newsh. - hullsh = *horiz; - spivot(*horiz, newsh); - while (1) { - senext2(newsh, leftsh); - // Get the left hull edge of 'horiz' by spinning edges around the - // destination of 'horiz'. - spinedge = hullsh; - do { - hullsh = spinedge; - senextself(hullsh); - spivot(hullsh, spinedge); - adjustedgering(spinedge, CCW); - } while (spinedge.sh != dummysh); - // Test whether 'inspoint' is visible from 'hullsh'. - horg = sorg(hullsh); - hdest = sdest(hullsh); - aboveflag = orient3d(horg, hdest, liftpoint, inspoint) < 0.0; - if (aboveflag) { - // It's a visible hull edge. - makeshellface(subfaces, &newsh); - setsorg(newsh, sdest(hullsh)); - setsdest(newsh, sorg(hullsh)); - setsapex(newsh, inspoint); - setshellmark(newsh, facetidx); - // Make the connection. - sbond(newsh, hullsh); - senext(newsh, rightsh); - sbond(rightsh, leftsh); - // 'horiz' becomes interior edge. - enqueueflipedge(hullsh, flipqueue); - } else { - // 'leftsh' is a new hull edge. - dummysh[0] = sencode(leftsh); - break; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// incrflipdelaunaysub() Create a Delaunay triangulation from a 3D point // -// set using the incremental flip algorithm. // -// // -// 'facetidx' is the index of the facet in 'in->facetlist' (starts from 1), // -// 'ptlist' is the index list of the vertices of the facet, 'idx2verlist' is // -// a map from indices to vertices. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -incrflipdelaunaysub(int facetidx, list* ptlist, point* idx2verlist, - queue* flipqueue) -{ - face startsh; - point pointloop; - enum locateresult loc; - int idx, i; - - for (i = 1; i < ptlist->len(); i++) { - idx = * (int *) (* ptlist)[i]; - pointloop = idx2verlist[idx - in->firstnumber]; - // Set vertices be type FACETVERTEX to indicate they belong to a facet. - setpointtype(pointloop, FACETVERTEX); - startsh.sh = dummysh; - loc = locatesub(pointloop, &startsh, NULL); - if (loc == ONVERTEX) continue; - if (loc == ONFACE) { - splitsubface(pointloop, &startsh, flipqueue); - } else if (loc == ONEDGE) { - splitsubedge(pointloop, &startsh, flipqueue); - } else if (loc == OUTSIDE) { - collectvisiblesubs(facetidx, pointloop, &startsh, flipqueue); - } - flipsub(flipqueue); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// finddirectionsub() Find the first subface in a facet on the path from // -// one point to another. // -// // -// Finds the subface in the facet that intersects a line segment drawn from // -// the origin of `searchsh' to the point `tend', and returns the result in // -// `searchsh'. The origin of `searchsh' does not change, even though the // -// subface returned may differ from the one passed in. // -// // -// The return value notes whether the destination or apex of the found face // -// is collinear with the two points in question. // -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::finddirectionresult tetgenmesh:: -finddirectionsub(face* searchsh, point tend) -{ - face checksh; - point startpoint, liftpoint; - point leftpoint, rightpoint; - REAL leftccw, rightccw; - int leftflag, rightflag; - - adjustedgering(*searchsh, CCW); - liftpoint = getliftpoint(shellmark(*searchsh)); - startpoint = sorg(*searchsh); - rightpoint = sdest(*searchsh); - leftpoint = sapex(*searchsh); - // Is `tend' to the left? - leftccw = orient3d(tend, startpoint, liftpoint, leftpoint); - leftflag = leftccw > 0.0; - // Is `tend' to the right? - rightccw = orient3d(startpoint, tend, liftpoint, rightpoint); - rightflag = rightccw > 0.0; - if (leftflag && rightflag) { - // `searchsh' faces directly away from `tend'. We could go left or - // right. Ask whether it's a triangle or a boundary on the left. - senext2(*searchsh, checksh); - spivotself(checksh); - if (checksh.sh == dummysh) { - leftflag = 0; - } else { - rightflag = 0; - } - } - while (leftflag) { - // Turn left until satisfied. - senext2self(*searchsh); - spivotself(*searchsh); - if (searchsh->sh == dummysh) { - printf("Internal error in finddirectionsub(): Unable to find a\n"); - printf(" triangle leading from %d to %d.\n", pointmark(startpoint), - pointmark(tend)); - internalerror(); - } - adjustedgering(*searchsh, CCW); - leftpoint = sapex(*searchsh); - rightccw = leftccw; - leftccw = orient3d(tend, startpoint, liftpoint, leftpoint); - leftflag = leftccw > 0.0; - } - while (rightflag) { - // Turn right until satisfied. - spivotself(*searchsh); - if (searchsh->sh == dummysh) { - printf("Internal error in finddirectionsub(): Unable to find a\n"); - printf(" triangle leading from %d to %d.\n", pointmark(startpoint), - pointmark(tend)); - internalerror(); - } - adjustedgering(*searchsh, CCW); - senextself(*searchsh); - rightpoint = sdest(*searchsh); - leftccw = rightccw; - rightccw = orient3d(startpoint, tend, liftpoint, rightpoint); - rightflag = rightccw > 0.0; - } - if (leftccw == 0.0) { - return LEFTCOLLINEAR; - } else if (rightccw == 0.0) { - return RIGHTCOLLINEAR; - } else { - return ACROSSEDGE; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// insertsubseg() Create a subsegment and insert it between two subfaces. // -// // -// The new subsegment is inserted at the edge described by the handle 'tri'. // -// If 'tri' is not on the hull, the segment is inserted between two faces. // -// If 'tri' is a hull face, the initial face ring of this segment will be // -// set only one face which is self-bonded. The official face ring will be // -// constructed later in routine unifysegments(). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::insertsubseg(face* tri) -{ - face oppotri; - face newsubseg; - - // Check if there's already a subsegment here. - sspivot(*tri, newsubseg); - if (newsubseg.sh == dummysh) { - // Make new subsegment and initialize its vertices. - makeshellface(subsegs, &newsubseg); - setsorg(newsubseg, sorg(*tri)); - setsdest(newsubseg, sdest(*tri)); - // Bond new subsegment to the two triangles it is sandwiched between. - ssbond(*tri, newsubseg); - spivot(*tri, oppotri); - // 'oppotri' might be "out space". - if (oppotri.sh != dummysh) { - ssbond(oppotri, newsubseg); - } else { - // Outside! Bond '*tri' to itself. - sbond(*tri, *tri); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// scoutsegmentsub() Scout the first triangle on the path from one point // -// to another, and check for completion (reaching the // -// second point), a collinear point,or the intersection // -// of two segments. // -// // -// Returns true if the entire segment is successfully inserted, and false if // -// the job must be finished by constrainededge(). // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::scoutsegmentsub(face* searchsh, point tend) -{ - face newsubseg; - face crosssub, crosssubseg; - point leftpoint, rightpoint; - enum finddirectionresult collinear; - - collinear = finddirectionsub(searchsh, tend); - rightpoint = sdest(*searchsh); - leftpoint = sapex(*searchsh); - if (rightpoint == tend || leftpoint == tend) { - // The segment is already an edge. - if (leftpoint == tend) { - senext2self(*searchsh); - } - // Insert a subsegment. - insertsubseg(searchsh); - return true; - } else if (collinear == LEFTCOLLINEAR) { - // We've collided with a vertex between the segment's endpoints. - // Make the collinear vertex be the triangle's origin. - senextself(*searchsh); // lprevself(*searchtri); - // Insert a subsegment. - insertsubseg(searchsh); - // Insert the remainder of the segment. - return scoutsegmentsub(searchsh, tend); - } else if (collinear == RIGHTCOLLINEAR) { - // We've collided with a vertex between the segment's endpoints. - // Insert a subsegment. - insertsubseg(searchsh); - // Make the collinear vertex be the triangle's origin. - senextself(*searchsh); // lnextself(*searchtri); - // Insert the remainder of the segment. - return scoutsegmentsub(searchsh, tend); - } else { - senext(*searchsh, crosssub); // lnext(*searchtri, crosstri); - // Check for a crossing segment. - sspivot(crosssub, crosssubseg); - assert(crosssubseg.sh == dummysh); - return false; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// delaunayfixup() Enforce the Delaunay condition at an edge, fanning out // -// recursively from an existing point. Pay special // -// attention to stacking inverted triangles. // -// // -// This is a support routine for inserting segments into a constrained // -// Delaunay triangulation. // -// // -// The origin of 'fixupsh' is treated as if it has just been inserted, and // -// the local Delaunay condition needs to be enforced. It is only enforced in // -// one sector, however, that being the angular range defined by 'fixupsh'. // -// // -// `leftside' indicates whether or not fixupsh is to the left of the segment // -// being inserted. (Imagine that the segment is pointing up from endpoint1 // -// to endpoint2.) // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::delaunayfixup(face* fixupsh, int leftside) -{ - face nearsh, farsh, faredge; - point nearpoint, leftpoint, rightpoint, farpoint; - point liftpoint; - REAL sign; - - // It is up to the caller, that 'fixupsh' must be in CCW edge ring. - // adjustedgering(*fixupsh, CCW); - assert((fixupsh->shver % 2) == 0); - senext(*fixupsh, nearsh); - spivot(nearsh, farsh); - if (nearsh.sh == farsh.sh) { - farsh.sh = dummysh; - } - // Check if the edge opposite the origin of fixupsh can be flipped. - if (farsh.sh == dummysh) { - return; - } - adjustedgering(farsh, CCW); - sspivot(nearsh, faredge); - if (faredge.sh != dummysh) { - return; - } - // Find all the relevant vertices. - liftpoint = getliftpoint(shellmark(*fixupsh)); - nearpoint = sapex(nearsh); - leftpoint = sorg(nearsh); - rightpoint = sdest(nearsh); - farpoint = sapex(farsh); - // Check whether the previous polygon point is a reflex point. - if (leftside) { - if (orient3d(nearpoint, leftpoint, liftpoint, farpoint) <= 0.0) { - // leftpoint is a reflex point too. Nothing can - // be done until a convex section is found. - return; - } - } else { - if (orient3d(farpoint, rightpoint, liftpoint, nearpoint) <= 0.0) { - // rightpoint is a reflex point too. Nothing can - // be done until a convex section is found. - return; - } - } - if (orient3d(rightpoint, leftpoint, liftpoint, farpoint) > 0.0) { - // farsh is not an inverted triangle, and farpoint is not a reflex - // point. As there are no reflex vertices, fixupsh isn't an - // inverted triangle, either. Hence, test the edge between the - // triangles to ensure it is locally Delaunay. - sign = insphere(leftpoint, farpoint, rightpoint, liftpoint, nearpoint) - * orient3d(leftpoint, farpoint, rightpoint, liftpoint); - if (sign <= 0.0) { - return; - } - // Not locally Delaunay; go on to an edge flip. - } // else farsh is inverted; remove it from the stack by flipping. - flip22sub(&nearsh, NULL); - senext2self(*fixupsh); // Restore the origin of fixupsh after the flip. - // Recursively process the two triangles that result from the flip. - delaunayfixup(fixupsh, leftside); - delaunayfixup(&farsh, leftside); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// constrainededge() Force a segment into a constrained Delaunay // -// triangulation by deleting the triangles it // -// intersects, and triangulating the polygons that // -// form on each side of it. // -// // -// Generates a single subsegment connecting `tstart' to `tend'. The triangle // -// `startsh' has `tstart' as its origin. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::constrainededge(face* startsh, point tend) -{ - face fixupsh, fixupsh2; - face crosssubseg, newsubseg; - point tstart, farpoint; - point liftpoint; - REAL area; - int collision; - int done; - - liftpoint = getliftpoint(shellmark(*startsh)); - tstart = sorg(*startsh); - // Always works in the CCW edge ring. - adjustedgering(*startsh, CCW); - // Make sure the 'tstart' remians be the origin. - if (sorg(*startsh) != tstart) { - senextself(*startsh); - assert(sorg(*startsh) == tstart); - } - senext(*startsh, fixupsh); - flip22sub(&fixupsh, NULL); - // `collision' indicates whether we have found a vertex directly - // between endpoint1 and endpoint2. - collision = 0; - done = 0; - do { - farpoint = sorg(fixupsh); - // `farpoint' is the extreme point of the polygon we are "digging" - // to get from tstart to tend. - if (farpoint == tend) { - spivot(fixupsh, fixupsh2); // oprev(fixupsh, fixupsh2); - adjustedgering(fixupsh2, CCW); - senextself(fixupsh2); - // Enforce the Delaunay condition around tend. - delaunayfixup(&fixupsh, 0); - delaunayfixup(&fixupsh2, 1); - done = 1; - } else { - // Check whether farpoint is to the left or right of the segment - // being inserted, to decide which edge of fixupsh to dig - // through next. - area = orient3d(tstart, tend, liftpoint, farpoint); - if (area == 0.0) { - // We've collided with a vertex between tstart and tend. - collision = 1; - spivot(fixupsh, fixupsh2); // oprev(fixupsh, fixupsh2); - adjustedgering(fixupsh2, CCW); - senextself(fixupsh2); - // Enforce the Delaunay condition around farpoint. - delaunayfixup(&fixupsh, 0); - delaunayfixup(&fixupsh2, 1); - done = 1; - } else { - if (area > 0.0) { // farpoint is to the left of the segment. - spivot(fixupsh, fixupsh2); // oprev(fixupsh, fixupsh2); - adjustedgering(fixupsh2, CCW); - senextself(fixupsh2); - // Enforce the Delaunay condition around farpoint, on the - // left side of the segment only. - delaunayfixup(&fixupsh2, 1); - // Flip the edge that crosses the segment. After the edge is - // flipped, one of its endpoints is the fan vertex, and the - // destination of fixupsh is the fan vertex. - senext2self(fixupsh); // lprevself(fixupsh); - } else { // farpoint is to the right of the segment. - delaunayfixup(&fixupsh, 0); - // Flip the edge that crosses the segment. After the edge is - // flipped, one of its endpoints is the fan vertex, and the - // destination of fixupsh is the fan vertex. - spivotself(fixupsh); // oprevself(fixupsh); - adjustedgering(fixupsh, CCW); - senextself(fixupsh); - } - // Check for two intersecting segments. - sspivot(fixupsh, crosssubseg); - if (crosssubseg.sh == dummysh) { - flip22sub(&fixupsh, NULL);// May create inverted triangle at left. - } else { - // We've collided with a segment between tstart and tend. - /* collision = 1; - // Insert a vertex at the intersection. - segmentintersection(m, b, &fixupsh, &crosssubseg, tend); - done = 1; - */ - assert(0); - } - } - } - } while (!done); - // Insert a subsegment to make the segment permanent. - insertsubseg(&fixupsh); - // If there was a collision with an interceding vertex, install another - // segment connecting that vertex with endpoint2. - if (collision) { - // Insert the remainder of the segment. - if (!scoutsegmentsub(&fixupsh, tend)) { - constrainededge(&fixupsh, tend); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// insertsegmentsub() Insert a PSLG segment into a triangulation. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::insertsegmentsub(point tstart, point tend) -{ - face searchsh1, searchsh2; - - if (b->verbose > 2) { - printf(" Insert subsegment (%d, %d).\n", pointmark(tstart), - pointmark(tend)); - } - - // Find a triangle whose origin is the segment's first endpoint. - searchsh1.sh = dummysh; - // Search for the segment's first endpoint by point location. - if (locatesub(tstart, &searchsh1, NULL) != ONVERTEX) { - printf("Internal error in insertsegmentsub():"); - printf(" Unable to locate PSLG vertex %d.\n", pointmark(tstart)); - internalerror(); - } - // Scout the beginnings of a path from the first endpoint - // toward the second. - if (scoutsegmentsub(&searchsh1, tend)) { - // The segment was easily inserted. - return; - } - // The first endpoint may have changed if a collision with an intervening - // vertex on the segment occurred. - tstart = sorg(searchsh1); - - // Find a boundary triangle to search from. - searchsh2.sh = dummysh; - // Search for the segment's second endpoint by point location. - if (locatesub(tend, &searchsh2, NULL) != ONVERTEX) { - printf("Internal error in insertsegmentsub():"); - printf(" Unable to locate PSLG vertex %d.\n", pointmark(tend)); - internalerror(); - } - // Scout the beginnings of a path from the second endpoint - // toward the first. - if (scoutsegmentsub(&searchsh2, tstart)) { - // The segment was easily inserted. - return; - } - // The second endpoint may have changed if a collision with an intervening - // vertex on the segment occurred. - tend = sorg(searchsh2); - - // Insert the segment directly into the triangulation. - constrainededge(&searchsh1, tend); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// infecthullsub() Virally infect all of the triangles of the convex hull // -// that are not protected by subsegments. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::infecthullsub(memorypool* viri) -{ - face hulltri, nexttri, starttri; - face hullsubseg; - shellface **deadshellface; - - // Find a triangle handle on the hull. - hulltri.sh = dummysh; - hulltri.shver = 0; - spivotself(hulltri); - adjustedgering(hulltri, CCW); - // Remember where we started so we know when to stop. - starttri = hulltri; - // Go once counterclockwise around the convex hull. - do { - // Ignore triangles that are already infected. - if (!sinfected(hulltri)) { - // Is the triangle protected by a subsegment? - sspivot(hulltri, hullsubseg); - if (hullsubseg.sh == dummysh) { - // The triangle is not protected; infect it. - if (!sinfected(hulltri)) { - sinfect(hulltri); - deadshellface = (shellface **) viri->alloc(); - *deadshellface = hulltri.sh; - } - } - } - // To find the next hull edge, go clockwise around the next vertex. - senextself(hulltri); // lnextself(hulltri); - spivot(hulltri, nexttri); // oprev(hulltri, nexttri); - if (nexttri.sh == hulltri.sh) { - nexttri.sh = dummysh; // 'hulltri' is self-bonded. - } else { - adjustedgering(nexttri, CCW); - senextself(nexttri); - } - while (nexttri.sh != dummysh) { - hulltri = nexttri; - spivot(hulltri, nexttri); // oprev(hulltri, nexttri); - if (nexttri.sh == hulltri.sh) { - nexttri.sh = dummysh; // 'hulltri' is self-bonded. - } else { - adjustedgering(nexttri, CCW); - senextself(nexttri); - } - } - } while (hulltri != starttri); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// plaguesub() Spread the virus from all infected triangles to any // -// neighbors not protected by subsegments. Delete all // -// infected triangles. // -// // -// This is the procedure that actually creates holes and concavities. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::plaguesub(memorypool* viri) -{ - face testtri, neighbor, ghostsh; - face neighborsubseg; - shellface **virusloop; - shellface **deadshellface; - int i; - - // Loop through all the infected triangles, spreading the virus to - // their neighbors, then to their neighbors' neighbors. - viri->traversalinit(); - virusloop = (shellface **) viri->traverse(); - while (virusloop != (shellface **) NULL) { - testtri.sh = *virusloop; - // Check each of the triangle's three neighbors. - for (i = 0; i < 3; i++) { - // Find the neighbor. - spivot(testtri, neighbor); - // Check for a subsegment between the triangle and its neighbor. - sspivot(testtri, neighborsubseg); - // Check if the neighbor is nonexistent or already infected. - if ((neighbor.sh == dummysh) || sinfected(neighbor)) { - if (neighborsubseg.sh != dummysh) { - // There is a subsegment separating the triangle from its - // neighbor, but both triangles are dying, so the subsegment - // dies too. - shellfacedealloc(subsegs, neighborsubseg.sh); - if (neighbor.sh != dummysh) { - // Make sure the subsegment doesn't get deallocated again - // later when the infected neighbor is visited. - ssdissolve(neighbor); - } - } - } else { // The neighbor exists and is not infected. - if (neighborsubseg.sh == dummysh) { - // There is no subsegment protecting the neighbor, so the - // neighbor becomes infected. - sinfect(neighbor); - // Ensure that the neighbor's neighbors will be infected. - deadshellface = (shellface **) viri->alloc(); - *deadshellface = neighbor.sh; - } else { // The neighbor is protected by a subsegment. - // Remove this triangle from the subsegment. - ssbond(neighbor, neighborsubseg); - } - } - senextself(testtri); - } - virusloop = (shellface **) viri->traverse(); - } - - ghostsh.sh = dummysh; // A handle of outer space. - viri->traversalinit(); - virusloop = (shellface **) viri->traverse(); - while (virusloop != (shellface **) NULL) { - testtri.sh = *virusloop; - // Record changes in the number of boundary edges, and disconnect - // dead triangles from their neighbors. - for (i = 0; i < 3; i++) { - spivot(testtri, neighbor); - if (neighbor.sh != dummysh) { - // Disconnect the triangle from its neighbor. - // sdissolve(neighbor); - sbond(neighbor, ghostsh); - } - senextself(testtri); - } - // Return the dead triangle to the pool of triangles. - shellfacedealloc(subfaces, testtri.sh); - virusloop = (shellface **) viri->traverse(); - } - // Empty the virus pool. - viri->restart(); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// carveholessub() Find the holes and infect them. Find the area // -// constraints and infect them. Infect the convex hull. // -// Spread the infection and kill triangles. Spread the // -// area constraints. // -// // -// This routine mainly calls other routines to carry out all these functions.// -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::carveholessub(int holes, REAL* holelist) -{ - face searchtri, triangleloop; - shellface **holetri; - memorypool *viri; - enum locateresult intersect; - int i; - - // Initialize a pool of viri to be used for holes, concavities. - viri = new memorypool(sizeof(shellface *), 1024, POINTER, 0); - - // Mark as infected any unprotected triangles on the boundary. - // This is one way by which concavities are created. - infecthullsub(viri); - - if (holes > 0) { - // Infect each triangle in which a hole lies. - for (i = 0; i < 3 * holes; i += 3) { - // Ignore holes that aren't within the bounds of the mesh. - if ((holelist[i] >= xmin) && (holelist[i] <= xmax) - && (holelist[i + 1] >= ymin) && (holelist[i + 1] <= ymax) - && (holelist[i + 2] >= zmin) && (holelist[i + 2] <= zmax)) { - // Start searching from some triangle on the outer boundary. - searchtri.sh = dummysh; - // Find a triangle that contains the hole. - intersect = locatesub(&holelist[i], &searchtri, NULL); - if ((intersect != OUTSIDE) && (!sinfected(searchtri))) { - // Infect the triangle. This is done by marking the triangle - // as infected and including the triangle in the virus pool. - sinfect(searchtri); - holetri = (shellface **) viri->alloc(); - *holetri = searchtri.sh; - } - } - } - } - - if (viri->items > 0) { - // Carve the holes and concavities. - plaguesub(viri); - } - // The virus pool should be empty now. - - // Free up memory. - delete viri; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangulatefacet() Create the constrained Delaunay triang. of a facet. // -// // -// 'facetidx' is the index of the facet in 'in->facetlist' (starts from 1), // -// 'idx2verlist' is a map from indices to vertices. 'ptlist' and 'conlist' // -// are two lists used to assemble the input data for each facet, 'ptlist' // -// stores the index set of its vertices, 'conlist' stores the set of its // -// segments, they should be empty on input and output. // -// // -// On completion, the CDT of this facet is constructed in pool 'subfaces'. // -// Every isolated point on the facet will be set a type of FACETVERTEX. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -triangulatefacet(int facetidx, list* ptlist, list* conlist, point* idx2verlist, - queue* flipqueue) -{ - tetgenio::facet *f; - tetgenio::polygon *p; - point tstart, tend; - int end1, end2; - int *cons, idx1, idx2; - int i, j; - - if (b->verbose > 1) { - printf(" Triangulate facet %d.\n", facetidx); - } - - // Get the pointer of the facet. - f = &in->facetlist[facetidx - 1]; - - // Are there duplicated points? - if ((b->object == tetgenbehavior::STL) || dupverts) { - // Loop all polygons of this facet. - for (i = 0; i < f->numberofpolygons; i++) { - p = &(f->polygonlist[i]); - // Loop other vertices of this polygon. - for (j = 0; j < p->numberofvertices; j++) { - idx1 = p->vertexlist[j]; - tstart = idx2verlist[idx1 - in->firstnumber]; - if (pointtype(tstart) == DUPLICATEDVERTEX) { - // Reset the index of vertex-j. - tend = point2pt(tstart); - idx2 = pointmark(tend); - p->vertexlist[j] = idx2; - } - } - } - } - - // Loop all polygons of this facet, get the sets of vertices and segments. - for (i = 0; i < f->numberofpolygons; i++) { - p = &(f->polygonlist[i]); - // Get the first vertex. - end1 = p->vertexlist[0]; - if ((end1 < in->firstnumber) || - (end1 >= in->firstnumber + in->numberofpoints)) { - if (!b->quiet) { - printf("Warning: Invalid the 1st vertex %d of polygon", end1); - printf(" %d in facet %d.\n", i + 1, facetidx); - } - break; // Skip to mesh this facet. - } - // Save it in 'ptlist' if it didn't be added, and set its position. - idx1 = ptlist->hasitem(&end1); - if (idx1 == -1) { - ptlist->append(&end1); - idx1 = ptlist->len() - 1; - } - // Loop other vertices of this polygon. - for (j = 1; j <= p->numberofvertices; j++) { - // get a vertex. - if (j < p->numberofvertices) { - end2 = p->vertexlist[j]; - } else { - end2 = p->vertexlist[0]; // Form a loop from last to first. - } - if ((end2 < in->firstnumber) || - (end2 >= in->firstnumber + in->numberofpoints)) { - if (!b->quiet) { - printf("Warning: Invalid vertex %d in polygon %d", end2, i + 1); - printf(" in facet %d.\n", facetidx); - } - } else { - if (end1 != end2) { - // 'end1' and 'end2' form a segment. Save 'end2' in 'ptlist' if - // it didn't be added before. - idx2 = ptlist->hasitem(&end2); - if (idx2 == -1) { - ptlist->append(&end2); - idx2 = ptlist->len() - 1; - } - // Save the segment in 'conlist'. - cons = (int *) conlist->append(NULL); - cons[0] = idx1; - cons[1] = idx2; - // Set the start for next continuous segment. - end1 = end2; - idx1 = idx2; - } else { - // It's a (degenerate) segment with identical endpoints, which - // represents an isolate vertex in facet. - if (p->numberofvertices > 2) { - // This may be an error in the input, anyway, we let it be. - if (!b->quiet) { - printf("Warning: Polygon %d has two identical vertices", i + 1); - printf(" in facet %d.\n", facetidx); - } - } - // Set the vertex type be 'FACETVERTEX'. - // setpointtype(idx2verlist[end1 - in->firstnumber], FACETVERTEX); - // Ignore this vertex. - } - } - if (p->numberofvertices == 2) { - // This case the polygon is either a segment or an isolated vertex. - break; - } - } - } - - // Have got the vertex list and segment list. - if (b->verbose > 1) { - printf(" %d vertices, %d segments", ptlist->len(), conlist->len()); - if (f->numberofholes > 0) { - printf(", %d holes\n", f->numberofholes); - } - printf(".\n"); - } - - if (ptlist->len() > 2) { - // Construct an initial triangulation. - if (incrflipinitsub(facetidx, ptlist, idx2verlist)) { - if (ptlist->len() > 3) { - // Create the Delaunay triangulation of 'ptlist'. - incrflipdelaunaysub(facetidx, ptlist, idx2verlist, flipqueue); - } - // Insert segments (in 'conlist') into the Delaunay triangulation. - for (i = 0; i < conlist->len(); i++) { - cons = (int *)(* conlist)[i]; - idx1 = * (int *)(* ptlist)[cons[0]]; - tstart = idx2verlist[idx1 - in->firstnumber]; - idx2 = * (int *)(* ptlist)[cons[1]]; - tend = idx2verlist[idx2 - in->firstnumber]; - insertsegmentsub(tstart, tend); - } - if (ptlist->len() > 3 && conlist->len() > 3) { - // Carve holes and concavities. - carveholessub(f->numberofholes, f->holelist); - } - } - } - - // Clear working lists. - ptlist->clear(); - conlist->clear(); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// unifysegments() Unify identical segments and build facet connections. // -// // -// After the surface mesh has been created. Each facet has its own segments. // -// There are many segments having the same endpoints, which are indentical. // -// This routine has two purposes: (1) identify the set of segments which // -// have the same endpoints and unify them into one segment, remove redundant // -// ones; and (2) create the face rings of the unified segments, hence, setup // -// the facet connections. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::unifysegments() -{ - list *sfacelist; - shellface **facesperverlist; - face subsegloop, testseg; - face sface, sface1, sface2; - point torg, tdest; - REAL da1, da2; - int *idx2facelist; - int idx, k, m; - - if (b->verbose) { - printf(" Unifying segments.\n"); - } - - // Compute a mapping from indices of vertices to subfaces. - makesubfacemap(idx2facelist, facesperverlist); - // Initialize 'sfacelist' for constructing the face link of each segment. - sfacelist = new list(sizeof(face), NULL); - - subsegs->traversalinit(); - subsegloop.sh = shellfacetraverse(subsegs); - while (subsegloop.sh != (shellface *) NULL) { - subsegloop.shver = 0; // For sure. - torg = sorg(subsegloop); - tdest = sdest(subsegloop); - idx = pointmark(torg) - in->firstnumber; - // Loop through the set of subfaces containing 'torg'. Get all the - // subfaces containing the edge (torg, tdest). Save and order them - // in 'sfacelist', the ordering is defined by the right-hand rule - // with thumb points from torg to tdest. - for (k = idx2facelist[idx]; k < idx2facelist[idx + 1]; k++) { - sface.sh = facesperverlist[k]; - sface.shver = 0; - // sface may be died due to the removing of duplicated subfaces. - if (!isdead(&sface) && isfacehasedge(&sface, torg, tdest)) { - // 'sface' contains this segment. - findedge(&sface, torg, tdest); - // Save it in 'sfacelist'. - if (sfacelist->len() < 2) { - sfacelist->append(&sface); - } else { - for (m = 0; m < sfacelist->len() - 1; m++) { - sface1 = * (face *)(* sfacelist)[m]; - sface2 = * (face *)(* sfacelist)[m + 1]; - da1 = facedihedral(torg, tdest, sapex(sface1), sapex(sface)); - da2 = facedihedral(torg, tdest, sapex(sface1),sapex(sface2)); - if (da1 < da2) { - break; // Insert it after m. - } - } - sfacelist->insert(m + 1, &sface); - } - } - } - if (b->verbose > 1) { - printf(" Identifying %d segments of (%d %d).\n", sfacelist->len(), - pointmark(torg), pointmark(tdest)); - } - // Set the connection between this segment and faces containing it, - // at the same time, remove redundant segments. - for (k = 0; k < sfacelist->len(); k++) { - sface = *(face *)(* sfacelist)[k]; - sspivot(sface, testseg); - // If 'testseg' is not 'subsegloop', it is a redundant segment that - // needs be removed. BE CAREFUL it may already be removed. Do not - // remove it twice, i.e., we need do test 'isdead()' together. - if ((testseg.sh != subsegloop.sh) && !isdead(&testseg)) { - shellfacedealloc(subsegs, testseg.sh); - } - // 'ssbond' bonds the subface and the segment together, and dissloves - // the old bond as well. - ssbond(sface, subsegloop); - } - // Set connection between these faces. - sface = *(face *)(* sfacelist)[0]; - for (k = 1; k <= sfacelist->len(); k++) { - if (k < sfacelist->len()) { - sface1 = *(face *)(* sfacelist)[k]; - } else { - sface1 = *(face *)(* sfacelist)[0]; // Form a face loop. - } - /* - // Check if these two subfaces are the same. It is possible when user - // defines one facet (or polygon) two or more times. If they are, - // they should not be bonded together, instead of that, one of them - // should be delete from the surface mesh. - if ((sfacelist->len() > 1) && sapex(sface) == sapex(sface1)) { - // They are duplicated faces. - if (b->verbose) { - printf(" A duplicated subface (%d, %d, %d) is removed.\n", - pointmark(torg), pointmark(tdest), pointmark(sapex(sface))); - } - if (k == sfacelist->len()) { - // 'sface' is the last face, however, it is same as the first one. - // In order to form the ring, we have to let the second last - // face bond to the first one 'sface1'. - shellfacedealloc(subfaces, sface.sh); - assert(sfacelist->len() >= 2); - assert(k == sfacelist->len()); - sface = *(face *)(* sfacelist)[k - 2]; - } else { - // 'sface1' is in the middle and may be the last one. - shellfacedealloc(subfaces, sface1.sh); - // Skip this face and go to the next one. - continue; - } - } - */ - if (b->verbose > 2) { - printf(" Bond subfaces (%d, %d, %d) and (%d, %d, %d).\n", - pointmark(torg), pointmark(tdest), pointmark(sapex(sface)), - pointmark(torg), pointmark(tdest), pointmark(sapex(sface1))); - } - sbond1(sface, sface1); - sface = sface1; - } - // Clear the working list. - sfacelist->clear(); - subsegloop.sh = shellfacetraverse(subsegs); - } - - delete [] idx2facelist; - delete [] facesperverlist; - delete sfacelist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// mergefacets() Merge adjacent facets to be one facet if they are // -// coplanar and have the same boundary marker. // -// // -// Segments between two merged facets will be removed from the mesh. If all // -// segments around a vertex have been removed, change its vertex type to be // -// FACETVERTEX. Edge flips will be performed to ensure the Delaunay criteria // -// of the triangulation of merged facets. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::mergefacets(queue* flipqueue) -{ - face parentsh, neighsh, neineighsh; - face segloop; - point eorg, edest; - REAL ori; - bool mergeflag; - int* segspernodelist; - int fidx1, fidx2; - int i, j; - - if (b->verbose) { - printf(" Merging coplanar facets.\n"); - } - // Create and initialize 'segspernodelist'. - segspernodelist = new int[points->items + 1]; - for (i = 0; i < points->items + 1; i++) { - segspernodelist[i] = 0; - } - - // Loop the segments, counter the number of segments sharing each vertex. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - // Increment the number of sharing segments for each endpoint. - for (i = 0; i < 2; i++) { - j = pointmark((point) segloop.sh[3 + i]); - segspernodelist[j]++; - } - segloop.sh = shellfacetraverse(subsegs); - } - - // Loop the segments, find out dead segments. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - eorg = sorg(segloop); - edest = sdest(segloop); - spivot(segloop, parentsh); - spivot(parentsh, neighsh); - spivot(neighsh, neineighsh); - if (parentsh.sh != neighsh.sh && parentsh.sh == neineighsh.sh) { - // Exactly two subfaces at this segment. - fidx1 = shellmark(parentsh) - 1; - fidx2 = shellmark(neighsh) - 1; - // Possibly merge them if they are not in the same facet. - if (fidx1 != fidx2) { - // Test if they are coplanar. - ori = orient3d(eorg, edest, sapex(parentsh), sapex(neighsh)); - if (ori != 0.0) { - if (iscoplanar(eorg, edest, sapex(parentsh), sapex(neighsh), ori, - b->epsilon)) { - ori = 0.0; // They are assumed as coplanar. - } - } - if (ori == 0.0) { - mergeflag = (in->facetmarkerlist == (int *) NULL || - in->facetmarkerlist[fidx1] == in->facetmarkerlist[fidx2]); - if (mergeflag) { - // This segment becomes dead. - if (b->verbose > 1) { - printf(" Removing segment (%d, %d).\n", pointmark(eorg), - pointmark(edest)); - } - ssdissolve(parentsh); - ssdissolve(neighsh); - shellfacedealloc(subsegs, segloop.sh); - j = pointmark(eorg); - segspernodelist[j]--; - if (segspernodelist[j] == 0) { - setpointtype(eorg, FACETVERTEX); - } - j = pointmark(edest); - segspernodelist[j]--; - if (segspernodelist[j] == 0) { - setpointtype(edest, FACETVERTEX); - } - // Add 'parentsh' to queue checking for flip. - enqueueflipedge(parentsh, flipqueue); - } - } - } - } - segloop.sh = shellfacetraverse(subsegs); - } - - if (!flipqueue->empty()) { - // Restore the Delaunay property in the facet triangulation. - flipsub(flipqueue); - } - - delete [] segspernodelist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// meshsurface() Create a surface triangulation of a PLC. // -// // -// The surface mesh consists of a set of subfaces which are two dimensional // -// constrained Delaunay triangulations of the facets of the PLC and a set of // -// subsegments which are edges bounded the facets. Subfaces belong to one // -// facet are connecting each other. Around each subsegment is a subface ring,// -// which saves the connection between facets sharing at this subsegment. // -// // -// This routine first creates the CDTs separatly, that is, each facet will // -// be meshed into a set of subfaces and subsegments. As a result, subfaces // -// only have connections to subfaces which are belong to the same facet. And // -// subsegments are over-created. Then, routine unifysegment() is called to // -// remove redundant subsegments and create the face ring around subsegments. // -// // -// Return the number of (input) segments. // -// // -/////////////////////////////////////////////////////////////////////////////// - -long tetgenmesh::meshsurface() -{ - list *ptlist, *conlist; - queue *flipqueue; - point *idx2verlist; - int i; - - if (!b->quiet) { - printf("Creating surface mesh.\n"); - } - - // Compute a mapping from indices to points. - makeindex2pointmap(idx2verlist); - // Initialize 'liftpointarray'. - liftpointarray = new REAL[in->numberoffacets * 3]; - // Initialize 'flipqueue'. - flipqueue = new queue(sizeof(badface)); - // Two re-useable lists 'ptlist' and 'conlist'. - ptlist = new list("int"); - conlist = new list(sizeof(int) * 2, NULL); - - // Loop the facet list, triangulate each facet. On finish, all subfaces - // are in 'subfaces', all segments are in 'subsegs' (Note: there exist - // duplicated segments). - for (i = 0; i < in->numberoffacets; i++) { - triangulatefacet(i + 1, ptlist, conlist, idx2verlist, flipqueue); - } - - // Unify segments in 'subsegs', remove redundant segments. Face links - // of segments are also built. - unifysegments(); - - if (b->object == tetgenbehavior::STL) { - // Remove redundant vertices (for .stl input mesh). - jettisonnodes(); - } - - if (!b->nomerge) { - // Merge adjacent facets if they are coplanar. - mergefacets(flipqueue); - } - - delete [] idx2verlist; - delete flipqueue; - delete conlist; - delete ptlist; - - return subsegs->items; -} - -// -// End of surface triangulation routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// interecursive() Recursively do intersection test on a set of triangles.// -// // -// Recursively split the set 'subfacearray' of subfaces into two sets using // -// a cut plane parallel to x-, or, y-, or z-axies. The split criteria are // -// follows. Assume the cut plane is H, and H+ denotes the left halfspace of // -// H, and H- denotes the right halfspace of H; and s be a subface: // -// // -// (1) If all points of s lie at H+, put it into left array; // -// (2) If all points of s lie at H-, put it into right array; // -// (3) If some points of s lie at H+ and some of lie at H-, or some // -// points lie on H, put it into both arraies. // -// // -// Partitions by x-axis if axis == '0'; by y-axis if axis == '1'; by z-axis // -// if axis == '2'. If current cut plane is parallel to the x-axis, the next // -// one will be parallel to y-axis, and the next one after the next is z-axis,// -// and then alternately return back to x-axis. // -// // -// Stop splitting when the number of triangles of the input array is not // -// decreased anymore. Do tests on the current set. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -interecursive(shellface** subfacearray, int arraysize, int axis, REAL bxmin, - REAL bxmax, REAL bymin, REAL bymax, REAL bzmin, REAL bzmax, - int* internum) -{ - shellface **leftarray, **rightarray; - face sface1, sface2; - point p1, p2, p3; - point p4, p5, p6; - enum intersectresult intersect; - REAL split; - bool toleft, toright; - int leftsize, rightsize; - int i, j; - - if (b->verbose > 1) { - printf(" Recur %d faces. Bbox (%g, %g, %g),(%g, %g, %g). %s-axis\n", - arraysize, bxmin, bymin, bzmin, bxmax, bymax, bzmax, - axis == 0 ? "x" : (axis == 1 ? "y" : "z")); - } - - leftarray = new shellface*[arraysize]; - if (leftarray == NULL) { - printf("Error in interecursive(): Insufficient memory.\n"); - exit(1); - } - rightarray = new shellface*[arraysize]; - if (rightarray == NULL) { - printf("Error in interecursive(): Insufficient memory.\n"); - exit(1); - } - leftsize = rightsize = 0; - - if (axis == 0) { - // Split along x-axis. - split = 0.5 * (bxmin + bxmax); - } else if (axis == 1) { - // Split along y-axis. - split = 0.5 * (bymin + bymax); - } else { - // Split along z-axis. - split = 0.5 * (bzmin + bzmax); - } - - for (i = 0; i < arraysize; i++) { - sface1.sh = subfacearray[i]; - p1 = (point) sface1.sh[3]; - p2 = (point) sface1.sh[4]; - p3 = (point) sface1.sh[5]; - toleft = toright = false; - if (p1[axis] < split) { - toleft = true; - if (p2[axis] >= split || p3[axis] >= split) { - toright = true; - } - } else if (p1[axis] > split) { - toright = true; - if (p2[axis] <= split || p3[axis] <= split) { - toleft = true; - } - } else { - // p1[axis] == split; - toleft = true; - toright = true; - } - // At least one is true; - assert(!(toleft == false && toright == false)); - if (toleft) { - leftarray[leftsize] = sface1.sh; - leftsize++; - } - if (toright) { - rightarray[rightsize] = sface1.sh; - rightsize++; - } - } - - if (leftsize < arraysize && rightsize < arraysize) { - // Continue to partition the input set. Now 'subfacearray' has been - // split into two sets, it's memory can be freed. 'leftarray' and - // 'rightarray' will be freed in the next recursive (after they're - // partitioned again or performing tests). - delete [] subfacearray; - // Continue to split these two sets. - if (axis == 0) { - interecursive(leftarray, leftsize, 1, bxmin, split, bymin, bymax, - bzmin, bzmax, internum); - interecursive(rightarray, rightsize, 1, split, bxmax, bymin, bymax, - bzmin, bzmax, internum); - } else if (axis == 1) { - interecursive(leftarray, leftsize, 2, bxmin, bxmax, bymin, split, - bzmin, bzmax, internum); - interecursive(rightarray, rightsize, 2, bxmin, bxmax, split, bymax, - bzmin, bzmax, internum); - } else { - interecursive(leftarray, leftsize, 0, bxmin, bxmax, bymin, bymax, - bzmin, split, internum); - interecursive(rightarray, rightsize, 0, bxmin, bxmax, bymin, bymax, - split, bzmax, internum); - } - } else { - if (b->verbose > 1) { - printf(" Checking intersecting faces.\n"); - } - // Perform a brute-force compare on the set. - for (i = 0; i < arraysize; i++) { - sface1.sh = subfacearray[i]; - p1 = (point) sface1.sh[3]; - p2 = (point) sface1.sh[4]; - p3 = (point) sface1.sh[5]; - for (j = i + 1; j < arraysize; j++) { - sface2.sh = subfacearray[j]; - p4 = (point) sface2.sh[3]; - p5 = (point) sface2.sh[4]; - p6 = (point) sface2.sh[5]; - intersect = triangle_triangle_inter(p1, p2, p3, p4, p5, p6); - if (intersect == INTERSECT || intersect == SHAREFACE) { - if (!b->quiet) { - if (intersect == INTERSECT) { - printf(" Facet #%d intersects facet #%d at triangles:\n", - shellmark(sface1), shellmark(sface2)); - printf(" (%4d, %4d, %4d) and (%4d, %4d, %4d)\n", - pointmark(p1), pointmark(p2), pointmark(p3), - pointmark(p4), pointmark(p5), pointmark(p6)); - } else { - printf(" Facet #%d duplicates facet #%d at triangle:\n", - shellmark(sface1), shellmark(sface2)); - printf(" (%4d, %4d, %4d)\n", pointmark(p1), pointmark(p2), - pointmark(p3)); - } - } - // Increase the number of intersecting pairs. - (*internum)++; - // Infect these two faces (although they may already be infected). - sinfect(sface1); - sinfect(sface2); - } - } - } - // Don't forget to free all three arrays. No further partition. - delete [] leftarray; - delete [] rightarray; - delete [] subfacearray; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// detectinterfaces() Detect intersecting triangles. // -// // -// Given a set of triangles, find the pairs of intersecting triangles from // -// them. Here the set of triangles is in 'subfaces' which is a surface mesh // -// of a PLC (.poly or .smesh). // -// // -// To detect whether or not two triangles are intersecting is done by the // -// routine 'triangle_triangle_inter()'. The algorithm for the test is very // -// simple and stable. It is based on geometric orientation test which uses // -// exact arithmetics. // -// // -// Use divide-and-conquer algorithm for reducing the number of intersection // -// tests. Start from the bounding box of the input point set, recursively // -// partition the box into smaller boxes, until the number of triangles in a // -// box is not decreased anymore. Then perform triangle-triangle tests on the // -// remaining set of triangles. The memory allocated in the input set is // -// freed immediately after it has been partitioned into two arrays. So it // -// can be re-used for the consequent partitions. // -// // -// On return, pool 'subfaces' will be cleared, and only the intersecting // -// triangles remain for output (to a .face file). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::detectinterfaces() -{ - shellface **subfacearray; - face shloop; - int internum; - int i; - - if (!b->quiet) { - printf("Detecting intersecting facets.\n"); - } - - // Construct a map from indices to subfaces; - subfacearray = new shellface*[subfaces->items]; - subfaces->traversalinit(); - shloop.sh = shellfacetraverse(subfaces); - i = 0; - while (shloop.sh != (shellface *) NULL) { - subfacearray[i] = shloop.sh; - shloop.sh = shellfacetraverse(subfaces); - i++; - } - - internum = 0; - // Recursively split the set of triangles into two sets using a cut plane - // parallel to x-, or, y-, or z-axies. Stop splitting when the number - // of subfaces is not decreasing anymore. Do tests on the current set. - interecursive(subfacearray, subfaces->items, 0, xmin, xmax, ymin, ymax, - zmin, zmax, &internum); - - if (!b->quiet) { - if (internum > 0) { - printf("\n!! Found %d pairs of faces are intersecting.\n\n", internum); - } else { - printf("\nNo faces are intersecting.\n\n"); - } - } - - if (internum > 0) { - // Traverse all subfaces, deallocate those have not been infected (they - // are not intersecting faces). Uninfect those have been infected. - // After this loop, only intersecting faces remain. - subfaces->traversalinit(); - shloop.sh = shellfacetraverse(subfaces); - while (shloop.sh != (shellface *) NULL) { - if (sinfected(shloop)) { - suninfect(shloop); - } else { - shellfacedealloc(subfaces, shloop.sh); - } - shloop.sh = shellfacetraverse(subfaces); - } - } else { - // Deallocate all subfaces. - subfaces->restart(); - } -} - -// -// Begin of segments recovery routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// markacutevertices() Set the proper type (ACUTEVERTEX, NONACUTEVERTEX) // -// for segment vertices. // -// // -// Parameter 'acuteangle' gives the upperbound (in degree). Angles which are // -// smaller or equal than it are assumed as acute angles. A vertex is acute // -// if at least two segments incident at it with an acute angle. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::markacutevertices(REAL acuteangle) -{ - shellface** segsperverlist; - face segloop, workseg, inciseg; - point eorg, edest, eapex; - REAL cosbound, anglearc; - REAL v1[3], v2[3], L, D; - bool isacute; - int* idx2seglist; - int idx, i, j, k; - - if (b->verbose) { - printf(" Marking segments have acute corners.\n"); - } - - // Constructing a map from vertex to segments. - makesegmentmap(idx2seglist, segsperverlist); - - // Initialize all vertices be unknown. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - // Check and set types for the two ends of this segment. - for (segloop.shver = 0; segloop.shver < 2; segloop.shver++) { - eorg = sorg(segloop); - setpointtype(eorg, FACETVERTEX); - } - segloop.sh = shellfacetraverse(subsegs); - } - - anglearc = acuteangle * 3.1415926535897932 / 180.0; - cosbound = cos(anglearc); - - // Loop over the set of subsegments. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - // Check and set types for the two ends of this segment. - for (segloop.shver = 0; segloop.shver < 2; segloop.shver++) { - eorg = sorg(segloop); - if ((pointtype(eorg) != ACUTEVERTEX) && - (pointtype(eorg) != NONACUTEVERTEX)) { - // This vertex has no type be set yet. - idx = pointmark(eorg) - in->firstnumber; - isacute = false; - for (i = idx2seglist[idx]; i < idx2seglist[idx + 1] && !isacute; i++) { - workseg.sh = segsperverlist[i]; - workseg.shver = 0; - if (sorg(workseg) != eorg) { - sesymself(workseg); - } - assert(sorg(workseg) == eorg); - edest = sdest(workseg); - for (j = i + 1; j < idx2seglist[idx + 1] && !isacute; j++) { - inciseg.sh = segsperverlist[j]; - inciseg.shver = 0; - assert(inciseg.sh != workseg.sh); - if (sorg(inciseg) != eorg) { - sesymself(inciseg); - } - assert(sorg(inciseg) == eorg); - eapex = sdest(inciseg); - // Check angles between segs (eorg, edest) and (eorg, eapex). - for (k = 0; k < 3; k++) { - v1[k] = edest[k] - eorg[k]; - v2[k] = eapex[k] - eorg[k]; - } - L = sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]); - for (k = 0; k < 3; k++) v1[k] /= L; - L = sqrt(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2]); - for (k = 0; k < 3; k++) v2[k] /= L; - D = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; - if (D >= cosbound) { - isacute = true; - } - } - } - if (isacute) { - setpointtype(eorg, ACUTEVERTEX); - } else { - setpointtype(eorg, NONACUTEVERTEX); - } - } - } - segloop.sh = shellfacetraverse(subsegs); - } - - delete [] idx2seglist; - delete [] segsperverlist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// finddirection() Find the first tetrahedron on the path from one point // -// to another. // -// // -// Find the tetrahedron that intersects a line segment L (from the origin of // -// 'searchtet' to the point 'tend'), and returns the result in 'searchtet'. // -// The origin of 'searchtet' does not change, even though the tetrahedron // -// returned may differ from the one passed in. This routine is used to find // -// the direction to move in to get from one point to another. // -// // -// The return value notes the location of the line segment L with respect to // -// 'searchtet': // -// - Returns RIGHTCOLLINEAR indicates L is collinear with the line segment // -// from the origin to the destination of 'searchtet'. // -// - Returns LEFTCOLLINEAR indicates L is collinear with the line segment // -// from the origin to the apex of 'searchtet'. // -// - Returns TOPCOLLINEAR indicates L is collinear with the line segment // -// from the origin to the opposite of 'searchtet'. // -// - Returns ACROSSEDGE indicates L intersects with the line segment from // -// the destination to the apex of 'searchtet'. // -// - Returns ACROSSFACE indicates L intersects with the face opposite to // -// the origin of 'searchtet'. // -// - Returns BELOWHULL indicates L crosses outside the mesh domain. This // -// can only happen when the domain is non-convex. // -// // -// NOTE: This routine only works correctly when the mesh is exactly Delaunay.// -// // -/////////////////////////////////////////////////////////////////////////////// - -enum tetgenmesh::finddirectionresult tetgenmesh:: -finddirection(triface *searchtet, point tend) -{ - triface neightet; - point tstart, tdest, tapex, toppo; - REAL ori1, ori2, ori3; - - tstart = org(*searchtet); - assert(tstart != tend); - adjustedgering(*searchtet, CCW); - if (tstart != org(*searchtet)) { - enextself(*searchtet); // For keeping the same origin. - } - tdest = dest(*searchtet); - if (tdest == tend) { - return RIGHTCOLLINEAR; - } - tapex = apex(*searchtet); - if (tapex == tend) { - return LEFTCOLLINEAR; - } - - ori1 = orient3d(tstart, tdest, tapex, tend); - if (ori1 > 0.0) { - // 'tend' is below the face, get the neighbor of this side. - sym(*searchtet, neightet); - if (neightet.tet != dummytet) { - findorg(&neightet, tstart); - adjustedgering(neightet, CCW); - if (org(neightet) != tstart) { - enextself(neightet); // keep the same origin. - } - // Set the changed configuratiuon. - *searchtet = neightet; - ori1 = -1.0; - tdest = dest(*searchtet); - tapex = apex(*searchtet); - } else { - // A hull face. Only possible for a nonconvex mesh. -#ifdef SELF_CHECK - assert(nonconvex); -#endif - return BELOWHULL; - } - } - - // Repeatedly change the 'searchtet', remain 'tstart' be its origin, until - // find a tetrahedron contains 'tend' or is crossed by the line segment - // from 'tstart' to 'tend'. - while (true) { - toppo = oppo(*searchtet); - if (toppo == tend) { - return TOPCOLLINEAR; - } - ori2 = orient3d(tstart, toppo, tdest, tend); - if (ori2 > 0.0) { - // 'tend' is below the face, get the neighbor at this side. - fnext(*searchtet, neightet); - symself(neightet); - if (neightet.tet != dummytet) { - findorg(&neightet, tstart); - adjustedgering(neightet, CCW); - if (org(neightet) != tstart) { - enextself(neightet); // keep the same origin. - } - // Set the changed configuration. - *searchtet = neightet; - ori1 = -1.0; - tdest = dest(*searchtet); - tapex = apex(*searchtet); - // Continue the search from the changed 'searchtet'. - continue; - } else { - // A hull face. Only possible for a nonconvex mesh. -#ifdef SELF_CHECK - assert(nonconvex); -#endif - return BELOWHULL; - } - } - ori3 = orient3d(tapex, toppo, tstart, tend); - if (ori3 > 0.0) { - // 'tend' is below the face, get the neighbor at this side. - enext2fnext(*searchtet, neightet); - symself(neightet); - if (neightet.tet != dummytet) { - findorg(&neightet, tstart); - adjustedgering(neightet, CCW); - if (org(neightet) != tstart) { - enextself(neightet); // keep the same origin. - } - // Set the changed configuration. - *searchtet = neightet; - ori1 = -1.0; - tdest = dest(*searchtet); - tapex = apex(*searchtet); - // Continue the search from the changed 'searchtet'. - continue; - } else { - // A hull face. Only possible for a nonconvex mesh. -#ifdef SELF_CHECK - assert(nonconvex); -#endif - return BELOWHULL; - } - } - // Now 'ori1', 'ori2' and 'ori3' are possible be 0.0 or all < 0.0; - if (ori1 < 0.0) { - // Possible cases are: ACROSSFACE, ACROSSEDGE, TOPCOLLINEAR. - if (ori2 < 0.0) { - if (ori3 < 0.0) { - return ACROSSFACE; - } else { // ori3 == 0.0; - // Cross edge (apex, oppo) - enext2fnextself(*searchtet); - esymself(*searchtet); // org(*searchtet) == tstart; - return ACROSSEDGE; - } - } else { // ori2 == 0.0; - if (ori3 < 0.0) { - // Cross edge (dest, oppo) - fnextself(*searchtet); - esymself(*searchtet); - enextself(*searchtet); // org(*searchtet) == tstart; - return ACROSSEDGE; - } else { // ori3 == 0.0; - // Collinear with edge (org, oppo) - return TOPCOLLINEAR; - } - } - } else { // ori1 == 0.0; - // Possible cases are: RIGHTCOLLINEAR, LEFTCOLLINEAR, ACROSSEDGE. - if (ori2 < 0.0) { - if (ori3 < 0.0) { - // Cross edge (tdest, tapex) - return ACROSSEDGE; - } else { // ori3 == 0.0 - // Collinear with edge (torg, tapex) - return LEFTCOLLINEAR; - } - } else { // ori2 == 0.0; - assert(ori3 != 0.0); - // Collinear with edge (torg, tdest) - return RIGHTCOLLINEAR; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getsearchtet() Find a tetrahedron whose origin is either 'p1' or 'p2'. // -// // -// On return, the origin of 'searchtet' is either 'p1' or 'p2', and 'tend' // -// returns the other point. 'searchtet' serves as the starting tetrahedron // -// for searching of the line segment from 'p1' to 'p2' or vice versa. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -getsearchtet(point p1, point p2, triface* searchtet, point* tend) -{ - tetrahedron encodedtet1, encodedtet2; - - // Is there a valid handle provided by the user? - if ((searchtet->tet != (tetrahedron *) NULL) && !isdead(searchtet)) { - // Find which endpoint the handle holds. - if (findorg(searchtet, p1)) { - *tend = p2; - return; - } else { - if (findorg(searchtet, p2)) { - *tend = p1; - return; - } - } - } - // If not, search the handle stored in 'p1' or 'p2'. - *tend = (point) NULL; - encodedtet1 = point2tet(p1); - encodedtet2 = point2tet(p2); - if (encodedtet1 != (tetrahedron) NULL) { - decode(encodedtet1, *searchtet); - // Be careful, here 'searchtet' may be dead. - if (findorg(searchtet, p1)) { - *tend = p2; - } - } else if (encodedtet2 != (tetrahedron) NULL) { - decode(encodedtet2, *searchtet); - // Be careful, here 'searchtet' may be dead. - if (findorg(searchtet, p2)) { - *tend = p1; - } - } - // If still not, perform a full point location. The starting tetrahedron - // is chosen as follows: Use the handle stored in 'p1' or 'p2' if it is - // alive; otherwise, start from a tetrahedron on the convex hull. - if (*tend == (point) NULL) { - if (encodedtet1 != (tetrahedron) NULL) { - decode(encodedtet1, *searchtet); - // Be careful, here 'searchtet' may be dead. - } - if (isdead(searchtet)) { - if (encodedtet2 != (tetrahedron) NULL) { - decode(encodedtet2, *searchtet); - // Be careful, here 'searchtet' may be dead. - } - if (isdead(searchtet)) { - searchtet->tet = dummytet; - searchtet->loc = 0; - symself(*searchtet); - } - assert(!isdead(searchtet)); - } - if (locate(p1, searchtet) != ONVERTEX) { - printf("Internal error in getsearchtet(): Failed to locate point\n"); - printf(" (%.12g, %.12g, %.12g) %d.\n", p1[0], p1[1], p1[2], - pointmark(p1)); - internalerror(); - } - // Remember this handle in 'p1' to enhance the search speed. - setpoint2tet(p1, encode(*searchtet)); - *tend = p2; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// isedgeencroached() Check whether or not a subsegment is encroached by // -// a given point. // -// // -// A segment with endpoints 'p1' and 'p2' is encroached by the point 'testpt'// -// if it lies in the diametral sphere of this segment. The degenerate case // -// that 'testpt' lies on the sphere can be treated as either be encroached // -// or not so. If you want to regard this case as be encroached, set the flag // -// 'degflag' be TRUE. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -isedgeencroached(point p1, point p2, point testpt, bool degflag) -{ - REAL dotproduct; - - // Check if the segment is facing an angle larger than 90 degree? - dotproduct = (p1[0] - testpt[0]) * (p2[0] - testpt[0]) - + (p1[1] - testpt[1]) * (p2[1] - testpt[1]) - + (p1[2] - testpt[2]) * (p2[2] - testpt[2]); - if (dotproduct < 0) { - return true; - } else if (dotproduct == 0 && degflag) { - return true; - } else { - return false; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// scoutrefpoint() Search the reference point of a missing segment. // -// // -// A segment S is missing in current Delaunay tetrahedralization DT and will // -// be split by inserting a point V in it. The two end points of S are the // -// origin of 'searchtet' and 'tend'. And we know that S is crossing the face // -// of 'searchtet' opposite to its origin (may be intersecting with the edge // -// from the destination to the apex of the 'searchtet'). The search of P is // -// completed by walking through all faces of DT across by S. // -// // -// The reference point P of S is an existing vertex of DT which is 'respon- // -// sible' for deciding where to insert V. P is chosen as follows: // -// (1) P encroaches upon S; and // -// (2) the circumradius of the smallest circumsphere of the triangle // -// formed by the two endpoints of S and P is maximum over other // -// encroaching points of S. // -// The reference point of S may not unique, choose arbitrary one if there're // -// several points available. // -// // -// Warning: This routine is correct when the tetrahedralization is Delaunay // -// and convex. Otherwise, the search loop may not terminate. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::point tetgenmesh::scoutrefpoint(triface* searchtet, point tend) -{ - triface checkface; - point tstart, testpt, refpoint; - REAL cent[3], radius, largest; - REAL ahead; - bool ncollinear; - int sides; - - if (b->verbose > 2) { - printf(" Scout the reference point of segment (%d, %d).\n", - pointmark(org(*searchtet)), pointmark(tend)); - } - - tstart = org(*searchtet); - refpoint = (point) NULL; - - // Check the three vertices of the crossing face. - testpt = apex(*searchtet); - if (isedgeencroached(tstart, tend, testpt, true)) { - ncollinear = circumsphere(tstart, tend, testpt, NULL, cent, &radius); - assert(ncollinear); - refpoint = testpt; - largest = radius; - } - testpt = dest(*searchtet); - if (isedgeencroached(tstart, tend, testpt, true)) { - ncollinear = circumsphere(tstart, tend, testpt, NULL, cent, &radius); - assert(ncollinear); - if (refpoint == (point) NULL) { - refpoint = testpt; - largest = radius; - } else { - if (radius > largest) { - refpoint = testpt; - largest = radius; - } - } - } - testpt = oppo(*searchtet); - if (isedgeencroached(tstart, tend, testpt, true)) { - ncollinear = circumsphere(tstart, tend, testpt, NULL, cent, &radius); - assert(ncollinear); - if (refpoint == (point) NULL) { - refpoint = testpt; - largest = radius; - } else { - if (radius > largest) { - refpoint = testpt; - largest = radius; - } - } - } - // Check the opposite vertex of the neighboring tet in case the segment - // crosses the edge (leftpoint, rightpoint) of the crossing face. - sym(*searchtet, checkface); - if (checkface.tet != dummytet) { - testpt = oppo(checkface); - if (isedgeencroached(tstart, tend, testpt, true)) { - ncollinear = circumsphere(tstart, tend, testpt, NULL, cent, &radius); - assert(ncollinear); - if (refpoint == (point) NULL) { - refpoint = testpt; - largest = radius; - } else { - if (radius > largest) { - refpoint = testpt; - largest = radius; - } - } - } - } - - // Walk through all crossing faces. - enextfnext(*searchtet, checkface); - sym(checkface, *searchtet); - while (true) { - // Check if we are reaching the boundary of the triangulation. - assert(searchtet->tet != dummytet); - // Search for an adjoining tetrahedron we can walk through. - searchtet->ver = 0; - // 'testpt' is the shared vertex for the following orientation tests. - testpt = oppo(*searchtet); - if (testpt == tend) { - // The searching is finished. - break; - } else { - // 'testpt' may encroach the segment. - if ((testpt != tstart) && (testpt != refpoint)) { - if (isedgeencroached(tstart, tend, testpt, true)) { - ncollinear = circumsphere(tstart, tend, testpt, NULL, cent, &radius); - if (!ncollinear) { - // 'testpt' is collinear with the segment. It may happen when a - // set of collinear and continuous segments is defined by two - // extreme endpoints. In this case, we should choose 'testpt' - // as the splitting point immediately. No new point should be - // created. - refpoint = testpt; - break; - } - if (refpoint == (point) NULL) { - refpoint = testpt; - largest = radius; - } else { - if (radius > largest) { - refpoint = testpt; - largest = radius; - } - } - } - } - } - // Check three side-faces of 'searchtet' to find the one through - // which we can walk next. - for (sides = 0; sides < 3; sides++) { - fnext(*searchtet, checkface); - ahead = orient3d(org(checkface), dest(checkface), testpt, tend); - if (ahead < 0.0) { - // We can walk through this face and continue the searching. - sym(checkface, *searchtet); - break; - } - enextself(*searchtet); - } - assert (sides < 3); - } - - assert(refpoint != (point) NULL); - return refpoint; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getsegmentorigin() Return the origin of the (unsplit) segment. // -// // -// After a segment (or a subsegment) is split. Two resulting subsegments are // -// connecting each other through the pointers saved in their data fields. // -// With these pointers, the whole (unsplit) segment can be found. 'splitseg' // -// may be a split subsegment. Returns the origin of the unsplit segment. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::point tetgenmesh::getsegmentorigin(face* splitseg) -{ - face workseg; - point farorg; - - farorg = sorg(*splitseg); - if ((pointtype(farorg) != ACUTEVERTEX) && - (pointtype(farorg) != NONACUTEVERTEX)) { - workseg = *splitseg; - do { - senext2self(workseg); - spivotself(workseg); - if (workseg.sh != dummysh) { - workseg.shver = 0; // It's a subsegment. - if (sdest(workseg) != farorg) { - sesymself(workseg); - assert(sdest(workseg) == farorg); - } - farorg = sorg(workseg); - if ((pointtype(farorg) == ACUTEVERTEX) || - (pointtype(farorg) == NONACUTEVERTEX)) break; - } - } while (workseg.sh != dummysh); - } - assert((pointtype(farorg) == ACUTEVERTEX) || - (pointtype(farorg) == NONACUTEVERTEX)); - return farorg; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// getsplitpoint() Get a point for splitting a segment. // -// // -// 'splitseg' is the segment will be split. 'refpoint' is a reference point // -// for splitting this segment. Moreover, it should not collinear with the // -// splitting segment. (The collinear case will be detected by iscollinear() // -// before entering this routine.) The calculation of the splitting point is // -// governed by three rules introduced in my paper. // -// // -// After the position is calculated, a new point is created at this location.// -// The new point has one of the two pointtypes: FREESEGVERTEX indicating it // -// is an inserting vertex on segment, and NONACUTEVERTEX indicating it is an // -// endpoint of a segment which original has type-3 now becomes type-2. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::point tetgenmesh::getsplitpoint(face* splitseg, point refpoint) -{ - point splitpoint; - point farorg, fardest; - point ei, ej, ek, c; - REAL v[3], r, split; - bool acuteorg, acutedest; - int stype, ptmark; - int i; - - // First determine the type of the segment (type-1, type-2, or type-3). - farorg = getsegmentorigin(splitseg); - acuteorg = (pointtype(farorg) == ACUTEVERTEX); - sesymself(*splitseg); - fardest = getsegmentorigin(splitseg); - acutedest = (pointtype(fardest) == ACUTEVERTEX); - sesymself(*splitseg); - - if (acuteorg) { - if (acutedest) { - stype = 3; - } else { - stype = 2; - ek = farorg; - } - } else { - if (acutedest) { - stype = 2; - // Adjust splitseg, so that its origin is acute. - sesymself(*splitseg); - ek = fardest; - } else { - stype = 1; - } - } - ei = sorg(*splitseg); - ej = sdest(*splitseg); - - if (b->verbose > 1) { - printf(" Splitting segment (%d, %d) type-%d with refpoint %d.\n", - pointmark(ei), pointmark(ej), stype, pointmark(refpoint)); - } - - if (stype == 1 || stype == 3) { - // Use rule-1. - REAL eij, eip, ejp; - eij = distance(ei, ej); - eip = distance(ei, refpoint); - ejp = distance(ej, refpoint); - if ((eip < ejp) && (eip < 0.5 * eij)) { - c = ei; - r = eip; - } else if ((eip > ejp) && (ejp < 0.5 * eij)) { - c = ej; - ej = ei; - r = ejp; - } else { - c = ei; - r = 0.5 * eij; - } - split = r / eij; - for (i = 0; i < 3; i++) { - v[i] = c[i] + split * (ej[i] - c[i]); - } - } else { - // Use rule-2 or rule-3. - REAL eki, ekj, ekp, evj, evp, eiv; - c = ek; - eki = distance(ek, ei); // eki may equal zero. - ekj = distance(ek, ej); - ekp = distance(ek, refpoint); - // Calculate v (the going to split position between ei, ej). - r = ekp; - assert(eki < r && r < ekj); - split = r / ekj; - for (i = 0; i < 3; i++) { - v[i] = c[i] + split * (ej[i] - c[i]); - } - evj = ekj - r; // distance(v, ej); - evp = distance(v, refpoint); - if (evj < evp) { - // v is rejected, use rule-3. - eiv = distance(ei, v); - if (evp <= 0.5 * eiv) { - r = eki + eiv - evp; - } else { - r = eki + 0.5 * eiv; - } - assert(eki < r && r < ekj); - split = r / ekj; - for (i = 0; i < 3; i++) { - v[i] = c[i] + split * (ej[i] - c[i]); - } - if (b->verbose > 1) { - printf(" Using rule-3.\n"); - } - } - } - - if (b->verbose > 1) { - if (stype == 2) { - printf(" Split = %.12g.\n", distance(ei, v) / distance(ei, ej)); - } else { - printf(" Split = %.12g.\n", distance(c, v) / distance(c, ej)); - } - } - - // Allocate a point from points. - splitpoint = (point) points->alloc(); - // Set its coordinates. - for (i = 0; i < 3; i++) { - splitpoint[i] = v[i]; - } - // Interpolate its attributes. - for (i = 0; i < in->numberofpointattributes; i++) { - splitpoint[i + 3] = c[i + 3] + split * (ej[i + 3] - c[i + 3]); - } - // Remember the index (starts from 'in->firstnumber') of this vertex. - ptmark = (int) points->items - (in->firstnumber == 1 ? 0 : 1); - setpointmark(splitpoint, ptmark); - if (stype == 3) { - // Change a type-3 segment into two type-2 segments. - setpointtype(splitpoint, NONACUTEVERTEX); - } else { - // Set it's type be FREESEGVERTEX. - setpointtype(splitpoint, FREESEGVERTEX); - } - // Init this field. - setpoint2tet(splitpoint, NULL); - - return splitpoint; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// delaunizesegments() Split segments repeatedly until they appear in a // -// Delaunay tetrahedralization together. // -// // -// Given a PLC X, which has a set V of vertices and a set of segments. Start // -// from a Delaunay tetrahedralization D of V, this routine recovers segments // -// of X in D by incrementally inserting points on missing segments, updating // -// D with the newly inserted points into D', which remains to be a Delaunay // -// tetrahedralization and respects the segments of X. Hence, each segment of // -// X appears as a union of edges in D'. // -// // -// This routine dynamically maintains two meshes, one is DT, another is the // -// surface mesh F of X. DT and F have exactly the same vertices. They are // -// updated simultaneously with the newly inserted points. // -// // -// Missing segments are found by looping the set S of segments, checking the // -// existence of each segment in DT. Once a segment is found missing in DT, // -// it is split into two subsegments by inserting a point into both DT and F, // -// and S is updated accordingly. However, the inserted point may cause some // -// other existing segments be non-Delaunay, hence are missing from the DT. // -// In order to force all segments to appear in DT, we have to loop S again // -// after some segments are split. (A little ugly method) Use a handle to // -// remember the last segment be split in one loop, hence all segments after // -// it are existing and need not be checked. // -// // -// In priciple, a segment on the convex hull should exist in DT. However, if // -// there are four coplanar points on the convex hull, and the DT only can // -// contain one diagonal edge which is unfortunately not the segment, then it // -// is missing. During the recovery of the segment, it is possible that the // -// calculated inserting point for recovering this convex hull segment is not // -// exact enough and lies (slightly) outside the DT. In order to insert the // -// point, we enlarge the convex hull of the DT, so it can contain the point // -// and remains convex. 'inserthullsite()' is called under this case. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::delaunizesegments() -{ - queue *flipqueue; - triface searchtet; - face segloop, lastsplit; - face splitsh; - point p1, p2; - point tend, checkpoint; - point refpoint, splitpoint; - enum finddirectionresult collinear; - enum insertsiteresult success; - bool finish; - - if (!b->quiet) { - printf("Delaunizing segments.\n"); - } - - // Mark segment vertices (acute or not) for determining segment types. - markacutevertices(60.0); - // Construct a map from points to tetrahedra for speeding point location. - makepoint2tetmap(); - // Initialize a queue for returning non-Delaunay faces and edges. - flipqueue = new queue(sizeof(badface)); - // 'lastsplit' is the last segment be split in one loop, all segments - // after it are existing. At first, set it be NULL; - lastsplit.sh = (shellface *) NULL; - - finish = false; - while (!finish && (steinerleft != 0)) { - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while ((segloop.sh != (shellface *) NULL) && (steinerleft != 0)) { - // Search the segment in DT. - p1 = sorg(segloop); - p2 = sdest(segloop); - if (b->verbose > 2) { - printf(" Checking segment (%d, %d).\n", pointmark(p1), pointmark(p2)); - } - getsearchtet(p1, p2, &searchtet, &tend); - collinear = finddirection(&searchtet, tend); - if (collinear == LEFTCOLLINEAR) { - checkpoint = apex(searchtet); - } else if (collinear == RIGHTCOLLINEAR) { - checkpoint = dest(searchtet); - } else if (collinear == TOPCOLLINEAR) { - checkpoint = oppo(searchtet); - } else { - assert(collinear == ACROSSFACE || collinear == ACROSSEDGE); - checkpoint = (point) NULL; - } - if (checkpoint != tend) { - // The segment is missing. - if (checkpoint != (point) NULL) { - splitpoint = checkpoint; - } else { - refpoint = scoutrefpoint(&searchtet, tend); - if (iscollinear(p1, p2, refpoint, b->epsilon)) { - splitpoint = refpoint; - } else { - splitpoint = getsplitpoint(&segloop, refpoint); - // Insert 'splitpoint' into DT. - success = insertsite(splitpoint, &searchtet, false, flipqueue); - if (success == OUTSIDEPOINT) { - // A convex hull edge is mssing, and the inserting point lies - // (slightly) outside the convex hull due to the significant - // digits lost in the calculation. Enlarge the convex hull. - inserthullsite(splitpoint, &searchtet, flipqueue, NULL, NULL); - } - if (steinerleft > 0) steinerleft--; - // Remember a handle in 'splitpoint' to enhance the speed of - // consequent point location. - setpoint2tet(splitpoint, encode(searchtet)); - // Maintain Delaunayness in DT. - flip(flipqueue, NULL); - } - } - // Insert 'splitpoint' into F. - spivot(segloop, splitsh); - splitsubedge(splitpoint, &splitsh, flipqueue); - flipsub(flipqueue); - // Remember 'segloop'. - lastsplit = segloop; - } else { - // The segment exists. - if (segloop.sh == lastsplit.sh) { - finish = true; - break; - } - } - segloop.sh = shellfacetraverse(subsegs); - } - if (lastsplit.sh == (shellface *) NULL) { - // No missing segment! - finish = true; - } - } - - delete flipqueue; -} - -// -// End of segments recovery routines -// - -// -// Begin of constrained Delaunay triangulation routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// insertsubface() Insert a subface into the Delaunay tetrahedralization. // -// // -// Search the subface in current Delaunay tetrahedralization. Return TRUE if // -// the subface exists, i.e., it appears as a face of the DT and is inserted. // -// Otherwise, return FALSE indicating it is a missing face. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::insertsubface(face* insertsh, triface* searchtet) -{ - triface spintet, symtet; - face testsh, testseg; - face spinsh, casin, casout; - point tapex, checkpoint; - enum finddirectionresult collinear; - int hitbdry; - - // Search one edge of 'insertsh'. - getsearchtet(sorg(*insertsh), sdest(*insertsh), searchtet, &checkpoint); - collinear = finddirection(searchtet, checkpoint); - if (collinear == LEFTCOLLINEAR) { - enext2self(*searchtet); - esymself(*searchtet); - } else if (collinear == TOPCOLLINEAR) { - fnextself(*searchtet); - enext2self(*searchtet); - esymself(*searchtet); - } - if (dest(*searchtet) != checkpoint) { - // The edge is missing => subface is missing. - return false; - } - - // Spin around the edge (torg, tdest), look for a face containing tapex. - tapex = sapex(*insertsh); - spintet = *searchtet; - hitbdry = 0; - do { - if (apex(spintet) == tapex) { - // The subface is exist in DT. We will insert this subface. Before - // insertion, make sure there is no subface at this position. - tspivot(spintet, testsh); - if (testsh.sh == dummysh) { - adjustedgering(spintet, CCW); - findedge(insertsh, org(spintet), dest(spintet)); - tsbond(spintet, *insertsh); - sym(spintet, symtet); // 'symtet' maybe outside, use it anyway. - sesymself(*insertsh); - tsbond(symtet, *insertsh); - } else { - // There already exists one subface. They're Duplicated. - printf("Warning: Two subfaces are found duplicated at "); - printf("(%d, %d, %d)\n", pointmark(sorg(testsh)), - pointmark(sdest(testsh)), pointmark(sapex(testsh))); - printf(" The one of facet #%d is ignored.\n", shellmark(*insertsh)); - // printf(" Hint: -d switch can find all duplicated facets.\n"); - } - return true; - } - if (!fnextself(spintet)) { - hitbdry ++; - if (hitbdry < 2) { - esym(*searchtet, spintet); - if (!fnextself(spintet)) { - hitbdry ++; - } - } - } - } while (hitbdry < 2 && apex(spintet) != apex(*searchtet)); - - // The face is missing. - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tritritest() Test if two triangles are intersecting in their interior. // -// // -// One triangles is represented by 'checktet', the other is given by three // -// corners 'p1', 'p2' and 'p3'. This routine calls triangle_triangle_inter() // -// to detect whether or not these two triangles are exactly intersecting in // -// their interior (excluding the cases share a vertex, share an edge, or are // -// coincide). // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::tritritest(triface* checktet, point p1, point p2, point p3) -{ - point forg, fdest, fapex; - enum intersectresult intersect; - - forg = org(*checktet); - fdest = dest(*checktet); - fapex = apex(*checktet); - -#ifdef SELF_CHECK - REAL ax, ay, az, bx, by, bz; - REAL n[3]; - // face (torg, tdest, tapex) should not be degenerate. However p1, p2, - // and p3 may be collinear. Check it. - ax = forg[0] - fdest[0]; - ay = forg[1] - fdest[1]; - az = forg[2] - fdest[2]; - bx = forg[0] - fapex[0]; - by = forg[1] - fapex[1]; - bz = forg[2] - fapex[2]; - n[0] = ay * bz - by * az; - n[1] = az * bx - bz * ax; - n[2] = ax * by - bx * ay; - assert(fabs(n[0]) + fabs(n[1]) + fabs(n[2]) > 0.0); - // The components of n should not smaller than the machine epsilon. - - ax = p1[0] - p2[0]; - ay = p1[1] - p2[1]; - az = p1[2] - p2[2]; - bx = p1[0] - p3[0]; - by = p1[1] - p3[1]; - bz = p1[2] - p3[2]; - n[0] = ay * bz - by * az; - n[1] = az * bx - bz * ax; - n[2] = ax * by - bx * ay; - assert(fabs(n[0]) + fabs(n[1]) + fabs(n[2]) > 0.0); - // The components of n should not smaller than the machine epsilon. -#endif - - intersect = triangle_triangle_inter(forg, fdest, fapex, p1, p2, p3); - return intersect == INTERSECT; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// initializecavity() Create the initial fronts. // -// // -// 'floorlist' is a list of coplanar subfaces, they are oriented in the same // -// direction pointing to the ceiling. 'ceilinglist' is a list of faces of // -// tetrahedra which are crossing the cavity, they form the rest part of the // -// boundary of the cavity. 'frontlink' is used to return the list of fronts, // -// it is empty on input. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -initializecavity(list* floorlist, list* ceillist, list* floorptlist, - list* ceilptlist, link* frontlink, link* ptlink) -{ - triface neightet, casingtet; - triface faketet; - face worksh; - int i; - - // First add all faces in 'floorlist' into 'frontlink'. - for (i = 0; i < floorlist->len(); i++) { - worksh = * (face *)(* floorlist)[i]; - // Current side of 'worksh' should be empty. - stpivot(worksh, neightet); - assert(neightet.tet == dummytet); - // Check another side, if there is no tetrahedron, create a 'fake' - // tetrahedron in order to hold this side. It will be removed - // during filling the cavity. - sesymself(worksh); - stpivot(worksh, casingtet); - if (casingtet.tet == dummytet) { - maketetrahedron(&faketet); - setorg(faketet, sorg(worksh)); - setdest(faketet, sdest(worksh)); - setapex(faketet, sapex(worksh)); - setoppo(faketet, (point) NULL); // Indicates it is 'fake'. - tsbond(faketet, worksh); - frontlink->add(&faketet); - } else { - frontlink->add(&casingtet); - } - } - // Second add all casing faces in 'ceilinglist' into 'frontlink'. - for (i = 0; i < ceillist->len(); i++) { - neightet = * (triface *) (* ceillist)[i]; - // The ceil is a face of cavity tetrahedron (going to be deleted). - assert(infected(neightet)); - sym(neightet, casingtet); - if (casingtet.tet == dummytet) { - // This side is on the hull. Create a 'fake' tetrahedron in order to - // hold this side. It will be removed during filling the cavity. - tspivot(neightet, worksh); - maketetrahedron(&faketet); - setorg(faketet, org(neightet)); - setdest(faketet, dest(neightet)); - setapex(faketet, apex(neightet)); - setoppo(faketet, (point) NULL); // Indicates it is 'fake'. - if (worksh.sh != dummysh) { - sesymself(worksh); - tsbond(faketet, worksh); - } - frontlink->add(&faketet); - } else { - frontlink->add(&casingtet); - } - } - // Put points in 'equatptlist' and 'ceilptlist' into 'ptlink'. - for (i = 0; i < floorptlist->len(); i++) { - ptlink->add((point *)(* floorptlist)[i]); - } - for (i = 0; i < ceilptlist->len(); i++) { - ptlink->add((point *)(* ceilptlist)[i]); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// reducecavity() Reduce the cavity by chopping off tetrahedra formed by // -// faces in 'frontlink' without creating new edges. // -// // -// When a face of cavity has three neighbors which are sharing a same vertex,// -// form a tetrahedron from the face and the vertex, consequently, four faces // -// of the cavity are removed. If only two of its three neighbors share a // -// common vertex, it only can form a tetrahedron when no vertex of the // -// cavity lies inside the tetrahedorn, consequently, three faces are removed // -// from the cavity and a face(at the open side) becomes a face of the cavity.// -// // -// Not every face of the cavity can be removed by this way. This routine // -// returns when there is no face can be removed. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::reducecavity(link* frontlink, link* ptlink, queue* flipqueue) -{ - triface front, *neigh[3], *checkface; - triface newtet, newface; - face checksh; - point *ploop; - point forg, fdest; - point workpt[3], shareoppo; - REAL sign; - bool isneighbor, isconvex; - int loopcount, share; - int i, j, k; - - if (b->verbose > 2) { - printf(" Reducecavity: %d faces.\n", (int) frontlink->len()); - } - - loopcount = 0; - while (loopcount < frontlink->len()) { - // Get and remove a front face from 'fronlink'. - front = * (triface *) frontlink->del(1); - // Make the front point to insde the cavity. - adjustedgering(front, CW); - if (b->verbose > 2) { - printf(" Get front (%d, %d, %d).\n", pointmark(org(front)), - pointmark(dest(front)), pointmark(apex(front))); - } - // Find the three neighbors of 'front' in 'frontlink'. They must exist, - // because the cavity is closed. - for (i = 0; i < 3; i++) { - forg = org(front); - fdest = dest(front); - isneighbor = false; - for (j = 0; j < frontlink->len() && !isneighbor; j++) { - checkface = (triface *) frontlink->getnitem(j + 1); - for (k = 0; k < 3; k++) { - workpt[0] = org(*checkface); - workpt[1] = dest(*checkface); - if (workpt[0] == forg) { - if (workpt[1] == fdest) isneighbor = true; - } else if (workpt[0] == fdest) { - if (workpt[1] == forg) isneighbor = true; - } - if (isneighbor) { - neigh[i] = checkface; - break; - } - enextself(*checkface); - } - } - assert(isneighbor); - enextself(front); - } - - // Find the number of common apexes. - for (i = 0; i < 3; i++) { - workpt[i] = apex(*neigh[i]); - } - if (workpt[0] == workpt[1]) { - shareoppo = workpt[0]; - if (workpt[1] == workpt[2]) { - share = 3; - } else { - share = 2; - } - } else if (workpt[0] == workpt[2]) { - shareoppo = workpt[0]; - share = 2; - } else { - if (workpt[1] == workpt[2]) { - shareoppo = workpt[1]; - share = 2; - } else { - share = 1; - } - } - - if (share == 2) { - // It is possible that the open side is also a cavity face, but not - // pop up because there are more than two cavity faces sharing the - // edge. Check is there a cavity face having this edge and having - // its apex be 'shareoppo'. - for (i = 0; i < 3; i++) { - if (workpt[i] != shareoppo) { - // 'neigh[i]' is the open side. Get the edge. - forg = org(*neigh[i]); - fdest = dest(*neigh[i]); - break; - } - } - assert(i < 3); - // Search faces containing edge (forg, fdest) in 'frontlist'. If - // the found face containing 'shareoppo', stop; - for (j = 0; j < frontlink->len() && share != 3; j++) { - checkface = (triface *) frontlink->getnitem(j + 1); - // Skip if it is one of the neighbors. - if ((checkface == neigh[0]) || (checkface == neigh[1]) || - (checkface == neigh[2])) continue; - isneighbor = false; - for (k = 0; k < 3; k++) { - workpt[0] = org(*checkface); - workpt[1] = dest(*checkface); - if (workpt[0] == forg) { - if (workpt[1] == fdest) isneighbor = true; - } else if (workpt[0] == fdest) { - if (workpt[1] == forg) isneighbor = true; - } - if (isneighbor) { - if (apex(*checkface) == shareoppo) { - // Find! Change the old neighbor at this side be this one. - neigh[i] = checkface; - share = 3; - break; - } - } - enextself(*checkface); - } - } - } - - isconvex = true; - if (share == 2 || share == 3) { - // It is possible to reduce the cavity by constructing a tetrahedron - // from the face 'front' and 'shareoppo'. However, we have to make - // sure that this tetrahedron is valid, i.e., shareoppo should lie - // above front. - workpt[0] = org(front); - workpt[1] = dest(front); - workpt[2] = apex(front); - sign = orient3d(workpt[0], workpt[1], workpt[2], shareoppo); - if (sign > 0.0) { - // It is not a valid tetrahedron, skip to create it. - isconvex = false; - } else if (sign == 0.0) { - // These four points are coplanar. If there are only three faces - // left, we should stop here. Create a degenerate tetrahedron - // on these four faces and return. It will be repaired later. - if (frontlink->len() > 3) { - isconvex = false; - } - } - } - if (share == 2 && isconvex) { - // Check if we can reduce the tetrahedron formed by the front and the - // shareoppo. The condition is no vertex is inside the tetrahedron. - for (i = 0; i < ptlink->len() && isconvex; i++) { - ploop = (point *) ptlink->getnitem(i + 1); - if (*ploop == workpt[0] || *ploop == workpt[1] || *ploop == workpt[2] - || *ploop == shareoppo) continue; - sign = orient3d(workpt[0], workpt[1], workpt[2], *ploop); - isconvex = sign > 0.0; - if (isconvex) continue; - sign = orient3d(workpt[1], workpt[0], shareoppo, *ploop); - isconvex = sign > 0.0; - if (isconvex) continue; - sign = orient3d(workpt[2], workpt[1], shareoppo, *ploop); - isconvex = sign > 0.0; - if (isconvex) continue; - sign = orient3d(workpt[0], workpt[2], shareoppo, *ploop); - isconvex = sign > 0.0; - } - } - - if (share == 1 || !isconvex) { - // Put 'front' back into 'frontlink'. - frontlink->add(&front); - loopcount++; // Increase the loop counter. - continue; - } else { - // Find a reducable tetrahedron. Reset the loop counter. - loopcount = 0; - } - - if (b->verbose > 2) { - for (i = 0; i < 3; i++) { - if (apex(*neigh[i]) == shareoppo) { - printf(" (%d, %d, %d).\n", pointmark(org(*neigh[i])), - pointmark(dest(*neigh[i])), pointmark(apex(*neigh[i]))); - } - } - } - - // The front will be finished by two or three faces. - maketetrahedron(&newtet); - setorg(newtet, org(front)); - setdest(newtet, dest(front)); - setapex(newtet, apex(front)); - setoppo(newtet, shareoppo); - // 'front' may be a 'fake' tet. - tspivot(front, checksh); - if (oppo(front) == (point) NULL) { - // Dealloc the 'fake' tet. - tetrahedrondealloc(front.tet); - // This side (newtet) is a boundary face, let 'dummytet' bond to it. - // Otherwise, 'dummytet' may point to a dead tetrahedron after the - // old cavity tets are removed. - dummytet[0] = encode(newtet); - } else { - // Bond two tetrahedra, also dissolve the old bond at 'front'. - bond(newtet, front); - // 'front' becomes an interior face, add it to 'flipqueue'. - if (flipqueue != (queue *) NULL) { - enqueueflipface(front, flipqueue); - } - } - if (checksh.sh != dummysh) { - if (oppo(front) == (point) NULL) { - stdissolve(checksh); - } - sesymself(checksh); - tsbond(newtet, checksh); - } - // Bond the neighbor faces to 'newtet'. - for (i = 0; i < 3; i++) { - fnext(newtet, newface); - if (apex(*neigh[i]) == shareoppo) { - // This side is finished. 'neigh[i]' may be a 'fake' tet. - tspivot(*neigh[i], checksh); - if (oppo(*neigh[i]) == (point) NULL) { - // Dealloc the 'fake' tet. - tetrahedrondealloc(neigh[i]->tet); - // This side (newface) is a boundary face, let 'dummytet' bond to - // it. Otherwise, 'dummytet' may point to a dead tetrahedron - // after the old cavity tets are removed. - dummytet[0] = encode(newface); - } else { - // Bond two tetrahedra, also dissolve the old bond at 'neigh[i]'. - bond(newface, *neigh[i]); - // 'neigh[i]' becomes an interior face, add it to 'flipqueue'. - if (flipqueue != (queue *) NULL) { - enqueueflipface(*neigh[i], flipqueue); - } - } - if (checksh.sh != dummysh) { - if (oppo(*neigh[i]) == (point) NULL) { - stdissolve(checksh); - } - sesymself(checksh); - tsbond(newface, checksh); - } - // Remove it from the link. - frontlink->del(neigh[i]); - } else { - // This side is unfinished. Add 'newface' into 'frontlink'. - frontlink->add(&newface); - } - // Get the face in 'newtet' corresponding to 'neigh[i]'. - enextself(newtet); - } - } // End of while loop. - - return frontlink->len() == 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// reducecavity1() Reduce the cavity by forming a new tetrahedron from a // -// cavity face to a visible point. As a result, create // -// one or more new edges inside the cavity. // -// // -// We know that the cavity is not simply reducable, we have to create new // -// faces inside the cavity in order to reduce the cavity. This routine finds // -// the most suitable edge we can create in the cavity. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::reducecavity1(link* frontlink, queue* flipqueue) -{ - list *edgelist; - triface front, *neigh[3], *checkface; - triface newtet, newface; - face checksh; - point forg, fdest; - point workpt[3], *edgeends; - REAL sign; - bool isneighbor, isvalid; - bool isexist, isfind; - bool isreducable; - unsigned long count; - int loopcount; - int i, j, k; - - if (b->verbose > 2) { - printf(" Reducecavity1: %d faces.\n", (int) frontlink->len()); - } - - // Initialize 'edgelist'. Each edge has two endpoints and 1 counter. - edgelist = new list(sizeof(point) * 3, NULL); - - loopcount = 0; - while (loopcount < frontlink->len()) { - front = * (triface *) frontlink->getnitem(loopcount + 1); - // Make the front point to the inside of the cavity. - adjustedgering(front, CW); - if (b->verbose > 2) { - printf(" Get front (%d, %d, %d).\n", pointmark(org(front)), - pointmark(dest(front)), pointmark(apex(front))); - } - // Find the three neighbors of 'front' in 'frontlink'. - for (i = 0; i < 3; i++) { - forg = org(front); - fdest = dest(front); - isneighbor = false; - for (j = 0; j < frontlink->len() && !isneighbor; j++) { - if (j == loopcount) continue; - checkface = (triface *) frontlink->getnitem(j + 1); - for (k = 0; k < 3; k++) { - workpt[0] = org(*checkface); - workpt[1] = dest(*checkface); - if (workpt[0] == forg) { - if (workpt[1] == fdest) isneighbor = true; - } else if (workpt[0] == fdest) { - if (workpt[1] == forg) isneighbor = true; - } - if (isneighbor) { - neigh[i] = checkface; - break; - } - enextself(*checkface); - } - } - assert(isneighbor); - enextself(front); - } - // Check the three edges which are possibly created in cavity. - for (i = 0; i < 3; i++) { - // 'forg', 'fdest' is the edge. - forg = apex(front); - fdest = apex(*neigh[i]); - // Two face vertices. - workpt[0] = org(front); - workpt[1] = dest(front); - // Only do check if these four points form a positive volume. Allow - // the case that they are coplanar. - sign = orient3d(workpt[0], workpt[1], forg, fdest); - if (sign <= 0.0) { - // Check the face (forg, fdest, workpt[i]) is valid or not. - isvalid = true; - for (j = 0; j < 2 && isvalid; j++) { - // Skip the following tests if the face is (nearly) degenerate. - if (iscollinear(forg, fdest, workpt[j], b->epsilon)) { - isvalid = false; - } - for (k = 0; k < frontlink->len() && isvalid; k++) { - if (k == loopcount) continue; - checkface = (triface *) frontlink->getnitem(k + 1); - if (checkface == neigh[i]) continue; - isvalid = !tritritest(checkface, forg, fdest, workpt[j]); - } - } - if (isvalid) { - // This edge can be created. Check in 'edgelist', if it is not - // in there, add it, if it exists, increase its counter. - isexist = false; - for (j = 0; j < edgelist->len() && !isexist; j++) { - edgeends = (point *)(* edgelist)[j]; - if (edgeends[0] == forg) { - if (edgeends[1] == fdest) isexist = true; - } else if (edgeends[0] == fdest) { - if (edgeends[1] == forg) isexist = true; - } - } - if (!isexist) { - // Not exist, add it into 'edgelist'. - if (b->verbose > 2) { - printf(" Add edge (%d, %d).\n", pointmark(forg), - pointmark(fdest)); - } - edgeends = (point *) edgelist->append(NULL); - edgeends[0] = forg; - edgeends[1] = fdest; - edgeends[2] = (point) 1; - } else { - // Exist, only increase its counter. - if (b->verbose > 2) { - printf(" Increase edge (%d, %d)'s counter.\n", - pointmark(forg), pointmark(fdest)); - } - count = (unsigned long)(edgeends[2]); - edgeends[2] = (point) (++count); - } - } - } - enextself(front); - } - loopcount++; - } - - isreducable = edgelist->len() > 0; - - if (edgelist->len() > 0) { - // Get the edge which has the largest counter. - k = 0; - for (i = 0; i < edgelist->len(); i++) { - edgeends = (point *)(* edgelist)[i]; - count = (unsigned long)(edgeends[2]); - if (k < (int) count) { - k = (int) count; - j = i; - } - } - // Get the edge we want to create. - edgeends = (point *)(* edgelist)[j]; - if (b->verbose > 2) { - printf(" Create new edge (%d, %d).\n", pointmark(edgeends[0]), - pointmark(edgeends[1])); - } - // Find two adjacent faces in 'frontlink' conatining this edge's ends. - neigh[0] = neigh[1] = (triface *) NULL; - isfind = false; - for (i = 0; i < frontlink->len() && !isfind; i++) { - checkface = (triface *) frontlink->getnitem(i + 1); - for (j = 0; j < 3; j++) { - if (apex(*checkface) == edgeends[0]) { - neigh[0] = checkface; - break; - } - enextself(*checkface); - } - if (neigh[0] != (triface *) NULL) { - forg = org(*neigh[0]); - fdest = dest(*neigh[0]); - for (k = 0; k < frontlink->len(); k++) { - if (k == i) continue; - checkface = (triface *) frontlink->getnitem(k + 1); - isneighbor = false; - for (j = 0; j < 3; j++) { - workpt[0] = org(*checkface); - workpt[1] = dest(*checkface); - if (workpt[0] == forg) { - if (workpt[1] == fdest) isneighbor = true; - } else if (workpt[0] == fdest) { - if (workpt[1] == forg) isneighbor = true; - } - if (isneighbor) break; - enextself(*checkface); - } - if (isneighbor) { - if (apex(*checkface) == edgeends[1]) { - neigh[1] = checkface; - isfind = true; - break; - } - } - } - if (neigh[1] == (triface *) NULL) { - neigh[0] = (triface *) NULL; - } - } - } - assert(isfind); - if (b->verbose > 2) { - for (i = 0; i < 2; i++) { - printf(" Finish face (%d, %d, %d).\n", pointmark(org(*neigh[i])), - pointmark(dest(*neigh[i])), pointmark(apex(*neigh[i]))); - } - } - // Make the front point inside the cavity. - front = *neigh[0]; - adjustedgering(front, CW); - maketetrahedron(&newtet); - setorg(newtet, org(front)); - setdest(newtet, dest(front)); - setapex(newtet, apex(front)); - setoppo(newtet, edgeends[1]); - // 'front' may be a 'fake' tet. - tspivot(front, checksh); - if (oppo(front) == (point) NULL) { - // Dealloc the 'fake' tet. - tetrahedrondealloc(front.tet); - // This side (newtet) is a boundary face, let 'dummytet' bond to it. - // Otherwise, 'dummytet' may point to a dead tetrahedron after the - // old cavity tets are removed. - dummytet[0] = encode(newtet); - } else { - // Bond two tetrahedra, also dissolve the old bond at 'front'. - bond(newtet, front); - // 'front' becomes an interior face, add it to 'flipqueue'. - if (flipqueue != (queue *) NULL) { - enqueueflipface(front, flipqueue); - } - } - if (checksh.sh != dummysh) { - if (oppo(front) == (point) NULL) { - stdissolve(checksh); - } - sesymself(checksh); - tsbond(newtet, checksh); - } - fnext(newtet, newface); - // 'neigh[1]' may be a 'fake' tet. - tspivot(*neigh[1], checksh); - if (oppo(*neigh[1]) == (point) NULL) { - // Dealloc the 'fake' tet. - tetrahedrondealloc(neigh[1]->tet); - // This side (newface) is a boundary face, let 'dummytet' bond to it. - // Otherwise, 'dummytet' may point to a dead tetrahedron after the - // old cavity tets are removed. - dummytet[0] = encode(newface); - } else { - // Bond two tetrahedra, also dissolve the old bond at 'newface'. - bond(*neigh[1], newface); - // 'neigh[0]' becomes an interior face, add it to 'flipqueue'. - if (flipqueue != (queue *) NULL) { - enqueueflipface(*neigh[1], flipqueue); - } - } - if (checksh.sh != dummysh) { - if (oppo(*neigh[1]) == (point) NULL) { - stdissolve(checksh); - } - sesymself(checksh); - tsbond(newface, checksh); - } - // Remove 'neigh[0]', 'neigh[1]' from 'frontlink'. - frontlink->del(neigh[0]); - frontlink->del(neigh[1]); - // Add two new faces into 'frontlink'. - enextfnext(newtet, newface); - frontlink->add(&newface); - enext2fnext(newtet, newface); - frontlink->add(&newface); - } - - delete edgelist; - return isreducable; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// triangulatecavity() Triangulate a cavity by filling a set of Delaunay // -// tetrahedra inside. // -// // -// The boundary of the cavity is consisted of two list of triangular faces. // -// 'floorlist' is a list of coplanar subfaces. All subfaces are oriented in // -// the same direction so that the cavity is in the above part of each face. // -// 'ceilinglist' is a list of faces of tetrahedra which are crossing the // -// cavity, they form the rest part of the boundary of the cavity. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -triangulatecavity(list* floorlist, list* ceillist, list* floorptlist, - list* ceilptlist) -{ - link *frontlink; - link *ptlink; - queue *flipqueue; - - if (b->verbose > 1) { - printf(" Triangulate cavity %d floors, %d ceilings.\n", - floorlist->len(), ceillist->len()); - } - - // Initialize flipqueue; - flipqueue = new queue(sizeof(badface)); - // Initialize 'frontlink', 'ptlink'. - frontlink = new link(sizeof(triface), NULL, 256); - ptlink = new link(sizeof(point), NULL, 256); - - initializecavity(floorlist, ceillist, floorptlist, ceilptlist, frontlink, - ptlink); - - // Loop until 'frontlink' is empty. - while (frontlink->len() > 0) { - // Shrink the cavity by finishing easy connected fronts. - if (!reducecavity(frontlink, ptlink, flipqueue)) { - // Create new fronts inside the cavity (may insert point(s)). - if (!reducecavity1(frontlink, flipqueue)) { - // reducecavity2(frontlink, flipqueue); - assert(0); - } - } - } - // Some inner faces may need be flipped. - flip(flipqueue, NULL); - - delete frontlink; - delete ptlink; - delete flipqueue; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// formmissingregion() Form the missing region from a given missing face. // -// // -// 'missingsh' is a missing subface. Start from it, we can find the missing // -// adjoinging subfaces. More detail, remember that all missing subfaces have // -// been infected, and missing region of a facet is bounded by facet segments.// -// All missing subfaces of the region can be found by checking the neighbors // -// of 'missingsh', and the neighbors of the neighbors, and so on. // -// // -// 'missingshlist' returns all missing subfaces of this region, furthermore, // -// the edge rings of these subfaces are oriented in the same direction. // -// 'equatptlist' returns the vertices of the missing subfaces. Both lists // -// should be empty on input. 'worklist' is used for marking vertices of the // -// missing region. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -formmissingregion(face* missingsh, list* missingshlist, list* equatptlist, - int* worklist) -{ - face neighsh, worksh, workseg; - point workpt[3]; - int idx, i, j; - - // Add 'missingsh' into 'missingshlist'. - missingshlist->append(missingsh); - // Save and mark its three vertices. - workpt[0] = sorg(*missingsh); - workpt[1] = sdest(*missingsh); - workpt[2] = sapex(*missingsh); - for (i = 0; i < 3; i++) { - idx = pointmark(workpt[i]) - in->firstnumber; - worklist[idx] = 1; - equatptlist->append(&workpt[i]); - } - // Temporarily uninfect it (avoid to save it again). - suninfect(*missingsh); - - // Find other missing subfaces. - for (i = 0; i < missingshlist->len(); i++) { - // Get a missing subface. - worksh = * (face *)(* missingshlist)[i]; - // Check three neighbors of this face. - for (j = 0; j < 3; j++) { - sspivot(worksh, workseg); - if (workseg.sh == dummysh) { - spivot(worksh, neighsh); - if (sinfected(neighsh)) { - // Find a missing subface, adjust the edge ring. - if (sorg(neighsh) != sdest(worksh)) { - sesymself(neighsh); - } - if (b->verbose > 2) { - printf(" Add missing subface (%d, %d, %d).\n", - pointmark(sorg(neighsh)), pointmark(sdest(neighsh)), - pointmark(sapex(neighsh))); - } - missingshlist->append(&neighsh); - // Save and mark its apex. - workpt[0] = sapex(neighsh); - idx = pointmark(workpt[0]) - in->firstnumber; - worklist[idx] = 1; - equatptlist->append(&workpt[0]); - // Temporarily uninfect it (avoid to save it again). - suninfect(neighsh); - } - } - senextself(worksh); - } - } - - // The missing region has been formed. Infect missing subfaces again. - for (i = 0; i < missingshlist->len(); i++) { - worksh = * (face *)(* missingshlist)[i]; - sinfect(worksh); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// scoutcrossingedge() Search an edge crossing the missing region. // -// // -// 'missingshlist' contains all subfaces of the missing region. This routine // -// first form a 'boundedgelist' consists of all boundary edges of the region,// -// which are existing in DT (because they are either edges of existing faces // -// or segments of the facet). A crossing edge is found by rotating faces of // -// DT around one of the boundary edges. It is possible that there is no edge // -// crosses the missing region (e.g. the region has a degenerate point set). // -// // -// If find a croosing edge, return TRUE, and 'crossedgelist' contains this // -// edge. Otherwise, return FALSE. Both 'boundedgelist' and 'crossedgelist' // -// should be empty on input. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -scoutcrossingedge(list* missingshlist, list* boundedgelist, - list* crossedgelist, int* worklist) -{ - triface starttet, spintet, worktet; - face startsh, neighsh, worksh, workseg; - point torg, tdest, tapex, workpt[3]; - enum finddirectionresult collinear; - bool crossflag, inlistflag; - int hitbdry, i, j, k; - - // Form the 'boundedgelist'. Loop through 'missingshlist', check edges - // of these subfaces. If an edge is a subsegment, or the neighbor - // subface is uninfected, add it to 'boundedgelist'. - for (i = 0; i < missingshlist->len(); i++) { - worksh = * (face *)(* missingshlist)[i]; - for (j = 0; j < 3; j++) { - sspivot(worksh, workseg); - if (workseg.sh == dummysh) { - spivot(worksh, neighsh); - if (!sinfected(neighsh)) { - boundedgelist->append(&worksh); - } - } else { - boundedgelist->append(&worksh); - } - senextself(worksh); - } - } - - crossflag = false; - // Find a crossing edge. It is possible there is no such edge. We need to - // loop through all edges of 'boundedgelist' for sure we don't miss any. - for (i = 0; i < boundedgelist->len() && !crossflag; i++) { - startsh = * (face *)(* boundedgelist)[i]; - // 'startsh' holds an existing edge of the DT, find it. - torg = sorg(startsh); - tdest = sdest(startsh); - tapex = sapex(startsh); - getsearchtet(torg, tdest, &starttet, &workpt[0]); - collinear = finddirection(&starttet, workpt[0]); - if (collinear == LEFTCOLLINEAR) { - enext2self(starttet); - esymself(starttet); - } else if (collinear == TOPCOLLINEAR) { - fnextself(starttet); - enext2self(starttet); - esymself(starttet); - } - assert(dest(starttet) == workpt[0]); - // Find the crossing edge by rotating faces around 'starttet'. - spintet = starttet; - hitbdry = 0; - do { - if (fnextself(spintet)) { - // Check if the opposite edge of 'spintet' crosses the region. - workpt[1] = apex(spintet); - workpt[2] = oppo(spintet); - j = pointmark(workpt[1]) - in->firstnumber; - k = pointmark(workpt[2]) - in->firstnumber; - if (worklist[j] == 1 || worklist[k] == 1) { - // One of the two points is a vertex of the missing region. This - // edge can not cross this region. - inlistflag = false; - } else { - // Check if the edge crosses the region by performing a triangle - // triangle intersection test. ('workpt[0]' is the dest of the - // rotating edge 'spintet'). - inlistflag = (triangle_triangle_inter(torg, tdest, tapex, workpt[0], - workpt[1], workpt[2]) == INTERSECT); - } - if (inlistflag) { - // Find an edge crossing the missing region. Save it. - worktet = spintet; - adjustedgering(worktet, CCW); - enextfnextself(worktet); - enextself(worktet); - // Add this edge (worktet) into 'crossedgelist'. - crossedgelist->append(&worktet); - break; - } - if (apex(spintet) == apex(starttet)) break; - } else { - hitbdry++; - // It is only possible to hit boundary once. - if (hitbdry < 2) { - esym(starttet, spintet); - } - } - } while (hitbdry < 2); - crossflag = (crossedgelist->len() == 1); - } - - return crossflag; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// rearrangesubfaces() Rearrange the set of subfaces of a missing region // -// so that they conform to the faces of DT. // -// // -// The missing region formed by subfaces of 'missingshlist' contains a set // -// of degenerate vertices, hence the set of subfaces don't match the set of // -// faces in DT. Instead of forcing them to present in DT, we re-arrange the // -// connection of them so that the new subfaces conform to the faces of DT. // -// // -// 'boundedgelist' is a set of boundary edges of the region, these edges(may // -// be subsegments) must exist in DT. The process of rearrangement can be // -// described as follows: // -// - Form an inital link of boundary egdes; // -// - For each boundary edge (it must exist in DT), // -// - Remove it from the link; // -// - Look for a face in DT which contains this edge and has its apex // -// be a region vertex; Such face should exist (otherwise, an edge // -// will cross the region). // -// - Create a new subface on this face; insert it into the surface // -// mesh (the old subface connected at this edge will automatically // -// be disconnecte; // -// - Check the other two edges of this new created subface, if one // -// matches a boundary edge, remove the edge from the link (it is // -// finished) and bond them together. Otherwise, add a new boundary // -// to the link. // -// - Loop until the link of boundary edge is empty. // -// // -// On completion, we have created and inserted a set of new subfaces which // -// conform to faces of DT. The set of old subfaces in 'missingshlist' are // -// deleted. The region vertices in 'equatptlist' are unmarked. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -rearrangesubfaces(list* missingshlist, list* boundedgelist, list* equatptlist, - int* worklist) -{ - link *boundedgelink; - triface starttet, spintet, neightet, worktet; - face shloop, newsh, neighsh, spinsh, worksh; - face workseg, casingin, casingout; - point torg, tdest, workpt; - point liftpoint; - enum finddirectionresult collinear; - REAL area, ori1, ori2; - bool matchflag, finishflag; - int shmark, idx, hitbdry; - int i, j; - - // Initialize the boundary edge link. - boundedgelink = new link(sizeof(face), NULL, 256); - - // Create an initial boundary link. - for (i = 0; i < boundedgelist->len(); i++) { - shloop = * (face *)(* boundedgelist)[i]; - if (i == 0) { - if (b->quality) { - // area will be copied to all new created subfaces. - area = areabound(shloop); - } - // 'shmark' will be set to all new created subfaces. - shmark = shellmark(shloop); - // Get the liftpoint of this facet for later checking. - liftpoint = getliftpoint(shmark); - } - sspivot(shloop, workseg); - if (workseg.sh == dummysh) { - // This edge is an interior edge. - spivot(shloop, neighsh); - boundedgelink->add(&neighsh); - } else { - // This side has a segment, the edge exists. - boundedgelink->add(&shloop); - } - } - - // Loop until the link is empty. Each boundary edge will be finished by a - // new subface. After a new subface is created, it will be inserted into - // both the surface mesh and the DT, and new boundary edge will be added - // into the link. - while (boundedgelink->len() > 0) { - // Remove the top boundary edge from the link. - shloop = * (face *) boundedgelink->del(1); - sspivot(shloop, workseg); // 'workseg' indicates it is a segment or not. - torg = sorg(shloop); - tdest = sdest(shloop); - // Find a tetrahedron containing edge (torg, tdest). - getsearchtet(torg, tdest, &starttet, &workpt); - collinear = finddirection(&starttet, workpt); - if (collinear == LEFTCOLLINEAR) { - enext2self(starttet); - esymself(starttet); - } else if (collinear == TOPCOLLINEAR) { - fnextself(starttet); - enext2self(starttet); - esymself(starttet); - } - assert(dest(starttet) == workpt); - // Spinning faces around this edge, find the one lies on the facet AND - // is not a subface yet. - matchflag = false; - spintet = starttet; - hitbdry = 0; - do { - workpt = apex(spintet); - idx = pointmark(workpt) - in->firstnumber; - if (worklist[idx] == 1) { - // This face is on the facet. - if (workseg.sh != dummysh) { - // 'shloop' is a segment. - if (workpt != sapex(shloop)) { - // Be careful that 'workpt' may not be the vertex that we're - // looking for. Because the missing region may be non-convex. - // However, the right vertex should be at the same side of - // the apex of 'shloop'. - ori1 = orient3d(torg, tdest, liftpoint, sapex(shloop)); - ori2 = orient3d(torg, tdest, liftpoint, workpt); - assert(ori1 != 0.0 && ori2 != 0.0); - if ((ori1 > 0.0 && ori2 > 0.0) || (ori1 < 0.0 && ori2 < 0.0)) { - matchflag = true; - break; - } - } else { - // This face is already exist! It is possible. Created by - // previous recovering procedures. - matchflag = true; - break; - } - } else { - // 'shloop' is not a segment. Only insert a subface when there - // does not already exist a subface. - tspivot(spintet, neighsh); - if (neighsh.sh == dummysh) { - // This face is not a subface yet. - matchflag = true; - break; - } - } - } - if (!fnextself(spintet)) { - hitbdry ++; - if (hitbdry < 2) { - esym(starttet, spintet); - if (!fnextself(spintet)) { - hitbdry ++; - } - } - } - } while (hitbdry < 2 && apex(spintet) != apex(starttet)); - assert(matchflag == true); - tspivot(spintet, neighsh); - if (neighsh.sh != dummysh) { - printf("Error: Invalid PLC.\n"); - printf(" Facet #%d and facet #%d overlap each other.\n", - shellmark(neighsh), shellmark(shloop)); - printf(" It might be caused by a facet is defined more than once.\n"); - printf(" Hint: Use -d switch to find all overlapping facets.\n"); - exit(1); - } - // The side of 'spintet' is at which a new subface will be attached. - adjustedgering(spintet, CCW); - // Create the new subface. - makeshellface(subfaces, &newsh); - setsorg(newsh, org(spintet)); - setsdest(newsh, dest(spintet)); - setsapex(newsh, apex(spintet)); - if (b->quality) { - // Copy the areabound into the new subface. - setareabound(newsh, area); - } - setshellmark(newsh, shmark); - // Insert it into the current mesh. - tsbond(spintet, newsh); - sym(spintet, neightet); - if (neightet.tet != dummytet) { - sesym(newsh, neighsh); - tsbond(neightet, neighsh); - } - // Insert it into the surface mesh. - sspivot(shloop, workseg); - if (workseg.sh == dummysh) { - sbond(shloop, newsh); - } else { - // There is a subsegment, 'shloop' is the subface which is going to - // die. Insert the 'newsh' at the place of 'shloop' into its face - // link, so as to dettach 'shloop'. The original connection is: - // -> casingin -> shloop -> casingout ->, it will be changed with: - // -> casingin -> newsh -> casingout ->. Pay attention to the - // case when this subsegment is dangling in the mesh, i.e., 'shloop' - // is bonded to itself. - spivot(shloop, casingout); - if (shloop.sh != casingout.sh) { - // 'shloop' is not bonded to itself. - spinsh = casingout; - do { - casingin = spinsh; - spivotself(spinsh); - } while (sapex(spinsh) != sapex(shloop)); - assert(casingin.sh != shloop.sh); - // Bond casingin -> newsh -> casingout. - sbond1(casingin, newsh); - sbond1(newsh, casingout); - } else { - // Bond newsh -> newsh. - sbond(newsh, newsh); - } - // Bond the segment. - ssbond(newsh, workseg); - } - // Check other two sides of this new subface. If a side is not bonded - // to any edge in the link, it will be added to the link. - for (i = 0; i < 2; i++) { - if (i == 0) { - senext(newsh, worksh); - } else { - senext2(newsh, worksh); - } - torg = sorg(worksh); - tdest = sdest(worksh); - finishflag = false; - for (j = 0; j < boundedgelink->len() && !finishflag; j++) { - neighsh = * (face *) boundedgelink->getnitem(j + 1); - if ((sorg(neighsh) == torg && sdest(neighsh) == tdest) || - (sorg(neighsh) == tdest && sdest(neighsh) == torg)) { - // Find a boundary edge. Bond them and exit the loop. - sspivot(neighsh, workseg); - if (workseg.sh == dummysh) { - sbond(neighsh, worksh); - } else { - // There is a subsegment, 'neighsh' is the subface which is - // going to die. Do the same as above for 'worksh'. - spivot(neighsh, casingout); - if (neighsh.sh != casingout.sh) { - // 'neighsh' is not bonded to itself. - spinsh = casingout; - do { - casingin = spinsh; - spivotself(spinsh); - } while (sapex(spinsh) != sapex(neighsh)); - assert(casingin.sh != neighsh.sh); - // Bond casingin -> worksh -> casingout. - sbond1(casingin, worksh); - sbond1(worksh, casingout); - } else { - // Bond worksh -> worksh. - sbond(worksh, worksh); - } - // Bond the segment. - ssbond(worksh, workseg); - } - // Remove this boundary edge from the link. - boundedgelink->del(j + 1); - finishflag = true; - } - } - if (!finishflag) { - // It's a new boundary edge, add it to link. - boundedgelink->add(&worksh); - } - } - } - - // Deallocate the set of old missing subfaces. - for (i = 0; i < missingshlist->len(); i++) { - worksh = * (face *)(* missingshlist)[i]; - shellfacedealloc(subfaces, worksh.sh); - } - // Unmark region vertices in 'worklist'. - for (i = 0; i < equatptlist->len(); i++) { - workpt = * (point *)(* equatptlist)[i]; - idx = pointmark(workpt) - in->firstnumber; - worklist[idx] = 0; - } - - delete boundedgelink; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// recoversubfaces() Recover the set of subfaces of a missing region so // -// that they become faces of the DT. // -// // -// 'missingshlist' contains a set of missing subfaces which form the missing // -// region. A cavity retriangulation method is used to recover these subfaces // -// in the DT. To do so, first find all the tetrahedra in DT that intersect // -// the relative interior of the missing region. Then delete them from the DT,// -// this will form a cavity C inside the DT. Now we want to retriangulate the // -// C and want the missing subfaces will appear after the retriangulation. To // -// complete this, we first insert the missing subfaces into the C, so as to // -// split it into two disjointed cavity. Then retriangulate them separately. // -// (See the intoduction of the routine triangulatecavity() for the cavity // -// retriangulation method.) // -// // -// On input, 'crossedgelist' contains an edge which is crossing the missing // -// region. All tetrahedra containing this edge must cross the region. It is // -// possible there are other crossing edges as well. They can be found by // -// checking the edges of the discovered crossing tetrahedra. Through this // -// way, other crossing tetrahedra of the region can be found incrementally. // -// However, it doesn't guarantee we can get all crossing tetrahedra of this // -// region. The discovered tetrahedra are connected each other. There may // -// exist other tetrahedra which are crossing the region but disjoint with // -// the set of discovered tetrahedra. Due to this fact, we need to check the // -// missing subfaces once more. Only recover those which are crossed by the // -// set of discovered tetrahedra. The other subfaces remain missing and will // -// be recovered later. // -// // -// On completion, we have modified the DT to incorporate a set of subfaces. // -// The recovered subfaces of 'missingshlist' are uninfected. The region // -// vertices in 'equatptlist' are unmarked. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -recoversubfaces(list* missingshlist, list* crossedgelist, list* equatptlist, - int* worklist) -{ - list *crossshlist, *crosstetlist; - list *belowfacelist, *abovefacelist; - list *belowptlist, *aboveptlist; - triface starttet, spintet, neightet, worktet; - face startsh, neighsh, worksh, workseg; - point torg, tdest, tapex, workpt[3]; - REAL checksign, orgori, destori; - bool crossflag, inlistflag; - bool belowflag, aboveflag; - int idx, share; - int i, j, k; - - // Initialize the working lists. - crossshlist = new list(sizeof(face), NULL); - crosstetlist = new list(sizeof(triface), NULL); - belowfacelist = new list(sizeof(triface), NULL); - abovefacelist = new list(sizeof(triface), NULL); - belowptlist = new list("point *"); - aboveptlist = new list("point *"); - - // Get a face as horizon. - startsh = * (face *)(* missingshlist)[0]; - torg = sorg(startsh); - tdest = sdest(startsh); - tapex = sapex(startsh); - - // Collect the set of crossing tetrahedra by rotating crossing edges. At - // the beginning, 'crossedgelist' contains one crossing edge, others - // will be discovered after newly crossing tetrahedra are found. - for (i = 0; i < crossedgelist->len(); i++) { - starttet = * (triface *)(* crossedgelist)[i]; - adjustedgering(starttet, CCW); - if (b->verbose > 2) { - printf(" Collect tets containing edge (%d, %d).\n", - pointmark(org(starttet)), pointmark(dest(starttet))); - } - orgori = orient3d(torg, tdest, tapex, org(starttet)); - destori = orient3d(torg, tdest, tapex, dest(starttet)); - assert(orgori * destori < 0.0); - spintet = starttet; - do { - // The face rotation should not meet boundary. - fnextself(spintet); - // Check the validity of the PLC. - tspivot(spintet, worksh); - if (worksh.sh != dummysh) { - printf("Error: Invalid PLC.\n"); - printf(" Two subfaces (%d, %d, %d) and (%d, %d, %d)\n", - pointmark(torg), pointmark(tdest), pointmark(tapex), - pointmark(sorg(worksh)), pointmark(sdest(worksh)), - pointmark(sapex(worksh))); - printf(" are found intersecting each other.\n"); - printf(" Hint: Use -d switch to find all intersecting facets.\n"); - exit(1); - } - if (!infected(spintet)) { - if (b->verbose > 2) { - printf(" Add crossing tet (%d, %d, %d, %d).\n", - pointmark(org(spintet)), pointmark(dest(spintet)), - pointmark(apex(spintet)), pointmark(oppo(spintet))); - } - infect(spintet); - crosstetlist->append(&spintet); - } - // Check whether other two edges of 'spintet' is a crossing edge. - // It can be quickly checked from the apex of 'spintet', if it is - // not on the facet, then there exists a crossing edge. - workpt[0] = apex(spintet); - idx = pointmark(workpt[0]) - in->firstnumber; - if (worklist[idx] != 1) { - // Either edge (dest, apex) or edge (apex, org) crosses. - checksign = orient3d(torg, tdest, tapex, workpt[0]); - assert(checksign != 0.0); - if (checksign * orgori < 0.0) { - enext2(spintet, worktet); // edge (apex, org). - workpt[1] = org(spintet); - } else { - assert(checksign * destori < 0.0); - enext(spintet, worktet); // edge (dest, apex). - workpt[1] = dest(spintet); - } - // 'worktet' represents the crossing edge. Add it into list only - // it doesn't exist in 'crossedgelist'. - inlistflag = false; - for (j = 0; j < crossedgelist->len() && !inlistflag; j++) { - neightet = * (triface *)(* crossedgelist)[j]; - if (org(neightet) == workpt[0]) { - if (dest(neightet) == workpt[1]) inlistflag = true; - } else if (org(neightet) == workpt[1]) { - if (dest(neightet) == workpt[0]) inlistflag = true; - } - } - if (!inlistflag) { - crossedgelist->append(&worktet); - } - } - } while (apex(spintet) != apex(starttet)); - } - - // Identifying the boundary faces of the cavity. - for (i = 0; i < crosstetlist->len(); i++) { - starttet = * (triface *)(* crosstetlist)[i]; - assert(infected(starttet)); - adjustedgering(starttet, CCW); - // Only need to check two sides of starttet. Current side and the side - // of fnext() are sharing the crossing edge, the two neighbors must - // be crossing tetrahedra. Hence these two sides can't be boundaries - // of the cavity. - for (j = 0; j < 2; j++) { - if (j == 0) { - enextfnext(starttet, worktet); - } else { - enext2fnext(starttet, worktet); - } - sym(worktet, neightet); - // If the neighbor doesn't exist or exists but doesn't be infected, - // it's a boundary face of the cavity, save it. - if (neightet.tet == dummytet || !infected(neightet)) { - workpt[0] = org(worktet); - workpt[1] = dest(worktet); - workpt[2] = apex(worktet); - belowflag = aboveflag = false; - share = 0; - for (k = 0; k < 3; k++) { - idx = pointmark(workpt[k]) - in->firstnumber; - if (worklist[idx] == 0) { - // It's not a vertices of facet, find which side it lies. - checksign = orient3d(torg, tdest, tapex, workpt[k]); - assert(checksign != 0.0); - if (checksign > 0.0) { - // It lies "below" the facet wrt. 'startsh'. - worklist[idx] = 2; - belowptlist->append(&workpt[k]); - } else if (checksign < 0.0) { - // It lies "above" the facet wrt. 'startsh'. - worklist[idx] = 3; - aboveptlist->append(&workpt[k]); - } - } - if (worklist[idx] == 2) { - // This face lies "below" the facet wrt. 'startsh'. - belowflag = true; - } else if (worklist[idx] == 3) { - // This face lies "above" the facet wrt. 'startsh'. - aboveflag = true; - } else { - // In degenerate case, this face may just be the equator. - assert(worklist[idx] == 1); - share++; - } - } - // The degenerate case has been ruled out. - assert(share < 3); - // Only one flag is possible for a cavity face. - assert(belowflag ^ aboveflag); - if (belowflag) { - belowfacelist->append(&worktet); - } else if (aboveflag) { - abovefacelist->append(&worktet); - } - } - } - } - - // Form the set of missing subfaces which are crossed by tetrahedra of - // 'crosstetlist'. It is a subset of 'missingshlist'. These faces - // need be recovered (using cavity filling algorithm). Other subfaces - // remain infected and will be recovered later. - for (i = 0; i < missingshlist->len(); i++) { - worksh = * (face *)(* missingshlist)[i]; - assert(sinfected(worksh)); - torg = sorg(worksh); - tdest = sdest(worksh); - tapex = sapex(worksh); - crossflag = false; - for (j = 0; j < crosstetlist->len() && !crossflag; j++) { - starttet = * (triface *)(* crosstetlist)[j]; - adjustedgering(starttet, CCW); - // Only need to check two sides of worktet. - for (k = 0; k < 2 && !crossflag; k++) { - if (k == 0) { - worktet = starttet; - } else { - fnext(starttet, worktet); - } - // torg, tdest and tapex SHOULD be non-collinear. - crossflag = tritritest(&worktet, torg, tdest, tapex); - } - } - if (crossflag) { - // 'worksh' is crossed by 'worktet', uninfect it. - suninfect(worksh); - crossshlist->append(&worksh); - } - } - - // Clear flags set in 'worklist'. - for (i = 0; i < equatptlist->len(); i++) { - workpt[0] = * (point *)(* equatptlist)[i]; - idx = pointmark(workpt[0]) - in->firstnumber; - // assert(worklist[idx] == 1); - worklist[idx] = 0; - } - for (i = 0; i < belowptlist->len(); i++) { - workpt[0] = * (point *)(* belowptlist)[i]; - idx = pointmark(workpt[0]) - in->firstnumber; - // assert(worklist[idx] == 2); - worklist[idx] = 0; - } - for (i = 0; i < aboveptlist->len(); i++) { - workpt[0] = * (point *)(* aboveptlist)[i]; - idx = pointmark(workpt[0]) - in->firstnumber; - // assert(worklist[idx] == 3); - worklist[idx] = 0; - } - - assert (aboveptlist->len() > 0); - // Retriangulate the upper part of the cavity. - triangulatecavity(crossshlist, abovefacelist, equatptlist, aboveptlist); - - // Inverse the direction of faces in 'missingshlist'. - for (i = 0; i < crossshlist->len(); i++) { - worksh = * (face *)(* crossshlist)[i]; - sesymself(worksh); - * (face *)(* crossshlist)[i] = worksh; - } - - assert(belowptlist->len() > 0); - // Retriangulate the lower part of the cavity. - triangulatecavity(crossshlist, belowfacelist, equatptlist, belowptlist); - - // Delete old tetrahedra of this cavity. - for (i = 0; i < crosstetlist->len(); i++) { - worktet = * (triface *)(* crosstetlist)[i]; - tetrahedrondealloc(worktet.tet); - } - - delete crossshlist; - delete crosstetlist; - delete belowfacelist; - delete abovefacelist; - delete belowptlist; - delete aboveptlist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// constrainedfacets() Insert PLC facets into the Delaunay tetrahedraliz- // -// ation of the PLC vertices. // -// // -// This is the last step of our CDT algorithm, which transforms a Delaunay // -// tetrahedralization DT into a constrained Delaunay tetrahedralization by // -// forcing all subfaces of the surface mesh F of the PLC into the DT. It is // -// important that all PLC segments have been previously recovered in DT, so // -// the existence of a CDT is guaranteed (by our CDT theorem). Hence, all // -// subfaces of F can be recovered in the DT without inserting vertices. // -// // -// The process of constrained facets can be though of "merging" the surface // -// mesh F completely into the Delaunay tetrahedralization DT. Recover the // -// subfaces in DT if they are not matching. Hence, the process is divided // -// into two steps: first insert all existing subfaces of F into DT, that is, // -// each subface already appears as a face of DT; at the same time, queue all // -// missing subfaces. Then recover missing subfaces (explained below). The // -// second step changes a DT into a CDT. // -// // -// When a subface s of a facet f is found missing in DT, most probably, some // -// other subfaces near to s and belong to f are also missing. The set of // -// adjoining missing subfaces of f forms a missing region. It is obvious to // -// see that this region is closed and is bounded by the edges of existing // -// subfaces or the segments of f. Instead of recovering missing subfaces of // -// this region one by one, they are recovered together, i.e., each time a // -// closed missing region will be recovered. // -// // -// There are two possibilities can from a mssing region R: (1) Some edges of // -// DT intersect subfaces in R; (2) No edge of DT cross R, but another set of // -// faces of DT spans R, this is because the existence of degeneracies (five // -// or more vertices of R are cospherical). If it is case (1), we modify DT // -// so that its faces spans R. A cavity retriangulation algorithm is used to // -// recover the region. If it is case (2), F is modified so that the set of // -// subfaces of F matches faces in DT. A face rearrangment algorithm is used. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::constrainedfacets() -{ - queue *missingshqueue; - list *missingshlist; - list *boundedgelist; - list *crossedgelist; - list *equatptlist; - triface searchtet; - face subloop; - int *worklist; - int i; - - if (!b->quiet) { - printf("Constraining facets.\n"); - } - - // Compute a mapping from points to tetrahedra. - makepoint2tetmap(); - // Initialize the queue to store the set of missing subfaces. - missingshqueue = new queue(sizeof(face)); - // Initialize the working lists. - missingshlist = new list(sizeof(face), NULL); - boundedgelist = new list(sizeof(face), NULL); - crossedgelist = new list(sizeof(triface), NULL); - equatptlist = new list("point *"); - // Initialize the list for matching vertices. - worklist = new int[points->items]; - for (i = 0; i < points->items; i++) { - worklist[i] = 0; - } - - // Step 1, go through all subfaces, insert existing subfaces into DT. - // Missing subfaces are queued. Moreover, they are infected so that - // can be distinguished from existing ones. - searchtet.tet = (tetrahedron *) NULL; - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - if (!insertsubface(&subloop, &searchtet)) { - if (b->verbose > 1) { - printf(" Queuing missing subface (%d, %d, %d).\n", - pointmark(sorg(subloop)), pointmark(sdest(subloop)), - pointmark(sapex(subloop))); - } - sinfect(subloop); - missingshqueue->push(&subloop); - } - subloop.sh = shellfacetraverse(subfaces); - } - - // Step 2, recover all missing subfaces. - while (!missingshqueue->empty()) { - subloop = * (face *) missingshqueue->pop(); - if (!isdead(&subloop) && sinfected(subloop)) { - if (b->verbose > 1) { - printf(" Recovering subface (%d, %d, %d).\n", - pointmark(sorg(subloop)), pointmark(sdest(subloop)), - pointmark(sapex(subloop))); - } - // Other operation may have recovered this subface. - if (!insertsubface(&subloop, &searchtet)) { - // First form the missing region. - formmissingregion(&subloop, missingshlist, equatptlist, worklist); - // Are there crossing tetrahedra? - if (scoutcrossingedge(missingshlist, boundedgelist, crossedgelist, - worklist)) { - // There are! Recover by retriangulating cavities. - recoversubfaces(missingshlist, crossedgelist, equatptlist, worklist); - // There may remain some un-recovered subfaces. Don't ignore them. - for (i = 0; i < missingshlist->len(); i++) { - subloop = * (face *)(* missingshlist)[i]; - if (sinfected(subloop)) { - // Put it back into queue. - missingshqueue->push(&subloop); - } - } - } else { - // No crossing tetrahedra. Rearrange subfaces in surface mesh. - rearrangesubfaces(missingshlist, boundedgelist, equatptlist, - worklist); - } - // Clear all working lists. - missingshlist->clear(); - boundedgelist->clear(); - crossedgelist->clear(); - equatptlist->clear(); - } else { - // This subface has been recovered. Only uninfect it. - suninfect(subloop); - } - } - } - - delete missingshqueue; - delete missingshlist; - delete boundedgelist; - delete crossedgelist; - delete equatptlist; - delete [] worklist; -} - -// -// End of constrained Delaunay triangulation routines -// - -// -// Begin of carving out holes and concavities routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// indenthull() Remove redundant tetrahedra on the convex hull. // -// // -// All tetrahedra on the hull which are not protected by subfaces will be // -// removed. As a result, the convex tetrahedralization becomes concave, and // -// the new hull is formed by subfaces. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::indenthull() -{ - memorypool *viri; - link *hulllink; - tetrahedron **virusloop; - triface tetloop, hullface; - triface checkface, neightet; - face checksh; - point p1, p2, p3; - bool indentflag;; - int i; - - if (b->verbose) { - printf(" Indenting hulls.\n"); - } - - // Initialize a pool of viri. - viri = new memorypool(sizeof(tetrahedron *), 1024, POINTER, 0); - // Initialize the hulllink. - hulllink = new link(sizeof(triface), NULL, 1024); - - // Find out all hull faces which are not protected by subfaces. At the - // same time, infect all tetrahedra which has faces on the hull and - // are protected by subfaces. - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - indentflag = true; - for (tetloop.loc = 0; tetloop.loc < 4; tetloop.loc++) { - // Is this face on the hull? - sym(tetloop, neightet); - if (neightet.tet == dummytet) { - // Is the face protected by a subface? - tspivot(tetloop, checksh); - if (checksh.sh == dummysh) { - // Add this face into hulllink. - hulllink->add(&tetloop); - } else { - // It is protected by a subface. - indentflag = false; - } - } - } - if (!indentflag) { - // Infect it to indicate it is at interior space. - virusloop = (tetrahedron **) viri->alloc(); - *virusloop = tetloop.tet; - } - tetloop.tet = tetrahedrontraverse(); - } - - // Loop until the hulllink is empty. - while (hulllink->len() > 0) { - // Remove a hullface from the link. - hullface = * (triface *) hulllink->del(1); - // The tet may already be removed. - if (isdead(&hullface)) continue; - if (b->verbose > 1) { - printf(" Indenting face (%d, %d, %d).\n", pointmark(org(hullface)), - pointmark(dest(hullface)), pointmark(apex(hullface))); - } - // The tet may be an interior one (if it is infected). - indentflag = !infected(hullface); - // Check if hullface can be indented. - adjustedgering(hullface, CCW); - for (i = 0; i < 3 && indentflag; i++) { - fnext(hullface, checkface); - sym(checkface, neightet); - tspivot(checkface, checksh); - if (neightet.tet != dummytet) { - // The neighbor exists. - if (checksh.sh == dummysh) { - // This side is not protected by a subface. If the neighbor is - // marked as an interior tet, hullface survives. - indentflag = !infected(neightet); - } else { - // It is protected by a subface. - if (!infected(neightet)) { - // This is a new discovered interior tet. Infect it. - infect(neightet); - virusloop = (tetrahedron **) viri->alloc(); - *virusloop = neightet.tet; - } - } - } - enextself(hullface); - } - if (!indentflag) { - // hullface survives. - p1 = org(hullface); - p2 = dest(hullface); - p3 = apex(hullface); - printf("Warning: Face (%d, %d, %d) is open.\n", pointmark(p1), - pointmark(p2), pointmark(p3)); - if (!infected(hullface)) { - // Infect it and add it into viris. - infect(hullface); - virusloop = (tetrahedron **) viri->alloc(); - *virusloop = hullface.tet; - } - continue; - } - // Indent hullface. That is, remove it from the hull. The hullsize is - // changed, new discoved open hullfaces will be added to hulllink. - for (i = 0; i < 3; i++) { - fnext(hullface, checkface); - sym(checkface, neightet); - tspivot(checkface, checksh); - if (neightet.tet != dummytet) { - // The neighbor exists. - if (checksh.sh == dummysh) { - // This side is not protected. - assert(!infected(neightet)); - hulllink->add(&neightet); - } else { - // It is protected. - assert(infected(neightet)); - stdissolve(checksh); - } - // It becomes a new hull face. - dissolve(neightet); - hullsize++; - } else { - // This side is hull face also. - if (checksh.sh != dummysh) { - // A dangling subface. It will be isolated. - stdissolve(checksh); - } - // Decrease the hullsize. - hullsize--; - } - enextself(hullface); - } - // Delete the tetrahedron. - tetrahedrondealloc(hullface.tet); - // Decrease the hullsize. - hullsize--; - } - - // Uninfect infected tetrahedra. - viri->traversalinit(); - virusloop = (tetrahedron **) viri->traverse(); - while (virusloop != (tetrahedron **) NULL) { - neightet.tet = *virusloop; - uninfect(neightet); - virusloop = (tetrahedron **) viri->traverse(); - } - - delete viri; - delete hulllink; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// infecthull() Virally infect all of the tetrahedra of the convex hull // -// that are not protected by subfaces. Where there are // -// subfaces, set boundary markers as appropriate. // -// // -// Memorypool 'viri' is used to return all the infected tetrahedra. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::infecthull(memorypool *viri) -{ - triface tetloop, tsymtet; - tetrahedron **deadtet; - face hullface; - // point horg, hdest, hapex; - - if (b->verbose) { - printf(" Marking concavities for elimination.\n"); - } - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - // Is this tetrahedron on the hull? - for (tetloop.loc = 0; tetloop.loc < 4; tetloop.loc++) { - sym(tetloop, tsymtet); - if (tsymtet.tet == dummytet) { - // Is the tetrahedron protected by a subface? - tspivot(tetloop, hullface); - if (hullface.sh == dummysh) { - // The tetrahedron is not protected; infect it. - if (!infected(tetloop)) { - infect(tetloop); - deadtet = (tetrahedron **) viri->alloc(); - *deadtet = tetloop.tet; - break; // Go and get next tet. - } - } else { - // The tetrahedron is protected; set boundary markers if appropriate. - if (shellmark(hullface) == 0) { - setshellmark(hullface, 1); - /* - horg = sorg(hullface); - hdest = sdest(hullface); - hapex = sapex(hullface); - if (pointmark(horg) == 0) { - setpointmark(horg, 1); - } - if (pointmark(hdest) == 0) { - setpointmark(hdest, 1); - } - if (pointmark(hapex) == 0) { - setpointmark(hapex, 1); - } - */ - } - } - } - } - tetloop.tet = tetrahedrontraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// plague() Spread the virus from all infected tetrahedra to any // -// neighbors not protected by subfaces. Delete all infected // -// tetrahedra. // -// // -// This is the procedure that actually creates holes and concavities. // -// // -// This procedure operates in two phases. The first phase identifies all // -// the tetrahedra that will die, and marks them as infected. They are // -// marked to ensure that each tetrahedron is added to the virus pool only // -// once, so the procedure will terminate. // -// // -// The second phase actually eliminates the infected tetrahedra. It also // -// eliminates orphaned segments and points(not done now). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::plague(memorypool *viri) -{ - tetrahedron **virusloop; - tetrahedron **deadtet; - triface testtet, neighbor; - face neighsh, testseg; - face spinsh, casingin, casingout; - point checkpt; - int *tetspernodelist; - int i, j; - - if (b->verbose) { - printf(" Marking neighbors of marked tetrahedra.\n"); - } - // Loop through all the infected tetrahedra, spreading the virus to - // their neighbors, then to their neighbors' neighbors. - viri->traversalinit(); - virusloop = (tetrahedron **) viri->traverse(); - while (virusloop != (tetrahedron **) NULL) { - testtet.tet = *virusloop; - // Temporarily uninfect this tetrahedron, not necessary. - uninfect(testtet); - // Check each of the tetrahedron's four neighbors. - for (testtet.loc = 0; testtet.loc < 4; testtet.loc++) { - // Find the neighbor. - sym(testtet, neighbor); - // Check for a shell between the tetrahedron and its neighbor. - tspivot(testtet, neighsh); - // Check if the neighbor is nonexistent or already infected. - if ((neighbor.tet == dummytet) || infected(neighbor)) { - if (neighsh.sh != dummysh) { - // There is a subface separating the tetrahedron from its neighbor, - // but both tetrahedra are dying, so the subface dies too. - // Before deallocte this subface, dissolve the connections between - // other subfaces, subsegments and tetrahedra. - neighsh.shver = 0; - // For keep the same enext() direction. - findedge(&testtet, sorg(neighsh), sdest(neighsh)); - for (i = 0; i < 3; i++) { - sspivot(neighsh, testseg); - if (testseg.sh != dummysh) { - // A subsegment is found at this side, dissolve this subface - // from the face link of this subsegment. - testseg.shver = 0; - spinsh = neighsh; - if (sorg(spinsh) != sorg(testseg)) { - sesymself(spinsh); - } - spivot(spinsh, casingout); - if (casingout.sh == spinsh.sh) { - // This is a trivial face link, only 'neighsh' itself, - // the subsegment at this side is also died. - shellfacedealloc(subsegs, testseg.sh); - } else { - spinsh = casingout; - do { - casingin = spinsh; - spivotself(spinsh); - } while (spinsh.sh != neighsh.sh); - // Set the link casingin->casingout. - sbond1(casingin, casingout); - // Bond the subsegment anyway. - ssbond(casingin, testseg); - } - } - senextself(neighsh); - enextself(testtet); - } - shellfacedealloc(subfaces, neighsh.sh); - if (neighbor.tet != dummytet) { - // Make sure the subface doesn't get deallocated again later - // when the infected neighbor is visited. - tsdissolve(neighbor); - } - } - } else { // The neighbor exists and is not infected. - if (neighsh.sh == dummysh) { - // There is no subface protecting the neighbor, infect it. - infect(neighbor); - // Ensure that the neighbor's neighbors will be infected. - deadtet = (tetrahedron **) viri->alloc(); - *deadtet = neighbor.tet; - } else { // The neighbor is protected by a subface. - // Remove this tetrahedron from the subface. - stdissolve(neighsh); - // The subface becomes a boundary. Set markers accordingly. - if (shellmark(neighsh) == 0) { - setshellmark(neighsh, 1); - } - } - } - } - // Remark the tetrahedron as infected, so it doesn't get added to the - // virus pool again. - infect(testtet); - virusloop = (tetrahedron **) viri->traverse(); - } - - if (b->verbose) { - printf(" Deleting marked tetrahedra.\n"); - } - - // Create and initialize 'segspernodelist'. - tetspernodelist = new int[points->items + 1]; - for (i = 0; i < points->items + 1; i++) tetspernodelist[i] = 0; - - // Loop the tetrahedra list, counter the number of tets sharing each node. - tetrahedrons->traversalinit(); - testtet.tet = tetrahedrontraverse(); - while (testtet.tet != (tetrahedron *) NULL) { - // Increment the number of sharing tets for each endpoint. - for (i = 0; i < 4; i++) { - j = pointmark((point) testtet.tet[4 + i]); - tetspernodelist[j]++; - } - testtet.tet = tetrahedrontraverse(); - } - - viri->traversalinit(); - virusloop = (tetrahedron **) viri->traverse(); - while (virusloop != (tetrahedron **) NULL) { - testtet.tet = *virusloop; - // Record changes in the number of boundary faces, and disconnect - // dead tetrahedra from their neighbors. - for (testtet.loc = 0; testtet.loc < 4; testtet.loc++) { - sym(testtet, neighbor); - if (neighbor.tet == dummytet) { - // There is no neighboring tetrahedron on this face, so this face - // is a boundary face. This tetrahedron is being deleted, so this - // boundary face is deleted. - hullsize--; - } else { - // Disconnect the tetrahedron from its neighbor. - dissolve(neighbor); - // There is a neighboring tetrahedron on this face, so this face - // becomes a boundary face when this tetrahedron is deleted. - hullsize++; - } - } - // Check the four corners of this tet if they're isolated. - for (i = 0; i < 4; i++) { - checkpt = (point) testtet.tet[4 + i]; - j = pointmark(checkpt); - tetspernodelist[j]--; - if (tetspernodelist[j] == 0) { - setpointtype(checkpt, UNUSEDVERTEX); - } - } - // Return the dead tetrahedron to the pool of tetrahedra. - tetrahedrondealloc(testtet.tet); - virusloop = (tetrahedron **) viri->traverse(); - } - - delete [] tetspernodelist; - // Empty the virus pool. - viri->restart(); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// regionplague() Spread regional attributes and/or volume constraints // -// (from a .poly file) throughout the mesh. // -// // -// This procedure operates in two phases. The first phase spreads an // -// attribute and/or an volume constraint through a (segment-bounded) region. // -// The tetrahedra are marked to ensure that each tetrahedra is added to the // -// virus pool only once, so the procedure will terminate. // -// // -// The second phase uninfects all infected tetrahedra, returning them to // -// normal. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -regionplague(memorypool *viri, REAL attribute, REAL volume) -{ - tetrahedron **virusloop; - tetrahedron **regiontet; - triface testtet, neighbor; - face neighsh; - - if (b->verbose > 1) { - printf(" Marking neighbors of marked tetrahedra.\n"); - } - // Loop through all the infected tetrahedra, spreading the attribute - // and/or volume constraint to their neighbors, then to their neighbors' - // neighbors. - viri->traversalinit(); - virusloop = (tetrahedron **) viri->traverse(); - while (virusloop != (tetrahedron **) NULL) { - testtet.tet = *virusloop; - // Temporarily uninfect this tetrahedron, not necessary. - uninfect(testtet); - if (b->regionattrib) { - // Set an attribute. - setelemattribute(testtet.tet, in->numberoftetrahedronattributes, - attribute); - } - if (b->varvolume) { - // Set an volume constraint. - setvolumebound(testtet.tet, volume); - } - // Check each of the tetrahedron's four neighbors. - for (testtet.loc = 0; testtet.loc < 4; testtet.loc++) { - // Find the neighbor. - sym(testtet, neighbor); - // Check for a subface between the tetrahedron and its neighbor. - tspivot(testtet, neighsh); - // Make sure the neighbor exists, is not already infected, and - // isn't protected by a subface, or is protected by a nonsolid - // subface. - if ((neighbor.tet != dummytet) && !infected(neighbor) - && (neighsh.sh == dummysh)) { - // Infect the neighbor. - infect(neighbor); - // Ensure that the neighbor's neighbors will be infected. - regiontet = (tetrahedron **) viri->alloc(); - *regiontet = neighbor.tet; - } - } - // Remark the tetrahedron as infected, so it doesn't get added to the - // virus pool again. - infect(testtet); - virusloop = (tetrahedron **) viri->traverse(); - } - - // Uninfect all tetrahedra. - if (b->verbose > 1) { - printf(" Unmarking marked tetrahedra.\n"); - } - viri->traversalinit(); - virusloop = (tetrahedron **) viri->traverse(); - while (virusloop != (tetrahedron **) NULL) { - testtet.tet = *virusloop; - uninfect(testtet); - virusloop = (tetrahedron **) viri->traverse(); - } - // Empty the virus pool. - viri->restart(); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// carveholes() Find the holes and infect them. Find the volume // -// constraints and infect them. Infect the convex hull. // -// Spread the infection and kill tetrahedra. Spread the // -// volume constraints. // -// // -// This routine mainly calls other routines to carry out all these functions.// -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::carveholes() -{ - memorypool *viri; - triface searchtet; - triface *holetets; - triface *regiontets; - tetrahedron *tptr; - tetrahedron **holetet; - tetrahedron **regiontet; - enum locateresult intersect; - int i; - - if (!b->quiet) { - printf("Removing unwanted tetrahedra.\n"); - if (b->verbose && (in->numberofholes > 0)) { - printf(" Marking holes for elimination.\n"); - } - } - - if (in->numberofholes > 0) { - // Allocate storage for the tetrahedra in which hole points fall. - holetets = (triface *) new triface[in->numberofholes]; - } - if (in->numberofregions > 0) { - // Allocate storage for the tetrahedra in which region points fall. - regiontets = (triface *) new triface[in->numberofregions]; - } - - // Now, we have to find all the holes and regions BEFORE we infect hull - // and carve the holes, because locate() won't work when there exist - // infect tetrahedra and the tetrahedronlization is no longer convex. - - if (in->numberofholes > 0) { - // Infect each tetrahedron in which a hole lies. - for (i = 0; i < 3 * in->numberofholes; i += 3) { - // Ignore holes that aren't within the bounds of the mesh. - if ((in->holelist[i] >= xmin) && (in->holelist[i] <= xmax) - && (in->holelist[i + 1] >= ymin) - && (in->holelist[i + 1] <= ymax) - && (in->holelist[i + 2] >= zmin) - && (in->holelist[i + 2] <= zmax)) { - searchtet.tet = dummytet; - // Find a tetrahedron that contains the hole. - intersect = locate(&in->holelist[i], &searchtet); - if ((intersect != OUTSIDE) && (!infected(searchtet))) { - // Record the tetrahedron for processing carve hole. - holetets[i / 3] = searchtet; - } - } - } - } - - if (in->numberofregions > 0) { - // Find the starting tetrahedron for each region. - for (i = 0; i < in->numberofregions; i++) { - regiontets[i].tet = dummytet; - // Ignore region points that aren't within the bounds of the mesh. - if ((in->regionlist[5 * i] >= xmin) - && (in->regionlist[5 * i] <= xmax) - && (in->regionlist[5 * i + 1] >= ymin) - && (in->regionlist[5 * i + 1] <= ymax) - && (in->regionlist[5 * i + 2] >= zmin) - && (in->regionlist[5 * i + 2] <= zmax)) { - searchtet.tet = dummytet; - // Find a tetrahedron that contains the region point. - intersect = locate(&in->regionlist[5 * i], &searchtet); - if ((intersect != OUTSIDE) && (!infected(searchtet))) { - // Record the tetrahedron for processing after the - // holes have been carved. - regiontets[i] = searchtet; - } - } - } - } - - // Initialize a pool of viri to be used for holes, concavities, - // regional attributes, and/or regional volume constraints. - viri = new memorypool(sizeof(tetrahedron *), 1024, POINTER, 0); - // Mark as infected any unprotected tetrahedra on the boundary. - // This is one way by which concavities are created. - infecthull(viri); - - if (in->numberofholes > 0) { - // Infect the hole tetrahedron. This is done by marking the - // tetrahedron as infect and including the tetrahedron in - // the virus pool. - for (i = 0; i < in->numberofholes; i++) { - infect(holetets[i]); - holetet = (tetrahedron **) viri->alloc(); - *holetet = holetets[i].tet; - } - } - - if (viri->items > 0) { - // Carve the holes and concavities. - plague(viri); - } - // The virus pool should be empty now. - - if (in->numberofregions > 0) { - if (!b->quiet) { - if (b->regionattrib) { - if (b->varvolume) { - printf("Spreading regional attributes and volume constraints.\n"); - } else { - printf("Spreading regional attributes.\n"); - } - } else { - printf("Spreading regional volume constraints.\n"); - } - } - if (b->regionattrib && !b->refine) { - // Assign every tetrahedron a regional attribute of zero. - tetrahedrons->traversalinit(); - tptr = tetrahedrontraverse(); - while (tptr != (tetrahedron *) NULL) { - setelemattribute(tptr, in->numberoftetrahedronattributes, 0.0); - tptr = tetrahedrontraverse(); - } - } - for (i = 0; i < in->numberofregions; i++) { - if (regiontets[i].tet != dummytet) { - // Make sure the tetrahedron under consideration still exists. - // It may have been eaten by the virus. - if (!isdead(&(regiontets[i]))) { - // Put one tetrahedron in the virus pool. - infect(regiontets[i]); - regiontet = (tetrahedron **) viri->alloc(); - *regiontet = regiontets[i].tet; - // Apply one region's attribute and/or volume constraint. - regionplague(viri, in->regionlist[5 * i + 3], - in->regionlist[5 * i + 4]); - // The virus pool should be empty now. - } - } - } - if (b->regionattrib && !b->refine) { - // Note the fact that each tetrahedron has an additional attribute. - in->numberoftetrahedronattributes++; - } - } - - // Free up memory. - delete viri; - if (in->numberofholes > 0) { - delete [] holetets; - } - if (in->numberofregions > 0) { - delete [] regiontets; - } -} - -// -// End of carving out holes and concavities routines -// - -// -// Begin of mesh update routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// reconstructmesh() Reconstruct a tetrahedral mesh from a list of // -// tetrahedra and possibly a list of boundary faces. // -// // -// The list of tetrahedra is stored in 'in->tetrahedronlist', the list of // -// boundary faces is stored in 'in->trifacelist'. The tetrahedral mesh is // -// reconstructed in memorypool 'tetrahedrons', its boundary faces (subfaces) // -// are reconstructed in 'subfaces', its boundary edges (subsegments) are // -// reconstructed in 'subsegs'. If the -a switch is used, this procedure will // -// also read a list of REALs from 'in->tetrahedronvolumelist' and set a // -// maximum volume constraint on each tetrahedron. // -// // -// If the user has provided the boundary faces in 'in->trifacelist', they // -// will be inserted the mesh. Otherwise subfaces will be identified from the // -// mesh. All hull faces (including faces of the internal holes) will be // -// recognized as subfaces, internal faces between two tetrahedra which have // -// different attributes will also be recognized as subfaces. // -// // -// Subsegments will be identified after subfaces are reconstructed. Edges at // -// the intersections of non-coplanar subfaces are recognized as subsegments. // -// Edges between two coplanar subfaces with different boundary markers are // -// also recognized as subsegments. // -// // -// The facet index of each subface will be set automatically after we have // -// recovered subfaces and subsegments. That is, the set of subfaces, which // -// are coplanar and have the same boundary marker will be recognized as a // -// facet and has a unique index, stored as the facet marker in each subface // -// of the set, the real boundary marker of each subface will be found in // -// 'in->facetmarkerlist' by the index. Facet index will be used in Delaunay // -// refinement for detecting two incident facets. // -// // -// Points which are not corners of tetrahedra will be inserted into the mesh.// -// Return the number of faces on the hull after the reconstruction. // -// // -/////////////////////////////////////////////////////////////////////////////// - -long tetgenmesh::reconstructmesh() -{ - tetrahedron **tetsperverlist; - shellface **facesperverlist; - triface tetloop, neightet, neineightet, spintet; - face subloop, neighsh, neineighsh, subseg; - face sface1, sface2; - point *idx2verlist; - point torg, tdest, tapex, toppo; - point norg, ndest, napex; - list *neighshlist, *markerlist; - REAL sign, attrib, volume; - REAL da1, da2; - bool bondflag, insertsegflag; - int *idx2tetlist; - int *idx2facelist; - int *worklist; - int facetidx, marker; - int iorg, idest, iapex, ioppo; - int inorg, indest, inapex; - int index, i, j; - - if (!b->quiet) { - printf("Reconstructing mesh.\n"); - } - - // Create a map from index to points. - makeindex2pointmap(idx2verlist); - - // Create the tetrahedra. - for (i = 0; i < in->numberoftetrahedra; i++) { - // Create a new tetrahedron and set its four corners, make sure that - // four corners form a positive orientation. - maketetrahedron(&tetloop); - index = i * in->numberofcorners; - // Although there may be 10 nodes, we only read the first 4. - iorg = in->tetrahedronlist[index] - in->firstnumber; - idest = in->tetrahedronlist[index + 1] - in->firstnumber; - iapex = in->tetrahedronlist[index + 2] - in->firstnumber; - ioppo = in->tetrahedronlist[index + 3] - in->firstnumber; - torg = idx2verlist[iorg]; - tdest = idx2verlist[idest]; - tapex = idx2verlist[iapex]; - toppo = idx2verlist[ioppo]; - sign = orient3d(torg, tdest, tapex, toppo); - if (sign > 0.0) { - norg = torg; torg = tdest; tdest = norg; - } else if (sign == 0.0) { - printf("Warning: Tetrahedron %d is degenerate.\n", i + in->firstnumber); - } - setorg(tetloop, torg); - setdest(tetloop, tdest); - setapex(tetloop, tapex); - setoppo(tetloop, toppo); - // Temporarily set the vertices be type FREEVOLVERTEX, to indicate that - // they belong to the mesh. These types may be changed later. - setpointtype(torg, FREEVOLVERTEX); - setpointtype(tdest, FREEVOLVERTEX); - setpointtype(tapex, FREEVOLVERTEX); - setpointtype(toppo, FREEVOLVERTEX); - // Set element attributes if they exist. - for (j = 0; j < in->numberoftetrahedronattributes; j++) { - index = i * in->numberoftetrahedronattributes; - attrib = in->tetrahedronattributelist[index + j]; - setelemattribute(tetloop.tet, j, attrib); - } - // If -a switch is used (with no number follows) Set a volume - // constraint if it exists. - if (b->varvolume) { - if (in->tetrahedronvolumelist != (REAL *) NULL) { - volume = in->tetrahedronvolumelist[i]; - } else { - volume = -1.0; - } - setvolumebound(tetloop.tet, volume); - } - } - - // Set the connection between tetrahedra. - hullsize = 0l; - // Create a map from nodes to tetrahedra. - maketetrahedronmap(idx2tetlist, tetsperverlist); - // Initialize the worklist. - worklist = new int[points->items]; - for (i = 0; i < points->items; i++) { - worklist[i] = 0; - } - - // Loop all tetrahedra, bond two tetrahedra if they share a common face. - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - // Loop the four sides of the tetrahedron. - for (tetloop.loc = 0; tetloop.loc < 4; tetloop.loc++) { - sym(tetloop, neightet); - if (neightet.tet != dummytet) continue; // This side has finished. - torg = org(tetloop); - tdest = dest(tetloop); - tapex = apex(tetloop); - iorg = pointmark(torg) - in->firstnumber; - idest = pointmark(tdest) - in->firstnumber; - iapex = pointmark(tapex) - in->firstnumber; - worklist[iorg] = 1; - worklist[idest] = 1; - worklist[iapex] = 1; - bondflag = false; - // Search its neighbor in the adjacent tets of torg. - for (j = idx2tetlist[iorg]; j < idx2tetlist[iorg + 1] && !bondflag; - j++) { - if (tetsperverlist[j] == tetloop.tet) continue; // Skip myself. - neightet.tet = tetsperverlist[j]; - for (neightet.loc = 0; neightet.loc < 4; neightet.loc++) { - sym(neightet, neineightet); - if (neineightet.tet == dummytet) { - norg = org(neightet); - ndest = dest(neightet); - napex = apex(neightet); - inorg = pointmark(norg) - in->firstnumber; - indest = pointmark(ndest) - in->firstnumber; - inapex = pointmark(napex) - in->firstnumber; - if ((worklist[inorg] + worklist[indest] + worklist[inapex]) == 3) { - // Find! Bond them together and break the loop. - bond(tetloop, neightet); - bondflag = true; - break; - } - } - } - } - if (!bondflag) { - hullsize++; // It's a hull face. - // Bond this side to outer space. - dummytet[0] = encode(tetloop); - if (in->pointmarkerlist != (int *) NULL) { - // Set its three corners's markers be boundary (hull) vertices. - if (in->pointmarkerlist[iorg] == 0) { - in->pointmarkerlist[iorg] = 1; - } - if (in->pointmarkerlist[idest] == 0) { - in->pointmarkerlist[idest] = 1; - } - if (in->pointmarkerlist[iapex] == 0) { - in->pointmarkerlist[iapex] = 1; - } - } - } - worklist[iorg] = 0; - worklist[idest] = 0; - worklist[iapex] = 0; - } - tetloop.tet = tetrahedrontraverse(); - } - - // Subfaces will be inserted into the mesh. - if (in->trifacelist != (int *) NULL) { - // Recover subfaces from 'in->trifacelist'. - for (i = 0; i < in->numberoftrifaces; i++) { - index = i * 3; - iorg = in->trifacelist[index] - in->firstnumber; - idest = in->trifacelist[index + 1] - in->firstnumber; - iapex = in->trifacelist[index + 2] - in->firstnumber; - // Look for the location of this subface. - worklist[iorg] = 1; - worklist[idest] = 1; - worklist[iapex] = 1; - bondflag = false; - // Search its neighbor in the adjacent tets of torg. - for (j = idx2tetlist[iorg]; j < idx2tetlist[iorg + 1] && !bondflag; - j++) { - neightet.tet = tetsperverlist[j]; - for (neightet.loc = 0; neightet.loc < 4; neightet.loc++) { - norg = org(neightet); - ndest = dest(neightet); - napex = apex(neightet); - inorg = pointmark(norg) - in->firstnumber; - indest = pointmark(ndest) - in->firstnumber; - inapex = pointmark(napex) - in->firstnumber; - if ((worklist[inorg] + worklist[indest] + worklist[inapex]) == 3) { - bondflag = true; // Find! - break; - } - } - } - if (bondflag) { - // Create a new subface and insert it into the mesh. - makeshellface(subfaces, &subloop); - torg = idx2verlist[iorg]; - tdest = idx2verlist[idest]; - tapex = idx2verlist[iapex]; - setsorg(subloop, torg); - setsdest(subloop, tdest); - setsapex(subloop, tapex); - // Set the vertices be FREESUBVERTEX to indicate they belong to a - // facet of the domain. They may be changed later. - setpointtype(torg, FREESUBVERTEX); - setpointtype(tdest, FREESUBVERTEX); - setpointtype(tapex, FREESUBVERTEX); - if (in->trifacemarkerlist != (int *) NULL) { - setshellmark(subloop, in->trifacemarkerlist[i]); - } - adjustedgering(neightet, CCW); - findedge(&subloop, org(neightet), dest(neightet)); - tsbond(neightet, subloop); - sym(neightet, neineightet); - if (neineightet.tet != dummytet) { - sesymself(subloop); - tsbond(neineightet, subloop); - } - } else { - printf("Warning: Subface %d is discarded.\n", i + in->firstnumber); - } - worklist[iorg] = 0; - worklist[idest] = 0; - worklist[iapex] = 0; - } - } else { - // Indentify subfaces from the mesh. - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - // Loop the four sides of the tetrahedron. - for (tetloop.loc = 0; tetloop.loc < 4; tetloop.loc++) { - tspivot(tetloop, subloop); - if (subloop.sh != dummysh) continue; - bondflag = false; - sym(tetloop, neightet); - if (neightet.tet == dummytet) { - // It's a hull face. Insert a subface at here. - bondflag = true; - } else { - // It's an interior face. Insert a subface if two tetrahedra have - // different attributes (i.e., they belong to two regions). - if (in->numberoftetrahedronattributes > 0) { - if (elemattribute(neightet.tet, - in->numberoftetrahedronattributes - 1) != - elemattribute(tetloop.tet, - in->numberoftetrahedronattributes - 1)) { - bondflag = true; - } - } - } - if (bondflag) { - adjustedgering(tetloop, CCW); - makeshellface(subfaces, &subloop); - torg = org(tetloop); - tdest = dest(tetloop); - tapex = apex(tetloop); - setsorg(subloop, torg); - setsdest(subloop, tdest); - setsapex(subloop, tapex); - // Set the vertices be FACETVERTEX to indicate they belong to a - // facet of the domain. They may be changed later. - setpointtype(torg, FACETVERTEX); - setpointtype(tdest, FACETVERTEX); - setpointtype(tapex, FACETVERTEX); - tsbond(tetloop, subloop); - if (neightet.tet != dummytet) { - sesymself(subloop); - tsbond(neightet, subloop); - } - } - } - tetloop.tet = tetrahedrontraverse(); - } - } - - // Set the connection between subfaces. An subsegment may have more than - // two subfaces sharing it, 'neighshlist' stores all subfaces sharing - // one edge. - neighshlist = new list(sizeof(face), NULL); - // Create a map from nodes to subfaces. - makesubfacemap(idx2facelist, facesperverlist); - - // Loop over the set of subfaces, setup the connection between subfaces. - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - for (i = 0; i < 3; i++) { - spivot(subloop, neighsh); - if (neighsh.sh == dummysh) { - // This side is 'empty', operate on it. - torg = sorg(subloop); - tdest = sdest(subloop); - tapex = sapex(subloop); - neighshlist->append(&subloop); - iorg = pointmark(torg) - in->firstnumber; - // Search its neighbor in the adjacent list of torg. - for (j = idx2facelist[iorg]; j < idx2facelist[iorg + 1]; j++) { - neighsh.sh = facesperverlist[j]; - if (neighsh.sh == subloop.sh) continue; - neighsh.shver = 0; - if (isfacehasedge(&neighsh, torg, tdest)) { - findedge(&neighsh, torg, tdest); - // Insert 'neighsh' into 'neighshlist'. - if (neighshlist->len() < 2) { - neighshlist->append(&neighsh); - } else { - for (index = 0; index < neighshlist->len() - 1; index++) { - sface1 = * (face *)(* neighshlist)[index]; - sface2 = * (face *)(* neighshlist)[index + 1]; - da1 = facedihedral(torg, tdest, sapex(sface1), sapex(neighsh)); - da2 = facedihedral(torg, tdest, sapex(sface1), sapex(sface2)); - if (da1 < da2) { - break; // Insert it after index. - } - } - neighshlist->insert(index + 1, &neighsh); - } - } - } - // Bond the subfaces in 'neighshlist'. - if (neighshlist->len() > 1) { - neighsh = * (face *)(* neighshlist)[0]; - for (j = 1; j <= neighshlist->len(); j++) { - if (j < neighshlist->len()) { - neineighsh = * (face *)(* neighshlist)[j]; - } else { - neineighsh = * (face *)(* neighshlist)[0]; - } - sbond1(neighsh, neineighsh); - neighsh = neineighsh; - } - } else { - // No neighbor subface be found, bond 'subloop' to itself. - sbond(subloop, subloop); - } - neighshlist->clear(); - } - senextself(subloop); - } - subloop.sh = shellfacetraverse(subfaces); - } - - // Subsegments will be introudced. - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - for (i = 0; i < 3; i++) { - sspivot(subloop, subseg); - if (subseg.sh == dummysh) { - // This side has no subsegment bonded, check it. - torg = sorg(subloop); - tdest = sdest(subloop); - tapex = sapex(subloop); - spivot(subloop, neighsh); - spivot(neighsh, neineighsh); - insertsegflag = false; - if (subloop.sh == neighsh.sh || subloop.sh != neineighsh.sh) { - // This side is either self-bonded or more than two subfaces, - // insert a subsegment at this side. - insertsegflag = true; - } else { - // Only two subfaces case. - assert(subloop.sh != neighsh.sh); - napex = sapex(neighsh); - sign = orient3d(torg, tdest, tapex, napex); - if (iscoplanar(torg, tdest, tapex, napex, sign, b->epsilon)) { - // Although they are coplanar, we still need to check if they - // have the same boundary marker. - insertsegflag = (shellmark(subloop) != shellmark(neighsh)); - } else { - // Non-coplanar. - insertsegflag = true; - } - } - if (insertsegflag) { - // Create a subsegment at this side. - makeshellface(subsegs, &subseg); - setsorg(subseg, torg); - setsdest(subseg, tdest); - // At the moment, all segment vertices have type FACETVERTEX. - // They will be set to type ACUTEVERTEX or NONACUTEVERTEX by - // routine markacutevertices() later. - // setpointtype(torg, SEGMENTVERTEX); - // setpointtype(tdest, SEGMENTVERTEX); - // Bond all subfaces to this subsegment. - neighsh = subloop; - do { - ssbond(neighsh, subseg); - spivotself(neighsh); - } while (neighsh.sh != subloop.sh); - } - } - senextself(subloop); - } - subloop.sh = shellfacetraverse(subfaces); - } - // Remember the number of input segments. - insegment = subsegs->items; - // Find the acute vertices and set them be type ACUTEVERTEX. - - // Indentify the facet and set facet index for each subface. - markerlist = new list("int"); - - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - // Only operate on uninfected subface, after operating, infect it. - if (!sinfected(subloop)) { - // A new facet has found. - marker = shellmark(subloop); - markerlist->append(&marker); - facetidx = markerlist->len(); // 'facetidx' starts from 1. - setshellmark(subloop, facetidx); - sinfect(subloop); - neighshlist->append(&subloop); - // Find out all subfaces of this facet (bounded by subsegments). - for (i = 0; i < neighshlist->len(); i++) { - neighsh = * (face *) (* neighshlist)[i]; - for (j = 0; j < 3; j++) { - sspivot(neighsh, subseg); - if (subseg.sh == dummysh) { - spivot(neighsh, neineighsh); - if (!sinfected(neineighsh)) { - // 'neineighsh' is in the same facet as 'subloop'. - assert(shellmark(neineighsh) == marker); - setshellmark(neineighsh, facetidx); - sinfect(neineighsh); - neighshlist->append(&neineighsh); - } - } - senextself(neighsh); - } - } - neighshlist->clear(); - } - subloop.sh = shellfacetraverse(subfaces); - } - // Save the facet markers in 'in->facetmarkerlist'. - in->numberoffacets = markerlist->len(); - in->facetmarkerlist = new int[in->numberoffacets]; - for (i = 0; i < in->numberoffacets; i++) { - marker = * (int *) (* markerlist)[i]; - in->facetmarkerlist[i] = marker; - } - // Uninfect all subfaces. - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - assert(sinfected(subloop)); - suninfect(subloop); - subloop.sh = shellfacetraverse(subfaces); - } - - // The mesh contains boundary now. - checksubfaces = 1; - - if (b->quality) { - // Check and recover the Delaunay property. - queue* flipqueue = new queue(sizeof(badface)); - checkdelaunay(flipqueue); - if (!flipqueue->empty()) { - // Call flip algorithm to recover Delaunayness. - flip(flipqueue, NULL); - } - delete flipqueue; - } - - delete markerlist; - delete neighshlist; - delete [] worklist; - delete [] idx2tetlist; - delete [] tetsperverlist; - delete [] idx2facelist; - delete [] facesperverlist; - delete [] idx2verlist; - - return hullsize; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// insertaddpoints() Insert additional points in 'in->addpointlist'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::insertaddpoints() -{ - queue *flipqueue; - triface searchtet; - face checksh, checkseg; - point newpoint; - point p1, p2, p3, p4; - enum locateresult loc; - REAL ori; - int ptmark; - int index; - int i, j; - - if (!b->quiet) { - printf("Insert additional points into mesh.\n"); - } - // Initialize 'flipqueue'. - flipqueue = new queue(sizeof(badface)); - recenttet.tet = dummytet; - - index = 0; - for (i = 0; i < in->numberofaddpoints; i++) { - // Create a newpoint. - newpoint = (point) points->alloc(); - newpoint[0] = in->addpointlist[index++]; - newpoint[1] = in->addpointlist[index++]; - newpoint[2] = in->addpointlist[index++]; - for (j = 0; j < in->numberofpointattributes; j++) { - newpoint[3 + j] = 0.0; - } - // Remember the point index (starts from 'in->firstnumber'). - ptmark = (int) points->items - (in->firstnumber == 1 ? 0 : 1); - setpointmark(newpoint, ptmark); - // Find the location of the inserted point. - searchtet = recenttet; - loc = locate(newpoint, &searchtet); - if (loc != OUTSIDE) { - if (loc != ONVERTEX) { - loc = adjustlocate(newpoint, &searchtet, loc, b->epsilon); - } - } - if (loc == OUTSIDE) { - // Perform a brute-force search. - tetrahedrons->traversalinit(); - searchtet.tet = tetrahedrontraverse(); - while (searchtet.tet != (tetrahedron *) NULL) { - p1 = (point) searchtet.tet[4]; - p2 = (point) searchtet.tet[5]; - p3 = (point) searchtet.tet[6]; - p4 = (point) searchtet.tet[7]; - ori = orient3d(p2, p1, p3, newpoint); - if (ori >= 0) { - ori = orient3d(p1, p2, p4, newpoint); - if (ori >= 0) { - ori = orient3d(p2, p3, p4, newpoint); - if (ori >= 0) { - ori = orient3d(p3, p1, p4, newpoint); - if (ori >= 0) { - // 'newpoint' lies inside, or on a face, or on an edge, or - // a vertex of 'searchtet'. - loc = adjustlocate(newpoint, &searchtet, OUTSIDE, b->epsilon); - if (loc != OUTSIDE) break; - } - } - } - } - searchtet.tet = tetrahedrontraverse(); - } - } - // Insert the point if it not lies outside or on a vertex. - switch (loc) { - case INTETRAHEDRON: - setpointtype(newpoint, FREEVOLVERTEX); - splittetrahedron(newpoint, &searchtet, flipqueue); - break; - case ONFACE: - tspivot(searchtet, checksh); - if (checksh.sh != dummysh) { - setpointtype(newpoint, FREESUBVERTEX); - } else { - setpointtype(newpoint, FREEVOLVERTEX); - } - splittetface(newpoint, &searchtet, flipqueue); - break; - case ONEDGE: - tsspivot(&searchtet, &checkseg); - if (checkseg.sh != dummysh) { - setpointtype(newpoint, FREESEGVERTEX); - } else { - tspivot(searchtet, checksh); - if (checksh.sh != dummysh) { - setpointtype(newpoint, FREESUBVERTEX); - } else { - setpointtype(newpoint, FREEVOLVERTEX); - } - } - splittetedge(newpoint, &searchtet, flipqueue); - break; - case ONVERTEX: - if (b->verbose) { - printf("Warning: Point (%.17g, %.17g, %.17g) falls on a vertex.\n", - newpoint[0], newpoint[1], newpoint[2]); - } - break; - case OUTSIDE: - if (b->verbose) { - printf("Warning: Point (%.17g, %.17g, %.17g) lies outside the mesh.\n", - newpoint[0], newpoint[1], newpoint[2]); - } - break; - } - // Remember the tetrahedron for next point searching. - recenttet = searchtet; - if (loc == ONVERTEX || loc == OUTSIDE) { - pointdealloc(newpoint); - } else { - flip(flipqueue, NULL); - } - } - - delete flipqueue; -} - -// -// End of mesh update routines -// - -// -// Begin of Delaunay refinement routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// initializerpsarray() Calculate the initial radii of protecting spheres // -// of all acute vertices, save in 'rpsarray'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::initializerpsarray(REAL* rpsarray) -{ - list *neightetlist; - tetrahedron tetptr; - triface starttet, neightet; - point pointloop, workpt[3]; - REAL rps, len; - int index, i, j; - - if (b->verbose) { - printf(" Initializing protecting spheres.\n"); - } - - // Initialize the point2tet field of each point. - points->traversalinit(); - pointloop = pointtraverse(); - while (pointloop != (point) NULL) { - setpoint2tet(pointloop, (tetrahedron) NULL); - pointloop = pointtraverse(); - } - // Construct a map from points to tetrahedra. - makepoint2tetmap(); - // Initialize 'neightetlist'. - neightetlist = new list(sizeof(triface), NULL, 256); - - points->traversalinit(); - pointloop = pointtraverse(); - while (pointloop != (point) NULL) { - tetptr = point2tet(pointloop); - // Only calculate lfs(p) if it is acute and is not dangling. - if ((pointtype(pointloop) == ACUTEVERTEX) && - (tetptr != (tetrahedron) NULL)) { - decode(tetptr, starttet); - assert((starttet.tet != NULL) && (starttet.tet != dummytet)); - // Find all tetrahedra sharing 'pointloop'. - findorg(&starttet, pointloop); - infect(starttet); - neightetlist->append(&starttet); - for (i = 0; i < neightetlist->len(); i++) { - starttet = * (triface *)(* neightetlist)[i]; - assert(infected(starttet)); - // The origin of 'starttet' should be 'pointloop'. - adjustedgering(starttet, CCW); - if (org(starttet) != pointloop) { - enextself(starttet); - } - assert(org(starttet) == pointloop); - // Let 'starttet' be the opposite face of 'pointloop'. - enextfnextself(starttet); - assert(oppo(starttet) == pointloop); - // Get three neighbors of faces having 'pointloop'. - adjustedgering(starttet, CCW); - for (j = 0; j < 3; j++) { - fnext(starttet, neightet); - symself(neightet); - // Add it into list if is is not outer space and not infected. - if ((neightet.tet != dummytet) && !infected(neightet)) { - findorg(&neightet, pointloop); - infect(neightet); - neightetlist->append(&neightet); - } - enextself(starttet); - } - } - // 'neightetlist' contains all tetrahedra sharing at 'pointloop'. Get - // the shortest edge length of edges sharing at 'pointloop'. - rps = longest; - for (i = 0; i < neightetlist->len(); i++) { - starttet = * (triface *)(* neightetlist)[i]; - assert(org(starttet) == pointloop); - workpt[0] = dest(starttet); - workpt[1] = apex(starttet); - workpt[2] = oppo(starttet); - for (j = 0; j < 3; j++) { - len = distance(workpt[j], pointloop); - if (pointtype(workpt[j]) == ACUTEVERTEX) { - len /= 3.0; - } else { - len /= 2.0; - } - if (len < rps) rps = len; - } - } - // Uninfect tetrahedra and clear 'neightetlist'. - for (i = 0; i < neightetlist->len(); i++) { - starttet = * (triface *)(* neightetlist)[i]; - uninfect(starttet); - } - neightetlist->clear(); - } else { - // A non-acute or dangling vertex. - rps = 0.0; - } - // Return the local feature size of pointloop. - index = pointmark(pointloop) - in->firstnumber; - rpsarray[index] = rps; - pointloop = pointtraverse(); - } - - delete neightetlist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// marksharpfacets() Make a map of facets which form sharp corners. // -// // -// A sharp corner between two facets has a dihedral angle smaller than the // -// 'dihedbound' (in degrees). The map is returned in an integer array // -// 'idx2facetlist'. If idx2facetlist[facetidx - 1] is '1', it means that // -// facet form a sharp corner with other facet. // -// // -// NOTE: idx2facetlist is created inside this routine, don't forget to free // -// it after using. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::marksharpfacets(int*& idx2facetlist, REAL dihedbound) -{ - list *incishlist; - triface adjtet; - face segloop, prevseg, checkseg; - face subloop, parentsh, spinsh; - face neighsh, checksh; - point eorg, edest; - REAL anglebound, angle; - int facetidx; - int i, j; - - if (b->verbose) { - printf(" Marking facets have sharp corners.\n"); - } - - anglebound = dihedbound * 3.1415926535897932 / 180.; - // Create and initialize 'idx2facetlist'. - idx2facetlist = new int[in->numberoffacets + 1]; - for (i = 0; i < in->numberoffacets + 1; i++) idx2facetlist[i] = 0; - // A list keeps incident and not co-facet subfaces around a subsegment. - incishlist = new list(sizeof(face), NULL); - - // Loop the set of subsegments once, counter the number of incident - // facets of each facet. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - // A subsegment may be split into many pieces, we only need one piece - // for getting the incident facets. Only operate on the one which - // contains the origin of the unsplit subsegment. - segloop.shver = 0; - senext2(segloop, prevseg); - spivotself(prevseg); - if (prevseg.sh == dummysh) { - // Operate on this subsegment. - segloop.shver = 0; - spivot(segloop, parentsh); - assert(parentsh.sh != dummysh); - spivot(parentsh, spinsh); - if (spinsh.sh != parentsh.sh) { - // This subface is not self-bonded. - eorg = sorg(segloop); - edest = sdest(segloop); - // Get all incident subfaces around 'segloop'. - spinsh = parentsh; - do { - if (sorg(spinsh) != eorg) { - sesymself(spinsh); - } - incishlist->append(&spinsh); - spivotself(spinsh); - } while (spinsh.sh != parentsh.sh); - // Check the pair of adjacent subfaces for small angle. - spinsh = * (face *)(* incishlist)[0]; - for (i = 1; i <= incishlist->len(); i++) { - if (i == incishlist->len()) { - neighsh = * (face *)(* incishlist)[0]; - } else { - neighsh = * (face *)(* incishlist)[i]; - } - // Only do test when the side spinsh is faceing inward. - stpivot(spinsh, adjtet); - if (adjtet.tet != dummytet) { - angle = facedihedral(eorg, edest, sapex(spinsh), sapex(neighsh)); - if (angle < anglebound) { - facetidx = shellmark(spinsh); - idx2facetlist[facetidx - 1] = 1; - facetidx = shellmark(neighsh); - idx2facetlist[facetidx - 1] = 1; - } - } - spinsh = neighsh; - } - incishlist->clear(); - } - } - segloop.sh = shellfacetraverse(subsegs); - } - - // Ensure all the sharp facets are marked. The mergefacet() operation - // may leave several facets having different markers merged. - incishlist->clear(); - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - // Only operate on sharp and unmarked subfaces. - facetidx = shellmark(subloop); - if (!sinfected(subloop) && (idx2facetlist[facetidx - 1] == 1)) { - sinfect(subloop); - incishlist->append(&subloop); - // Find out all subfaces of this facet (bounded by subsegments). - for (i = 0; i < incishlist->len(); i++) { - neighsh = * (face *) (* incishlist)[i]; - for (j = 0; j < 3; j++) { - sspivot(neighsh, checkseg); - if (checkseg.sh == dummysh) { - spivot(neighsh, checksh); - if (!sinfected(checksh)) { - // 'checksh' is in the same facet as 'subloop'. - sinfect(checksh); - // Check if it is marked. - facetidx = shellmark(checksh); - if (idx2facetlist[facetidx - 1] == 0) { - idx2facetlist[facetidx - 1] = 1; - } - incishlist->append(&checksh); - } - } - senextself(neighsh); - } - } - incishlist->clear(); - } - subloop.sh = shellfacetraverse(subfaces); - } - // Uninfect all sharp subfaces. - subfaces->traversalinit(); - subloop.sh = shellfacetraverse(subfaces); - while (subloop.sh != (shellface *) NULL) { - if (sinfected(subloop)) { - facetidx = shellmark(subloop); - assert(idx2facetlist[facetidx - 1] == 1); - suninfect(subloop); - } - subloop.sh = shellfacetraverse(subfaces); - } - - delete incishlist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// enqueuebadtet() Add a bad tetrahedron to the end of a queue. // -// // -// The queue is actually a set of 64 queues. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh:: -enqueuebadtet(triface *instet, REAL ratio, point insorg, point insdest, - point insapex, point insoppo, point inscent) -{ - badtetrahedron *newtet; - int queuenumber; - - // Allocate space for the bad tetrahedron. - newtet = (badtetrahedron *) badtetrahedrons->alloc(); - newtet->tet = *instet; - newtet->key = ratio; - newtet->cent[0] = inscent[0]; - newtet->cent[1] = inscent[1]; - newtet->cent[2] = inscent[2]; - newtet->tetorg = insorg; - newtet->tetdest = insdest; - newtet->tetapex = insapex; - newtet->tetoppo = insoppo; - newtet->nexttet = (badtetrahedron *) NULL; - // Determine the appropriate queue to put the bad tetrahedron into. - if (ratio > b->goodratio) { - queuenumber = (int) ((ratio - b->goodratio) / 0.5); - // 'queuenumber' may overflow (negative) caused by a very large ratio. - if ((queuenumber > 63) || (queuenumber < 0)) { - queuenumber = 63; - } - } else { - // It's not a bad ratio; put the tet in the lowest-priority queue. - queuenumber = 0; - } - // Add the tetrahedron to the end of a queue. - *tetquetail[queuenumber] = newtet; - // Maintain a pointer to the NULL pointer at the end of the queue. - tetquetail[queuenumber] = &newtet->nexttet; - - if (b->verbose > 2) { - printf(" Queueing bad tet: (%d, %d, %d, %d), ratio %g, qnum %d.\n", - pointmark(insorg), pointmark(insdest), pointmark(insapex), - pointmark(insoppo), sqrt(ratio), queuenumber); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// dequeuebadtet() Remove a tetrahedron from the front of the queue. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::badtetrahedron* tetgenmesh::dequeuebadtet() -{ - badtetrahedron *result; - int queuenumber; - - // Look for a nonempty queue. - for (queuenumber = 63; queuenumber >= 0; queuenumber--) { - result = tetquefront[queuenumber]; - if (result != (badtetrahedron *) NULL) { - // Remove the tetrahedron from the queue. - tetquefront[queuenumber] = result->nexttet; - // Maintain a pointer to the NULL pointer at the end of the queue. - if (tetquefront[queuenumber] == (badtetrahedron *) NULL) { - tetquetail[queuenumber] = &tetquefront[queuenumber]; - } - return result; - } - } - return (badtetrahedron *) NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checkseg4encroach() Check a subsegment to see if it is encroached. // -// // -// A subsegment is encroached if there is a vertex in its diametral circle // -// (that is, the subsegment faces an angle greater than 90 degrees). // -// // -// If 'testpt' is not NULL, only check whether 'testsubseg' is encroached by // -// it or not. Otherwise, check all apexes of faces containing 'testsubseg', // -// to see if there is one encroaches it. // -// // -// If 'enqueueflag' is TRUE, add 'testsubseg' to queue 'badsubsegs' if it is // -// encroached. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -checkseg4encroach(face* testsubseg, point testpt, bool enqueueflag) -{ - badface *encsubseg; - triface starttet, spintet; - point eorg, edest, eapex, encpt; - REAL cent[3], radius, dist, diff; - bool enq; - int hitbdry; - - eorg = sorg(*testsubseg); - edest = sdest(*testsubseg); - cent[0] = 0.5 * (eorg[0] + edest[0]); - cent[1] = 0.5 * (eorg[1] + edest[1]); - cent[2] = 0.5 * (eorg[2] + edest[2]); - radius = distance(cent, eorg); - - enq = false; - encpt = (point) NULL; - if (testpt == (point) NULL) { - // Check if it is encroached by traversing all faces containing it. - sstpivot(testsubseg, &starttet); - eapex = apex(starttet); - spintet = starttet; - hitbdry = 0; - do { - dist = distance(cent, apex(spintet)); - diff = dist - radius; - if (fabs(diff) / radius <= b->epsilon) diff = 0.0; // Rounding. - if (diff < 0.0) { - enq = true; - encpt = apex(spintet); - break; - } - if (!fnextself(spintet)) { - hitbdry++; - if (hitbdry < 2) { - esym(starttet, spintet); - if (!fnextself(spintet)) { - hitbdry++; - } - } - } - } while (apex(spintet) != eapex && (hitbdry < 2)); - } else { - // Only check if 'testsubseg' is encroached by 'testpt'. - dist = distance(cent, testpt); - diff = dist - radius; - if (fabs(diff) / radius <= b->epsilon) diff = 0.0; // Rounding. - if (diff < 0.0) { - enq = true; - } - } - - if (enq && enqueueflag) { - if (b->verbose > 2) { - printf(" Queuing encroaching subsegment (%d, %d).\n", - pointmark(eorg), pointmark(edest)); - } - encsubseg = (badface *) badsubsegs->alloc(); - encsubseg->ss = *testsubseg; - encsubseg->forg = eorg; - encsubseg->fdest = edest; - encsubseg->foppo = encpt; - // Set the pointer of 'encsubseg' into 'testseg'. It has two purposes: - // (1) We can regonize it is encroached; (2) It is uniquely queued. - setshell2badface(encsubseg->ss, encsubseg); - } - - return enq; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checksub4encroach() Check a subface to see if it is encroached. If so, // -// add it to the list. // -// // -// A subface is encroached if there is a vertex in its diametral sphere. If // -// 'testpt != NULL', only test if 'testsub' is encroached by it. Otherwise, // -// test the opposites of the adjoining tetrahedra of 'testsub' at both side // -// to see whether it is encroached or not. If 'enqueueflag = TRUE', add // -// 'testsub' into pool 'badsubfaces'. Return TRUE if 'testsub' is encroached,// -// return FALSE if it is not. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh:: -checksub4encroach(face* testsub, point testpt, bool enqueueflag) -{ - badface *encsub; - triface abuttet; - point forg, fdest, fapex, encpt; - REAL cent[3], radius, dist, diff; - bool enq, bqual, ncollinear; - int quenumber, i; - - enq = false; - encpt = (point) NULL; - bqual = checksub4badqual(testsub); - - if (!bqual) { - forg = sorg(*testsub); - fdest = sdest(*testsub); - fapex = sapex(*testsub); - ncollinear = circumsphere(forg, fdest, fapex, NULL, cent, &radius); - assert(ncollinear == true); - - if (testpt == (point) NULL) { - stpivot(*testsub, abuttet); - if (abuttet.tet != dummytet) { - dist = distance(cent, oppo(abuttet)); - diff = dist - radius; - if (fabs(diff) / radius <= b->epsilon) diff = 0.0; // Rounding. - enq = diff < 0.0; - if (enq) encpt = oppo(abuttet); - } - if (!enq) { - sesymself(*testsub); - stpivot(*testsub, abuttet); - if (abuttet.tet != dummytet) { - dist = distance(cent, oppo(abuttet)); - diff = dist - radius; - if (fabs(diff) / radius <= b->epsilon) diff = 0.0; // Rounding. - enq = diff < 0.0; - if (enq) encpt = oppo(abuttet); - } - } - } else { - // Only do test when 'testpt' is one of its corners. - if (testpt != forg && testpt != fdest && testpt != fapex) { - dist = distance(cent, testpt); - diff = dist - radius; - if (fabs(diff) / radius <= b->epsilon) diff = 0.0; // Rounding. - enq = diff < 0.0; - } - } - } - - if ((enq || bqual) && enqueueflag) { - encsub = (badface *) badsubfaces->alloc(); - encsub->ss = *testsub; - encsub->forg = sorg(*testsub); - encsub->fdest = sdest(*testsub); - encsub->fapex = sapex(*testsub); - encsub->foppo = encpt; - if (enq) { - for (i = 0; i < 3; i++) encsub->cent[i] = cent[i]; - } else { - for (i = 0; i < 3; i++) encsub->cent[i] = 0.0; - } - encsub->nextface = (badface *) NULL; - // Set the pointer of 'encsubseg' into 'testsub'. It has two purposes: - // (1) We can regonize it is encroached; (2) It is uniquely queued. - setshell2badface(encsub->ss, encsub); - quenumber = bqual ? 1 : 0; - // Add the subface to the end of a queue. - *subquetail[quenumber] = encsub; - // Maintain a pointer to the NULL pointer at the end of the queue. - subquetail[quenumber] = &encsub->nextface; - if (b->verbose > 2) { - printf(" Queuing %s subface (%d, %d, %d).\n", - enq ? "encroached" : "badqual", pointmark(encsub->forg), - pointmark(encsub->fdest), pointmark(encsub->fapex)); - } - } - - return enq || bqual; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checksub4badquality() Test if the quality of a subface is bad. // -// // -// A subface has bad quality if: (1) its minimum internal angle is smaller // -// than 20 degree; or (2) its area is larger than a maximum area condition. // -// Return TRUE if it is bad. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::checksub4badqual(face* testsub) -{ - face sametestsub; - face subseg1, subseg2; - point torg, tdest, tapex; - point anglevertex; - REAL dxod, dyod, dzod; - REAL dxda, dyda, dzda; - REAL dxao, dyao, dzao; - REAL dxod2, dyod2, dzod2; - REAL dxda2, dyda2, dzda2; - REAL dxao2, dyao2, dzao2; - REAL apexlen, orglen, destlen; - REAL angle, area; - bool enq; - - enq = false; - torg = sorg(*testsub); - tdest = sdest(*testsub); - tapex = sapex(*testsub); - dxod = torg[0] - tdest[0]; - dyod = torg[1] - tdest[1]; - dzod = torg[2] - tdest[2]; - dxda = tdest[0] - tapex[0]; - dyda = tdest[1] - tapex[1]; - dzda = tdest[2] - tapex[2]; - dxao = tapex[0] - torg[0]; - dyao = tapex[1] - torg[1]; - dzao = tapex[2] - torg[2]; - dxod2 = dxod * dxod; - dyod2 = dyod * dyod; - dzod2 = dzod * dzod; - dxda2 = dxda * dxda; - dyda2 = dyda * dyda; - dzda2 = dzda * dzda; - dxao2 = dxao * dxao; - dyao2 = dyao * dyao; - dzao2 = dzao * dzao; - // Find the lengths of the triangle's three edges. - apexlen = dxod2 + dyod2 + dzod2; - orglen = dxda2 + dyda2 + dzda2; - destlen = dxao2 + dyao2 + dzao2; - if ((apexlen < orglen) && (apexlen < destlen)) { - // The edge opposite the apex is shortest. - // Find the square of the cosine of the angle at the apex. - angle = dxda * dxao + dyda * dyao + dzda * dzao; - angle = angle * angle / (orglen * destlen); - anglevertex = tapex; - senext(*testsub, sametestsub); - sspivot(sametestsub, subseg1); - senext2(*testsub, sametestsub); - sspivot(sametestsub, subseg2); - } else if (orglen < destlen) { - // The edge opposite the origin is shortest. - // Find the square of the cosine of the angle at the origin. - angle = dxod * dxao + dyod * dyao + dzod * dzao; - angle = angle * angle / (apexlen * destlen); - anglevertex = torg; - sspivot(*testsub, subseg1); - senext2(*testsub, sametestsub); - sspivot(sametestsub, subseg2); - } else { - // The edge opposite the destination is shortest. - // Find the square of the cosine of the angle at the destination. - angle = dxod * dxda + dyod * dyda + dzod * dzda; - angle = angle * angle / (apexlen * orglen); - anglevertex = tdest; - sspivot(*testsub, subseg1); - senext(*testsub, sametestsub); - sspivot(sametestsub, subseg2); - } - - // Check if both edges that form the angle are segments. - if ((subseg1.sh != dummysh) && (subseg2.sh != dummysh)) { - // The angle is a segment intersection. Don't add this bad subface to - // the list; there's nothing that can be done about a small angle - // between two segments. - angle = 0.0; - } else if (pointtype(anglevertex) == ACUTEVERTEX) { - // If the small angle vertex is acute, do not refine this face. - angle = 0.0; - } - - // Check whether the angle is smaller than permitted. - if (angle > b->goodangle) { - enq = true; - } - - if (!enq && areabound(*testsub) > 0.0) { - // Check whether the area is larger than desired. A variation form of - // Heron's formula which only uses the squares of the edge lengthes - // is used to calculated the area of a 3D triangle. - area = apexlen + orglen - destlen; - area = area * area; - area = 4 * apexlen * orglen - area; - area = 0.25 * sqrt(fabs(area)); - if (area > areabound(*testsub)) { - enq = true; - } - } - - return enq; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checktet4badqual() Test a tetrahedron for quality measures. // -// // -// Tests a tetrahedron to see if it satisfies the minimum ratio condition // -// and the maximum volume condition. Tetrahedra that aren't upto spec are // -// added to the bad tetrahedron queue. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::checktet4badqual(triface* testtet) -{ - point torg, tdest, tapex, toppo; - REAL dxod, dyod, dzod, dxda, dyda, dzda, dxao, dyao, dzao; - REAL dxop, dyop, dzop, dxdp, dydp, dzdp, dxap, dyap, dzap; - REAL dxod2, dyod2, dzod2, dxda2, dyda2, dzda2, dxao2, dyao2, dzao2; - REAL dxop2, dyop2, dzop2, dxdp2, dydp2, dzdp2, dxap2, dyap2, dzap2; - REAL dxoc, dyoc, dzoc, dxoc2, dyoc2, dzoc2; - REAL edgelen[6], cent[3]; - REAL smedgelen, averlen, volume; - REAL radius, ratio2; - int i; - - torg = org(*testtet); - tdest = dest(*testtet); - tapex = apex(*testtet); - toppo = oppo(*testtet); - - dxod = torg[0] - tdest[0]; - dyod = torg[1] - tdest[1]; - dzod = torg[2] - tdest[2]; - dxda = tdest[0] - tapex[0]; - dyda = tdest[1] - tapex[1]; - dzda = tdest[2] - tapex[2]; - dxao = tapex[0] - torg[0]; - dyao = tapex[1] - torg[1]; - dzao = tapex[2] - torg[2]; - - dxop = torg[0] - toppo[0]; - dyop = torg[1] - toppo[1]; - dzop = torg[2] - toppo[2]; - dxdp = tdest[0] - toppo[0]; - dydp = tdest[1] - toppo[1]; - dzdp = tdest[2] - toppo[2]; - dxap = tapex[0] - toppo[0]; - dyap = tapex[1] - toppo[1]; - dzap = tapex[2] - toppo[2]; - - dxod2 = dxod * dxod; - dyod2 = dyod * dyod; - dzod2 = dzod * dzod; - dxda2 = dxda * dxda; - dyda2 = dyda * dyda; - dzda2 = dzda * dzda; - dxao2 = dxao * dxao; - dyao2 = dyao * dyao; - dzao2 = dzao * dzao; - - dxop2 = dxop * dxop; - dyop2 = dyop * dyop; - dzop2 = dzop * dzop; - dxdp2 = dxdp * dxdp; - dydp2 = dydp * dydp; - dzdp2 = dzdp * dzdp; - dxap2 = dxap * dxap; - dyap2 = dyap * dyap; - dzap2 = dzap * dzap; - - // Find the smallest edge length of 'testtet'. - edgelen[0] = dxod2 + dyod2 + dzod2; - edgelen[1] = dxda2 + dyda2 + dzda2; - edgelen[2] = dxao2 + dyao2 + dzao2; - edgelen[3] = dxop2 + dyop2 + dzop2; - edgelen[4] = dxdp2 + dydp2 + dzdp2; - edgelen[5] = dxap2 + dyap2 + dzap2; - smedgelen = averlen = edgelen[0]; - for (i = 1; i < 6; i++) { - averlen += sqrt(edgelen[i]); - if (smedgelen > edgelen[i]) { - smedgelen = edgelen[i]; - } - } - averlen /= 6.0; - - // Find the circumcenter and circumradius of 'testtet'. - circumsphere(torg, tdest, tapex, toppo, cent, NULL); - dxoc = torg[0] - cent[0]; - dyoc = torg[1] - cent[1]; - dzoc = torg[2] - cent[2]; - dxoc2 = dxoc * dxoc; - dyoc2 = dyoc * dyoc; - dzoc2 = dzoc * dzoc; - radius = dxoc2 + dyoc2 + dzoc2; - - // Calculate the square of radius-edge ratio. - ratio2 = radius / smedgelen; - - // Check whether the ratio is smaller than permitted. - if (ratio2 > b->goodratio) { - // Add this tet to the list of bad tetrahedra. - enqueuebadtet(testtet, ratio2, torg, tdest, tapex, toppo, cent); - return true; - } - if (b->varvolume || b->fixedvolume) { - volume = orient3d(torg, tdest, tapex, toppo); - if (volume < 0) volume = -volume; - volume /= 6.0; - // Check whether the volume is larger than permitted. - if (b->fixedvolume && (volume > b->maxvolume)) { - // Add this tetrahedron to the list of bad tetrahedra. - enqueuebadtet(testtet, 0, torg, tdest, tapex, toppo, cent); - return true; - } else if (b->varvolume) { - // Nonpositive volume constraints are treated as unconstrained. - if ((volume > volumebound(testtet->tet)) && - (volumebound(testtet->tet) > 0.0)) { - // Add this tetrahedron to the list of bad tetrahedron. - enqueuebadtet(testtet, 0, torg, tdest, tapex, toppo, cent); - return true; - } - } - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checktet4illtet() Test a tetrahedron to see if it is illegal. // -// // -// A tetrahedron is assumed as illegal if its four corners are defined on // -// one facet. A tetrahedron has zero volume is illegal. Add it into queue // -// if it is illegal. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::checktet4illtet(triface* testtet, list* illtetlist) -{ - badtetrahedron *badtet; - triface neighface; - face testsh, neighsh, testseg; - bool isill; - int i; - - isill = false; - testtet->loc = 0; - testtet->ver = 0; - tspivot(*testtet, testsh); // edge ab - if (testsh.sh != dummysh) { - // Check subfaces at edges ab, bc, ca. - findedge(&testsh, org(*testtet), dest(*testtet)); - for (i = 0; i < 3; i++) { - sspivot(testsh, testseg); - if (testseg.sh == dummysh) { - fnext(*testtet, neighface); - tspivot(neighface, neighsh); - if (neighsh.sh != dummysh) { - isill = true; - break; - } - } - enextself(*testtet); - senextself(testsh); - } - } - if (!isill) { - testtet->loc = 0; - testtet->ver = 0; - fnextself(*testtet); - esymself(*testtet); - tspivot(*testtet, testsh); - if (testsh.sh != dummysh) { - // Check subfaces at edges ad, db. - findedge(&testsh, org(*testtet), dest(*testtet)); - for (i = 0; i < 2; i++) { - enextself(*testtet); - senextself(testsh); - sspivot(testsh, testseg); - if (testseg.sh == dummysh) { - fnext(*testtet, neighface); - tspivot(neighface, neighsh); - if (neighsh.sh != dummysh) { - isill = true; - break; - } - } - } - } - } - if (!isill) { - testtet->loc = 0; - testtet->ver = 0; - enextfnextself(*testtet); - esymself(*testtet); - enext2self(*testtet); // edge cd. - tspivot(*testtet, testsh); - if (testsh.sh != dummysh) { - findedge(&testsh, org(*testtet), dest(*testtet)); - sspivot(testsh, testseg); - if (testseg.sh == dummysh) { - fnext(*testtet, neighface); - tspivot(neighface, neighsh); - if (neighsh.sh != dummysh) { - isill = true; - } - } - } - } - if (isill) { - badtet = (badtetrahedron *) illtetlist->append(NULL); - badtet->tet = *testtet; - badtet->tetorg = org(*testtet); - badtet->tetdest = dest(*testtet); - badtet->tetapex = apex(*testtet); - badtet->tetoppo = oppo(*testtet); - if (b->verbose > 2) { - printf(" Queuing illtet (%d, %d, %d, %d).\n", - pointmark(badtet->tetorg), pointmark(badtet->tetdest), - pointmark(badtet->tetapex), pointmark(badtet->tetoppo)); - } - } - return isill; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checktet4sliver() Test a tetrahedron for large dihedral angle. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::checktet4sliver(triface* testtet, list* illtetlist) -{ - badtetrahedron *badtet; - point pa, pb, pc, pd; - REAL dihed[6]; - bool issliver; - - pa = (point) testtet->tet[4]; - pb = (point) testtet->tet[5]; - pc = (point) testtet->tet[6]; - pd = (point) testtet->tet[7]; - tetalldihedral(pa, pb, pc, pd, dihed); - - issliver = false; - testtet->loc = 0; - testtet->ver = 0; - if (dihed[0] > b->maxdihedral) { // Edge ab - issliver = true; - } - if (!issliver && (dihed[1] > b->maxdihedral)) { // Edge ac - enext2self(*testtet); - issliver = true; - } - if (!issliver && (dihed[2] > b->maxdihedral)) { // Edge ad - fnextself(*testtet); - enext2self(*testtet); - esymself(*testtet); - issliver = true; - } - if (!issliver && (dihed[3] > b->maxdihedral)) { // Edge bc - enextself(*testtet); - issliver = true; - } - if (!issliver && (dihed[4] > b->maxdihedral)) { // Edge bd - fnextself(*testtet); - enextself(*testtet); - esymself(*testtet); - issliver = true; - } - if (!issliver && (dihed[5] > b->maxdihedral)) { // Edge cd - enextfnextself(*testtet); - enextself(*testtet); - esymself(*testtet); - issliver = true; - } - - if (issliver) { - badtet = (badtetrahedron *) illtetlist->append(NULL); - badtet->tet = *testtet; - badtet->tetorg = org(*testtet); - badtet->tetdest = dest(*testtet); - badtet->tetapex = apex(*testtet); - badtet->tetoppo = oppo(*testtet); - if (b->verbose > 2) { - printf(" Queuing sliver (%d, %d, %d, %d).\n", - pointmark(badtet->tetorg), pointmark(badtet->tetdest), - pointmark(badtet->tetapex), pointmark(badtet->tetoppo)); - } - } - return issliver; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checkseg4splitting() Check an encroached subsegment to see if it is // -// suitable to be split. // -// // -// If a subsegment is one of edges of a subface which is on the sharp corner,// -// it is not suitable to be split. If the volume constraint is set, it is // -// still suitable to be split if there is a tetrahedron around it which has // -// volume larger than volumebound. To avoid resulting too skinny tetrahedron,// -// we compare the longest edge length to the cubic root of volumebound. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::checkseg4splitting(face* testseg, REAL* rpsarray, bool bqual) -{ - triface spintet; - face parentsh, spinsh; - point eorg, edest, fapex; - bool acuteorg, acutedest; - REAL rpslimit; - REAL L, L3; - int ptidx; - - eorg = sorg(*testseg); - edest = sdest(*testseg); - acuteorg = pointtype(eorg) == ACUTEVERTEX; - acutedest = pointtype(edest) == ACUTEVERTEX; - if ((acuteorg && acutedest) || (!acuteorg && !acutedest)) { - // Can be split. - return true; - } - // Now exactly one vertex is acute. - assert(acuteorg || acutedest); - if (!bqual) { - // We're not forced to split it. However, if it is encroached by an - // existing vertex, we must split it, otherwise, not split it. - return checkseg4encroach(testseg, NULL, false); - } - - L = distance(eorg, edest); - if (acuteorg) { - ptidx = pointmark(eorg) - in->firstnumber; - } else { - assert(acutedest); - ptidx = pointmark(edest) - in->firstnumber; - } - rpslimit = rpsarray[ptidx] / 4.0; - if (L > (rpslimit * 1.1)) { - // The edge is not too small, can be split. - return true; - } - // L <= rpslimit. We should not split it. However, it may still be - // split if its length is too long wrt. the volume constraints. - if (b->varvolume || b->fixedvolume) { - L3 = L * L * L / 6.0; - if (b->fixedvolume && (L3 > b->maxvolume)) { - // This edge is too long wrt. the maximum volume bound. Split it. - return true; - } - if (b->varvolume) { - spivot(*testseg, parentsh); - if (sorg(parentsh) != eorg) sesymself(parentsh); - stpivot(parentsh, spintet); - if (spintet.tet == dummytet) { - sesymself(parentsh); - stpivot(parentsh, spintet); - assert(spintet.tet != dummytet); - } - findedge(&spintet, eorg, edest); - fapex = apex(spintet); - while (true) { - if (!fnextself(spintet)) { - // Meet a boundary, walk through it. - tspivot(spintet, spinsh); - assert(spinsh.sh != dummysh); - findedge(&spinsh, eorg, edest); - sfnextself(spinsh); - stpivot(spinsh, spintet); - assert(spintet.tet != dummytet); - findedge(&spintet, eorg, edest); - } - if ((L3 > volumebound(spintet.tet)) && - (volumebound(spintet.tet) > 0.0)) { - // This edge is too long wrt. the maximum volume bound. Split it. - return true; - } - if (apex(spintet) == fapex) break; - } - } - } - - // Not split it. - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checksub4splitting() Check an encroached subface to see if it is // -// suitable to be split. // -// // -// If a subface is on the sharp corner, it is not suitable to be split. If // -// the volume constraint is set, it is still suitable to be split if there // -// is a tetrahedron around it which has volume larger than volumebound. To // -// avoid resulting too skinny tet, we compare the longest edge length to the // -// cubic root of volumebound. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::checksub4splitting(face* testsh) -{ - triface testtet; - point p[3]; - REAL L, L3; - int i; - - if (b->varvolume || b->fixedvolume) { - // Check if all the tetrahedra having this subface are conforming to - // the volume bound specified in b.maxvolume. Here we don't use each - // tetrahedron's volume for comparsion, instead is an approximate - // volume (one sixth of the cubic of its longest edge length). We - // hope this way can find skinny tetrahedra and split them. - p[0] = sorg(*testsh); - p[1] = sdest(*testsh); - p[2] = sapex(*testsh); - // Get the longest edge length of testsh = L. - L = distance(p[0], p[1]); - L3 = distance(p[1], p[2]); - L = (L >= L3 ? L : L3); - L3 = distance(p[2], p[0]); - L = (L >= L3 ? L : L3); - - L3 = L * L * L / 6.0; - if (b->fixedvolume && (L3 > b->maxvolume)) { - // This face is too large wrt. the maximum volume bound. Split it. - return true; - } - if (b->varvolume) { - for (i = 0; i < 2; i ++) { - stpivot(*testsh, testtet); - if (testtet.tet != dummytet) { - if ((L3 > volumebound(testtet.tet)) && - (volumebound(testtet.tet) > 0.0)) { - // This face is too large wrt. the maximum volume bound. - return true; - } - } - sesymself(*testsh); - } - } - } - return false; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// doqualchecktetlist() Put bad-quality tetrahedra in 'qualchecktetlist' // -// into queue and clear it. // -// // -// 'qualchecktetlist' stores a list of tetrahedra which are possibly bad- // -// quality, furthermore, one tetrahedron may appear many times in it. For // -// testing and queuing each bad-quality tetrahedron only once, infect it // -// after testing, later on, only test the one which is not infected. On // -// finish, uninfect them. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::doqualchecktetlist() -{ - triface testtet; - int i; - - for (i = 0; i < qualchecktetlist->len(); i++) { - testtet = * (triface *) (* qualchecktetlist)[i]; - if (!isdead(&testtet) && !infected(testtet)) { - checktet4badqual(&testtet); - infect(testtet); - } - } - for (i = 0; i < qualchecktetlist->len(); i++) { - testtet = * (triface *) (* qualchecktetlist)[i]; - if (!isdead(&testtet) && infected(testtet)) { - uninfect(testtet); - } - } - qualchecktetlist->clear(); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tallencsegs() Check for encroached segments, save them in list. // -// // -// If both 'testpt' and 'cavtetlist' are not NULLs, then check the segments // -// in 'cavtetlist' to see if they're encroached by 'testpt'. Otherwise, // -// check the entire list of segments to see if they're encroached by any of // -// mesh vertices. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::tallencsegs(point testpt, list *cavtetlist) -{ - triface starttet, neightet; - face checkseg; - long oldencnum; - int i, j; - - // Remember the current number of encroached segments. - oldencnum = badsubsegs->items; - - if (cavtetlist != (list *) NULL) { - assert(testpt != (point) NULL); - // Check segments in the list of tetrahedra. - for (i = 0; i < cavtetlist->len(); i++) { - starttet = * (triface *)(* cavtetlist)[i]; - infect(starttet); // Indicate it has been tested. - sym(starttet, neightet); - if (!infected(neightet)) { - // Test all three edges of this face. - for (j = 0; j < 3; j++) { - tsspivot(&starttet, &checkseg); - if (checkseg.sh != dummysh) { - if (!shell2badface(checkseg)) { - checkseg4encroach(&checkseg, testpt, true); - } - } - enextself(starttet); - } - } - adjustedgering(starttet, CCW); - fnext(starttet, neightet); - symself(neightet); - if ((neightet.tet == dummytet) || !infected(neightet)) { - fnext(starttet, neightet); - // Test the tow other edges of this face. - for (j = 0; j < 2; j++) { - enextself(neightet); - tsspivot(&neightet, &checkseg); - if (checkseg.sh != dummysh) { - if (!shell2badface(checkseg)) { - checkseg4encroach(&checkseg, testpt, true); - } - } - } - } - enextfnext(starttet, neightet); - symself(neightet); - if ((neightet.tet == dummytet) || !infected(neightet)) { - enextfnext(starttet, neightet); - // Only test the next edge of this face. - enextself(neightet); - tsspivot(&neightet, &checkseg); - if (checkseg.sh != dummysh) { - if (!shell2badface(checkseg)) { - checkseg4encroach(&checkseg, testpt, true); - } - } - } - } - // Uninfect all tetrahedra in the list. - for (i = 0; i < cavtetlist->len(); i++) { - starttet = * (triface *)(* cavtetlist)[i]; - assert(infected(starttet)); - uninfect(starttet); - } - } else { - // Check the entire list of segments. - subsegs->traversalinit(); - checkseg.sh = shellfacetraverse(subsegs); - while (checkseg.sh != (shellface *) NULL) { - checkseg4encroach(&checkseg, NULL, true); - checkseg.sh = shellfacetraverse(subsegs); - } - } - - return (badsubsegs->items > oldencnum); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tallencsubs() Find all encroached subfaces and save them in list. // -// // -// If 'cavtetlist' and 'testpt' are not NULL, only check subfaces which are // -// in cavtetlist. Otherwise check all subfaces in current mesh. If 'protonly'// -// is TRUE, only check subfaces which are in protecting cylinders & spheres. // -// Return TRUE if at least one encorached subface is found. // -// // -/////////////////////////////////////////////////////////////////////////////// - -bool tetgenmesh::tallencsubs(point testpt, list* cavtetlist) -{ - triface starttet, neightet; - face checksh; - long oldencnum; - int i, j; - - // Remember the current number of encroached segments. - oldencnum = badsubfaces->items; - - if (cavtetlist != (list *) NULL) { - assert(testpt != (point) NULL); - // Check subfaces in the list of tetrahedra. - for (i = 0; i < cavtetlist->len(); i++) { - starttet = * (triface *)(* cavtetlist)[i]; - infect(starttet); // Indicate it has been tested. - sym(starttet, neightet); - if (!infected(neightet)) { - // Test if this face is encroached. - tspivot(starttet, checksh); - if (checksh.sh != dummysh) { - // If it is not encroached, test it. - if (shell2badface(checksh) == NULL) { - checksub4encroach(&checksh, testpt, true); - } - } - } - adjustedgering(starttet, CCW); - // Check the other three sides of this tet. - for (j = 0; j < 3; j++) { - fnext(starttet, neightet); - symself(neightet); - if ((neightet.tet == dummytet) || !infected(neightet)) { - fnext(starttet, neightet); - // Test if this face is encroached. - tspivot(neightet, checksh); - if (checksh.sh != dummysh) { - // If it is not encroached, test it. - if (shell2badface(checksh) == NULL) { - checksub4encroach(&checksh, testpt, true); - } - } - } - enextself(starttet); - } - } - // Uninfect all tetrahedra in the list. - for (i = 0; i < cavtetlist->len(); i++) { - starttet = * (triface *)(* cavtetlist)[i]; - assert(infected(starttet)); - uninfect(starttet); - } - } else { - // Check the entire list of subfaces. - subfaces->traversalinit(); - checksh.sh = shellfacetraverse(subfaces); - while (checksh.sh != (shellface *) NULL) { - // If it is not encroached, test it. - checksub4encroach(&checksh, NULL, true); - checksh.sh = shellfacetraverse(subfaces); - } - } - - return (badsubfaces->items > oldencnum); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tallbadtetrahedrons() Test every tetrahedron in the mesh for quality // -// measures. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::tallbadtetrahedrons() -{ - triface tetloop; - - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - checktet4badqual(&tetloop); - tetloop.tet = tetrahedrontraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tallilltets() Test every tetrahedron in the mesh for illegal tet. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::tallilltets(list* illtetlist) -{ - triface tetloop; - REAL bakdihedral; - - bakdihedral = b->maxdihedral; - b->maxdihedral = 3.1415926535897932 * (1.0 - b->epsilon); - - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - if (!checktet4illtet(&tetloop, illtetlist)) { - checktet4sliver(&tetloop, illtetlist); - } - tetloop.tet = tetrahedrontraverse(); - } - - b->maxdihedral = bakdihedral; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tallslivers() Test every tetrahedron in the mesh for sliver checking. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::tallslivers(list* illtetlist) -{ - triface tetloop; - - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - checktet4sliver(&tetloop, illtetlist); - tetloop.tet = tetrahedrontraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// removeilltets() Repair mesh by removing illegal elements. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::removeilltets() -{ - badtetrahedron *badtet; - list *illtetlist; - queue *flipqueue; - int i; - - if (!b->quiet) { - printf("Removing illegal tetrahedra.\n"); - } - // Initialize the pool of bad tetrahedra. - illtetlist = new list(sizeof(badtetrahedron), NULL, 1024); - // Initialize 'flipqueue'. - flipqueue = new queue(sizeof(badface)); - // Initialize the pool of recently flipped faces. - flipstackers = new memorypool(sizeof(flipstacker), 1024, POINTER, 0); - - // Test all tetrahedra to see if they're slivers. - tallilltets(illtetlist); - do { - for (i = 0; i < illtetlist->len(); i++) { - badtet = (badtetrahedron *)(* illtetlist)[i]; - if (!isdead(&badtet->tet) && (org(badtet->tet) == badtet->tetorg) && - (dest(badtet->tet) == badtet->tetdest) && - (apex(badtet->tet) == badtet->tetapex) && - (oppo(badtet->tet) == badtet->tetoppo)) { - removebadtet(ILLEGAL, &badtet->tet, flipqueue); - } - } - illtetlist->clear(); - tallilltets(illtetlist); - } while (illtetlist->len() > 0); - - delete flipstackers; - delete flipqueue; - delete illtetlist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// removeslivers() Repair mesh by removing slivers. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::removeslivers() -{ - badtetrahedron *badtet; - list *illtetlist; - int i; - - if (!b->quiet) { - printf("Removing slivers.\n"); - } - - // Initialize the pool of bad tetrahedra. - illtetlist = new list(sizeof(badtetrahedron), NULL, 1024); - // Initialize the pool of recently flipped faces. - flipstackers = new memorypool(sizeof(flipstacker), 1024, POINTER, 0); - - // Test all tetrahedra to see if they're slivers. - tallslivers(illtetlist); - for (i = 0; i < illtetlist->len(); i++) { - badtet = (badtetrahedron *)(* illtetlist)[i]; - if (!isdead(&badtet->tet) && (org(badtet->tet) == badtet->tetorg) && - (dest(badtet->tet) == badtet->tetdest) && - (apex(badtet->tet) == badtet->tetapex) && - (oppo(badtet->tet) == badtet->tetoppo)) { - // It's a sliver, remove it. - removebadtet(SLIVER, &badtet->tet, NULL); - } - } - illtetlist->clear(); - - delete flipstackers; - delete illtetlist; -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// repairencsegs() Repair all the encroached subsegments until no // -// subsegment is encroached. // -// // -// At beginning, all encroached subsegments are stored in pool 'badsubsegs'. // -// Each encroached subsegment is repaired by splitting it, i.e., inserting a // -// point somewhere in it. Newly inserted points may encroach upon other // -// subsegments, these are also repaired. // -// // -// After splitting a segment, the Delaunay property of the mesh is recovered // -// by flip operations. 'flipqueue' returns a list of updated faces which may // -// be non-locally Delaunay. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::repairencsegs(REAL* rpsarray, bool bqual, queue* flipqueue) -{ - badface *encloop; - triface starttet; - face startsh, spinsh, checksh; - face splitseg, checkseg; - point eorg, edest; - point newpoint, ppt; - bool acuteorg, acutedest; - REAL rps, len, split; - int ptidx, i; - - if (b->verbose > 1) { - printf(" Splitting encroached subsegments.\n"); - } - - // Note that steinerleft == -1 if an unlimited number of Steiner points - // is allowed. Loop until 'badsubsegs' is empty. - while ((badsubsegs->items > 0) && (steinerleft != 0)) { - badsubsegs->traversalinit(); - encloop = badfacetraverse(badsubsegs); - while ((encloop != (badface *) NULL) && (steinerleft != 0)) { - splitseg = encloop->ss; - // Every splitseg has a pointer to encloop, now clear it. - assert(shell2badface(splitseg) == encloop); - setshell2badface(splitseg, NULL); - eorg = sorg(splitseg); - edest = sdest(splitseg); - assert((eorg == encloop->forg) && (edest == encloop->fdest)); - if (b->verbose > 1) { - printf(" Get encseg (%d, %d).\n", pointmark(eorg), pointmark(edest)); - } - - if (checkseg4splitting(&splitseg, rpsarray, bqual)) { - // Decide the position to split the segment. Use the cutting sphere - // if any of the endpoints is acute. - acuteorg = (pointtype(eorg) == ACUTEVERTEX); - acutedest = (pointtype(edest) == ACUTEVERTEX); - if (acuteorg || acutedest) { - if (!acuteorg) { - // eorg is not acute, but edest is. Exchange eorg, edest. - eorg = edest; - edest = sorg(splitseg); - } - // Now, eorg must be acute. - len = distance(eorg, edest); - // Get the radius of the current protecting sphere. - ptidx = pointmark(eorg) - in->firstnumber; - rps = rpsarray[ptidx]; - // Calculate the suitable radius to split the segment. It should - // be no larger than half of the segment length. - while (rps > 0.51 * len) { - rps *= 0.5; - } - assert((rps * 16.0) > rpsarray[ptidx]); - // Where to split the segment. - split = rps / len; - ppt = eorg; - } else { - split = 0.5; - ppt = (point) NULL; - } - - // Create the new point. - makepoint(&newpoint); - // Set its coordinates. - for (i = 0; i < 3; i++) { - newpoint[i] = eorg[i] + split * (edest[i] - eorg[i]); - } - // Interpolate its attributes. - for (i = 0; i < in->numberofpointattributes; i++) { - newpoint[i + 3] = eorg[i + 3] + split * (edest[i + 3] - eorg[i + 3]); - } - // Set the parent point into the newpoint. - setpoint2ppt(newpoint, ppt); - // Set the type of the newpoint. - setpointtype(newpoint, FREESEGVERTEX); - // Set splitseg into the newpoint. - setpoint2sh(newpoint, sencode(splitseg)); - - // Insert new point into the mesh. It should be always success. - splitseg.shver = 0; - sstpivot(&splitseg, &starttet); - splittetedge(newpoint, &starttet, flipqueue); - if (steinerleft > 0) steinerleft--; - - // Check the two new subsegments to see if they're encroached. - checkseg4encroach(&splitseg, NULL, true); - if (badsubfaces != (memorypool *) NULL) { - // Check the subfaces link of s to see if they're encroached. - spivot(splitseg, startsh); - spinsh = startsh; - do { - findedge(&spinsh, sorg(splitseg), sdest(splitseg)); - // The next two lines are only for checking. - sspivot(spinsh, checkseg); - assert(checkseg.sh == splitseg.sh); - checksh = spinsh; - if (!shell2badface(checksh)) { - checksub4encroach(&checksh, NULL, true); - } - // The above operation may change the edge. - findedge(&spinsh, sorg(splitseg), sdest(splitseg)); - spivotself(spinsh); - } while (spinsh.sh != startsh.sh); - } - senextself(splitseg); - spivotself(splitseg); - assert(splitseg.sh != (shellface *) NULL); - splitseg.shver = 0; - checkseg4encroach(&splitseg, NULL, true); - if (badsubfaces != (memorypool *) NULL) { - // Check the subfaces link of s to see if they're encroached. - spivot(splitseg, startsh); - spinsh = startsh; - do { - findedge(&spinsh, sorg(splitseg), sdest(splitseg)); - // The next two lines are only for checking. - sspivot(spinsh, checkseg); - assert(checkseg.sh == splitseg.sh); - checksh = spinsh; - if (!shell2badface(checksh)) { - checksub4encroach(&checksh, NULL, true); - } - // The above operation may change the edge. - findedge(&spinsh, sorg(splitseg), sdest(splitseg)); - spivotself(spinsh); - } while (spinsh.sh != startsh.sh); - } - - // Recover Delaunay property by flipping. All existing segments which - // are encroached by the new point will be discovered during flips - // and be queued in list. - flip(flipqueue, NULL); - // Queuing bad-quality tetrahedra if need. - if (badtetrahedrons != (memorypool *) NULL) { - doqualchecktetlist(); - } - } - - // Remove this entry from list. - badfacedealloc(badsubsegs, encloop); - // Get the next encroached segments. - encloop = badfacetraverse(badsubsegs); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// repairencsubs() Repair all the encroached subfaces until no subface is // -// encroached. // -// // -// At beginning, all encroached subfaces are stored in pool 'badsubfaces'. // -// Each encroached subface is repaired by splitting it, i.e., inserting a // -// point at its circumcenter. However, if this point encroaches upon one or // -// more subsegments then we don not add it and instead split the subsegments.// -// Newly inserted points may encroach upon other subfaces, these are also // -// repaired. // -// // -// After splitting a subface, the Delaunay property of the mesh is recovered // -// by flip operations. 'flipqueue' returns a list of updated faces and may // -// be non-locally Delaunay. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::repairencsubs(REAL* rpsarray, int* idx2facetlist, - list* cavtetlist, queue* flipqueue) -{ - badface *encloop; - triface starttet; - face splitsub, neisplitsub; - face checksh, checkseg; - point newpoint, checkpt; - point pa, pb; - enum locateresult loc; - REAL epspp, dist; - bool enq, reject; - bool splitit, bqual; - int facetidx, quenumber; - int epscount; - int i; - - if (b->verbose > 1) { - printf(" Splitting encroached subfaces.\n"); - } - - // Note that steinerleft == -1 if an unlimited number of Steiner points - // is allowed. Loop until the list 'badsubfaces' is empty. - while ((badsubfaces->items > 0) && (steinerleft != 0)) { - // Look for a nonempty queue. - encloop = (badface *) NULL; - for (quenumber = 1; quenumber >= 0; quenumber--) { - encloop = subquefront[quenumber]; - if (encloop != (badface *) NULL) { - // Remove the badface from the queue. - subquefront[quenumber] = encloop->nextface; - // Maintain a pointer to the NULL pointer at the end of the queue. - if (subquefront[quenumber] == (badface *) NULL) { - subquetail[quenumber] = &subquefront[quenumber]; - } - break; - } - } - assert(encloop != (badface *) NULL); - if (b->verbose > 2) { - printf(" Dequeuing ensub (%d, %d, %d) [%d].\n", - pointmark(encloop->forg), pointmark(encloop->fdest), - pointmark(encloop->fapex), quenumber); - } - - // Clear the pointer saved in encloop->ss. - splitsub = encloop->ss; - setshell2badface(splitsub, NULL); - // The subface may be not the same one when it was determined to be - // encroached. If its adjacent encroached subface was split, the - // consequent flips may change it into another subface. - enq = ((sorg(splitsub) == encloop->forg) && - (sdest(splitsub) == encloop->fdest) && - (sapex(splitsub) == encloop->fapex)); - if (enq) { - // This subface is encroached or has bad quality. - bqual = (quenumber == 1); - facetidx = shellmark(splitsub); - // Split it if it is bad quality or is not sharp. - splitit = bqual || (idx2facetlist[facetidx - 1] != 1); - if (!splitit) { - // Split it if it's neighboring tets have too big volume. - bqual = checksub4splitting(&splitsub); - splitit = (bqual == true); - } - if (splitit) { - // We can or force to split this subface. - makepoint(&newpoint); - // If it is a bad quality face, calculate its circumcenter. - if (quenumber == 1) { - circumsphere(encloop->forg, encloop->fdest, encloop->fapex, NULL, - encloop->cent, NULL); - } - // Set the coordinates of newpoint. - for (i = 0; i < 3; i++) newpoint[i] = encloop->cent[i]; - stpivot(splitsub, starttet); - if (starttet.tet == dummytet) { - sesymself(splitsub); - stpivot(splitsub, starttet); - } - assert(starttet.tet != dummytet); - // Locate the newpoint in facet (resulting in splitsub). - loc = locatesub(newpoint, &splitsub, oppo(starttet)); - stpivot(splitsub, starttet); - if (starttet.tet == dummytet) { - sesymself(splitsub); - stpivot(splitsub, starttet); - } - assert(starttet.tet != dummytet); - // Look if the newpoint encroaches upon some segments. - recenttet = starttet; // Used for the input of preciselocate(). - collectcavtets(newpoint, cavtetlist); - assert(cavtetlist->len() > 0); - reject = tallencsegs(newpoint, cavtetlist); - // Clear the list for the next use. - cavtetlist->clear(); - if (!reject) { - // Remove the encroached subface by inserting the newpoint. - if (loc != ONVERTEX) { - // Adjust the location of newpoint wrt. starttet. - epspp = b->epsilon; - epscount = 0; - while (epscount < 16) { - loc = adjustlocate(newpoint, &starttet, ONFACE, epspp); - if (loc == ONVERTEX) { - checkpt = org(starttet); - dist = distance(checkpt, newpoint); - if ((dist / longest) > b->epsilon) { - epspp *= 1e-2; - epscount++; - continue; - } - } - break; - } - } - pa = org(starttet); - pb = dest(starttet); - findedge(&splitsub, pa, pb); - // Let splitsub be face abc. ab is the current edge. - if (loc == ONFACE) { - // Split the face abc into three faces abv, bcv, cav. - splittetface(newpoint, &starttet, flipqueue); - // Adjust splitsub be abv. - findedge(&splitsub, pa, pb); - assert(sapex(splitsub) == newpoint); - // Check the three new subfaces to see if they're encroached. - // splitsub may be queued (it exists before split). - checksh = splitsub; - if (!shell2badface(checksh)) { - checksub4encroach(&checksh, NULL, true); // abv - } - senext(splitsub, checksh); - spivotself(checksh); - // It is a new created face and should not be infected. - assert(checksh.sh != dummysh && !shell2badface(checksh)); - checksub4encroach(&checksh, NULL, true); // bcv - senext2(splitsub, checksh); - spivotself(checksh); - // It is a new created face and should not be infected. - assert(checksh.sh != dummysh && !shell2badface(checksh)); - checksub4encroach(&checksh, NULL, true); // cav - } else if (loc == ONEDGE) { - // Let the adjacent subface be bad. ab is the spliting edge. - // Split two faces abc, bad into 4 faces avc, vbc, avd, vbd. - sspivot(splitsub, checkseg); - assert(checkseg.sh == dummysh); - // Remember the neighbor subface abd (going to be split also). - spivot(splitsub, neisplitsub); - findedge(&neisplitsub, pa, pb); - // Split two faces abc, abd into four faces avc, vbc, avd, vbd. - splittetedge(newpoint, &starttet, flipqueue); - // Adjust splitsub be avc, neisplitsub be avd. - findedge(&splitsub, pa, newpoint); - findedge(&neisplitsub, pa, newpoint); - // Check the four new subfaces to see if they're encroached. - // splitsub may be an infected one (it exists before split). - checksh = splitsub; - if (!shell2badface(checksh)) { - checksub4encroach(&checksh, NULL, true); // avc - } - // Get vbc. - senext(splitsub, checksh); - spivotself(checksh); - // vbc is newly created. - assert(checksh.sh != dummysh && !shell2badface(checksh)); - checksub4encroach(&checksh, NULL, true); // vbc - // neisplitsub may be an infected one (it exists before split). - checksh = neisplitsub; - if (!shell2badface(checksh)) { - checksub4encroach(&checksh, NULL, true); // avd - } - // Get vbd. - senext(neisplitsub, checksh); - spivotself(checksh); - // vbd is newly created. - assert(checksh.sh != dummysh && !shell2badface(checksh)); - checksub4encroach(&checksh, NULL, true); // vbd - } else { - printf("Internal error in splitencsub(): Point %d locates %s.\n", - pointmark(newpoint), loc == ONVERTEX ? "on vertex" : "outside"); - internalerror(); - } - if (steinerleft > 0) steinerleft--; - // Recover Delaunay property by flipping. All existing subfaces - // which are encroached by the new point will be discovered - // during flips and be queued in list. - flip(flipqueue, NULL); - // There should be no encroached segments. - // assert(badsubsegs->items == 0); - // Queuing bad-quality tetrahedra if need. - if (badtetrahedrons != (memorypool *) NULL) { - doqualchecktetlist(); - } - } else { - // newpoint encroaches upon some segments. Rejected. - /* - if (bqual) { - // Re-queue this face to process it later. - badface *splitsub = encloop->ss; - encsub = (badface *) badsubfaces->alloc(); - encsub->ss = splitsub; - encsub->forg = sorg(splitsub); - encsub->fdest = sdest(splitsub); - encsub->fapex = sapex(splitsub); - encsub->foppo = encloop->foppo; - for (i = 0; i < 3; i++) encsub->cent[i] = newpoint[i]; - encsub->nextface = (badface *) NULL; - setshell2badface(encsub->ss, encsub); - // Add the subface to the end of a queue. - *subquetail[quenumber] = encsub; - // Maintain a pointer to the NULL pointer at the end of the queue. - subquetail[quenumber] = &encsub->nextface; - if (b->verbose > 2) { - printf(" Requeuing subface (%d, %d, %d) [%d].\n", - pointmark(encsub->forg), pointmark(encsub->fdest), - pointmark(encsub->fapex), quenumber); - } - } - */ - // Delete the newpoint. - pointdealloc(newpoint); - // Repair all the encroached segments. - if (badsubsegs->items > 0) { - repairencsegs(rpsarray, bqual, flipqueue); - } - } - } - } else { - // enq = false! This subface has been changed, check it again. - checksub4encroach(&splitsub, NULL, true); - } - // Remove this entry from list. - badfacedealloc(badsubfaces, encloop); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// repairbadtets() Repair all bad-quality tetrahedra until no tetrahedron // -// is considered as bad-quality. // -// // -// At beginning, all bad-quality tetrahedra are stored in 'badtetrahedrons'. // -// Each bad tetrahedron is repaired by splitting it, i.e., inserting a point // -// at its circumcenter. However, if this point encroaches any subsegment or // -// subface, we do not add it and instead split the subsegment or subface. // -// Newly inserted points may create other bad-quality tetrahedra, these are // -// also repaired. // -// // -// After splitting a subface, the Delaunay property of the mesh is recovered // -// by flip operations. 'flipqueue' returns a list of updated faces and may // -// be non-locally Delaunay. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::repairbadtets(REAL* rpsarray, int* idx2facetlist, - list* cavtetlist, queue* flipqueue) -{ - badtetrahedron *badtet; - triface starttet; - point newpoint; - point torg, tdest, tapex, toppo; - enum insertsiteresult success; - bool reject; - int i; - - // Loop until pool 'badtetrahedrons' is empty. Note that steinerleft == -1 - // if an unlimited number of Steiner points is allowed. - while ((badtetrahedrons->items > 0) && (steinerleft != 0)) { - badtet = dequeuebadtet(); - assert (badtet != (badtetrahedron *) NULL); - // Make sure that this tetrahedron is still the same tetrahedron it was - // when it was tested and determined to be of bad quality. Subsequent - // transformations may have made it a different tetrahedron. - if (!isdead(&badtet->tet) && org(badtet->tet) == badtet->tetorg && - dest(badtet->tet) == badtet->tetdest && - apex(badtet->tet) == badtet->tetapex && - oppo(badtet->tet) == badtet->tetoppo) { - // Create a newpoint at the circumcenter of this tetrahedron. - makepoint(&newpoint); - for (i = 0; i < 3; i++) newpoint[i] = badtet->cent[i]; - for (i = 0; i < in->numberofpointattributes; i++) newpoint[3 + i] = 0.0; - // Set it's type be FREEVOLVERTEX. - setpointtype(newpoint, FREEVOLVERTEX); - - // Look if the newpoint encroaches upon some segments, subfaces. - recenttet = badtet->tet; // Used for the input of preciselocate(). - collectcavtets(newpoint, cavtetlist); - assert(cavtetlist->len() > 0); - reject = tallencsegs(newpoint, cavtetlist); - if (!reject) { - reject = tallencsubs(newpoint, cavtetlist); - } - // Clear the list for the next use. - cavtetlist->clear(); - - if (!reject) { - // Insert the point, it should be always success. - starttet = badtet->tet; - success = insertsite(newpoint, &starttet, true, flipqueue); - if (success != DUPLICATEPOINT) { - if (steinerleft > 0) steinerleft--; - // Recover Delaunay property by flipping. - flip(flipqueue, NULL); - // Queuing bad-quality tetrahedra if need. - doqualchecktetlist(); - } else { - // !!! It's a bug!!! - pointdealloc(newpoint); - } - } else { - // newpoint encroaches upon some segments or subfaces. Rejected. - pointdealloc(newpoint); - if (badsubsegs->items > 0) { - // Repair all the encroached segments. - repairencsegs(rpsarray, false, flipqueue); - } - if (badsubfaces->items > 0) { - // Repair all the encroached subfaces. - repairencsubs(rpsarray, idx2facetlist, cavtetlist, flipqueue); - } - } - } - // Remove the bad-quality tetrahedron from the pool. - badtetrahedrons->dealloc((void *) badtet); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// enforcequality() Remove all the encroached subsegments, subfaces and // -// bad tetrahedra from the tetrahedral mesh. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::enforcequality() -{ - queue *flipqueue; - list *cavtetlist; - REAL *rpsarray; - int *idx2facetlist; - int i; - - if (!b->quiet) { - printf("Adding Steiner points to enforce quality.\n"); - } - - // Initialize working queues, lists. - flipqueue = new queue(sizeof(badface)); - cavtetlist = new list(sizeof(triface), NULL, 256); - rpsarray = new REAL[points->items]; - - // Mark segment vertices (acute or not) for determining segment types. - markacutevertices(89.0); - // Mark facets have sharp corners (for termination). - marksharpfacets(idx2facetlist, 89.0); - // Calculate the protecting spheres for all acute points. - initializerpsarray(rpsarray); - - // Initialize the pool of encroached subsegments. - badsubsegs = new memorypool(sizeof(badface), SUBPERBLOCK, POINTER, 0); - // Test all segments to see if they're encroached. - tallencsegs(NULL, NULL); - if (b->verbose && badsubsegs->items > 0) { - printf(" Splitting encroached subsegments.\n"); - } - // Fix encroached subsegments without noting any encr. subfaces. - repairencsegs(rpsarray, true, flipqueue); - - // Initialize the pool of encroached subfaces. - badsubfaces = new memorypool(sizeof(badface), SUBPERBLOCK, POINTER, 0); - // Initialize the queues of badfaces. - for (i = 0; i < 2; i++) subquefront[i] = (badface *) NULL; - for (i = 0; i < 2; i++) subquetail[i] = &subquefront[i]; - // Test all subfaces to see if they're encroached. - tallencsubs(NULL, NULL); - if (b->verbose && badsubfaces->items > 0) { - printf(" Splitting encroached subfaces.\n"); - } - // Fix encroached subfaces without noting bad tetrahedra. - repairencsubs(rpsarray, idx2facetlist, cavtetlist, flipqueue); - // At this point, the mesh should be (conforming) Delaunay. - - // Next, fix bad quality tetrahedra. - if ((b->minratio > 0.0) || b->varvolume || b->fixedvolume) { - // Initialize the pool of bad tetrahedra. - badtetrahedrons = new memorypool(sizeof(badtetrahedron), ELEPERBLOCK, - POINTER, 0); - // Initialize the list of bad tetrahedra. - qualchecktetlist = new list(sizeof(triface), NULL); - // Initialize the queues of bad tetrahedra. - for (i = 0; i < 64; i++) tetquefront[i] = (badtetrahedron *) NULL; - for (i = 0; i < 64; i++) tetquetail[i] = &tetquefront[i]; - // Test all tetrahedra to see if they're bad. - tallbadtetrahedrons(); - if (b->verbose && badtetrahedrons->items > 0) { - printf(" Splitting bad tetrahedra.\n"); - } - repairbadtets(rpsarray, idx2facetlist, cavtetlist, flipqueue); - // At this point, it should no bad quality tetrahedra. - delete qualchecktetlist; - delete badtetrahedrons; - } - - delete badsubfaces; - delete badsubsegs; - delete cavtetlist; - delete flipqueue; - delete [] idx2facetlist; - delete [] rpsarray; -} - -// -// End of Delaunay refinement routines -// - -// -// Begin of I/O rouitnes -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// transfernodes() Transfer nodes from 'io->pointlist' to 'this->points'. // -// // -// Initializing 'this->points'. Transferring all points from 'in->pointlist'// -// into it. All points are indexed (start from in->firstnumber). Each point // -// is initialized be UNUSEDVERTEX. The bounding box (xmin, xmax, ymin, ymax,// -// zmin, zmax) and the diameter (longest) of the point set are calculated. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::transfernodes() -{ - point pointloop; - REAL x, y, z; - int coordindex; - int attribindex; - int i, j; - - // Read the points. - coordindex = 0; - attribindex = 0; - for (i = 0; i < in->numberofpoints; i++) { - makepoint(&pointloop); - // Read the point coordinates. - x = pointloop[0] = in->pointlist[coordindex++]; - y = pointloop[1] = in->pointlist[coordindex++]; - z = pointloop[2] = in->pointlist[coordindex++]; - // Read the point attributes. - for (j = 0; j < in->numberofpointattributes; j++) { - pointloop[3 + j] = in->pointattributelist[attribindex++]; - } - // Determine the smallest and largests x, y and z coordinates. - if (i == 0) { - xmin = xmax = x; - ymin = ymax = y; - zmin = zmax = z; - } else { - xmin = (x < xmin) ? x : xmin; - xmax = (x > xmax) ? x : xmax; - ymin = (y < ymin) ? y : ymin; - ymax = (y > ymax) ? y : ymax; - zmin = (z < zmin) ? z : zmin; - zmax = (z > zmax) ? z : zmax; - } - } - // 'longest' is the largest possible edge length formed by input vertices. - // It is used as the measure to distinguish two identical points. - x = xmax - xmin; - y = ymax - ymin; - z = zmax - zmin; - longest = sqrt(x * x + y * y + z * z); - if (longest == 0.0) { - printf("Error: The point set is trivial.\n"); - exit(1); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// jettisonnodes() Jettison unused or duplicated vertices. // -// // -// Unused points are those input points which are outside the mesh domain or // -// have no connection (isolated) to the mesh. Duplicated points exist for // -// example if the input PLC is read from a .stl mesh file (marked during the // -// Delaunay tetrahedralization step. This routine remove these points from // -// points list. All existing points are reindexed. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::jettisonnodes() -{ - point pointloop; - bool jetflag; - int idx; - - if (!b->quiet) { - printf("Jettisoning redundants points.\n"); - } - - points->traversalinit(); - pointloop = pointtraverse(); - idx = in->firstnumber; - while (pointloop != (point) NULL) { - jetflag = (pointtype(pointloop) == DUPLICATEDVERTEX) || - (pointtype(pointloop) == UNUSEDVERTEX); - if (jetflag) { - // It is a duplicated point, delete it. - pointdealloc(pointloop); - } else { - // Index it. - setpointmark(pointloop, idx); - idx++; - } - pointloop = pointtraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// highorder() Create extra nodes for quadratic subparametric elements. // -// // -// 'highordertable' is an array (size = numberoftetrahedra * 6) for storing // -// high-order nodes of each tetrahedron. This routine is used only when -o2 // -// switch is used. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::highorder() -{ - triface tetloop, worktet; - triface spintet, adjtet; - point torg, tdest, tapex; - point *extralist, *adjextralist; - point newpoint; - int hitbdry, ptmark; - int i, j; - - // The 'edgeindex' (from 0 to 5) is list as follows: - // 0 - (v0, v1), 1 - (v1, v2), 2 - (v2, v0) - // 3 - (v3, v0), 4 - (v3, v1), 5 - (v3, v2) - // Define an edgeindex map: (loc, ver)->edgeindex. - int edgeindexmap[4][6] = {0, 0, 1, 1, 2, 2, - 3, 3, 4, 4, 0, 0, - 4, 4, 5, 5, 1, 1, - 5, 5, 3, 3, 2, 2}; - - if (!b->quiet) { - printf("Adding vertices for second-order tetrahedra.\n"); - } - - // Initialize the 'highordertable'. - highordertable = new point[tetrahedrons->items * 6]; - if (highordertable == (point *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - - // The following line ensures that dead items in the pool of nodes cannot - // be allocated for the extra nodes associated with high order elements. - // This ensures that the primary nodes (at the corners of elements) will - // occur earlier in the output files, and have lower indices, than the - // extra nodes. - points->deaditemstack = (void *) NULL; - - // Assign an entry for each tetrahedron to find its extra nodes. At the - // mean while, initialize all extra nodes be NULL. - i = 0; - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - tetloop.tet[highorderindex] = (tetrahedron) &highordertable[i]; - for (j = 0; j < 6; j++) { - highordertable[i + j] = (point) NULL; - } - i += 6; - tetloop.tet = tetrahedrontraverse(); - } - - // To create a unique node on each edge. Loop over all tetrahedra, and - // look at the six edges of each tetrahedron. If the extra node in - // the tetrahedron corresponding to this edge is NULL, create a node - // for this edge, at the same time, set the new node into the extra - // node lists of all other tetrahedra sharing this edge. - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - // Get the list of extra nodes. - extralist = (point *) tetloop.tet[highorderindex]; - for (i = 0; i < 6; i++) { - if (extralist[i] == (point) NULL) { - // Operate on this edge. - worktet = tetloop; - worktet.loc = 0; worktet.ver = 0; - // Get the correct edge in 'worktet'. - switch(i) { - case 0: // (v0, v1) - break; - case 1: // (v1, v2) - enextself(worktet); - break; - case 2: // (v2, v0) - enext2self(worktet); - break; - case 3: // (v3, v0) - fnextself(worktet); - enext2self(worktet); - break; - case 4: // (v3, v1) - enextself(worktet); - fnextself(worktet); - enext2self(worktet); - break; - case 5: // (v3, v2) - enext2self(worktet); - fnextself(worktet); - enext2self(worktet); - } - // Create a new node on this edge. - torg = org(worktet); - tdest = dest(worktet); - // Create a new node in the middle of the edge. - newpoint = (point) points->alloc(); - // Interpolate its attributes. - for (j = 0; j < 3 + in->numberofpointattributes; j++) { - newpoint[j] = 0.5 * (torg[j] + tdest[j]); - } - ptmark = (int) points->items - (in->firstnumber == 1 ? 0 : 1); - setpointmark(newpoint, ptmark); - // Add this node to its extra node list. - extralist[i] = newpoint; - // Set 'newpoint' into extra node lists of other tetrahedra - // sharing this edge. - tapex = apex(worktet); - spintet = worktet; - hitbdry = 0; - while (hitbdry < 2) { - if (fnextself(spintet)) { - // Get the extra node list of 'spintet'. - adjextralist = (point *) spintet.tet[highorderindex]; - // Find the index of its extra node list. - j = edgeindexmap[spintet.loc][spintet.ver]; - // Only set 'newpoint' into 'adjextralist' if it is a NULL. - // Because two faces can belong to the same tetrahedron. - if (adjextralist[j] == (point) NULL) { - adjextralist[j] = newpoint; - } - if (apex(spintet) == tapex) { - break; - } - } else { - hitbdry++; - if (hitbdry < 2) { - esym(worktet, spintet); - } - } - } - } - } - tetloop.tet = tetrahedrontraverse(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outnodes() Output the points to a .node file or a tetgenio structure. // -// // -// Note: each point has already been numbered on input (the first index is // -// 'in->firstnumber'). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outnodes(tetgenio* out) -{ - FILE *outfile; - char outnodefilename[FILENAMESIZE]; - point pointloop; - int nextras, bmark, marker; - int coordindex, attribindex; - int pointnumber, index, i; - - if (out == (tetgenio *) NULL) { - strcpy(outnodefilename, b->outfilename); - strcat(outnodefilename, ".node"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", outnodefilename); - } else { - printf("Writing nodes.\n"); - } - } - - nextras = in->numberofpointattributes; - bmark = !b->nobound && in->pointmarkerlist; - - if (out == (tetgenio *) NULL) { - outfile = fopen(outnodefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", outnodefilename); - exit(1); - } - // Number of points, number of dimensions, number of point attributes, - // and number of boundary markers (zero or one). - fprintf(outfile, "%ld %d %d %d\n", points->items, 3, nextras, bmark); - } else { - // Allocate space for 'pointlist'; - out->pointlist = new REAL[points->items * 3]; - if (out->pointlist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - // Allocate space for 'pointattributelist' if necessary; - if (nextras > 0) { - out->pointattributelist = new REAL[points->items * nextras]; - if (out->pointattributelist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - // Allocate space for 'pointmarkerlist' if necessary; - if (bmark) { - out->pointmarkerlist = new int[points->items]; - if (out->pointmarkerlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - out->numberofpoints = points->items; - out->numberofpointattributes = nextras; - coordindex = 0; - attribindex = 0; - } - - points->traversalinit(); - pointloop = pointtraverse(); - pointnumber = in->firstnumber; - index = 0; - while (pointloop != (point) NULL) { - if (bmark) { - // Determine the boundary marker. - if (index < in->numberofpoints) { - // Input point's marker is directly copied to output. - marker = in->pointmarkerlist[index]; - if (marker == 0) { - // Change the marker if it is a boundary point. - marker = ((pointtype(pointloop) != UNUSEDVERTEX) && - (pointtype(pointloop) != FREEVOLVERTEX) && - (pointtype(pointloop) != DUPLICATEDVERTEX)) - ? 1 : 0; - } - } else if ((pointtype(pointloop) != UNUSEDVERTEX) && - (pointtype(pointloop) != FREEVOLVERTEX) && - (pointtype(pointloop) != DUPLICATEDVERTEX)) { - // A boundary vertex has marker 1. - marker = 1; - } else { - // Free or internal point has a zero marker. - marker = 0; - } - } - if (out == (tetgenio *) NULL) { - // Point number, x, y and z coordinates. - fprintf(outfile, "%4d %.17g %.17g %.17g", pointnumber, - pointloop[0], pointloop[1], pointloop[2]); - for (i = 0; i < nextras; i++) { - // Write an attribute. - fprintf(outfile, " %.17g", pointloop[3 + i]); - } - if (bmark) { - // Write the boundary marker. - fprintf(outfile, " %d", marker); - } - fprintf(outfile, "\n"); - } else { - // X, y, and z coordinates. - out->pointlist[coordindex++] = pointloop[0]; - out->pointlist[coordindex++] = pointloop[1]; - out->pointlist[coordindex++] = pointloop[2]; - // Point attributes. - for (i = 0; i < nextras; i++) { - // Output an attribute. - out->pointattributelist[attribindex++] = pointloop[3 + i]; - } - if (bmark) { - // Output the boundary marker. - out->pointmarkerlist[index] = marker; - } - } - pointloop = pointtraverse(); - pointnumber++; - index++; - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outelements() Output the tetrahedra to an .ele file or a tetgenio // -// structure. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outelements(tetgenio* out) -{ - FILE *outfile; - char outelefilename[FILENAMESIZE]; - tetrahedron* tptr; - int *tlist; - REAL *talist; - int pointindex; - int attribindex; - point p1, p2, p3, p4; - point *extralist; - int elementnumber; - int eextras; - int i; - - if (out == (tetgenio *) NULL) { - strcpy(outelefilename, b->outfilename); - strcat(outelefilename, ".ele"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", outelefilename); - } else { - printf("Writing elements.\n"); - } - } - - eextras = in->numberoftetrahedronattributes; - if (out == (tetgenio *) NULL) { - outfile = fopen(outelefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", outelefilename); - exit(1); - } - // Number of tetras, points per tetra, attributes per tetra. - fprintf(outfile, "%ld %d %d\n", tetrahedrons->items, - b->order == 1 ? 4 : 10, eextras); - } else { - // Allocate memory for output tetrahedra. - out->tetrahedronlist = new int[tetrahedrons->items * - (b->order == 1 ? 4 : 10)]; - if (out->tetrahedronlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - // Allocate memory for output tetrahedron attributes if necessary. - if (eextras > 0) { - out->tetrahedronattributelist = new REAL[tetrahedrons->items * eextras]; - if (out->tetrahedronattributelist == (REAL *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - out->numberoftetrahedra = tetrahedrons->items; - out->numberofcorners = b->order == 1 ? 4 : 10; - out->numberoftetrahedronattributes = eextras; - tlist = out->tetrahedronlist; - talist = out->tetrahedronattributelist; - pointindex = 0; - attribindex = 0; - } - - tetrahedrons->traversalinit(); - tptr = tetrahedrontraverse(); - elementnumber = in->firstnumber; - while (tptr != (tetrahedron *) NULL) { - p1 = (point) tptr[4]; - p2 = (point) tptr[5]; - p3 = (point) tptr[6]; - p4 = (point) tptr[7]; - if (out == (tetgenio *) NULL) { - // Tetrahedron number, indices for four points. - fprintf(outfile, "%5d %5d %5d %5d %5d", elementnumber, - pointmark(p1), pointmark(p2), pointmark(p3), pointmark(p4)); - if (b->order == 2) { - extralist = (point *) tptr[highorderindex]; - // Tetrahedron number, indices for four points plus six extra points. - fprintf(outfile, " %5d %5d %5d %5d %5d %5d", - pointmark(extralist[0]), pointmark(extralist[1]), - pointmark(extralist[2]), pointmark(extralist[3]), - pointmark(extralist[4]), pointmark(extralist[5])); - } - for (i = 0; i < eextras; i++) { - fprintf(outfile, " %.17g", elemattribute(tptr, i)); - } - fprintf(outfile, "\n"); - } else { - tlist[pointindex++] = pointmark(p1); - tlist[pointindex++] = pointmark(p2); - tlist[pointindex++] = pointmark(p3); - tlist[pointindex++] = pointmark(p4); - if (b->order == 2) { - extralist = (point *) tptr[highorderindex]; - tlist[pointindex++] = pointmark(extralist[0]); - tlist[pointindex++] = pointmark(extralist[1]); - tlist[pointindex++] = pointmark(extralist[2]); - tlist[pointindex++] = pointmark(extralist[3]); - tlist[pointindex++] = pointmark(extralist[4]); - tlist[pointindex++] = pointmark(extralist[5]); - } - for (i = 0; i < eextras; i++) { - talist[attribindex++] = elemattribute(tptr, i); - } - } - tptr = tetrahedrontraverse(); - elementnumber++; - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outfaces() Output all faces to a .face file or a tetgenio structure. // -// // -// This routines outputs all triangular faces (including outer boundary // -// faces and inner faces) of this mesh. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outfaces(tetgenio* out) -{ - FILE *outfile; - char facefilename[FILENAMESIZE]; - int *elist; - int *emlist; - int index; - triface tface, tsymface; - face checkmark; - point torg, tdest, tapex; - long faces; - int bmark, faceid, marker; - int facenumber; - - if (out == (tetgenio *) NULL) { - strcpy(facefilename, b->outfilename); - strcat(facefilename, ".face"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", facefilename); - } else { - printf("Writing faces.\n"); - } - } - - faces = (4l * tetrahedrons->items + hullsize) / 2l; - bmark = !b->nobound && in->facetmarkerlist; - - if (out == (tetgenio *) NULL) { - outfile = fopen(facefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", facefilename); - exit(1); - } - fprintf(outfile, "%ld %d\n", faces, bmark); - } else { - // Allocate memory for 'trifacelist'. - out->trifacelist = new int[faces * 3]; - if (out->trifacelist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - // Allocate memory for 'trifacemarkerlist' if necessary. - if (bmark) { - out->trifacemarkerlist = new int[faces]; - if (out->trifacemarkerlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - out->numberoftrifaces = faces; - elist = out->trifacelist; - emlist = out->trifacemarkerlist; - index = 0; - } - - tetrahedrons->traversalinit(); - tface.tet = tetrahedrontraverse(); - facenumber = in->firstnumber; - // To loop over the set of faces, loop over all tetrahedra, and look at - // the four faces of each one. If there isn't another tetrahedron - // adjacent to this face, operate on the face. If there is another - // adjacent tetrahedron, operate on the face only if the current - // tetrahedron has a smaller pointer than its neighbor. This way, each - // face is considered only once. - while (tface.tet != (tetrahedron *) NULL) { - for (tface.loc = 0; tface.loc < 4; tface.loc ++) { - sym(tface, tsymface); - if ((tsymface.tet == dummytet) || (tface.tet < tsymface.tet)) { - torg = org(tface); - tdest = dest(tface); - tapex = apex(tface); - if (bmark) { - // Get the boundary marker of this face. If it is an inner face, - // it has no boundary marker, set it be zero. - if (b->useshelles) { - // Shell face is used. - tspivot(tface, checkmark); - if (checkmark.sh == dummysh) { - marker = 0; // It is an inner face. - } else { - faceid = shellmark(checkmark) - 1; - marker = in->facetmarkerlist[faceid]; - } - } else { - // Shell face is not used, only distinguish outer and inner face. - marker = tsymface.tet != dummytet ? 1 : 0; - } - } - if (out == (tetgenio *) NULL) { - // Face number, indices of three vertices. - fprintf(outfile, "%5d %4d %4d %4d", facenumber, - pointmark(torg), pointmark(tdest), pointmark(tapex)); - if (bmark) { - // Output a boundary marker. - fprintf(outfile, " %d", marker); - } - fprintf(outfile, "\n"); - } else { - // Output indices of three vertices. - elist[index++] = pointmark(torg); - elist[index++] = pointmark(tdest); - elist[index++] = pointmark(tapex); - if (bmark) { - emlist[facenumber - in->firstnumber] = marker; - } - } - facenumber++; - } - } - tface.tet = tetrahedrontraverse(); - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outhullfaces() Output outer boundary faces to a .face file or a // -// tetgenio structure. // -// // -// The normal of each face is arranged to point inside of the domain (use // -// right-hand rule). This routines will outputs convex hull faces if the // -// mesh is a Delaunay tetrahedralization. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outhullfaces(tetgenio* out) -{ - FILE *outfile; - char facefilename[FILENAMESIZE]; - int *elist; - int index; - triface tface, tsymface; - face checkmark; - point torg, tdest, tapex; - int facenumber; - - if (out == (tetgenio *) NULL) { - strcpy(facefilename, b->outfilename); - strcat(facefilename, ".face"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", facefilename); - } else { - printf("Writing faces.\n"); - } - } - - if (out == (tetgenio *) NULL) { - outfile = fopen(facefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", facefilename); - exit(1); - } - fprintf(outfile, "%ld 0\n", hullsize); - } else { - // Allocate memory for 'trifacelist'. - out->trifacelist = new int[hullsize * 3]; - if (out->trifacelist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - out->numberoftrifaces = hullsize; - elist = out->trifacelist; - index = 0; - } - - tetrahedrons->traversalinit(); - tface.tet = tetrahedrontraverse(); - facenumber = in->firstnumber; - // To loop over the set of hull faces, loop over all tetrahedra, and look - // at the four faces of each one. If there isn't another tetrahedron - // adjacent to this face, operate on the face. - while (tface.tet != (tetrahedron *) NULL) { - for (tface.loc = 0; tface.loc < 4; tface.loc ++) { - sym(tface, tsymface); - if (tsymface.tet == dummytet) { - torg = org(tface); - tdest = dest(tface); - tapex = apex(tface); - if (out == (tetgenio *) NULL) { - // Face number, indices of three vertices. - fprintf(outfile, "%5d %4d %4d %4d", facenumber, - pointmark(torg), pointmark(tdest), pointmark(tapex)); - fprintf(outfile, "\n"); - } else { - // Output indices of three vertices. - elist[index++] = pointmark(torg); - elist[index++] = pointmark(tdest); - elist[index++] = pointmark(tapex); - } - facenumber++; - } - } - tface.tet = tetrahedrontraverse(); - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outsubfaces() Output subfaces (i.e. boundary faces) to a .face file or // -// a tetgenio structure. // -// // -// The boundary faces are exist in 'subfaces'. For listing triangle vertices // -// in the same sense for all triangles in the mesh, the direction determined // -// by right-hand rule is pointer to the inside of the volume. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outsubfaces(tetgenio* out) -{ - FILE *outfile; - char facefilename[FILENAMESIZE]; - int *elist; - int *emlist; - int index; - triface abuttingtet; - face faceloop; - point torg, tdest, tapex; - int bmark, faceid, marker; - int facenumber; - - if (out == (tetgenio *) NULL) { - strcpy(facefilename, b->outfilename); - strcat(facefilename, ".face"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", facefilename); - } else { - printf("Writing faces.\n"); - } - } - - bmark = !b->nobound && in->facetmarkerlist; - - if (out == (tetgenio *) NULL) { - outfile = fopen(facefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", facefilename); - exit(1); - } - // Number of subfaces. - fprintf(outfile, "%ld %d\n", subfaces->items, bmark); - } else { - // Allocate memory for 'trifacelist'. - out->trifacelist = new int[subfaces->items * 3]; - if (out->trifacelist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - // Allocate memory for 'trifacemarkerlist', if necessary. - if (bmark) { - out->trifacemarkerlist = new int[subfaces->items]; - if (out->trifacemarkerlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - } - out->numberoftrifaces = subfaces->items; - elist = out->trifacelist; - emlist = out->trifacemarkerlist; - index = 0; - } - - subfaces->traversalinit(); - faceloop.sh = shellfacetraverse(subfaces); - facenumber = in->firstnumber; - while (faceloop.sh != (shellface *) NULL) { - stpivot(faceloop, abuttingtet); - if (abuttingtet.tet == dummytet) { - sesymself(faceloop); - stpivot(faceloop, abuttingtet); - // assert(abuttingtet.tet != dummytet) { - } - if (abuttingtet.tet != dummytet) { - // If there is a tetrahedron containing this subface, orient it so - // that the normal of this face points to inside of the volume by - // right-hand rule. - adjustedgering(abuttingtet, CCW); - torg = org(abuttingtet); - tdest = dest(abuttingtet); - tapex = apex(abuttingtet); - } else { - // This may happen when only a surface mesh be generated. - torg = sorg(faceloop); - tdest = sdest(faceloop); - tapex = sapex(faceloop); - } - if (bmark) { - faceid = shellmark(faceloop) - 1; - marker = in->facetmarkerlist[faceid]; - } - if (out == (tetgenio *) NULL) { - fprintf(outfile, "%5d %4d %4d %4d", facenumber, - pointmark(torg), pointmark(tdest), pointmark(tapex)); - if (bmark) { - fprintf(outfile, " %d", marker); - } - fprintf(outfile, "\n"); - } else { - // Output three vertices of this face; - elist[index++] = pointmark(torg); - elist[index++] = pointmark(tdest); - elist[index++] = pointmark(tapex); - if (bmark) { - emlist[facenumber - in->firstnumber] = marker; - } - } - facenumber++; - faceloop.sh = shellfacetraverse(subfaces); - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outsubsegments() Output segments (i.e. boundary edges) to a .edge file // -// or a tetgenio structure. // -// // -// The boundary edges are stored in 'subsegs'. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outsubsegments(tetgenio* out) -{ - FILE *outfile; - char edgefilename[FILENAMESIZE]; - int *elist; - int index; - face edgeloop; - point torg, tdest; - int edgenumber; - - if (out == (tetgenio *) NULL) { - strcpy(edgefilename, b->outfilename); - strcat(edgefilename, ".edge"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", edgefilename); - } else { - printf("Writing faces.\n"); - } - } - - if (out == (tetgenio *) NULL) { - outfile = fopen(edgefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", edgefilename); - exit(1); - } - // Number of subsegments. - fprintf(outfile, "%ld\n", subsegs->items); - } else { - // Allocate memory for 'edgelist'. - out->edgelist = new int[subsegs->items * 2]; - if (out->edgelist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - out->numberofedges = subsegs->items; - elist = out->edgelist; - index = 0; - } - - subsegs->traversalinit(); - edgeloop.sh = shellfacetraverse(subsegs); - edgenumber = in->firstnumber; - while (edgeloop.sh != (shellface *) NULL) { - torg = sorg(edgeloop); - tdest = sdest(edgeloop); - if (out == (tetgenio *) NULL) { - fprintf(outfile, "%5d %4d %4d\n", edgenumber, pointmark(torg), - pointmark(tdest)); - } else { - // Output three vertices of this face; - elist[index++] = pointmark(torg); - elist[index++] = pointmark(tdest); - } - edgenumber++; - edgeloop.sh = shellfacetraverse(subsegs); - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outneighbors() Output a list of neighbors to a .neigh file or a // -// tetgenio structure. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outneighbors(tetgenio* out) -{ - FILE *outfile; - char neighborfilename[FILENAMESIZE]; - int *nlist; - int index; - tetrahedron *tptr; - triface tetloop, tetsym; - int neighbor1, neighbor2, neighbor3, neighbor4; - int elementnumber; - - if (out == (tetgenio *) NULL) { - strcpy(neighborfilename, b->outfilename); - strcat(neighborfilename, ".neigh"); - } - - if (!b->quiet) { - if (out == (tetgenio *) NULL) { - printf("Writing %s.\n", neighborfilename); - } else { - printf("Writing neighbors.\n"); - } - } - - if (out == (tetgenio *) NULL) { - outfile = fopen(neighborfilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", neighborfilename); - exit(1); - } - // Number of tetrahedra, four faces per tetrahedron. - fprintf(outfile, "%ld %d\n", tetrahedrons->items, 4); - } else { - // Allocate memory for 'neighborlist'. - out->neighborlist = new int[tetrahedrons->items * 4]; - if (out->neighborlist == (int *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - nlist = out->neighborlist; - index = 0; - } - - tetrahedrons->traversalinit(); - tptr = tetrahedrontraverse(); - elementnumber = in->firstnumber; - while (tptr != (tetrahedron *) NULL) { - * (int *) (tptr + 8) = elementnumber; - tptr = tetrahedrontraverse(); - elementnumber++; - } - * (int *) (dummytet + 8) = -1; - - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - elementnumber = in->firstnumber; - while (tetloop.tet != (tetrahedron *) NULL) { - tetloop.loc = 2; - sym(tetloop, tetsym); - neighbor1 = * (int *) (tetsym.tet + 8); - tetloop.loc = 3; - sym(tetloop, tetsym); - neighbor2 = * (int *) (tetsym.tet + 8); - tetloop.loc = 1; - sym(tetloop, tetsym); - neighbor3 = * (int *) (tetsym.tet + 8); - tetloop.loc = 0; - sym(tetloop, tetsym); - neighbor4 = * (int *) (tetsym.tet + 8); - if (out == (tetgenio *) NULL) { - // Tetrahedra number, neighboring tetrahedron numbers. - fprintf(outfile, "%4d %4d %4d %4d %4d\n", elementnumber, - neighbor1, neighbor2, neighbor3, neighbor4); - } else { - nlist[index++] = neighbor1; - nlist[index++] = neighbor2; - nlist[index++] = neighbor3; - nlist[index++] = neighbor4; - } - tetloop.tet = tetrahedrontraverse(); - elementnumber++; - } - - if (out == (tetgenio *) NULL) { - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outsmesh() Write surface mesh to a .smesh file, which can be read and // -// tetrahedralized by TetGen. // -// // -// You can specify a filename (without suffix) in 'smfilename'. If you don't // -// supply a filename (let smfilename be NULL), the default name stored in // -// 'tetgenbehavior' will be used. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outsmesh(char* smfilename) -{ - FILE *outfile; - char smefilename[FILENAMESIZE]; - face faceloop; - point pointloop; - point p1, p2, p3; - int pointnumber; - int nextras, bmark; - int faceid, marker; - - if (smfilename != (char *) NULL && smfilename[0] != '\0') { - strcpy(smefilename, smfilename); - } else if (b->outfilename[0] != '\0') { - strcpy(smefilename, b->outfilename); - } else { - strcpy(smefilename, "unnamed"); - } - strcat(smefilename, ".smesh"); - - if (!b->quiet) { - printf("Writing %s.\n", smefilename); - } - outfile = fopen(smefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", smefilename); - return; - } - - fprintf(outfile, "# %s. TetGen's input file.\n", smefilename); - - nextras = in->numberofpointattributes; - bmark = !b->nobound && in->pointmarkerlist; - - fprintf(outfile, "\n# part 1: node list.\n"); - // Number of points, number of dimensions, number of point attributes, - // and number of boundary markers (zero or one). - fprintf(outfile, "%ld %d %d %d\n", points->items, 3, nextras, bmark); - - points->traversalinit(); - pointloop = pointtraverse(); - pointnumber = in->firstnumber; - while (pointloop != (point) NULL) { - // Point coordinates. - fprintf(outfile, "%4d %.17g %.17g %.17g", pointnumber, - pointloop[0], pointloop[1], pointloop[2]); - if (in->numberofpointattributes > 0) { - // Write an attribute, ignore others if more than one. - fprintf(outfile, " %.17g", pointloop[3]); - } - fprintf(outfile, "\n"); - setpointmark(pointloop, pointnumber); - pointloop = pointtraverse(); - pointnumber++; - } - - bmark = !b->nobound && in->facetmarkerlist; - - fprintf(outfile, "\n# part 2: facet list.\n"); - // Number of facets, boundary marker. - fprintf(outfile, "%ld %d\n", subfaces->items, bmark); - - subfaces->traversalinit(); - faceloop.sh = shellfacetraverse(subfaces); - while (faceloop.sh != (shellface *) NULL) { - p1 = sorg(faceloop); - p2 = sdest(faceloop); - p3 = sapex(faceloop); - if (bmark) { - faceid = shellmark(faceloop) - 1; - marker = in->facetmarkerlist[faceid]; - } - fprintf(outfile, "3 %4d %4d %4d", pointmark(p1), pointmark(p2), - pointmark(p3)); - if (bmark) { - fprintf(outfile, " %d", marker); - } - fprintf(outfile, "\n"); - faceloop.sh = shellfacetraverse(subfaces); - } - - fprintf(outfile, "\n# part 3: hole list.\n"); - fprintf(outfile, "0\n"); - - fprintf(outfile, "\n# part 4: region list.\n"); - fprintf(outfile, "0\n"); - - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outmesh2medit() Write mesh to a .mesh file, which can be read and // -// rendered by Medit (a free mesh viewer from INRIA). // -// // -// You can specify a filename (without suffix) in 'mfilename'. If you don't // -// supply a filename (let mfilename be NULL), the default name stored in // -// 'tetgenbehavior' will be used. The output file will have the suffix .mesh.// -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outmesh2medit(char* mfilename) -{ - FILE *outfile; - char mefilename[FILENAMESIZE]; - tetrahedron* tetptr; - triface tface, tsymface; - face segloop, checkmark; - point pointloop, p1, p2, p3, p4; - long faces; - int pointnumber; - int i; - - if (mfilename != (char *) NULL && mfilename[0] != '\0') { - strcpy(mefilename, mfilename); - } else if (b->outfilename[0] != '\0') { - strcpy(mefilename, b->outfilename); - } else { - strcpy(mefilename, "unnamed"); - } - strcat(mefilename, ".mesh"); - - if (!b->quiet) { - printf("Writing %s.\n", mefilename); - } - outfile = fopen(mefilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", mefilename); - return; - } - - fprintf(outfile, "MeshVersionFormatted 1\n"); - fprintf(outfile, "\n"); - fprintf(outfile, "Dimension\n"); - fprintf(outfile, "3\n"); - fprintf(outfile, "\n"); - - fprintf(outfile, "\n# Set of mesh vertices\n"); - fprintf(outfile, "Vertices\n"); - fprintf(outfile, "%ld\n", points->items); - - points->traversalinit(); - pointloop = pointtraverse(); - pointnumber = 1; // Medit need start number form 1. - while (pointloop != (point) NULL) { - // Point coordinates. - fprintf(outfile, "%.17g %.17g %.17g", - pointloop[0], pointloop[1], pointloop[2]); - if (in->numberofpointattributes > 0) { - // Write an attribute, ignore others if more than one. - fprintf(outfile, " %.17g\n", pointloop[3]); - } else { - fprintf(outfile, " 0\n"); - } - setpointmark(pointloop, pointnumber); - pointloop = pointtraverse(); - pointnumber++; - } - - // Compute the number of edges. - faces = (4l * tetrahedrons->items + hullsize) / 2l; - - fprintf(outfile, "\n# Set of Triangles\n"); - fprintf(outfile, "Triangles\n"); - fprintf(outfile, "%ld\n", faces); - - tetrahedrons->traversalinit(); - tface.tet = tetrahedrontraverse(); - // To loop over the set of faces, loop over all tetrahedra, and look at - // the four faces of each tetrahedron. If there isn't another tetrahedron - // adjacent to the face, operate on the face. If there is another adj- - // acent tetrahedron, operate on the face only if the current tetrahedron - // has a smaller pointer than its neighbor. This way, each face is - // considered only once. - while (tface.tet != (tetrahedron *) NULL) { - for (tface.loc = 0; tface.loc < 4; tface.loc ++) { - sym(tface, tsymface); - if (tface.tet < tsymface.tet || tsymface.tet == dummytet) { - p1 = org (tface); - p2 = dest(tface); - p3 = apex(tface); - fprintf(outfile, "%5d %5d %5d", - pointmark(p1), pointmark(p2), pointmark(p3)); - fprintf(outfile, " 0\n"); - } - } - tface.tet = tetrahedrontraverse(); - } - - fprintf(outfile, "\n# Set of Tetrahedra\n"); - fprintf(outfile, "Tetrahedra\n"); - fprintf(outfile, "%ld\n", tetrahedrons->items); - - tetrahedrons->traversalinit(); - tetptr = tetrahedrontraverse(); - while (tetptr != (tetrahedron *) NULL) { - p1 = (point) tetptr[4]; - p2 = (point) tetptr[5]; - p3 = (point) tetptr[6]; - p4 = (point) tetptr[7]; - fprintf(outfile, "%5d %5d %5d %5d", - pointmark(p1), pointmark(p2), pointmark(p3), pointmark(p4)); - if (in->numberoftetrahedronattributes > 0) { - fprintf(outfile, " %.17g", elemattribute(tetptr, 0)); - } else { - fprintf(outfile, " 0"); - } - fprintf(outfile, "\n"); - tetptr = tetrahedrontraverse(); - } - - fprintf(outfile, "\nCorners\n"); - fprintf(outfile, "%d\n", in->numberofpoints); - - for (i = 0; i < in->numberofpoints; i++) { - fprintf(outfile, "%4d\n", i + 1); - } - - if (b->useshelles) { - fprintf(outfile, "\nEdges\n"); - fprintf(outfile, "%ld\n", subsegs->items); - - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - p1 = sorg(segloop); - p2 = sdest(segloop); - fprintf(outfile, "%5d %5d", pointmark(p1), pointmark(p2)); - fprintf(outfile, " 0\n"); - segloop.sh = shellfacetraverse(subsegs); - } - } - - fprintf(outfile, "\nEnd\n"); - fclose(outfile); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outmesh2gid() Write mesh to a .ele.msh file and a .face.msh file, // -// which can be imported and rendered by Gid. // -// // -// You can specify a filename (without suffix) in 'gfilename'. If you don't // -// supply a filename (let gfilename be NULL), the default name stored in // -// 'tetgenbehavior' will be used. The suffixes (.ele.msh and .face.msh) will // -// be automatically added. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outmesh2gid(char* gfilename) -{ - FILE *outfile; - char gidfilename[FILENAMESIZE]; - tetrahedron* tetptr; - triface tface, tsymface; - face sface; - point pointloop, p1, p2, p3, p4; - int pointnumber; - int elementnumber; - - if (gfilename != (char *) NULL && gfilename[0] != '\0') { - strcpy(gidfilename, gfilename); - } else if (b->outfilename[0] != '\0') { - strcpy(gidfilename, b->outfilename); - } else { - strcpy(gidfilename, "unnamed"); - } - strcat(gidfilename, ".ele.msh"); - - if (!b->quiet) { - printf("Writing %s.\n", gidfilename); - } - outfile = fopen(gidfilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", gidfilename); - return; - } - - fprintf(outfile, "mesh dimension = 3 elemtype tetrahedron nnode = 4\n"); - fprintf(outfile, "coordinates\n"); - - points->traversalinit(); - pointloop = pointtraverse(); - pointnumber = 1; // Gid need start number form 1. - while (pointloop != (point) NULL) { - // Point coordinates. - fprintf(outfile, "%4d %.17g %.17g %.17g", pointnumber, - pointloop[0], pointloop[1], pointloop[2]); - if (in->numberofpointattributes > 0) { - // Write an attribute, ignore others if more than one. - fprintf(outfile, " %.17g", pointloop[3]); - } - fprintf(outfile, "\n"); - setpointmark(pointloop, pointnumber); - pointloop = pointtraverse(); - pointnumber++; - } - - fprintf(outfile, "end coordinates\n"); - fprintf(outfile, "elements\n"); - - tetrahedrons->traversalinit(); - tetptr = tetrahedrontraverse(); - elementnumber = 1; - while (tetptr != (tetrahedron *) NULL) { - p1 = (point) tetptr[4]; - p2 = (point) tetptr[5]; - p3 = (point) tetptr[6]; - p4 = (point) tetptr[7]; - fprintf(outfile, "%5d %5d %5d %5d %5d", elementnumber, - pointmark(p1), pointmark(p2), pointmark(p3), pointmark(p4)); - if (in->numberoftetrahedronattributes > 0) { - fprintf(outfile, " %.17g", elemattribute(tetptr, 0)); - } - fprintf(outfile, "\n"); - tetptr = tetrahedrontraverse(); - elementnumber++; - } - - fprintf(outfile, "end elements\n"); - fclose(outfile); - - if (gfilename != (char *) NULL && gfilename[0] != '\0') { - strcpy(gidfilename, gfilename); - } else if (b->outfilename[0] != '\0') { - strcpy(gidfilename, b->outfilename); - } else { - strcpy(gidfilename, "unnamed"); - } - strcat(gidfilename, ".face.msh"); - - if (!b->quiet) { - printf("Writing %s.\n", gidfilename); - } - outfile = fopen(gidfilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", gidfilename); - return; - } - - fprintf(outfile, "mesh dimension = 3 elemtype triangle nnode = 3\n"); - fprintf(outfile, "coordinates\n"); - - points->traversalinit(); - pointloop = pointtraverse(); - pointnumber = 1; // Gid need start number form 1. - while (pointloop != (point) NULL) { - // Point coordinates. - fprintf(outfile, "%4d %.17g %.17g %.17g", pointnumber, - pointloop[0], pointloop[1], pointloop[2]); - if (in->numberofpointattributes > 0) { - // Write an attribute, ignore others if more than one. - fprintf(outfile, " %.17g", pointloop[3]); - } - fprintf(outfile, "\n"); - setpointmark(pointloop, pointnumber); - pointloop = pointtraverse(); - pointnumber++; - } - - fprintf(outfile, "end coordinates\n"); - fprintf(outfile, "elements\n"); - - tetrahedrons->traversalinit(); - tface.tet = tetrahedrontraverse(); - elementnumber = 1; - while (tface.tet != (tetrahedron *) NULL) { - for (tface.loc = 0; tface.loc < 4; tface.loc ++) { - sym(tface, tsymface); - if ((tface.tet < tsymface.tet) || (tsymface.tet == dummytet)) { - p1 = org(tface); - p2 = dest(tface); - p3 = apex(tface); - if (tsymface.tet == dummytet) { - // It's a hull face, output it. - fprintf(outfile, "%5d %d %d %d\n", elementnumber, - pointmark(p1), pointmark(p2), pointmark(p3)); - elementnumber++; - } else if (b->useshelles) { - // Only output it if it's a subface. - tspivot(tface, sface); - if (sface.sh != dummysh) { - fprintf(outfile, "%5d %d %d %d\n", elementnumber, - pointmark(p1), pointmark(p2), pointmark(p3)); - elementnumber++; - } - } - } - } - tface.tet = tetrahedrontraverse(); - } - - fprintf(outfile, "end elements\n"); - fclose(outfile); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// outmesh2off() Write the mesh to an .off file. // -// // -// .off, the Object File Format, is one of the popular file formats from the // -// Geometry Center's Geomview package (http://www.geomview.org). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::outmesh2off(char* ofilename) -{ - FILE *outfile; - char offfilename[FILENAMESIZE]; - triface tface, tsymface; - point pointloop, p1, p2, p3; - long faces; - int shift; - - if (ofilename != (char *) NULL && ofilename[0] != '\0') { - strcpy(offfilename, ofilename); - } else if (b->outfilename[0] != '\0') { - strcpy(offfilename, b->outfilename); - } else { - strcpy(offfilename, "unnamed"); - } - strcat(offfilename, ".off"); - - if (!b->quiet) { - printf("Writing %s.\n", offfilename); - } - outfile = fopen(offfilename, "w"); - if (outfile == (FILE *) NULL) { - printf("File I/O Error: Cannot create file %s.\n", offfilename); - return; - } - - // Calculate the number of triangular faces in the tetrahedral mesh. - faces = (4l * tetrahedrons->items + hullsize) / 2l; - - // Number of points, faces, and edges(not used, here show hullsize). - fprintf(outfile, "OFF\n%ld %ld %ld\n", points->items, faces, hullsize); - - // Write the points. - points->traversalinit(); - pointloop = pointtraverse(); - while (pointloop != (point) NULL) { - fprintf(outfile, " %.17g %.17g %.17g\n", pointloop[0], pointloop[1], - pointloop[2]); - pointloop = pointtraverse(); - } - - // OFF always use zero as the first index. - shift = in->firstnumber == 1 ? 1 : 0; - - tetrahedrons->traversalinit(); - tface.tet = tetrahedrontraverse(); - // To loop over the set of faces, loop over all tetrahedra, and look at - // the four faces of each tetrahedron. If there isn't another tetrahedron - // adjacent to the face, operate on the face. If there is another adj- - // acent tetrahedron, operate on the face only if the current tetrahedron - // has a smaller pointer than its neighbor. This way, each face is - // considered only once. - while (tface.tet != (tetrahedron *) NULL) { - for (tface.loc = 0; tface.loc < 4; tface.loc ++) { - sym(tface, tsymface); - if ((tface.tet < tsymface.tet) || (tsymface.tet == dummytet)) { - p1 = org(tface); - p2 = dest(tface); - p3 = apex(tface); - // Face number, indices of three vertexs. - fprintf(outfile, "3 %4d %4d %4d\n", pointmark(p1) - shift, - pointmark(p2) - shift, pointmark(p3) - shift); - } - } - tface.tet = tetrahedrontraverse(); - } - - fprintf(outfile, "# Generated by %s\n", b->commandline); - fclose(outfile); -} - -// -// End of I/O rouitnes -// - -// -// Begin of user interaction routines -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// internalerror() Ask the user to send me the defective product. Exit. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::internalerror() -{ - printf(" Please report this bug to sihang@mail.berlios.de. Include the\n"); - printf(" message above, your input data set, and the exact command\n"); - printf(" line you used to run this program, thank you.\n"); - exit(1); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checkmesh() Test the mesh for topological consistency. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::checkmesh() -{ - triface tetraloop; - triface oppotet, oppooppotet; - point tetorg, tetdest, tetapex, tetoppo; - point oppodest, oppoapex; - REAL oritest; - int horrors; - - if (!b->quiet) { - printf(" Checking consistency of mesh...\n"); - } - horrors = 0; - // Run through the list of tetrahedra, checking each one. - tetrahedrons->traversalinit(); - tetraloop.tet = tetrahedrontraverse(); - while (tetraloop.tet != (tetrahedron *) NULL) { - // Check all four faces of the tetrahedron. - for (tetraloop.loc = 0; tetraloop.loc < 4; tetraloop.loc++) { - tetorg = org(tetraloop); - tetdest = dest(tetraloop); - tetapex = apex(tetraloop); - tetoppo = oppo(tetraloop); - if (tetraloop.loc == 0) { // Only test for inversion once. - oritest = orient3d(tetorg, tetdest, tetapex, tetoppo); - if (oritest >= 0.0) { - printf(" !! !! %s ", oritest > 0.0 ? "Inverted" : "Degenerated"); - printtet(&tetraloop); - printf(" orient3d = %.17g.\n", oritest); - horrors++; - } - } - // Find the neighboring tetrahedron on this face. - sym(tetraloop, oppotet); - if (oppotet.tet != dummytet) { - // Check that the tetrahedron's neighbor knows it's a neighbor. - sym(oppotet, oppooppotet); - if ((tetraloop.tet != oppooppotet.tet) - || (tetraloop.loc != oppooppotet.loc)) { - printf(" !! !! Asymmetric tetra-tetra bond:\n"); - if (tetraloop.tet == oppooppotet.tet) { - printf(" (Right tetrahedron, wrong orientation)\n"); - } - printf(" First "); - printtet(&tetraloop); - printf(" Second (nonreciprocating) "); - printtet(&oppotet); - horrors++; - } - // Check that both tetrahedra agree on the identities - // of their shared vertices. - if (findorg(&oppotet, tetorg)) { - oppodest = dest(oppotet); - oppoapex = apex(oppotet); - } else { - oppodest = (point) NULL; - } - if ((tetdest != oppoapex) || (tetapex != oppodest)) { - printf(" !! !! Mismatched face coordinates between two tetras:\n"); - printf(" First mismatched "); - printtet(&tetraloop); - printf(" Second mismatched "); - printtet(&oppotet); - horrors++; - } - } - } - tetraloop.tet = tetrahedrontraverse(); - } - if (horrors == 0) { - if (!b->quiet) { - printf(" In my studied opinion, the mesh appears to be consistent.\n"); - } - } else if (horrors == 1) { - printf(" !! !! !! !! Precisely one festering wound discovered.\n"); - } else { - printf(" !! !! !! !! %d abominations witnessed.\n", horrors); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checkshells() Test the boundary mesh for topological consistency. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::checkshells() -{ - triface oppotet, oppooppotet, testtet; - face shloop, segloop, spin; - face testsh, testseg, testshsh; - point shorg, shdest, segorg, segdest; - REAL checksign; - bool same; - int horrors; - int i; - - if (!b->quiet) { - printf(" Checking consistency of the mesh boundary...\n"); - } - horrors = 0; - - // Run through the list of subfaces, checking each one. - subfaces->traversalinit(); - shloop.sh = shellfacetraverse(subfaces); - while (shloop.sh != (shellface *) NULL) { - // Check two connected tetrahedra if they exist. - shloop.shver = 0; - stpivot(shloop, oppotet); - if (oppotet.tet != dummytet) { - tspivot(oppotet, testsh); - if (testsh.sh != shloop.sh) { - printf(" !! !! Wrong tetra-subface connection.\n"); - printf(" Tetra: "); - printtet(&oppotet); - printf(" Subface: "); - printsh(&shloop); - horrors++; - } - if (oppo(oppotet) != (point) NULL) { - adjustedgering(oppotet, CCW); - checksign = orient3d(sorg(shloop), sdest(shloop), sapex(shloop), - oppo(oppotet)); - if (checksign >= 0.0) { - printf(" !! !! Wrong subface orientation.\n"); - printf(" Subface: "); - printsh(&shloop); - horrors++; - } - } - } - sesymself(shloop); - stpivot(shloop, oppooppotet); - if (oppooppotet.tet != dummytet) { - tspivot(oppooppotet, testsh); - if (testsh.sh != shloop.sh) { - printf(" !! !! Wrong tetra-subface connection.\n"); - printf(" Tetra: "); - printtet(&oppooppotet); - printf(" Subface: "); - printsh(&shloop); - horrors++; - } - if (oppotet.tet != dummytet) { - sym(oppotet, testtet); - if (testtet.tet != oppooppotet.tet) { - printf(" !! !! Wrong tetra-subface-tetra connection.\n"); - printf(" Tetra 1: "); - printtet(&oppotet); - printf(" Subface: "); - printsh(&shloop); - printf(" Tetra 2: "); - printtet(&oppooppotet); - horrors++; - } - } - if (oppo(oppooppotet) != (point) NULL) { - adjustedgering(oppooppotet, CCW); - checksign = orient3d(sorg(shloop), sdest(shloop), sapex(shloop), - oppo(oppooppotet)); - if (checksign >= 0.0) { - printf(" !! !! Wrong subface orientation.\n"); - printf(" Subface: "); - printsh(&shloop); - horrors++; - } - } - } - // Check connection between subfaces. - shloop.shver = 0; - for (i = 0; i < 3; i++) { - shorg = sorg(shloop); - shdest = sdest(shloop); - sspivot(shloop, testseg); - if (testseg.sh != dummysh) { - segorg = sorg(testseg); - segdest = sdest(testseg); - same = ((shorg == segorg) && (shdest == segdest)) - || ((shorg == segdest) && (shdest == segorg)); - if (!same) { - printf(" !! !! Wrong subface-subsegment connection.\n"); - printf(" Subface: "); - printsh(&shloop); - printf(" Subsegment: "); - printsh(&testseg); - horrors++; - } - } - spivot(shloop, testsh); - if (testsh.sh != dummysh) { - segorg = sorg(testsh); - segdest = sdest(testsh); - same = ((shorg == segorg) && (shdest == segdest)) - || ((shorg == segdest) && (shdest == segorg)); - if (!same) { - printf(" !! !! Wrong subface-subface connection.\n"); - printf(" Subface 1: "); - printsh(&shloop); - printf(" Subface 2: "); - printsh(&testsh); - horrors++; - } - spivot(testsh, testshsh); - shorg = sorg(testshsh); - shdest = sdest(testshsh); - same = ((shorg == segorg) && (shdest == segdest)) - || ((shorg == segdest) && (shdest == segorg)); - if (!same) { - printf(" !! !! Wrong subface-subface connection.\n"); - printf(" Subface 1: "); - printsh(&testsh); - printf(" Subface 2: "); - printsh(&testshsh); - horrors++; - } - if (testseg.sh == dummysh) { - if (testshsh.sh != shloop.sh) { - printf(" !! !! Wrong subface-subface connection.\n"); - printf(" Subface 1: "); - printsh(&shloop); - printf(" Subface 2: "); - printsh(&testsh); - horrors++; - } - } - } - senextself(shloop); - } - shloop.sh = shellfacetraverse(subfaces); - } - - // Run through the list of subsegs, checking each one. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - segorg = sorg(segloop); - segdest = sdest(segloop); - spivot(segloop, testsh); - if (testsh.sh == dummysh) { - printf(" !! !! Wrong subsegment-subface connection.\n"); - printf(" Subsegment: "); - printsh(&segloop); - horrors++; - segloop.sh = shellfacetraverse(subsegs); - continue; - } - shorg = sorg(testsh); - shdest = sdest(testsh); - same = ((shorg == segorg) && (shdest == segdest)) - || ((shorg == segdest) && (shdest == segorg)); - if (!same) { - printf(" !! !! Wrong subsegment-subface connection.\n"); - printf(" Subsegment : "); - printsh(&segloop); - printf(" Subface : "); - printsh(&testsh); - horrors++; - segloop.sh = shellfacetraverse(subsegs); - continue; - } - // Check the connection of face loop around this subsegment. - spin = testsh; - i = 0; - do { - spivotself(spin); - shorg = sorg(spin); - shdest = sdest(spin); - same = ((shorg == segorg) && (shdest == segdest)) - || ((shorg == segdest) && (shdest == segorg)); - if (!same) { - printf(" !! !! Wrong subsegment-subface connection.\n"); - printf(" Subsegment : "); - printsh(&segloop); - printf(" Subface : "); - printsh(&testsh); - horrors++; - break; - } - i++; - } while (spin.sh != testsh.sh && i < 1000); - if (i >= 1000) { - printf(" !! !! Wrong subsegment-subface connection.\n"); - printf(" Subsegment : "); - printsh(&segloop); - horrors++; - } - segloop.sh = shellfacetraverse(subsegs); - } - if (horrors == 0) { - if (!b->quiet) { - printf(" Mesh boundaries connected correctly.\n"); - } - } else { - printf(" !! !! !! !! %d boundary connection viewed with horror.\n", - horrors); - return; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checkdelaunay() Ensure that the mesh is constrained Delaunay. // -// // -// If 'flipqueue' is not NULL, non-locally Delaunay faces are saved in it. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::checkdelaunay(queue* flipqueue) -{ - triface tetraloop; - triface oppotet; - face opposhelle; - point tetorg, tetdest, tetapex, tetoppo; - point oppooppo; - REAL sign; - int shouldbedelaunay; - int horrors; - - if (!b->quiet) { - printf(" Checking Delaunay property of the mesh...\n"); - } - horrors = 0; - // Run through the list of triangles, checking each one. - tetrahedrons->traversalinit(); - tetraloop.tet = tetrahedrontraverse(); - while (tetraloop.tet != (tetrahedron *) NULL) { - // Check all four faces of the tetrahedron. - for (tetraloop.loc = 0; tetraloop.loc < 4; tetraloop.loc++) { - tetorg = org(tetraloop); - tetdest = dest(tetraloop); - tetapex = apex(tetraloop); - tetoppo = oppo(tetraloop); - sym(tetraloop, oppotet); - oppooppo = oppo(oppotet); - // Only test that the face is locally Delaunay if there is an - // adjoining tetrahedron whose pointer is larger (to ensure that - // each pair isn't tested twice). - shouldbedelaunay = (oppotet.tet != dummytet) - && (tetoppo != (point) NULL) - && (oppooppo != (point) NULL) - && (tetraloop.tet < oppotet.tet); - if (checksubfaces && shouldbedelaunay) { - // If a shell edge separates the triangles, then the edge is - // constrained, so no local Delaunay test should be done. - tspivot(tetraloop, opposhelle); - if (opposhelle.sh != dummysh){ - shouldbedelaunay = 0; - } - } - if (shouldbedelaunay) { - sign = insphere(tetdest, tetorg, tetapex, tetoppo, oppooppo); - if (checksubfaces && sign > 0.0) { - if (iscospheric(tetdest, tetorg, tetapex, tetoppo, oppooppo, - b->epsilon)) sign = 0.0; - } - if (sign > 0.0) { - if (flipqueue) { - enqueueflipface(tetraloop, flipqueue); - } else { - printf(" !! Non-locally Delaunay face (%d, %d, %d).\n", - pointmark(tetorg), pointmark(tetdest), pointmark(tetapex)); - } - horrors++; - } - } - } - tetraloop.tet = tetrahedrontraverse(); - } - if (flipqueue == (queue *) NULL) { - if (horrors == 0) { - if (!b->quiet) { - printf(" The mesh is %s.\n", - checksubfaces ? "constrained Delaunay" : "Delaunay"); - } - } else { - printf(" !! !! !! !! %d obscenities viewed with horror.\n", horrors); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// checkconforming() Ensure that the mesh is conforming Delaunay. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::checkconforming() -{ - face segloop, shloop; - int encsubsegs, encsubfaces; - - if (!b->quiet) { - printf(" Checking conforming Delaunay property of mesh...\n"); - } - encsubsegs = encsubfaces = 0; - // Run through the list of subsegments, check each one. - subsegs->traversalinit(); - segloop.sh = shellfacetraverse(subsegs); - while (segloop.sh != (shellface *) NULL) { - if (checkseg4encroach(&segloop, NULL, false)) { - printf(" !! !! Non-conforming subsegment: "); - printsh(&segloop); - encsubsegs++; - } - segloop.sh = shellfacetraverse(subsegs); - } - // Run through the list of subfaces, check each one. - subfaces->traversalinit(); - shloop.sh = shellfacetraverse(subfaces); - while (shloop.sh != (shellface *) NULL) { - if (checksub4encroach(&shloop, NULL, false)) { - printf(" !! !! Non-conforming subface: "); - printsh(&shloop); - encsubfaces++; - } - shloop.sh = shellfacetraverse(subfaces); - } - if (encsubsegs == 0 && encsubfaces == 0) { - if (!b->quiet) { - printf(" The mesh is conforming Delaunay.\n"); - } - } else { - if (encsubsegs > 0) { - printf(" !! !! %d subsegments are non-conforming.\n", encsubsegs); - } - if (encsubfaces > 0) { - printf(" !! !! %d subfaces are non-conforming.\n", encsubfaces); - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// qualitystatistics() Print statistics about the quality of the mesh. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::qualitystatistics() -{ - triface tetloop; - point p[4]; - char sbuf[128]; - REAL radiusratiotable[12]; - REAL aspectratiotable[16]; - REAL dx[6], dy[6], dz[6]; - REAL edgelength[6]; - REAL alldihed[6]; - REAL cent[3]; - REAL shortest, longest; - REAL smallestvolume, biggestvolume; - REAL smallestdiangle, biggestdiangle; - REAL tetvol; - REAL tetlongest2; - REAL minaltitude; - REAL cirradius, insradius; - REAL shortlen, longlen; - REAL tetaspect, tetradius; - REAL smalldiangle, bigdiangle; - int radiustable[12]; - int aspecttable[16]; - int dihedangletable[18]; - int radiusindex; - int aspectindex; - int tendegree; - int i, j, k; - - printf("Mesh quality statistics:\n\n"); - - radiusratiotable[0] = 0.707; radiusratiotable[1] = 1.0; - radiusratiotable[2] = 1.1; radiusratiotable[3] = 1.2; - radiusratiotable[4] = 1.4; radiusratiotable[5] = 1.6; - radiusratiotable[6] = 1.8; radiusratiotable[7] = 2.0; - radiusratiotable[8] = 2.5; radiusratiotable[9] = 3.0; - radiusratiotable[10] = 10.0; radiusratiotable[11] = 0.0; - - aspectratiotable[0] = 1.5; aspectratiotable[1] = 2.0; - aspectratiotable[2] = 2.5; aspectratiotable[3] = 3.0; - aspectratiotable[4] = 4.0; aspectratiotable[5] = 6.0; - aspectratiotable[6] = 10.0; aspectratiotable[7] = 15.0; - aspectratiotable[8] = 25.0; aspectratiotable[9] = 50.0; - aspectratiotable[10] = 100.0; aspectratiotable[11] = 300.0; - aspectratiotable[12] = 1000.0; aspectratiotable[13] = 10000.0; - aspectratiotable[14] = 100000.0; aspectratiotable[15] = 0.0; - - for (i = 0; i < 12; i++) { - radiustable[i] = 0; - } - for (i = 0; i < 16; i++) { - aspecttable[i] = 0; - } - for (i = 0; i < 18; i++) { - dihedangletable[i] = 0; - } - - minaltitude = xmax - xmin + ymax - ymin + zmax - zmin; - minaltitude = minaltitude * minaltitude; - shortest = minaltitude; - longest = 0.0; - smallestvolume = minaltitude; - biggestvolume = 0.0; - smallestdiangle = 180.0; - biggestdiangle = 0.0; - - // Loop all elements, calculate quality parameters for each element. - tetrahedrons->traversalinit(); - tetloop.tet = tetrahedrontraverse(); - while (tetloop.tet != (tetrahedron *) NULL) { - p[0] = org(tetloop); - p[1] = dest(tetloop); - p[2] = apex(tetloop); - p[3] = oppo(tetloop); - tetlongest2 = 0.0; - - // Calculate the longest and shortest edge length. - for (i = 0; i < 3; i++) { - j = plus1mod3[i]; - k = minus1mod3[i]; - dx[i] = p[j][0] - p[k][0]; - dy[i] = p[j][1] - p[k][1]; - dz[i] = p[j][2] - p[k][2]; - edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i] + dz[i] * dz[i]; - if (i == 0) { - shortlen = longlen = edgelength[i]; - } else { - shortlen = edgelength[i] < shortlen ? edgelength[i] : shortlen; - longlen = edgelength[i] > longlen ? edgelength[i] : longlen; - } - if (edgelength[i] > tetlongest2) { - tetlongest2 = edgelength[i]; - } - if (edgelength[i] > longest) { - longest = edgelength[i]; - } - if (edgelength[i] < shortest) { - shortest = edgelength[i]; - } - } - for (i = 3; i < 6; i++) { - j = i - 3; - k = 3; - dx[i] = p[j][0] - p[k][0]; - dy[i] = p[j][1] - p[k][1]; - dz[i] = p[j][2] - p[k][2]; - edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i] + dz[i] * dz[i]; - shortlen = edgelength[i] < shortlen ? edgelength[i] : shortlen; - longlen = edgelength[i] > longlen ? edgelength[i] : longlen; - if (edgelength[i] > tetlongest2) { - tetlongest2 = edgelength[i]; - } - if (edgelength[i] > longest) { - longest = edgelength[i]; - } - if (edgelength[i] < shortest) { - shortest = edgelength[i]; - } - } - - // Calculate the largest and smallest volume. - tetvol = orient3d(p[0], p[1], p[2], p[3]) / 6.0; - if (tetvol < 0) tetvol = -tetvol; - if (tetvol < smallestvolume) { - smallestvolume = tetvol; - } - if (tetvol > biggestvolume) { - biggestvolume = tetvol; - } - - // Calculate the largest and smallest dihedral angles. - tetalldihedral(p[0], p[1], p[2], p[3], alldihed); - for (i = 0; i < 6; i++) { - alldihed[i] = alldihed[i] * 180.0 / PI; - if (i == 0) { - smalldiangle = bigdiangle = alldihed[i]; - } else { - smalldiangle = alldihed[i] < smalldiangle ? alldihed[i] : smalldiangle; - bigdiangle = alldihed[i] > bigdiangle ? alldihed[i] : bigdiangle; - } - if (alldihed[i] < smallestdiangle) { - smallestdiangle = alldihed[i]; - } else if (alldihed[i] > biggestdiangle) { - biggestdiangle = alldihed[i]; - } - } - tendegree = (int) (smalldiangle / 10.); - dihedangletable[tendegree]++; - tendegree = (int) (bigdiangle / 10.); - dihedangletable[tendegree]++; - - // Calculate aspect ratio and radius-edge ratio for this element. - tetaspect = 0.0; - if (!circumsphere(p[0], p[1], p[2], p[3], cent, &cirradius)) { - // ! Very bad element. - tetaspect = 1.e+8; - tetradius = 100.0; - } else { - inscribedsphere(p[0], p[1], p[2], p[3], cent, &insradius); - } - if (tetaspect == 0.0) { - tetradius = cirradius / sqrt(shortlen); - tetaspect = sqrt(longlen) / (2.0 * insradius); - - } - aspectindex = 0; - while ((tetaspect > aspectratiotable[aspectindex]) && (aspectindex < 15)) { - aspectindex++; - } - aspecttable[aspectindex]++; - radiusindex = 0; - while ((tetradius > radiusratiotable[radiusindex]) && (radiusindex < 11)) { - radiusindex++; - } - radiustable[radiusindex]++; - - tetloop.tet = tetrahedrontraverse(); - } - - shortest = sqrt(shortest); - longest = sqrt(longest); - minaltitude = sqrt(minaltitude); - - printf(" Smallest volume: %16.5g | Largest volume: %16.5g\n", - smallestvolume, biggestvolume); - printf(" Shortest edge: %16.5g | Longest edge: %16.5g\n", - shortest, longest); - sprintf(sbuf, "%.17g", biggestdiangle); - if (strlen(sbuf) > 8) { - sbuf[8] = '\0'; - } - printf(" Smallest dihedral: %14.5g | Largest dihedral: %s\n\n", - smallestdiangle, sbuf); - - printf(" Radius-edge ratio histogram:\n"); - printf(" < %-6.6g : %8d | %6.6g - %-6.6g : %8d\n", - radiusratiotable[0], radiustable[0], radiusratiotable[5], - radiusratiotable[6], radiustable[6]); - for (i = 1; i < 5; i++) { - printf(" %6.6g - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n", - radiusratiotable[i - 1], radiusratiotable[i], radiustable[i], - radiusratiotable[i + 5], radiusratiotable[i + 6], - radiustable[i + 6]); - } - printf(" %6.6g - %-6.6g : %8d | %6.6g - : %8d\n", - radiusratiotable[4], radiusratiotable[5], radiustable[5], - radiusratiotable[10], radiustable[11]); - printf(" (A tetrahedron's radius-edge ratio is its radius of "); - printf("circumsphere divided\n"); - printf(" by its shortest edge length)\n\n"); - - printf(" Aspect ratio histogram:\n"); - printf(" 1.1547 - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n", - aspectratiotable[0], aspecttable[0], aspectratiotable[7], - aspectratiotable[8], aspecttable[8]); - for (i = 1; i < 7; i++) { - printf(" %6.6g - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n", - aspectratiotable[i - 1], aspectratiotable[i], aspecttable[i], - aspectratiotable[i + 7], aspectratiotable[i + 8], - aspecttable[i + 8]); - } - printf(" %6.6g - %-6.6g : %8d | %6.6g - : %8d\n", - aspectratiotable[6], aspectratiotable[7], aspecttable[7], - aspectratiotable[14], aspecttable[15]); - printf(" (A tetrahedron's aspect ratio is its longest edge length"); - printf(" divided by the\n"); - printf(" diameter of its inscribed sphere)\n\n"); - - printf(" Dihedral Angle histogram:\n"); - for (i = 0; i < 9; i++) { - printf(" %3d - %2d degrees: %8d | %3d - %3d degrees: %8d\n", - i * 10, i * 10 + 10, dihedangletable[i], - i * 10 + 90, i * 10 + 100, dihedangletable[i + 9]); - } - printf("\n"); -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// statistics() Print all sorts of cool facts. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetgenmesh::statistics() -{ - printf("\nStatistics:\n\n"); - printf(" Input points: %d\n", in->numberofpoints); - if (b->refine) { - printf(" Input tetrahedra: %d\n", in->numberoftetrahedra); - } - if (b->plc) { - printf(" Input facets: %d\n", in->numberoffacets); - printf(" Input holes: %d\n", in->numberofholes); - printf(" Input regions: %d\n", in->numberofregions); - } - - printf("\n Mesh points: %ld\n", points->items); - printf(" Mesh tetrahedra: %ld\n", tetrahedrons->items); - if (b->plc || b->refine) { - printf(" Mesh faces: %ld\n", (4l * tetrahedrons->items + hullsize) / 2l); - } - if (b->plc || b->refine) { - printf(" Mesh subfaces: %ld\n", subfaces->items); - printf(" Mesh subsegments: %ld\n\n", subsegs->items); - } else { - printf(" Convex hull faces: %ld\n\n", hullsize); - } - if (b->verbose) { - // if (b->quality || b->removesliver) { - qualitystatistics(); - // } - printf("\n"); - } -} - -// -// End of user interaction routines -// - -// -// Begin of constructor and destructor of tetgenmesh -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// ~tetgenmesh() Deallocte memory occupied by a tetgenmesh object. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::~tetgenmesh() -{ - in = (tetgenio *) NULL; - b = (tetgenbehavior *) NULL; - - if (tetrahedrons != (memorypool *) NULL) { - delete tetrahedrons; - } - if (subfaces != (memorypool *) NULL) { - delete subfaces; - } - if (subsegs != (memorypool *) NULL) { - delete subsegs; - } - if (points != (memorypool *) NULL) { - delete points; - } - if (dummytetbase != (tetrahedron *) NULL) { - delete [] dummytetbase; - } - if (dummyshbase != (shellface *) NULL) { - delete [] dummyshbase; - } - if (liftpointarray != (REAL *) NULL) { - delete [] liftpointarray; - } - if (highordertable != (point *) NULL) { - delete [] highordertable; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetgenmesh() Initialize a tetgenmesh object. // -// // -/////////////////////////////////////////////////////////////////////////////// - -tetgenmesh::tetgenmesh() -{ - in = (tetgenio *) NULL; - b = (tetgenbehavior *) NULL; - - tetrahedrons = (memorypool *) NULL; - subfaces = (memorypool *) NULL; - subsegs = (memorypool *) NULL; - points = (memorypool *) NULL; - badsubsegs = (memorypool *) NULL; - badsubfaces = (memorypool *) NULL; - badtetrahedrons = (memorypool *) NULL; - flipstackers = (memorypool *) NULL; - - dummytet = (tetrahedron *) NULL; - dummytetbase = (tetrahedron *) NULL; - dummysh = (shellface *) NULL; - dummyshbase = (shellface *) NULL; - - liftpointarray = (REAL *) NULL; - highordertable = (point *) NULL; - - xmax = xmin = ymax = ymin = zmax = zmin = 0.0; - longest = 0.0; - hullsize = 0l; - insegment = 0l; - pointmarkindex = 0; - point2simindex = 0; - highorderindex = 0; - elemattribindex = 0; - volumeboundindex = 0; - shmarkindex = 0; - areaboundindex = 0; - checksubfaces = 0; - checkquality = 0; - nonconvex = 0; - dupverts = 0; - samples = 0l; - randomseed = 0l; - macheps = 0.0; - flip23s = flip32s = flip22s = flip44s = 0l; -} - -// -// End of constructor and destructor of tetgenmesh -// - -// -// End of class 'tetgenmesh' implementation. -// - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetrahedralize() The interface for users using TetGen library to // -// generate tetrahedral meshes with all features. // -// // -// The sequence is roughly as follows. Many of these steps can be skipped, // -// depending on the command line switches. // -// // -// - Initialize constants and parse the command line. // -// - Read the vertices from a file and either // -// - tetrahedralize them (no -r), or // -// - read an old mesh from files and reconstruct it (-r). // -// - Insert the PLC segments and facets (-p). // -// - Read the holes (-p), regional attributes (-pA), and regional volume // -// constraints (-pa). Carve the holes and concavities, and spread the // -// regional attributes and volume constraints. // -// - Enforce the constraints on minimum quality bound (-q) and maximum // -// volume (-a). Also enforce the conforming Delaunay property (-q and -a). // -// - Promote the mesh's linear tetrahedra to higher order elements (-o). // -// - Write the output files and print the statistics. // -// - Check the consistency and Delaunay property of the mesh (-C). // -// // -/////////////////////////////////////////////////////////////////////////////// - -#include <time.h> // Defined type clock_t, constant CLOCKS_PER_SEC. - -void tetrahedralize(tetgenbehavior *b, tetgenio *in, tetgenio *out) -{ - tetgenmesh m; - clock_t tv0, tv1, tv2, tv3, tv4, tv5, tv6, tv7, tv8; - - if (!b->quiet) { - tv0 = clock(); - } - - m.b = b; - m.in = in; - - m.macheps = exactinit(); - m.initializepointpool(); - m.initializetetshpools(); - m.steinerleft = b->steiner; - - if (!b->quiet) { - tv1 = clock(); - } - - m.transfernodes(); - if (b->refine) { - m.reconstructmesh(); - } else { - m.incrflipdelaunay(); - } - - if (!b->quiet) { - tv2 = clock(); - if (b->refine) { - printf("Mesh reconstruction seconds: %g\n", - (tv2 - tv1) / (REAL) CLOCKS_PER_SEC); - } else if (!b->detectinter) { - printf("Delaunay seconds: %g\n", (tv2 - tv1) / (REAL) CLOCKS_PER_SEC); - } - } - - if (b->useshelles && !b->refine) { - m.insegment = m.meshsurface(); - if (b->detectinter) { - m.detectinterfaces(); - } else { - if (!b->nobisect) { - m.delaunizesegments(); - m.checksubfaces = 1; - m.constrainedfacets(); - } - } - } - - if (!b->quiet) { - tv3 = clock(); - if (b->useshelles && !b->refine) { - if (b->detectinter) { - printf("Intersection seconds: %g\n", - (tv3 - tv2) / (REAL) CLOCKS_PER_SEC); - } else { - if (!b->nobisect) { - printf("Segment and facet seconds: %g\n", - (tv3 - tv2) / (REAL) CLOCKS_PER_SEC); - } - } - } - } - - if (b->plc && !b->refine && !b->detectinter) { - if (b->checkclosure) { - m.indenthull(); - } else { - m.carveholes(); - } - m.nonconvex = 1; - } - - if (!b->quiet) { - tv4 = clock(); - if (b->plc && !b->refine && !b->detectinter) { - printf("Hole seconds: %g\n", (tv4 - tv3) / (REAL) CLOCKS_PER_SEC); - } - } - - if ((b->plc || b->refine) && !b->detectinter && !b->checkclosure) { - m.removeilltets(); - } - - if (!b->quiet) { - tv5 = clock(); - if ((b->plc || b->refine) && !b->detectinter) { - printf("Repair seconds: %g\n", (tv5 - tv4) / (REAL) CLOCKS_PER_SEC); - } - } - - if (b->insertaddpoints) { - if (in->numberofaddpoints == 0) { - in->load_addnodes(b->infilename); - } - if (in->numberofaddpoints > 0) { - m.insertaddpoints(); - } - } - - if (!b->quiet) { - tv6 = clock(); - if ((b->plc || b->refine) && (in->numberofaddpoints > 0)) { - printf("Add points seconds: %g\n", (tv6 - tv5) / (REAL) CLOCKS_PER_SEC); - } - } - - if (b->quality && (m.tetrahedrons->items > 0)) { - m.enforcequality(); - } - - if (!b->quiet) { - tv7 = clock(); - if (b->quality && (m.tetrahedrons->items > 0)) { - printf("Quality seconds: %g\n", (tv7 - tv6) / (REAL) CLOCKS_PER_SEC); - } - } - - if ((b->plc || b->refine) && b->removesliver) { - m.removeslivers(); - } - - if (!b->quiet) { - tv8 = clock(); - if ((b->plc || b->refine) && b->removesliver) { - printf("Sliver repair seconds: %g\n", - (tv8 - tv7) / (REAL) CLOCKS_PER_SEC); - } - } - - if (b->order > 1) { - m.highorder(); - } - - if (!b->quiet) { - printf("\n"); - } - - if (out != (tetgenio *) NULL) { - out->firstnumber = in->firstnumber; - out->mesh_dim = in->mesh_dim; - } - - if (b->nonodewritten || b->noiterationnum) { - if (!b->quiet) { - printf("NOT writing a .node file.\n"); - } - } else { - if (b->detectinter) { - if (m.subfaces->items > 0l) { - // Only output when there are intersecting faces. - m.outnodes(out); - } - } else { - m.outnodes(out); - } - } - - if (b->noelewritten) { - if (!b->quiet) { - printf("NOT writing an .ele file.\n"); - } - } else { - if (!b->detectinter) { - if (m.tetrahedrons->items > 0l) { - m.outelements(out); - } - } - } - - if (b->nofacewritten) { - if (!b->quiet) { - printf("NOT writing an .face file.\n"); - } - } else { - if (b->facesout) { - if (m.tetrahedrons->items > 0l) { - // Output all faces. - m.outfaces(out); - } - } else { - if (b->detectinter) { - if (m.subfaces->items > 0l) { - // Only output when there are intersecting faces. - m.outsubfaces(out); - } - } else if (b->plc || b->refine) { - if (m.tetrahedrons->items > 0l) { - // Output boundary faces. - m.outsubfaces(out); - } - } else { - if (m.tetrahedrons->items > 0l) { - // Output convex hull faces. - m.outhullfaces(out); - } - } - } - } - - if (b->edgesout && b->plc) { - m.outsubsegments(out); - } - - if (!out && b->plc && ((b->object == tetgenbehavior::OFF) || - (b->object == tetgenbehavior::PLY) || - (b->object == tetgenbehavior::STL))) { - m.outsmesh(b->outfilename); - } - - if (!out && b->meditview) { - m.outmesh2medit(b->outfilename); - } - - if (!out && b->gidview) { - m.outmesh2gid(b->outfilename); - } - - if (!out && b->geomview) { - m.outmesh2off(b->outfilename); - } - - if (b->neighout) { - m.outneighbors(out); - } - - if (!b->quiet) { - tv7 = clock(); - printf("\nOutput seconds: %g\n", (tv7 - tv6) / (REAL) CLOCKS_PER_SEC); - printf("Total running seconds: %g\n", - (tv7 - tv0) / (REAL) CLOCKS_PER_SEC); - } - - if (b->docheck) { - m.checkmesh(); - if (m.checksubfaces) { - m.checkshells(); - } - if (b->docheck > 1) { - m.checkdelaunay(NULL); - if (b->docheck > 2) { - if (b->quality || b->refine) { - m.checkconforming(); - } - } - } - } - - if (!b->quiet) { - m.statistics(); - } -} - -#ifndef TETLIBRARY - -/////////////////////////////////////////////////////////////////////////////// -// // -// main() The entrance for running TetGen from command line. // -// // -/////////////////////////////////////////////////////////////////////////////// - -int main(int argc, char *argv[]) - -#else // with TETLIBRARY - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetrahedralize() The entrance for calling TetGen from another program. // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetrahedralize(char *switches, tetgenio *in, tetgenio *out) - -#endif // not TETLIBRARY - -{ - tetgenbehavior b; - -#ifndef TETLIBRARY - - tetgenio in; - - if (!b.parse_commandline(argc, argv)) { - exit(1); - } - if (b.refine) { - if (!in.load_tetmesh(b.infilename)) { - exit(1); - } - } else { - if (!in.load_plc(b.infilename, (int) b.object)) { - exit(1); - } - } - tetrahedralize(&b, &in, NULL); - - return 0; - -#else // with TETLIBRARY - - if (!b.parse_commandline(switches)) { - exit(1); - } - tetrahedralize(&b, in, out); - -#endif // not TETLIBRARY -} diff --git a/Tetgen/tetgen.h b/Tetgen/tetgen.h deleted file mode 100644 index cbe84252e8..0000000000 --- a/Tetgen/tetgen.h +++ /dev/null @@ -1,1764 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// // -// TetGen // -// // -// A Quality Tetrahedral Mesh Generator and 3D Delaunay Triangulator // -// // -// Version 1.3 // -// June 13, 2004 // -// // -// Copyright 2002, 2004 // -// Hang Si // -// Rathausstr. 9, 10178 Berlin, Germany // -// si@wias-berlin.de // -// // -// You can obtain TetGen via internet: http://tetgen.berlios.de. It may be // -// freely copied, modified, and redistributed under the copyright notices // -// given in the file LICENSE. // -// // -// TetGen is a program for generating quality tetrahedral meshes and three- // -// dimensional Delaunay triangulations. It currently computes exact // -// Delaunay tetrahedralizations, constrained Delaunay tetrahedralizations, // -// and quality tetrahedral meshes. The latter are nicely graded and whose // -// tetrahedra have radius-edge ratio bounded, and are conforming Delaunay // -// if there are no input angles smaller than 60 degree. // -// // -// TetGen incorporates a suit of geometrical and mesh generation algorithms. // -// A brief description of these algorithms used in TetGen can be found in // -// the first section of the user's manual. References are given for users // -// who are interesting in these approaches. However, the main references // -// are listed below: // -// // -// The efficient Delaunay tetrahedralization algorithm is: H. Edelsbrunner // -// and N. R. Shah, "Incremental Topological Flipping Works for Regular // -// Triangulations". Algorithmica 15: 223-241, 1996. // -// // -// The constrained Delaunay tetrahedralization algorithm is described in: // -// H. Si and K. Gaertner, "An Algorithm for Three-Dimensional Constrained // -// Delaunay Triangles". Proceedings of the 4th International Conference on // -// Engineering Computational Technology, Lisbon, September 2004. // -// // -// The Delaunay refinement algorithm is from: J. R. Shewchuk, "Tetrahedral // -// Mesh Generation by Delaunay Refinement". Proceedings of the 14th Annual // -// Symposium on Computational Geometry, pages 86-95, 1998. // -// // -// The mesh data structure of TetGen is a combination of two types of mesh // -// data structures. The tetrahedron-based mesh data structure introduced // -// by Shewchuk is eligible to implement algorithms of generating Delaunay // -// tetrahedralizations. However, constrained Delaunay tetrahedralization // -// and quality mesh generation algorithms require other mesh elements // -// (subfaces, subsegments) be handled at the same time. The triangle-edge // -// data structure from Muecke is adopted for this purpose. Handling // -// these data types together is through a set of fast mesh manipulation // -// primitives. References of these two data structures are found below: // -// // -// J. R. Shewchuk, "Delaunay Refinement Mesh Generation". PhD thesis, // -// Carnegie Mellon University, 1997. // -// // -// E. P. Muecke, "Shapes and Implementations in Three-Dimensional // -// Geometry". PhD thesis, Univ. of Illinois, Urbana, Illinois, 1993. // -// // -// The research of mesh generation is definitly on the move. A lot of state- // -// of-the-art algorithms need to be implemented and evaluated. I heartily // -// welcome new algorithms especially for quality conforming Delaunay mesh // -// generation and anisotropic conforming Delaunay mesh generation. If you // -// have any idea on new approaches, please please kindly let me know. // -// // -// TetGen is supported by the "pdelib" project of Weierstrass Institute for // -// Applied Analysis and Stochastics (WIAS) in Berlin. It is a collection // -// of software components for solving non-linear partial differential // -// equations including 2D and 3D mesh generators, sparse matrix solvers, // -// and scientific visualization tools, etc. For more information please // -// see: http://www.wias-berlin.de/software/pdelib. // -// // -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetgen.h // -// // -// Header file of the TetGen library. Also is the user-level header file. // -// // -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// // -// TetGen Library Overview // -// // -// TetGen library is comprised by several data types and global functions. // -// // -// If you quickly go through this file, you will find there are only three // -// main data types defined, which are "tetgenio", "tetgenbehavior", and // -// "tetgenmesh". Tetgenio is used to pass data into and out of mesh routines // -// of the library; tetgenbehavior sets the command line options selected by // -// user and thus controls the behaviors of TetGen; tetgenmesh, the biggest // -// data type I've ever defined, contains everything for creating Delaunay // -// tetrahedralizations and tetrahedral meshes. These data types are defined // -// as C++ classes. // -// // -// There are few global functions as well. "tetrahedralize()" is the (only) // -// user interface for calling TetGen from other programs. Two functions // -// "orient3d()" and "insphere()" are incorporated from a public C code for // -// performing exact geometrical tests. // -// // -/////////////////////////////////////////////////////////////////////////////// - -#ifndef tetgenH -#define tetgenH - -// To compile TetGen as a library (e.g. libtet.a) but not as an executable -// program, define the TETLIBRARY symbol. The library of TetGen can be -// linked with programs which want to call TetGen as a function. - -// #define TETLIBRARY - -// Uncomment the following line to disable assert macros. These macros are -// inserted in places where I hope to catch bugs. Somewhat, they slow down -// the speed of TetGen. They can be ignored by adding the -DNDEBUG -// compiler switch or uncomment the following line - -// #define NDEBUG - -// To insert lots of self-checks for internal errors, define the SELF_CHECK -// symbol. This will slow down the program significantly. - -// #define SELF_CHECK - -// For single precision ( which will save some memory and reduce paging ), -// define the symbol SINGLE by using the -DSINGLE compiler switch or by -// writing "#define SINGLE" below. -// -// For double precision ( which will allow you to refine meshes to a smaller -// edge length), leave SINGLE undefined. - -// #define SINGLE - -#ifdef SINGLE - #define REAL float -#else - #define REAL double -#endif // not defined SINGLE - -// Here is the most general used head files for all C/C++ codes - -#include <stdio.h> // Standard IO: FILE, NULL, EOF, printf(), ... -#include <stdlib.h> // Standard lib: abort(), system(), getenv(), ... -#include <string.h> // String lib: strcpy(), strcat(), strcmp(), ... -#include <math.h> // Math lib: sin(), sqrt(), pow(), ... -#include <assert.h> - -/////////////////////////////////////////////////////////////////////////////// -// // -// The tetgenio data type // -// // -// Used to pass data into and out of the library of TetGen. // -// // -// If you want to program with the library of TetGen, it's necessary for you // -// to understand the tetgenio data type, while the other two data types can // -// be hidden through calling the global function "tetrahedralize()". As you // -// will see below, that basically tetgenio is nothing more than a collection // -// of arrays. These arrays are used to store points, tetrahedra, (triangular)// -// faces, boundary markers, and so forth. They are used to describe data in // -// input & output files of TetGen. If you understand TetGen's file formats, // -// then it is straighforward for you to understand these arrays. The file // -// formats of TetGen are described in the third section of the user's manual.// -// // -// Once you create an object of tetgenio, all arrays are initialized to NULL.// -// This is done by routine "initialize()", it is automatically called by the // -// constructor. Before you set data into these arrays, you need to allocate // -// enough memory for them. After you use the object, you need to clear the // -// memory occupied by these arrays. Routine "deinitialize()" will be auto- // -// matically called on deletion of the object. It will clear the memory in // -// each array if it is not a NULL. However, it assumes that the memory is // -// allocated by C++ operator 'new'. If you use malloc() to allocate memory, // -// you should free them yourself, after they're freed, call "initialize()" // -// once to disable "deinitialize()". // -// // -// In all cases, the first item in any array is stored starting at index [0].// -// However, that item is item number `firstnumber' which may be '0' or '1'. // -// Be sure to set the 'firstnumber' be '1' if your indices pointing into the // -// pointlist is starting from '1'. Default, it is initialized be '0'. // -// // -// Tetgenio also contains routines for reading and writing TetGen's files as // -// well. Both the library of TetGen and TetView use these routines to parse // -// input files, i.e., .node, .poly, .smesh, .ele, .face, and .edge files. // -// Other routines are provided mainly for debugging purpose. // -// // -/////////////////////////////////////////////////////////////////////////////// - -class tetgenio { - - public: - - // Maximum number of characters in a file name (including the null). - enum {FILENAMESIZE = 1024}; - - // Maxi. numbers of chars in a line read from a file (incl. the null). - enum {INPUTLINESIZE = 1024}; - - // The polygon data structure. A "polygon" is a planar polygon. It can - // be arbitrary shaped (convex or non-convex) and bounded by non- - // crossing segments, i.e., the number of vertices it has indictes the - // same number of edges. - // 'vertexlist' is a list of vertex indices (integers), its length is - // indicated by 'numberofvertices'. The vertex indices are odered in - // either counterclockwise or clockwise way. - typedef struct { - int *vertexlist; - int numberofvertices; - } polygon; - - static void init(polygon* p) { - p->vertexlist = (int *) NULL; - p->numberofvertices = 0; - } - - // The facet data structure. A "facet" is a planar facet. It is used - // to represent a planar straight line graph (PSLG) in two dimension. - // A PSLG contains a list of polygons. It also may conatin holes in it, - // indicated by a list of hole points (their coordinates). - typedef struct { - polygon *polygonlist; - int numberofpolygons; - REAL *holelist; - int numberofholes; - } facet; - - static void init(facet* f) { - f->polygonlist = (polygon *) NULL; - f->numberofpolygons = 0; - f->holelist = (REAL *) NULL; - f->numberofholes = 0; - } - - public: - - // Items are numbered starting from 'firstnumber' (0 or 1), default is 0. - int firstnumber; - - // Dimension of the mesh (2 or 3), default is 3. - int mesh_dim; - - // `pointlist': An array of point coordinates. The first point's x - // coordinate is at index [0] and its y coordinate at index [1], its - // z coordinate is at index [2], followed by the coordinates of the - // remaining points. Each point occupies three REALs. - // `pointattributelist': An array of point attributes. Each point's - // attributes occupy `numberofpointattributes' REALs. - // 'addpointlist': An array of additional point coordinates. - // `pointmarkerlist': An array of point markers; one int per point. - REAL *pointlist; - REAL *pointattributelist; - REAL *addpointlist; - int *pointmarkerlist; - int numberofpoints; - int numberofpointattributes; - int numberofaddpoints; - - // `elementlist': An array of element (triangle or tetrahedron) corners. - // The first element's first corner is at index [0], followed by its - // other corners in counterclockwise order, followed by any other - // nodes if the element represents a nonlinear element. Each element - // occupies `numberofcorners' ints. - // `elementattributelist': An array of element attributes. Each - // element's attributes occupy `numberofelementattributes' REALs. - // `elementconstraintlist': An array of constraints, i.e. triangle's - // area or tetrahedron's volume; one REAL per element. Input only. - // `neighborlist': An array of element neighbors; 3 or 4 ints per - // element. Output only. - int *tetrahedronlist; - REAL *tetrahedronattributelist; - REAL *tetrahedronvolumelist; - int *neighborlist; - int numberoftetrahedra; - int numberofcorners; - int numberoftetrahedronattributes; - - // `facetlist': An array of facets. Each entry is a structure of facet. - // `facetmarkerlist': An array of facet markers; one int per facet. - facet *facetlist; - int *facetmarkerlist; - int numberoffacets; - - // `holelist': An array of holes. The first hole's x, y and z - // coordinates are at indices [0], [1] and [2], followed by the - // remaining holes. Three REALs per hole. - REAL *holelist; - int numberofholes; - - // `regionlist': An array of regional attributes and area or volume - // constraints. The first constraint's x, y and z coordinates are at - // indices [0], [1] and [2], followed by the regional attribute and - // index [3], followed by the maximum area or volume at index [4], - // followed by the remaining area or volume constraints. Five REALs - // per constraint. - // Note that each regional attribute is used only if you select the `A' - // switch, and each constraint is used only if you select the `a' - // switch (with no number following), but omitting one of these - // switches does not change the memory layout. - REAL *regionlist; - int numberofregions; - - // `trifacelist': An array of triangular face endpoints. The first - // face's endpoints are at indices [0], [1] and [2], followed by the - // remaining faces. Three ints per face. - // `trifacemarkerlist': An array of face markers; one int per face. - int *trifacelist; - int *trifacemarkerlist; - int numberoftrifaces; - - // `edgelist': An array of edge endpoints. The first edge's endpoints - // are at indices [0] and [1], followed by the remaining edges. Two - // ints per edge. - // `edgemarkerlist': An array of edge markers; one int per edge. - int *edgelist; - int *edgemarkerlist; - int numberofedges; - - public: - - // Initialize routine. - void initialize(); - void deinitialize(); - - // Input & output routines. - bool load_node_call(FILE* infile, int markers, char* nodefilename); - bool load_node(char* filename); - bool load_addnodes(char* filename); - bool load_poly(char* filename); - bool load_off(char* filename); - bool load_ply(char* filename); - bool load_stl(char* filename); - bool load_medit(char* filename); - bool load_plc(char* filename, int object); - bool load_tetmesh(char* filename); - void save_nodes(char* filename); - void save_elements(char* filename); - void save_faces(char* filename); - void save_edges(char* filename); - void save_neighbors(char* filename); - void save_poly(char* filename); - - // Read line and parse string functions. - char *readline(char* string, FILE* infile, int *linenumber); - char *findnextfield(char* string); - char *readnumberline(char* string, FILE* infile, char* infilename); - char *findnextnumber(char* string); - - // Constructor and destructor. - tetgenio() {initialize();} - ~tetgenio() {deinitialize();} -}; - -/////////////////////////////////////////////////////////////////////////////// -// // -// The tetgenbehavior data type // -// // -// Used to parse command line switches and file names. // -// // -// It includes a list of variables corresponding to the commandline switches // -// for control the behavior of TetGen. These varibales are all initialized // -// to their default values. // -// // -// Routine "parse_commandline()" defined in this data type is used to change // -// the vaules of the variables. This routine accepts the standard parameters // -// ('argc' and 'argv') that pass to C/C++ main() function. It also accepts a // -// string which contains the command line options. // -// // -// You don't need to understand this data type. It can be implicitly called // -// by the global function "tetrahedralize()" defined below. The necessary // -// thing you need to know is the meaning of command line switches of TetGen. // -// They are described in the third section of the user's manual. // -// // -/////////////////////////////////////////////////////////////////////////////// - -class tetgenbehavior { - - public: - - // Labels define the objects which are acceptable by TetGen. They are - // recoggnized from the extensions of the input filenames. - // - NODES, a list of nodes (.node); - // - POLY, a piecewise linear complex (.poly or .smesh); - // - OFF, a polyhedron (.off, Geomview's file format); - // - PLY, a polyhedron (.ply, file format from gatech); - // - STL, a surface mesh (.stl, stereolithography format); - // - MEDIT, a surface mesh (.mesh, Medit's file format); - // - MESH, a tetrahedral mesh (.ele). - // If no extension is available, the imposed commandline switch - // (-p or -r) implies the object. - - enum objecttype {NONE, NODES, POLY, OFF, PLY, STL, MEDIT, MESH}; - - // Variables of command line switches. After each variable are the - // corresponding switch and its default value. Read the user's manul - // or online instructions to find out the meaning of these switches. - - int plc; // '-p' switch, 0. - int refine; // '-r' switch, 0. - int quality; // '-q' switch, 0. - REAL minratio; // number after '-q' switch, 2.0. - REAL goodratio; // number calculated from 'minratio', 0.0. - REAL minangle; // minimum angle bound, 20.0. - REAL goodangle; // cosine squared of minangle, 0.0. - int varvolume; // '-a' switch without number, 0. - int fixedvolume; // '-a' switch with number, 0. - REAL maxvolume; // number after '-a' switch, -1.0. - int removesliver; // '-s' switch, 0. - REAL maxdihedral; // number after '-s' switch, 0.0. - int insertaddpoints; // '-i' switch, 0. - int regionattrib; // '-A' switch, 0. - REAL epsilon; // number after '-T' switch, 1.0e-8. - int nomerge; // not merge two coplanar facets, '-M' switch, 0. - int detectinter; // '-d' switch, 0. - int checkclosure; // '-c' switch, 0. - int zeroindex; // '-z' switch, 0. - int jettison; // '-j' switch, 0. - int order; // element order, specified after '-o' switch, 1. - int facesout; // '-f' switch, 0. - int edgesout; // '-e' switch, 0. - int neighout; // '-n' switch, 0. - int meditview; // '-g' switch, 0. - int gidview; // '-G' switch, 0. - int geomview; // '-O' switch, 0. - int nobound; // '-B' switch, 0. - int nonodewritten; // '-N' switch, 0. - int noelewritten; // '-E' switch, 0. - int nofacewritten; // '-F' switch, 0. - int noiterationnum; // '-I' switch, 0. - int nobisect; // count of how often '-Y' switch is selected, 0. - int noflip; // do not perform flips. '-Y' switch. 0. - int steiner; // number after '-S' switch. 0. - int dopermute; // do permutation. '-P' switch, 0. - int srandseed; // number of a random seed after '-P' switch, 1. - int docheck; // '-C' switch, 0. - int quiet; // '-Q' switch, 0. - int verbose; // count of how often '-V' switch is selected, 0. - int useshelles; // '-p', '-r', '-q', 'd', or 'c' switch, 0. - enum objecttype object; // determined by -p, or -r switch. NONE. - - // Variables used to save command line switches and in/out file names. - char commandline[1024]; - char infilename[1024]; - char outfilename[1024]; - - // Default initialize and de-initialize functions. - tetgenbehavior(); - ~tetgenbehavior() {} - - void versioninfo(); - void syntax(); - void usage(); - - // Command line parse routine. - bool parse_commandline(int argc, char **argv); - bool parse_commandline(char *switches) { - return parse_commandline(0, &switches); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// // -// Geometric predicates // -// // -// TetGen uses two basic geometric predicates, which are orientation test, // -// and locally Delaunay test (insphere test). // -// // -// Orientation test: let a, b, c be a sequence of 3 points in R^3 and are // -// not collinear, there exists a unique plane H passes through them. Let H+ // -// H- be the two spaces separated by H, which are defined as follows (using // -// left-hand rule): make a fist using your left hand in such a way that your // -// fingers follow the order of a, b and c, then your thumb is pointing to H+.// -// The orientation test is to determine whether another point d lies in H+ // -// (also say that d has positive orientation), or in H- (also say that d has // -// negative orientation), or on H (zero orientation). // -// // -// Locally Delaunay test (insphere test): let a, b, c, d be 4 points in R^3 // -// and are not coplanar, there exists a unique circumsphere S passes through // -// these 4 points. The task is to check if another point e lies outside, on // -// or inside S. // -// // -// The following routines use arbitrary precision floating-point arithmetic // -// to implement these geometric predicates. They are fast and robust. It is // -// provided by J. R. Schewchuk in public domain. See the following link: // -// http://www.cs.cmu.edu/~quake/robust.html. The source code are found in a // -// separate file "predicates.cxx". // -// // -/////////////////////////////////////////////////////////////////////////////// - -REAL exactinit(); -REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd); -REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe); - -/////////////////////////////////////////////////////////////////////////////// -// // -// The tetgenmesh data type // -// // -// Includes data types and mesh routines for Delaunay tetrahedralizations // -// and tetrahedral meshes. // -// // -// An object of tetgenmesh can be used to store a triangular or tetrahedral // -// mesh and its settings. TetGen's functions operates on one mesh each time. // -// This type allows reusing of the same function for different meshes. // -// // -// The mesh data structure (tetrahedron-based and triangle-edge data struct- // -// ures) are declared in this data type. There are other accessary data type // -// defined as well, they are used for efficient memory management and fast // -// link list operations, etc. // -// // -// All algorithms TetGen used are implemented in this data type as member // -// functions. References of these algorithms can be found in user's manual. // -// // -// You don't need to study this data type if you only want to use TetGen's // -// library to create tetrahedral mesh. The global function "tetrahedralize()"// -// implicitly creates the object and calls its member functions due to the // -// command line switches you used. // -// // -/////////////////////////////////////////////////////////////////////////////// - -class tetgenmesh { - - public: - - // Maximum number of characters in a file name (including the null). - enum {FILENAMESIZE = 1024}; - - // For efficiency, a variety of data structures are allocated in bulk. - // The following constants determine how many of each structure is - // allocated at once. - enum {VERPERBLOCK = 4092, SUBPERBLOCK = 4092, ELEPERBLOCK = 8188}; - - // Used for the point location scheme of Mucke, Saias, and Zhu, to - // decide how large a random sample of tetrahedra to inspect. - enum {SAMPLEFACTOR = 11}; - - // Labels that signify two edge rings of a triangle defined in Muecke's - // triangle-edge data structure, one (CCW) traversing edges in count- - // erclockwise direction and one (CW) in clockwise direction. - enum {CCW = 0, CW = 1}; - - // Labels that signify whether a record consists primarily of pointers - // or of floating-point words. Used to make decisions about data - // alignment. - enum wordtype {POINTER, FLOATINGPOINT}; - - // Labels that signify the type of a vertex. An UNUSEDVERTEX is a vertex - // read from input (.node file or tetgenio structure) or an isolated - // vertex (outside the mesh). It is the default type for a newpoint. - enum verttype {UNUSEDVERTEX, NONACUTEVERTEX, ACUTEVERTEX, FREESEGVERTEX, - FACETVERTEX, PROTCYLSPHVERTEX, FREECYLSPHVERTEX, - PROTCYLVERTEX, PROTSPHVERTEX, FREECYLVERTEX, - FREESPHVERTEX, FREESUBVERTEX, FREEVOLVERTEX, - DUPLICATEDVERTEX, DEADVERTEX = -32768}; - - // Labels that signify the type of a subsegment or a subface. An input - // (sub)segment may have type NONSHARPSEGMENT, SHARPSEGMENT. Segments - // preceding with "PROT" are artificially created for protecting the - // internal region of cylinders and spheres. A subface may have one of - // the three types PROTCYLSUBFACE, PROTSPHSUBFACE, and NONPROTSUBFACE. - enum shestype {NONSHARPSEGMENT, SHARPSEGMENT, PROTCYLSEGMENT, - PROTSPHSEGMENT, PROTCYLSUBFACE, PROTSPHSUBFACE, - NONPROTSUBFACE}; - - // Labels that signify the type of flips which can be applied on a face. - // A flipable face has one of the types T23, T32, T22, and T44. Types - // NONCONVEX, FORBIDDEN and UNFLIPABLE indicate non-flipable faces. - enum fliptype {T23, T32, T22, T44, UNFLIPABLE, FORBIDDENFACE, - FORBIDDENEDGE, NONCONVEX}; - - // Labels that signify the type of a bad tetrahedron. - enum badtettype {SKINNY, CAP, SLIVER, ILLEGAL}; - - // Labels that signify the result of triangle-triangle intersection. - // The result indicates that two triangles t1 and t2 are completely - // DISJOINT, or adjoint only at a vertex SHAREVERTEX, or adjoint at - // an edge SHAREEDGE, or coincident SHAREFACE, or INTERSECT. - enum intersectresult {DISJOINT, SHAREVERTEX, SHAREEDGE, SHAREFACE, - INTERSECT}; - - // Labels that signify the result of point location. The result of a - // search indicates that the point falls inside a tetrahedron, inside - // a triangle, on an edge, on a vertex, or outside the mesh. - enum locateresult {INTETRAHEDRON, ONFACE, ONEDGE, ONVERTEX, OUTSIDE}; - - // Labels that signify the result of vertex insertion. The result - // indicates that the vertex was inserted with complete success, was - // inserted but encroaches upon a subsegment, was not inserted because - // it lies on a segment, or was not inserted because another vertex - // occupies the same location. - enum insertsiteresult {SUCCESSINTET, SUCCESSONFACE, SUCCESSONEDGE, - ENCROACHINGPOINT, DUPLICATEPOINT, OUTSIDEPOINT}; - - // Labels that signify the result of direction finding. The result - // indicates that a segment connecting the two query points accross - // an edge of the direction triangle/tetrahedron, across a face of - // the direction tetrahedron, along the left edge of the direction - // triangle/tetrahedron, along the right edge of the direction - // triangle/tetrahedron, or along the top edge of the tetrahedron. - enum finddirectionresult {ACROSSEDGE, ACROSSFACE, LEFTCOLLINEAR, - RIGHTCOLLINEAR, TOPCOLLINEAR, BELOWHULL}; - -/////////////////////////////////////////////////////////////////////////////// -// // -// The basic mesh element data structures // -// // -// There are four types of mesh elements: tetrahedra, subfaces, subsegments, // -// and points, where subfaces and subsegments are triangles and edges which // -// appear on boundaries. A tetrahedralization of a 3D point set comprises // -// tetrahedra and points; a surface mesh of a 3D domain comprises subfaces // -// (triangles), subsegments and points; and it is the elements of all the // -// four types consist of a tetrahedral mesh of a 3D domain. However, TetGen // -// uses three data types: 'tetrahedron', 'shellface', and 'point' to repres- // -// ent the basic mesh elements. A 'tetrahedron' is a tetrahedron; while a // -// 'shellface' can represent either a subface or a subsegment; and a 'point' // -// represent a point. Theese three data types, linked by pointers comprise // -// a tetrahedralization or a mesh. // -// // -// The data type 'tetrahedron' primarily consists of a list of four pointers // -// to its corners, a list of four pointers to its adjoining tetrahedra, a // -// list of four pointers to its adjoining subfaces(when subfaces are needed).// -// Optinoally, (depending on the selected switches), it may contain an arbi- // -// trary number of user-defined floating-point attributes, an optional max- // -// imum volume constraint (-a switch), and a pointer to a list of high-order // -// nodes (-o2 switch). Because the size of a tetrahedron is not determined // -// until running time, it is not simply declared as a structure. // -// // -// For purpose of storing geometric information, it is important to know the // -// ordering of the vertices of a tetrahedron. Let v0, v1, v2, and v3 be the // -// four nodes corresponding to the order of their storage in a tetrahedron. // -// v3 always has negative orientation with respect to v0, v1, v2 (in other // -// words, v3 lies above the oriented plane passes through v0, v1, v2). Let // -// the four faces of the tetrahedron be f0, f1, f2, and f3. Vertices of each // -// face are stipulated as follows: f0 (v0, v1, v2), f1 (v0, v3, v1), f2 (v1, // -// v3, v2), f3 (v2, v3, v0). Adjoining tetrahedra as well as subfaces are // -// stored in the order of its faces, e.g., the first adjoining tetrahedra is // -// the neighbor at f0, and so on. // -// // -// A subface is represented by the data type 'shellface'. It has three // -// pointers to its vertices, three pointers to its adjoining subfaces, three // -// pointers to subsegments, two pointers to its adjoining tetrahedra, and a // -// boundary marker (an integer). Furthermore, the pointers to vertices, // -// adjoining subfaces, and subsegments are ordered in a way that indicates // -// their geometric relation. Let the three vertices according to the order // -// of their storage be v0, v1 and v2, respectively, and e0, e1 and e2 be the // -// three edges, then we have: e0 (v0, v1), e1 (v1, v2), e2 (v2, v0). Adjoin- // -// ing subfaces and subsegments are stored in the order of its edges. // -// // -// A subsegment is also represented by a 'shellface'. It has exactly the // -// same data fields as a subface has, but only uses some of them. It has two // -// pointers to its endpoints, two pointers to its adjoining (and collinear) // -// subsegments, one pointer to a subface containing it (there may exist any // -// number of subfaces having it, choose one of them arbitrarily). The geome- // -// tric relation between its endpoints and adjoining (collinear) subsegments // -// is kept with respect to the storing order of its endpoints. The adjoining // -// subsegment at the first endpoint is saved ahead of the other. // -// // -// The data type 'point' is relatively simple. A point is a list of floating // -// -point numbers, starting with the x, y, and z coordinates, followed by an // -// arbitrary number of optional user-defined floating-point attributes, an // -// integer boundary marker, an integer for the point type, and a pointer to // -// a tetrahedron. The latter is used for speeding up point location during // -// the mesh generation. // -// // -// For a tetrahedron on a boundary (or a hull) of the mesh, some or all of // -// the adjoining tetrahedra may not be present. For an interior tetrahedron, // -// often no neighboring subfaces are present, Such absent tetrahedra and // -// subfaces are never represented by the NULL pointers; they are represented // -// by two special records: `dummytet', the tetrahedron fills "outer space", // -// and `dummysh', the vacuous subfaces which are omnipresent. // -// // -// Tetrahedra and adjoining subfaces are glued together through the pointers // -// saved in each data fields of them. Subfaces and adjoining subsegments are // -// connected in the same fashion. However, there are no pointers directly // -// gluing tetrahedra and adjoining subsegments. For the purpose of saving // -// space, the connections between tetrahedra and subsegments are entirely // -// mediated through subfaces. The following part is an explaination of how // -// subfaces are connected in TetGen. // -// // -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// // -// The subface-subface and subface-subsegment connections // -// // -// Adjoining subfaces sharing a common edge are connected in such a way that // -// they form a face ring around the edge. It is in deed a single linked list // -// which is cyclic, e.g., one can start from any subface in it and traverse // -// back. When the edge is not a subsegment, the ring only has two coplanar // -// subfaces which are pointing to each other. Otherwise, the face ring may // -// have any number of subfaces (and are not all coplanar). // -// // -// The face ring around a subsegment is formed as follows. Let s be a sub- // -// segment, and f be a subface containing s as an edge. The direction of s // -// is stipulated from its first endpoint to its second (the first and second // -// endpoints are according to their storage in s). When the direction of s // -// is determined, other two edges of f are oriented following this direction.// -// The "directional normal" of f is a ray starts from any point in f, points // -// to the direction of the cross product of any of two edge vectors of f. // -// // -// The face ring of s is a cyclic ordered set of subfaces containing s, i.e.,// -// F(s) = {f1, f2, ..., fn}, n >= 1. Where the order is defined as follows: // -// let fi, fj be two faces in F(s), the "normal-angle", nangle(i,j) (range // -// from 0 to 360 degree) is the angle between the directional normals of fi // -// and fj; that fi is in front of fj (or symbolically, fi < fj) if there // -// exists another fk in F(s), and nangle(k, i) < nangle(k, j). The face ring // -// of s can be represented as: f1 < f2 < ... < fn < f1. // -// // -// The easiest way to imagine how a face ring is formed is to use the right- // -// hand rule. Make a fist using your right hand with the thumb pointing to // -// the direction of the subsegment. The face ring is connected following the // -// direction of your fingers. // -// // -// The subface and subsegment are also connected through pointers stored in // -// their own data fields. Every subface has a pointer ti its adjoining sub- // -// segment. However, a subsegment only has one pointer to a subface which is // -// containing it. Such subface can be choosn arbitrarily, other subfaces are // -// found through the face ring. // -// // -/////////////////////////////////////////////////////////////////////////////// - - // The tetrahedron data structure. Fields of a tetrahedron contains: - // - a list of four adjoining tetrahedra; - // - a list of four vertices; - // - a list of four subfaces (optional, used for -p switch); - // - a list of user-defined floating-point attributes (optional); - // - a volume constraint (optional, used for -a switch); - // - a pointer to a list of high-ordered nodes (optional, -o2 switch); - - typedef REAL **tetrahedron; - - // The shellface data structure. Fields of a shellface contains: - // - a list of three adjoining subfaces; - // - a list of three vertices; - // - a list of two adjoining tetrahedra; - // - a list of three adjoining subsegments; - // - a pointer to a badface containing it (optional, used for -q); - // - an area constraint (optional, used for -q); - // - an integer for boundary marker; - // - an integer for type: SHARPSEGMENT, NONSHARPSEGMENT, ...; - - typedef REAL **shellface; - - // The point data structure. It is actually an array of REALs: - // - x, y and z coordinates; - // - a list of user-defined point attributes (optional); - // - a pointer to a simplex (tet, tri, edge, or vertex); - // - a pointer to a parent point (optional, used for -q); - // - an integer for boundary marker; - // - an integer for verttype: INPUTVERTEX, FREEVERTEX, ...; - - typedef REAL *point; - -/////////////////////////////////////////////////////////////////////////////// -// // -// The mesh handle (triface, face) data types // -// // -// Two special data types, 'triface' and 'face' are defined for maintaining // -// and updating meshes. They are like pointers (or handles), which allow you // -// to hold one particular part of the mesh, i.e., a tetrahedron, a triangle, // -// an edge and a vertex. However, these data types do not themselves store // -// any part of the mesh. The mesh is made of the data types defined above. // -// // -// Muecke's "triangle-edge" data structure is the prototype for these data // -// types. It allows a universal representation for every tetrahedron, // -// triangle, edge and vertex. For understanding the following descriptions // -// of these handle data structures, readers are required to read both the // -// introduction and implementation detail of "triangle-edge" data structure // -// in Muecke's thesis. // -// // -// A 'triface' represents a face of a tetrahedron and an oriented edge of // -// the face simultaneously. It has a pointer 'tet' to a tetrahedron, an // -// integer 'loc' (range from 0 to 3) as the face index, and an integer 'ver' // -// (range from 0 to 5) as the edge version. A face of the tetrahedron can be // -// uniquly determined by the pair (tet, loc), and an oriented edge of this // -// face can be uniquly determined by the triple (tet, loc, ver). Therefore, // -// different usages of one triface are possible. If we only use the pair // -// (tet, loc), it refers to a face, and if we add the 'ver' additionally to // -// the pair, it is an oriented edge of this face. // -// // -// A 'face' represents a subface and an oriented edge of it simultaneously. // -// It has a pointer 'sh' to a subface, an integer 'shver'(range from 0 to 5) // -// as the edge version. The pair (sh, shver) determines a unique oriented // -// edge of this subface. A 'face' is also used to represent a subsegment, // -// in this case, 'sh' points to the subsegment, and 'shver' indicates the // -// one of two orientations of this subsegment, hence, it only can be 0 or 1. // -// // -// Mesh navigation and updating are accomplished through a set of mesh // -// manipulation primitives which operate on trifaces and faces. They are // -// introduced below. // -// // -/////////////////////////////////////////////////////////////////////////////// - - class triface { - - public: - - tetrahedron* tet; - int loc, ver; - - // Constructors; - triface() : tet(0), loc(0), ver(0) {} - // Operators; - triface& operator=(const triface& t) { - tet = t.tet; loc = t.loc; ver = t.ver; - return *this; - } - bool operator==(triface& t) { - return tet == t.tet && loc == t.loc && ver == t.ver; - } - bool operator!=(triface& t) { - return tet != t.tet || loc != t.loc || ver != t.ver; - } - }; - - class face { - - public: - - shellface *sh; - int shver; - - // Constructors; - face() : sh(0), shver(0) {} - // Operators; - face& operator=(const face& s) { - sh = s.sh; shver = s.shver; - return *this; - } - bool operator==(face& s) {return (sh == s.sh) && (shver == s.shver);} - bool operator!=(face& s) {return (sh != s.sh) || (shver != s.shver);} - }; - -/////////////////////////////////////////////////////////////////////////////// -// // -// The badface structure // -// // -// This structure has several usages in TetGen. A 'badface' can represent a // -// tetrahedron face possibly be non-locally Delaunay and will be flipped if // -// it is. A 'badface' can hold an encroached subsegment or subface needs to // -// be split in conforming Delaunay process. // -// // -// A badface has the following fields: 'tt' points to a tetrahedral face // -// which is possibly non-locally Delaunay. 'ss' points to an encroached // -// subsegment or subface. 'cent' is the diametric circumcent of the 'shface',// -// Three vertices 'forg', 'fdest' and 'fapex' are stored so that one can // -// check whether a face is still the same. 'prevface' and 'nextface' are // -// used to implement a double link for managing many badfaces. // -// // -/////////////////////////////////////////////////////////////////////////////// - - struct badface { - triface tt; - face ss; - REAL cent[3]; - point forg, fdest, fapex, foppo; - struct badface *prevface, *nextface; - }; - - // A queue structure used to store bad tetrahedra. Each tetrahedron's - // vertices are stored so that one can check whether a tetrahedron is - // still the same. - - struct badtetrahedron { - triface tet; // A bad tet. - REAL key; // radius-edge ratio^2. - REAL cent[3]; // The circumcenters' coordinates. - point tetorg, tetdest, tetapex, tetoppo; // The four vertices. - struct badtetrahedron *nexttet; // Pointer to next bad tet. - }; - - // A stack of faces flipped during the most recent vertex insertion. - // The stack is used to undo the point insertion if the point - // encroaches upon other subfaces or subsegments. - - struct flipstacker { - triface flippedface; // A recently flipped face. - enum fliptype fc; // The flipped type T23, T32, T22 or T44. - point forg, fdest, fapex; // The three vertices for checking. - struct flipstacker *prevflip; // Previous flip in the stack. - }; - -/////////////////////////////////////////////////////////////////////////////// -// // -// The list, link and queue data structures // -// // -// These data types are used to manipulate a set of (same-typed) data items. // -// For a given set S = {a, b, c, ...}, a list stores the elements of S in a // -// piece of continuous memory. It allows quickly accessing each element of S,// -// thus is suitable for storing a fix-sized set. While a link stores its // -// elements incontinuously. It allows quickly inserting or deleting one item,// -// thus is good for storing a size-changable set. A queue is basically a // -// special case of a link where one data element joins the link at the end // -// and leaves in an ordered fashion at the other end. // -// // -// These data types are all implemented with dynamic memory re-allocation. // -// // -/////////////////////////////////////////////////////////////////////////////// - - // The compfunc data type. "compfunc" is a pointer to a linear-order - // function, which takes two 'void*' arguments and returning an 'int'. - // - // A function: int cmp(const T &, const T &), is said to realize a - // linear order on the type T if there is a linear order <= on T such - // that for all x and y in T satisfy the following relation: - // -1 if x < y. - // comp(x, y) = 0 if x is equivalent to y. - // +1 if x > y. - typedef int (*compfunc) (const void *, const void *); - - // The predefined compare functions for primitive data types. They - // take two pointers of the corresponding date type, perform the - // comparation, and return -1, 0 or 1 indicating the default linear - // order of them. - - // Compare two 'integers'. - static int compare_2_ints(const void* x, const void* y); - // Compare two 'longs'. - static int compare_2_longs(const void* x, const void* y); - // Compare two 'unsigned longs'. - static int compare_2_unsignedlongs(const void* x, const void* y); - - // The function used to determine the size of primitive data types and - // set the corresponding predefined linear order functions for them. - static void set_compfunc(char* str, int* itembytes, compfunc* pcomp); - -/////////////////////////////////////////////////////////////////////////////// -// // -// List data structure. // -// // -// A 'list' is an array of items with automatically reallocation of memory. // -// It behaves like an array. // -// // -// 'base' is the starting address of the array; The memory unit in list is // -// byte, i.e., sizeof(char). 'itembytes' is the size of each item in byte, // -// so that the next item in list will be found at the next 'itembytes' // -// counted from the current position. // -// // -// 'items' is the number of items stored in list. 'maxitems' indicates how // -// many items can be stored in this list. 'expandsize' is the increasing // -// size (items) when the list is full. // -// // -// 'comp' is a pointer pointing to a linear order function for the list. // -// default it is set to 'NULL'. // -// // -// The index of list always starts from zero, i.e., for a list L contains // -// n elements, the first element is L[0], and the last element is L[n-1]. // -// This feature lets lists likes C/C++ arrays. // -// // -/////////////////////////////////////////////////////////////////////////////// - - class list { - - public: - - char *base; - int itembytes; - int items, maxitems, expandsize; - compfunc comp; - - public: - - list(int itbytes, compfunc pcomp, int mitems = 256, int exsize = 128) { - listinit(itbytes, pcomp, mitems, exsize); - } - list(char* str, int mitems = 256, int exsize = 128) { - set_compfunc(str, &itembytes, &comp); - listinit(itembytes, comp, mitems, exsize); - } - ~list() { free(base); } - - void *operator[](int i) { return (void *) (base + i * itembytes); } - - void listinit(int itbytes, compfunc pcomp, int mitems, int exsize); - void setcomp(compfunc compf) { comp = compf; } - void clear() { items = 0; } - int len() { return items; } - void *append(void* appitem); - void *insert(int pos, void* insitem); - void del(int pos); - int hasitem(void* checkitem); - int remove(void* remitem); - void sort(); - }; - -/////////////////////////////////////////////////////////////////////////////// -// // -// Memorypool data structure. // -// // -// A type used to allocate memory. (It is incorporated from Shewchuk's // -// Triangle program) // -// // -// firstblock is the first block of items. nowblock is the block from which // -// items are currently being allocated. nextitem points to the next slab // -// of free memory for an item. deaditemstack is the head of a linked list // -// (stack) of deallocated items that can be recycled. unallocateditems is // -// the number of items that remain to be allocated from nowblock. // -// // -// Traversal is the process of walking through the entire list of items, and // -// is separate from allocation. Note that a traversal will visit items on // -// the "deaditemstack" stack as well as live items. pathblock points to // -// the block currently being traversed. pathitem points to the next item // -// to be traversed. pathitemsleft is the number of items that remain to // -// be traversed in pathblock. // -// // -// itemwordtype is set to POINTER or FLOATINGPOINT, and is used to suggest // -// what sort of word the record is primarily made up of. alignbytes // -// determines how new records should be aligned in memory. itembytes and // -// itemwords are the length of a record in bytes (after rounding up) and // -// words. itemsperblock is the number of items allocated at once in a // -// single block. items is the number of currently allocated items. // -// maxitems is the maximum number of items that have been allocated at // -// once; it is the current number of items plus the number of records kept // -// on deaditemstack. // -// // -/////////////////////////////////////////////////////////////////////////////// - - class memorypool { - - public: - - void **firstblock, **nowblock; - void *nextitem; - void *deaditemstack; - void **pathblock; - void *pathitem; - wordtype itemwordtype; - int alignbytes; - int itembytes, itemwords; - int itemsperblock; - long items, maxitems; - int unallocateditems; - int pathitemsleft; - - public: - - memorypool(); - memorypool(int, int, enum wordtype, int); - ~memorypool(); - - void poolinit(int, int, enum wordtype, int); - void restart(); - void *alloc(); - void dealloc(void*); - void traversalinit(); - void *traverse(); - }; - -/////////////////////////////////////////////////////////////////////////////// -// // -// Link data structure. // -// // -// A 'link' is a double linked nodes. It uses the memorypool data structure // -// for memory management. Following is an image of a link. // -// // -// head-> ____0____ ____1____ ____2____ _________<-tail // -// |__next___|--> |__next___|--> |__next___|--> |__NULL___| // -// |__NULL___|<-- |__prev___|<-- |__prev___|<-- |__prev___| // -// | | |_ _| |_ _| | | // -// | | |_ Data1 _| |_ Data2 _| | | // -// |_________| |_________| |_________| |_________| // -// // -// The unit size for storage is size of pointer, which may be 4-byte (in 32- // -// bit machine) or 8-byte (in 64-bit machine). The real size of an item is // -// stored in 'linkitembytes'. // -// // -// 'head' and 'tail' are pointers pointing to the first and last nodes. They // -// do not conatin data (See above). // -// // -// 'nextlinkitem' is a pointer pointing to a node which is the next one will // -// be traversed. 'curpos' remembers the position (1-based) of the current // -// traversing node. // -// // -// 'linkitems' indicates how many items in link. Note it is different with // -// 'items' of memorypool. // -// // -// The index of link starts from 1, i.e., for a link K contains n elements, // -// the first element of the link is K[1], and the last element is K[n]. // -// See the above figure. // -// // -/////////////////////////////////////////////////////////////////////////////// - - class link : public memorypool { - - public: - - void **head, **tail; - void *nextlinkitem; - int linkitembytes; - int linkitems; - int curpos; - compfunc comp; - - public: - - link(int _itembytes, compfunc _comp, int itemcount) { - linkinit(_itembytes, _comp, itemcount); - } - link(char* str, int itemcount) { - set_compfunc(str, &linkitembytes, &comp); - linkinit(linkitembytes, comp, itemcount); - } - - void linkinit(int _itembytes, compfunc _comp, int itemcount); - void setcomp(compfunc compf) { comp = compf; } - void rewind() { nextlinkitem = *head; curpos = 1; } - void goend() { nextlinkitem = *(tail + 1); curpos = linkitems; } - long len() { return linkitems; } - void clear(); - bool move(int numberofnodes); - bool locate(int pos); - void *add(void* newitem); - void *insert(int pos, void* insitem); - void *del(void* delitem); - void *del(int pos); - void *getitem(); - void *getnitem(int pos); - int hasitem(void* checkitem); - }; - -/////////////////////////////////////////////////////////////////////////////// -// // -// Queue data structure. // -// // -// A 'queue' is a basically a link. Following is an image of a queue. // -// ___________ ___________ ___________ // -// Pop() <-- |_ _|<--|_ _|<--|_ _| <-- Push() // -// |_ Data0 _| |_ Data1 _| |_ Data2 _| // -// |___________| |___________| |___________| // -// queue head queue tail // -// // -/////////////////////////////////////////////////////////////////////////////// - - class queue : public link { - - public: - - queue(int bytes, int count = 256) : link(bytes, NULL, count) {} - queue(char* str, int count = 256) : link(str, count) {} - - int empty() { return linkitems == 0; } - void *push(void* newitem) { return link::add(newitem); } - void *bot() { return link::getnitem(1); } - void *pop() { return link::del(1); } - }; - -/////////////////////////////////////////////////////////////////////////////// -// // -// Following are variables used in 'tetgenmesh' for miscellaneous purposes. // -// // -/////////////////////////////////////////////////////////////////////////////// - - // Pointer to an object of 'tetgenio', which contains input data. - tetgenio *in; - - // Pointer to an object of 'tetgenbehavor', which contains the user- - // defined command line swithes and filenames. - tetgenbehavior *b; - - // Variables used to allocate and access memory for tetrahedra, subfaces - // subsegments, points, encroached subfaces, encroached subsegments, - // bad-quality tetrahedra, and so on. - memorypool *tetrahedrons; - memorypool *subfaces; - memorypool *subsegs; - memorypool *points; - memorypool *badsubsegs; - memorypool *badsubfaces; - memorypool *badtetrahedrons; - memorypool *flipstackers; - - // Pointer to a recently visited tetrahedron. Improves point location - // if proximate points are inserted sequentially. - triface recenttet; - - // Pointer to the 'tetrahedron' that occupies all of "outer space". - tetrahedron *dummytet; - tetrahedron *dummytetbase; // Keep base address so we can free it later. - - // Pointer to the omnipresent subface. Referenced by any tetrahedron, - // or subface that isn't connected to a subface at that location. - shellface *dummysh; - shellface *dummyshbase; // Keep base address so we can free it later. - - // List of lifting points of facets used for surface triangulation. - REAL *liftpointarray; - - // List used for Delaunay refinement algorithm. - list *qualchecktetlist; - - // Queues that maintain the bad (badly-shaped or too large) tetrahedra. - // The tails are pointers to the pointers that have to be filled in to - // enqueue an item. The queues are ordered from 63 (highest priority) - // to 0 (lowest priority). - badface *subquefront[2], **subquetail[2]; - badtetrahedron *tetquefront[64], **tetquetail[64]; - - // Array (size = numberoftetrahedra * 6) for storing high-order nodes of - // tetrahedra (only used when -o2 switch is selected). - point *highordertable; - - REAL xmax, xmin, ymax, ymin, zmax, zmin; // Bounding box of points. - REAL longest; // The longest possible edge length. - long hullsize; // Number of faces of convex hull. - long insegment; // Number of input segments. - int steinerleft; // Number of Steiner points not yet used. - int pointmarkindex; // Index to find boundary marker of a point. - int point2simindex; // Index to find a simplex adjacent to a point. - int highorderindex; // Index to find extra nodes for highorder elements. - int elemattribindex; // Index to find attributes of a tetrahedron. - int volumeboundindex; // Index to find volume bound of a tetrahedron. - int shmarkindex; // Index to find boundary marker of a subface. - int areaboundindex; // Index to find area bound of a subface. - int checksubfaces; // Are there subfaces in the mesh yet? - int checkquality; // Has quality triangulation begun yet? - int nonconvex; // Is current mesh non-convex? - int dupverts; // Are there duplicated vertices? - long samples; // Number of random samples for point location. - unsigned long randomseed; // Current random number seed. - REAL macheps; // The machine epsilon. - long flip23s, flip32s, flip22s, flip44s; // Number of flips performed. - -/////////////////////////////////////////////////////////////////////////////// -// // -// Fast lookup tables for mesh manipulation primitives. // -// // -// Mesh manipulation primitives (given below) are basic operations on mesh // -// data structures. They answer basic queries on mesh handles, such as "what // -// is the origin (or destination, or apex) of the face?", "what is the next // -// (or previous) edge in the edge ring?", and "what is the next face in the // -// face ring?", and so on. // -// // -// The implementation of basic queries can take advangtage of the fact that // -// the mesh data structures additionally store geometric informations. For // -// example, we have ordered the four vertices (from 0 to 3) and four faces // -// (from 0 to 3) of a tetrahedron, and for each face of the tetrahedron, a // -// sequence of vertices has stipulated, therefore the origin of any face of // -// the tetrahedron can be quickly determined by a table 'locver2org', which // -// takes the index of the face and the edge version as inputs. A list of // -// fast lookup tables are defined below. They're just like global variables. // -// All tables are initialized once at the runtime and used by all objects of // -// tetgenmesh. // -// // -/////////////////////////////////////////////////////////////////////////////// - - // For enext() primitive, uses 'ver' as the index. - static int ve[6]; - - // For org(), dest() and apex() primitives, uses 'ver' as the index. - static int vo[6], vd[6], va[6]; - - // For org(), dest() and apex() primitives, uses 'loc' as the first - // index and 'ver' as the second index. - static int locver2org[4][6]; - static int locver2dest[4][6]; - static int locver2apex[4][6]; - - // For oppo() primitives, uses 'loc' as the index. - static int loc2oppo[4]; - - // For fnext() primitives, uses 'loc' as the first index and 'ver' as - // the second index, returns an array containing a new 'loc' and a - // new 'ver'. Note: Only valid for 'ver' equals one of {0, 2, 4}. - static int locver2nextf[4][6][2]; - - // For enumerating three edges of a triangle. - static int plus1mod3[3]; - static int minus1mod3[3]; - -/////////////////////////////////////////////////////////////////////////////// -// // -// Mesh manipulation primitives // -// // -// A serial of mesh operations such as topological maintenance, navigation, // -// local modification, etc., is accomplished through a set of mesh manipul- // -// ation primitives. These primitives are indeed very simple functions which // -// take one or two handles ('triface's and 'face's) as parameters, perform // -// basic operations such as "glue two tetrahedra at a face", "return the // -// origin of a tetrahedron", "return the subface adjoining at the face of a // -// tetrahedron", and so on. // -// // -// In the following, symbols t, t1, and t2 denote handles of type 'triface', // -// i.e., t is a face of a tetrahedron. Likewise, handles of type 'face' are // -// denoted by s, s1, s2; e denotes an oriented edge, and v denotes a vertex. // -// // -// The basic primitives for tetrahedra are: // -// // -// sym(t1, t2) t1 and t2 refer to the same face but point to two // -// different tetrahedra respectively. // -// bond(t1, t2) Bonds t1 and t2 together. t1 and t2 should refer to // -// the same face. // -// dissolve(t) Detaches the adjoining tetrahedron from t. t bonds to // -// 'dummytet' after this operation. // -// // -// v = org(t) v is the origin of t. // -// v = dest(t) v is the destination of t. // -// v = apex(t) v is the apex of t. // -// v = oppo(t) v is the opposite of t. // -// // -// esym(t1, t2) t2 is the inversed edge of t1, i.e., t1 and t2 are two // -// directed edges of the same undirected edge. // -// enext(t1, t2) t2 is the successor of t1 in the edge ring. // -// enext2(t1, t2) t2 is the precessor of t1 in the edge ring. // -// // -// fnext(t1, t2) t2 is the successor of t1 in the face ring. // -// // -// The basic primitives for subfaces (as well as subsegments) are: // -// // -// spivot(s1, s2) s1 and s2 refer to the same edge but point to two // -// different subfaces respectively. // -// sbond(s1, s2) Bonds s1 and s2 together (at an edge). // -// sbond1(s1, s2) Only bonds s2 to s1 (but not s1 to s2). It is used // -// for creating the face ring. // -// sdissolve(s) Detaches the adjoining subface from s. s bonds to // -// 'dummysh' after this operation. // -// // -// v = sorg(s) v is the origin of s. // -// v = sdest(s) v is the destination of s. // -// v = sapex(s) v is the apex of s. // -// // -// sesym(s1, s2) s2 is the inversed edge of s1. // -// senext(s1, s2) s2 is the successor of s1 in the edge ring. // -// senext2(s1, s2) s2 is the precessor of s1 in the edge ring.. // -// // -// For interacting tetrahedra and subfaces: // -// // -// tspivot(t, s) Returns the adjoining subface of t in s. s may hold // -// 'dummysh' when t is an internal face. // -// stpivot(s, t) Returns the adjoining tetrahedron of s in t. t may be // -// 'dummytet'. // -// tsbond(t, s) Bond t and s together. t and s must represent the // -// same face. // -// tsdissolve(t) Detaches the adjoining subface from t. // -// stdissolve(s) Detaches the adjoining tetrahedron from s. // -// // -// For interacting subfaces and subsegments: // -// // -// sspivot(s, e) Returns the adjoining subsegment of s in e. // -// ssbond(s, e) Bond s and e together. s and e must represent the // -// same edge. // -// ssdissolve(s) Detaches the adjoining subsegment from s. // -// // -/////////////////////////////////////////////////////////////////////////////// - - // Primitives for tetrahedra. - inline void decode(tetrahedron ptr, triface& t); - inline tetrahedron encode(triface& t); - inline void sym(triface& t1, triface& t2); - inline void symself(triface& t); - inline void bond(triface& t1, triface& t2); - inline void dissolve(triface& t); - inline point org(triface& t); - inline point dest(triface& t); - inline point apex(triface& t); - inline point oppo(triface& t); - inline void setorg(triface& t, point pointptr); - inline void setdest(triface& t, point pointptr); - inline void setapex(triface& t, point pointptr); - inline void setoppo(triface& t, point pointptr); - inline void esym(triface& t1, triface& t2); - inline void esymself(triface& t); - inline void enext(triface& t1, triface& t2); - inline void enextself(triface& t); - inline void enext2(triface& t1, triface& t2); - inline void enext2self(triface& t); - inline bool fnext(triface& t1, triface& t2); - inline bool fnextself(triface& t); - inline void enextfnext(triface& t1, triface& t2); - inline void enextfnextself(triface& t); - inline void enext2fnext(triface& t1, triface& t2); - inline void enext2fnextself(triface& t); - inline void infect(triface& t); - inline void uninfect(triface& t); - inline bool infected(triface& t); - inline REAL elemattribute(tetrahedron* ptr, int attnum); - inline void setelemattribute(tetrahedron* ptr, int attnum, REAL value); - inline REAL volumebound(tetrahedron* ptr); - inline void setvolumebound(tetrahedron* ptr, REAL value); - - // Primitives for subfaces and subsegments. - inline void sdecode(shellface sptr, face& s); - inline shellface sencode(face& s); - inline void spivot(face& s1, face& s2); - inline void spivotself(face& s); - inline void sbond(face& s1, face& s2); - inline void sbond1(face& s1, face& s2); - inline void sdissolve(face& s); - inline point sorg(face& s); - inline point sdest(face& s); - inline point sapex(face& s); - inline void setsorg(face& s, point pointptr); - inline void setsdest(face& s, point pointptr); - inline void setsapex(face& s, point pointptr); - inline void sesym(face& s1, face& s2); - inline void sesymself(face& s); - inline void senext(face& s1, face& s2); - inline void senextself(face& s); - inline void senext2(face& s1, face& s2); - inline void senext2self(face& s); - inline void sfnext(face&, face&); - inline void sfnextself(face&); - inline badface* shell2badface(face& s); - inline void setshell2badface(face& s, badface* value); - inline REAL areabound(face& s); - inline void setareabound(face& s, REAL value); - inline int shellmark(face& s); - inline void setshellmark(face& s, int value); - inline enum shestype shelltype(face& s); - inline void setshelltype(face& s, enum shestype value); - inline void sinfect(face& s); - inline void suninfect(face& s); - inline bool sinfected(face& s); - - // Primitives for interacting tetrahedra and subfaces. - inline void tspivot(triface& t, face& s); - inline void stpivot(face& s, triface& t); - inline void tsbond(triface& t, face& s); - inline void tsdissolve(triface& t); - inline void stdissolve(face& s); - - // Primitives for interacting subfaces and subsegs. - inline void sspivot(face& s, face& edge); - inline void ssbond(face& s, face& edge); - inline void ssdissolve(face& s); - - // Primitives for points. - inline int pointmark(point pt); - inline void setpointmark(point pt, int value); - inline enum verttype pointtype(point pt); - inline void setpointtype(point pt, enum verttype value); - inline tetrahedron point2tet(point pt); - inline void setpoint2tet(point pt, tetrahedron value); - inline shellface point2sh(point pt); - inline void setpoint2sh(point pt, shellface value); - inline point point2pt(point pt); - inline void setpoint2pt(point pt, point value); - inline point point2ppt(point pt); - inline void setpoint2ppt(point pt, point value); - inline point getliftpoint(int facetmark); - - // Advanced primitives. - inline void adjustedgering(triface& t, int direction); - inline void adjustedgering(face& s, int direction); - inline bool isdead(triface* t); - inline bool isdead(face* s); - inline bool isfacehaspoint(face* t, point testpoint); - inline bool isfacehasedge(face* s, point tend1, point tend2); - inline bool issymexist(triface* t); - bool getnextface(triface*, triface*); - void getnextsface(face*, face*); - void tsspivot(triface*, face*); - void sstpivot(face*, triface*); - bool findorg(triface* t, point dorg); - bool findorg(face* s, point dorg); - void findedge(triface* t, point eorg, point edest); - void findedge(face* s, point eorg, point edest); - void findface(triface *fface, point forg, point fdest, point fapex); - void getonextseg(face* s, face* lseg); - void getseghasorg(face* sseg, point dorg); - point getsubsegfarorg(face* sseg); - point getsubsegfardest(face* sseg); - void printtet(triface*); - void printsh(face*); - -/////////////////////////////////////////////////////////////////////////////// -// // -// Primitive geometric test functions // -// // -// A primitive operation is a function f that maps a set Q of k objects to // -// +1, 0, or -1. Primitive geometric functions operater on geometric objects // -// (points, segments, triangles, polyhedron, etc), determine the geometric // -// relations between them. Like the orientation of a sequence of d+1 points // -// in d-dimension, whether or not a point lies inside a triangle, and so on. // -// Algorithms for solving geometric problems are always based on the answers // -// of some primitives so that the corresponding deterministic rules can be // -// applied. However, the implementation of geometric algorithms is not a // -// trivial task even for one which is very simple and only relies on few // -// primitives. The correctness of primitives is crucial for the cotrol flow. // -// // -// The following functions perform various primitives geometric tests, some // -// perform tests with exact arithmetic and some do not. // -// // -// The triangle-triangle intersection test is implemented with exact arithm- // -// etic. It exactly tells whether or not two triangles in three dimensions // -// intersect. Before implementing this test myself, I tried two C codes // -// (implemented by Thomas Moeller and Philippe Guigue, respectively), which // -// are all public available and very efficient. However both of them failed // -// frequently. Another unsuitable problem is that both codes only tell // -// whether or not two triangles are intersecting and not distinguish the // -// cases whether they are exactly intersecting in interior or they share a // -// vertex, or share an edge. All the latter cases are acceptable and should // -// return not intersection in TetGen. // -// // -/////////////////////////////////////////////////////////////////////////////// - - // Triangle-triangle intersection tests - enum intersectresult edge_vertex_collinear_inter(REAL*, REAL*, REAL*); - enum intersectresult edge_edge_coplanar_inter(REAL*, REAL*, REAL*, - REAL*, REAL*); - enum intersectresult triangle_vertex_coplanar_inter(REAL*, REAL*, REAL*, - REAL*, REAL*); - enum intersectresult triangle_edge_coplanar_inter(REAL*, REAL*, REAL*, - REAL*, REAL*, REAL*); - enum intersectresult triangle_edge_inter_tail(REAL*, REAL*, REAL*, REAL*, - REAL*, REAL, REAL); - enum intersectresult triangle_edge_inter(REAL*, REAL*, REAL*, REAL*, - REAL*); - enum intersectresult triangle_triangle_inter(REAL*, REAL*, REAL*, REAL*, - REAL*, REAL*); - - // Degenerate cases tests - bool iscollinear(REAL*, REAL*, REAL*, REAL epspp); - bool iscoplanar(REAL*, REAL*, REAL*, REAL*, REAL vol6, REAL epspp); - bool iscospheric(REAL*, REAL*, REAL*, REAL*, REAL*, REAL epspp); - - // Linear algebra functions - inline REAL dot(REAL* v1, REAL* v2); - inline void cross(REAL* v1, REAL* v2, REAL* n); - void initm44(REAL a00, REAL a01, REAL a02, REAL a03, - REAL a10, REAL a11, REAL a12, REAL a13, - REAL a20, REAL a21, REAL a22, REAL a23, - REAL a30, REAL a31, REAL a32, REAL a33, REAL M[4][4]); - void m4xm4(REAL m1[4][4], REAL m2[4][4]); - void m4xv4(REAL v2[4], REAL m[4][4], REAL v1[4]); - bool lu_decmp(REAL lu[3][3], int n, int* ps, REAL* d, int N); - void lu_solve(REAL lu[3][3], int n, int* ps, REAL* b, int N); - - // Geometric quantities calculators. - inline REAL distance(REAL* p1, REAL* p2); - REAL shortdistance(REAL* p, REAL* e1, REAL* e2); - REAL interiorangle(REAL* o, REAL* p1, REAL* p2, REAL* n); - void projpt2edge(REAL* p, REAL* e1, REAL* e2, REAL* prj); - void projpt2face(REAL* p, REAL* f1, REAL* f2, REAL* f3, REAL* prj); - void facenormal(REAL* pa, REAL* pb, REAL* pc, REAL* n, REAL* nlen); - void edgeorthonormal(REAL* e1, REAL* e2, REAL* op, REAL* n); - REAL facedihedral(REAL* pa, REAL* pb, REAL* pc1, REAL* pc2); - void tetalldihedral(point, point, point, point, REAL dihed[6]); - bool circumsphere(REAL*, REAL*, REAL*, REAL*, REAL* cent, REAL* radius); - void inscribedsphere(REAL*, REAL*, REAL*, REAL*, REAL* cent, REAL* radius); - void rotatepoint(REAL* p, REAL rotangle, REAL* p1, REAL* p2); - void spherelineint(REAL* p1, REAL* p2, REAL* C, REAL R, REAL p[7]); - void linelineint(REAL *p1,REAL *p2, REAL *p3, REAL *p4, REAL p[7]); - - // Memory managment routines. - void dummyinit(int, int); - void initializepointpool(); - void initializetetshpools(); - void tetrahedrondealloc(tetrahedron*); - tetrahedron *tetrahedrontraverse(); - void shellfacedealloc(memorypool*, shellface*); - shellface *shellfacetraverse(memorypool*); - void badfacedealloc(memorypool*, badface*); - badface *badfacetraverse(memorypool*); - void pointdealloc(point); - point pointtraverse(); - void maketetrahedron(triface*); - void makeshellface(memorypool*, face*); - void makepoint(point*); - - // Mesh items searching routines. - void makepoint2tetmap(); - void makeindex2pointmap(point*& idx2verlist); - void makesegmentmap(int*& idx2seglist, shellface**& segsperverlist); - void makesubfacemap(int*& idx2facelist, shellface**& facesperverlist); - void maketetrahedronmap(int*& idx2tetlist, tetrahedron**& tetsperverlist); - - // Point location routines. - unsigned long randomnation(unsigned int choices); - REAL distance2(tetrahedron* tetptr, point p); - enum locateresult preciselocate(point searchpoint, triface* searchtet); - enum locateresult locate(point searchpoint, triface* searchtet); - enum locateresult adjustlocate(point searchpoint, triface* searchtet, - enum locateresult precise, REAL epspp); - - // Mesh transformation routines. - enum fliptype categorizeface(triface& horiz); - void enqueueflipface(triface& checkface, queue* flipqueue); - void enqueueflipedge(face& checkedge, queue* flipqueue); - void flip23(triface* flipface, queue* flipqueue); - void flip32(triface* flipface, queue* flipqueue); - void flip22(triface* flipface, queue* flipqueue); - void flip22sub(face* flipedge, queue* flipqueue); - long flip(queue* flipqueue, flipstacker **plastflip); - void undoflip(flipstacker *lastflip); - - void splittetrahedron(point newpoint, triface* splittet, queue* flipqueue); - void unsplittetrahedron(triface* splittet); - void splittetface(point newpoint, triface* splittet, queue* flipqueue); - void unsplittetface(triface* splittet); - void splitsubface(point newpoint, face* splitface, queue* flipqueue); - void unsplitsubface(face* splitsh); - void splittetedge(point newpoint, triface* splittet, queue* flipqueue); - void unsplittetedge(triface* splittet); - void splitsubedge(point newpoint, face* splitsh, queue* flipqueue); - void unsplitsubedge(face* splitsh); - enum insertsiteresult insertsite(point newpoint, triface* searchtet, - bool approx, queue* flipqueue); - void undosite(enum insertsiteresult insresult, triface* splittet, - point torg, point tdest, point tapex, point toppo); - void inserthullsite(point inspoint, triface* horiz, queue* flipqueue, - link* hulllink, int* worklist); - void collectcavtets(point newpoint, list* cavtetlist); - - void removetetbypeeloff(triface *badtet, queue* flipqueue); - void removetetbyflip32(triface *badtet, queue* flipqueue); - bool removetetbycflips(triface *badtet, queue* flipqueue); - bool removebadtet(enum badtettype bt, triface *badtet, queue* flipqueue); - - // Incremental flip Delaunay triangulation routines. - void incrflipinit(queue* insertqueue); - long incrflipdelaunay(); - - // Surface triangulation routines. - enum locateresult locatesub(point searchpt, face* searchsh, point abovept); - long flipsub(queue* flipqueue); - bool incrflipinitsub(int facetidx, list* ptlist, point* idx2verlist); - void collectvisiblesubs(int facetidx, point inspoint, face* horiz, - queue* flipqueue); - void incrflipdelaunaysub(int facetidx, list* ptlist, point* idx2verlist, - queue* flipqueue); - enum finddirectionresult finddirectionsub(face* searchsh, point tend); - void insertsubseg(face* tri); - bool scoutsegmentsub(face* searchsh, point tend); - void delaunayfixup(face* fixupsh, int leftside); - void constrainededge(face* startsh, point tend); - void insertsegmentsub(point tstart, point tend); - void infecthullsub(memorypool* viri); - void plaguesub(memorypool* viri); - void carveholessub(int holes, REAL* holelist); - void triangulatefacet(int facetidx, list* ptlist, list* conlist, - point* idx2verlist, queue* flipqueue); - void unifysegments(); - void mergefacets(queue* flipqueue); - long meshsurface(); - - // Detect intersecting facets of PLC. - void interecursive(shellface** subfacearray, int arraysize, int axis, - REAL bxmin, REAL bxmax, REAL bymin, REAL bymax, - REAL bzmin, REAL bzmax, int* internum); - void detectinterfaces(); - - // Segments recovery routines. - void markacutevertices(REAL acuteangle); - enum finddirectionresult finddirection(triface* searchtet, point tend); - void getsearchtet(point p1, point p2, triface* searchtet, point* tend); - bool isedgeencroached(point p1, point p2, point testpt, bool degflag); - point scoutrefpoint(triface* searchtet, point tend); - point getsegmentorigin(face* splitseg); - point getsplitpoint(face* splitseg, point refpoint); - void delaunizesegments(); - - // Constrained Delaunay triangulation routines. - bool insertsubface(face* insertsh, triface* searchtet); - bool tritritest(triface* checktet, point p1, point p2, point p3); - void initializecavity(list* floorlist, list* ceillist, list* floorptlist, - list* ceilptlist, link* frontlink, link* ptlink); - bool reducecavity(link* frontlink, link* ptlink, queue* flipqueue); - bool reducecavity1(link* frontlink, queue* flipqueue); - void triangulatecavity(list* floorlist, list* ceillist, list* floorptlist, - list* ceilptlist); - void formmissingregion(face* missingsh, list* missingshlist, - list* equatptlist, int* worklist); - bool scoutcrossingedge(list* missingshlist, list* boundedgelist, - list* crossedgelist, int* worklist); - void rearrangesubfaces(list* missingshlist, list* boundedgelist, - list* equatptlist, int* worklist); - void recoversubfaces(list* missingshlist, list* crossedgelist, - list* equatptlist, int* worklist); - void constrainedfacets(); - - // Carving out holes and concavities routines. - void indenthull(); - void infecthull(memorypool *viri); - void plague(memorypool *viri); - void regionplague(memorypool *viri, REAL attribute, REAL volume); - void carveholes(); - - // Mesh update rotuines. - long reconstructmesh(); - void insertaddpoints(); - - // Delaunay refinement routines. - void initializerpsarray(REAL* rpsarray); - void marksharpfacets(int*& idx2facetlist, REAL dihedbound); - void enqueuebadtet(triface *instet, REAL ratio, point insorg, - point insdest, point insapex, point insoppo, - point inscent); - badtetrahedron* dequeuebadtet(); - bool checkseg4encroach(face* testseg, point testpt, bool enqueueflag); - bool checksub4encroach(face* testsub, point testpt, bool enqueueflag); - bool checksub4badqual(face* testsub); - bool checktet4badqual(triface* testtet); - bool checktet4illtet(triface* testtet, list* illtetlist); - bool checktet4sliver(triface* testtet, list* illtetlist); - bool checkseg4splitting(face* testseg, REAL* rpsarray, bool bqual); - bool checksub4splitting(face* testsub); - void doqualchecktetlist(); - bool tallencsegs(point testpt, list *cavtetlist); - bool tallencsubs(point testpt, list *cavtetlist); - void tallbadtetrahedrons(); - void tallilltets(list* illtetlist); - void tallslivers(list* illtetlist); - void removeilltets(); - void removeslivers(); - void repairencsegs(REAL* rpsarray, bool bqual, queue* flipqueue); - void repairencsubs(REAL* rpsarray, int* idx2facetlist, list* cavtetlist, - queue* flipqueue); - void repairbadtets(REAL* rpsarray, int* idx2facetlist, list* cavtetlist, - queue* flipqueue); - void enforcequality(); - - // I/O routines - void transfernodes(); - void jettisonnodes(); - void highorder(); - void outnodes(tetgenio* out); - void outelements(tetgenio* out); - void outfaces(tetgenio* out); - void outhullfaces(tetgenio* out); - void outsubfaces(tetgenio* out); - void outsubsegments(tetgenio* out); - void outneighbors(tetgenio* out); - void outsmesh(char* smfilename); - void outmesh2medit(char* mfilename); - void outmesh2gid(char* gfilename); - void outmesh2off(char* ofilename); - - // User interaction routines. - void internalerror(); - void checkmesh(); - void checkshells(); - void checkdelaunay(queue* flipqueue); - void checkconforming(); - void qualitystatistics(); - void statistics(); - - public: - - // Constructor and destructor. - tetgenmesh(); - ~tetgenmesh(); - -}; // End of class tetgenmesh. - -/////////////////////////////////////////////////////////////////////////////// -// // -// tetrahedralize() Interface for using TetGen's library to generate // -// Delaunay tetrahedralizations, constrained Delaunay // -// tetrahedralizations, quality tetrahedral meshes. // -// // -// Two functions (interfaces) are available. The difference is only the way // -// of passing switches. One directly accepts an object of 'tetgenbehavior', // -// the other accepts a string which is the same as one can used in command // -// line. The latter may be more convenient for users who don't know the // -// 'tetgenbehavir' structure. // -// // -// 'in' is the input object containing a PLC or a list of points. It should // -// not be a NULL. 'out' is for outputting the mesh or tetrahedralization // -// created by TetGen. If it is NULL, the output will be redirect to file(s). // -// // -/////////////////////////////////////////////////////////////////////////////// - -void tetrahedralize(tetgenbehavior *b, tetgenio *in, tetgenio *out); -void tetrahedralize(char *switches, tetgenio *in, tetgenio *out); - -#endif // #ifndef tetgenH diff --git a/Triangle/Makefile b/Triangle/Makefile deleted file mode 100644 index 789eb0790a..0000000000 --- a/Triangle/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# $Id: Makefile,v 1.18 2005-01-01 19:35:39 geuzaine Exp $ -# -# Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -# USA. -# -# Please report all bugs and problems to <gmsh@geuz.org>. - -include ../variables - -LIB = ../lib/libGmshTriangle.a - -# Don't optimize triangle: it crashes on Linux -# CFLAGS = ${OPTIM} ${FLAGS} -DTRILIBRARY -CFLAGS = ${FLAGS} -DTRILIBRARY - -SRC = triangle.c - -OBJ = ${SRC:.c=.o} - -.SUFFIXES: .o .c - -${LIB}: ${OBJ} - ${AR} ${LIB} ${OBJ} - ${RANLIB} ${LIB} - -.c.o: - ${CC} ${CFLAGS} -c $< - -clean: - rm -f *.o - -depend: - (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \ - ${CC} -MM ${CFLAGS} ${SRC} \ - ) >Makefile.new - cp Makefile Makefile.bak - cp Makefile.new Makefile - rm -f Makefile.new - -# DO NOT DELETE THIS LINE -triangle.o: triangle.c triangle.h diff --git a/Triangle/README b/Triangle/README deleted file mode 100644 index 8570b1e278..0000000000 --- a/Triangle/README +++ /dev/null @@ -1,74 +0,0 @@ - -If you want to use Jonathan Shewchuk's Triangle as an alternative -isotropic 2D mesh generator in Gmsh, please download Triangle from the -author's web site at http://www.cs.cmu.edu/~quake/triangle.html, -unpack the archive and copy the two files 'triangle.c' and -'triangle.h' in this directory. Then run configure and rebuild Gmsh. - -Please note that by doing so, you agree to Triangle's licensing -requirements (stated below). Most notably, you can only redistribute -Gmsh if no compensation is received. - -============================================================================== - -Triangle -A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. -Version 1.5 - -Copyright 1993, 1995, 1997, 1998, 2002, 2004 Jonathan Richard Shewchuk -2360 Woolsey #H -Berkeley, California 94705-1927 -Please send bugs and comments to jrs@cs.berkeley.edu - -Created as part of the Archimedes project (tools for parallel FEM). -Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship. -There is no warranty whatsoever. Use at your own risk. - - -Triangle generates exact Delaunay triangulations, constrained Delaunay -triangulations, Voronoi diagrams, and quality conforming Delaunay -triangulations. The latter can be generated with no small angles, and are -thus suitable for finite element analysis. Show Me graphically displays -the contents of the geometric files used by Triangle. Show Me can also -write images in PostScript form. - -Information on the algorithms used by Triangle, including complete -references, can be found in the comments at the beginning of the triangle.c -source file. Another listing of these references, with PostScript copies -of some of the papers, is available from the Web page - - http://www.cs.cmu.edu/~quake/triangle.research.html - ------------------------------------------------------------------------------- - -These programs may be freely redistributed under the condition that the -copyright notices (including the copy of this notice in the code comments -and the copyright notice printed when the `-h' switch is selected) are -not removed, and no compensation is received. Private, research, and -institutional use is free. You may distribute modified versions of this -code UNDER THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT -IN THE SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH -SOURCE AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND -CLEAR NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as -part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT -WITH THE AUTHOR. (If you are not directly supplying this code to a -customer, and you are instead telling them how they can obtain it for -free, then you are not required to make any arrangement with me.) - ------------------------------------------------------------------------------- - -If you use Triangle, and especially if you use it to accomplish real -work, I would like very much to hear from you. A short letter or email -(to jrs@cs.cmu.edu) describing how you use Triangle will mean a lot to -me. The more people I know are using this program, the more easily I can -justify spending time on improvements and on the three-dimensional -successor to Triangle, which in turn will benefit you. Also, I can put -you on a list to receive email whenever a new version of Triangle is -available. - -If you use a mesh generated by Triangle or plotted by Show Me in a -publication, please include an acknowledgment as well. - - -Jonathan Richard Shewchuk -April 27, 2004 diff --git a/Triangle/triangle.c b/Triangle/triangle.c deleted file mode 100644 index 203100baca..0000000000 --- a/Triangle/triangle.c +++ /dev/null @@ -1,16008 +0,0 @@ -/*****************************************************************************/ -/* */ -/* 888888888 ,o, / 888 */ -/* 888 88o88o " o8888o 88o8888o o88888o 888 o88888o */ -/* 888 888 888 88b 888 888 888 888 888 d888 88b */ -/* 888 888 888 o88^o888 888 888 "88888" 888 8888oo888 */ -/* 888 888 888 C888 888 888 888 / 888 q888 */ -/* 888 888 888 "88o^888 888 888 Cb 888 "88oooo" */ -/* "8oo8D */ -/* */ -/* A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. */ -/* (triangle.c) */ -/* */ -/* Version 1.5 */ -/* April 27, 2004 */ -/* */ -/* Copyright 1993, 1995, 1997, 1998, 2002, 2004 */ -/* Jonathan Richard Shewchuk */ -/* 2360 Woolsey #H */ -/* Berkeley, California 94705-1927 */ -/* jrs@cs.berkeley.edu */ -/* */ -/* This program may be freely redistributed under the condition that the */ -/* copyright notices (including this entire header and the copyright */ -/* notice printed when the `-h' switch is selected) are not removed, and */ -/* no compensation is received. Private, research, and institutional */ -/* use is free. You may distribute modified versions of this code UNDER */ -/* THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE */ -/* SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE */ -/* AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR */ -/* NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as */ -/* part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT */ -/* WITH THE AUTHOR. (If you are not directly supplying this code to a */ -/* customer, and you are instead telling them how they can obtain it for */ -/* free, then you are not required to make any arrangement with me.) */ -/* */ -/* Hypertext instructions for Triangle are available on the Web at */ -/* */ -/* http://www.cs.cmu.edu/~quake/triangle.html */ -/* */ -/* Some of the references listed below are marked with an asterisk. [*] */ -/* These references are available for downloading from the Web page */ -/* */ -/* http://www.cs.cmu.edu/~quake/triangle.research.html */ -/* */ -/* Three papers discussing aspects of Triangle are available. A short */ -/* overview appears in "Triangle: Engineering a 2D Quality Mesh */ -/* Generator and Delaunay Triangulator," in Applied Computational */ -/* Geometry: Towards Geometric Engineering, Ming C. Lin and Dinesh */ -/* Manocha, editors, Lecture Notes in Computer Science volume 1148, */ -/* pages 203-222, Springer-Verlag, Berlin, May 1996 (from the First ACM */ -/* Workshop on Applied Computational Geometry). [*] */ -/* */ -/* The algorithms are discussed in the greatest detail in "Delaunay */ -/* Refinement Algorithms for Triangular Mesh Generation," Computational */ -/* Geometry: Theory and Applications 22(1-3):21-74, May 2002. [*] */ -/* */ -/* More detail about the data structures may be found in my dissertation: */ -/* "Delaunay Refinement Mesh Generation," Ph.D. thesis, Technical Report */ -/* CMU-CS-97-137, School of Computer Science, Carnegie Mellon University, */ -/* Pittsburgh, Pennsylvania, 18 May 1997. [*] */ -/* */ -/* Triangle was created as part of the Archimedes project in the School of */ -/* Computer Science at Carnegie Mellon University. Archimedes is a */ -/* system for compiling parallel finite element solvers. For further */ -/* information, see Hesheng Bao, Jacobo Bielak, Omar Ghattas, Loukas F. */ -/* Kallivokas, David R. O'Hallaron, Jonathan R. Shewchuk, and Jifeng Xu, */ -/* "Large-scale Simulation of Elastic Wave Propagation in Heterogeneous */ -/* Media on Parallel Computers," Computer Methods in Applied Mechanics */ -/* and Engineering 152(1-2):85-102, 22 January 1998. */ -/* */ -/* Triangle's Delaunay refinement algorithm for quality mesh generation is */ -/* a hybrid of one due to Jim Ruppert, "A Delaunay Refinement Algorithm */ -/* for Quality 2-Dimensional Mesh Generation," Journal of Algorithms */ -/* 18(3):548-585, May 1995 [*], and one due to L. Paul Chew, "Guaranteed- */ -/* Quality Mesh Generation for Curved Surfaces," Proceedings of the Ninth */ -/* Annual Symposium on Computational Geometry (San Diego, California), */ -/* pages 274-280, Association for Computing Machinery, May 1993. */ -/* */ -/* The Delaunay refinement algorithm has been modified so that it */ -/* consistently meshes domains with small input angles, as described in */ -/* my lengthy journal article listed above, or in abbreviated form in */ -/* Jonathan Richard Shewchuk, "Mesh Generation for Domains with Small */ -/* Angles," Proceedings of the Sixteenth Annual Symposium on */ -/* Computational Geometry (Hong Kong), pages 1-10, Association for */ -/* Computing Machinery, June 2000. [*] */ -/* */ -/* My implementation of the divide-and-conquer and incremental Delaunay */ -/* triangulation algorithms follows closely the presentation of Guibas */ -/* and Stolfi, even though I use a triangle-based data structure instead */ -/* of their quad-edge data structure. (In fact, I originally implemented */ -/* Triangle using the quad-edge data structure, but the switch to a */ -/* triangle-based data structure sped Triangle by a factor of two.) The */ -/* mesh manipulation primitives and the two aforementioned Delaunay */ -/* triangulation algorithms are described by Leonidas J. Guibas and Jorge */ -/* Stolfi, "Primitives for the Manipulation of General Subdivisions and */ -/* the Computation of Voronoi Diagrams," ACM Transactions on Graphics */ -/* 4(2):74-123, April 1985. */ -/* */ -/* Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai */ -/* Lee and Bruce J. Schachter, "Two Algorithms for Constructing the */ -/* Delaunay Triangulation," International Journal of Computer and */ -/* Information Science 9(3):219-242, 1980. Triangle's improvement of the */ -/* divide-and-conquer algorithm by alternating between vertical and */ -/* horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and- */ -/* Conquer Algorithm for Constructing Delaunay Triangulations," */ -/* Algorithmica 2(2):137-151, 1987. */ -/* */ -/* The incremental insertion algorithm was first proposed by C. L. Lawson, */ -/* "Software for C1 Surface Interpolation," in Mathematical Software III, */ -/* John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977. */ -/* For point location, I use the algorithm of Ernst P. Mucke, Isaac */ -/* Saias, and Binhai Zhu, "Fast Randomized Point Location Without */ -/* Preprocessing in Two- and Three-Dimensional Delaunay Triangulations," */ -/* Proceedings of the Twelfth Annual Symposium on Computational Geometry, */ -/* ACM, May 1996. [*] If I were to randomize the order of vertex */ -/* insertion (I currently don't bother), their result combined with the */ -/* result of Kenneth L. Clarkson and Peter W. Shor, "Applications of */ -/* Random Sampling in Computational Geometry II," Discrete & */ -/* Computational Geometry 4(1):387-421, 1989, would yield an expected */ -/* O(n^{4/3}) bound on running time. */ -/* */ -/* The O(n log n) sweepline Delaunay triangulation algorithm is taken from */ -/* Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams", */ -/* Algorithmica 2(2):153-174, 1987. A random sample of edges on the */ -/* boundary of the triangulation are maintained in a splay tree for the */ -/* purpose of point location. Splay trees are described by Daniel */ -/* Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */ -/* Trees," Journal of the ACM 32(3):652-686, July 1985. */ -/* */ -/* The algorithms for exact computation of the signs of determinants are */ -/* described in Jonathan Richard Shewchuk, "Adaptive Precision Floating- */ -/* Point Arithmetic and Fast Robust Geometric Predicates," Discrete & */ -/* Computational Geometry 18(3):305-363, October 1997. (Also available */ -/* as Technical Report CMU-CS-96-140, School of Computer Science, */ -/* Carnegie Mellon University, Pittsburgh, Pennsylvania, May 1996.) [*] */ -/* An abbreviated version appears as Jonathan Richard Shewchuk, "Robust */ -/* Adaptive Floating-Point Geometric Predicates," Proceedings of the */ -/* Twelfth Annual Symposium on Computational Geometry, ACM, May 1996. [*] */ -/* Many of the ideas for my exact arithmetic routines originate with */ -/* Douglas M. Priest, "Algorithms for Arbitrary Precision Floating Point */ -/* Arithmetic," Tenth Symposium on Computer Arithmetic, pp. 132-143, IEEE */ -/* Computer Society Press, 1991. [*] Many of the ideas for the correct */ -/* evaluation of the signs of determinants are taken from Steven Fortune */ -/* and Christopher J. Van Wyk, "Efficient Exact Arithmetic for Computa- */ -/* tional Geometry," Proceedings of the Ninth Annual Symposium on */ -/* Computational Geometry, ACM, pp. 163-172, May 1993, and from Steven */ -/* Fortune, "Numerical Stability of Algorithms for 2D Delaunay Triangu- */ -/* lations," International Journal of Computational Geometry & Applica- */ -/* tions 5(1-2):193-213, March-June 1995. */ -/* */ -/* The method of inserting new vertices off-center (not precisely at the */ -/* circumcenter of every poor-quality triangle) is from Alper Ungor, */ -/* "Off-centers: A New Type of Steiner Points for Computing Size-Optimal */ -/* quality-guaranteed Delaunay triangulations," Proceedings of LATIN */ -/* 2004 (Buenos Aires, Argentina), April 2004. */ -/* */ -/* For definitions of and results involving Delaunay triangulations, */ -/* constrained and conforming versions thereof, and other aspects of */ -/* triangular mesh generation, see the excellent survey by Marshall Bern */ -/* and David Eppstein, "Mesh Generation and Optimal Triangulation," in */ -/* Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang, */ -/* editors, World Scientific, Singapore, pp. 23-90, 1992. [*] */ -/* */ -/* The time for incrementally adding PSLG (planar straight line graph) */ -/* segments to create a constrained Delaunay triangulation is probably */ -/* O(t^2) per segment in the worst case and O(t) per segment in the */ -/* common case, where t is the number of triangles that intersect the */ -/* segment before it is inserted. This doesn't count point location, */ -/* which can be much more expensive. I could improve this to O(d log d) */ -/* time, but d is usually quite small, so it's not worth the bother. */ -/* (This note does not apply to conforming Delaunay triangulations, for */ -/* which a different method is used to insert segments.) */ -/* */ -/* The time for adding segments to a conforming Delaunay triangulation is */ -/* not clear, but does not depend upon t alone. In some cases, very */ -/* small features (like a vertex lying next to a segment) can cause a */ -/* single segment to be split an arbitrary number of times. Of course, */ -/* floating-point precision is a practical barrier to how much this can */ -/* happen. */ -/* */ -/* The time for deleting a vertex from a Delaunay triangulation is O(d^2) */ -/* in the worst case and O(d) in the common case, where d is the degree */ -/* of the vertex being deleted. I could improve this to O(d log d) time, */ -/* but d is usually quite small, so it's not worth the bother. */ -/* */ -/* Ruppert's Delaunay refinement algorithm typically generates triangles */ -/* at a linear rate (constant time per triangle) after the initial */ -/* triangulation is formed. There may be pathological cases where */ -/* quadratic time is required, but these never arise in practice. */ -/* */ -/* The geometric predicates (circumcenter calculations, segment */ -/* intersection formulae, etc.) appear in my "Lecture Notes on Geometric */ -/* Robustness" at http://www.cs.berkeley.edu/~jrs/mesh.html . */ -/* */ -/* If you make any improvements to this code, please please please let me */ -/* know, so that I may obtain the improvements. Even if you don't change */ -/* the code, I'd still love to hear what it's being used for. */ -/* */ -/* Disclaimer: Neither I nor Carnegie Mellon warrant this code in any way */ -/* whatsoever. This code is provided "as-is". Use at your own risk. */ -/* */ -/*****************************************************************************/ - -/* For single precision (which will save some memory and reduce paging), */ -/* define the symbol SINGLE by using the -DSINGLE compiler switch or by */ -/* writing "#define SINGLE" below. */ -/* */ -/* For double precision (which will allow you to refine meshes to a smaller */ -/* edge length), leave SINGLE undefined. */ -/* */ -/* Double precision uses more memory, but improves the resolution of the */ -/* meshes you can generate with Triangle. It also reduces the likelihood */ -/* of a floating exception due to overflow. Finally, it is much faster */ -/* than single precision on 64-bit architectures like the DEC Alpha. I */ -/* recommend double precision unless you want to generate a mesh for which */ -/* you do not have enough memory. */ - -/* #define SINGLE */ - -#ifdef SINGLE -#define REAL float -#else /* not SINGLE */ -#define REAL double -#endif /* not SINGLE */ - -/* If yours is not a Unix system, define the NO_TIMER compiler switch to */ -/* remove the Unix-specific timing code. */ - -/* #define NO_TIMER */ - -/* To insert lots of self-checks for internal errors, define the SELF_CHECK */ -/* symbol. This will slow down the program significantly. It is best to */ -/* define the symbol using the -DSELF_CHECK compiler switch, but you could */ -/* write "#define SELF_CHECK" below. If you are modifying this code, I */ -/* recommend you turn self-checks on until your work is debugged. */ - -/* #define SELF_CHECK */ - -/* To compile Triangle as a callable object library (triangle.o), define the */ -/* TRILIBRARY symbol. Read the file triangle.h for details on how to call */ -/* the procedure triangulate() that results. */ - -/* #define TRILIBRARY */ - -/* It is possible to generate a smaller version of Triangle using one or */ -/* both of the following symbols. Define the REDUCED symbol to eliminate */ -/* all features that are primarily of research interest; specifically, the */ -/* -i, -F, -s, and -C switches. Define the CDT_ONLY symbol to eliminate */ -/* all meshing algorithms above and beyond constrained Delaunay */ -/* triangulation; specifically, the -r, -q, -a, -S, and -s switches. */ -/* These reductions are most likely to be useful when generating an object */ -/* library (triangle.o) by defining the TRILIBRARY symbol. */ - -/* #define REDUCED */ -/* #define CDT_ONLY */ - -/* On some machines, my exact arithmetic routines might be defeated by the */ -/* use of internal extended precision floating-point registers. The best */ -/* way to solve this problem is to set the floating-point registers to use */ -/* single or double precision internally. On 80x86 processors, this may */ -/* be accomplished by setting the CPU86 symbol for the Microsoft C */ -/* compiler, or the LINUX symbol for the gcc compiler running on Linux. */ -/* */ -/* An inferior solution is to declare certain values as `volatile', thus */ -/* forcing them to be stored to memory and rounded off. Unfortunately, */ -/* this solution might slow Triangle down quite a bit. To use volatile */ -/* values, write "#define INEXACT volatile" below. Normally, however, */ -/* INEXACT should be defined to be nothing. ("#define INEXACT".) */ -/* */ -/* For more discussion, see http://www.cs.cmu.edu/~quake/robust.pc.html . */ -/* For yet more discussion, see Section 5 of my paper, "Adaptive Precision */ -/* Floating-Point Arithmetic and Fast Robust Geometric Predicates" (also */ -/* available as Section 6.6 of my dissertation). */ - -/* #define CPU86 */ -/* #define LINUX */ - -#define INEXACT /* Nothing */ -/* #define INEXACT volatile */ - -/* Maximum number of characters in a file name (including the null). */ - -#define FILENAMESIZE 512 - -/* Maximum number of characters in a line read from a file (including the */ -/* null). */ - -#define INPUTLINESIZE 512 - -/* For efficiency, a variety of data structures are allocated in bulk. The */ -/* following constants determine how many of each structure is allocated */ -/* at once. */ - -#define TRIPERBLOCK 4092 /* Number of triangles allocated at once. */ -#define SUBSEGPERBLOCK 508 /* Number of subsegments allocated at once. */ -#define VERTEXPERBLOCK 4092 /* Number of vertices allocated at once. */ -#define VIRUSPERBLOCK 1020 /* Number of virus triangles allocated at once. */ -/* Number of encroached subsegments allocated at once. */ -#define BADSUBSEGPERBLOCK 252 -/* Number of skinny triangles allocated at once. */ -#define BADTRIPERBLOCK 4092 -/* Number of flipped triangles allocated at once. */ -#define FLIPSTACKERPERBLOCK 252 -/* Number of splay tree nodes allocated at once. */ -#define SPLAYNODEPERBLOCK 508 - -/* The vertex types. A DEADVERTEX has been deleted entirely. An */ -/* UNDEADVERTEX is not part of the mesh, but is written to the output */ -/* .node file and affects the node indexing in the other output files. */ - -#define INPUTVERTEX 0 -#define SEGMENTVERTEX 1 -#define FREEVERTEX 2 -#define DEADVERTEX -32768 -#define UNDEADVERTEX -32767 - -/* The next line is used to outsmart some very stupid compilers. If your */ -/* compiler is smarter, feel free to replace the "int" with "void". */ -/* Not that it matters. */ - -#define VOID int - -/* Two constants for algorithms based on random sampling. Both constants */ -/* have been chosen empirically to optimize their respective algorithms. */ - -/* Used for the point location scheme of Mucke, Saias, and Zhu, to decide */ -/* how large a random sample of triangles to inspect. */ - -#define SAMPLEFACTOR 11 - -/* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */ -/* of boundary edges should be maintained in the splay tree for point */ -/* location on the front. */ - -#define SAMPLERATE 10 - -/* A number that speaks for itself, every kissable digit. */ - -#define PI 3.141592653589793238462643383279502884197169399375105820974944592308 - -/* Another fave. */ - -#define SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732 - -/* And here's one for those of you who are intimidated by math. */ - -#define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333 - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#ifndef NO_TIMER -#include <sys/time.h> -#endif /* not NO_TIMER */ -#ifdef CPU86 -#include <float.h> -#endif /* CPU86 */ -#ifdef LINUX -#include <fpu_control.h> -#endif /* LINUX */ -#ifdef TRILIBRARY -#include "triangle.h" -#endif /* TRILIBRARY */ - -/* A few forward declarations. */ - -#ifndef TRILIBRARY -char *readline(); -char *findfield(); -#endif /* not TRILIBRARY */ - -/* Labels that signify whether a record consists primarily of pointers or of */ -/* floating-point words. Used to make decisions about data alignment. */ - -enum wordtype {POINTER, FLOATINGPOINT}; - -/* Labels that signify the result of point location. The result of a */ -/* search indicates that the point falls in the interior of a triangle, on */ -/* an edge, on a vertex, or outside the mesh. */ - -enum locateresult {INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE}; - -/* Labels that signify the result of vertex insertion. The result indicates */ -/* that the vertex was inserted with complete success, was inserted but */ -/* encroaches upon a subsegment, was not inserted because it lies on a */ -/* segment, or was not inserted because another vertex occupies the same */ -/* location. */ - -enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX, - DUPLICATEVERTEX}; - -/* Labels that signify the result of direction finding. The result */ -/* indicates that a segment connecting the two query points falls within */ -/* the direction triangle, along the left edge of the direction triangle, */ -/* or along the right edge of the direction triangle. */ - -enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR}; - -/*****************************************************************************/ -/* */ -/* The basic mesh data structures */ -/* */ -/* There are three: vertices, triangles, and subsegments (abbreviated */ -/* `subseg'). These three data structures, linked by pointers, comprise */ -/* the mesh. A vertex simply represents a mesh vertex and its properties. */ -/* A triangle is a triangle. A subsegment is a special data structure used */ -/* to represent an impenetrable edge of the mesh (perhaps on the outer */ -/* boundary, on the boundary of a hole, or part of an internal boundary */ -/* separating two triangulated regions). Subsegments represent boundaries, */ -/* defined by the user, that triangles may not lie across. */ -/* */ -/* A triangle consists of a list of three vertices, a list of three */ -/* adjoining triangles, a list of three adjoining subsegments (when */ -/* segments exist), an arbitrary number of optional user-defined */ -/* floating-point attributes, and an optional area constraint. The latter */ -/* is an upper bound on the permissible area of each triangle in a region, */ -/* used for mesh refinement. */ -/* */ -/* For a triangle on a boundary of the mesh, some or all of the neighboring */ -/* triangles may not be present. For a triangle in the interior of the */ -/* mesh, often no neighboring subsegments are present. Such absent */ -/* triangles and subsegments are never represented by NULL pointers; they */ -/* are represented by two special records: `dummytri', the triangle that */ -/* fills "outer space", and `dummysub', the omnipresent subsegment. */ -/* `dummytri' and `dummysub' are used for several reasons; for instance, */ -/* they can be dereferenced and their contents examined without violating */ -/* protected memory. */ -/* */ -/* However, it is important to understand that a triangle includes other */ -/* information as well. The pointers to adjoining vertices, triangles, and */ -/* subsegments are ordered in a way that indicates their geometric relation */ -/* to each other. Furthermore, each of these pointers contains orientation */ -/* information. Each pointer to an adjoining triangle indicates which face */ -/* of that triangle is contacted. Similarly, each pointer to an adjoining */ -/* subsegment indicates which side of that subsegment is contacted, and how */ -/* the subsegment is oriented relative to the triangle. */ -/* */ -/* The data structure representing a subsegment may be thought to be */ -/* abutting the edge of one or two triangle data structures: either */ -/* sandwiched between two triangles, or resting against one triangle on an */ -/* exterior boundary or hole boundary. */ -/* */ -/* A subsegment consists of a list of two vertices, a list of two */ -/* adjoining subsegments, and a list of two adjoining triangles. One of */ -/* the two adjoining triangles may not be present (though there should */ -/* always be one), and neighboring subsegments might not be present. */ -/* Subsegments also store a user-defined integer "boundary marker". */ -/* Typically, this integer is used to indicate what boundary conditions are */ -/* to be applied at that location in a finite element simulation. */ -/* */ -/* Like triangles, subsegments maintain information about the relative */ -/* orientation of neighboring objects. */ -/* */ -/* Vertices are relatively simple. A vertex is a list of floating-point */ -/* numbers, starting with the x, and y coordinates, followed by an */ -/* arbitrary number of optional user-defined floating-point attributes, */ -/* followed by an integer boundary marker. During the segment insertion */ -/* phase, there is also a pointer from each vertex to a triangle that may */ -/* contain it. Each pointer is not always correct, but when one is, it */ -/* speeds up segment insertion. These pointers are assigned values once */ -/* at the beginning of the segment insertion phase, and are not used or */ -/* updated except during this phase. Edge flipping during segment */ -/* insertion will render some of them incorrect. Hence, don't rely upon */ -/* them for anything. */ -/* */ -/* Other than the exception mentioned above, vertices have no information */ -/* about what triangles, subfacets, or subsegments they are linked to. */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* Handles */ -/* */ -/* The oriented triangle (`otri') and oriented subsegment (`osub') data */ -/* structures defined below do not themselves store any part of the mesh. */ -/* The mesh itself is made of `triangle's, `subseg's, and `vertex's. */ -/* */ -/* Oriented triangles and oriented subsegments will usually be referred to */ -/* as "handles." A handle is essentially a pointer into the mesh; it */ -/* allows you to "hold" one particular part of the mesh. Handles are used */ -/* to specify the regions in which one is traversing and modifying the mesh.*/ -/* A single `triangle' may be held by many handles, or none at all. (The */ -/* latter case is not a memory leak, because the triangle is still */ -/* connected to other triangles in the mesh.) */ -/* */ -/* An `otri' is a handle that holds a triangle. It holds a specific edge */ -/* of the triangle. An `osub' is a handle that holds a subsegment. It */ -/* holds either the left or right side of the subsegment. */ -/* */ -/* Navigation about the mesh is accomplished through a set of mesh */ -/* manipulation primitives, further below. Many of these primitives take */ -/* a handle and produce a new handle that holds the mesh near the first */ -/* handle. Other primitives take two handles and glue the corresponding */ -/* parts of the mesh together. The orientation of the handles is */ -/* important. For instance, when two triangles are glued together by the */ -/* bond() primitive, they are glued at the edges on which the handles lie. */ -/* */ -/* Because vertices have no information about which triangles they are */ -/* attached to, I commonly represent a vertex by use of a handle whose */ -/* origin is the vertex. A single handle can simultaneously represent a */ -/* triangle, an edge, and a vertex. */ -/* */ -/*****************************************************************************/ - -/* The triangle data structure. Each triangle contains three pointers to */ -/* adjoining triangles, plus three pointers to vertices, plus three */ -/* pointers to subsegments (declared below; these pointers are usually */ -/* `dummysub'). It may or may not also contain user-defined attributes */ -/* and/or a floating-point "area constraint." It may also contain extra */ -/* pointers for nodes, when the user asks for high-order elements. */ -/* Because the size and structure of a `triangle' is not decided until */ -/* runtime, I haven't simply declared the type `triangle' as a struct. */ - -typedef REAL **triangle; /* Really: typedef triangle *triangle */ - -/* An oriented triangle: includes a pointer to a triangle and orientation. */ -/* The orientation denotes an edge of the triangle. Hence, there are */ -/* three possible orientations. By convention, each edge always points */ -/* counterclockwise about the corresponding triangle. */ - -struct otri { - triangle *tri; - int orient; /* Ranges from 0 to 2. */ -}; - -/* The subsegment data structure. Each subsegment contains two pointers to */ -/* adjoining subsegments, plus two pointers to vertices, plus two pointers */ -/* to adjoining triangles, plus one boundary marker. */ - -typedef REAL **subseg; /* Really: typedef subseg *subseg */ - -/* An oriented subsegment: includes a pointer to a subsegment and an */ -/* orientation. The orientation denotes a side of the edge. Hence, there */ -/* are two possible orientations. By convention, the edge is always */ -/* directed so that the "side" denoted is the right side of the edge. */ - -struct osub { - subseg *ss; - int ssorient; /* Ranges from 0 to 1. */ -}; - -/* The vertex data structure. Each vertex is actually an array of REALs. */ -/* The number of REALs is unknown until runtime. An integer boundary */ -/* marker, and sometimes a pointer to a triangle, is appended after the */ -/* REALs. */ - -typedef REAL *vertex; - -/* A queue used to store encroached subsegments. Each subsegment's vertices */ -/* are stored so that we can check whether a subsegment is still the same. */ - -struct badsubseg { - subseg encsubseg; /* An encroached subsegment. */ - vertex subsegorg, subsegdest; /* Its two vertices. */ -}; - -/* A queue used to store bad triangles. The key is the square of the cosine */ -/* of the smallest angle of the triangle. Each triangle's vertices are */ -/* stored so that one can check whether a triangle is still the same. */ - -struct badtriang { - triangle poortri; /* A skinny or too-large triangle. */ - REAL key; /* cos^2 of smallest (apical) angle. */ - vertex triangorg, triangdest, triangapex; /* Its three vertices. */ - struct badtriang *nexttriang; /* Pointer to next bad triangle. */ -}; - -/* A stack of triangles flipped during the most recent vertex insertion. */ -/* The stack is used to undo the vertex insertion if the vertex encroaches */ -/* upon a subsegment. */ - -struct flipstacker { - triangle flippedtri; /* A recently flipped triangle. */ - struct flipstacker *prevflip; /* Previous flip in the stack. */ -}; - -/* A node in a heap used to store events for the sweepline Delaunay */ -/* algorithm. Nodes do not point directly to their parents or children in */ -/* the heap. Instead, each node knows its position in the heap, and can */ -/* look up its parent and children in a separate array. The `eventptr' */ -/* points either to a `vertex' or to a triangle (in encoded format, so */ -/* that an orientation is included). In the latter case, the origin of */ -/* the oriented triangle is the apex of a "circle event" of the sweepline */ -/* algorithm. To distinguish site events from circle events, all circle */ -/* events are given an invalid (smaller than `xmin') x-coordinate `xkey'. */ - -struct event { - REAL xkey, ykey; /* Coordinates of the event. */ - VOID *eventptr; /* Can be a vertex or the location of a circle event. */ - int heapposition; /* Marks this event's position in the heap. */ -}; - -/* A node in the splay tree. Each node holds an oriented ghost triangle */ -/* that represents a boundary edge of the growing triangulation. When a */ -/* circle event covers two boundary edges with a triangle, so that they */ -/* are no longer boundary edges, those edges are not immediately deleted */ -/* from the tree; rather, they are lazily deleted when they are next */ -/* encountered. (Since only a random sample of boundary edges are kept */ -/* in the tree, lazy deletion is faster.) `keydest' is used to verify */ -/* that a triangle is still the same as when it entered the splay tree; if */ -/* it has been rotated (due to a circle event), it no longer represents a */ -/* boundary edge and should be deleted. */ - -struct splaynode { - struct otri keyedge; /* Lprev of an edge on the front. */ - vertex keydest; /* Used to verify that splay node is still live. */ - struct splaynode *lchild, *rchild; /* Children in splay tree. */ -}; - -/* A type used to allocate memory. firstblock is the first block of items. */ -/* nowblock is the block from which items are currently being allocated. */ -/* nextitem points to the next slab of free memory for an item. */ -/* deaditemstack is the head of a linked list (stack) of deallocated items */ -/* that can be recycled. unallocateditems is the number of items that */ -/* remain to be allocated from nowblock. */ -/* */ -/* Traversal is the process of walking through the entire list of items, and */ -/* is separate from allocation. Note that a traversal will visit items on */ -/* the "deaditemstack" stack as well as live items. pathblock points to */ -/* the block currently being traversed. pathitem points to the next item */ -/* to be traversed. pathitemsleft is the number of items that remain to */ -/* be traversed in pathblock. */ -/* */ -/* itemwordtype is set to POINTER or FLOATINGPOINT, and is used to suggest */ -/* what sort of word the record is primarily made up of. alignbytes */ -/* determines how new records should be aligned in memory. itembytes and */ -/* itemwords are the length of a record in bytes (after rounding up) and */ -/* words. itemsperblock is the number of items allocated at once in a */ -/* single block. itemsfirstblock is the number of items in the first */ -/* block, which can vary from the others. items is the number of */ -/* currently allocated items. maxitems is the maximum number of items */ -/* that have been allocated at once; it is the current number of items */ -/* plus the number of records kept on deaditemstack. */ - -struct memorypool { - VOID **firstblock, **nowblock; - VOID *nextitem; - VOID *deaditemstack; - VOID **pathblock; - VOID *pathitem; - enum wordtype itemwordtype; - int alignbytes; - int itembytes, itemwords; - int itemsperblock; - int itemsfirstblock; - long items, maxitems; - int unallocateditems; - int pathitemsleft; -}; - - -/* Global constants. */ - -REAL splitter; /* Used to split REAL factors for exact multiplication. */ -REAL epsilon; /* Floating-point machine epsilon. */ -REAL resulterrbound; -REAL ccwerrboundA, ccwerrboundB, ccwerrboundC; -REAL iccerrboundA, iccerrboundB, iccerrboundC; -REAL o3derrboundA, o3derrboundB, o3derrboundC; - -/* Random number seed is not constant, but I've made it global anyway. */ - -unsigned long randomseed; /* Current random number seed. */ - - -/* Mesh data structure. Triangle operates on only one mesh, but the mesh */ -/* structure is used (instead of global variables) to allow reentrancy. */ - -struct mesh { - -/* Variables used to allocate memory for triangles, subsegments, vertices, */ -/* viri (triangles being eaten), encroached segments, bad (skinny or too */ -/* large) triangles, and splay tree nodes. */ - - struct memorypool triangles; - struct memorypool subsegs; - struct memorypool vertices; - struct memorypool viri; - struct memorypool badsubsegs; - struct memorypool badtriangles; - struct memorypool flipstackers; - struct memorypool splaynodes; - -/* Variables that maintain the bad triangle queues. The queues are */ -/* ordered from 63 (highest priority) to 0 (lowest priority). */ - - struct badtriang *queuefront[64]; - struct badtriang *queuetail[64]; - int nextnonemptyq[64]; - int firstnonemptyq; - -/* Variable that maintains the stack of recently flipped triangles. */ - - struct flipstacker *lastflip; - -/* Other variables. */ - - REAL xmin, xmax, ymin, ymax; /* x and y bounds. */ - REAL xminextreme; /* Nonexistent x value used as a flag in sweepline. */ - int invertices; /* Number of input vertices. */ - int inelements; /* Number of input triangles. */ - int insegments; /* Number of input segments. */ - int holes; /* Number of input holes. */ - int regions; /* Number of input regions. */ - int undeads; /* Number of input vertices that don't appear in the mesh. */ - long edges; /* Number of output edges. */ - int mesh_dim; /* Dimension (ought to be 2). */ - int nextras; /* Number of attributes per vertex. */ - int eextras; /* Number of attributes per triangle. */ - long hullsize; /* Number of edges in convex hull. */ - int steinerleft; /* Number of Steiner points not yet used. */ - int vertexmarkindex; /* Index to find boundary marker of a vertex. */ - int vertex2triindex; /* Index to find a triangle adjacent to a vertex. */ - int highorderindex; /* Index to find extra nodes for high-order elements. */ - int elemattribindex; /* Index to find attributes of a triangle. */ - int areaboundindex; /* Index to find area bound of a triangle. */ - int checksegments; /* Are there segments in the triangulation yet? */ - int checkquality; /* Has quality triangulation begun yet? */ - int readnodefile; /* Has a .node file been read? */ - long samples; /* Number of random samples for point location. */ - - long incirclecount; /* Number of incircle tests performed. */ - long counterclockcount; /* Number of counterclockwise tests performed. */ - long orient3dcount; /* Number of 3D orientation tests performed. */ - long hyperbolacount; /* Number of right-of-hyperbola tests performed. */ - long circumcentercount; /* Number of circumcenter calculations performed. */ - long circletopcount; /* Number of circle top calculations performed. */ - -/* Triangular bounding box vertices. */ - - vertex infvertex1, infvertex2, infvertex3; - -/* Pointer to the `triangle' that occupies all of "outer space." */ - - triangle *dummytri; - triangle *dummytribase; /* Keep base address so we can free() it later. */ - -/* Pointer to the omnipresent subsegment. Referenced by any triangle or */ -/* subsegment that isn't really connected to a subsegment at that */ -/* location. */ - - subseg *dummysub; - subseg *dummysubbase; /* Keep base address so we can free() it later. */ - -/* Pointer to a recently visited triangle. Improves point location if */ -/* proximate vertices are inserted sequentially. */ - - struct otri recenttri; - -}; /* End of `struct mesh'. */ - - -/* Data structure for command line switches and file names. This structure */ -/* is used (instead of global variables) to allow reentrancy. */ - -struct behavior { - -/* Switches for the triangulator. */ -/* poly: -p switch. refine: -r switch. */ -/* quality: -q switch. */ -/* minangle: minimum angle bound, specified after -q switch. */ -/* goodangle: cosine squared of minangle. */ -/* offconstant: constant used to place off-center Steiner points. */ -/* vararea: -a switch without number. */ -/* fixedarea: -a switch with number. */ -/* maxarea: maximum area bound, specified after -a switch. */ -/* usertest: -u switch. */ -/* regionattrib: -A switch. convex: -c switch. */ -/* weighted: 1 for -w switch, 2 for -W switch. jettison: -j switch */ -/* firstnumber: inverse of -z switch. All items are numbered starting */ -/* from `firstnumber'. */ -/* edgesout: -e switch. voronoi: -v switch. */ -/* neighbors: -n switch. geomview: -g switch. */ -/* nobound: -B switch. nopolywritten: -P switch. */ -/* nonodewritten: -N switch. noelewritten: -E switch. */ -/* noiterationnum: -I switch. noholes: -O switch. */ -/* noexact: -X switch. */ -/* order: element order, specified after -o switch. */ -/* nobisect: count of how often -Y switch is selected. */ -/* steiner: maximum number of Steiner points, specified after -S switch. */ -/* incremental: -i switch. sweepline: -F switch. */ -/* dwyer: inverse of -l switch. */ -/* splitseg: -s switch. */ -/* nolenses: -L switch. docheck: -C switch. */ -/* quiet: -Q switch. verbose: count of how often -V switch is selected. */ -/* usesegments: -p, -r, -q, or -c switch; determines whether segments are */ -/* used at all. */ -/* */ -/* Read the instructions to find out the meaning of these switches. */ - - int poly, refine, quality, vararea, fixedarea, usertest; - int regionattrib, convex, weighted, jettison; - int firstnumber; - int edgesout, voronoi, neighbors, geomview; - int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum; - int noholes, noexact, nolenses; - int incremental, sweepline, dwyer; - int splitseg; - int docheck; - int quiet, verbose; - int usesegments; - int order; - int nobisect; - int steiner; - REAL minangle, goodangle, offconstant; - REAL maxarea; - -/* Variables for file names. */ - -#ifndef TRILIBRARY - char innodefilename[FILENAMESIZE]; - char inelefilename[FILENAMESIZE]; - char inpolyfilename[FILENAMESIZE]; - char areafilename[FILENAMESIZE]; - char outnodefilename[FILENAMESIZE]; - char outelefilename[FILENAMESIZE]; - char outpolyfilename[FILENAMESIZE]; - char edgefilename[FILENAMESIZE]; - char vnodefilename[FILENAMESIZE]; - char vedgefilename[FILENAMESIZE]; - char neighborfilename[FILENAMESIZE]; - char offfilename[FILENAMESIZE]; -#endif /* not TRILIBRARY */ - -}; /* End of `struct behavior'. */ - - -/*****************************************************************************/ -/* */ -/* Mesh manipulation primitives. Each triangle contains three pointers to */ -/* other triangles, with orientations. Each pointer points not to the */ -/* first byte of a triangle, but to one of the first three bytes of a */ -/* triangle. It is necessary to extract both the triangle itself and the */ -/* orientation. To save memory, I keep both pieces of information in one */ -/* pointer. To make this possible, I assume that all triangles are aligned */ -/* to four-byte boundaries. The decode() routine below decodes a pointer, */ -/* extracting an orientation (in the range 0 to 2) and a pointer to the */ -/* beginning of a triangle. The encode() routine compresses a pointer to a */ -/* triangle and an orientation into a single pointer. My assumptions that */ -/* triangles are four-byte-aligned and that the `unsigned long' type is */ -/* long enough to hold a pointer are two of the few kludges in this program.*/ -/* */ -/* Subsegments are manipulated similarly. A pointer to a subsegment */ -/* carries both an address and an orientation in the range 0 to 1. */ -/* */ -/* The other primitives take an oriented triangle or oriented subsegment, */ -/* and return an oriented triangle or oriented subsegment or vertex; or */ -/* they change the connections in the data structure. */ -/* */ -/* Below, triangles and subsegments are denoted by their vertices. The */ -/* triangle abc has origin (org) a, destination (dest) b, and apex (apex) */ -/* c. These vertices occur in counterclockwise order about the triangle. */ -/* The handle abc may simultaneously denote vertex a, edge ab, and triangle */ -/* abc. */ -/* */ -/* Similarly, the subsegment ab has origin (sorg) a and destination (sdest) */ -/* b. If ab is thought to be directed upward (with b directly above a), */ -/* then the handle ab is thought to grasp the right side of ab, and may */ -/* simultaneously denote vertex a and edge ab. */ -/* */ -/* An asterisk (*) denotes a vertex whose identity is unknown. */ -/* */ -/* Given this notation, a partial list of mesh manipulation primitives */ -/* follows. */ -/* */ -/* */ -/* For triangles: */ -/* */ -/* sym: Find the abutting triangle; same edge. */ -/* sym(abc) -> ba* */ -/* */ -/* lnext: Find the next edge (counterclockwise) of a triangle. */ -/* lnext(abc) -> bca */ -/* */ -/* lprev: Find the previous edge (clockwise) of a triangle. */ -/* lprev(abc) -> cab */ -/* */ -/* onext: Find the next edge counterclockwise with the same origin. */ -/* onext(abc) -> ac* */ -/* */ -/* oprev: Find the next edge clockwise with the same origin. */ -/* oprev(abc) -> a*b */ -/* */ -/* dnext: Find the next edge counterclockwise with the same destination. */ -/* dnext(abc) -> *ba */ -/* */ -/* dprev: Find the next edge clockwise with the same destination. */ -/* dprev(abc) -> cb* */ -/* */ -/* rnext: Find the next edge (counterclockwise) of the adjacent triangle. */ -/* rnext(abc) -> *a* */ -/* */ -/* rprev: Find the previous edge (clockwise) of the adjacent triangle. */ -/* rprev(abc) -> b** */ -/* */ -/* org: Origin dest: Destination apex: Apex */ -/* org(abc) -> a dest(abc) -> b apex(abc) -> c */ -/* */ -/* bond: Bond two triangles together at the resepective handles. */ -/* bond(abc, bad) */ -/* */ -/* */ -/* For subsegments: */ -/* */ -/* ssym: Reverse the orientation of a subsegment. */ -/* ssym(ab) -> ba */ -/* */ -/* spivot: Find adjoining subsegment with the same origin. */ -/* spivot(ab) -> a* */ -/* */ -/* snext: Find next subsegment in sequence. */ -/* snext(ab) -> b* */ -/* */ -/* sorg: Origin sdest: Destination */ -/* sorg(ab) -> a sdest(ab) -> b */ -/* */ -/* sbond: Bond two subsegments together at the respective origins. */ -/* sbond(ab, ac) */ -/* */ -/* */ -/* For interacting tetrahedra and subfacets: */ -/* */ -/* tspivot: Find a subsegment abutting a triangle. */ -/* tspivot(abc) -> ba */ -/* */ -/* stpivot: Find a triangle abutting a subsegment. */ -/* stpivot(ab) -> ba* */ -/* */ -/* tsbond: Bond a triangle to a subsegment. */ -/* tsbond(abc, ba) */ -/* */ -/*****************************************************************************/ - -/********* Mesh manipulation primitives begin here *********/ -/** **/ -/** **/ - -/* Fast lookup arrays to speed some of the mesh manipulation primitives. */ - -int plus1mod3[3] = {1, 2, 0}; -int minus1mod3[3] = {2, 0, 1}; - -/********* Primitives for triangles *********/ -/* */ -/* */ - -/* decode() converts a pointer to an oriented triangle. The orientation is */ -/* extracted from the two least significant bits of the pointer. */ - -#define decode(ptr, otri) \ - (otri).orient = (int) ((unsigned long) (ptr) & (unsigned long) 3l); \ - (otri).tri = (triangle *) \ - ((unsigned long) (ptr) ^ (unsigned long) (otri).orient) - -/* encode() compresses an oriented triangle into a single pointer. It */ -/* relies on the assumption that all triangles are aligned to four-byte */ -/* boundaries, so the two least significant bits of (otri).tri are zero. */ - -#define encode(otri) \ - (triangle) ((unsigned long) (otri).tri | (unsigned long) (otri).orient) - -/* The following handle manipulation primitives are all described by Guibas */ -/* and Stolfi. However, Guibas and Stolfi use an edge-based data */ -/* structure, whereas I use a triangle-based data structure. */ - -/* sym() finds the abutting triangle, on the same edge. Note that the edge */ -/* direction is necessarily reversed, because the handle specified by an */ -/* oriented triangle is directed counterclockwise around the triangle. */ - -#define sym(otri1, otri2) \ - ptr = (otri1).tri[(otri1).orient]; \ - decode(ptr, otri2); - -#define symself(otri) \ - ptr = (otri).tri[(otri).orient]; \ - decode(ptr, otri); - -/* lnext() finds the next edge (counterclockwise) of a triangle. */ - -#define lnext(otri1, otri2) \ - (otri2).tri = (otri1).tri; \ - (otri2).orient = plus1mod3[(otri1).orient] - -#define lnextself(otri) \ - (otri).orient = plus1mod3[(otri).orient] - -/* lprev() finds the previous edge (clockwise) of a triangle. */ - -#define lprev(otri1, otri2) \ - (otri2).tri = (otri1).tri; \ - (otri2).orient = minus1mod3[(otri1).orient] - -#define lprevself(otri) \ - (otri).orient = minus1mod3[(otri).orient] - -/* onext() spins counterclockwise around a vertex; that is, it finds the */ -/* next edge with the same origin in the counterclockwise direction. This */ -/* edge is part of a different triangle. */ - -#define onext(otri1, otri2) \ - lprev(otri1, otri2); \ - symself(otri2); - -#define onextself(otri) \ - lprevself(otri); \ - symself(otri); - -/* oprev() spins clockwise around a vertex; that is, it finds the next edge */ -/* with the same origin in the clockwise direction. This edge is part of */ -/* a different triangle. */ - -#define oprev(otri1, otri2) \ - sym(otri1, otri2); \ - lnextself(otri2); - -#define oprevself(otri) \ - symself(otri); \ - lnextself(otri); - -/* dnext() spins counterclockwise around a vertex; that is, it finds the */ -/* next edge with the same destination in the counterclockwise direction. */ -/* This edge is part of a different triangle. */ - -#define dnext(otri1, otri2) \ - sym(otri1, otri2); \ - lprevself(otri2); - -#define dnextself(otri) \ - symself(otri); \ - lprevself(otri); - -/* dprev() spins clockwise around a vertex; that is, it finds the next edge */ -/* with the same destination in the clockwise direction. This edge is */ -/* part of a different triangle. */ - -#define dprev(otri1, otri2) \ - lnext(otri1, otri2); \ - symself(otri2); - -#define dprevself(otri) \ - lnextself(otri); \ - symself(otri); - -/* rnext() moves one edge counterclockwise about the adjacent triangle. */ -/* (It's best understood by reading Guibas and Stolfi. It involves */ -/* changing triangles twice.) */ - -#define rnext(otri1, otri2) \ - sym(otri1, otri2); \ - lnextself(otri2); \ - symself(otri2); - -#define rnextself(otri) \ - symself(otri); \ - lnextself(otri); \ - symself(otri); - -/* rprev() moves one edge clockwise about the adjacent triangle. */ -/* (It's best understood by reading Guibas and Stolfi. It involves */ -/* changing triangles twice.) */ - -#define rprev(otri1, otri2) \ - sym(otri1, otri2); \ - lprevself(otri2); \ - symself(otri2); - -#define rprevself(otri) \ - symself(otri); \ - lprevself(otri); \ - symself(otri); - -/* These primitives determine or set the origin, destination, or apex of a */ -/* triangle. */ - -#define org(otri, vertexptr) \ - vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3] - -#define dest(otri, vertexptr) \ - vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3] - -#define apex(otri, vertexptr) \ - vertexptr = (vertex) (otri).tri[(otri).orient + 3] - -#define setorg(otri, vertexptr) \ - (otri).tri[plus1mod3[(otri).orient] + 3] = (triangle) vertexptr - -#define setdest(otri, vertexptr) \ - (otri).tri[minus1mod3[(otri).orient] + 3] = (triangle) vertexptr - -#define setapex(otri, vertexptr) \ - (otri).tri[(otri).orient + 3] = (triangle) vertexptr - -/* Bond two triangles together. */ - -#define bond(otri1, otri2) \ - (otri1).tri[(otri1).orient] = encode(otri2); \ - (otri2).tri[(otri2).orient] = encode(otri1) - -/* Dissolve a bond (from one side). Note that the other triangle will still */ -/* think it's connected to this triangle. Usually, however, the other */ -/* triangle is being deleted entirely, or bonded to another triangle, so */ -/* it doesn't matter. */ - -#define dissolve(otri) \ - (otri).tri[(otri).orient] = (triangle) m->dummytri - -/* Copy an oriented triangle. */ - -#define otricopy(otri1, otri2) \ - (otri2).tri = (otri1).tri; \ - (otri2).orient = (otri1).orient - -/* Test for equality of oriented triangles. */ - -#define otriequal(otri1, otri2) \ - (((otri1).tri == (otri2).tri) && \ - ((otri1).orient == (otri2).orient)) - -/* Primitives to infect or cure a triangle with the virus. These rely on */ -/* the assumption that all subsegments are aligned to four-byte boundaries.*/ - -#define infect(otri) \ - (otri).tri[6] = (triangle) \ - ((unsigned long) (otri).tri[6] | (unsigned long) 2l) - -#define uninfect(otri) \ - (otri).tri[6] = (triangle) \ - ((unsigned long) (otri).tri[6] & ~ (unsigned long) 2l) - -/* Test a triangle for viral infection. */ - -#define infected(otri) \ - (((unsigned long) (otri).tri[6] & (unsigned long) 2l) != 0l) - -/* Check or set a triangle's attributes. */ - -#define elemattribute(otri, attnum) \ - ((REAL *) (otri).tri)[m->elemattribindex + (attnum)] - -#define setelemattribute(otri, attnum, value) \ - ((REAL *) (otri).tri)[m->elemattribindex + (attnum)] = value - -/* Check or set a triangle's maximum area bound. */ - -#define areabound(otri) ((REAL *) (otri).tri)[m->areaboundindex] - -#define setareabound(otri, value) \ - ((REAL *) (otri).tri)[m->areaboundindex] = value - -/* Check or set a triangle's deallocation. Its second pointer is set to */ -/* NULL to indicate that it is not allocated. (Its first pointer is used */ -/* for the stack of dead items.) Its fourth pointer (its first vertex) */ -/* is set to NULL in case a `badtriang' structure points to it. */ - -#define deadtri(tria) ((tria)[1] == (triangle) NULL) - -#define killtri(tria) \ - (tria)[1] = (triangle) NULL; \ - (tria)[3] = (triangle) NULL - -/********* Primitives for subsegments *********/ -/* */ -/* */ - -/* sdecode() converts a pointer to an oriented subsegment. The orientation */ -/* is extracted from the least significant bit of the pointer. The two */ -/* least significant bits (one for orientation, one for viral infection) */ -/* are masked out to produce the real pointer. */ - -#define sdecode(sptr, osub) \ - (osub).ssorient = (int) ((unsigned long) (sptr) & (unsigned long) 1l); \ - (osub).ss = (subseg *) \ - ((unsigned long) (sptr) & ~ (unsigned long) 3l) - -/* sencode() compresses an oriented subsegment into a single pointer. It */ -/* relies on the assumption that all subsegments are aligned to two-byte */ -/* boundaries, so the least significant bit of (osub).ss is zero. */ - -#define sencode(osub) \ - (subseg) ((unsigned long) (osub).ss | (unsigned long) (osub).ssorient) - -/* ssym() toggles the orientation of a subsegment. */ - -#define ssym(osub1, osub2) \ - (osub2).ss = (osub1).ss; \ - (osub2).ssorient = 1 - (osub1).ssorient - -#define ssymself(osub) \ - (osub).ssorient = 1 - (osub).ssorient - -/* spivot() finds the other subsegment (from the same segment) that shares */ -/* the same origin. */ - -#define spivot(osub1, osub2) \ - sptr = (osub1).ss[(osub1).ssorient]; \ - sdecode(sptr, osub2) - -#define spivotself(osub) \ - sptr = (osub).ss[(osub).ssorient]; \ - sdecode(sptr, osub) - -/* snext() finds the next subsegment (from the same segment) in sequence; */ -/* one whose origin is the input subsegment's destination. */ - -#define snext(osub1, osub2) \ - sptr = (osub1).ss[1 - (osub1).ssorient]; \ - sdecode(sptr, osub2) - -#define snextself(osub) \ - sptr = (osub).ss[1 - (osub).ssorient]; \ - sdecode(sptr, osub) - -/* These primitives determine or set the origin or destination of a */ -/* subsegment. */ - -#define sorg(osub, vertexptr) \ - vertexptr = (vertex) (osub).ss[2 + (osub).ssorient] - -#define sdest(osub, vertexptr) \ - vertexptr = (vertex) (osub).ss[3 - (osub).ssorient] - -#define setsorg(osub, vertexptr) \ - (osub).ss[2 + (osub).ssorient] = (subseg) vertexptr - -#define setsdest(osub, vertexptr) \ - (osub).ss[3 - (osub).ssorient] = (subseg) vertexptr - -/* These primitives read or set a boundary marker. Boundary markers are */ -/* used to hold user-defined tags for setting boundary conditions in */ -/* finite element solvers. */ - -#define mark(osub) (* (int *) ((osub).ss + 6)) - -#define setmark(osub, value) \ - * (int *) ((osub).ss + 6) = value - -/* Bond two subsegments together. */ - -#define sbond(osub1, osub2) \ - (osub1).ss[(osub1).ssorient] = sencode(osub2); \ - (osub2).ss[(osub2).ssorient] = sencode(osub1) - -/* Dissolve a subsegment bond (from one side). Note that the other */ -/* subsegment will still think it's connected to this subsegment. */ - -#define sdissolve(osub) \ - (osub).ss[(osub).ssorient] = (subseg) m->dummysub - -/* Copy a subsegment. */ - -#define subsegcopy(osub1, osub2) \ - (osub2).ss = (osub1).ss; \ - (osub2).ssorient = (osub1).ssorient - -/* Test for equality of subsegments. */ - -#define subsegequal(osub1, osub2) \ - (((osub1).ss == (osub2).ss) && \ - ((osub1).ssorient == (osub2).ssorient)) - -/* Check or set a subsegment's deallocation. Its second pointer is set to */ -/* NULL to indicate that it is not allocated. (Its first pointer is used */ -/* for the stack of dead items.) Its third pointer (its first vertex) */ -/* is set to NULL in case a `badsubseg' structure points to it. */ - -#define deadsubseg(sub) ((sub)[1] == (subseg) NULL) - -#define killsubseg(sub) \ - (sub)[1] = (subseg) NULL; \ - (sub)[2] = (subseg) NULL - -/********* Primitives for interacting triangles and subsegments *********/ -/* */ -/* */ - -/* tspivot() finds a subsegment abutting a triangle. */ - -#define tspivot(otri, osub) \ - sptr = (subseg) (otri).tri[6 + (otri).orient]; \ - sdecode(sptr, osub) - -/* stpivot() finds a triangle abutting a subsegment. It requires that the */ -/* variable `ptr' of type `triangle' be defined. */ - -#define stpivot(osub, otri) \ - ptr = (triangle) (osub).ss[4 + (osub).ssorient]; \ - decode(ptr, otri) - -/* Bond a triangle to a subsegment. */ - -#define tsbond(otri, osub) \ - (otri).tri[6 + (otri).orient] = (triangle) sencode(osub); \ - (osub).ss[4 + (osub).ssorient] = (subseg) encode(otri) - -/* Dissolve a bond (from the triangle side). */ - -#define tsdissolve(otri) \ - (otri).tri[6 + (otri).orient] = (triangle) m->dummysub - -/* Dissolve a bond (from the subsegment side). */ - -#define stdissolve(osub) \ - (osub).ss[4 + (osub).ssorient] = (subseg) m->dummytri - -/********* Primitives for vertices *********/ -/* */ -/* */ - -#define vertexmark(vx) ((int *) (vx))[m->vertexmarkindex] - -#define setvertexmark(vx, value) \ - ((int *) (vx))[m->vertexmarkindex] = value - -#define vertextype(vx) ((int *) (vx))[m->vertexmarkindex + 1] - -#define setvertextype(vx, value) \ - ((int *) (vx))[m->vertexmarkindex + 1] = value - -#define vertex2tri(vx) ((triangle *) (vx))[m->vertex2triindex] - -#define setvertex2tri(vx, value) \ - ((triangle *) (vx))[m->vertex2triindex] = value - -/** **/ -/** **/ -/********* Mesh manipulation primitives end here *********/ - -/********* User-defined triangle evaluation routine begins here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* triunsuitable() Determine if a triangle is unsuitable, and thus must */ -/* be further refined. */ -/* */ -/* You may write your own procedure that decides whether or not a selected */ -/* triangle is too big (and needs to be refined). There are two ways to do */ -/* this. */ -/* */ -/* (1) Modify the procedure `triunsuitable' below, then recompile */ -/* Triangle. */ -/* */ -/* (2) Define the symbol EXTERNAL_TEST (either by adding the definition */ -/* to this file, or by using the appropriate compiler switch). This way, */ -/* you can compile triangle.c separately from your test. Write your own */ -/* `triunsuitable' procedure in a separate C file (using the same prototype */ -/* as below). Compile it and link the object code with triangle.o. */ -/* */ -/* This procedure returns 1 if the triangle is too large and should be */ -/* refined; 0 otherwise. */ -/* */ -/*****************************************************************************/ - -#ifdef EXTERNAL_TEST - -int triunsuitable(); - -#else /* not EXTERNAL_TEST */ - -int triunsuitable(triorg, tridest, triapex, area) -vertex triorg; /* The triangle's origin vertex. */ -vertex tridest; /* The triangle's destination vertex. */ -vertex triapex; /* The triangle's apex vertex. */ -REAL area; /* The area of the triangle. */ -{ - REAL dxoa, dxda, dxod; - REAL dyoa, dyda, dyod; - REAL oalen, dalen, odlen; - REAL maxlen; - - dxoa = triorg[0] - triapex[0]; - dyoa = triorg[1] - triapex[1]; - dxda = tridest[0] - triapex[0]; - dyda = tridest[1] - triapex[1]; - dxod = triorg[0] - tridest[0]; - dyod = triorg[1] - tridest[1]; - /* Find the squares of the lengths of the triangle's three edges. */ - oalen = dxoa * dxoa + dyoa * dyoa; - dalen = dxda * dxda + dyda * dyda; - odlen = dxod * dxod + dyod * dyod; - /* Find the square of the length of the longest edge. */ - maxlen = (dalen > oalen) ? dalen : oalen; - maxlen = (odlen > maxlen) ? odlen : maxlen; - - if (maxlen > 0.05 * (triorg[0] * triorg[0] + triorg[1] * triorg[1]) + 0.02) { - return 1; - } else { - return 0; - } -} - -#endif /* not EXTERNAL_TEST */ - -/** **/ -/** **/ -/********* User-defined triangle evaluation routine ends here *********/ - -/********* Memory allocation wrappers begin here *********/ -/** **/ -/** **/ - -#ifdef ANSI_DECLARATORS -VOID *trimalloc(int size) -#else /* not ANSI_DECLARATORS */ -VOID *trimalloc(size) -int size; -#endif /* not ANSI_DECLARATORS */ - -{ - VOID *memptr; - - memptr = malloc((unsigned int) size); - if (memptr == (VOID *) NULL) { - printf("Error: Out of memory.\n"); - exit(1); - } - return(memptr); -} - -#ifdef ANSI_DECLARATORS -void trifree(VOID *memptr) -#else /* not ANSI_DECLARATORS */ -void trifree(memptr) -VOID *memptr; -#endif /* not ANSI_DECLARATORS */ - -{ - free(memptr); -} - -/** **/ -/** **/ -/********* Memory allocation wrappers end here *********/ - -/********* User interaction routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* syntax() Print list of command line switches. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -void syntax() -{ -#ifdef CDT_ONLY -#ifdef REDUCED - printf("triangle [-pAcjevngBPNEIOXzo_lQVh] input_file\n"); -#else /* not REDUCED */ - printf("triangle [-pAcjevngBPNEIOXzo_iFlCQVh] input_file\n"); -#endif /* not REDUCED */ -#else /* not CDT_ONLY */ -#ifdef REDUCED - printf("triangle [-prq__a__uAcjevngBPNEIOXzo_YS__LlQVh] input_file\n"); -#else /* not REDUCED */ - printf("triangle [-prq__a__uAcjevngBPNEIOXzo_YS__LiFlsCQVh] input_file\n"); -#endif /* not REDUCED */ -#endif /* not CDT_ONLY */ - - printf(" -p Triangulates a Planar Straight Line Graph (.poly file).\n"); -#ifndef CDT_ONLY - printf(" -r Refines a previously generated mesh.\n"); - printf( - " -q Quality mesh generation. A minimum angle may be specified.\n"); - printf(" -a Applies a maximum triangle area constraint.\n"); - printf(" -u Applies a user-defined triangle constraint.\n"); -#endif /* not CDT_ONLY */ - printf( - " -A Applies attributes to identify triangles in certain regions.\n"); - printf(" -c Encloses the convex hull with segments.\n"); - printf(" -w Weighted Delaunay triangulation.\n"); - printf(" -W Regular triangulation (lower hull of a height field).\n"); - printf(" -j Jettison unused vertices from output .node file.\n"); - printf(" -e Generates an edge list.\n"); - printf(" -v Generates a Voronoi diagram.\n"); - printf(" -n Generates a list of triangle neighbors.\n"); - printf(" -g Generates an .off file for Geomview.\n"); - printf(" -B Suppresses output of boundary information.\n"); - printf(" -P Suppresses output of .poly file.\n"); - printf(" -N Suppresses output of .node file.\n"); - printf(" -E Suppresses output of .ele file.\n"); - printf(" -I Suppresses mesh iteration numbers.\n"); - printf(" -O Ignores holes in .poly file.\n"); - printf(" -X Suppresses use of exact arithmetic.\n"); - printf(" -z Numbers all items starting from zero (rather than one).\n"); - printf(" -o2 Generates second-order subparametric elements.\n"); -#ifndef CDT_ONLY - printf(" -Y Suppresses boundary segment splitting.\n"); - printf(" -S Specifies maximum number of added Steiner points.\n"); - printf(" -L Uses equatorial circles, not equatorial lenses.\n"); -#endif /* not CDT_ONLY */ -#ifndef REDUCED - printf(" -i Uses incremental method, rather than divide-and-conquer.\n"); - printf(" -F Uses Fortune's sweepline algorithm, rather than d-and-c.\n"); -#endif /* not REDUCED */ - printf(" -l Uses vertical cuts only, rather than alternating cuts.\n"); -#ifndef REDUCED -#ifndef CDT_ONLY - printf( - " -s Force segments into mesh by splitting (instead of using CDT).\n"); - printf(" -L Uses Ruppert's diametral spheres, not diametral lenses.\n"); -#endif /* not CDT_ONLY */ - printf(" -C Check consistency of final mesh.\n"); -#endif /* not REDUCED */ - printf(" -Q Quiet: No terminal output except errors.\n"); - printf(" -V Verbose: Detailed information on what I'm doing.\n"); - printf(" -h Help: Detailed instructions for Triangle.\n"); - exit(0); -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* info() Print out complete instructions. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -void info() -{ - printf("Triangle\n"); - printf( -"A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n"); - printf("Version 1.5\n\n"); - printf( -"Copyright 1993, 1995, 1997, 1998, 2002, 2004 Jonathan Richard Shewchuk\n"); - printf("2360 Woolsey #H / Berkeley, California 94705-1927\n"); - printf("Bugs/comments to jrs@cs.berkeley.edu\n"); - printf( -"Created as part of the Archimedes project (tools for parallel FEM).\n"); - printf( -"Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n"); - printf("There is no warranty whatsoever. Use at your own risk.\n"); -#ifdef SINGLE - printf("This executable is compiled for single precision arithmetic.\n\n\n"); -#else /* not SINGLE */ - printf("This executable is compiled for double precision arithmetic.\n\n\n"); -#endif /* not SINGLE */ - printf( -"Triangle generates exact Delaunay triangulations, constrained Delaunay\n"); - printf( -"triangulations, Voronoi diagrams, and quality conforming Delaunay\n"); - printf( -"triangulations. The latter can be generated with no small angles, and are\n" -); - printf( -"thus suitable for finite element analysis. If no command line switches are\n" -); - printf( -"specified, your .node input file is read, and the Delaunay triangulation is\n" -); - printf("returned in .node and .ele output files. The command syntax is:\n"); - printf("\n"); - printf("triangle [-prq__a__uAcjevngBPNEIOXzo_YS__LiFlsCQVh] input_file\n"); - printf("\n"); - printf( -"Underscores indicate that numbers may optionally follow certain switches.\n"); - printf( -"Do not leave any space between a switch and its numeric parameter.\n"); - printf( -"input_file must be a file with extension .node, or extension .poly if the\n"); - printf( -"-p switch is used. If -r is used, you must supply .node and .ele files,\n"); - printf( -"and possibly a .poly file and an .area file as well. The formats of these\n" -); - printf("files are described below.\n\n"); - printf("Command Line Switches:\n\n"); - printf( -" -p Reads a Planar Straight Line Graph (.poly file), which can specify\n" -); - printf(" vertices, segments, holes, regional attributes, and area\n"); - printf( -" constraints. Generates a constrained Delaunay triangulation (CDT)\n" -); - printf( -" fitting the input; or, if -s, -q, -a, or -u is used, a conforming\n"); - printf( -" constrained Delaunay triangulation (CCDT). If -p is not used,\n"); - printf(" Triangle reads a .node file by default.\n"); - printf( -" -r Refines a previously generated mesh. The mesh is read from a .node\n" -); - printf( -" file and an .ele file. If -p is also used, a .poly file is read\n"); - printf( -" and used to constrain segments in the mesh. If -a is also used\n"); - printf( -" (with no number following), an .area file is read and used to\n"); - printf( -" impose area constraints on the mesh. Further details on refinement\n" -); - printf(" are given below.\n"); - printf( -" -q Quality mesh generation by my variant of Jim Ruppert's Delaunay\n"); - printf( -" refinement algorithm. Adds vertices to the mesh to ensure that no\n" -); - printf( -" angles smaller than 20 degrees occur. An alternative minimum angle\n" -); - printf( -" may be specified after the `q'. If the minimum angle is 20.7\n"); - printf( -" degrees or smaller, the triangulation algorithm is mathematically\n"); - printf( -" guaranteed to terminate (assuming infinite precision arithmetic--\n"); - printf( -" Triangle may fail to terminate if you run out of precision). In\n"); - printf( -" practice, the algorithm often succeeds for minimum angles up to\n"); - printf( -" 33.8 degrees. For some meshes, however, it may be necessary to\n"); - printf( -" reduce the minimum angle to avoid problems associated with\n"); - printf( -" insufficient floating-point precision. The specified angle may\n"); - printf(" include a decimal point.\n"); - printf( -" -a Imposes a maximum triangle area. If a number follows the `a', no\n"); - printf( -" triangle is generated whose area is larger than that number. If no\n" -); - printf( -" number is specified, an .area file (if -r is used) or .poly file\n"); - printf( -" (if -r is not used) specifies a set of maximum area constraints.\n"); - printf( -" An .area file contains a separate area constraint for each\n"); - printf( -" triangle, and is useful for refining a finite element mesh based on\n" -); - printf( -" a posteriori error estimates. A .poly file can optionally contain\n" -); - printf( -" an area constraint for each segment-bounded region, thereby\n"); - printf( -" controlling triangle densities in a first triangulation of a PSLG.\n" -); - printf( -" You can impose both a fixed area constraint and a varying area\n"); - printf( -" constraint by invoking the -a switch twice, once with and once\n"); - printf( -" without a number following. Each area specified may include a\n"); - printf(" decimal point.\n"); - printf( -" -u Imposes a user-defined constraint on triangle size. There are two\n" -); - printf( -" ways to use this feature. One is to edit the triunsuitable()\n"); - printf( -" procedure in triangle.c to encode any constraint you like, then\n"); - printf( -" recompile Triangle. The other is to compile triangle.c with the\n"); - printf( -" EXTERNAL_TEST symbol set (compiler switch -DEXTERNAL_TEST), then\n"); - printf( -" link Triangle against a separate object file that implements\n"); - printf( -" triunsuitable(). In either case, the -u switch causes the user-\n"); - printf(" defined test to be applied to every triangle.\n"); - printf( -" -A Assigns an additional attribute to each triangle that identifies\n"); - printf( -" what segment-bounded region each triangle belongs to. Attributes\n"); - printf( -" are assigned to regions by the .poly file. If a region is not\n"); - printf( -" explicitly marked by the .poly file, triangles in that region are\n"); - printf( -" assigned an attribute of zero. The -A switch has an effect only\n"); - printf(" when the -p switch is used and the -r switch is not.\n"); - printf( -" -c Creates segments on the convex hull of the triangulation. If you\n"); - printf( -" are triangulating a vertex set, this switch causes a .poly file to\n" -); - printf( -" be written, containing all edges in the convex hull. If you are\n"); - printf( -" triangulating a PSLG, this switch specifies that the whole convex\n"); - printf( -" hull of the PSLG should be triangulated, regardless of what\n"); - printf( -" segments the PSLG has. If you do not use this switch when\n"); - printf( -" triangulating a PSLG, it is assumed that you have identified the\n"); - printf( -" region to be triangulated by surrounding it with segments of the\n"); - printf( -" input PSLG. Beware: if you are not careful, this switch can cause\n" -); - printf( -" the introduction of an extremely thin angle between a PSLG segment\n" -); - printf( -" and a convex hull segment, which can cause overrefinement (and\n"); - printf( -" possibly failure if Triangle runs out of precision). If you are\n"); - printf( -" refining a mesh, the -c switch works differently; it generates the\n" -); - printf( -" set of boundary edges of the mesh (useful if no .poly file was\n"); - printf(" read).\n"); - printf( -" -j Jettisons vertices that are not part of the final triangulation\n"); - printf( -" from the output .node file. By default, Triangle copies all\n"); - printf( -" vertices in the input .node file to the output .node file, in the\n"); - printf( -" same order, so their indices do not change. The -j switch prevents\n" -); - printf( -" duplicated input vertices from appearing in the output .node file;\n" -); - printf( -" hence, if two input vertices have exactly the same coordinates,\n"); - printf( -" only the first appears in the output. If any vertices are\n"); - printf( -" jettisoned, the vertex numbering in the output .node file differs\n"); - printf(" from that of the input .node file.\n"); - printf( -" -e Outputs (to an .edge file) a list of edges of the triangulation.\n"); - printf( -" -v Outputs the Voronoi diagram associated with the triangulation.\n"); - printf( -" Does not attempt to detect degeneracies, so some Voronoi vertices\n"); - printf( -" may be duplicated. See the discussion of Voronoi diagrams below.\n"); - printf( -" -n Outputs (to a .neigh file) a list of triangles neighboring each\n"); - printf(" triangle.\n"); - printf( -" -g Outputs the mesh to an Object File Format (.off) file, suitable for\n" -); - printf(" viewing with the Geometry Center's Geomview package.\n"); - printf( -" -B No boundary markers in the output .node, .poly, and .edge output\n"); - printf( -" files. See the detailed discussion of boundary markers below.\n"); - printf( -" -P No output .poly file. Saves disk space, but you lose the ability\n"); - printf( -" to maintain constraining segments on later refinements of the mesh.\n" -); - printf(" -N No output .node file.\n"); - printf(" -E No output .ele file.\n"); - printf( -" -I No iteration numbers. Suppresses the output of .node and .poly\n"); - printf( -" files, so your input files won't be overwritten. (If your input is\n" -); - printf( -" a .poly file only, a .node file is written.) Cannot be used with\n"); - printf( -" the -r switch, because that would overwrite your input .ele file.\n"); - printf( -" Shouldn't be used with the -q, -a, -u, or -s switch if you are\n"); - printf( -" using a .node file for input, because no .node file is written, so\n" -); - printf(" there is no record of any added Steiner points.\n"); - printf(" -O No holes. Ignores the holes in the .poly file.\n"); - printf( -" -X No exact arithmetic. Normally, Triangle uses exact floating-point\n" -); - printf( -" arithmetic for certain tests if it thinks the inexact tests are not\n" -); - printf( -" accurate enough. Exact arithmetic ensures the robustness of the\n"); - printf( -" triangulation algorithms, despite floating-point roundoff error.\n"); - printf( -" Disabling exact arithmetic with the -X switch causes a small\n"); - printf( -" improvement in speed and creates the possibility (albeit small)\n"); - printf( -" that Triangle will fail to produce a valid mesh. Not recommended.\n" -); - printf( -" -z Numbers all items starting from zero (rather than one). Note that\n" -); - printf( -" this switch is normally overrided by the value used to number the\n"); - printf( -" first vertex of the input .node or .poly file. However, this\n"); - printf( -" switch is useful when calling Triangle from another program.\n"); - printf( -" -o2 Generates second-order subparametric elements with six nodes each.\n" -); - printf( -" -Y No new vertices on the boundary. This switch is useful when the\n"); - printf( -" mesh boundary must be preserved so that it conforms to some\n"); - printf( -" adjacent mesh. Be forewarned that you will probably sacrifice some\n" -); - printf( -" of the quality of the mesh; Triangle will try, but the resulting\n"); - printf( -" mesh may contain triangles of poor aspect ratio. Works well if all\n" -); - printf( -" the boundary vertices are closely spaced. Specify this switch\n"); - printf( -" twice (`-YY') to prevent all segment splitting, including internal\n" -); - printf(" boundaries.\n"); - printf( -" -S Specifies the maximum number of Steiner points (vertices that are\n"); - printf( -" not in the input, but are added to meet the constraints on minimum\n" -); - printf( -" angle and maximum area). The default is to allow an unlimited\n"); - printf( -" number. If you specify this switch with no number after it,\n"); - printf( -" the limit is set to zero. Triangle always adds vertices at segment\n" -); - printf( -" intersections, even if it needs to use more vertices than the limit\n" -); - printf( -" you set. When Triangle inserts segments by splitting (-s), it\n"); - printf( -" always adds enough vertices to ensure that all the segments of the\n" -); - printf(" PLSG are recovered, ignoring the limit if necessary.\n"); - printf( -" -L Do not use diametral lenses to determine whether subsegments are\n"); - printf( -" encroached; use diametral circles instead (as in Ruppert's\n"); - printf( -" algorithm). Use this switch if you want all triangles in the mesh\n" -); - printf( -" to be Delaunay, and not just constrained Delaunay; or if you want\n"); - printf( -" to ensure that all Voronoi vertices lie within the triangulation.\n"); - printf( -" (Applications such as some finite volume methods may have this\n"); - printf( -" requirement.) This switch may increase the number of vertices in\n"); - printf(" the mesh to meet these constraints.\n"); - printf( -" -i Uses an incremental rather than divide-and-conquer algorithm to\n"); - printf( -" form a Delaunay triangulation. Try it if the divide-and-conquer\n"); - printf(" algorithm fails.\n"); - printf( -" -F Uses Steven Fortune's sweepline algorithm to form a Delaunay\n"); - printf( -" triangulation. Warning: does not use exact arithmetic for all\n"); - printf(" calculations. An exact result is not guaranteed.\n"); - printf( -" -l Uses only vertical cuts in the divide-and-conquer algorithm. By\n"); - printf( -" default, Triangle uses alternating vertical and horizontal cuts,\n"); - printf( -" which usually improve the speed except with vertex sets that are\n"); - printf( -" small or short and wide. This switch is primarily of theoretical\n"); - printf(" interest.\n"); - printf( -" -s Specifies that segments should be forced into the triangulation by\n" -); - printf( -" recursively splitting them at their midpoints, rather than by\n"); - printf( -" generating a constrained Delaunay triangulation. Segment splitting\n" -); - printf( -" is true to Ruppert's original algorithm, but can create needlessly\n" -); - printf( -" small triangles. This switch is primarily of theoretical interest.\n" -); - printf( -" -C Check the consistency of the final mesh. Uses exact arithmetic for\n" -); - printf( -" checking, even if the -X switch is used. Useful if you suspect\n"); - printf(" Triangle is buggy.\n"); - printf( -" -Q Quiet: Suppresses all explanation of what Triangle is doing,\n"); - printf(" unless an error occurs.\n"); - printf( -" -V Verbose: Gives detailed information about what Triangle is doing.\n" -); - printf( -" Add more `V's for increasing amount of detail. `-V' gives\n"); - printf( -" information on algorithmic progress and more detailed statistics.\n"); - printf( -" `-VV' gives vertex-by-vertex details, and prints so much that\n"); - printf( -" Triangle runs much more slowly. `-VVVV' gives information only\n"); - printf(" a debugger could love.\n"); - printf(" -h Help: Displays these instructions.\n"); - printf("\n"); - printf("Definitions:\n"); - printf("\n"); - printf( -" A Delaunay triangulation of a vertex set is a triangulation whose\n"); - printf( -" vertices are the vertex set, wherein no vertex in the vertex set falls in\n" -); - printf( -" the interior of the circumcircle (circle that passes through all three\n"); - printf(" vertices) of any triangle in the triangulation.\n\n"); - printf( -" A Voronoi diagram of a vertex set is a subdivision of the plane into\n"); - printf( -" polygonal regions (some of which may be infinite), where each region is\n"); - printf( -" the set of points in the plane that are closer to some input vertex than\n" -); - printf( -" to any other input vertex. (The Voronoi diagram is the geometric dual of\n" -); - printf(" the Delaunay triangulation.)\n\n"); - printf( -" A Planar Straight Line Graph (PSLG) is a set of vertices and segments.\n"); - printf( -" Segments are simply edges, whose endpoints are vertices in the PSLG.\n"); - printf( -" Segments may intersect each other only at their endpoints. The file\n"); - printf(" format for PSLGs (.poly files) is described below.\n\n"); - printf( -" A constrained Delaunay triangulation (CDT) of a PSLG is similar to a\n"); - printf( -" Delaunay triangulation, but each PSLG segment is present as a single edge\n" -); - printf( -" in the triangulation. (A constrained Delaunay triangulation is not truly\n" -); - printf( -" a Delaunay triangulation.) By definition, a CDT does not have any\n"); - printf(" vertices other than those specified in the input PSLG.\n\n"); - printf( -" A conforming Delaunay triangulation of a PSLG is a true Delaunay\n"); - printf( -" triangulation in which each PSLG segment is represented by a linear\n"); - printf( -" contiguous sequence of edges in the triangulation. Each input segment\n"); - printf( -" may have been subdivided into shorter subsegments by the insertion of\n"); - printf( -" additional vertices. These inserted vertices are necessary to maintain\n"); - printf( -" the Delaunay property while ensuring that every segment is represented.\n"); - printf("\n"); - printf("File Formats:\n"); - printf("\n"); - printf( -" All files may contain comments prefixed by the character '#'. Vertices,\n" -); - printf( -" triangles, edges, holes, and maximum area constraints must be numbered\n"); - printf( -" consecutively, starting from either 1 or 0. Whichever you choose, all\n"); - printf( -" input files must be consistent; if the vertices are numbered from 1, so\n"); - printf( -" must be all other objects. Triangle automatically detects your choice\n"); - printf( -" while reading the .node (or .poly) file. (When calling Triangle from\n"); - printf( -" another program, use the -z switch if you wish to number objects from\n"); - printf(" zero.) Examples of these file formats are given below.\n\n"); - printf(" .node files:\n"); - printf( -" First line: <# of vertices> <dimension (must be 2)> <# of attributes>\n" -); - printf( -" <# of boundary markers (0 or 1)>\n" -); - printf( -" Remaining lines: <vertex #> <x> <y> [attributes] [boundary marker]\n"); - printf("\n"); - printf( -" The attributes, which are typically floating-point values of physical\n"); - printf( -" quantities (such as mass or conductivity) associated with the nodes of\n" -); - printf( -" a finite element mesh, are copied unchanged to the output mesh. If -q,\n" -); - printf( -" -a, -u, or -s is selected, each new Steiner point added to the mesh\n"); - printf(" has attributes assigned to it by linear interpolation.\n\n"); - printf( -" If the fourth entry of the first line is `1', the last column of the\n"); - printf( -" remainder of the file is assumed to contain boundary markers. Boundary\n" -); - printf( -" markers are used to identify boundary vertices and vertices resting on\n" -); - printf( -" PSLG segments; a complete description appears in a section below. The\n" -); - printf( -" .node file produced by Triangle contains boundary markers in the last\n"); - printf(" column unless they are suppressed by the -B switch.\n\n"); - printf(" .ele files:\n"); - printf( -" First line: <# of triangles> <nodes per triangle> <# of attributes>\n"); - printf( -" Remaining lines: <triangle #> <node> <node> <node> ... [attributes]\n"); - printf("\n"); - printf( -" Nodes are indices into the corresponding .node file. The first three\n"); - printf( -" nodes are the corner vertices, and are listed in counterclockwise order\n" -); - printf( -" around each triangle. (The remaining nodes, if any, depend on the type\n" -); - printf(" of finite element used.)\n\n"); - printf( -" The attributes are just like those of .node files. Because there is no\n" -); - printf( -" simple mapping from input to output triangles, an attempt is made to\n"); - printf( -" interpolate attributes, which may result in a good deal of diffusion of\n" -); - printf( -" attributes among nearby triangles as the triangulation is refined.\n"); - printf( -" Attributes do not diffuse across segments, so attributes used to\n"); - printf(" identify segment-bounded regions remain intact.\n\n"); - printf( -" In .ele files produced by Triangle, each triangular element has three\n"); - printf( -" nodes (vertices) unless the -o2 switch is used, in which case\n"); - printf( -" subparametric quadratic elements with six nodes each are generated.\n"); - printf( -" The first three nodes are the corners in counterclockwise order, and\n"); - printf( -" the fourth, fifth, and sixth nodes lie on the midpoints of the edges\n"); - printf( -" opposite the first, second, and third vertices, respectively.\n"); - printf("\n"); - printf(" .poly files:\n"); - printf( -" First line: <# of vertices> <dimension (must be 2)> <# of attributes>\n" -); - printf( -" <# of boundary markers (0 or 1)>\n" -); - printf( -" Following lines: <vertex #> <x> <y> [attributes] [boundary marker]\n"); - printf(" One line: <# of segments> <# of boundary markers (0 or 1)>\n"); - printf( -" Following lines: <segment #> <endpoint> <endpoint> [boundary marker]\n"); - printf(" One line: <# of holes>\n"); - printf(" Following lines: <hole #> <x> <y>\n"); - printf( -" Optional line: <# of regional attributes and/or area constraints>\n"); - printf( -" Optional following lines: <region #> <x> <y> <attribute> <max area>\n"); - printf("\n"); - printf( -" A .poly file represents a PSLG, as well as some additional information.\n" -); - printf( -" The first section lists all the vertices, and is identical to the\n"); - printf( -" format of .node files. <# of vertices> may be set to zero to indicate\n" -); - printf( -" that the vertices are listed in a separate .node file; .poly files\n"); - printf( -" produced by Triangle always have this format. A vertex set represented\n" -); - printf( -" this way has the advantage that it may easily be triangulated with or\n"); - printf( -" without segments (depending on whether the .poly or .node file is\n"); - printf(" read).\n\n"); - printf( -" The second section lists the segments. Segments are edges whose\n"); - printf( -" presence in the triangulation is enforced (although each segment may be\n" -); - printf( -" subdivided into smaller edges). Each segment is specified by listing\n"); - printf( -" the indices of its two endpoints. This means that you must include its\n" -); - printf( -" endpoints in the vertex list. Each segment, like each point, may have\n" -); - printf(" a boundary marker.\n\n"); - printf( -" If -q, -a, -u, and -s are not selected, Triangle produces a constrained\n" -); - printf( -" Delaunay triangulation (CDT), in which each segment appears as a single\n" -); - printf( -" edge in the triangulation. If -q, -a, -u, or -s is selected, Triangle\n" -); - printf( -" produces a conforming constrained Delaunay triangulation (CCDT), in\n"); - printf( -" which segments may be subdivided into smaller edges. If -L is selected\n" -); - printf( -" as well, Triangle produces a conforming Delaunay triangulation, so\n"); - printf( -" every triangle is Delaunay, and not just constrained Delaunay.\n"); - printf("\n"); - printf( -" The third section lists holes (and concavities, if -c is selected) in\n"); - printf( -" the triangulation. Holes are specified by identifying a point inside\n"); - printf( -" each hole. After the triangulation is formed, Triangle creates holes\n"); - printf( -" by eating triangles, spreading out from each hole point until its\n"); - printf( -" progress is blocked by PSLG segments; you must be careful to enclose\n"); - printf( -" each hole in segments, or your whole triangulation might be eaten away.\n" -); - printf( -" If the two triangles abutting a segment are eaten, the segment itself\n"); - printf( -" is also eaten. Do not place a hole directly on a segment; if you do,\n"); - printf(" Triangle chooses one side of the segment arbitrarily.\n\n"); - printf( -" The optional fourth section lists regional attributes (to be assigned\n"); - printf( -" to all triangles in a region) and regional constraints on the maximum\n"); - printf( -" triangle area. Triangle reads this section only if the -A switch is\n"); - printf( -" used or the -a switch is used without a number following it, and the -r\n" -); - printf( -" switch is not used. Regional attributes and area constraints are\n"); - printf( -" propagated in the same manner as holes; you specify a point for each\n"); - printf( -" attribute and/or constraint, and the attribute and/or constraint\n"); - printf( -" affects the whole region (bounded by segments) containing the point.\n"); - printf( -" If two values are written on a line after the x and y coordinate, the\n"); - printf( -" first such value is assumed to be a regional attribute (but is only\n"); - printf( -" applied if the -A switch is selected), and the second value is assumed\n" -); - printf( -" to be a regional area constraint (but is only applied if the -a switch\n" -); - printf( -" is selected). You may specify just one value after the coordinates,\n"); - printf( -" which can serve as both an attribute and an area constraint, depending\n" -); - printf( -" on the choice of switches. If you are using the -A and -a switches\n"); - printf( -" simultaneously and wish to assign an attribute to some region without\n"); - printf(" imposing an area constraint, use a negative maximum area.\n\n"); - printf( -" When a triangulation is created from a .poly file, you must either\n"); - printf( -" enclose the entire region to be triangulated in PSLG segments, or\n"); - printf( -" use the -c switch, which encloses the convex hull of the input vertex\n"); - printf( -" set. If you do not use the -c switch, Triangle eats all triangles that\n" -); - printf( -" are not enclosed by segments; if you are not careful, your whole\n"); - printf( -" triangulation may be eaten away. If you do use the -c switch, you can\n" -); - printf( -" still produce concavities by the appropriate placement of holes just\n"); - printf(" within the convex hull.\n\n"); - printf( -" An ideal PSLG has no intersecting segments, nor any vertices that lie\n"); - printf( -" upon segments (except, of course, the endpoints of each segment.) You\n" -); - printf( -" aren't required to make your .poly files ideal, but you should be aware\n" -); - printf( -" of what can go wrong. Segment intersections are relatively safe--\n"); - printf( -" Triangle calculates the intersection points for you and adds them to\n"); - printf( -" the triangulation--as long as your machine's floating-point precision\n"); - printf( -" doesn't become a problem. You are tempting the fates if you have three\n" -); - printf( -" segments that cross at the same location, and expect Triangle to figure\n" -); - printf( -" out where the intersection point is. Thanks to floating-point roundoff\n" -); - printf( -" error, Triangle will probably decide that the three segments intersect\n" -); - printf( -" at three different points, and you will find a minuscule triangle in\n"); - printf( -" your output--unless Triangle tries to refine the tiny triangle, uses\n"); - printf( -" up the last bit of machine precision, and fails to terminate at all.\n"); - printf( -" You're better off putting the intersection point in the input files,\n"); - printf( -" and manually breaking up each segment into two. Similarly, if you\n"); - printf( -" place a vertex at the middle of a segment, and hope that Triangle will\n" -); - printf( -" break up the segment at that vertex, you might get lucky. On the other\n" -); - printf( -" hand, Triangle might decide that the vertex doesn't lie precisely on\n"); - printf( -" the segment, and you'll have a needle-sharp triangle in your output--or\n" -); - printf(" a lot of tiny triangles if you're generating a quality mesh.\n"); - printf("\n"); - printf( -" When Triangle reads a .poly file, it also writes a .poly file, which\n"); - printf( -" includes all edges that are parts of input segments. If the -c switch\n" -); - printf( -" is used, the output .poly file also includes all of the edges on the\n"); - printf( -" convex hull. Hence, the output .poly file is useful for finding edges\n" -); - printf( -" associated with input segments and for setting boundary conditions in\n"); - printf( -" finite element simulations. Moreover, you will need it if you plan to\n" -); - printf( -" refine the output mesh, and don't want segments to be missing in later\n" -); - printf(" triangulations.\n\n"); - printf(" .area files:\n"); - printf(" First line: <# of triangles>\n"); - printf(" Following lines: <triangle #> <maximum area>\n\n"); - printf( -" An .area file associates with each triangle a maximum area that is used\n" -); - printf( -" for mesh refinement. As with other file formats, every triangle must\n"); - printf( -" be represented, and they must be numbered consecutively. A triangle\n"); - printf( -" may be left unconstrained by assigning it a negative maximum area.\n"); - printf("\n"); - printf(" .edge files:\n"); - printf(" First line: <# of edges> <# of boundary markers (0 or 1)>\n"); - printf( -" Following lines: <edge #> <endpoint> <endpoint> [boundary marker]\n"); - printf("\n"); - printf( -" Endpoints are indices into the corresponding .node file. Triangle can\n" -); - printf( -" produce .edge files (use the -e switch), but cannot read them. The\n"); - printf( -" optional column of boundary markers is suppressed by the -B switch.\n"); - printf("\n"); - printf( -" In Voronoi diagrams, one also finds a special kind of edge that is an\n"); - printf( -" infinite ray with only one endpoint. For these edges, a different\n"); - printf(" format is used:\n\n"); - printf(" <edge #> <endpoint> -1 <direction x> <direction y>\n\n"); - printf( -" The `direction' is a floating-point vector that indicates the direction\n" -); - printf(" of the infinite ray.\n\n"); - printf(" .neigh files:\n"); - printf( -" First line: <# of triangles> <# of neighbors per triangle (always 3)>\n" -); - printf( -" Following lines: <triangle #> <neighbor> <neighbor> <neighbor>\n"); - printf("\n"); - printf( -" Neighbors are indices into the corresponding .ele file. An index of -1\n" -); - printf( -" indicates no neighbor (because the triangle is on an exterior\n"); - printf( -" boundary). The first neighbor of triangle i is opposite the first\n"); - printf(" corner of triangle i, and so on.\n\n"); - printf( -" Triangle can produce .neigh files (use the -n switch), but cannot read\n" -); - printf(" them.\n\n"); - printf("Boundary Markers:\n\n"); - printf( -" Boundary markers are tags used mainly to identify which output vertices\n"); - printf( -" and edges are associated with which PSLG segment, and to identify which\n"); - printf( -" vertices and edges occur on a boundary of the triangulation. A common\n"); - printf( -" use is to determine where boundary conditions should be applied to a\n"); - printf( -" finite element mesh. You can prevent boundary markers from being written\n" -); - printf(" into files produced by Triangle by using the -B switch.\n\n"); - printf( -" The boundary marker associated with each segment in an output .poly file\n" -); - printf(" and each edge in an output .edge file is chosen as follows:\n"); - printf( -" - If an output edge is part or all of a PSLG segment with a nonzero\n"); - printf( -" boundary marker, then the edge is assigned the same marker.\n"); - printf( -" - Otherwise, if the edge occurs on a boundary of the triangulation\n"); - printf( -" (including boundaries of holes), then the edge is assigned the marker\n" -); - printf(" one (1).\n"); - printf(" - Otherwise, the edge is assigned the marker zero (0).\n"); - printf( -" The boundary marker associated with each vertex in an output .node file\n"); - printf(" is chosen as follows:\n"); - printf( -" - If a vertex is assigned a nonzero boundary marker in the input file,\n" -); - printf( -" then it is assigned the same marker in the output .node file.\n"); - printf( -" - Otherwise, if the vertex lies on a PSLG segment (including the\n"); - printf( -" segment's endpoints) with a nonzero boundary marker, then the vertex\n" -); - printf( -" is assigned the same marker. If the vertex lies on several such\n"); - printf(" segments, one of the markers is chosen arbitrarily.\n"); - printf( -" - Otherwise, if the vertex occurs on a boundary of the triangulation,\n"); - printf(" then the vertex is assigned the marker one (1).\n"); - printf(" - Otherwise, the vertex is assigned the marker zero (0).\n"); - printf("\n"); - printf( -" If you want Triangle to determine for you which vertices and edges are on\n" -); - printf( -" the boundary, assign them the boundary marker zero (or use no markers at\n" -); - printf( -" all) in your input files. In the output files, all boundary vertices,\n"); - printf(" edges, and segments are assigned the value one.\n\n"); - printf("Triangulation Iteration Numbers:\n\n"); - printf( -" Because Triangle can read and refine its own triangulations, input\n"); - printf( -" and output files have iteration numbers. For instance, Triangle might\n"); - printf( -" read the files mesh.3.node, mesh.3.ele, and mesh.3.poly, refine the\n"); - printf( -" triangulation, and output the files mesh.4.node, mesh.4.ele, and\n"); - printf(" mesh.4.poly. Files with no iteration number are treated as if\n"); - printf( -" their iteration number is zero; hence, Triangle might read the file\n"); - printf( -" points.node, triangulate it, and produce the files points.1.node and\n"); - printf(" points.1.ele.\n\n"); - printf( -" Iteration numbers allow you to create a sequence of successively finer\n"); - printf( -" meshes suitable for multigrid methods. They also allow you to produce a\n" -); - printf( -" sequence of meshes using error estimate-driven mesh refinement.\n"); - printf("\n"); - printf( -" If you're not using refinement or quality meshing, and you don't like\n"); - printf( -" iteration numbers, use the -I switch to disable them. This switch also\n"); - printf( -" disables output of .node and .poly files to prevent your input files from\n" -); - printf( -" being overwritten. (If the input is a .poly file that contains its own\n"); - printf(" points, a .node file is written.)\n\n"); - printf("Examples of How to Use Triangle:\n\n"); - printf( -" `triangle dots' reads vertices from dots.node, and writes their Delaunay\n" -); - printf( -" triangulation to dots.1.node and dots.1.ele. (dots.1.node is identical\n"); - printf( -" to dots.node.) `triangle -I dots' writes the triangulation to dots.ele\n"); - printf( -" instead. (No additional .node file is needed, so none is written.)\n"); - printf("\n"); - printf( -" `triangle -pe object.1' reads a PSLG from object.1.poly (and possibly\n"); - printf( -" object.1.node, if the vertices are omitted from object.1.poly) and writes\n" -); - printf( -" its constrained Delaunay triangulation to object.2.node and object.2.ele.\n" -); - printf( -" The segments are copied to object.2.poly, and all edges are written to\n"); - printf(" object.2.edge.\n\n"); - printf( -" `triangle -pq31.5a.1 object' reads a PSLG from object.poly (and possibly\n" -); - printf( -" object.node), generates a mesh whose angles are all 31.5 degrees or\n"); - printf( -" greater and whose triangles all have areas of 0.1 or less, and writes the\n" -); - printf( -" mesh to object.1.node and object.1.ele. Each segment may be broken up\n"); - printf(" into multiple subsegments; these are written to object.1.poly.\n"); - printf("\n"); - printf( -" Here is a sample file `box.poly' describing a square with a square hole:\n" -); - printf("\n"); - printf( -" # A box with eight vertices in 2D, no attributes, one boundary marker.\n" -); - printf(" 8 2 0 1\n"); - printf(" # Outer box has these vertices:\n"); - printf(" 1 0 0 0\n"); - printf(" 2 0 3 0\n"); - printf(" 3 3 0 0\n"); - printf(" 4 3 3 33 # A special marker for this vertex.\n"); - printf(" # Inner square has these vertices:\n"); - printf(" 5 1 1 0\n"); - printf(" 6 1 2 0\n"); - printf(" 7 2 1 0\n"); - printf(" 8 2 2 0\n"); - printf(" # Five segments with boundary markers.\n"); - printf(" 5 1\n"); - printf(" 1 1 2 5 # Left side of outer box.\n"); - printf(" # Square hole has these segments:\n"); - printf(" 2 5 7 0\n"); - printf(" 3 7 8 0\n"); - printf(" 4 8 6 10\n"); - printf(" 5 6 5 0\n"); - printf(" # One hole in the middle of the inner square.\n"); - printf(" 1\n"); - printf(" 1 1.5 1.5\n"); - printf("\n"); - printf( -" Note that some segments are missing from the outer square, so one must\n"); - printf( -" use the `-c' switch. After `triangle -pqc box.poly', here is the output\n" -); - printf( -" file `box.1.node', with twelve vertices. The last four vertices were\n"); - printf( -" added to meet the angle constraint. Vertices 1, 2, and 9 have markers\n"); - printf( -" from segment 1. Vertices 6 and 8 have markers from segment 4. All the\n"); - printf( -" other vertices but 4 have been marked to indicate that they lie on a\n"); - printf(" boundary.\n\n"); - printf(" 12 2 0 1\n"); - printf(" 1 0 0 5\n"); - printf(" 2 0 3 5\n"); - printf(" 3 3 0 1\n"); - printf(" 4 3 3 33\n"); - printf(" 5 1 1 1\n"); - printf(" 6 1 2 10\n"); - printf(" 7 2 1 1\n"); - printf(" 8 2 2 10\n"); - printf(" 9 0 1.5 5\n"); - printf(" 10 1.5 0 1\n"); - printf(" 11 3 1.5 1\n"); - printf(" 12 1.5 3 1\n"); - printf(" # Generated by triangle -pqc box.poly\n"); - printf("\n"); - printf(" Here is the output file `box.1.ele', with twelve triangles.\n"); - printf("\n"); - printf(" 12 3 0\n"); - printf(" 1 5 6 9\n"); - printf(" 2 10 3 7\n"); - printf(" 3 6 8 12\n"); - printf(" 4 9 1 5\n"); - printf(" 5 6 2 9\n"); - printf(" 6 7 3 11\n"); - printf(" 7 11 4 8\n"); - printf(" 8 7 5 10\n"); - printf(" 9 12 2 6\n"); - printf(" 10 8 7 11\n"); - printf(" 11 5 1 10\n"); - printf(" 12 8 4 12\n"); - printf(" # Generated by triangle -pqc box.poly\n\n"); - printf( -" Here is the output file `box.1.poly'. Note that segments have been added\n" -); - printf( -" to represent the convex hull, and some segments have been split by newly\n" -); - printf( -" added vertices. Note also that <# of vertices> is set to zero to\n"); - printf(" indicate that the vertices should be read from the .node file.\n"); - printf("\n"); - printf(" 0 2 0 1\n"); - printf(" 12 1\n"); - printf(" 1 1 9 5\n"); - printf(" 2 5 7 1\n"); - printf(" 3 8 7 1\n"); - printf(" 4 6 8 10\n"); - printf(" 5 5 6 1\n"); - printf(" 6 3 10 1\n"); - printf(" 7 4 11 1\n"); - printf(" 8 2 12 1\n"); - printf(" 9 9 2 5\n"); - printf(" 10 10 1 1\n"); - printf(" 11 11 3 1\n"); - printf(" 12 12 4 1\n"); - printf(" 1\n"); - printf(" 1 1.5 1.5\n"); - printf(" # Generated by triangle -pqc box.poly\n"); - printf("\n"); - printf("Refinement and Area Constraints:\n"); - printf("\n"); - printf( -" The -r switch causes a mesh (.node and .ele files) to be read and\n"); - printf( -" refined. If the -p switch is also used, a .poly file is read and used to\n" -); - printf( -" specify edges that are constrained and cannot be eliminated (although\n"); - printf( -" they can be divided into smaller edges) by the refinement process.\n"); - printf("\n"); - printf( -" When you refine a mesh, you generally want to impose tighter quality\n"); - printf( -" constraints. One way to accomplish this is to use -q with a larger\n"); - printf( -" angle, or -a followed by a smaller area than you used to generate the\n"); - printf( -" mesh you are refining. Another way to do this is to create an .area\n"); - printf( -" file, which specifies a maximum area for each triangle, and use the -a\n"); - printf( -" switch (without a number following). Each triangle's area constraint is\n" -); - printf( -" applied to that triangle. Area constraints tend to diffuse as the mesh\n"); - printf( -" is refined, so if there are large variations in area constraint between\n"); - printf(" adjacent triangles, you may not get the results you want.\n\n"); - printf( -" If you are refining a mesh composed of linear (three-node) elements, the\n" -); - printf( -" output mesh contains all the nodes present in the input mesh, in the same\n" -); - printf( -" order, with new nodes added at the end of the .node file. However, the\n"); - printf( -" refinement is not hierarchical: there is no guarantee that each output\n"); - printf( -" element is contained in a single input element. Often, output elements\n"); - printf( -" overlap two input elements, and some input edges are not present in the\n"); - printf( -" output mesh. Hence, a sequence of refined meshes forms a hierarchy of\n"); - printf( -" nodes, but not a hierarchy of elements. If you refine a mesh of higher-\n" -); - printf( -" order elements, the hierarchical property applies only to the nodes at\n"); - printf( -" the corners of an element; other nodes may not be present in the refined\n" -); - printf(" mesh.\n\n"); - printf( -" Maximum area constraints in .poly files operate differently from those in\n" -); - printf( -" .area files. A maximum area in a .poly file applies to the whole\n"); - printf( -" (segment-bounded) region in which a point falls, whereas a maximum area\n"); - printf( -" in an .area file applies to only one triangle. Area constraints in .poly\n" -); - printf( -" files are used only when a mesh is first generated, whereas area\n"); - printf( -" constraints in .area files are used only to refine an existing mesh, and\n" -); - printf( -" are typically based on a posteriori error estimates resulting from a\n"); - printf(" finite element simulation on that mesh.\n\n"); - printf( -" `triangle -rq25 object.1' reads object.1.node and object.1.ele, then\n"); - printf( -" refines the triangulation to enforce a 25 degree minimum angle, and then\n" -); - printf( -" writes the refined triangulation to object.2.node and object.2.ele.\n"); - printf("\n"); - printf( -" `triangle -rpaa6.2 z.3' reads z.3.node, z.3.ele, z.3.poly, and z.3.area.\n" -); - printf( -" After reconstructing the mesh and its subsegments, Triangle refines the\n"); - printf( -" mesh so that no triangle has area greater than 6.2, and furthermore the\n"); - printf( -" triangles satisfy the maximum area constraints in z.3.area. No angle\n"); - printf( -" bound is imposed at all. The output is written to z.4.node, z.4.ele, and\n" -); - printf(" z.4.poly.\n\n"); - printf( -" The sequence `triangle -qa1 x', `triangle -rqa.3 x.1', `triangle -rqa.1\n"); - printf( -" x.2' creates a sequence of successively finer meshes x.1, x.2, and x.3,\n"); - printf(" suitable for multigrid.\n\n"); - printf("Convex Hulls and Mesh Boundaries:\n\n"); - printf( -" If the input is a vertex set (rather than a PSLG), Triangle produces its\n" -); - printf( -" convex hull as a by-product in the output .poly file if you use the -c\n"); - printf( -" switch. There are faster algorithms for finding a two-dimensional convex\n" -); - printf( -" hull than triangulation, of course, but this one comes for free.\n"); - printf("\n"); - printf( -" If the input is an unconstrained mesh (you are using the -r switch but\n"); - printf( -" not the -p switch), Triangle produces a list of its boundary edges\n"); - printf( -" (including hole boundaries) as a by-product when you use the -c switch.\n"); - printf( -" If you also use the -p switch, the output .poly file contains all the\n"); - printf(" segments from the input .poly file as well.\n\n"); - printf("Voronoi Diagrams:\n\n"); - printf( -" The -v switch produces a Voronoi diagram, in files suffixed .v.node and\n"); - printf( -" .v.edge. For example, `triangle -v points' reads points.node, produces\n"); - printf( -" its Delaunay triangulation in points.1.node and points.1.ele, and\n"); - printf( -" produces its Voronoi diagram in points.1.v.node and points.1.v.edge. The\n" -); - printf( -" .v.node file contains a list of all Voronoi vertices, and the .v.edge\n"); - printf( -" file contains a list of all Voronoi edges, some of which may be infinite\n" -); - printf( -" rays. (The choice of filenames makes it easy to run the set of Voronoi\n"); - printf(" vertices through Triangle, if so desired.)\n\n"); - printf( -" This implementation does not use exact arithmetic to compute the Voronoi\n" -); - printf( -" vertices, and does not check whether neighboring vertices are identical.\n" -); - printf( -" Be forewarned that if the Delaunay triangulation is degenerate or\n"); - printf( -" near-degenerate, the Voronoi diagram may have duplicate vertices,\n"); - printf( -" crossing edges, or infinite rays whose direction vector is zero.\n"); - printf("\n"); - printf( -" The result is a valid Voronoi diagram only if Triangle's output is a true\n" -); - printf( -" Delaunay triangulation. The Voronoi output is usually meaningless (and\n"); - printf( -" may contain crossing edges and other pathology) if the output is a CDT or\n" -); - printf( -" CCDT, or if it has holes or concavities. If the triangulation is convex\n" -); - printf( -" and has no holes, this can be fixed by using the -L switch to ensure a\n"); - printf(" conforming Delaunay triangulation is constructed.\n\n"); - printf("Mesh Topology:\n\n"); - printf( -" You may wish to know which triangles are adjacent to a certain Delaunay\n"); - printf( -" edge in an .edge file, which Voronoi regions are adjacent to a certain\n"); - printf( -" Voronoi edge in a .v.edge file, or which Voronoi regions are adjacent to\n" -); - printf( -" each other. All of this information can be found by cross-referencing\n"); - printf( -" output files with the recollection that the Delaunay triangulation and\n"); - printf(" the Voronoi diagram are planar duals.\n\n"); - printf( -" Specifically, edge i of an .edge file is the dual of Voronoi edge i of\n"); - printf( -" the corresponding .v.edge file, and is rotated 90 degrees counterclock-\n"); - printf( -" wise from the Voronoi edge. Triangle j of an .ele file is the dual of\n"); - printf( -" vertex j of the corresponding .v.node file. Voronoi region k is the dual\n" -); - printf(" of vertex k of the corresponding .node file.\n\n"); - printf( -" Hence, to find the triangles adjacent to a Delaunay edge, look at the\n"); - printf( -" vertices of the corresponding Voronoi edge. If the endpoints of a\n"); - printf( -" Voronoi edge are Voronoi vertices 2 and 6 respectively, then triangles 2\n" -); - printf( -" and 6 adjoin the left and right sides of the corresponding Delaunay edge,\n" -); - printf( -" respectively. To find the Voronoi regions adjacent to a Voronoi edge,\n"); - printf( -" look at the endpoints of the corresponding Delaunay edge. If the\n"); - printf( -" endpoints of a Delaunay edge are input vertices 7 and 12, then Voronoi\n"); - printf( -" regions 7 and 12 adjoin the right and left sides of the corresponding\n"); - printf( -" Voronoi edge, respectively. To find which Voronoi regions are adjacent\n"); - printf(" to each other, just read the list of Delaunay edges.\n\n"); - printf( -" Triangle does not write a list of Voronoi regions, but one can be\n"); - printf( -" reconstructed straightforwardly. For instance, to find all the edges of\n" -); - printf( -" Voronoi region 1, search the output .edge file for every edge that has\n"); - printf( -" input vertex 1 as an endpoint. The corresponding dual edges in the\n"); - printf(" output .v.edge file form the boundary of Voronoi region 1.\n\n"); - printf("Quadratic Elements:\n\n"); - printf( -" Triangle generates meshes with subparametric quadratic elements if the\n"); - printf( -" -o2 switch is specified. Quadratic elements have six nodes per element,\n" -); - printf( -" rather than three. `Subparametric' means that the edges of the triangles\n" -); - printf( -" are always straight, so that subparametric quadratic elements are\n"); - printf( -" geometrically identical to linear elements, even though they can be used\n" -); - printf( -" with quadratic interpolating functions. The three extra nodes of an\n"); - printf( -" element fall at the midpoints of the three edges, with the fourth, fifth,\n" -); - printf( -" and sixth nodes appearing opposite the first, second, and third corners\n"); - printf(" respectively.\n\n"); - printf("Statistics:\n\n"); - printf( -" After generating a mesh, Triangle prints a count of the number of\n"); - printf( -" vertices, triangles, edges, exterior boundary edges (including hole\n"); - printf( -" boundaries), interior boundary edges, and segments in the output mesh.\n"); - printf( -" If you've forgotten the statistics for an existing mesh, run Triangle on\n" -); - printf( -" that mesh with the -rNEP switches to read the mesh and print the\n"); - printf( -" statistics without writing any files. Use -rpNEP if you've got a .poly\n"); - printf(" file for the mesh.\n\n"); - printf( -" The -V switch produces extended statistics, including a rough estimate\n"); - printf( -" of memory use, the number of calls to geometric predicates, and\n"); - printf(" histograms of triangle aspect ratios and angles in the mesh.\n\n"); - printf("Exact Arithmetic:\n\n"); - printf( -" Triangle uses adaptive exact arithmetic to perform what computational\n"); - printf( -" geometers call the `orientation' and `incircle' tests. If the floating-\n" -); - printf( -" point arithmetic of your machine conforms to the IEEE 754 standard (as\n"); - printf( -" most workstations do), and does not use extended precision internal\n"); - printf( -" floating-point registers, then your output is guaranteed to be an\n"); - printf( -" absolutely true Delaunay or constrained Delaunay triangulation, roundoff\n" -); - printf( -" error notwithstanding. The word `adaptive' implies that these arithmetic\n" -); - printf( -" routines compute the result only to the precision necessary to guarantee\n" -); - printf( -" correctness, so they are usually nearly as fast as their approximate\n"); - printf(" counterparts.\n\n"); - printf( -" Pentiums have extended precision floating-point registers. These must be\n" -); - printf( -" reconfigured so their precision is reduced to memory precision. Triangle\n" -); - printf( -" does this if it is compiled correctly. See the makefile for details.\n"); - printf("\n"); - printf( -" The exact tests can be disabled with the -X switch. On most inputs, this\n" -); - printf( -" switch reduces the computation time by about eight percent--it's not\n"); - printf( -" worth the risk. There are rare difficult inputs (having many collinear\n"); - printf( -" and cocircular vertices), however, for which the difference in speed\n"); - printf( -" could be a factor of two. Be forewarned that these are precisely the\n"); - printf( -" inputs most likely to cause errors if you use the -X switch. Hence, the\n" -); - printf(" -X switch is not recommended.\n\n"); - printf( -" Unfortunately, the exact tests don't solve every numerical problem.\n"); - printf( -" Exact arithmetic is not used to compute the positions of new vertices,\n"); - printf( -" because the bit complexity of vertex coordinates would grow without\n"); - printf( -" bound. Hence, segment intersections aren't computed exactly; in very\n"); - printf( -" unusual cases, roundoff error in computing an intersection point might\n"); - printf( -" actually lead to an inverted triangle and an invalid triangulation.\n"); - printf( -" (This is one reason to compute your own intersection points in your .poly\n" -); - printf( -" files.) Similarly, exact arithmetic is not used to compute the vertices\n" -); - printf(" of the Voronoi diagram.\n\n"); - printf( -" Another pair of problems not solved by the exact arithmetic routines is\n"); - printf( -" underflow and overflow. If Triangle is compiled for double precision\n"); - printf( -" arithmetic, I believe that Triangle's geometric predicates work correctly\n" -); - printf( -" if the exponent of every input coordinate falls in the range [-148, 201].\n" -); - printf( -" Underflow can silently prevent the orientation and incircle tests from\n"); - printf( -" being performed exactly, while overflow typically causes a floating\n"); - printf(" exception.\n\n"); - printf("Calling Triangle from Another Program:\n\n"); - printf(" Read the file triangle.h for details.\n\n"); - printf("Troubleshooting:\n\n"); - printf(" Please read this section before mailing me bugs.\n\n"); - printf(" `My output mesh has no triangles!'\n\n"); - printf( -" If you're using a PSLG, you've probably failed to specify a proper set\n" -); - printf( -" of bounding segments, or forgotten to use the -c switch. Or you may\n"); - printf( -" have placed a hole badly, thereby eating all your triangles. To test\n"); - printf(" these possibilities, try again with the -c and -O switches.\n"); - printf( -" Alternatively, all your input vertices may be collinear, in which case\n" -); - printf(" you can hardly expect to triangulate them.\n\n"); - printf(" `Triangle doesn't terminate, or just crashes.'\n\n"); - printf( -" Bad things can happen when triangles get so small that the distance\n"); - printf( -" between their vertices isn't much larger than the precision of your\n"); - printf( -" machine's arithmetic. If you've compiled Triangle for single-precision\n" -); - printf( -" arithmetic, you might do better by recompiling it for double-precision.\n" -); - printf( -" Then again, you might just have to settle for more lenient constraints\n" -); - printf( -" on the minimum angle and the maximum area than you had planned.\n"); - printf("\n"); - printf( -" You can minimize precision problems by ensuring that the origin lies\n"); - printf( -" inside your vertex set, or even inside the densest part of your\n"); - printf( -" mesh. If you're triangulating an object whose x coordinates all fall\n"); - printf( -" between 6247133 and 6247134, you're not leaving much floating-point\n"); - printf(" precision for Triangle to work with.\n\n"); - printf( -" Precision problems can occur covertly if the input PSLG contains two\n"); - printf( -" segments that meet (or intersect) at an extremely small angle, or if\n"); - printf( -" such an angle is introduced by the -c switch. If you don't realize\n"); - printf( -" that a tiny angle is being formed, you might never discover why\n"); - printf( -" Triangle is crashing. To check for this possibility, use the -S switch\n" -); - printf( -" (with an appropriate limit on the number of Steiner points, found by\n"); - printf( -" trial-and-error) to stop Triangle early, and view the output .poly file\n" -); - printf( -" with Show Me (described below). Look carefully for regions where dense\n" -); - printf( -" clusters of vertices are forming and for small angles between segments.\n" -); - printf( -" Zoom in closely, as such segments might look like a single segment from\n" -); - printf(" a distance.\n\n"); - printf( -" If some of the input values are too large, Triangle may suffer a\n"); - printf( -" floating exception due to overflow when attempting to perform an\n"); - printf( -" orientation or incircle test. (Read the section on exact arithmetic\n"); - printf( -" above.) Again, I recommend compiling Triangle for double (rather\n"); - printf(" than single) precision arithmetic.\n\n"); - printf( -" Unexpected problems can arise if you use quality meshing (-q, -a, or\n"); - printf( -" -u) with an input that is not segment-bounded--that is, if your input\n"); - printf( -" is a vertex set, or you're using the -c switch. If the convex hull of\n" -); - printf( -" your input vertices has collinear vertices on its boundary, an input\n"); - printf( -" vertex that you think lies on the convex hull might actually lie just\n"); - printf( -" inside the convex hull. If so, an extremely thin triangle is formed by\n" -); - printf( -" the vertex and the convex hull edge beside it. When Triangle tries to\n" -); - printf( -" refine the mesh to enforce angle and area constraints, extremely tiny\n"); - printf( -" triangles may be formed, or Triangle may fail because of insufficient\n"); - printf(" floating-point precision.\n\n"); - printf( -" `The numbering of the output vertices doesn't match the input vertices.'\n" -); - printf("\n"); - printf( -" You may have had duplicate input vertices, or you may have eaten some\n"); - printf( -" of your input vertices with a hole, or by placing them outside the area\n" -); - printf( -" enclosed by segments. In any case, you can solve the problem by not\n"); - printf(" using the -j switch.\n\n"); - printf( -" `Triangle executes without incident, but when I look at the resulting\n"); - printf( -" mesh, it has overlapping triangles or other geometric inconsistencies.'\n"); - printf("\n"); - printf( -" If you select the -X switch, Triangle occasionally makes mistakes due\n"); - printf( -" to floating-point roundoff error. Although these errors are rare,\n"); - printf( -" don't use the -X switch. If you still have problems, please report the\n" -); - printf(" bug.\n\n"); - printf( -" Strange things can happen if you've taken liberties with your PSLG. Do\n"); - printf( -" you have a vertex lying in the middle of a segment? Triangle sometimes\n"); - printf( -" copes poorly with that sort of thing. Do you want to lay out a collinear\n" -); - printf( -" row of evenly spaced, segment-connected vertices? Have you simply\n"); - printf( -" defined one long segment connecting the leftmost vertex to the rightmost\n" -); - printf( -" vertex, and a bunch of vertices lying along it? This method occasionally\n" -); - printf( -" works, especially with horizontal and vertical lines, but often it\n"); - printf( -" doesn't, and you'll have to connect each adjacent pair of vertices with a\n" -); - printf(" separate segment. If you don't like it, tough.\n\n"); - printf( -" Furthermore, if you have segments that intersect other than at their\n"); - printf( -" endpoints, try not to let the intersections fall extremely close to PSLG\n" -); - printf(" vertices or each other.\n\n"); - printf( -" If you have problems refining a triangulation not produced by Triangle:\n"); - printf( -" Are you sure the triangulation is geometrically valid? Is it formatted\n"); - printf( -" correctly for Triangle? Are the triangles all listed so the first three\n" -); - printf( -" vertices are their corners in counterclockwise order? Are all of the\n"); - printf( -" triangles constrained Delaunay? Triangle's Delaunay refinement algorithm\n" -); - printf(" assumes that it starts with a CDT.\n\n"); - printf("Show Me:\n\n"); - printf( -" Triangle comes with a separate program named `Show Me', whose primary\n"); - printf( -" purpose is to draw meshes on your screen or in PostScript. Its secondary\n" -); - printf( -" purpose is to check the validity of your input files, and do so more\n"); - printf( -" thoroughly than Triangle does. Unlike Triangle, Show Me requires that\n"); - printf(" you have the X Windows system.\n\n"); - printf("Triangle on the Web:\n\n"); - printf( -" To see an illustrated, updated version of these instructions, check out\n"); - printf("\n"); - printf(" http://www.cs.cmu.edu/~quake/triangle.html\n"); - printf("\n"); - printf("A Brief Plea:\n"); - printf("\n"); - printf( -" If you use Triangle, and especially if you use it to accomplish real\n"); - printf( -" work, I would like very much to hear from you. A short letter or email\n"); - printf( -" (to jrs@cs.berkeley.edu) describing how you use Triangle will mean a lot\n" -); - printf( -" to me. The more people I know are using this program, the more easily I\n" -); - printf( -" can justify spending time on improvements, which in turn will benefit\n"); - printf( -" you. Also, I can put you on a list to receive email whenever a new\n"); - printf(" version of Triangle is available.\n\n"); - printf( -" If you use a mesh generated by Triangle in a publication, please include\n" -); - printf(" an acknowledgment as well.\n\n"); - printf("Research credit:\n\n"); - printf( -" Of course, I can take credit for only a fraction of the ideas that made\n"); - printf( -" this mesh generator possible. Triangle owes its existence to the efforts\n" -); - printf( -" of many fine computational geometers and other researchers, including\n"); - printf( -" Marshall Bern, L. Paul Chew, Boris Delaunay, Rex A. Dwyer, David\n"); - printf( -" Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E. Knuth, Charles L.\n" -); - printf( -" Lawson, Der-Tsai Lee, Ernst P. Mucke, Douglas M. Priest, Jim Ruppert,\n"); - printf( -" Isaac Saias, Bruce J. Schachter, Micha Sharir, Daniel D. Sleator, Jorge\n"); - printf( -" Stolfi, Robert E. Tarjan, Alper Ungor, Christopher J. Van Wyk, and Binhai\n" -); - printf(" Zhu. See the comments at the beginning of the source code for\n"); - printf(" references.\n\n"); - exit(0); -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* internalerror() Ask the user to send me the defective product. Exit. */ -/* */ -/*****************************************************************************/ - -void internalerror() -{ - printf(" Please report this bug to jrs@cs.berkeley.edu\n"); - printf(" Include the message above, your input data set, and the exact\n"); - printf(" command line you used to run Triangle.\n"); - exit(1); -} - -/*****************************************************************************/ -/* */ -/* parsecommandline() Read the command line, identify switches, and set */ -/* up options and file names. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void parsecommandline(int argc, char **argv, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void parsecommandline(argc, argv, b) -int argc; -char **argv; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ -#ifdef TRILIBRARY -#define STARTINDEX 0 -#else /* not TRILIBRARY */ -#define STARTINDEX 1 - int increment; - int meshnumber; -#endif /* not TRILIBRARY */ - int i, j, k; - char workstring[FILENAMESIZE]; - - b->poly = b->refine = b->quality = 0; - b->vararea = b->fixedarea = b->usertest = 0; - b->regionattrib = b->convex = b->weighted = b->jettison = 0; - b->firstnumber = 1; - b->edgesout = b->voronoi = b->neighbors = b->geomview = 0; - b->nobound = b->nopolywritten = b->nonodewritten = b->noelewritten = 0; - b->noiterationnum = 0; - b->noholes = b->noexact = 0; - b->incremental = b->sweepline = 0; - b->dwyer = 1; - b->splitseg = 0; - b->docheck = 0; - b->nobisect = 0; - b->nolenses = 0; - b->steiner = -1; - b->order = 1; - b->minangle = 0.0; - b->maxarea = -1.0; - b->quiet = b->verbose = 0; -#ifndef TRILIBRARY - b->innodefilename[0] = '\0'; -#endif /* not TRILIBRARY */ - - for (i = STARTINDEX; i < argc; i++) { -#ifndef TRILIBRARY - if (argv[i][0] == '-') { -#endif /* not TRILIBRARY */ - for (j = STARTINDEX; argv[i][j] != '\0'; j++) { - if (argv[i][j] == 'p') { - b->poly = 1; - } -#ifndef CDT_ONLY - if (argv[i][j] == 'r') { - b->refine = 1; - } - if (argv[i][j] == 'q') { - b->quality = 1; - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - b->minangle = (REAL) strtod(workstring, (char **) NULL); - } else { - b->minangle = 20.0; - } - } - if (argv[i][j] == 'a') { - b->quality = 1; - if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - b->fixedarea = 1; - k = 0; - while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) || - (argv[i][j + 1] == '.')) { - j++; - workstring[k] = argv[i][j]; - k++; - } - workstring[k] = '\0'; - b->maxarea = (REAL) strtod(workstring, (char **) NULL); - if (b->maxarea <= 0.0) { - printf("Error: Maximum area must be greater than zero.\n"); - exit(1); - } - } else { - b->vararea = 1; - } - } - if (argv[i][j] == 'u') { - b->quality = 1; - b->usertest = 1; - } -#endif /* not CDT_ONLY */ - if (argv[i][j] == 'A') { - b->regionattrib = 1; - } - if (argv[i][j] == 'c') { - b->convex = 1; - } - if (argv[i][j] == 'w') { - b->weighted = 1; - } - if (argv[i][j] == 'W') { - b->weighted = 2; - } - if (argv[i][j] == 'j') { - b->jettison = 1; - } - if (argv[i][j] == 'z') { - b->firstnumber = 0; - } - if (argv[i][j] == 'e') { - b->edgesout = 1; - } - if (argv[i][j] == 'v') { - b->voronoi = 1; - } - if (argv[i][j] == 'n') { - b->neighbors = 1; - } - if (argv[i][j] == 'g') { - b->geomview = 1; - } - if (argv[i][j] == 'B') { - b->nobound = 1; - } - if (argv[i][j] == 'P') { - b->nopolywritten = 1; - } - if (argv[i][j] == 'N') { - b->nonodewritten = 1; - } - if (argv[i][j] == 'E') { - b->noelewritten = 1; - } -#ifndef TRILIBRARY - if (argv[i][j] == 'I') { - b->noiterationnum = 1; - } -#endif /* not TRILIBRARY */ - if (argv[i][j] == 'O') { - b->noholes = 1; - } - if (argv[i][j] == 'X') { - b->noexact = 1; - } - if (argv[i][j] == 'o') { - if (argv[i][j + 1] == '2') { - j++; - b->order = 2; - } - } -#ifndef CDT_ONLY - if (argv[i][j] == 'Y') { - b->nobisect++; - } - if (argv[i][j] == 'S') { - b->steiner = 0; - while ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) { - j++; - b->steiner = b->steiner * 10 + (int) (argv[i][j] - '0'); - } - } -#endif /* not CDT_ONLY */ -#ifndef REDUCED - if (argv[i][j] == 'i') { - b->incremental = 1; - } - if (argv[i][j] == 'F') { - b->sweepline = 1; - } -#endif /* not REDUCED */ - if (argv[i][j] == 'l') { - b->dwyer = 0; - } -#ifndef REDUCED -#ifndef CDT_ONLY - if (argv[i][j] == 's') { - b->splitseg = 1; - } - if (argv[i][j] == 'L') { - b->nolenses = 1; - } -#endif /* not CDT_ONLY */ - if (argv[i][j] == 'C') { - b->docheck = 1; - } -#endif /* not REDUCED */ - if (argv[i][j] == 'Q') { - b->quiet = 1; - } - if (argv[i][j] == 'V') { - b->verbose++; - } -#ifndef TRILIBRARY - if ((argv[i][j] == 'h') || (argv[i][j] == 'H') || - (argv[i][j] == '?')) { - info(); - } -#endif /* not TRILIBRARY */ - } -#ifndef TRILIBRARY - } else { - strncpy(b->innodefilename, argv[i], FILENAMESIZE - 1); - b->innodefilename[FILENAMESIZE - 1] = '\0'; - } -#endif /* not TRILIBRARY */ - } -#ifndef TRILIBRARY - if (b->innodefilename[0] == '\0') { - syntax(); - } - if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".node")) { - b->innodefilename[strlen(b->innodefilename) - 5] = '\0'; - } - if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".poly")) { - b->innodefilename[strlen(b->innodefilename) - 5] = '\0'; - b->poly = 1; - } -#ifndef CDT_ONLY - if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 4], ".ele")) { - b->innodefilename[strlen(b->innodefilename) - 4] = '\0'; - b->refine = 1; - } - if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".area")) { - b->innodefilename[strlen(b->innodefilename) - 5] = '\0'; - b->refine = 1; - b->quality = 1; - b->vararea = 1; - } -#endif /* not CDT_ONLY */ -#endif /* not TRILIBRARY */ - b->usesegments = b->poly || b->refine || b->quality || b->convex; - b->goodangle = cos(b->minangle * PI / 180.0); - if (b->goodangle == 1.0) { - b->offconstant = 0.0; - } else { - b->offconstant = 0.475 * sqrt((1.0 + b->goodangle) / (1.0 - b->goodangle)); - } - b->goodangle *= b->goodangle; - if (b->refine && b->noiterationnum) { - printf( - "Error: You cannot use the -I switch when refining a triangulation.\n"); - exit(1); - } - /* Be careful not to allocate space for element area constraints that */ - /* will never be assigned any value (other than the default -1.0). */ - if (!b->refine && !b->poly) { - b->vararea = 0; - } - /* Be careful not to add an extra attribute to each element unless the */ - /* input supports it (PSLG in, but not refining a preexisting mesh). */ - if (b->refine || !b->poly) { - b->regionattrib = 0; - } - /* Regular/weighted triangulations are incompatible with PSLGs */ - /* and meshing. */ - if (b->weighted && (b->poly || b->quality)) { - b->weighted = 0; - if (!b->quiet) { - printf("Warning: weighted triangulations (-w, -W) are incompatible\n"); - printf(" with PSLGs (-p) and meshing (-q, -a, -u). Weights ignored.\n" - ); - } - } - if (b->jettison && b->nonodewritten && !b->quiet) { - printf("Warning: -j and -N switches are somewhat incompatible.\n"); - printf(" If any vertices are jettisoned, you will need the output\n"); - printf(" .node file to reconstruct the new node indices."); - } - -#ifndef TRILIBRARY - strcpy(b->inpolyfilename, b->innodefilename); - strcpy(b->inelefilename, b->innodefilename); - strcpy(b->areafilename, b->innodefilename); - increment = 0; - strcpy(workstring, b->innodefilename); - j = 1; - while (workstring[j] != '\0') { - if ((workstring[j] == '.') && (workstring[j + 1] != '\0')) { - increment = j + 1; - } - j++; - } - meshnumber = 0; - if (increment > 0) { - j = increment; - do { - if ((workstring[j] >= '0') && (workstring[j] <= '9')) { - meshnumber = meshnumber * 10 + (int) (workstring[j] - '0'); - } else { - increment = 0; - } - j++; - } while (workstring[j] != '\0'); - } - if (b->noiterationnum) { - strcpy(b->outnodefilename, b->innodefilename); - strcpy(b->outelefilename, b->innodefilename); - strcpy(b->edgefilename, b->innodefilename); - strcpy(b->vnodefilename, b->innodefilename); - strcpy(b->vedgefilename, b->innodefilename); - strcpy(b->neighborfilename, b->innodefilename); - strcpy(b->offfilename, b->innodefilename); - strcat(b->outnodefilename, ".node"); - strcat(b->outelefilename, ".ele"); - strcat(b->edgefilename, ".edge"); - strcat(b->vnodefilename, ".v.node"); - strcat(b->vedgefilename, ".v.edge"); - strcat(b->neighborfilename, ".neigh"); - strcat(b->offfilename, ".off"); - } else if (increment == 0) { - strcpy(b->outnodefilename, b->innodefilename); - strcpy(b->outpolyfilename, b->innodefilename); - strcpy(b->outelefilename, b->innodefilename); - strcpy(b->edgefilename, b->innodefilename); - strcpy(b->vnodefilename, b->innodefilename); - strcpy(b->vedgefilename, b->innodefilename); - strcpy(b->neighborfilename, b->innodefilename); - strcpy(b->offfilename, b->innodefilename); - strcat(b->outnodefilename, ".1.node"); - strcat(b->outpolyfilename, ".1.poly"); - strcat(b->outelefilename, ".1.ele"); - strcat(b->edgefilename, ".1.edge"); - strcat(b->vnodefilename, ".1.v.node"); - strcat(b->vedgefilename, ".1.v.edge"); - strcat(b->neighborfilename, ".1.neigh"); - strcat(b->offfilename, ".1.off"); - } else { - workstring[increment] = '%'; - workstring[increment + 1] = 'd'; - workstring[increment + 2] = '\0'; - sprintf(b->outnodefilename, workstring, meshnumber + 1); - strcpy(b->outpolyfilename, b->outnodefilename); - strcpy(b->outelefilename, b->outnodefilename); - strcpy(b->edgefilename, b->outnodefilename); - strcpy(b->vnodefilename, b->outnodefilename); - strcpy(b->vedgefilename, b->outnodefilename); - strcpy(b->neighborfilename, b->outnodefilename); - strcpy(b->offfilename, b->outnodefilename); - strcat(b->outnodefilename, ".node"); - strcat(b->outpolyfilename, ".poly"); - strcat(b->outelefilename, ".ele"); - strcat(b->edgefilename, ".edge"); - strcat(b->vnodefilename, ".v.node"); - strcat(b->vedgefilename, ".v.edge"); - strcat(b->neighborfilename, ".neigh"); - strcat(b->offfilename, ".off"); - } - strcat(b->innodefilename, ".node"); - strcat(b->inpolyfilename, ".poly"); - strcat(b->inelefilename, ".ele"); - strcat(b->areafilename, ".area"); -#endif /* not TRILIBRARY */ -} - -/** **/ -/** **/ -/********* User interaction routines begin here *********/ - -/********* Debugging routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* printtriangle() Print out the details of an oriented triangle. */ -/* */ -/* I originally wrote this procedure to simplify debugging; it can be */ -/* called directly from the debugger, and presents information about an */ -/* oriented triangle in digestible form. It's also used when the */ -/* highest level of verbosity (`-VVV') is specified. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void printtriangle(struct mesh *m, struct behavior *b, struct otri *t) -#else /* not ANSI_DECLARATORS */ -void printtriangle(m, b, t) -struct mesh *m; -struct behavior *b; -struct otri *t; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri printtri; - struct osub printsh; - vertex printvertex; - - printf("triangle x%lx with orientation %d:\n", (unsigned long) t->tri, - t->orient); - decode(t->tri[0], printtri); - if (printtri.tri == m->dummytri) { - printf(" [0] = Outer space\n"); - } else { - printf(" [0] = x%lx %d\n", (unsigned long) printtri.tri, - printtri.orient); - } - decode(t->tri[1], printtri); - if (printtri.tri == m->dummytri) { - printf(" [1] = Outer space\n"); - } else { - printf(" [1] = x%lx %d\n", (unsigned long) printtri.tri, - printtri.orient); - } - decode(t->tri[2], printtri); - if (printtri.tri == m->dummytri) { - printf(" [2] = Outer space\n"); - } else { - printf(" [2] = x%lx %d\n", (unsigned long) printtri.tri, - printtri.orient); - } - - org(*t, printvertex); - if (printvertex == (vertex) NULL) - printf(" Origin[%d] = NULL\n", (t->orient + 1) % 3 + 3); - else - printf(" Origin[%d] = x%lx (%.12g, %.12g)\n", - (t->orient + 1) % 3 + 3, (unsigned long) printvertex, - printvertex[0], printvertex[1]); - dest(*t, printvertex); - if (printvertex == (vertex) NULL) - printf(" Dest [%d] = NULL\n", (t->orient + 2) % 3 + 3); - else - printf(" Dest [%d] = x%lx (%.12g, %.12g)\n", - (t->orient + 2) % 3 + 3, (unsigned long) printvertex, - printvertex[0], printvertex[1]); - apex(*t, printvertex); - if (printvertex == (vertex) NULL) - printf(" Apex [%d] = NULL\n", t->orient + 3); - else - printf(" Apex [%d] = x%lx (%.12g, %.12g)\n", - t->orient + 3, (unsigned long) printvertex, - printvertex[0], printvertex[1]); - - if (b->usesegments) { - sdecode(t->tri[6], printsh); - if (printsh.ss != m->dummysub) { - printf(" [6] = x%lx %d\n", (unsigned long) printsh.ss, - printsh.ssorient); - } - sdecode(t->tri[7], printsh); - if (printsh.ss != m->dummysub) { - printf(" [7] = x%lx %d\n", (unsigned long) printsh.ss, - printsh.ssorient); - } - sdecode(t->tri[8], printsh); - if (printsh.ss != m->dummysub) { - printf(" [8] = x%lx %d\n", (unsigned long) printsh.ss, - printsh.ssorient); - } - } - - if (b->vararea) { - printf(" Area constraint: %.4g\n", areabound(*t)); - } -} - -/*****************************************************************************/ -/* */ -/* printsubseg() Print out the details of an oriented subsegment. */ -/* */ -/* I originally wrote this procedure to simplify debugging; it can be */ -/* called directly from the debugger, and presents information about an */ -/* oriented subsegment in digestible form. It's also used when the highest */ -/* level of verbosity (`-VVV') is specified. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void printsubseg(struct mesh *m, struct behavior *b, struct osub *s) -#else /* not ANSI_DECLARATORS */ -void printsubseg(m, b, s) -struct mesh *m; -struct behavior *b; -struct osub *s; -#endif /* not ANSI_DECLARATORS */ - -{ - struct osub printsh; - struct otri printtri; - vertex printvertex; - - printf("subsegment x%lx with orientation %d and mark %d:\n", - (unsigned long) s->ss, s->ssorient, mark(*s)); - sdecode(s->ss[0], printsh); - if (printsh.ss == m->dummysub) { - printf(" [0] = No subsegment\n"); - } else { - printf(" [0] = x%lx %d\n", (unsigned long) printsh.ss, - printsh.ssorient); - } - sdecode(s->ss[1], printsh); - if (printsh.ss == m->dummysub) { - printf(" [1] = No subsegment\n"); - } else { - printf(" [1] = x%lx %d\n", (unsigned long) printsh.ss, - printsh.ssorient); - } - - sorg(*s, printvertex); - if (printvertex == (vertex) NULL) - printf(" Origin[%d] = NULL\n", 2 + s->ssorient); - else - printf(" Origin[%d] = x%lx (%.12g, %.12g)\n", - 2 + s->ssorient, (unsigned long) printvertex, - printvertex[0], printvertex[1]); - sdest(*s, printvertex); - if (printvertex == (vertex) NULL) - printf(" Dest [%d] = NULL\n", 3 - s->ssorient); - else - printf(" Dest [%d] = x%lx (%.12g, %.12g)\n", - 3 - s->ssorient, (unsigned long) printvertex, - printvertex[0], printvertex[1]); - - decode(s->ss[4], printtri); - if (printtri.tri == m->dummytri) { - printf(" [4] = Outer space\n"); - } else { - printf(" [4] = x%lx %d\n", (unsigned long) printtri.tri, - printtri.orient); - } - decode(s->ss[5], printtri); - if (printtri.tri == m->dummytri) { - printf(" [5] = Outer space\n"); - } else { - printf(" [5] = x%lx %d\n", (unsigned long) printtri.tri, - printtri.orient); - } -} - -/** **/ -/** **/ -/********* Debugging routines end here *********/ - -/********* Memory management routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* poolrestart() Deallocate all items in a pool. */ -/* */ -/* The pool is returned to its starting state, except that no memory is */ -/* freed to the operating system. Rather, the previously allocated blocks */ -/* are ready to be reused. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void poolrestart(struct memorypool *pool) -#else /* not ANSI_DECLARATORS */ -void poolrestart(pool) -struct memorypool *pool; -#endif /* not ANSI_DECLARATORS */ - -{ - unsigned long alignptr; - - pool->items = 0; - pool->maxitems = 0; - - /* Set the currently active block. */ - pool->nowblock = pool->firstblock; - /* Find the first item in the pool. Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->nowblock + 1); - /* Align the item on an `alignbytes'-byte boundary. */ - pool->nextitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); - /* There are lots of unallocated items left in this block. */ - pool->unallocateditems = pool->itemsfirstblock; - /* The stack of deallocated items is empty. */ - pool->deaditemstack = (VOID *) NULL; -} - -/*****************************************************************************/ -/* */ -/* poolinit() Initialize a pool of memory for allocation of items. */ -/* */ -/* This routine initializes the machinery for allocating items. A `pool' */ -/* is created whose records have size at least `bytecount'. Items will be */ -/* allocated in `itemcount'-item blocks. Each item is assumed to be a */ -/* collection of words, and either pointers or floating-point values are */ -/* assumed to be the "primary" word type. (The "primary" word type is used */ -/* to determine alignment of items.) If `alignment' isn't zero, all items */ -/* will be `alignment'-byte aligned in memory. `alignment' must be either */ -/* a multiple or a factor of the primary word size; powers of two are safe. */ -/* `alignment' is normally used to create a few unused bits at the bottom */ -/* of each item's pointer, in which information may be stored. */ -/* */ -/* Don't change this routine unless you understand it. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void poolinit(struct memorypool *pool, int bytecount, int itemcount, - int firstitemcount, enum wordtype wtype, int alignment) -#else /* not ANSI_DECLARATORS */ -void poolinit(pool, bytecount, itemcount, firstitemcount, wtype, alignment) -struct memorypool *pool; -int bytecount; -int itemcount; -int firstitemcount; -enum wordtype wtype; -int alignment; -#endif /* not ANSI_DECLARATORS */ - -{ - int wordsize; - - /* Initialize values in the pool. */ - pool->itemwordtype = wtype; - wordsize = (pool->itemwordtype == POINTER) ? sizeof(VOID *) : sizeof(REAL); - /* Find the proper alignment, which must be at least as large as: */ - /* - The parameter `alignment'. */ - /* - The primary word type, to avoid unaligned accesses. */ - /* - sizeof(VOID *), so the stack of dead items can be maintained */ - /* without unaligned accesses. */ - if (alignment > wordsize) { - pool->alignbytes = alignment; - } else { - pool->alignbytes = wordsize; - } - if (sizeof(VOID *) > pool->alignbytes) { - pool->alignbytes = sizeof(VOID *); - } - pool->itemwords = ((bytecount + pool->alignbytes - 1) / pool->alignbytes) - * (pool->alignbytes / wordsize); - pool->itembytes = pool->itemwords * wordsize; - pool->itemsperblock = itemcount; - if (firstitemcount == 0) { - pool->itemsfirstblock = itemcount; - } else { - pool->itemsfirstblock = firstitemcount; - } - - /* Allocate a block of items. Space for `itemsfirstblock' items and one */ - /* pointer (to point to the next block) are allocated, as well as space */ - /* to ensure alignment of the items. */ - pool->firstblock = (VOID **) - trimalloc(pool->itemsfirstblock * pool->itembytes + (int) sizeof(VOID *) + - pool->alignbytes); - /* Set the next block pointer to NULL. */ - *(pool->firstblock) = (VOID *) NULL; - poolrestart(pool); -} - -/*****************************************************************************/ -/* */ -/* pooldeinit() Free to the operating system all memory taken by a pool. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void pooldeinit(struct memorypool *pool) -#else /* not ANSI_DECLARATORS */ -void pooldeinit(pool) -struct memorypool *pool; -#endif /* not ANSI_DECLARATORS */ - -{ - while (pool->firstblock != (VOID **) NULL) { - pool->nowblock = (VOID **) *(pool->firstblock); - trifree((VOID *) pool->firstblock); - pool->firstblock = pool->nowblock; - } -} - -/*****************************************************************************/ -/* */ -/* poolalloc() Allocate space for an item. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -VOID *poolalloc(struct memorypool *pool) -#else /* not ANSI_DECLARATORS */ -VOID *poolalloc(pool) -struct memorypool *pool; -#endif /* not ANSI_DECLARATORS */ - -{ - VOID *newitem; - VOID **newblock; - unsigned long alignptr; - - /* First check the linked list of dead items. If the list is not */ - /* empty, allocate an item from the list rather than a fresh one. */ - if (pool->deaditemstack != (VOID *) NULL) { - newitem = pool->deaditemstack; /* Take first item in list. */ - pool->deaditemstack = * (VOID **) pool->deaditemstack; - } else { - /* Check if there are any free items left in the current block. */ - if (pool->unallocateditems == 0) { - /* Check if another block must be allocated. */ - if (*(pool->nowblock) == (VOID *) NULL) { - /* Allocate a new block of items, pointed to by the previous block. */ - newblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes + - (int) sizeof(VOID *) + - pool->alignbytes); - *(pool->nowblock) = (VOID *) newblock; - /* The next block pointer is NULL. */ - *newblock = (VOID *) NULL; - } - - /* Move to the new block. */ - pool->nowblock = (VOID **) *(pool->nowblock); - /* Find the first item in the block. */ - /* Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->nowblock + 1); - /* Align the item on an `alignbytes'-byte boundary. */ - pool->nextitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); - /* There are lots of unallocated items left in this block. */ - pool->unallocateditems = pool->itemsperblock; - } - - /* Allocate a new item. */ - newitem = pool->nextitem; - /* Advance `nextitem' pointer to next free item in block. */ - if (pool->itemwordtype == POINTER) { - pool->nextitem = (VOID *) ((VOID **) pool->nextitem + pool->itemwords); - } else { - pool->nextitem = (VOID *) ((REAL *) pool->nextitem + pool->itemwords); - } - pool->unallocateditems--; - pool->maxitems++; - } - pool->items++; - return newitem; -} - -/*****************************************************************************/ -/* */ -/* pooldealloc() Deallocate space for an item. */ -/* */ -/* The deallocated space is stored in a queue for later reuse. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void pooldealloc(struct memorypool *pool, VOID *dyingitem) -#else /* not ANSI_DECLARATORS */ -void pooldealloc(pool, dyingitem) -struct memorypool *pool; -VOID *dyingitem; -#endif /* not ANSI_DECLARATORS */ - -{ - /* Push freshly killed item onto stack. */ - *((VOID **) dyingitem) = pool->deaditemstack; - pool->deaditemstack = dyingitem; - pool->items--; -} - -/*****************************************************************************/ -/* */ -/* traversalinit() Prepare to traverse the entire list of items. */ -/* */ -/* This routine is used in conjunction with traverse(). */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void traversalinit(struct memorypool *pool) -#else /* not ANSI_DECLARATORS */ -void traversalinit(pool) -struct memorypool *pool; -#endif /* not ANSI_DECLARATORS */ - -{ - unsigned long alignptr; - - /* Begin the traversal in the first block. */ - pool->pathblock = pool->firstblock; - /* Find the first item in the block. Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->pathblock + 1); - /* Align with item on an `alignbytes'-byte boundary. */ - pool->pathitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); - /* Set the number of items left in the current block. */ - pool->pathitemsleft = pool->itemsfirstblock; -} - -/*****************************************************************************/ -/* */ -/* traverse() Find the next item in the list. */ -/* */ -/* This routine is used in conjunction with traversalinit(). Be forewarned */ -/* that this routine successively returns all items in the list, including */ -/* deallocated ones on the deaditemqueue. It's up to you to figure out */ -/* which ones are actually dead. Why? I don't want to allocate extra */ -/* space just to demarcate dead items. It can usually be done more */ -/* space-efficiently by a routine that knows something about the structure */ -/* of the item. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -VOID *traverse(struct memorypool *pool) -#else /* not ANSI_DECLARATORS */ -VOID *traverse(pool) -struct memorypool *pool; -#endif /* not ANSI_DECLARATORS */ - -{ - VOID *newitem; - unsigned long alignptr; - - /* Stop upon exhausting the list of items. */ - if (pool->pathitem == pool->nextitem) { - return (VOID *) NULL; - } - - /* Check whether any untraversed items remain in the current block. */ - if (pool->pathitemsleft == 0) { - /* Find the next block. */ - pool->pathblock = (VOID **) *(pool->pathblock); - /* Find the first item in the block. Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->pathblock + 1); - /* Align with item on an `alignbytes'-byte boundary. */ - pool->pathitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); - /* Set the number of items left in the current block. */ - pool->pathitemsleft = pool->itemsperblock; - } - - newitem = pool->pathitem; - /* Find the next item in the block. */ - if (pool->itemwordtype == POINTER) { - pool->pathitem = (VOID *) ((VOID **) pool->pathitem + pool->itemwords); - } else { - pool->pathitem = (VOID *) ((REAL *) pool->pathitem + pool->itemwords); - } - pool->pathitemsleft--; - return newitem; -} - -/*****************************************************************************/ -/* */ -/* dummyinit() Initialize the triangle that fills "outer space" and the */ -/* omnipresent subsegment. */ -/* */ -/* The triangle that fills "outer space," called `dummytri', is pointed to */ -/* by every triangle and subsegment on a boundary (be it outer or inner) of */ -/* the triangulation. Also, `dummytri' points to one of the triangles on */ -/* the convex hull (until the holes and concavities are carved), making it */ -/* possible to find a starting triangle for point location. */ -/* */ -/* The omnipresent subsegment, `dummysub', is pointed to by every triangle */ -/* or subsegment that doesn't have a full complement of real subsegments */ -/* to point to. */ -/* */ -/* `dummytri' and `dummysub' are generally required to fulfill only a few */ -/* invariants: their vertices must remain NULL and `dummytri' must always */ -/* be bonded (at offset zero) to some triangle on the convex hull of the */ -/* mesh, via a boundary edge. Otherwise, the connections of `dummytri' and */ -/* `dummysub' may change willy-nilly. This makes it possible to avoid */ -/* writing a good deal of special-case code (in the edge flip, for example) */ -/* for dealing with the boundary of the mesh, places where no subsegment is */ -/* present, and so forth. Other entities are frequently bonded to */ -/* `dummytri' and `dummysub' as if they were real mesh entities, with no */ -/* harm done. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void dummyinit(struct mesh *m, struct behavior *b, int trianglewords, - int subsegwords) -#else /* not ANSI_DECLARATORS */ -void dummyinit(m, b, trianglewords, subsegwords) -struct mesh *m; -struct behavior *b; -int trianglewords; -int subsegwords; -#endif /* not ANSI_DECLARATORS */ - -{ - unsigned long alignptr; - - /* Set up `dummytri', the `triangle' that occupies "outer space." */ - m->dummytribase = (triangle *) - trimalloc(trianglewords * (int) sizeof(triangle) + - m->triangles.alignbytes); - /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */ - alignptr = (unsigned long) m->dummytribase; - m->dummytri = (triangle *) - (alignptr + (unsigned long) m->triangles.alignbytes - - (alignptr % (unsigned long) m->triangles.alignbytes)); - /* Initialize the three adjoining triangles to be "outer space." These */ - /* will eventually be changed by various bonding operations, but their */ - /* values don't really matter, as long as they can legally be */ - /* dereferenced. */ - m->dummytri[0] = (triangle) m->dummytri; - m->dummytri[1] = (triangle) m->dummytri; - m->dummytri[2] = (triangle) m->dummytri; - /* Three NULL vertices. */ - m->dummytri[3] = (triangle) NULL; - m->dummytri[4] = (triangle) NULL; - m->dummytri[5] = (triangle) NULL; - - if (b->usesegments) { - /* Set up `dummysub', the omnipresent subsegment pointed to by any */ - /* triangle side or subsegment end that isn't attached to a real */ - /* subsegment. */ - m->dummysubbase = (subseg *) trimalloc(subsegwords * (int) sizeof(subseg) + - m->subsegs.alignbytes); - /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */ - alignptr = (unsigned long) m->dummysubbase; - m->dummysub = (subseg *) - (alignptr + (unsigned long) m->subsegs.alignbytes - - (alignptr % (unsigned long) m->subsegs.alignbytes)); - /* Initialize the two adjoining subsegments to be the omnipresent */ - /* subsegment. These will eventually be changed by various bonding */ - /* operations, but their values don't really matter, as long as they */ - /* can legally be dereferenced. */ - m->dummysub[0] = (subseg) m->dummysub; - m->dummysub[1] = (subseg) m->dummysub; - /* Two NULL vertices. */ - m->dummysub[2] = (subseg) NULL; - m->dummysub[3] = (subseg) NULL; - /* Initialize the two adjoining triangles to be "outer space." */ - m->dummysub[4] = (subseg) m->dummytri; - m->dummysub[5] = (subseg) m->dummytri; - /* Set the boundary marker to zero. */ - * (int *) (m->dummysub + 6) = 0; - - /* Initialize the three adjoining subsegments of `dummytri' to be */ - /* the omnipresent subsegment. */ - m->dummytri[6] = (triangle) m->dummysub; - m->dummytri[7] = (triangle) m->dummysub; - m->dummytri[8] = (triangle) m->dummysub; - } -} - -/*****************************************************************************/ -/* */ -/* initializevertexpool() Calculate the size of the vertex data structure */ -/* and initialize its memory pool. */ -/* */ -/* This routine also computes the `vertexmarkindex' and `vertex2triindex' */ -/* indices used to find values within each vertex. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void initializevertexpool(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void initializevertexpool(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - int vertexsize; - - /* The index within each vertex at which the boundary marker is found, */ - /* followed by the vertex type. Ensure the vertex marker is aligned to */ - /* a sizeof(int)-byte address. */ - m->vertexmarkindex = ((m->mesh_dim + m->nextras) * sizeof(REAL) + - sizeof(int) - 1) / - sizeof(int); - vertexsize = (m->vertexmarkindex + 2) * sizeof(int); - if (b->poly) { - /* The index within each vertex at which a triangle pointer is found. */ - /* Ensure the pointer is aligned to a sizeof(triangle)-byte address. */ - m->vertex2triindex = (vertexsize + sizeof(triangle) - 1) / - sizeof(triangle); - vertexsize = (m->vertex2triindex + 1) * sizeof(triangle); - } - - /* Initialize the pool of vertices. */ - poolinit(&m->vertices, vertexsize, VERTEXPERBLOCK, - m->invertices > VERTEXPERBLOCK ? m->invertices : VERTEXPERBLOCK, - (sizeof(REAL) >= sizeof(triangle)) ? FLOATINGPOINT : POINTER, 0); -} - -/*****************************************************************************/ -/* */ -/* initializetrisubpools() Calculate the sizes of the triangle and */ -/* subsegment data structures and initialize */ -/* their memory pools. */ -/* */ -/* This routine also computes the `highorderindex', `elemattribindex', and */ -/* `areaboundindex' indices used to find values within each triangle. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void initializetrisubpools(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void initializetrisubpools(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - int trisize; - - /* The index within each triangle at which the extra nodes (above three) */ - /* associated with high order elements are found. There are three */ - /* pointers to other triangles, three pointers to corners, and possibly */ - /* three pointers to subsegments before the extra nodes. */ - m->highorderindex = 6 + (b->usesegments * 3); - /* The number of bytes occupied by a triangle. */ - trisize = ((b->order + 1) * (b->order + 2) / 2 + (m->highorderindex - 3)) * - sizeof(triangle); - /* The index within each triangle at which its attributes are found, */ - /* where the index is measured in REALs. */ - m->elemattribindex = (trisize + sizeof(REAL) - 1) / sizeof(REAL); - /* The index within each triangle at which the maximum area constraint */ - /* is found, where the index is measured in REALs. Note that if the */ - /* `regionattrib' flag is set, an additional attribute will be added. */ - m->areaboundindex = m->elemattribindex + m->eextras + b->regionattrib; - /* If triangle attributes or an area bound are needed, increase the number */ - /* of bytes occupied by a triangle. */ - if (b->vararea) { - trisize = (m->areaboundindex + 1) * sizeof(REAL); - } else if (m->eextras + b->regionattrib > 0) { - trisize = m->areaboundindex * sizeof(REAL); - } - /* If a Voronoi diagram or triangle neighbor graph is requested, make */ - /* sure there's room to store an integer index in each triangle. This */ - /* integer index can occupy the same space as the subsegment pointers */ - /* or attributes or area constraint or extra nodes. */ - if ((b->voronoi || b->neighbors) && - (trisize < 6 * sizeof(triangle) + sizeof(int))) { - trisize = 6 * sizeof(triangle) + sizeof(int); - } - - /* Having determined the memory size of a triangle, initialize the pool. */ - poolinit(&m->triangles, trisize, TRIPERBLOCK, - (2 * m->invertices - 2) > TRIPERBLOCK ? (2 * m->invertices - 2) : - TRIPERBLOCK, POINTER, 4); - - if (b->usesegments) { - /* Initialize the pool of subsegments. Take into account all six */ - /* pointers and one boundary marker. */ - poolinit(&m->subsegs, 6 * sizeof(triangle) + sizeof(int), SUBSEGPERBLOCK, - SUBSEGPERBLOCK, POINTER, 4); - - /* Initialize the "outer space" triangle and omnipresent subsegment. */ - dummyinit(m, b, m->triangles.itemwords, m->subsegs.itemwords); - } else { - /* Initialize the "outer space" triangle. */ - dummyinit(m, b, m->triangles.itemwords, 0); - } -} - -/*****************************************************************************/ -/* */ -/* triangledealloc() Deallocate space for a triangle, marking it dead. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void triangledealloc(struct mesh *m, triangle *dyingtriangle) -#else /* not ANSI_DECLARATORS */ -void triangledealloc(m, dyingtriangle) -struct mesh *m; -triangle *dyingtriangle; -#endif /* not ANSI_DECLARATORS */ - -{ - /* Mark the triangle as dead. This makes it possible to detect dead */ - /* triangles when traversing the list of all triangles. */ - killtri(dyingtriangle); - pooldealloc(&m->triangles, (VOID *) dyingtriangle); -} - -/*****************************************************************************/ -/* */ -/* triangletraverse() Traverse the triangles, skipping dead ones. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -triangle *triangletraverse(struct mesh *m) -#else /* not ANSI_DECLARATORS */ -triangle *triangletraverse(m) -struct mesh *m; -#endif /* not ANSI_DECLARATORS */ - -{ - triangle *newtriangle; - - do { - newtriangle = (triangle *) traverse(&m->triangles); - if (newtriangle == (triangle *) NULL) { - return (triangle *) NULL; - } - } while (deadtri(newtriangle)); /* Skip dead ones. */ - return newtriangle; -} - -/*****************************************************************************/ -/* */ -/* subsegdealloc() Deallocate space for a subsegment, marking it dead. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void subsegdealloc(struct mesh *m, subseg *dyingsubseg) -#else /* not ANSI_DECLARATORS */ -void subsegdealloc(m, dyingsubseg) -struct mesh *m; -subseg *dyingsubseg; -#endif /* not ANSI_DECLARATORS */ - -{ - /* Mark the subsegment as dead. This makes it possible to detect dead */ - /* subsegments when traversing the list of all subsegments. */ - killsubseg(dyingsubseg); - pooldealloc(&m->subsegs, (VOID *) dyingsubseg); -} - -/*****************************************************************************/ -/* */ -/* subsegtraverse() Traverse the subsegments, skipping dead ones. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -subseg *subsegtraverse(struct mesh *m) -#else /* not ANSI_DECLARATORS */ -subseg *subsegtraverse(m) -struct mesh *m; -#endif /* not ANSI_DECLARATORS */ - -{ - subseg *newsubseg; - - do { - newsubseg = (subseg *) traverse(&m->subsegs); - if (newsubseg == (subseg *) NULL) { - return (subseg *) NULL; - } - } while (deadsubseg(newsubseg)); /* Skip dead ones. */ - return newsubseg; -} - -/*****************************************************************************/ -/* */ -/* vertexdealloc() Deallocate space for a vertex, marking it dead. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void vertexdealloc(struct mesh *m, vertex dyingvertex) -#else /* not ANSI_DECLARATORS */ -void vertexdealloc(m, dyingvertex) -struct mesh *m; -vertex dyingvertex; -#endif /* not ANSI_DECLARATORS */ - -{ - /* Mark the vertex as dead. This makes it possible to detect dead */ - /* vertices when traversing the list of all vertices. */ - setvertextype(dyingvertex, DEADVERTEX); - pooldealloc(&m->vertices, (VOID *) dyingvertex); -} - -/*****************************************************************************/ -/* */ -/* vertextraverse() Traverse the vertices, skipping dead ones. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -vertex vertextraverse(struct mesh *m) -#else /* not ANSI_DECLARATORS */ -vertex vertextraverse(m) -struct mesh *m; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex newvertex; - - do { - newvertex = (vertex) traverse(&m->vertices); - if (newvertex == (vertex) NULL) { - return (vertex) NULL; - } - } while (vertextype(newvertex) == DEADVERTEX); /* Skip dead ones. */ - return newvertex; -} - -/*****************************************************************************/ -/* */ -/* badsubsegdealloc() Deallocate space for a bad subsegment, marking it */ -/* dead. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void badsubsegdealloc(struct mesh *m, struct badsubseg *dyingseg) -#else /* not ANSI_DECLARATORS */ -void badsubsegdealloc(m, dyingseg) -struct mesh *m; -struct badsubseg *dyingseg; -#endif /* not ANSI_DECLARATORS */ - -{ - /* Set subsegment's origin to NULL. This makes it possible to detect dead */ - /* subsegments when traversing the list of all encroached subsegments. */ - dyingseg->subsegorg = (vertex) NULL; - pooldealloc(&m->badsubsegs, (VOID *) dyingseg); -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* badsubsegtraverse() Traverse the bad subsegments, skipping dead ones. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -struct badsubseg *badsubsegtraverse(struct mesh *m) -#else /* not ANSI_DECLARATORS */ -struct badsubseg *badsubsegtraverse(m) -struct mesh *m; -#endif /* not ANSI_DECLARATORS */ - -{ - struct badsubseg *newseg; - - do { - newseg = (struct badsubseg *) traverse(&m->badsubsegs); - if (newseg == (struct badsubseg *) NULL) { - return (struct badsubseg *) NULL; - } - } while (newseg->subsegorg == (vertex) NULL); /* Skip dead ones. */ - return newseg; -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* getvertex() Get a specific vertex, by number, from the list. */ -/* */ -/* The first vertex is number 'firstnumber'. */ -/* */ -/* Note that this takes O(n) time (with a small constant, if VERTEXPERBLOCK */ -/* is large). I don't care to take the trouble to make it work in constant */ -/* time. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -vertex getvertex(struct mesh *m, struct behavior *b, int number) -#else /* not ANSI_DECLARATORS */ -vertex getvertex(m, b, number) -struct mesh *m; -struct behavior *b; -int number; -#endif /* not ANSI_DECLARATORS */ - -{ - VOID **getblock; - vertex foundvertex; - unsigned long alignptr; - int current; - - getblock = m->vertices.firstblock; - current = b->firstnumber; - - /* Find the right block. */ - if (current + m->vertices.itemsfirstblock <= number) { - getblock = (VOID **) *getblock; - current += m->vertices.itemsfirstblock; - while (current + m->vertices.itemsperblock <= number) { - getblock = (VOID **) *getblock; - current += m->vertices.itemsperblock; - } - } - - /* Now find the right vertex. */ - alignptr = (unsigned long) (getblock + 1); - foundvertex = (vertex) (alignptr + (unsigned long) m->vertices.alignbytes - - (alignptr % (unsigned long) m->vertices.alignbytes)); - while (current < number) { - foundvertex += m->vertices.itemwords; - current++; - } - return foundvertex; -} - -/*****************************************************************************/ -/* */ -/* triangledeinit() Free all remaining allocated memory. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void triangledeinit(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void triangledeinit(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - pooldeinit(&m->triangles); - trifree((VOID *) m->dummytribase); - if (b->usesegments) { - pooldeinit(&m->subsegs); - trifree((VOID *) m->dummysubbase); - } - pooldeinit(&m->vertices); -#ifndef CDT_ONLY - if (b->quality) { - pooldeinit(&m->badsubsegs); - if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) { - pooldeinit(&m->badtriangles); - pooldeinit(&m->flipstackers); - } - } -#endif /* not CDT_ONLY */ -} - -/** **/ -/** **/ -/********* Memory management routines end here *********/ - -/********* Constructors begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* maketriangle() Create a new triangle with orientation zero. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void maketriangle(struct mesh *m, struct behavior *b, struct otri *newotri) -#else /* not ANSI_DECLARATORS */ -void maketriangle(m, b, newotri) -struct mesh *m; -struct behavior *b; -struct otri *newotri; -#endif /* not ANSI_DECLARATORS */ - -{ - int i; - - newotri->tri = (triangle *) poolalloc(&m->triangles); - /* Initialize the three adjoining triangles to be "outer space". */ - newotri->tri[0] = (triangle) m->dummytri; - newotri->tri[1] = (triangle) m->dummytri; - newotri->tri[2] = (triangle) m->dummytri; - /* Three NULL vertices. */ - newotri->tri[3] = (triangle) NULL; - newotri->tri[4] = (triangle) NULL; - newotri->tri[5] = (triangle) NULL; - if (b->usesegments) { - /* Initialize the three adjoining subsegments to be the omnipresent */ - /* subsegment. */ - newotri->tri[6] = (triangle) m->dummysub; - newotri->tri[7] = (triangle) m->dummysub; - newotri->tri[8] = (triangle) m->dummysub; - } - for (i = 0; i < m->eextras; i++) { - setelemattribute(*newotri, i, 0.0); - } - if (b->vararea) { - setareabound(*newotri, -1.0); - } - - newotri->orient = 0; -} - -/*****************************************************************************/ -/* */ -/* makesubseg() Create a new subsegment with orientation zero. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void makesubseg(struct mesh *m, struct osub *newsubseg) -#else /* not ANSI_DECLARATORS */ -void makesubseg(m, newsubseg) -struct mesh *m; -struct osub *newsubseg; -#endif /* not ANSI_DECLARATORS */ - -{ - newsubseg->ss = (subseg *) poolalloc(&m->subsegs); - /* Initialize the two adjoining subsegments to be the omnipresent */ - /* subsegment. */ - newsubseg->ss[0] = (subseg) m->dummysub; - newsubseg->ss[1] = (subseg) m->dummysub; - /* Two NULL vertices. */ - newsubseg->ss[2] = (subseg) NULL; - newsubseg->ss[3] = (subseg) NULL; - /* Initialize the two adjoining triangles to be "outer space." */ - newsubseg->ss[4] = (subseg) m->dummytri; - newsubseg->ss[5] = (subseg) m->dummytri; - /* Set the boundary marker to zero. */ - setmark(*newsubseg, 0); - - newsubseg->ssorient = 0; -} - -/** **/ -/** **/ -/********* Constructors end here *********/ - -/********* Geometric primitives begin here *********/ -/** **/ -/** **/ - -/* The adaptive exact arithmetic geometric predicates implemented herein are */ -/* described in detail in my paper, "Adaptive Precision Floating-Point */ -/* Arithmetic and Fast Robust Geometric Predicates." See the header for a */ -/* full citation. */ - -/* Which of the following two methods of finding the absolute values is */ -/* fastest is compiler-dependent. A few compilers can inline and optimize */ -/* the fabs() call; but most will incur the overhead of a function call, */ -/* which is disastrously slow. A faster way on IEEE machines might be to */ -/* mask the appropriate bit, but that's difficult to do in C without */ -/* forcing the value to be stored to memory (rather than be kept in the */ -/* register to which the optimizer assigned it). */ - -#define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) -/* #define Absolute(a) fabs(a) */ - -/* Many of the operations are broken up into two pieces, a main part that */ -/* performs an approximate operation, and a "tail" that computes the */ -/* roundoff error of that operation. */ -/* */ -/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ -/* Split(), and Two_Product() are all implemented as described in the */ -/* reference. Each of these macros requires certain variables to be */ -/* defined in the calling routine. The variables `bvirt', `c', `abig', */ -/* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ -/* they store the result of an operation that may incur roundoff error. */ -/* The input parameter `x' (or the highest numbered `x_' parameter) must */ -/* also be declared `INEXACT'. */ - -#define Fast_Two_Sum_Tail(a, b, x, y) \ - bvirt = x - a; \ - y = b - bvirt - -#define Fast_Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Fast_Two_Sum_Tail(a, b, x, y) - -#define Two_Sum_Tail(a, b, x, y) \ - bvirt = (REAL) (x - a); \ - avirt = x - bvirt; \ - bround = b - bvirt; \ - around = a - avirt; \ - y = around + bround - -#define Two_Sum(a, b, x, y) \ - x = (REAL) (a + b); \ - Two_Sum_Tail(a, b, x, y) - -#define Two_Diff_Tail(a, b, x, y) \ - bvirt = (REAL) (a - x); \ - avirt = x + bvirt; \ - bround = bvirt - b; \ - around = a - avirt; \ - y = around + bround - -#define Two_Diff(a, b, x, y) \ - x = (REAL) (a - b); \ - Two_Diff_Tail(a, b, x, y) - -#define Split(a, ahi, alo) \ - c = (REAL) (splitter * a); \ - abig = (REAL) (c - a); \ - ahi = c - abig; \ - alo = a - ahi - -#define Two_Product_Tail(a, b, x, y) \ - Split(a, ahi, alo); \ - Split(b, bhi, blo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -#define Two_Product(a, b, x, y) \ - x = (REAL) (a * b); \ - Two_Product_Tail(a, b, x, y) - -/* Two_Product_Presplit() is Two_Product() where one of the inputs has */ -/* already been split. Avoids redundant splitting. */ - -#define Two_Product_Presplit(a, b, bhi, blo, x, y) \ - x = (REAL) (a * b); \ - Split(a, ahi, alo); \ - err1 = x - (ahi * bhi); \ - err2 = err1 - (alo * bhi); \ - err3 = err2 - (ahi * blo); \ - y = (alo * blo) - err3 - -/* Square() can be done more quickly than Two_Product(). */ - -#define Square_Tail(a, x, y) \ - Split(a, ahi, alo); \ - err1 = x - (ahi * ahi); \ - err3 = err1 - ((ahi + ahi) * alo); \ - y = (alo * alo) - err3 - -#define Square(a, x, y) \ - x = (REAL) (a * a); \ - Square_Tail(a, x, y) - -/* Macros for summing expansions of various fixed lengths. These are all */ -/* unrolled versions of Expansion_Sum(). */ - -#define Two_One_Sum(a1, a0, b, x2, x1, x0) \ - Two_Sum(a0, b , _i, x0); \ - Two_Sum(a1, _i, x2, x1) - -#define Two_One_Diff(a1, a0, b, x2, x1, x0) \ - Two_Diff(a0, b , _i, x0); \ - Two_Sum( a1, _i, x2, x1) - -#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Sum(a1, a0, b0, _j, _0, x0); \ - Two_One_Sum(_j, _0, b1, x3, x2, x1) - -#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ - Two_One_Diff(a1, a0, b0, _j, _0, x0); \ - Two_One_Diff(_j, _0, b1, x3, x2, x1) - -/* Macro for multiplying a two-component expansion by a single component. */ - -#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ - Split(b, bhi, blo); \ - Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ - Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ - Two_Sum(_i, _0, _k, x1); \ - Fast_Two_Sum(_j, _k, x3, x2) - -/*****************************************************************************/ -/* */ -/* exactinit() Initialize the variables used for exact arithmetic. */ -/* */ -/* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ -/* floating-point arithmetic. `epsilon' bounds the relative roundoff */ -/* error. It is used for floating-point error analysis. */ -/* */ -/* `splitter' is used to split floating-point numbers into two half- */ -/* length significands for exact multiplication. */ -/* */ -/* I imagine that a highly optimizing compiler might be too smart for its */ -/* own good, and somehow cause this routine to fail, if it pretends that */ -/* floating-point arithmetic is too much like real arithmetic. */ -/* */ -/* Don't change this routine unless you fully understand it. */ -/* */ -/*****************************************************************************/ - -void exactinit() -{ - REAL half; - REAL check, lastcheck; - int every_other; -#ifdef LINUX - int cword; -#endif /* LINUX */ - -#ifdef CPU86 -#ifdef SINGLE - _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */ -#else /* not SINGLE */ - _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */ -#endif /* not SINGLE */ -#endif /* CPU86 */ -#ifdef LINUX -#ifdef SINGLE - /* cword = 4223; */ - cword = 4210; /* set FPU control word for single precision */ -#else /* not SINGLE */ - /* cword = 4735; */ - cword = 4722; /* set FPU control word for double precision */ -#endif /* not SINGLE */ - _FPU_SETCW(cword); -#endif /* LINUX */ - - every_other = 1; - half = 0.5; - epsilon = 1.0; - splitter = 1.0; - check = 1.0; - /* Repeatedly divide `epsilon' by two until it is too small to add to */ - /* one without causing roundoff. (Also check if the sum is equal to */ - /* the previous sum, for machines that round up instead of using exact */ - /* rounding. Not that these routines will work on such machines.) */ - do { - lastcheck = check; - epsilon *= half; - if (every_other) { - splitter *= 2.0; - } - every_other = !every_other; - check = 1.0 + epsilon; - } while ((check != 1.0) && (check != lastcheck)); - splitter += 1.0; - /* Error bounds for orientation and incircle tests. */ - resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; - ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; - ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; - ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; - iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; - iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; - iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; - o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; - o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; - o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; -} - -/*****************************************************************************/ -/* */ -/* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ -/* components from the output expansion. */ -/* */ -/* Sets h = e + f. See my Robust Predicates paper for details. */ -/* */ -/* If round-to-even is used (as with IEEE 754), maintains the strongly */ -/* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ -/* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ -/* properties. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h) -#else /* not ANSI_DECLARATORS */ -int fast_expansion_sum_zeroelim(elen, e, flen, f, h) /* h cannot be e or f. */ -int elen; -REAL *e; -int flen; -REAL *f; -REAL *h; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL Q; - INEXACT REAL Qnew; - INEXACT REAL hh; - INEXACT REAL bvirt; - REAL avirt, bround, around; - int eindex, findex, hindex; - REAL enow, fnow; - - enow = e[0]; - fnow = f[0]; - eindex = findex = 0; - if ((fnow > enow) == (fnow > -enow)) { - Q = enow; - enow = e[++eindex]; - } else { - Q = fnow; - fnow = f[++findex]; - } - hindex = 0; - if ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Fast_Two_Sum(enow, Q, Qnew, hh); - enow = e[++eindex]; - } else { - Fast_Two_Sum(fnow, Q, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - while ((eindex < elen) && (findex < flen)) { - if ((fnow > enow) == (fnow > -enow)) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - } else { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - } - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - } - while (eindex < elen) { - Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - while (findex < flen) { - Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; - Q = Qnew; - if (hh != 0.0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ -/* eliminating zero components from the */ -/* output expansion. */ -/* */ -/* Sets h = be. See my Robust Predicates paper for details. */ -/* */ -/* Maintains the nonoverlapping property. If round-to-even is used (as */ -/* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ -/* properties as well. (That is, if e has one of these properties, so */ -/* will h.) */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) -#else /* not ANSI_DECLARATORS */ -int scale_expansion_zeroelim(elen, e, b, h) /* e and h cannot be the same. */ -int elen; -REAL *e; -REAL b; -REAL *h; -#endif /* not ANSI_DECLARATORS */ - -{ - INEXACT REAL Q, sum; - REAL hh; - INEXACT REAL product1; - REAL product0; - int eindex, hindex; - REAL enow; - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - - Split(b, bhi, blo); - Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); - hindex = 0; - if (hh != 0) { - h[hindex++] = hh; - } - for (eindex = 1; eindex < elen; eindex++) { - enow = e[eindex]; - Two_Product_Presplit(enow, b, bhi, blo, product1, product0); - Two_Sum(Q, product0, sum, hh); - if (hh != 0) { - h[hindex++] = hh; - } - Fast_Two_Sum(product1, sum, Q, hh); - if (hh != 0) { - h[hindex++] = hh; - } - } - if ((Q != 0.0) || (hindex == 0)) { - h[hindex++] = Q; - } - return hindex; -} - -/*****************************************************************************/ -/* */ -/* estimate() Produce a one-word estimate of an expansion's value. */ -/* */ -/* See my Robust Predicates paper for details. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -REAL estimate(int elen, REAL *e) -#else /* not ANSI_DECLARATORS */ -REAL estimate(elen, e) -int elen; -REAL *e; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL Q; - int eindex; - - Q = e[0]; - for (eindex = 1; eindex < elen; eindex++) { - Q += e[eindex]; - } - return Q; -} - -/*****************************************************************************/ -/* */ -/* counterclockwise() Return a positive value if the points pa, pb, and */ -/* pc occur in counterclockwise order; a negative */ -/* value if they occur in clockwise order; and zero */ -/* if they are collinear. The result is also a rough */ -/* approximation of twice the signed area of the */ -/* triangle defined by the three points. */ -/* */ -/* Uses exact arithmetic if necessary to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. This determinant is */ -/* computed adaptively, in the sense that exact arithmetic is used only to */ -/* the degree it is needed to ensure that the returned value has the */ -/* correct sign. Hence, this function is usually quite fast, but will run */ -/* more slowly when the input points are collinear or nearly so. */ -/* */ -/* See my Robust Predicates paper for details. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -REAL counterclockwiseadapt(vertex pa, vertex pb, vertex pc, REAL detsum) -#else /* not ANSI_DECLARATORS */ -REAL counterclockwiseadapt(pa, pb, pc, detsum) -vertex pa; -vertex pb; -vertex pc; -REAL detsum; -#endif /* not ANSI_DECLARATORS */ - -{ - INEXACT REAL acx, acy, bcx, bcy; - REAL acxtail, acytail, bcxtail, bcytail; - INEXACT REAL detleft, detright; - REAL detlefttail, detrighttail; - REAL det, errbound; - REAL B[4], C1[8], C2[12], D[16]; - INEXACT REAL B3; - int C1length, C2length, Dlength; - REAL u[4]; - INEXACT REAL u3; - INEXACT REAL s1, t1; - REAL s0, t0; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - acx = (REAL) (pa[0] - pc[0]); - bcx = (REAL) (pb[0] - pc[0]); - acy = (REAL) (pa[1] - pc[1]); - bcy = (REAL) (pb[1] - pc[1]); - - Two_Product(acx, bcy, detleft, detlefttail); - Two_Product(acy, bcx, detright, detrighttail); - - Two_Two_Diff(detleft, detlefttail, detright, detrighttail, - B3, B[2], B[1], B[0]); - B[3] = B3; - - det = estimate(4, B); - errbound = ccwerrboundB * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pc[0], acx, acxtail); - Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); - Two_Diff_Tail(pa[1], pc[1], acy, acytail); - Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); - - if ((acxtail == 0.0) && (acytail == 0.0) - && (bcxtail == 0.0) && (bcytail == 0.0)) { - return det; - } - - errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det); - det += (acx * bcytail + bcy * acxtail) - - (acy * bcxtail + bcx * acytail); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Product(acxtail, bcy, s1, s0); - Two_Product(acytail, bcx, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); - - Two_Product(acx, bcytail, s1, s0); - Two_Product(acy, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); - - Two_Product(acxtail, bcytail, s1, s0); - Two_Product(acytail, bcxtail, t1, t0); - Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); - u[3] = u3; - Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); - - return(D[Dlength - 1]); -} - -#ifdef ANSI_DECLARATORS -REAL counterclockwise(struct mesh *m, struct behavior *b, - vertex pa, vertex pb, vertex pc) -#else /* not ANSI_DECLARATORS */ -REAL counterclockwise(m, b, pa, pb, pc) -struct mesh *m; -struct behavior *b; -vertex pa; -vertex pb; -vertex pc; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL detleft, detright, det; - REAL detsum, errbound; - - m->counterclockcount++; - - detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); - detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); - det = detleft - detright; - - if (b->noexact) { - return det; - } - - if (detleft > 0.0) { - if (detright <= 0.0) { - return det; - } else { - detsum = detleft + detright; - } - } else if (detleft < 0.0) { - if (detright >= 0.0) { - return det; - } else { - detsum = -detleft - detright; - } - } else { - return det; - } - - errbound = ccwerrboundA * detsum; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - return counterclockwiseadapt(pa, pb, pc, detsum); -} - -/*****************************************************************************/ -/* */ -/* incircle() Return a positive value if the point pd lies inside the */ -/* circle passing through pa, pb, and pc; a negative value if */ -/* it lies outside; and zero if the four points are cocircular.*/ -/* The points pa, pb, and pc must be in counterclockwise */ -/* order, or the sign of the result will be reversed. */ -/* */ -/* Uses exact arithmetic if necessary to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. This determinant is */ -/* computed adaptively, in the sense that exact arithmetic is used only to */ -/* the degree it is needed to ensure that the returned value has the */ -/* correct sign. Hence, this function is usually quite fast, but will run */ -/* more slowly when the input points are cocircular or nearly so. */ -/* */ -/* See my Robust Predicates paper for details. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -REAL incircleadapt(vertex pa, vertex pb, vertex pc, vertex pd, REAL permanent) -#else /* not ANSI_DECLARATORS */ -REAL incircleadapt(pa, pb, pc, pd, permanent) -vertex pa; -vertex pb; -vertex pc; -vertex pd; -REAL permanent; -#endif /* not ANSI_DECLARATORS */ - -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; - REAL det, errbound; - - INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - INEXACT REAL bc3, ca3, ab3; - REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; - int axbclen, axxbclen, aybclen, ayybclen, alen; - REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; - int bxcalen, bxxcalen, bycalen, byycalen, blen; - REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; - int cxablen, cxxablen, cyablen, cyyablen, clen; - REAL abdet[64]; - int ablen; - REAL fin1[1152], fin2[1152]; - REAL *finnow, *finother, *finswap; - int finlength; - - REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; - INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; - REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; - REAL aa[4], bb[4], cc[4]; - INEXACT REAL aa3, bb3, cc3; - INEXACT REAL ti1, tj1; - REAL ti0, tj0; - REAL u[4], v[4]; - INEXACT REAL u3, v3; - REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; - REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; - int temp8len, temp16alen, temp16blen, temp16clen; - int temp32alen, temp32blen, temp48len, temp64len; - REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; - int axtbblen, axtcclen, aytbblen, aytcclen; - REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; - int bxtaalen, bxtcclen, bytaalen, bytcclen; - REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; - int cxtaalen, cxtbblen, cytaalen, cytbblen; - REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; - int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen; - REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; - int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen; - REAL axtbctt[8], aytbctt[8], bxtcatt[8]; - REAL bytcatt[8], cxtabtt[8], cytabtt[8]; - int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen; - REAL abt[8], bct[8], cat[8]; - int abtlen, bctlen, catlen; - REAL abtt[4], bctt[4], catt[4]; - int abttlen, bcttlen, cattlen; - INEXACT REAL abtt3, bctt3, catt3; - REAL negate; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j; - REAL _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); - axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); - aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); - ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); - alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); - bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); - bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); - byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); - blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); - cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); - cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); - cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); - clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = iccerrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) - && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { - return det; - } - - errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); - det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) - + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) - + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) - + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) - + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) - + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Square(adx, adxadx1, adxadx0); - Square(ady, adyady1, adyady0); - Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); - aa[3] = aa3; - } - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Square(bdx, bdxbdx1, bdxbdx0); - Square(bdy, bdybdy1, bdybdy0); - Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); - bb[3] = bb3; - } - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Square(cdx, cdxcdx1, cdxcdx0); - Square(cdy, cdycdy1, cdycdy0); - Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); - cc[3] = cc3; - } - - if (adxtail != 0.0) { - axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, - temp16a); - - axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); - temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); - - axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); - temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, - temp16a); - - aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); - temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); - - aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); - temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdxtail != 0.0) { - bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, - temp16a); - - bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); - temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); - - bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); - temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, - temp16a); - - bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); - temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); - - bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); - temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdxtail != 0.0) { - cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, - temp16a); - - cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); - temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); - - cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); - temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); - temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, - temp16a); - - cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); - temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); - - cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); - temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); - - temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if ((adxtail != 0.0) || (adytail != 0.0)) { - if ((bdxtail != 0.0) || (bdytail != 0.0) - || (cdxtail != 0.0) || (cdytail != 0.0)) { - Two_Product(bdxtail, cdy, ti1, ti0); - Two_Product(bdx, cdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -bdy; - Two_Product(cdxtail, negate, ti1, ti0); - negate = -bdytail; - Two_Product(cdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); - - Two_Product(bdxtail, cdytail, ti1, ti0); - Two_Product(cdxtail, bdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); - bctt[3] = bctt3; - bcttlen = 4; - } else { - bct[0] = 0.0; - bctlen = 1; - bctt[0] = 0.0; - bcttlen = 1; - } - - if (adxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); - axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, - temp32a); - axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); - temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, - temp16a); - temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); - aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, - temp32a); - aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); - temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, - temp16a); - temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((bdxtail != 0.0) || (bdytail != 0.0)) { - if ((cdxtail != 0.0) || (cdytail != 0.0) - || (adxtail != 0.0) || (adytail != 0.0)) { - Two_Product(cdxtail, ady, ti1, ti0); - Two_Product(cdx, adytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -cdy; - Two_Product(adxtail, negate, ti1, ti0); - negate = -cdytail; - Two_Product(adx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); - - Two_Product(cdxtail, adytail, ti1, ti0); - Two_Product(adxtail, cdytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); - catt[3] = catt3; - cattlen = 4; - } else { - cat[0] = 0.0; - catlen = 1; - catt[0] = 0.0; - cattlen = 1; - } - - if (bdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); - bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, - temp32a); - bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); - temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, - temp16a); - temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); - bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, - temp32a); - bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); - temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, - temp16a); - temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if ((cdxtail != 0.0) || (cdytail != 0.0)) { - if ((adxtail != 0.0) || (adytail != 0.0) - || (bdxtail != 0.0) || (bdytail != 0.0)) { - Two_Product(adxtail, bdy, ti1, ti0); - Two_Product(adx, bdytail, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); - u[3] = u3; - negate = -ady; - Two_Product(bdxtail, negate, ti1, ti0); - negate = -adytail; - Two_Product(bdx, negate, tj1, tj0); - Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); - v[3] = v3; - abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); - - Two_Product(adxtail, bdytail, ti1, ti0); - Two_Product(bdxtail, adytail, tj1, tj0); - Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); - abtt[3] = abtt3; - abttlen = 4; - } else { - abt[0] = 0.0; - abtlen = 1; - abtt[0] = 0.0; - abttlen = 1; - } - - if (cdxtail != 0.0) { - temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); - cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdytail != 0.0) { - temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); - temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, - temp16a); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, - temp16a, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, - temp32a); - cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); - temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, - temp16a); - temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdytail != 0.0) { - temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); - cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, - temp32a); - temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp32alen, temp32a, temp48); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, - temp48, finother); - finswap = finnow; finnow = finother; finother = finswap; - - - temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, - temp32a); - cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); - temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, - temp16a); - temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, - temp16b); - temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, - temp16blen, temp16b, temp32b); - temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, - temp32blen, temp32b, temp64); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, - temp64, finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - - return finnow[finlength - 1]; -} - -#ifdef ANSI_DECLARATORS -REAL incircle(struct mesh *m, struct behavior *b, - vertex pa, vertex pb, vertex pc, vertex pd) -#else /* not ANSI_DECLARATORS */ -REAL incircle(m, b, pa, pb, pc, pd) -struct mesh *m; -struct behavior *b; -vertex pa; -vertex pb; -vertex pc; -vertex pd; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL adx, bdx, cdx, ady, bdy, cdy; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL alift, blift, clift; - REAL det; - REAL permanent, errbound; - - m->incirclecount++; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - alift = adx * adx + ady * ady; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - blift = bdx * bdx + bdy * bdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - clift = cdx * cdx + cdy * cdy; - - det = alift * (bdxcdy - cdxbdy) - + blift * (cdxady - adxcdy) - + clift * (adxbdy - bdxady); - - if (b->noexact) { - return det; - } - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift - + (Absolute(cdxady) + Absolute(adxcdy)) * blift - + (Absolute(adxbdy) + Absolute(bdxady)) * clift; - errbound = iccerrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return incircleadapt(pa, pb, pc, pd, permanent); -} - -/*****************************************************************************/ -/* */ -/* orient3d() Return a positive value if the point pd lies below the */ -/* plane passing through pa, pb, and pc; "below" is defined so */ -/* that pa, pb, and pc appear in counterclockwise order when */ -/* viewed from above the plane. Returns a negative value if */ -/* pd lies above the plane. Returns zero if the points are */ -/* coplanar. The result is also a rough approximation of six */ -/* times the signed volume of the tetrahedron defined by the */ -/* four points. */ -/* */ -/* Uses exact arithmetic if necessary to ensure a correct answer. The */ -/* result returned is the determinant of a matrix. This determinant is */ -/* computed adaptively, in the sense that exact arithmetic is used only to */ -/* the degree it is needed to ensure that the returned value has the */ -/* correct sign. Hence, this function is usually quite fast, but will run */ -/* more slowly when the input points are coplanar or nearly so. */ -/* */ -/* See my Robust Predicates paper for details. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -REAL orient3dadapt(vertex pa, vertex pb, vertex pc, vertex pd, - REAL aheight, REAL bheight, REAL cheight, REAL dheight, - REAL permanent) -#else /* not ANSI_DECLARATORS */ -REAL orient3dadapt(pa, pb, pc, pd, - aheight, bheight, cheight, dheight, permanent) -vertex pa; -vertex pb; -vertex pc; -vertex pd; -REAL aheight; -REAL bheight; -REAL cheight; -REAL dheight; -REAL permanent; -#endif /* not ANSI_DECLARATORS */ - -{ - INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight; - REAL det, errbound; - - INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; - REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; - REAL bc[4], ca[4], ab[4]; - INEXACT REAL bc3, ca3, ab3; - REAL adet[8], bdet[8], cdet[8]; - int alen, blen, clen; - REAL abdet[16]; - int ablen; - REAL *finnow, *finother, *finswap; - REAL fin1[192], fin2[192]; - int finlength; - - REAL adxtail, bdxtail, cdxtail; - REAL adytail, bdytail, cdytail; - REAL adheighttail, bdheighttail, cdheighttail; - INEXACT REAL at_blarge, at_clarge; - INEXACT REAL bt_clarge, bt_alarge; - INEXACT REAL ct_alarge, ct_blarge; - REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; - int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen; - INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; - INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; - REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; - REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; - INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; - INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; - REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; - REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; - REAL bct[8], cat[8], abt[8]; - int bctlen, catlen, abtlen; - INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; - INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; - REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; - REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; - REAL u[4], v[12], w[16]; - INEXACT REAL u3; - int vlength, wlength; - REAL negate; - - INEXACT REAL bvirt; - REAL avirt, bround, around; - INEXACT REAL c; - INEXACT REAL abig; - REAL ahi, alo, bhi, blo; - REAL err1, err2, err3; - INEXACT REAL _i, _j, _k; - REAL _0; - - adx = (REAL) (pa[0] - pd[0]); - bdx = (REAL) (pb[0] - pd[0]); - cdx = (REAL) (pc[0] - pd[0]); - ady = (REAL) (pa[1] - pd[1]); - bdy = (REAL) (pb[1] - pd[1]); - cdy = (REAL) (pc[1] - pd[1]); - adheight = (REAL) (aheight - dheight); - bdheight = (REAL) (bheight - dheight); - cdheight = (REAL) (cheight - dheight); - - Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); - Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); - Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); - bc[3] = bc3; - alen = scale_expansion_zeroelim(4, bc, adheight, adet); - - Two_Product(cdx, ady, cdxady1, cdxady0); - Two_Product(adx, cdy, adxcdy1, adxcdy0); - Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); - ca[3] = ca3; - blen = scale_expansion_zeroelim(4, ca, bdheight, bdet); - - Two_Product(adx, bdy, adxbdy1, adxbdy0); - Two_Product(bdx, ady, bdxady1, bdxady0); - Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); - ab[3] = ab3; - clen = scale_expansion_zeroelim(4, ab, cdheight, cdet); - - ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); - finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); - - det = estimate(finlength, fin1); - errbound = o3derrboundB * permanent; - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - Two_Diff_Tail(pa[0], pd[0], adx, adxtail); - Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); - Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); - Two_Diff_Tail(pa[1], pd[1], ady, adytail); - Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); - Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); - Two_Diff_Tail(aheight, dheight, adheight, adheighttail); - Two_Diff_Tail(bheight, dheight, bdheight, bdheighttail); - Two_Diff_Tail(cheight, dheight, cdheight, cdheighttail); - - if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) && - (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) && - (adheighttail == 0.0) && - (bdheighttail == 0.0) && - (cdheighttail == 0.0)) { - return det; - } - - errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); - det += (adheight * ((bdx * cdytail + cdy * bdxtail) - - (bdy * cdxtail + cdx * bdytail)) + - adheighttail * (bdx * cdy - bdy * cdx)) + - (bdheight * ((cdx * adytail + ady * cdxtail) - - (cdy * adxtail + adx * cdytail)) + - bdheighttail * (cdx * ady - cdy * adx)) + - (cdheight * ((adx * bdytail + bdy * adxtail) - - (ady * bdxtail + bdx * adytail)) + - cdheighttail * (adx * bdy - ady * bdx)); - if ((det >= errbound) || (-det >= errbound)) { - return det; - } - - finnow = fin1; - finother = fin2; - - if (adxtail == 0.0) { - if (adytail == 0.0) { - at_b[0] = 0.0; - at_blen = 1; - at_c[0] = 0.0; - at_clen = 1; - } else { - negate = -adytail; - Two_Product(negate, bdx, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - Two_Product(adytail, cdx, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } - } else { - if (adytail == 0.0) { - Two_Product(adxtail, bdy, at_blarge, at_b[0]); - at_b[1] = at_blarge; - at_blen = 2; - negate = -adxtail; - Two_Product(negate, cdy, at_clarge, at_c[0]); - at_c[1] = at_clarge; - at_clen = 2; - } else { - Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); - Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); - Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, - at_blarge, at_b[2], at_b[1], at_b[0]); - at_b[3] = at_blarge; - at_blen = 4; - Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); - Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); - Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, - at_clarge, at_c[2], at_c[1], at_c[0]); - at_c[3] = at_clarge; - at_clen = 4; - } - } - if (bdxtail == 0.0) { - if (bdytail == 0.0) { - bt_c[0] = 0.0; - bt_clen = 1; - bt_a[0] = 0.0; - bt_alen = 1; - } else { - negate = -bdytail; - Two_Product(negate, cdx, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - Two_Product(bdytail, adx, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } - } else { - if (bdytail == 0.0) { - Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); - bt_c[1] = bt_clarge; - bt_clen = 2; - negate = -bdxtail; - Two_Product(negate, ady, bt_alarge, bt_a[0]); - bt_a[1] = bt_alarge; - bt_alen = 2; - } else { - Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); - Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); - Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, - bt_clarge, bt_c[2], bt_c[1], bt_c[0]); - bt_c[3] = bt_clarge; - bt_clen = 4; - Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); - Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); - Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, - bt_alarge, bt_a[2], bt_a[1], bt_a[0]); - bt_a[3] = bt_alarge; - bt_alen = 4; - } - } - if (cdxtail == 0.0) { - if (cdytail == 0.0) { - ct_a[0] = 0.0; - ct_alen = 1; - ct_b[0] = 0.0; - ct_blen = 1; - } else { - negate = -cdytail; - Two_Product(negate, adx, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } - } else { - if (cdytail == 0.0) { - Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); - ct_a[1] = ct_alarge; - ct_alen = 2; - negate = -cdxtail; - Two_Product(negate, bdy, ct_blarge, ct_b[0]); - ct_b[1] = ct_blarge; - ct_blen = 2; - } else { - Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); - Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); - Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, - ct_alarge, ct_a[2], ct_a[1], ct_a[0]); - ct_a[3] = ct_alarge; - ct_alen = 4; - Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); - Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); - Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, - ct_blarge, ct_b[2], ct_b[1], ct_b[0]); - ct_b[3] = ct_blarge; - ct_blen = 4; - } - } - - bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); - wlength = scale_expansion_zeroelim(bctlen, bct, adheight, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); - wlength = scale_expansion_zeroelim(catlen, cat, bdheight, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); - wlength = scale_expansion_zeroelim(abtlen, abt, cdheight, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - - if (adheighttail != 0.0) { - vlength = scale_expansion_zeroelim(4, bc, adheighttail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdheighttail != 0.0) { - vlength = scale_expansion_zeroelim(4, ca, bdheighttail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdheighttail != 0.0) { - vlength = scale_expansion_zeroelim(4, ab, cdheighttail, v); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - if (adxtail != 0.0) { - if (bdytail != 0.0) { - Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheight, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdheighttail != 0.0) { - Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheighttail, - u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (cdytail != 0.0) { - negate = -adxtail; - Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheight, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdheighttail != 0.0) { - Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheighttail, - u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (bdxtail != 0.0) { - if (cdytail != 0.0) { - Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheight, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adheighttail != 0.0) { - Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheighttail, - u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (adytail != 0.0) { - negate = -bdxtail; - Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheight, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (cdheighttail != 0.0) { - Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheighttail, - u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - if (cdxtail != 0.0) { - if (adytail != 0.0) { - Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheight, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (bdheighttail != 0.0) { - Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheighttail, - u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - if (bdytail != 0.0) { - negate = -cdxtail; - Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheight, u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - if (adheighttail != 0.0) { - Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheighttail, - u3, u[2], u[1], u[0]); - u[3] = u3; - finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - } - } - - if (adheighttail != 0.0) { - wlength = scale_expansion_zeroelim(bctlen, bct, adheighttail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (bdheighttail != 0.0) { - wlength = scale_expansion_zeroelim(catlen, cat, bdheighttail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - if (cdheighttail != 0.0) { - wlength = scale_expansion_zeroelim(abtlen, abt, cdheighttail, w); - finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, - finother); - finswap = finnow; finnow = finother; finother = finswap; - } - - return finnow[finlength - 1]; -} - -#ifdef ANSI_DECLARATORS -REAL orient3d(struct mesh *m, struct behavior *b, - vertex pa, vertex pb, vertex pc, vertex pd, - REAL aheight, REAL bheight, REAL cheight, REAL dheight) -#else /* not ANSI_DECLARATORS */ -REAL orient3d(m, b, pa, pb, pc, pd, aheight, bheight, cheight, dheight) -struct mesh *m; -struct behavior *b; -vertex pa; -vertex pb; -vertex pc; -vertex pd; -REAL aheight; -REAL bheight; -REAL cheight; -REAL dheight; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight; - REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; - REAL det; - REAL permanent, errbound; - - m->orient3dcount++; - - adx = pa[0] - pd[0]; - bdx = pb[0] - pd[0]; - cdx = pc[0] - pd[0]; - ady = pa[1] - pd[1]; - bdy = pb[1] - pd[1]; - cdy = pc[1] - pd[1]; - adheight = aheight - dheight; - bdheight = bheight - dheight; - cdheight = cheight - dheight; - - bdxcdy = bdx * cdy; - cdxbdy = cdx * bdy; - - cdxady = cdx * ady; - adxcdy = adx * cdy; - - adxbdy = adx * bdy; - bdxady = bdx * ady; - - det = adheight * (bdxcdy - cdxbdy) - + bdheight * (cdxady - adxcdy) - + cdheight * (adxbdy - bdxady); - - if (b->noexact) { - return det; - } - - permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adheight) - + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdheight) - + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdheight); - errbound = o3derrboundA * permanent; - if ((det > errbound) || (-det > errbound)) { - return det; - } - - return orient3dadapt(pa, pb, pc, pd, aheight, bheight, cheight, dheight, - permanent); -} - -/*****************************************************************************/ -/* */ -/* nonregular() Return a positive value if the point pd is incompatible */ -/* with the circle or plane passing through pa, pb, and pc */ -/* (meaning that pd is inside the circle or below the */ -/* plane); a negative value if it is compatible; and zero if */ -/* the four points are cocircular/coplanar. The points pa, */ -/* pb, and pc must be in counterclockwise order, or the sign */ -/* of the result will be reversed. */ -/* */ -/* If the -w switch is used, the points are lifted onto the parabolic */ -/* lifting map, then they are dropped according to their weights, then the */ -/* 3D orientation test is applied. If the -W switch is used, the points' */ -/* heights are already provided, so the 3D orientation test is applied */ -/* directly. If neither switch is used, the incircle test is applied. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -REAL nonregular(struct mesh *m, struct behavior *b, - vertex pa, vertex pb, vertex pc, vertex pd) -#else /* not ANSI_DECLARATORS */ -REAL nonregular(m, b, pa, pb, pc, pd) -struct mesh *m; -struct behavior *b; -vertex pa; -vertex pb; -vertex pc; -vertex pd; -#endif /* not ANSI_DECLARATORS */ - -{ - if (b->weighted == 0) { - return incircle(m, b, pa, pb, pc, pd); - } else if (b->weighted == 1) { - return orient3d(m, b, pa, pb, pc, pd, - pa[0] * pa[0] + pa[1] * pa[1] - pa[2], - pb[0] * pb[0] + pb[1] * pb[1] - pb[2], - pc[0] * pc[0] + pc[1] * pc[1] - pc[2], - pd[0] * pd[0] + pd[1] * pd[1] - pd[2]); - } else { - return orient3d(m, b, pa, pb, pc, pd, pa[2], pb[2], pc[2], pd[2]); - } -} - -/*****************************************************************************/ -/* */ -/* findcircumcenter() Find the circumcenter of a triangle. */ -/* */ -/* The result is returned both in terms of x-y coordinates and xi-eta */ -/* (barycentric) coordinates. The xi-eta coordinate system is defined in */ -/* terms of the triangle: the origin of the triangle is the origin of the */ -/* coordinate system; the destination of the triangle is one unit along the */ -/* xi axis; and the apex of the triangle is one unit along the eta axis. */ -/* This procedure also returns the square of the length of the triangle's */ -/* shortest edge. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void findcircumcenter(struct mesh *m, struct behavior *b, - vertex torg, vertex tdest, vertex tapex, - vertex circumcenter, REAL *xi, REAL *eta, REAL *minedge, - int offcenter) -#else /* not ANSI_DECLARATORS */ -void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta, minedge, - offcenter) -struct mesh *m; -struct behavior *b; -vertex torg; -vertex tdest; -vertex tapex; -vertex circumcenter; -REAL *xi; -REAL *eta; -REAL *minedge; -int offcenter; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL xdo, ydo, xao, yao; - REAL dodist, aodist, dadist; - REAL denominator; - REAL dx, dy, dxoff, dyoff; - - m->circumcentercount++; - - /* Compute the circumcenter of the triangle. */ - xdo = tdest[0] - torg[0]; - ydo = tdest[1] - torg[1]; - xao = tapex[0] - torg[0]; - yao = tapex[1] - torg[1]; - dodist = xdo * xdo + ydo * ydo; - aodist = xao * xao + yao * yao; - dadist = (tdest[0] - tapex[0]) * (tdest[0] - tapex[0]) + - (tdest[1] - tapex[1]) * (tdest[1] - tapex[1]); - if (b->noexact) { - denominator = 0.5 / (xdo * yao - xao * ydo); - } else { - /* Use the counterclockwise() routine to ensure a positive (and */ - /* reasonably accurate) result, avoiding any possibility of */ - /* division by zero. */ - denominator = 0.5 / counterclockwise(m, b, tdest, tapex, torg); - /* Don't count the above as an orientation test. */ - m->counterclockcount--; - } - dx = (yao * dodist - ydo * aodist) * denominator; - dy = (xdo * aodist - xao * dodist) * denominator; - - /* Find the (squared) length of the triangle's shortest edge. This */ - /* serves as a conservative estimate of the insertion radius of the */ - /* circumcenter's parent. The estimate is used to ensure that */ - /* the algorithm terminates even if very small angles appear in */ - /* the input PSLG. */ - if ((dodist < aodist) && (dodist < dadist)) { - *minedge = dodist; - if (offcenter && (b->offconstant > 0.0)) { - /* Find the position of the off-center, as described by Alper Ungor. */ - dxoff = 0.5 * xdo - b->offconstant * ydo; - dyoff = 0.5 * ydo + b->offconstant * xdo; - /* If the off-center is closer to the origin than the */ - /* circumcenter, use the off-center instead. */ - if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) { - dx = dxoff; - dy = dyoff; - } - } - } else if (aodist < dadist) { - *minedge = aodist; - if (offcenter && (b->offconstant > 0.0)) { - dxoff = 0.5 * xao + b->offconstant * yao; - dyoff = 0.5 * yao - b->offconstant * xao; - /* If the off-center is closer to the origin than the */ - /* circumcenter, use the off-center instead. */ - if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) { - dx = dxoff; - dy = dyoff; - } - } - } else { - *minedge = dadist; - if (offcenter && (b->offconstant > 0.0)) { - dxoff = 0.5 * (tapex[0] - tdest[0]) - - b->offconstant * (tapex[1] - tdest[1]); - dyoff = 0.5 * (tapex[1] - tdest[1]) + - b->offconstant * (tapex[0] - tdest[0]); - /* If the off-center is closer to the destination than the */ - /* circumcenter, use the off-center instead. */ - if (dxoff * dxoff + dyoff * dyoff < - (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo)) { - dx = xdo + dxoff; - dy = ydo + dyoff; - } - } - } - - circumcenter[0] = torg[0] + dx; - circumcenter[1] = torg[1] + dy; - - /* To interpolate vertex attributes for the new vertex inserted at */ - /* the circumcenter, define a coordinate system with a xi-axis, */ - /* directed from the triangle's origin to its destination, and */ - /* an eta-axis, directed from its origin to its apex. */ - /* Calculate the xi and eta coordinates of the circumcenter. */ - *xi = (yao * dx - xao * dy) * (2.0 * denominator); - *eta = (xdo * dy - ydo * dx) * (2.0 * denominator); -} - -/** **/ -/** **/ -/********* Geometric primitives end here *********/ - -/*****************************************************************************/ -/* */ -/* triangleinit() Initialize some variables. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void triangleinit(struct mesh *m) -#else /* not ANSI_DECLARATORS */ -void triangleinit(m) -struct mesh *m; -#endif /* not ANSI_DECLARATORS */ - -{ - m->vertices.maxitems = m->triangles.maxitems = m->subsegs.maxitems = - m->viri.maxitems = m->badsubsegs.maxitems = m->badtriangles.maxitems = - m->flipstackers.maxitems = m->splaynodes.maxitems = 0l; - m->vertices.itembytes = m->triangles.itembytes = m->subsegs.itembytes = - m->viri.itembytes = m->badsubsegs.itembytes = m->badtriangles.itembytes = - m->flipstackers.itembytes = m->splaynodes.itembytes = 0; - m->recenttri.tri = (triangle *) NULL; /* No triangle has been visited yet. */ - m->undeads = 0; /* No eliminated input vertices yet. */ - m->samples = 1; /* Point location should take at least one sample. */ - m->checksegments = 0; /* There are no segments in the triangulation yet. */ - m->checkquality = 0; /* The quality triangulation stage has not begun. */ - m->incirclecount = m->counterclockcount = m->orient3dcount = 0; - m->hyperbolacount = m->circletopcount = m->circumcentercount = 0; - randomseed = 1; - - exactinit(); /* Initialize exact arithmetic constants. */ -} - -/*****************************************************************************/ -/* */ -/* randomnation() Generate a random number between 0 and `choices' - 1. */ -/* */ -/* This is a simple linear congruential random number generator. Hence, it */ -/* is a bad random number generator, but good enough for most randomized */ -/* geometric algorithms. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -unsigned long randomnation(unsigned int choices) -#else /* not ANSI_DECLARATORS */ -unsigned long randomnation(choices) -unsigned int choices; -#endif /* not ANSI_DECLARATORS */ - -{ - randomseed = (randomseed * 1366l + 150889l) % 714025l; - return randomseed / (714025l / choices + 1); -} - -/********* Mesh quality testing routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* checkmesh() Test the mesh for topological consistency. */ -/* */ -/*****************************************************************************/ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void checkmesh(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void checkmesh(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri triangleloop; - struct otri oppotri, oppooppotri; - vertex triorg, tridest, triapex; - vertex oppoorg, oppodest; - int horrors; - int saveexact; - triangle ptr; /* Temporary variable used by sym(). */ - - /* Temporarily turn on exact arithmetic if it's off. */ - saveexact = b->noexact; - b->noexact = 0; - if (!b->quiet) { - printf(" Checking consistency of mesh...\n"); - } - horrors = 0; - /* Run through the list of triangles, checking each one. */ - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - while (triangleloop.tri != (triangle *) NULL) { - /* Check all three edges of the triangle. */ - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - org(triangleloop, triorg); - dest(triangleloop, tridest); - if (triangleloop.orient == 0) { /* Only test for inversion once. */ - /* Test if the triangle is flat or inverted. */ - apex(triangleloop, triapex); - if (counterclockwise(m, b, triorg, tridest, triapex) <= 0.0) { - printf(" !! !! Inverted "); - printtriangle(m, b, &triangleloop); - horrors++; - } - } - /* Find the neighboring triangle on this edge. */ - sym(triangleloop, oppotri); - if (oppotri.tri != m->dummytri) { - /* Check that the triangle's neighbor knows it's a neighbor. */ - sym(oppotri, oppooppotri); - if ((triangleloop.tri != oppooppotri.tri) - || (triangleloop.orient != oppooppotri.orient)) { - printf(" !! !! Asymmetric triangle-triangle bond:\n"); - if (triangleloop.tri == oppooppotri.tri) { - printf(" (Right triangle, wrong orientation)\n"); - } - printf(" First "); - printtriangle(m, b, &triangleloop); - printf(" Second (nonreciprocating) "); - printtriangle(m, b, &oppotri); - horrors++; - } - /* Check that both triangles agree on the identities */ - /* of their shared vertices. */ - org(oppotri, oppoorg); - dest(oppotri, oppodest); - if ((triorg != oppodest) || (tridest != oppoorg)) { - printf(" !! !! Mismatched edge coordinates between two triangles:\n" - ); - printf(" First mismatched "); - printtriangle(m, b, &triangleloop); - printf(" Second mismatched "); - printtriangle(m, b, &oppotri); - horrors++; - } - } - } - triangleloop.tri = triangletraverse(m); - } - if (horrors == 0) { - if (!b->quiet) { - printf(" In my studied opinion, the mesh appears to be consistent.\n"); - } - } else if (horrors == 1) { - printf(" !! !! !! !! Precisely one festering wound discovered.\n"); - } else { - printf(" !! !! !! !! %d abominations witnessed.\n", horrors); - } - /* Restore the status of exact arithmetic. */ - b->noexact = saveexact; -} - -#endif /* not REDUCED */ - -/*****************************************************************************/ -/* */ -/* checkdelaunay() Ensure that the mesh is (constrained) Delaunay. */ -/* */ -/*****************************************************************************/ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void checkdelaunay(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void checkdelaunay(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri triangleloop; - struct otri oppotri; - struct osub opposubseg; - vertex triorg, tridest, triapex; - vertex oppoapex; - int shouldbedelaunay; - int horrors; - int saveexact; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - /* Temporarily turn on exact arithmetic if it's off. */ - saveexact = b->noexact; - b->noexact = 0; - if (!b->quiet) { - printf(" Checking Delaunay property of mesh...\n"); - } - horrors = 0; - /* Run through the list of triangles, checking each one. */ - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - while (triangleloop.tri != (triangle *) NULL) { - /* Check all three edges of the triangle. */ - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - org(triangleloop, triorg); - dest(triangleloop, tridest); - apex(triangleloop, triapex); - sym(triangleloop, oppotri); - apex(oppotri, oppoapex); - /* Only test that the edge is locally Delaunay if there is an */ - /* adjoining triangle whose pointer is larger (to ensure that */ - /* each pair isn't tested twice). */ - shouldbedelaunay = (oppotri.tri != m->dummytri) && - !deadtri(oppotri.tri) && (triangleloop.tri < oppotri.tri) && - (triorg != m->infvertex1) && (triorg != m->infvertex2) && - (triorg != m->infvertex3) && - (tridest != m->infvertex1) && (tridest != m->infvertex2) && - (tridest != m->infvertex3) && - (triapex != m->infvertex1) && (triapex != m->infvertex2) && - (triapex != m->infvertex3) && - (oppoapex != m->infvertex1) && (oppoapex != m->infvertex2) && - (oppoapex != m->infvertex3); - if (m->checksegments && shouldbedelaunay) { - /* If a subsegment separates the triangles, then the edge is */ - /* constrained, so no local Delaunay test should be done. */ - tspivot(triangleloop, opposubseg); - if (opposubseg.ss != m->dummysub){ - shouldbedelaunay = 0; - } - } - if (shouldbedelaunay) { - if (nonregular(m, b, triorg, tridest, triapex, oppoapex) > 0.0) { - if (!b->weighted) { - printf(" !! !! Non-Delaunay pair of triangles:\n"); - printf(" First non-Delaunay "); - printtriangle(m, b, &triangleloop); - printf(" Second non-Delaunay "); - } else { - printf(" !! !! Non-regular pair of triangles:\n"); - printf(" First non-regular "); - printtriangle(m, b, &triangleloop); - printf(" Second non-regular "); - } - printtriangle(m, b, &oppotri); - horrors++; - } - } - } - triangleloop.tri = triangletraverse(m); - } - if (horrors == 0) { - if (!b->quiet) { - printf( - " By virtue of my perceptive intelligence, I declare the mesh Delaunay.\n"); - } - } else if (horrors == 1) { - printf( - " !! !! !! !! Precisely one terrifying transgression identified.\n"); - } else { - printf(" !! !! !! !! %d obscenities viewed with horror.\n", horrors); - } - /* Restore the status of exact arithmetic. */ - b->noexact = saveexact; -} - -#endif /* not REDUCED */ - -/*****************************************************************************/ -/* */ -/* enqueuebadtriang() Add a bad triangle data structure to the end of a */ -/* queue. */ -/* */ -/* The queue is actually a set of 64 queues. I use multiple queues to give */ -/* priority to smaller angles. I originally implemented a heap, but the */ -/* queues are faster by a larger margin than I'd suspected. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void enqueuebadtriang(struct mesh *m, struct behavior *b, - struct badtriang *badtri) -#else /* not ANSI_DECLARATORS */ -void enqueuebadtriang(m, b, badtri) -struct mesh *m; -struct behavior *b; -struct badtriang *badtri; -#endif /* not ANSI_DECLARATORS */ - -{ - int queuenumber; - int i; - - if (b->verbose > 2) { - printf(" Queueing bad triangle:\n"); - printf(" (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - badtri->triangorg[0], badtri->triangorg[1], - badtri->triangdest[0], badtri->triangdest[1], - badtri->triangapex[0], badtri->triangapex[1]); - } - /* Determine the appropriate queue to put the bad triangle into. */ - if (badtri->key > 0.6) { - queuenumber = (int) (160.0 * (badtri->key - 0.6)); - if (queuenumber > 63) { - queuenumber = 63; - } - } else { - /* It's not a bad angle; put the triangle in the lowest-priority queue. */ - queuenumber = 0; - } - - /* Are we inserting into an empty queue? */ - if (m->queuefront[queuenumber] == (struct badtriang *) NULL) { - /* Yes, we are inserting into an empty queue. */ - /* Will this become the highest-priority queue? */ - if (queuenumber > m->firstnonemptyq) { - /* Yes, this is the highest-priority queue. */ - m->nextnonemptyq[queuenumber] = m->firstnonemptyq; - m->firstnonemptyq = queuenumber; - } else { - /* No, this is not the highest-priority queue. */ - /* Find the queue with next higher priority. */ - i = queuenumber + 1; - while (m->queuefront[i] == (struct badtriang *) NULL) { - i++; - } - /* Mark the newly nonempty queue as following a higher-priority queue. */ - m->nextnonemptyq[queuenumber] = m->nextnonemptyq[i]; - m->nextnonemptyq[i] = queuenumber; - } - /* Put the bad triangle at the beginning of the (empty) queue. */ - m->queuefront[queuenumber] = badtri; - } else { - /* Add the bad triangle to the end of an already nonempty queue. */ - m->queuetail[queuenumber]->nexttriang = badtri; - } - /* Maintain a pointer to the last triangle of the queue. */ - m->queuetail[queuenumber] = badtri; - /* Newly enqueued bad triangle has no successor in the queue. */ - badtri->nexttriang = (struct badtriang *) NULL; -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* enqueuebadtri() Add a bad triangle to the end of a queue. */ -/* */ -/* Allocates a badtriang data structure for the triangle, then passes it to */ -/* enqueuebadtriang(). */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void enqueuebadtri(struct mesh *m, struct behavior *b, struct otri *enqtri, - REAL angle, vertex enqapex, vertex enqorg, vertex enqdest) -#else /* not ANSI_DECLARATORS */ -void enqueuebadtri(m, b, enqtri, angle, enqapex, enqorg, enqdest) -struct mesh *m; -struct behavior *b; -struct otri *enqtri; -REAL angle; -vertex enqapex; -vertex enqorg; -vertex enqdest; -#endif /* not ANSI_DECLARATORS */ - -{ - struct badtriang *newbad; - - /* Allocate space for the bad triangle. */ - newbad = (struct badtriang *) poolalloc(&m->badtriangles); - newbad->poortri = encode(*enqtri); - newbad->key = angle; - newbad->triangapex = enqapex; - newbad->triangorg = enqorg; - newbad->triangdest = enqdest; - enqueuebadtriang(m, b, newbad); -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* dequeuebadtriang() Remove a triangle from the front of the queue. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -struct badtriang *dequeuebadtriang(struct mesh *m) -#else /* not ANSI_DECLARATORS */ -struct badtriang *dequeuebadtriang(m) -struct mesh *m; -#endif /* not ANSI_DECLARATORS */ - -{ - struct badtriang *result; - - /* If no queues are nonempty, return NULL. */ - if (m->firstnonemptyq < 0) { - return (struct badtriang *) NULL; - } - /* Find the first triangle of the highest-priority queue. */ - result = m->queuefront[m->firstnonemptyq]; - /* Remove the triangle from the queue. */ - m->queuefront[m->firstnonemptyq] = result->nexttriang; - /* If this queue is now empty, note the new highest-priority */ - /* nonempty queue. */ - if (result == m->queuetail[m->firstnonemptyq]) { - m->firstnonemptyq = m->nextnonemptyq[m->firstnonemptyq]; - } - return result; -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* under60degrees() Return 1 if the two incident input segments are */ -/* separated by an angle less than 60 degrees; */ -/* 0 otherwise. */ -/* */ -/* The two input segments MUST have the same origin. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -int under60degrees(struct osub *sub1, struct osub *sub2) { - vertex segmentapex, v1, v2; - REAL dotprod; - - sorg(*sub1, segmentapex); - sdest(*sub1, v1); - sdest(*sub2, v2); - dotprod = (v2[0] - segmentapex[0]) * (v1[0] - segmentapex[0]) + - (v2[1] - segmentapex[1]) * (v1[1] - segmentapex[1]); - return (dotprod > 0.0) && - (4.0 * dotprod * dotprod > - ((v1[0] - segmentapex[0]) * (v1[0] - segmentapex[0]) + - (v1[1] - segmentapex[1]) * (v1[1] - segmentapex[1])) * - ((v2[0] - segmentapex[0]) * (v2[0] - segmentapex[0]) + - (v2[1] - segmentapex[1]) * (v2[1] - segmentapex[1]))); -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* clockwiseseg() Find the next segment clockwise from `thissub' having */ -/* the same origin and return it as `nextsub' if the */ -/* intervening region is inside the domain. */ -/* */ -/* Returns 1 if the next segment is separated from `thissub' by less than */ -/* 60 degrees, and the intervening region is inside the domain. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -int clockwiseseg(struct mesh *m, struct osub *thissub, struct osub *nextsub) { - struct otri neighbortri; - triangle ptr; /* Temporary variable used by sym() and stpivot(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - stpivot(*thissub, neighbortri); - if (neighbortri.tri == m->dummytri) { - return 0; - } else { - lnextself(neighbortri); - tspivot(neighbortri, *nextsub); - while (nextsub->ss == m->dummysub) { - symself(neighbortri); - lnextself(neighbortri); - tspivot(neighbortri, *nextsub); - } - ssymself(*nextsub); - return under60degrees(thissub, nextsub); - } -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* counterclockwiseseg() Find the next segment counterclockwise from */ -/* `thissub' having the same origin and return it */ -/* as `nextsub' if the intervening region is inside */ -/* the domain. */ -/* */ -/* Returns 1 if the next segment is separated from `thissub' by less than */ -/* 60 degrees, and the intervening region is inside the domain. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -int counterclockwiseseg(struct mesh *m, struct osub *thissub, - struct osub *nextsub) { - struct otri neighbortri; - struct osub subsym; - triangle ptr; /* Temporary variable used by sym() and stpivot(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - ssym(*thissub, subsym); - stpivot(subsym, neighbortri); - if (neighbortri.tri == m->dummytri) { - return 0; - } else { - lprevself(neighbortri); - tspivot(neighbortri, *nextsub); - while (nextsub->ss == m->dummysub) { - symself(neighbortri); - lprevself(neighbortri); - tspivot(neighbortri, *nextsub); - } - return under60degrees(thissub, nextsub); - } -} - -#endif /* not CDT_ONLY */ - -#ifndef CDT_ONLY - -/*****************************************************************************/ -/* */ -/* splitpermitted() Return 1 if `testsubseg' is part of a subsegment */ -/* cluster that is eligible for splitting. */ -/* */ -/* The term "subsegment cluster" is formally defined in my paper "Mesh */ -/* Generation for Domains with Small Angles." The algorithm that uses this */ -/* procedure is also described there. */ -/* */ -/* A subsegment cluster is eligible for splitting if (1) it includes a */ -/* subsegment whose length is not a power of two, (2) its subsegments are */ -/* not all the same length, or (3) no new edge that will be created by */ -/* splitting all the subsegments in the cluster has a length shorter than */ -/* the insertion radius of the encroaching vertex, whose square is given */ -/* as the parameter `iradius'. Note that the shortest edges created by */ -/* splitting a cluster are those whose endpoints are both subsegment */ -/* midpoints introduced when the cluster is split. */ -/* */ -/* `testsubseg' is also eligible for splitting (and a 1 will be returned) */ -/* if it is part of two subsegment clusters; one at its origin and one at */ -/* its destination. */ -/* */ -/*****************************************************************************/ - -int splitpermitted(struct mesh *m, struct osub *testsubseg, REAL iradius) { - struct osub cwsubseg, ccwsubseg, cwsubseg2, ccwsubseg2; - struct osub testsym; - struct osub startsubseg, nowsubseg; - vertex suborg, dest1, dest2; - REAL nearestpoweroffour, seglength, prevseglength, edgelength; - int cwsmall, ccwsmall, cwsmall2, ccwsmall2; - int orgcluster, destcluster; - int toosmall; - - /* Find the square of the subsegment's length, and the nearest power of */ - /* four (which is the square of the nearest power of two to the */ - /* subsegment's length). */ - sorg(*testsubseg, suborg); - sdest(*testsubseg, dest1); - seglength = (dest1[0] - suborg[0]) * (dest1[0] - suborg[0]) + - (dest1[1] - suborg[1]) * (dest1[1] - suborg[1]); - nearestpoweroffour = 1.0; - while (seglength > 2.0 * nearestpoweroffour) { - nearestpoweroffour *= 4.0; - } - while (seglength < 0.5 * nearestpoweroffour) { - nearestpoweroffour *= 0.25; - } - /* If the segment's length is not a power of two, the segment */ - /* is eligible for splitting. */ - if ((nearestpoweroffour > 1.001 * seglength) || - (nearestpoweroffour < 0.999 * seglength)) { - return 1; - } - - /* Is `testsubseg' part of a subsegment cluster at its origin? */ - cwsmall = clockwiseseg(m, testsubseg, &cwsubseg); - ccwsmall = cwsmall ? 0 : counterclockwiseseg(m, testsubseg, &ccwsubseg); - orgcluster = cwsmall || ccwsmall; - - /* Is `testsubseg' part of a subsegment cluster at its destination? */ - ssym(*testsubseg, testsym); - cwsmall2 = clockwiseseg(m, &testsym, &cwsubseg2); - ccwsmall2 = cwsmall2 ? 0 : counterclockwiseseg(m, &testsym, &ccwsubseg2); - destcluster = cwsmall2 || ccwsmall2; - - if (orgcluster == destcluster) { - /* `testsubseg' is part of two clusters or none, */ - /* and thus should be split. */ - return 1; - } else if (orgcluster) { - /* `testsubseg' is part of a cluster at its origin. */ - subsegcopy(*testsubseg, startsubseg); - } else { - /* `testsubseg' is part of a cluster at its destination; switch to */ - /* the symmetric case, so we can use the same code to handle it. */ - subsegcopy(testsym, startsubseg); - subsegcopy(cwsubseg2, cwsubseg); - subsegcopy(ccwsubseg2, ccwsubseg); - cwsmall = cwsmall2; - ccwsmall = ccwsmall2; - } - - toosmall = 0; - if (cwsmall) { - /* Check the subsegment(s) clockwise from `testsubseg'. */ - subsegcopy(startsubseg, nowsubseg); - sorg(nowsubseg, suborg); - sdest(nowsubseg, dest1); - prevseglength = nearestpoweroffour; - do { - /* Is the next subsegment shorter than `startsubseg'? */ - sdest(cwsubseg, dest2); - seglength = (dest2[0] - suborg[0]) * (dest2[0] - suborg[0]) + - (dest2[1] - suborg[1]) * (dest2[1] - suborg[1]); - if (nearestpoweroffour > 1.001 * seglength) { - /* It's shorter; it's safe to split `startsubseg'. */ - return 1; - } - /* If the current and previous subsegments are split to a length */ - /* half that of `startsubseg' (which is a likely consequence if */ - /* `startsubseg' is split), what will be (the square of) the */ - /* length of the free edge between the splitting vertices? */ - edgelength = 0.5 * nearestpoweroffour * - (1 - (((dest1[0] - suborg[0]) * (dest2[0] - suborg[0]) + - (dest1[1] - suborg[1]) * (dest2[1] - suborg[1])) / - sqrt(prevseglength * seglength))); - if (edgelength < iradius) { - /* If this cluster is split, the new edge dest1-dest2 will be */ - /* smaller than the insertion radius of the encroaching vertex. */ - /* Hence, we'd prefer to avoid splitting it if possible. */ - toosmall = 1; - } - if (cwsubseg.ss == startsubseg.ss) { - /* We've gone all the way around the vertex. Split the cluster */ - /* if no edges will be too short. */ - return !toosmall; - } - - /* Find the next subsegment clockwise around the vertex. */ - subsegcopy(cwsubseg, nowsubseg); - dest1 = dest2; - prevseglength = seglength; - cwsmall = clockwiseseg(m, &nowsubseg, &cwsubseg); - } while (cwsmall); - - /* Prepare to start searching counterclockwise from */ - /* the starting subsegment. */ - ccwsmall = counterclockwiseseg(m, &startsubseg, &ccwsubseg); - } - - if (ccwsmall) { - /* Check the subsegment(s) counterclockwise from `testsubseg'. */ - subsegcopy(startsubseg, nowsubseg); - sorg(nowsubseg, suborg); - sdest(nowsubseg, dest1); - prevseglength = nearestpoweroffour; - do { - /* Is the next subsegment shorter than `startsubseg'? */ - sdest(ccwsubseg, dest2); - seglength = (dest2[0] - suborg[0]) * (dest2[0] - suborg[0]) + - (dest2[1] - suborg[1]) * (dest2[1] - suborg[1]); - if (nearestpoweroffour > 1.001 * seglength) { - /* It's shorter; it's safe to split `startsubseg'. */ - return 1; - } - /* half that of `startsubseg' (which is a likely consequence if */ - /* `startsubseg' is split), what will be (the square of) the */ - /* length of the free edge between the splitting vertices? */ - edgelength = 0.5 * nearestpoweroffour * - (1 - (((dest1[0] - suborg[0]) * (dest2[0] - suborg[0]) + - (dest1[1] - suborg[1]) * (dest2[1] - suborg[1])) / - sqrt(prevseglength * seglength))); - if (edgelength < iradius) { - /* If this cluster is split, the new edge dest1-dest2 will be */ - /* smaller than the insertion radius of the encroaching vertex. */ - /* Hence, we'd prefer to avoid splitting it if possible. */ - toosmall = 1; - } - if (ccwsubseg.ss == startsubseg.ss) { - /* We've gone all the way around the vertex. Split the cluster */ - /* if no edges will be too short. */ - return !toosmall; - } - - /* Find the next subsegment counterclockwise around the vertex. */ - subsegcopy(ccwsubseg, nowsubseg); - dest1 = dest2; - prevseglength = seglength; - ccwsmall = counterclockwiseseg(m, &nowsubseg, &ccwsubseg); - } while (ccwsmall); - } - - /* We've found every subsegment in the cluster. Split the cluster */ - /* if no edges will be too short. */ - return !toosmall; -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* checkseg4encroach() Check a subsegment to see if it is encroached; add */ -/* it to the list if it is. */ -/* */ -/* A subsegment is encroached if there is a vertex in its diametral circle */ -/* (that is, the subsegment faces an angle greater than 90 degrees). This */ -/* definition is due to Ruppert. */ -/* */ -/* Returns a nonzero value if the subsegment is encroached. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -int checkseg4encroach(struct mesh *m, struct behavior *b, - struct osub *testsubseg, REAL iradius) -#else /* not ANSI_DECLARATORS */ -int checkseg4encroach(m, b, testsubseg, iradius) -struct mesh *m; -struct behavior *b; -struct osub *testsubseg; -REAL iradius; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri neighbortri; - struct osub testsym; - struct badsubseg *encroachedseg; - REAL dotproduct; - int encroached; - int sides; - int enq; - vertex eorg, edest, eapex; - triangle ptr; /* Temporary variable used by stpivot(). */ - - encroached = 0; - sides = 0; - - sorg(*testsubseg, eorg); - sdest(*testsubseg, edest); - /* Check one neighbor of the subsegment. */ - stpivot(*testsubseg, neighbortri); - /* Does the neighbor exist, or is this a boundary edge? */ - if (neighbortri.tri != m->dummytri) { - sides++; - /* Find a vertex opposite this subsegment. */ - apex(neighbortri, eapex); - /* Check whether the apex is in the diametral lens of the subsegment */ - /* (or the diametral circle, if `nolenses' is set). A dot product */ - /* of two sides of the triangle is used to check whether the angle */ - /* at the apex is greater than 120 degrees (for lenses; 90 degrees */ - /* for diametral circles). */ - dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) + - (eorg[1] - eapex[1]) * (edest[1] - eapex[1]); - if (dotproduct < 0.0) { - if (b->nolenses || - (dotproduct * dotproduct >= - 0.25 * ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) + - (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) * - ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) + - (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) { - encroached = 1; - } - } - } - /* Check the other neighbor of the subsegment. */ - ssym(*testsubseg, testsym); - stpivot(testsym, neighbortri); - /* Does the neighbor exist, or is this a boundary edge? */ - if (neighbortri.tri != m->dummytri) { - sides++; - /* Find the other vertex opposite this subsegment. */ - apex(neighbortri, eapex); - /* Check whether the apex is in the diametral lens of the subsegment */ - /* (or the diametral circle, if `nolenses' is set). */ - dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) + - (eorg[1] - eapex[1]) * (edest[1] - eapex[1]); - if (dotproduct < 0.0) { - if (b->nolenses || - (dotproduct * dotproduct >= - 0.25 * ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) + - (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) * - ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) + - (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) { - encroached += 2; - } - } - } - - if (encroached && (!b->nobisect || ((b->nobisect == 1) && (sides == 2)))) { - /* Decide whether `testsubseg' should be split. */ - if (iradius > 0.0) { - /* The encroaching vertex is a triangle circumcenter, which will be */ - /* rejected. Hence, `testsubseg' probably should be split, unless */ - /* it is part of a subsegment cluster which, according to the rules */ - /* described in my paper "Mesh Generation for Domains with Small */ - /* Angles," should not be split. */ - enq = splitpermitted(m, testsubseg, iradius); - } else { - /* The encroaching vertex is an input vertex or was inserted in a */ - /* subsegment, so the encroached subsegment must be split. */ - enq = 1; - } - if (enq) { - if (b->verbose > 2) { - printf( - " Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n", - eorg[0], eorg[1], edest[0], edest[1]); - } - /* Add the subsegment to the list of encroached subsegments. */ - /* Be sure to get the orientation right. */ - encroachedseg = (struct badsubseg *) poolalloc(&m->badsubsegs); - if (encroached == 1) { - encroachedseg->encsubseg = sencode(*testsubseg); - encroachedseg->subsegorg = eorg; - encroachedseg->subsegdest = edest; - } else { - encroachedseg->encsubseg = sencode(testsym); - encroachedseg->subsegorg = edest; - encroachedseg->subsegdest = eorg; - } - } - } - - return encroached; -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* testtriangle() Test a face for quality measures. */ -/* */ -/* Tests a triangle to see if it satisfies the minimum angle condition and */ -/* the maximum area condition. Triangles that aren't up to spec are added */ -/* to the bad triangle queue. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri) -#else /* not ANSI_DECLARATORS */ -void testtriangle(m, b, testtri) -struct mesh *m; -struct behavior *b; -struct otri *testtri; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri sametesttri; - struct osub subseg1, subseg2; - vertex torg, tdest, tapex; - vertex anglevertex; - REAL dxod, dyod, dxda, dyda, dxao, dyao; - REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2; - REAL apexlen, orglen, destlen; - REAL angle; - REAL area; - subseg sptr; /* Temporary variable used by tspivot(). */ - - org(*testtri, torg); - dest(*testtri, tdest); - apex(*testtri, tapex); - dxod = torg[0] - tdest[0]; - dyod = torg[1] - tdest[1]; - dxda = tdest[0] - tapex[0]; - dyda = tdest[1] - tapex[1]; - dxao = tapex[0] - torg[0]; - dyao = tapex[1] - torg[1]; - dxod2 = dxod * dxod; - dyod2 = dyod * dyod; - dxda2 = dxda * dxda; - dyda2 = dyda * dyda; - dxao2 = dxao * dxao; - dyao2 = dyao * dyao; - /* Find the lengths of the triangle's three edges. */ - apexlen = dxod2 + dyod2; - orglen = dxda2 + dyda2; - destlen = dxao2 + dyao2; - if ((apexlen < orglen) && (apexlen < destlen)) { - /* The edge opposite the apex is shortest. */ - /* Find the square of the cosine of the angle at the apex. */ - angle = dxda * dxao + dyda * dyao; - angle = angle * angle / (orglen * destlen); - anglevertex = tapex; - lnext(*testtri, sametesttri); - tspivot(sametesttri, subseg1); - lnextself(sametesttri); - tspivot(sametesttri, subseg2); - } else if (orglen < destlen) { - /* The edge opposite the origin is shortest. */ - /* Find the square of the cosine of the angle at the origin. */ - angle = dxod * dxao + dyod * dyao; - angle = angle * angle / (apexlen * destlen); - anglevertex = torg; - tspivot(*testtri, subseg1); - lprev(*testtri, sametesttri); - tspivot(sametesttri, subseg2); - } else { - /* The edge opposite the destination is shortest. */ - /* Find the square of the cosine of the angle at the destination. */ - angle = dxod * dxda + dyod * dyda; - angle = angle * angle / (apexlen * orglen); - anglevertex = tdest; - tspivot(*testtri, subseg1); - lnext(*testtri, sametesttri); - tspivot(sametesttri, subseg2); - } - - /* Check if both edges that form the angle are segments. */ - if ((subseg1.ss != m->dummysub) && (subseg2.ss != m->dummysub)) { - /* The angle is a segment intersection. Don't add this bad triangle to */ - /* the list; there's nothing that can be done about a small angle */ - /* between two segments. */ - angle = 0.0; - } - - /* Check whether the angle is smaller than permitted. */ - if (angle > b->goodangle) { - /* Add this triangle to the list of bad triangles. */ - enqueuebadtri(m, b, testtri, angle, tapex, torg, tdest); - return; - } - - if (b->vararea || b->fixedarea || b->usertest) { - /* Check whether the area is larger than permitted. */ - area = 0.5 * (dxod * dyda - dyod * dxda); - if (b->fixedarea && (area > b->maxarea)) { - /* Add this triangle to the list of bad triangles. */ - enqueuebadtri(m, b, testtri, angle, tapex, torg, tdest); - return; - } - - /* Nonpositive area constraints are treated as unconstrained. */ - if ((b->vararea) && (area > areabound(*testtri)) && - (areabound(*testtri) > 0.0)) { - /* Add this triangle to the list of bad triangles. */ - enqueuebadtri(m, b, testtri, angle, tapex, torg, tdest); - return; - } - - if (b->usertest) { - /* Check whether the user thinks this triangle is too large. */ - if (triunsuitable(torg, tdest, tapex, area)) { - enqueuebadtri(m, b, testtri, angle, tapex, torg, tdest); - return; - } - } - } -} - -#endif /* not CDT_ONLY */ - -/** **/ -/** **/ -/********* Mesh quality testing routines end here *********/ - -/********* Point location routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* makevertexmap() Construct a mapping from vertices to triangles to */ -/* improve the speed of point location for segment */ -/* insertion. */ -/* */ -/* Traverses all the triangles, and provides each corner of each triangle */ -/* with a pointer to that triangle. Of course, pointers will be */ -/* overwritten by other pointers because (almost) each vertex is a corner */ -/* of several triangles, but in the end every vertex will point to some */ -/* triangle that contains it. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void makevertexmap(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void makevertexmap(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri triangleloop; - vertex triorg; - - if (b->verbose) { - printf(" Constructing mapping from vertices to triangles.\n"); - } - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - while (triangleloop.tri != (triangle *) NULL) { - /* Check all three vertices of the triangle. */ - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - org(triangleloop, triorg); - setvertex2tri(triorg, encode(triangleloop)); - } - triangleloop.tri = triangletraverse(m); - } -} - -/*****************************************************************************/ -/* */ -/* preciselocate() Find a triangle or edge containing a given point. */ -/* */ -/* Begins its search from `searchtri'. It is important that `searchtri' */ -/* be a handle with the property that `searchpoint' is strictly to the left */ -/* of the edge denoted by `searchtri', or is collinear with that edge and */ -/* does not intersect that edge. (In particular, `searchpoint' should not */ -/* be the origin or destination of that edge.) */ -/* */ -/* These conditions are imposed because preciselocate() is normally used in */ -/* one of two situations: */ -/* */ -/* (1) To try to find the location to insert a new point. Normally, we */ -/* know an edge that the point is strictly to the left of. In the */ -/* incremental Delaunay algorithm, that edge is a bounding box edge. */ -/* In Ruppert's Delaunay refinement algorithm for quality meshing, */ -/* that edge is the shortest edge of the triangle whose circumcenter */ -/* is being inserted. */ -/* */ -/* (2) To try to find an existing point. In this case, any edge on the */ -/* convex hull is a good starting edge. You must screen out the */ -/* possibility that the vertex sought is an endpoint of the starting */ -/* edge before you call preciselocate(). */ -/* */ -/* On completion, `searchtri' is a triangle that contains `searchpoint'. */ -/* */ -/* This implementation differs from that given by Guibas and Stolfi. It */ -/* walks from triangle to triangle, crossing an edge only if `searchpoint' */ -/* is on the other side of the line containing that edge. After entering */ -/* a triangle, there are two edges by which one can leave that triangle. */ -/* If both edges are valid (`searchpoint' is on the other side of both */ -/* edges), one of the two is chosen by drawing a line perpendicular to */ -/* the entry edge (whose endpoints are `forg' and `fdest') passing through */ -/* `fapex'. Depending on which side of this perpendicular `searchpoint' */ -/* falls on, an exit edge is chosen. */ -/* */ -/* This implementation is empirically faster than the Guibas and Stolfi */ -/* point location routine (which I originally used), which tends to spiral */ -/* in toward its target. */ -/* */ -/* Returns ONVERTEX if the point lies on an existing vertex. `searchtri' */ -/* is a handle whose origin is the existing vertex. */ -/* */ -/* Returns ONEDGE if the point lies on a mesh edge. `searchtri' is a */ -/* handle whose primary edge is the edge on which the point lies. */ -/* */ -/* Returns INTRIANGLE if the point lies strictly within a triangle. */ -/* `searchtri' is a handle on the triangle that contains the point. */ -/* */ -/* Returns OUTSIDE if the point lies outside the mesh. `searchtri' is a */ -/* handle whose primary edge the point is to the right of. This might */ -/* occur when the circumcenter of a triangle falls just slightly outside */ -/* the mesh due to floating-point roundoff error. It also occurs when */ -/* seeking a hole or region point that a foolish user has placed outside */ -/* the mesh. */ -/* */ -/* If `stopatsubsegment' is nonzero, the search will stop if it tries to */ -/* walk through a subsegment, and will return OUTSIDE. */ -/* */ -/* WARNING: This routine is designed for convex triangulations, and will */ -/* not generally work after the holes and concavities have been carved. */ -/* However, it can still be used to find the circumcenter of a triangle, as */ -/* long as the search is begun from the triangle in question. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -enum locateresult preciselocate(struct mesh *m, struct behavior *b, - vertex searchpoint, struct otri *searchtri, - int stopatsubsegment) -#else /* not ANSI_DECLARATORS */ -enum locateresult preciselocate(m, b, searchpoint, searchtri, stopatsubsegment) -struct mesh *m; -struct behavior *b; -vertex searchpoint; -struct otri *searchtri; -int stopatsubsegment; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri backtracktri; - struct osub checkedge; - vertex forg, fdest, fapex; - REAL orgorient, destorient; - int moveleft; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - if (b->verbose > 2) { - printf(" Searching for point (%.12g, %.12g).\n", - searchpoint[0], searchpoint[1]); - } - /* Where are we? */ - org(*searchtri, forg); - dest(*searchtri, fdest); - apex(*searchtri, fapex); - while (1) { - if (b->verbose > 2) { - printf(" At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - forg[0], forg[1], fdest[0], fdest[1], fapex[0], fapex[1]); - } - /* Check whether the apex is the point we seek. */ - if ((fapex[0] == searchpoint[0]) && (fapex[1] == searchpoint[1])) { - lprevself(*searchtri); - return ONVERTEX; - } - /* Does the point lie on the other side of the line defined by the */ - /* triangle edge opposite the triangle's destination? */ - destorient = counterclockwise(m, b, forg, fapex, searchpoint); - /* Does the point lie on the other side of the line defined by the */ - /* triangle edge opposite the triangle's origin? */ - orgorient = counterclockwise(m, b, fapex, fdest, searchpoint); - if (destorient > 0.0) { - if (orgorient > 0.0) { - /* Move left if the inner product of (fapex - searchpoint) and */ - /* (fdest - forg) is positive. This is equivalent to drawing */ - /* a line perpendicular to the line (forg, fdest) and passing */ - /* through `fapex', and determining which side of this line */ - /* `searchpoint' falls on. */ - moveleft = (fapex[0] - searchpoint[0]) * (fdest[0] - forg[0]) + - (fapex[1] - searchpoint[1]) * (fdest[1] - forg[1]) > 0.0; - } else { - moveleft = 1; - } - } else { - if (orgorient > 0.0) { - moveleft = 0; - } else { - /* The point we seek must be on the boundary of or inside this */ - /* triangle. */ - if (destorient == 0.0) { - lprevself(*searchtri); - return ONEDGE; - } - if (orgorient == 0.0) { - lnextself(*searchtri); - return ONEDGE; - } - return INTRIANGLE; - } - } - - /* Move to another triangle. Leave a trace `backtracktri' in case */ - /* floating-point roundoff or some such bogey causes us to walk */ - /* off a boundary of the triangulation. */ - if (moveleft) { - lprev(*searchtri, backtracktri); - fdest = fapex; - } else { - lnext(*searchtri, backtracktri); - forg = fapex; - } - sym(backtracktri, *searchtri); - - if (m->checksegments && stopatsubsegment) { - /* Check for walking through a subsegment. */ - tspivot(backtracktri, checkedge); - if (checkedge.ss != m->dummysub) { - /* Go back to the last triangle. */ - otricopy(backtracktri, *searchtri); - return OUTSIDE; - } - } - /* Check for walking right out of the triangulation. */ - if (searchtri->tri == m->dummytri) { - /* Go back to the last triangle. */ - otricopy(backtracktri, *searchtri); - return OUTSIDE; - } - - apex(*searchtri, fapex); - } -} - -/*****************************************************************************/ -/* */ -/* locate() Find a triangle or edge containing a given point. */ -/* */ -/* Searching begins from one of: the input `searchtri', a recently */ -/* encountered triangle `recenttri', or from a triangle chosen from a */ -/* random sample. The choice is made by determining which triangle's */ -/* origin is closest to the point we are searching for. Normally, */ -/* `searchtri' should be a handle on the convex hull of the triangulation. */ -/* */ -/* Details on the random sampling method can be found in the Mucke, Saias, */ -/* and Zhu paper cited in the header of this code. */ -/* */ -/* On completion, `searchtri' is a triangle that contains `searchpoint'. */ -/* */ -/* Returns ONVERTEX if the point lies on an existing vertex. `searchtri' */ -/* is a handle whose origin is the existing vertex. */ -/* */ -/* Returns ONEDGE if the point lies on a mesh edge. `searchtri' is a */ -/* handle whose primary edge is the edge on which the point lies. */ -/* */ -/* Returns INTRIANGLE if the point lies strictly within a triangle. */ -/* `searchtri' is a handle on the triangle that contains the point. */ -/* */ -/* Returns OUTSIDE if the point lies outside the mesh. `searchtri' is a */ -/* handle whose primary edge the point is to the right of. This might */ -/* occur when the circumcenter of a triangle falls just slightly outside */ -/* the mesh due to floating-point roundoff error. It also occurs when */ -/* seeking a hole or region point that a foolish user has placed outside */ -/* the mesh. */ -/* */ -/* WARNING: This routine is designed for convex triangulations, and will */ -/* not generally work after the holes and concavities have been carved. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -enum locateresult locate(struct mesh *m, struct behavior *b, - vertex searchpoint, struct otri *searchtri) -#else /* not ANSI_DECLARATORS */ -enum locateresult locate(m, b, searchpoint, searchtri) -struct mesh *m; -struct behavior *b; -vertex searchpoint; -struct otri *searchtri; -#endif /* not ANSI_DECLARATORS */ - -{ - VOID **sampleblock; - triangle *firsttri; - struct otri sampletri; - vertex torg, tdest; - unsigned long alignptr; - REAL searchdist, dist; - REAL ahead; - long sampleblocks, samplesperblock, samplenum; - long triblocks; - long i, j; - triangle ptr; /* Temporary variable used by sym(). */ - - if (b->verbose > 2) { - printf(" Randomly sampling for a triangle near point (%.12g, %.12g).\n", - searchpoint[0], searchpoint[1]); - } - /* Record the distance from the suggested starting triangle to the */ - /* point we seek. */ - org(*searchtri, torg); - searchdist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) + - (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]); - if (b->verbose > 2) { - printf(" Boundary triangle has origin (%.12g, %.12g).\n", - torg[0], torg[1]); - } - - /* If a recently encountered triangle has been recorded and has not been */ - /* deallocated, test it as a good starting point. */ - if (m->recenttri.tri != (triangle *) NULL) { - if (!deadtri(m->recenttri.tri)) { - org(m->recenttri, torg); - if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) { - otricopy(m->recenttri, *searchtri); - return ONVERTEX; - } - dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) + - (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]); - if (dist < searchdist) { - otricopy(m->recenttri, *searchtri); - searchdist = dist; - if (b->verbose > 2) { - printf(" Choosing recent triangle with origin (%.12g, %.12g).\n", - torg[0], torg[1]); - } - } - } - } - - /* The number of random samples taken is proportional to the cube root of */ - /* the number of triangles in the mesh. The next bit of code assumes */ - /* that the number of triangles increases monotonically. */ - while (SAMPLEFACTOR * m->samples * m->samples * m->samples < - m->triangles.items) { - m->samples++; - } - triblocks = (m->triangles.maxitems + TRIPERBLOCK - 1) / TRIPERBLOCK; - samplesperblock = (m->samples + triblocks - 1) / triblocks; - sampleblocks = m->samples / samplesperblock; - sampleblock = m->triangles.firstblock; - sampletri.orient = 0; - for (i = 0; i < sampleblocks; i++) { - alignptr = (unsigned long) (sampleblock + 1); - firsttri = (triangle *) (alignptr + (unsigned long) m->triangles.alignbytes - - (alignptr % (unsigned long) m->triangles.alignbytes)); - for (j = 0; j < samplesperblock; j++) { - if (i == triblocks - 1) { - samplenum = randomnation((unsigned int) - (m->triangles.maxitems - (i * TRIPERBLOCK))); - } else { - samplenum = randomnation(TRIPERBLOCK); - } - sampletri.tri = (triangle *) - (firsttri + (samplenum * m->triangles.itemwords)); - if (!deadtri(sampletri.tri)) { - org(sampletri, torg); - dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) + - (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]); - if (dist < searchdist) { - otricopy(sampletri, *searchtri); - searchdist = dist; - if (b->verbose > 2) { - printf(" Choosing triangle with origin (%.12g, %.12g).\n", - torg[0], torg[1]); - } - } - } - } - sampleblock = (VOID **) *sampleblock; - } - - /* Where are we? */ - org(*searchtri, torg); - dest(*searchtri, tdest); - /* Check the starting triangle's vertices. */ - if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) { - return ONVERTEX; - } - if ((tdest[0] == searchpoint[0]) && (tdest[1] == searchpoint[1])) { - lnextself(*searchtri); - return ONVERTEX; - } - /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */ - ahead = counterclockwise(m, b, torg, tdest, searchpoint); - if (ahead < 0.0) { - /* Turn around so that `searchpoint' is to the left of the */ - /* edge specified by `searchtri'. */ - symself(*searchtri); - } else if (ahead == 0.0) { - /* Check if `searchpoint' is between `torg' and `tdest'. */ - if (((torg[0] < searchpoint[0]) == (searchpoint[0] < tdest[0])) && - ((torg[1] < searchpoint[1]) == (searchpoint[1] < tdest[1]))) { - return ONEDGE; - } - } - return preciselocate(m, b, searchpoint, searchtri, 0); -} - -/** **/ -/** **/ -/********* Point location routines end here *********/ - -/********* Mesh transformation routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* insertsubseg() Create a new subsegment and insert it between two */ -/* triangles. */ -/* */ -/* The new subsegment is inserted at the edge described by the handle */ -/* `tri'. Its vertices are properly initialized. The marker `subsegmark' */ -/* is applied to the subsegment and, if appropriate, its vertices. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void insertsubseg(struct mesh *m, struct behavior *b, struct otri *tri, - int subsegmark) -#else /* not ANSI_DECLARATORS */ -void insertsubseg(m, b, tri, subsegmark) -struct mesh *m; -struct behavior *b; -struct otri *tri; /* Edge at which to insert the new subsegment. */ -int subsegmark; /* Marker for the new subsegment. */ -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri oppotri; - struct osub newsubseg; - vertex triorg, tridest; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - org(*tri, triorg); - dest(*tri, tridest); - /* Mark vertices if possible. */ - if (vertexmark(triorg) == 0) { - setvertexmark(triorg, subsegmark); - } - if (vertexmark(tridest) == 0) { - setvertexmark(tridest, subsegmark); - } - /* Check if there's already a subsegment here. */ - tspivot(*tri, newsubseg); - if (newsubseg.ss == m->dummysub) { - /* Make new subsegment and initialize its vertices. */ - makesubseg(m, &newsubseg); - setsorg(newsubseg, tridest); - setsdest(newsubseg, triorg); - /* Bond new subsegment to the two triangles it is sandwiched between. */ - /* Note that the facing triangle `oppotri' might be equal to */ - /* `dummytri' (outer space), but the new subsegment is bonded to it */ - /* all the same. */ - tsbond(*tri, newsubseg); - sym(*tri, oppotri); - ssymself(newsubseg); - tsbond(oppotri, newsubseg); - setmark(newsubseg, subsegmark); - if (b->verbose > 2) { - printf(" Inserting new "); - printsubseg(m, b, &newsubseg); - } - } else { - if (mark(newsubseg) == 0) { - setmark(newsubseg, subsegmark); - } - } -} - -/*****************************************************************************/ -/* */ -/* Terminology */ -/* */ -/* A "local transformation" replaces a small set of triangles with another */ -/* set of triangles. This may or may not involve inserting or deleting a */ -/* vertex. */ -/* */ -/* The term "casing" is used to describe the set of triangles that are */ -/* attached to the triangles being transformed, but are not transformed */ -/* themselves. Think of the casing as a fixed hollow structure inside */ -/* which all the action happens. A "casing" is only defined relative to */ -/* a single transformation; each occurrence of a transformation will */ -/* involve a different casing. */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* flip() Transform two triangles to two different triangles by flipping */ -/* an edge counterclockwise within a quadrilateral. */ -/* */ -/* Imagine the original triangles, abc and bad, oriented so that the */ -/* shared edge ab lies in a horizontal plane, with the vertex b on the left */ -/* and the vertex a on the right. The vertex c lies below the edge, and */ -/* the vertex d lies above the edge. The `flipedge' handle holds the edge */ -/* ab of triangle abc, and is directed left, from vertex a to vertex b. */ -/* */ -/* The triangles abc and bad are deleted and replaced by the triangles cdb */ -/* and dca. The triangles that represent abc and bad are NOT deallocated; */ -/* they are reused for dca and cdb, respectively. Hence, any handles that */ -/* may have held the original triangles are still valid, although not */ -/* directed as they were before. */ -/* */ -/* Upon completion of this routine, the `flipedge' handle holds the edge */ -/* dc of triangle dca, and is directed down, from vertex d to vertex c. */ -/* (Hence, the two triangles have rotated counterclockwise.) */ -/* */ -/* WARNING: This transformation is geometrically valid only if the */ -/* quadrilateral adbc is convex. Furthermore, this transformation is */ -/* valid only if there is not a subsegment between the triangles abc and */ -/* bad. This routine does not check either of these preconditions, and */ -/* it is the responsibility of the calling routine to ensure that they are */ -/* met. If they are not, the streets shall be filled with wailing and */ -/* gnashing of teeth. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void flip(struct mesh *m, struct behavior *b, struct otri *flipedge) -#else /* not ANSI_DECLARATORS */ -void flip(m, b, flipedge) -struct mesh *m; -struct behavior *b; -struct otri *flipedge; /* Handle for the triangle abc. */ -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri botleft, botright; - struct otri topleft, topright; - struct otri top; - struct otri botlcasing, botrcasing; - struct otri toplcasing, toprcasing; - struct osub botlsubseg, botrsubseg; - struct osub toplsubseg, toprsubseg; - vertex leftvertex, rightvertex, botvertex; - vertex farvertex; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - /* Identify the vertices of the quadrilateral. */ - org(*flipedge, rightvertex); - dest(*flipedge, leftvertex); - apex(*flipedge, botvertex); - sym(*flipedge, top); -#ifdef SELF_CHECK - if (top.tri == m->dummytri) { - printf("Internal error in flip(): Attempt to flip on boundary.\n"); - lnextself(*flipedge); - return; - } - if (m->checksegments) { - tspivot(*flipedge, toplsubseg); - if (toplsubseg.ss != m->dummysub) { - printf("Internal error in flip(): Attempt to flip a segment.\n"); - lnextself(*flipedge); - return; - } - } -#endif /* SELF_CHECK */ - apex(top, farvertex); - - /* Identify the casing of the quadrilateral. */ - lprev(top, topleft); - sym(topleft, toplcasing); - lnext(top, topright); - sym(topright, toprcasing); - lnext(*flipedge, botleft); - sym(botleft, botlcasing); - lprev(*flipedge, botright); - sym(botright, botrcasing); - /* Rotate the quadrilateral one-quarter turn counterclockwise. */ - bond(topleft, botlcasing); - bond(botleft, botrcasing); - bond(botright, toprcasing); - bond(topright, toplcasing); - - if (m->checksegments) { - /* Check for subsegments and rebond them to the quadrilateral. */ - tspivot(topleft, toplsubseg); - tspivot(botleft, botlsubseg); - tspivot(botright, botrsubseg); - tspivot(topright, toprsubseg); - if (toplsubseg.ss == m->dummysub) { - tsdissolve(topright); - } else { - tsbond(topright, toplsubseg); - } - if (botlsubseg.ss == m->dummysub) { - tsdissolve(topleft); - } else { - tsbond(topleft, botlsubseg); - } - if (botrsubseg.ss == m->dummysub) { - tsdissolve(botleft); - } else { - tsbond(botleft, botrsubseg); - } - if (toprsubseg.ss == m->dummysub) { - tsdissolve(botright); - } else { - tsbond(botright, toprsubseg); - } - } - - /* New vertex assignments for the rotated quadrilateral. */ - setorg(*flipedge, farvertex); - setdest(*flipedge, botvertex); - setapex(*flipedge, rightvertex); - setorg(top, botvertex); - setdest(top, farvertex); - setapex(top, leftvertex); - if (b->verbose > 2) { - printf(" Edge flip results in left "); - printtriangle(m, b, &top); - printf(" and right "); - printtriangle(m, b, flipedge); - } -} - -/*****************************************************************************/ -/* */ -/* unflip() Transform two triangles to two different triangles by */ -/* flipping an edge clockwise within a quadrilateral. Reverses */ -/* the flip() operation so that the data structures representing */ -/* the triangles are back where they were before the flip(). */ -/* */ -/* Imagine the original triangles, abc and bad, oriented so that the */ -/* shared edge ab lies in a horizontal plane, with the vertex b on the left */ -/* and the vertex a on the right. The vertex c lies below the edge, and */ -/* the vertex d lies above the edge. The `flipedge' handle holds the edge */ -/* ab of triangle abc, and is directed left, from vertex a to vertex b. */ -/* */ -/* The triangles abc and bad are deleted and replaced by the triangles cdb */ -/* and dca. The triangles that represent abc and bad are NOT deallocated; */ -/* they are reused for cdb and dca, respectively. Hence, any handles that */ -/* may have held the original triangles are still valid, although not */ -/* directed as they were before. */ -/* */ -/* Upon completion of this routine, the `flipedge' handle holds the edge */ -/* cd of triangle cdb, and is directed up, from vertex c to vertex d. */ -/* (Hence, the two triangles have rotated clockwise.) */ -/* */ -/* WARNING: This transformation is geometrically valid only if the */ -/* quadrilateral adbc is convex. Furthermore, this transformation is */ -/* valid only if there is not a subsegment between the triangles abc and */ -/* bad. This routine does not check either of these preconditions, and */ -/* it is the responsibility of the calling routine to ensure that they are */ -/* met. If they are not, the streets shall be filled with wailing and */ -/* gnashing of teeth. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void unflip(struct mesh *m, struct behavior *b, struct otri *flipedge) -#else /* not ANSI_DECLARATORS */ -void unflip(m, b, flipedge) -struct mesh *m; -struct behavior *b; -struct otri *flipedge; /* Handle for the triangle abc. */ -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri botleft, botright; - struct otri topleft, topright; - struct otri top; - struct otri botlcasing, botrcasing; - struct otri toplcasing, toprcasing; - struct osub botlsubseg, botrsubseg; - struct osub toplsubseg, toprsubseg; - vertex leftvertex, rightvertex, botvertex; - vertex farvertex; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - /* Identify the vertices of the quadrilateral. */ - org(*flipedge, rightvertex); - dest(*flipedge, leftvertex); - apex(*flipedge, botvertex); - sym(*flipedge, top); -#ifdef SELF_CHECK - if (top.tri == m->dummytri) { - printf("Internal error in unflip(): Attempt to flip on boundary.\n"); - lnextself(*flipedge); - return; - } - if (m->checksegments) { - tspivot(*flipedge, toplsubseg); - if (toplsubseg.ss != m->dummysub) { - printf("Internal error in unflip(): Attempt to flip a subsegment.\n"); - lnextself(*flipedge); - return; - } - } -#endif /* SELF_CHECK */ - apex(top, farvertex); - - /* Identify the casing of the quadrilateral. */ - lprev(top, topleft); - sym(topleft, toplcasing); - lnext(top, topright); - sym(topright, toprcasing); - lnext(*flipedge, botleft); - sym(botleft, botlcasing); - lprev(*flipedge, botright); - sym(botright, botrcasing); - /* Rotate the quadrilateral one-quarter turn clockwise. */ - bond(topleft, toprcasing); - bond(botleft, toplcasing); - bond(botright, botlcasing); - bond(topright, botrcasing); - - if (m->checksegments) { - /* Check for subsegments and rebond them to the quadrilateral. */ - tspivot(topleft, toplsubseg); - tspivot(botleft, botlsubseg); - tspivot(botright, botrsubseg); - tspivot(topright, toprsubseg); - if (toplsubseg.ss == m->dummysub) { - tsdissolve(botleft); - } else { - tsbond(botleft, toplsubseg); - } - if (botlsubseg.ss == m->dummysub) { - tsdissolve(botright); - } else { - tsbond(botright, botlsubseg); - } - if (botrsubseg.ss == m->dummysub) { - tsdissolve(topright); - } else { - tsbond(topright, botrsubseg); - } - if (toprsubseg.ss == m->dummysub) { - tsdissolve(topleft); - } else { - tsbond(topleft, toprsubseg); - } - } - - /* New vertex assignments for the rotated quadrilateral. */ - setorg(*flipedge, botvertex); - setdest(*flipedge, farvertex); - setapex(*flipedge, leftvertex); - setorg(top, farvertex); - setdest(top, botvertex); - setapex(top, rightvertex); - if (b->verbose > 2) { - printf(" Edge unflip results in left "); - printtriangle(m, b, flipedge); - printf(" and right "); - printtriangle(m, b, &top); - } -} - -/*****************************************************************************/ -/* */ -/* insertvertex() Insert a vertex into a Delaunay triangulation, */ -/* performing flips as necessary to maintain the Delaunay */ -/* property. */ -/* */ -/* The point `insertvertex' is located. If `searchtri.tri' is not NULL, */ -/* the search for the containing triangle begins from `searchtri'. If */ -/* `searchtri.tri' is NULL, a full point location procedure is called. */ -/* If `insertvertex' is found inside a triangle, the triangle is split into */ -/* three; if `insertvertex' lies on an edge, the edge is split in two, */ -/* thereby splitting the two adjacent triangles into four. Edge flips are */ -/* used to restore the Delaunay property. If `insertvertex' lies on an */ -/* existing vertex, no action is taken, and the value DUPLICATEVERTEX is */ -/* returned. On return, `searchtri' is set to a handle whose origin is the */ -/* existing vertex. */ -/* */ -/* Normally, the parameter `splitseg' is set to NULL, implying that no */ -/* subsegment should be split. In this case, if `insertvertex' is found to */ -/* lie on a segment, no action is taken, and the value VIOLATINGVERTEX is */ -/* returned. On return, `searchtri' is set to a handle whose primary edge */ -/* is the violated subsegment. */ -/* */ -/* If the calling routine wishes to split a subsegment by inserting a */ -/* vertex in it, the parameter `splitseg' should be that subsegment. In */ -/* this case, `searchtri' MUST be the triangle handle reached by pivoting */ -/* from that subsegment; no point location is done. */ -/* */ -/* `segmentflaws' and `triflaws' are flags that indicate whether or not */ -/* there should be checks for the creation of encroached subsegments or bad */ -/* quality triangles. If a newly inserted vertex encroaches upon */ -/* subsegments, these subsegments are added to the list of subsegments to */ -/* be split if `segmentflaws' is set. If bad triangles are created, these */ -/* are added to the queue if `triflaws' is set. */ -/* */ -/* If a duplicate vertex or violated segment does not prevent the vertex */ -/* from being inserted, the return value will be ENCROACHINGVERTEX if the */ -/* vertex encroaches upon a subsegment (and checking is enabled), or */ -/* SUCCESSFULVERTEX otherwise. In either case, `searchtri' is set to a */ -/* handle whose origin is the newly inserted vertex. */ -/* */ -/* insertvertex() does not use flip() for reasons of speed; some */ -/* information can be reused from edge flip to edge flip, like the */ -/* locations of subsegments. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b, - vertex newvertex, struct otri *searchtri, - struct osub *splitseg, - int segmentflaws, int triflaws, - REAL iradius) -#else /* not ANSI_DECLARATORS */ -enum insertvertexresult insertvertex(m, b, newvertex, searchtri, splitseg, - segmentflaws, triflaws, iradius) -struct mesh *m; -struct behavior *b; -vertex newvertex; -struct otri *searchtri; -struct osub *splitseg; -int segmentflaws; -int triflaws; -REAL iradius; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri horiz; - struct otri top; - struct otri botleft, botright; - struct otri topleft, topright; - struct otri newbotleft, newbotright; - struct otri newtopright; - struct otri botlcasing, botrcasing; - struct otri toplcasing, toprcasing; - struct otri testtri; - struct osub botlsubseg, botrsubseg; - struct osub toplsubseg, toprsubseg; - struct osub brokensubseg; - struct osub checksubseg; - struct osub rightsubseg; - struct osub newsubseg; - struct badsubseg *encroached; - struct flipstacker *newflip; - vertex first; - vertex leftvertex, rightvertex, botvertex, topvertex, farvertex; - REAL attrib; - REAL area; - enum insertvertexresult success; - enum locateresult intersect; - int doflip; - int mirrorflag; - int enq; - int i; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by spivot() and tspivot(). */ - - if (b->verbose > 1) { - printf(" Inserting (%.12g, %.12g).\n", newvertex[0], newvertex[1]); - } - - if (splitseg == (struct osub *) NULL) { - /* Find the location of the vertex to be inserted. Check if a good */ - /* starting triangle has already been provided by the caller. */ - if (searchtri->tri == m->dummytri) { - /* Find a boundary triangle. */ - horiz.tri = m->dummytri; - horiz.orient = 0; - symself(horiz); - /* Search for a triangle containing `newvertex'. */ - intersect = locate(m, b, newvertex, &horiz); - } else { - /* Start searching from the triangle provided by the caller. */ - otricopy(*searchtri, horiz); - intersect = preciselocate(m, b, newvertex, &horiz, 1); - } - } else { - /* The calling routine provides the subsegment in which */ - /* the vertex is inserted. */ - otricopy(*searchtri, horiz); - intersect = ONEDGE; - } - if (intersect == ONVERTEX) { - /* There's already a vertex there. Return in `searchtri' a triangle */ - /* whose origin is the existing vertex. */ - otricopy(horiz, *searchtri); - otricopy(horiz, m->recenttri); - return DUPLICATEVERTEX; - } - if ((intersect == ONEDGE) || (intersect == OUTSIDE)) { - /* The vertex falls on an edge or boundary. */ - if (m->checksegments && (splitseg == (struct osub *) NULL)) { - /* Check whether the vertex falls on a subsegment. */ - tspivot(horiz, brokensubseg); - if (brokensubseg.ss != m->dummysub) { - /* The vertex falls on a subsegment, and hence will not be inserted. */ - if (segmentflaws) { - if (b->nobisect == 2) { - enq = 0; -#ifndef CDT_ONLY - } else if (iradius > 0.0) { - enq = splitpermitted(m, &brokensubseg, iradius); -#endif /* not CDT_ONLY */ - } else { - enq = 1; - } - if (enq && (b->nobisect == 1)) { - /* This subsegment may be split only if it is an */ - /* internal boundary. */ - sym(horiz, testtri); - enq = testtri.tri != m->dummytri; - } - if (enq) { - /* Add the subsegment to the list of encroached subsegments. */ - encroached = (struct badsubseg *) poolalloc(&m->badsubsegs); - encroached->encsubseg = sencode(brokensubseg); - sorg(brokensubseg, encroached->subsegorg); - sdest(brokensubseg, encroached->subsegdest); - if (b->verbose > 2) { - printf( - " Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n", - encroached->subsegorg[0], encroached->subsegorg[1], - encroached->subsegdest[0], encroached->subsegdest[1]); - } - } - } - /* Return a handle whose primary edge contains the vertex, */ - /* which has not been inserted. */ - otricopy(horiz, *searchtri); - otricopy(horiz, m->recenttri); - return VIOLATINGVERTEX; - } - } - - /* Insert the vertex on an edge, dividing one triangle into two (if */ - /* the edge lies on a boundary) or two triangles into four. */ - lprev(horiz, botright); - sym(botright, botrcasing); - sym(horiz, topright); - /* Is there a second triangle? (Or does this edge lie on a boundary?) */ - mirrorflag = topright.tri != m->dummytri; - if (mirrorflag) { - lnextself(topright); - sym(topright, toprcasing); - maketriangle(m, b, &newtopright); - } else { - /* Splitting a boundary edge increases the number of boundary edges. */ - m->hullsize++; - } - maketriangle(m, b, &newbotright); - - /* Set the vertices of changed and new triangles. */ - org(horiz, rightvertex); - dest(horiz, leftvertex); - apex(horiz, botvertex); - setorg(newbotright, botvertex); - setdest(newbotright, rightvertex); - setapex(newbotright, newvertex); - setorg(horiz, newvertex); - for (i = 0; i < m->eextras; i++) { - /* Set the element attributes of a new triangle. */ - setelemattribute(newbotright, i, elemattribute(botright, i)); - } - if (b->vararea) { - /* Set the area constraint of a new triangle. */ - setareabound(newbotright, areabound(botright)); - } - if (mirrorflag) { - dest(topright, topvertex); - setorg(newtopright, rightvertex); - setdest(newtopright, topvertex); - setapex(newtopright, newvertex); - setorg(topright, newvertex); - for (i = 0; i < m->eextras; i++) { - /* Set the element attributes of another new triangle. */ - setelemattribute(newtopright, i, elemattribute(topright, i)); - } - if (b->vararea) { - /* Set the area constraint of another new triangle. */ - setareabound(newtopright, areabound(topright)); - } - } - - /* There may be subsegments that need to be bonded */ - /* to the new triangle(s). */ - if (m->checksegments) { - tspivot(botright, botrsubseg); - if (botrsubseg.ss != m->dummysub) { - tsdissolve(botright); - tsbond(newbotright, botrsubseg); - } - if (mirrorflag) { - tspivot(topright, toprsubseg); - if (toprsubseg.ss != m->dummysub) { - tsdissolve(topright); - tsbond(newtopright, toprsubseg); - } - } - } - - /* Bond the new triangle(s) to the surrounding triangles. */ - bond(newbotright, botrcasing); - lprevself(newbotright); - bond(newbotright, botright); - lprevself(newbotright); - if (mirrorflag) { - bond(newtopright, toprcasing); - lnextself(newtopright); - bond(newtopright, topright); - lnextself(newtopright); - bond(newtopright, newbotright); - } - - if (splitseg != (struct osub *) NULL) { - /* Split the subsegment into two. */ - setsdest(*splitseg, newvertex); - ssymself(*splitseg); - spivot(*splitseg, rightsubseg); - insertsubseg(m, b, &newbotright, mark(*splitseg)); - tspivot(newbotright, newsubseg); - sbond(*splitseg, newsubseg); - ssymself(newsubseg); - sbond(newsubseg, rightsubseg); - ssymself(*splitseg); - /* Transfer the subsegment's boundary marker to the vertex */ - /* if required. */ - if (vertexmark(newvertex) == 0) { - setvertexmark(newvertex, mark(*splitseg)); - } - } - - if (m->checkquality) { - poolrestart(&m->flipstackers); - m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers); - m->lastflip->flippedtri = encode(horiz); - m->lastflip->prevflip = (struct flipstacker *) &insertvertex; - } - -#ifdef SELF_CHECK - if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf( - " Clockwise triangle prior to edge vertex insertion (bottom).\n"); - } - if (mirrorflag) { - if (counterclockwise(m, b, leftvertex, rightvertex, topvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle prior to edge vertex insertion (top).\n"); - } - if (counterclockwise(m, b, rightvertex, topvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf( - " Clockwise triangle after edge vertex insertion (top right).\n"); - } - if (counterclockwise(m, b, topvertex, leftvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf( - " Clockwise triangle after edge vertex insertion (top left).\n"); - } - } - if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf( - " Clockwise triangle after edge vertex insertion (bottom left).\n"); - } - if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf( - " Clockwise triangle after edge vertex insertion (bottom right).\n"); - } -#endif /* SELF_CHECK */ - if (b->verbose > 2) { - printf(" Updating bottom left "); - printtriangle(m, b, &botright); - if (mirrorflag) { - printf(" Updating top left "); - printtriangle(m, b, &topright); - printf(" Creating top right "); - printtriangle(m, b, &newtopright); - } - printf(" Creating bottom right "); - printtriangle(m, b, &newbotright); - } - - /* Position `horiz' on the first edge to check for */ - /* the Delaunay property. */ - lnextself(horiz); - } else { - /* Insert the vertex in a triangle, splitting it into three. */ - lnext(horiz, botleft); - lprev(horiz, botright); - sym(botleft, botlcasing); - sym(botright, botrcasing); - maketriangle(m, b, &newbotleft); - maketriangle(m, b, &newbotright); - - /* Set the vertices of changed and new triangles. */ - org(horiz, rightvertex); - dest(horiz, leftvertex); - apex(horiz, botvertex); - setorg(newbotleft, leftvertex); - setdest(newbotleft, botvertex); - setapex(newbotleft, newvertex); - setorg(newbotright, botvertex); - setdest(newbotright, rightvertex); - setapex(newbotright, newvertex); - setapex(horiz, newvertex); - for (i = 0; i < m->eextras; i++) { - /* Set the element attributes of the new triangles. */ - attrib = elemattribute(horiz, i); - setelemattribute(newbotleft, i, attrib); - setelemattribute(newbotright, i, attrib); - } - if (b->vararea) { - /* Set the area constraint of the new triangles. */ - area = areabound(horiz); - setareabound(newbotleft, area); - setareabound(newbotright, area); - } - - /* There may be subsegments that need to be bonded */ - /* to the new triangles. */ - if (m->checksegments) { - tspivot(botleft, botlsubseg); - if (botlsubseg.ss != m->dummysub) { - tsdissolve(botleft); - tsbond(newbotleft, botlsubseg); - } - tspivot(botright, botrsubseg); - if (botrsubseg.ss != m->dummysub) { - tsdissolve(botright); - tsbond(newbotright, botrsubseg); - } - } - - /* Bond the new triangles to the surrounding triangles. */ - bond(newbotleft, botlcasing); - bond(newbotright, botrcasing); - lnextself(newbotleft); - lprevself(newbotright); - bond(newbotleft, newbotright); - lnextself(newbotleft); - bond(botleft, newbotleft); - lprevself(newbotright); - bond(botright, newbotright); - - if (m->checkquality) { - poolrestart(&m->flipstackers); - m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers); - m->lastflip->flippedtri = encode(horiz); - m->lastflip->prevflip = (struct flipstacker *) NULL; - } - -#ifdef SELF_CHECK - if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle prior to vertex insertion.\n"); - } - if (counterclockwise(m, b, rightvertex, leftvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle after vertex insertion (top).\n"); - } - if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle after vertex insertion (left).\n"); - } - if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle after vertex insertion (right).\n"); - } -#endif /* SELF_CHECK */ - if (b->verbose > 2) { - printf(" Updating top "); - printtriangle(m, b, &horiz); - printf(" Creating left "); - printtriangle(m, b, &newbotleft); - printf(" Creating right "); - printtriangle(m, b, &newbotright); - } - } - - /* The insertion is successful by default, unless an encroached */ - /* subsegment is found. */ - success = SUCCESSFULVERTEX; - /* Circle around the newly inserted vertex, checking each edge opposite */ - /* it for the Delaunay property. Non-Delaunay edges are flipped. */ - /* `horiz' is always the edge being checked. `first' marks where to */ - /* stop circling. */ - org(horiz, first); - rightvertex = first; - dest(horiz, leftvertex); - /* Circle until finished. */ - while (1) { - /* By default, the edge will be flipped. */ - doflip = 1; - - if (m->checksegments) { - /* Check for a subsegment, which cannot be flipped. */ - tspivot(horiz, checksubseg); - if (checksubseg.ss != m->dummysub) { - /* The edge is a subsegment and cannot be flipped. */ - doflip = 0; -#ifndef CDT_ONLY - if (segmentflaws) { - /* Does the new vertex encroach upon this subsegment? */ - if (checkseg4encroach(m, b, &checksubseg, iradius)) { - success = ENCROACHINGVERTEX; - } - } -#endif /* not CDT_ONLY */ - } - } - - if (doflip) { - /* Check if the edge is a boundary edge. */ - sym(horiz, top); - if (top.tri == m->dummytri) { - /* The edge is a boundary edge and cannot be flipped. */ - doflip = 0; - } else { - /* Find the vertex on the other side of the edge. */ - apex(top, farvertex); - /* In the incremental Delaunay triangulation algorithm, any of */ - /* `leftvertex', `rightvertex', and `farvertex' could be vertices */ - /* of the triangular bounding box. These vertices must be */ - /* treated as if they are infinitely distant, even though their */ - /* "coordinates" are not. */ - if ((leftvertex == m->infvertex1) || (leftvertex == m->infvertex2) || - (leftvertex == m->infvertex3)) { - /* `leftvertex' is infinitely distant. Check the convexity of */ - /* the boundary of the triangulation. 'farvertex' might be */ - /* infinite as well, but trust me, this same condition should */ - /* be applied. */ - doflip = counterclockwise(m, b, newvertex, rightvertex, farvertex) - > 0.0; - } else if ((rightvertex == m->infvertex1) || - (rightvertex == m->infvertex2) || - (rightvertex == m->infvertex3)) { - /* `rightvertex' is infinitely distant. Check the convexity of */ - /* the boundary of the triangulation. 'farvertex' might be */ - /* infinite as well, but trust me, this same condition should */ - /* be applied. */ - doflip = counterclockwise(m, b, farvertex, leftvertex, newvertex) - > 0.0; - } else if ((farvertex == m->infvertex1) || - (farvertex == m->infvertex2) || - (farvertex == m->infvertex3)) { - /* `farvertex' is infinitely distant and cannot be inside */ - /* the circumcircle of the triangle `horiz'. */ - doflip = 0; - } else { - /* Test whether the edge is locally Delaunay. */ - doflip = incircle(m, b, leftvertex, newvertex, rightvertex, - farvertex) > 0.0; - } - if (doflip) { - /* We made it! Flip the edge `horiz' by rotating its containing */ - /* quadrilateral (the two triangles adjacent to `horiz'). */ - /* Identify the casing of the quadrilateral. */ - lprev(top, topleft); - sym(topleft, toplcasing); - lnext(top, topright); - sym(topright, toprcasing); - lnext(horiz, botleft); - sym(botleft, botlcasing); - lprev(horiz, botright); - sym(botright, botrcasing); - /* Rotate the quadrilateral one-quarter turn counterclockwise. */ - bond(topleft, botlcasing); - bond(botleft, botrcasing); - bond(botright, toprcasing); - bond(topright, toplcasing); - if (m->checksegments) { - /* Check for subsegments and rebond them to the quadrilateral. */ - tspivot(topleft, toplsubseg); - tspivot(botleft, botlsubseg); - tspivot(botright, botrsubseg); - tspivot(topright, toprsubseg); - if (toplsubseg.ss == m->dummysub) { - tsdissolve(topright); - } else { - tsbond(topright, toplsubseg); - } - if (botlsubseg.ss == m->dummysub) { - tsdissolve(topleft); - } else { - tsbond(topleft, botlsubseg); - } - if (botrsubseg.ss == m->dummysub) { - tsdissolve(botleft); - } else { - tsbond(botleft, botrsubseg); - } - if (toprsubseg.ss == m->dummysub) { - tsdissolve(botright); - } else { - tsbond(botright, toprsubseg); - } - } - /* New vertex assignments for the rotated quadrilateral. */ - setorg(horiz, farvertex); - setdest(horiz, newvertex); - setapex(horiz, rightvertex); - setorg(top, newvertex); - setdest(top, farvertex); - setapex(top, leftvertex); - for (i = 0; i < m->eextras; i++) { - /* Take the average of the two triangles' attributes. */ - attrib = 0.5 * (elemattribute(top, i) + elemattribute(horiz, i)); - setelemattribute(top, i, attrib); - setelemattribute(horiz, i, attrib); - } - if (b->vararea) { - if ((areabound(top) <= 0.0) || (areabound(horiz) <= 0.0)) { - area = -1.0; - } else { - /* Take the average of the two triangles' area constraints. */ - /* This prevents small area constraints from migrating a */ - /* long, long way from their original location due to flips. */ - area = 0.5 * (areabound(top) + areabound(horiz)); - } - setareabound(top, area); - setareabound(horiz, area); - } - - if (m->checkquality) { - newflip = (struct flipstacker *) poolalloc(&m->flipstackers); - newflip->flippedtri = encode(horiz); - newflip->prevflip = m->lastflip; - m->lastflip = newflip; - } - -#ifdef SELF_CHECK - if (newvertex != (vertex) NULL) { - if (counterclockwise(m, b, leftvertex, newvertex, rightvertex) < - 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle prior to edge flip (bottom).\n"); - } - /* The following test has been removed because constrainededge() */ - /* sometimes generates inverted triangles that insertvertex() */ - /* removes. */ -/* - if (counterclockwise(m, b, rightvertex, farvertex, leftvertex) < - 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle prior to edge flip (top).\n"); - } -*/ - if (counterclockwise(m, b, farvertex, leftvertex, newvertex) < - 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle after edge flip (left).\n"); - } - if (counterclockwise(m, b, newvertex, rightvertex, farvertex) < - 0.0) { - printf("Internal error in insertvertex():\n"); - printf(" Clockwise triangle after edge flip (right).\n"); - } - } -#endif /* SELF_CHECK */ - if (b->verbose > 2) { - printf(" Edge flip results in left "); - lnextself(topleft); - printtriangle(m, b, &topleft); - printf(" and right "); - printtriangle(m, b, &horiz); - } - /* On the next iterations, consider the two edges that were */ - /* exposed (this is, are now visible to the newly inserted */ - /* vertex) by the edge flip. */ - lprevself(horiz); - leftvertex = farvertex; - } - } - } - if (!doflip) { - /* The handle `horiz' is accepted as locally Delaunay. */ -#ifndef CDT_ONLY - if (triflaws) { - /* Check the triangle `horiz' for quality. */ - testtriangle(m, b, &horiz); - } -#endif /* not CDT_ONLY */ - /* Look for the next edge around the newly inserted vertex. */ - lnextself(horiz); - sym(horiz, testtri); - /* Check for finishing a complete revolution about the new vertex, or */ - /* falling outside of the triangulation. The latter will happen */ - /* when a vertex is inserted at a boundary. */ - if ((leftvertex == first) || (testtri.tri == m->dummytri)) { - /* We're done. Return a triangle whose origin is the new vertex. */ - lnext(horiz, *searchtri); - lnext(horiz, m->recenttri); - return success; - } - /* Finish finding the next edge around the newly inserted vertex. */ - lnext(testtri, horiz); - rightvertex = leftvertex; - dest(horiz, leftvertex); - } - } -} - -/*****************************************************************************/ -/* */ -/* triangulatepolygon() Find the Delaunay triangulation of a polygon that */ -/* has a certain "nice" shape. This includes the */ -/* polygons that result from deletion of a vertex or */ -/* insertion of a segment. */ -/* */ -/* This is a conceptually difficult routine. The starting assumption is */ -/* that we have a polygon with n sides. n - 1 of these sides are currently */ -/* represented as edges in the mesh. One side, called the "base", need not */ -/* be. */ -/* */ -/* Inside the polygon is a structure I call a "fan", consisting of n - 1 */ -/* triangles that share a common origin. For each of these triangles, the */ -/* edge opposite the origin is one of the sides of the polygon. The */ -/* primary edge of each triangle is the edge directed from the origin to */ -/* the destination; note that this is not the same edge that is a side of */ -/* the polygon. `firstedge' is the primary edge of the first triangle. */ -/* From there, the triangles follow in counterclockwise order about the */ -/* polygon, until `lastedge', the primary edge of the last triangle. */ -/* `firstedge' and `lastedge' are probably connected to other triangles */ -/* beyond the extremes of the fan, but their identity is not important, as */ -/* long as the fan remains connected to them. */ -/* */ -/* Imagine the polygon oriented so that its base is at the bottom. This */ -/* puts `firstedge' on the far right, and `lastedge' on the far left. */ -/* The right vertex of the base is the destination of `firstedge', and the */ -/* left vertex of the base is the apex of `lastedge'. */ -/* */ -/* The challenge now is to find the right sequence of edge flips to */ -/* transform the fan into a Delaunay triangulation of the polygon. Each */ -/* edge flip effectively removes one triangle from the fan, committing it */ -/* to the polygon. The resulting polygon has one fewer edge. If `doflip' */ -/* is set, the final flip will be performed, resulting in a fan of one */ -/* (useless?) triangle. If `doflip' is not set, the final flip is not */ -/* performed, resulting in a fan of two triangles, and an unfinished */ -/* triangular polygon that is not yet filled out with a single triangle. */ -/* On completion of the routine, `lastedge' is the last remaining triangle, */ -/* or the leftmost of the last two. */ -/* */ -/* Although the flips are performed in the order described above, the */ -/* decisions about what flips to perform are made in precisely the reverse */ -/* order. The recursive triangulatepolygon() procedure makes a decision, */ -/* uses up to two recursive calls to triangulate the "subproblems" */ -/* (polygons with fewer edges), and then performs an edge flip. */ -/* */ -/* The "decision" it makes is which vertex of the polygon should be */ -/* connected to the base. This decision is made by testing every possible */ -/* vertex. Once the best vertex is found, the two edges that connect this */ -/* vertex to the base become the bases for two smaller polygons. These */ -/* are triangulated recursively. Unfortunately, this approach can take */ -/* O(n^2) time not only in the worst case, but in many common cases. It's */ -/* rarely a big deal for vertex deletion, where n is rarely larger than */ -/* ten, but it could be a big deal for segment insertion, especially if */ -/* there's a lot of long segments that each cut many triangles. I ought to */ -/* code a faster algorithm some day. */ -/* */ -/* The `edgecount' parameter is the number of sides of the polygon, */ -/* including its base. `triflaws' is a flag that determines whether the */ -/* new triangles should be tested for quality, and enqueued if they are */ -/* bad. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void triangulatepolygon(struct mesh *m, struct behavior *b, - struct otri *firstedge, struct otri *lastedge, - int edgecount, int doflip, int triflaws) -#else /* not ANSI_DECLARATORS */ -void triangulatepolygon(m, b, firstedge, lastedge, edgecount, doflip, triflaws) -struct mesh *m; -struct behavior *b; -struct otri *firstedge; -struct otri *lastedge; -int edgecount; -int doflip; -int triflaws; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri testtri; - struct otri besttri; - struct otri tempedge; - vertex leftbasevertex, rightbasevertex; - vertex testvertex; - vertex bestvertex; - int bestnumber; - int i; - triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */ - - /* Identify the base vertices. */ - apex(*lastedge, leftbasevertex); - dest(*firstedge, rightbasevertex); - if (b->verbose > 2) { - printf(" Triangulating interior polygon at edge\n"); - printf(" (%.12g, %.12g) (%.12g, %.12g)\n", leftbasevertex[0], - leftbasevertex[1], rightbasevertex[0], rightbasevertex[1]); - } - /* Find the best vertex to connect the base to. */ - onext(*firstedge, besttri); - dest(besttri, bestvertex); - otricopy(besttri, testtri); - bestnumber = 1; - for (i = 2; i <= edgecount - 2; i++) { - onextself(testtri); - dest(testtri, testvertex); - /* Is this a better vertex? */ - if (incircle(m, b, leftbasevertex, rightbasevertex, bestvertex, - testvertex) > 0.0) { - otricopy(testtri, besttri); - bestvertex = testvertex; - bestnumber = i; - } - } - if (b->verbose > 2) { - printf(" Connecting edge to (%.12g, %.12g)\n", bestvertex[0], - bestvertex[1]); - } - if (bestnumber > 1) { - /* Recursively triangulate the smaller polygon on the right. */ - oprev(besttri, tempedge); - triangulatepolygon(m, b, firstedge, &tempedge, bestnumber + 1, 1, - triflaws); - } - if (bestnumber < edgecount - 2) { - /* Recursively triangulate the smaller polygon on the left. */ - sym(besttri, tempedge); - triangulatepolygon(m, b, &besttri, lastedge, edgecount - bestnumber, 1, - triflaws); - /* Find `besttri' again; it may have been lost to edge flips. */ - sym(tempedge, besttri); - } - if (doflip) { - /* Do one final edge flip. */ - flip(m, b, &besttri); -#ifndef CDT_ONLY - if (triflaws) { - /* Check the quality of the newly committed triangle. */ - sym(besttri, testtri); - testtriangle(m, b, &testtri); - } -#endif /* not CDT_ONLY */ - } - /* Return the base triangle. */ - otricopy(besttri, *lastedge); -} - -/*****************************************************************************/ -/* */ -/* deletevertex() Delete a vertex from a Delaunay triangulation, ensuring */ -/* that the triangulation remains Delaunay. */ -/* */ -/* The origin of `deltri' is deleted. The union of the triangles adjacent */ -/* to this vertex is a polygon, for which the Delaunay triangulation is */ -/* found. Two triangles are removed from the mesh. */ -/* */ -/* Only interior vertices that do not lie on segments or boundaries may be */ -/* deleted. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri) -#else /* not ANSI_DECLARATORS */ -void deletevertex(m, b, deltri) -struct mesh *m; -struct behavior *b; -struct otri *deltri; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri countingtri; - struct otri firstedge, lastedge; - struct otri deltriright; - struct otri lefttri, righttri; - struct otri leftcasing, rightcasing; - struct osub leftsubseg, rightsubseg; - vertex delvertex; - vertex neworg; - int edgecount; - triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - org(*deltri, delvertex); - if (b->verbose > 1) { - printf(" Deleting (%.12g, %.12g).\n", delvertex[0], delvertex[1]); - } - vertexdealloc(m, delvertex); - - /* Count the degree of the vertex being deleted. */ - onext(*deltri, countingtri); - edgecount = 1; - while (!otriequal(*deltri, countingtri)) { -#ifdef SELF_CHECK - if (countingtri.tri == m->dummytri) { - printf("Internal error in deletevertex():\n"); - printf(" Attempt to delete boundary vertex.\n"); - internalerror(); - } -#endif /* SELF_CHECK */ - edgecount++; - onextself(countingtri); - } - -#ifdef SELF_CHECK - if (edgecount < 3) { - printf("Internal error in deletevertex():\n Vertex has degree %d.\n", - edgecount); - internalerror(); - } -#endif /* SELF_CHECK */ - if (edgecount > 3) { - /* Triangulate the polygon defined by the union of all triangles */ - /* adjacent to the vertex being deleted. Check the quality of */ - /* the resulting triangles. */ - onext(*deltri, firstedge); - oprev(*deltri, lastedge); - triangulatepolygon(m, b, &firstedge, &lastedge, edgecount, 0, - !b->nobisect); - } - /* Splice out two triangles. */ - lprev(*deltri, deltriright); - dnext(*deltri, lefttri); - sym(lefttri, leftcasing); - oprev(deltriright, righttri); - sym(righttri, rightcasing); - bond(*deltri, leftcasing); - bond(deltriright, rightcasing); - tspivot(lefttri, leftsubseg); - if (leftsubseg.ss != m->dummysub) { - tsbond(*deltri, leftsubseg); - } - tspivot(righttri, rightsubseg); - if (rightsubseg.ss != m->dummysub) { - tsbond(deltriright, rightsubseg); - } - - /* Set the new origin of `deltri' and check its quality. */ - org(lefttri, neworg); - setorg(*deltri, neworg); - if (!b->nobisect) { - testtriangle(m, b, deltri); - } - - /* Delete the two spliced-out triangles. */ - triangledealloc(m, lefttri.tri); - triangledealloc(m, righttri.tri); -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* undovertex() Undo the most recent vertex insertion. */ -/* */ -/* Walks through the list of transformations (flips and a vertex insertion) */ -/* in the reverse of the order in which they were done, and undoes them. */ -/* The inserted vertex is removed from the triangulation and deallocated. */ -/* Two triangles (possibly just one) are also deallocated. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void undovertex(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void undovertex(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri fliptri; - struct otri botleft, botright, topright; - struct otri botlcasing, botrcasing, toprcasing; - struct otri gluetri; - struct osub botlsubseg, botrsubseg, toprsubseg; - vertex botvertex, rightvertex; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - /* Walk through the list of transformations (flips and a vertex insertion) */ - /* in the reverse of the order in which they were done, and undo them. */ - while (m->lastflip != (struct flipstacker *) NULL) { - /* Find a triangle involved in the last unreversed transformation. */ - decode(m->lastflip->flippedtri, fliptri); - - /* We are reversing one of three transformations: a trisection of one */ - /* triangle into three (by inserting a vertex in the triangle), a */ - /* bisection of two triangles into four (by inserting a vertex in an */ - /* edge), or an edge flip. */ - if (m->lastflip->prevflip == (struct flipstacker *) NULL) { - /* Restore a triangle that was split into three triangles, */ - /* so it is again one triangle. */ - dprev(fliptri, botleft); - lnextself(botleft); - onext(fliptri, botright); - lprevself(botright); - sym(botleft, botlcasing); - sym(botright, botrcasing); - dest(botleft, botvertex); - - setapex(fliptri, botvertex); - lnextself(fliptri); - bond(fliptri, botlcasing); - tspivot(botleft, botlsubseg); - tsbond(fliptri, botlsubseg); - lnextself(fliptri); - bond(fliptri, botrcasing); - tspivot(botright, botrsubseg); - tsbond(fliptri, botrsubseg); - - /* Delete the two spliced-out triangles. */ - triangledealloc(m, botleft.tri); - triangledealloc(m, botright.tri); - } else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) { - /* Restore two triangles that were split into four triangles, */ - /* so they are again two triangles. */ - lprev(fliptri, gluetri); - sym(gluetri, botright); - lnextself(botright); - sym(botright, botrcasing); - dest(botright, rightvertex); - - setorg(fliptri, rightvertex); - bond(gluetri, botrcasing); - tspivot(botright, botrsubseg); - tsbond(gluetri, botrsubseg); - - /* Delete the spliced-out triangle. */ - triangledealloc(m, botright.tri); - - sym(fliptri, gluetri); - if (gluetri.tri != m->dummytri) { - lnextself(gluetri); - dnext(gluetri, topright); - sym(topright, toprcasing); - - setorg(gluetri, rightvertex); - bond(gluetri, toprcasing); - tspivot(topright, toprsubseg); - tsbond(gluetri, toprsubseg); - - /* Delete the spliced-out triangle. */ - triangledealloc(m, topright.tri); - } - - /* This is the end of the list, sneakily encoded. */ - m->lastflip->prevflip = (struct flipstacker *) NULL; - } else { - /* Undo an edge flip. */ - unflip(m, b, &fliptri); - } - - /* Go on and process the next transformation. */ - m->lastflip = m->lastflip->prevflip; - } -} - -#endif /* not CDT_ONLY */ - -/** **/ -/** **/ -/********* Mesh transformation routines end here *********/ - -/********* Divide-and-conquer Delaunay triangulation begins here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* The divide-and-conquer bounding box */ -/* */ -/* I originally implemented the divide-and-conquer and incremental Delaunay */ -/* triangulations using the edge-based data structure presented by Guibas */ -/* and Stolfi. Switching to a triangle-based data structure doubled the */ -/* speed. However, I had to think of a few extra tricks to maintain the */ -/* elegance of the original algorithms. */ -/* */ -/* The "bounding box" used by my variant of the divide-and-conquer */ -/* algorithm uses one triangle for each edge of the convex hull of the */ -/* triangulation. These bounding triangles all share a common apical */ -/* vertex, which is represented by NULL and which represents nothing. */ -/* The bounding triangles are linked in a circular fan about this NULL */ -/* vertex, and the edges on the convex hull of the triangulation appear */ -/* opposite the NULL vertex. You might find it easiest to imagine that */ -/* the NULL vertex is a point in 3D space behind the center of the */ -/* triangulation, and that the bounding triangles form a sort of cone. */ -/* */ -/* This bounding box makes it easy to represent degenerate cases. For */ -/* instance, the triangulation of two vertices is a single edge. This edge */ -/* is represented by two bounding box triangles, one on each "side" of the */ -/* edge. These triangles are also linked together in a fan about the NULL */ -/* vertex. */ -/* */ -/* The bounding box also makes it easy to traverse the convex hull, as the */ -/* divide-and-conquer algorithm needs to do. */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* vertexsort() Sort an array of vertices by x-coordinate, using the */ -/* y-coordinate as a secondary key. */ -/* */ -/* Uses quicksort. Randomized O(n log n) time. No, I did not make any of */ -/* the usual quicksort mistakes. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void vertexsort(vertex *sortarray, int arraysize) -#else /* not ANSI_DECLARATORS */ -void vertexsort(sortarray, arraysize) -vertex *sortarray; -int arraysize; -#endif /* not ANSI_DECLARATORS */ - -{ - int left, right; - int pivot; - REAL pivotx, pivoty; - vertex temp; - - if (arraysize == 2) { - /* Recursive base case. */ - if ((sortarray[0][0] > sortarray[1][0]) || - ((sortarray[0][0] == sortarray[1][0]) && - (sortarray[0][1] > sortarray[1][1]))) { - temp = sortarray[1]; - sortarray[1] = sortarray[0]; - sortarray[0] = temp; - } - return; - } - /* Choose a random pivot to split the array. */ - pivot = (int) randomnation((unsigned int) arraysize); - pivotx = sortarray[pivot][0]; - pivoty = sortarray[pivot][1]; - /* Split the array. */ - left = -1; - right = arraysize; - while (left < right) { - /* Search for a vertex whose x-coordinate is too large for the left. */ - do { - left++; - } while ((left <= right) && ((sortarray[left][0] < pivotx) || - ((sortarray[left][0] == pivotx) && - (sortarray[left][1] < pivoty)))); - /* Search for a vertex whose x-coordinate is too small for the right. */ - do { - right--; - } while ((left <= right) && ((sortarray[right][0] > pivotx) || - ((sortarray[right][0] == pivotx) && - (sortarray[right][1] > pivoty)))); - if (left < right) { - /* Swap the left and right vertices. */ - temp = sortarray[left]; - sortarray[left] = sortarray[right]; - sortarray[right] = temp; - } - } - if (left > 1) { - /* Recursively sort the left subset. */ - vertexsort(sortarray, left); - } - if (right < arraysize - 2) { - /* Recursively sort the right subset. */ - vertexsort(&sortarray[right + 1], arraysize - right - 1); - } -} - -/*****************************************************************************/ -/* */ -/* vertexmedian() An order statistic algorithm, almost. Shuffles an */ -/* array of vertices so that the first `median' vertices */ -/* occur lexicographically before the remaining vertices. */ -/* */ -/* Uses the x-coordinate as the primary key if axis == 0; the y-coordinate */ -/* if axis == 1. Very similar to the vertexsort() procedure, but runs in */ -/* randomized linear time. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void vertexmedian(vertex *sortarray, int arraysize, int median, int axis) -#else /* not ANSI_DECLARATORS */ -void vertexmedian(sortarray, arraysize, median, axis) -vertex *sortarray; -int arraysize; -int median; -int axis; -#endif /* not ANSI_DECLARATORS */ - -{ - int left, right; - int pivot; - REAL pivot1, pivot2; - vertex temp; - - if (arraysize == 2) { - /* Recursive base case. */ - if ((sortarray[0][axis] > sortarray[1][axis]) || - ((sortarray[0][axis] == sortarray[1][axis]) && - (sortarray[0][1 - axis] > sortarray[1][1 - axis]))) { - temp = sortarray[1]; - sortarray[1] = sortarray[0]; - sortarray[0] = temp; - } - return; - } - /* Choose a random pivot to split the array. */ - pivot = (int) randomnation((unsigned int) arraysize); - pivot1 = sortarray[pivot][axis]; - pivot2 = sortarray[pivot][1 - axis]; - /* Split the array. */ - left = -1; - right = arraysize; - while (left < right) { - /* Search for a vertex whose x-coordinate is too large for the left. */ - do { - left++; - } while ((left <= right) && ((sortarray[left][axis] < pivot1) || - ((sortarray[left][axis] == pivot1) && - (sortarray[left][1 - axis] < pivot2)))); - /* Search for a vertex whose x-coordinate is too small for the right. */ - do { - right--; - } while ((left <= right) && ((sortarray[right][axis] > pivot1) || - ((sortarray[right][axis] == pivot1) && - (sortarray[right][1 - axis] > pivot2)))); - if (left < right) { - /* Swap the left and right vertices. */ - temp = sortarray[left]; - sortarray[left] = sortarray[right]; - sortarray[right] = temp; - } - } - /* Unlike in vertexsort(), at most one of the following */ - /* conditionals is true. */ - if (left > median) { - /* Recursively shuffle the left subset. */ - vertexmedian(sortarray, left, median, axis); - } - if (right < median - 1) { - /* Recursively shuffle the right subset. */ - vertexmedian(&sortarray[right + 1], arraysize - right - 1, - median - right - 1, axis); - } -} - -/*****************************************************************************/ -/* */ -/* alternateaxes() Sorts the vertices as appropriate for the divide-and- */ -/* conquer algorithm with alternating cuts. */ -/* */ -/* Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1. */ -/* For the base case, subsets containing only two or three vertices are */ -/* always sorted by x-coordinate. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void alternateaxes(vertex *sortarray, int arraysize, int axis) -#else /* not ANSI_DECLARATORS */ -void alternateaxes(sortarray, arraysize, axis) -vertex *sortarray; -int arraysize; -int axis; -#endif /* not ANSI_DECLARATORS */ - -{ - int divider; - - divider = arraysize >> 1; - if (arraysize <= 3) { - /* Recursive base case: subsets of two or three vertices will be */ - /* handled specially, and should always be sorted by x-coordinate. */ - axis = 0; - } - /* Partition with a horizontal or vertical cut. */ - vertexmedian(sortarray, arraysize, divider, axis); - /* Recursively partition the subsets with a cross cut. */ - if (arraysize - divider >= 2) { - if (divider >= 2) { - alternateaxes(sortarray, divider, 1 - axis); - } - alternateaxes(&sortarray[divider], arraysize - divider, 1 - axis); - } -} - -/*****************************************************************************/ -/* */ -/* mergehulls() Merge two adjacent Delaunay triangulations into a */ -/* single Delaunay triangulation. */ -/* */ -/* This is similar to the algorithm given by Guibas and Stolfi, but uses */ -/* a triangle-based, rather than edge-based, data structure. */ -/* */ -/* The algorithm walks up the gap between the two triangulations, knitting */ -/* them together. As they are merged, some of their bounding triangles */ -/* are converted into real triangles of the triangulation. The procedure */ -/* pulls each hull's bounding triangles apart, then knits them together */ -/* like the teeth of two gears. The Delaunay property determines, at each */ -/* step, whether the next "tooth" is a bounding triangle of the left hull */ -/* or the right. When a bounding triangle becomes real, its apex is */ -/* changed from NULL to a real vertex. */ -/* */ -/* Only two new triangles need to be allocated. These become new bounding */ -/* triangles at the top and bottom of the seam. They are used to connect */ -/* the remaining bounding triangles (those that have not been converted */ -/* into real triangles) into a single fan. */ -/* */ -/* On entry, `farleft' and `innerleft' are bounding triangles of the left */ -/* triangulation. The origin of `farleft' is the leftmost vertex, and */ -/* the destination of `innerleft' is the rightmost vertex of the */ -/* triangulation. Similarly, `innerright' and `farright' are bounding */ -/* triangles of the right triangulation. The origin of `innerright' and */ -/* destination of `farright' are the leftmost and rightmost vertices. */ -/* */ -/* On completion, the origin of `farleft' is the leftmost vertex of the */ -/* merged triangulation, and the destination of `farright' is the rightmost */ -/* vertex. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void mergehulls(struct mesh *m, struct behavior *b, struct otri *farleft, - struct otri *innerleft, struct otri *innerright, - struct otri *farright, int axis) -#else /* not ANSI_DECLARATORS */ -void mergehulls(m, b, farleft, innerleft, innerright, farright, axis) -struct mesh *m; -struct behavior *b; -struct otri *farleft; -struct otri *innerleft; -struct otri *innerright; -struct otri *farright; -int axis; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri leftcand, rightcand; - struct otri baseedge; - struct otri nextedge; - struct otri sidecasing, topcasing, outercasing; - struct otri checkedge; - vertex innerleftdest; - vertex innerrightorg; - vertex innerleftapex, innerrightapex; - vertex farleftpt, farrightpt; - vertex farleftapex, farrightapex; - vertex lowerleft, lowerright; - vertex upperleft, upperright; - vertex nextapex; - vertex checkvertex; - int changemade; - int badedge; - int leftfinished, rightfinished; - triangle ptr; /* Temporary variable used by sym(). */ - - dest(*innerleft, innerleftdest); - apex(*innerleft, innerleftapex); - org(*innerright, innerrightorg); - apex(*innerright, innerrightapex); - /* Special treatment for horizontal cuts. */ - if (b->dwyer && (axis == 1)) { - org(*farleft, farleftpt); - apex(*farleft, farleftapex); - dest(*farright, farrightpt); - apex(*farright, farrightapex); - /* The pointers to the extremal vertices are shifted to point to the */ - /* topmost and bottommost vertex of each hull, rather than the */ - /* leftmost and rightmost vertices. */ - while (farleftapex[1] < farleftpt[1]) { - lnextself(*farleft); - symself(*farleft); - farleftpt = farleftapex; - apex(*farleft, farleftapex); - } - sym(*innerleft, checkedge); - apex(checkedge, checkvertex); - while (checkvertex[1] > innerleftdest[1]) { - lnext(checkedge, *innerleft); - innerleftapex = innerleftdest; - innerleftdest = checkvertex; - sym(*innerleft, checkedge); - apex(checkedge, checkvertex); - } - while (innerrightapex[1] < innerrightorg[1]) { - lnextself(*innerright); - symself(*innerright); - innerrightorg = innerrightapex; - apex(*innerright, innerrightapex); - } - sym(*farright, checkedge); - apex(checkedge, checkvertex); - while (checkvertex[1] > farrightpt[1]) { - lnext(checkedge, *farright); - farrightapex = farrightpt; - farrightpt = checkvertex; - sym(*farright, checkedge); - apex(checkedge, checkvertex); - } - } - /* Find a line tangent to and below both hulls. */ - do { - changemade = 0; - /* Make innerleftdest the "bottommost" vertex of the left hull. */ - if (counterclockwise(m, b, innerleftdest, innerleftapex, innerrightorg) > - 0.0) { - lprevself(*innerleft); - symself(*innerleft); - innerleftdest = innerleftapex; - apex(*innerleft, innerleftapex); - changemade = 1; - } - /* Make innerrightorg the "bottommost" vertex of the right hull. */ - if (counterclockwise(m, b, innerrightapex, innerrightorg, innerleftdest) > - 0.0) { - lnextself(*innerright); - symself(*innerright); - innerrightorg = innerrightapex; - apex(*innerright, innerrightapex); - changemade = 1; - } - } while (changemade); - /* Find the two candidates to be the next "gear tooth." */ - sym(*innerleft, leftcand); - sym(*innerright, rightcand); - /* Create the bottom new bounding triangle. */ - maketriangle(m, b, &baseedge); - /* Connect it to the bounding boxes of the left and right triangulations. */ - bond(baseedge, *innerleft); - lnextself(baseedge); - bond(baseedge, *innerright); - lnextself(baseedge); - setorg(baseedge, innerrightorg); - setdest(baseedge, innerleftdest); - /* Apex is intentionally left NULL. */ - if (b->verbose > 2) { - printf(" Creating base bounding "); - printtriangle(m, b, &baseedge); - } - /* Fix the extreme triangles if necessary. */ - org(*farleft, farleftpt); - if (innerleftdest == farleftpt) { - lnext(baseedge, *farleft); - } - dest(*farright, farrightpt); - if (innerrightorg == farrightpt) { - lprev(baseedge, *farright); - } - /* The vertices of the current knitting edge. */ - lowerleft = innerleftdest; - lowerright = innerrightorg; - /* The candidate vertices for knitting. */ - apex(leftcand, upperleft); - apex(rightcand, upperright); - /* Walk up the gap between the two triangulations, knitting them together. */ - while (1) { - /* Have we reached the top? (This isn't quite the right question, */ - /* because even though the left triangulation might seem finished now, */ - /* moving up on the right triangulation might reveal a new vertex of */ - /* the left triangulation. And vice-versa.) */ - leftfinished = counterclockwise(m, b, upperleft, lowerleft, lowerright) <= - 0.0; - rightfinished = counterclockwise(m, b, upperright, lowerleft, lowerright) - <= 0.0; - if (leftfinished && rightfinished) { - /* Create the top new bounding triangle. */ - maketriangle(m, b, &nextedge); - setorg(nextedge, lowerleft); - setdest(nextedge, lowerright); - /* Apex is intentionally left NULL. */ - /* Connect it to the bounding boxes of the two triangulations. */ - bond(nextedge, baseedge); - lnextself(nextedge); - bond(nextedge, rightcand); - lnextself(nextedge); - bond(nextedge, leftcand); - if (b->verbose > 2) { - printf(" Creating top bounding "); - printtriangle(m, b, &nextedge); - } - /* Special treatment for horizontal cuts. */ - if (b->dwyer && (axis == 1)) { - org(*farleft, farleftpt); - apex(*farleft, farleftapex); - dest(*farright, farrightpt); - apex(*farright, farrightapex); - sym(*farleft, checkedge); - apex(checkedge, checkvertex); - /* The pointers to the extremal vertices are restored to the */ - /* leftmost and rightmost vertices (rather than topmost and */ - /* bottommost). */ - while (checkvertex[0] < farleftpt[0]) { - lprev(checkedge, *farleft); - farleftapex = farleftpt; - farleftpt = checkvertex; - sym(*farleft, checkedge); - apex(checkedge, checkvertex); - } - while (farrightapex[0] > farrightpt[0]) { - lprevself(*farright); - symself(*farright); - farrightpt = farrightapex; - apex(*farright, farrightapex); - } - } - return; - } - /* Consider eliminating edges from the left triangulation. */ - if (!leftfinished) { - /* What vertex would be exposed if an edge were deleted? */ - lprev(leftcand, nextedge); - symself(nextedge); - apex(nextedge, nextapex); - /* If nextapex is NULL, then no vertex would be exposed; the */ - /* triangulation would have been eaten right through. */ - if (nextapex != (vertex) NULL) { - /* Check whether the edge is Delaunay. */ - badedge = incircle(m, b, lowerleft, lowerright, upperleft, nextapex) > - 0.0; - while (badedge) { - /* Eliminate the edge with an edge flip. As a result, the */ - /* left triangulation will have one more boundary triangle. */ - lnextself(nextedge); - sym(nextedge, topcasing); - lnextself(nextedge); - sym(nextedge, sidecasing); - bond(nextedge, topcasing); - bond(leftcand, sidecasing); - lnextself(leftcand); - sym(leftcand, outercasing); - lprevself(nextedge); - bond(nextedge, outercasing); - /* Correct the vertices to reflect the edge flip. */ - setorg(leftcand, lowerleft); - setdest(leftcand, NULL); - setapex(leftcand, nextapex); - setorg(nextedge, NULL); - setdest(nextedge, upperleft); - setapex(nextedge, nextapex); - /* Consider the newly exposed vertex. */ - upperleft = nextapex; - /* What vertex would be exposed if another edge were deleted? */ - otricopy(sidecasing, nextedge); - apex(nextedge, nextapex); - if (nextapex != (vertex) NULL) { - /* Check whether the edge is Delaunay. */ - badedge = incircle(m, b, lowerleft, lowerright, upperleft, - nextapex) > 0.0; - } else { - /* Avoid eating right through the triangulation. */ - badedge = 0; - } - } - } - } - /* Consider eliminating edges from the right triangulation. */ - if (!rightfinished) { - /* What vertex would be exposed if an edge were deleted? */ - lnext(rightcand, nextedge); - symself(nextedge); - apex(nextedge, nextapex); - /* If nextapex is NULL, then no vertex would be exposed; the */ - /* triangulation would have been eaten right through. */ - if (nextapex != (vertex) NULL) { - /* Check whether the edge is Delaunay. */ - badedge = incircle(m, b, lowerleft, lowerright, upperright, nextapex) > - 0.0; - while (badedge) { - /* Eliminate the edge with an edge flip. As a result, the */ - /* right triangulation will have one more boundary triangle. */ - lprevself(nextedge); - sym(nextedge, topcasing); - lprevself(nextedge); - sym(nextedge, sidecasing); - bond(nextedge, topcasing); - bond(rightcand, sidecasing); - lprevself(rightcand); - sym(rightcand, outercasing); - lnextself(nextedge); - bond(nextedge, outercasing); - /* Correct the vertices to reflect the edge flip. */ - setorg(rightcand, NULL); - setdest(rightcand, lowerright); - setapex(rightcand, nextapex); - setorg(nextedge, upperright); - setdest(nextedge, NULL); - setapex(nextedge, nextapex); - /* Consider the newly exposed vertex. */ - upperright = nextapex; - /* What vertex would be exposed if another edge were deleted? */ - otricopy(sidecasing, nextedge); - apex(nextedge, nextapex); - if (nextapex != (vertex) NULL) { - /* Check whether the edge is Delaunay. */ - badedge = incircle(m, b, lowerleft, lowerright, upperright, - nextapex) > 0.0; - } else { - /* Avoid eating right through the triangulation. */ - badedge = 0; - } - } - } - } - if (leftfinished || (!rightfinished && - (incircle(m, b, upperleft, lowerleft, lowerright, upperright) > - 0.0))) { - /* Knit the triangulations, adding an edge from `lowerleft' */ - /* to `upperright'. */ - bond(baseedge, rightcand); - lprev(rightcand, baseedge); - setdest(baseedge, lowerleft); - lowerright = upperright; - sym(baseedge, rightcand); - apex(rightcand, upperright); - } else { - /* Knit the triangulations, adding an edge from `upperleft' */ - /* to `lowerright'. */ - bond(baseedge, leftcand); - lnext(leftcand, baseedge); - setorg(baseedge, lowerright); - lowerleft = upperleft; - sym(baseedge, leftcand); - apex(leftcand, upperleft); - } - if (b->verbose > 2) { - printf(" Connecting "); - printtriangle(m, b, &baseedge); - } - } -} - -/*****************************************************************************/ -/* */ -/* divconqrecurse() Recursively form a Delaunay triangulation by the */ -/* divide-and-conquer method. */ -/* */ -/* Recursively breaks down the problem into smaller pieces, which are */ -/* knitted together by mergehulls(). The base cases (problems of two or */ -/* three vertices) are handled specially here. */ -/* */ -/* On completion, `farleft' and `farright' are bounding triangles such that */ -/* the origin of `farleft' is the leftmost vertex (breaking ties by */ -/* choosing the highest leftmost vertex), and the destination of */ -/* `farright' is the rightmost vertex (breaking ties by choosing the */ -/* lowest rightmost vertex). */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void divconqrecurse(struct mesh *m, struct behavior *b, vertex *sortarray, - int vertices, int axis, - struct otri *farleft, struct otri *farright) -#else /* not ANSI_DECLARATORS */ -void divconqrecurse(m, b, sortarray, vertices, axis, farleft, farright) -struct mesh *m; -struct behavior *b; -vertex *sortarray; -int vertices; -int axis; -struct otri *farleft; -struct otri *farright; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri midtri, tri1, tri2, tri3; - struct otri innerleft, innerright; - REAL area; - int divider; - - if (b->verbose > 2) { - printf(" Triangulating %d vertices.\n", vertices); - } - if (vertices == 2) { - /* The triangulation of two vertices is an edge. An edge is */ - /* represented by two bounding triangles. */ - maketriangle(m, b, farleft); - setorg(*farleft, sortarray[0]); - setdest(*farleft, sortarray[1]); - /* The apex is intentionally left NULL. */ - maketriangle(m, b, farright); - setorg(*farright, sortarray[1]); - setdest(*farright, sortarray[0]); - /* The apex is intentionally left NULL. */ - bond(*farleft, *farright); - lprevself(*farleft); - lnextself(*farright); - bond(*farleft, *farright); - lprevself(*farleft); - lnextself(*farright); - bond(*farleft, *farright); - if (b->verbose > 2) { - printf(" Creating "); - printtriangle(m, b, farleft); - printf(" Creating "); - printtriangle(m, b, farright); - } - /* Ensure that the origin of `farleft' is sortarray[0]. */ - lprev(*farright, *farleft); - return; - } else if (vertices == 3) { - /* The triangulation of three vertices is either a triangle (with */ - /* three bounding triangles) or two edges (with four bounding */ - /* triangles). In either case, four triangles are created. */ - maketriangle(m, b, &midtri); - maketriangle(m, b, &tri1); - maketriangle(m, b, &tri2); - maketriangle(m, b, &tri3); - area = counterclockwise(m, b, sortarray[0], sortarray[1], sortarray[2]); - if (area == 0.0) { - /* Three collinear vertices; the triangulation is two edges. */ - setorg(midtri, sortarray[0]); - setdest(midtri, sortarray[1]); - setorg(tri1, sortarray[1]); - setdest(tri1, sortarray[0]); - setorg(tri2, sortarray[2]); - setdest(tri2, sortarray[1]); - setorg(tri3, sortarray[1]); - setdest(tri3, sortarray[2]); - /* All apices are intentionally left NULL. */ - bond(midtri, tri1); - bond(tri2, tri3); - lnextself(midtri); - lprevself(tri1); - lnextself(tri2); - lprevself(tri3); - bond(midtri, tri3); - bond(tri1, tri2); - lnextself(midtri); - lprevself(tri1); - lnextself(tri2); - lprevself(tri3); - bond(midtri, tri1); - bond(tri2, tri3); - /* Ensure that the origin of `farleft' is sortarray[0]. */ - otricopy(tri1, *farleft); - /* Ensure that the destination of `farright' is sortarray[2]. */ - otricopy(tri2, *farright); - } else { - /* The three vertices are not collinear; the triangulation is one */ - /* triangle, namely `midtri'. */ - setorg(midtri, sortarray[0]); - setdest(tri1, sortarray[0]); - setorg(tri3, sortarray[0]); - /* Apices of tri1, tri2, and tri3 are left NULL. */ - if (area > 0.0) { - /* The vertices are in counterclockwise order. */ - setdest(midtri, sortarray[1]); - setorg(tri1, sortarray[1]); - setdest(tri2, sortarray[1]); - setapex(midtri, sortarray[2]); - setorg(tri2, sortarray[2]); - setdest(tri3, sortarray[2]); - } else { - /* The vertices are in clockwise order. */ - setdest(midtri, sortarray[2]); - setorg(tri1, sortarray[2]); - setdest(tri2, sortarray[2]); - setapex(midtri, sortarray[1]); - setorg(tri2, sortarray[1]); - setdest(tri3, sortarray[1]); - } - /* The topology does not depend on how the vertices are ordered. */ - bond(midtri, tri1); - lnextself(midtri); - bond(midtri, tri2); - lnextself(midtri); - bond(midtri, tri3); - lprevself(tri1); - lnextself(tri2); - bond(tri1, tri2); - lprevself(tri1); - lprevself(tri3); - bond(tri1, tri3); - lnextself(tri2); - lprevself(tri3); - bond(tri2, tri3); - /* Ensure that the origin of `farleft' is sortarray[0]. */ - otricopy(tri1, *farleft); - /* Ensure that the destination of `farright' is sortarray[2]. */ - if (area > 0.0) { - otricopy(tri2, *farright); - } else { - lnext(*farleft, *farright); - } - } - if (b->verbose > 2) { - printf(" Creating "); - printtriangle(m, b, &midtri); - printf(" Creating "); - printtriangle(m, b, &tri1); - printf(" Creating "); - printtriangle(m, b, &tri2); - printf(" Creating "); - printtriangle(m, b, &tri3); - } - return; - } else { - /* Split the vertices in half. */ - divider = vertices >> 1; - /* Recursively triangulate each half. */ - divconqrecurse(m, b, sortarray, divider, 1 - axis, farleft, &innerleft); - divconqrecurse(m, b, &sortarray[divider], vertices - divider, 1 - axis, - &innerright, farright); - if (b->verbose > 1) { - printf(" Joining triangulations with %d and %d vertices.\n", divider, - vertices - divider); - } - /* Merge the two triangulations into one. */ - mergehulls(m, b, farleft, &innerleft, &innerright, farright, axis); - } -} - -#ifdef ANSI_DECLARATORS -long removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost) -#else /* not ANSI_DECLARATORS */ -long removeghosts(m, b, startghost) -struct mesh *m; -struct behavior *b; -struct otri *startghost; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri searchedge; - struct otri dissolveedge; - struct otri deadtriangle; - vertex markorg; - long hullsize; - triangle ptr; /* Temporary variable used by sym(). */ - - if (b->verbose) { - printf(" Removing ghost triangles.\n"); - } - /* Find an edge on the convex hull to start point location from. */ - lprev(*startghost, searchedge); - symself(searchedge); - m->dummytri[0] = encode(searchedge); - /* Remove the bounding box and count the convex hull edges. */ - otricopy(*startghost, dissolveedge); - hullsize = 0; - do { - hullsize++; - lnext(dissolveedge, deadtriangle); - lprevself(dissolveedge); - symself(dissolveedge); - /* If no PSLG is involved, set the boundary markers of all the vertices */ - /* on the convex hull. If a PSLG is used, this step is done later. */ - if (!b->poly) { - /* Watch out for the case where all the input vertices are collinear. */ - if (dissolveedge.tri != m->dummytri) { - org(dissolveedge, markorg); - if (vertexmark(markorg) == 0) { - setvertexmark(markorg, 1); - } - } - } - /* Remove a bounding triangle from a convex hull triangle. */ - dissolve(dissolveedge); - /* Find the next bounding triangle. */ - sym(deadtriangle, dissolveedge); - /* Delete the bounding triangle. */ - triangledealloc(m, deadtriangle.tri); - } while (!otriequal(dissolveedge, *startghost)); - return hullsize; -} - -/*****************************************************************************/ -/* */ -/* divconqdelaunay() Form a Delaunay triangulation by the divide-and- */ -/* conquer method. */ -/* */ -/* Sorts the vertices, calls a recursive procedure to triangulate them, and */ -/* removes the bounding box, setting boundary markers as appropriate. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -long divconqdelaunay(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -long divconqdelaunay(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex *sortarray; - struct otri hullleft, hullright; - int divider; - int i, j; - - if (b->verbose) { - printf(" Sorting vertices.\n"); - } - - /* Allocate an array of pointers to vertices for sorting. */ - sortarray = (vertex *) trimalloc(m->invertices * (int) sizeof(vertex)); - traversalinit(&m->vertices); - for (i = 0; i < m->invertices; i++) { - sortarray[i] = vertextraverse(m); - } - /* Sort the vertices. */ - vertexsort(sortarray, m->invertices); - /* Discard duplicate vertices, which can really mess up the algorithm. */ - i = 0; - for (j = 1; j < m->invertices; j++) { - if ((sortarray[i][0] == sortarray[j][0]) - && (sortarray[i][1] == sortarray[j][1])) { - if (!b->quiet) { - printf( -"Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n", - sortarray[j][0], sortarray[j][1]); - } - setvertextype(sortarray[j], UNDEADVERTEX); - m->undeads++; - } else { - i++; - sortarray[i] = sortarray[j]; - } - } - i++; - if (b->dwyer) { - /* Re-sort the array of vertices to accommodate alternating cuts. */ - divider = i >> 1; - if (i - divider >= 2) { - if (divider >= 2) { - alternateaxes(sortarray, divider, 1); - } - alternateaxes(&sortarray[divider], i - divider, 1); - } - } - - if (b->verbose) { - printf(" Forming triangulation.\n"); - } - - /* Form the Delaunay triangulation. */ - divconqrecurse(m, b, sortarray, i, 0, &hullleft, &hullright); - trifree((VOID *) sortarray); - - return removeghosts(m, b, &hullleft); -} - -/** **/ -/** **/ -/********* Divide-and-conquer Delaunay triangulation ends here *********/ - -/********* Incremental Delaunay triangulation begins here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* boundingbox() Form an "infinite" bounding triangle to insert vertices */ -/* into. */ -/* */ -/* The vertices at "infinity" are assigned finite coordinates, which are */ -/* used by the point location routines, but (mostly) ignored by the */ -/* Delaunay edge flip routines. */ -/* */ -/*****************************************************************************/ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void boundingbox(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void boundingbox(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri inftri; /* Handle for the triangular bounding box. */ - REAL width; - - if (b->verbose) { - printf(" Creating triangular bounding box.\n"); - } - /* Find the width (or height, whichever is larger) of the triangulation. */ - width = m->xmax - m->xmin; - if (m->ymax - m->ymin > width) { - width = m->ymax - m->ymin; - } - if (width == 0.0) { - width = 1.0; - } - /* Create the vertices of the bounding box. */ - m->infvertex1 = (vertex) trimalloc(m->vertices.itembytes); - m->infvertex2 = (vertex) trimalloc(m->vertices.itembytes); - m->infvertex3 = (vertex) trimalloc(m->vertices.itembytes); - m->infvertex1[0] = m->xmin - 50.0 * width; - m->infvertex1[1] = m->ymin - 40.0 * width; - m->infvertex2[0] = m->xmax + 50.0 * width; - m->infvertex2[1] = m->ymin - 40.0 * width; - m->infvertex3[0] = 0.5 * (m->xmin + m->xmax); - m->infvertex3[1] = m->ymax + 60.0 * width; - - /* Create the bounding box. */ - maketriangle(m, b, &inftri); - setorg(inftri, m->infvertex1); - setdest(inftri, m->infvertex2); - setapex(inftri, m->infvertex3); - /* Link dummytri to the bounding box so we can always find an */ - /* edge to begin searching (point location) from. */ - m->dummytri[0] = (triangle) inftri.tri; - if (b->verbose > 2) { - printf(" Creating "); - printtriangle(m, b, &inftri); - } -} - -#endif /* not REDUCED */ - -/*****************************************************************************/ -/* */ -/* removebox() Remove the "infinite" bounding triangle, setting boundary */ -/* markers as appropriate. */ -/* */ -/* The triangular bounding box has three boundary triangles (one for each */ -/* side of the bounding box), and a bunch of triangles fanning out from */ -/* the three bounding box vertices (one triangle for each edge of the */ -/* convex hull of the inner mesh). This routine removes these triangles. */ -/* */ -/* Returns the number of edges on the convex hull of the triangulation. */ -/* */ -/*****************************************************************************/ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -long removebox(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -long removebox(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri deadtriangle; - struct otri searchedge; - struct otri checkedge; - struct otri nextedge, finaledge, dissolveedge; - vertex markorg; - long hullsize; - triangle ptr; /* Temporary variable used by sym(). */ - - if (b->verbose) { - printf(" Removing triangular bounding box.\n"); - } - /* Find a boundary triangle. */ - nextedge.tri = m->dummytri; - nextedge.orient = 0; - symself(nextedge); - /* Mark a place to stop. */ - lprev(nextedge, finaledge); - lnextself(nextedge); - symself(nextedge); - /* Find a triangle (on the boundary of the vertex set) that isn't */ - /* a bounding box triangle. */ - lprev(nextedge, searchedge); - symself(searchedge); - /* Check whether nextedge is another boundary triangle */ - /* adjacent to the first one. */ - lnext(nextedge, checkedge); - symself(checkedge); - if (checkedge.tri == m->dummytri) { - /* Go on to the next triangle. There are only three boundary */ - /* triangles, and this next triangle cannot be the third one, */ - /* so it's safe to stop here. */ - lprevself(searchedge); - symself(searchedge); - } - /* Find a new boundary edge to search from, as the current search */ - /* edge lies on a bounding box triangle and will be deleted. */ - m->dummytri[0] = encode(searchedge); - hullsize = -2l; - while (!otriequal(nextedge, finaledge)) { - hullsize++; - lprev(nextedge, dissolveedge); - symself(dissolveedge); - /* If not using a PSLG, the vertices should be marked now. */ - /* (If using a PSLG, markhull() will do the job.) */ - if (!b->poly) { - /* Be careful! One must check for the case where all the input */ - /* vertices are collinear, and thus all the triangles are part of */ - /* the bounding box. Otherwise, the setvertexmark() call below */ - /* will cause a bad pointer reference. */ - if (dissolveedge.tri != m->dummytri) { - org(dissolveedge, markorg); - if (vertexmark(markorg) == 0) { - setvertexmark(markorg, 1); - } - } - } - /* Disconnect the bounding box triangle from the mesh triangle. */ - dissolve(dissolveedge); - lnext(nextedge, deadtriangle); - sym(deadtriangle, nextedge); - /* Get rid of the bounding box triangle. */ - triangledealloc(m, deadtriangle.tri); - /* Do we need to turn the corner? */ - if (nextedge.tri == m->dummytri) { - /* Turn the corner. */ - otricopy(dissolveedge, nextedge); - } - } - triangledealloc(m, finaledge.tri); - - trifree((VOID *) m->infvertex1); /* Deallocate the bounding box vertices. */ - trifree((VOID *) m->infvertex2); - trifree((VOID *) m->infvertex3); - - return hullsize; -} - -#endif /* not REDUCED */ - -/*****************************************************************************/ -/* */ -/* incrementaldelaunay() Form a Delaunay triangulation by incrementally */ -/* inserting vertices. */ -/* */ -/* Returns the number of edges on the convex hull of the triangulation. */ -/* */ -/*****************************************************************************/ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -long incrementaldelaunay(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -long incrementaldelaunay(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri starttri; - vertex vertexloop; - - /* Create a triangular bounding box. */ - boundingbox(m, b); - if (b->verbose) { - printf(" Incrementally inserting vertices.\n"); - } - traversalinit(&m->vertices); - vertexloop = vertextraverse(m); - while (vertexloop != (vertex) NULL) { - starttri.tri = m->dummytri; - if (insertvertex(m, b, vertexloop, &starttri, (struct osub *) NULL, 0, 0, - 0.0) == DUPLICATEVERTEX) { - if (!b->quiet) { - printf( -"Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n", - vertexloop[0], vertexloop[1]); - } - setvertextype(vertexloop, UNDEADVERTEX); - m->undeads++; - } - vertexloop = vertextraverse(m); - } - /* Remove the bounding box. */ - return removebox(m, b); -} - -#endif /* not REDUCED */ - -/** **/ -/** **/ -/********* Incremental Delaunay triangulation ends here *********/ - -/********* Sweepline Delaunay triangulation begins here *********/ -/** **/ -/** **/ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void eventheapinsert(struct event **heap, int heapsize, struct event *newevent) -#else /* not ANSI_DECLARATORS */ -void eventheapinsert(heap, heapsize, newevent) -struct event **heap; -int heapsize; -struct event *newevent; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL eventx, eventy; - int eventnum; - int parent; - int notdone; - - eventx = newevent->xkey; - eventy = newevent->ykey; - eventnum = heapsize; - notdone = eventnum > 0; - while (notdone) { - parent = (eventnum - 1) >> 1; - if ((heap[parent]->ykey < eventy) || - ((heap[parent]->ykey == eventy) - && (heap[parent]->xkey <= eventx))) { - notdone = 0; - } else { - heap[eventnum] = heap[parent]; - heap[eventnum]->heapposition = eventnum; - - eventnum = parent; - notdone = eventnum > 0; - } - } - heap[eventnum] = newevent; - newevent->heapposition = eventnum; -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void eventheapify(struct event **heap, int heapsize, int eventnum) -#else /* not ANSI_DECLARATORS */ -void eventheapify(heap, heapsize, eventnum) -struct event **heap; -int heapsize; -int eventnum; -#endif /* not ANSI_DECLARATORS */ - -{ - struct event *thisevent; - REAL eventx, eventy; - int leftchild, rightchild; - int smallest; - int notdone; - - thisevent = heap[eventnum]; - eventx = thisevent->xkey; - eventy = thisevent->ykey; - leftchild = 2 * eventnum + 1; - notdone = leftchild < heapsize; - while (notdone) { - if ((heap[leftchild]->ykey < eventy) || - ((heap[leftchild]->ykey == eventy) - && (heap[leftchild]->xkey < eventx))) { - smallest = leftchild; - } else { - smallest = eventnum; - } - rightchild = leftchild + 1; - if (rightchild < heapsize) { - if ((heap[rightchild]->ykey < heap[smallest]->ykey) || - ((heap[rightchild]->ykey == heap[smallest]->ykey) - && (heap[rightchild]->xkey < heap[smallest]->xkey))) { - smallest = rightchild; - } - } - if (smallest == eventnum) { - notdone = 0; - } else { - heap[eventnum] = heap[smallest]; - heap[eventnum]->heapposition = eventnum; - heap[smallest] = thisevent; - thisevent->heapposition = smallest; - - eventnum = smallest; - leftchild = 2 * eventnum + 1; - notdone = leftchild < heapsize; - } - } -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void eventheapdelete(struct event **heap, int heapsize, int eventnum) -#else /* not ANSI_DECLARATORS */ -void eventheapdelete(heap, heapsize, eventnum) -struct event **heap; -int heapsize; -int eventnum; -#endif /* not ANSI_DECLARATORS */ - -{ - struct event *moveevent; - REAL eventx, eventy; - int parent; - int notdone; - - moveevent = heap[heapsize - 1]; - if (eventnum > 0) { - eventx = moveevent->xkey; - eventy = moveevent->ykey; - do { - parent = (eventnum - 1) >> 1; - if ((heap[parent]->ykey < eventy) || - ((heap[parent]->ykey == eventy) - && (heap[parent]->xkey <= eventx))) { - notdone = 0; - } else { - heap[eventnum] = heap[parent]; - heap[eventnum]->heapposition = eventnum; - - eventnum = parent; - notdone = eventnum > 0; - } - } while (notdone); - } - heap[eventnum] = moveevent; - moveevent->heapposition = eventnum; - eventheapify(heap, heapsize - 1, eventnum); -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void createeventheap(struct mesh *m, struct event ***eventheap, - struct event **events, struct event **freeevents) -#else /* not ANSI_DECLARATORS */ -void createeventheap(m, eventheap, events, freeevents) -struct mesh *m; -struct event ***eventheap; -struct event **events; -struct event **freeevents; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex thisvertex; - int maxevents; - int i; - - maxevents = (3 * m->invertices) / 2; - *eventheap = (struct event **) - trimalloc(maxevents * (int) sizeof(struct event *)); - *events = (struct event *) trimalloc(maxevents * (int) sizeof(struct event)); - traversalinit(&m->vertices); - for (i = 0; i < m->invertices; i++) { - thisvertex = vertextraverse(m); - (*events)[i].eventptr = (VOID *) thisvertex; - (*events)[i].xkey = thisvertex[0]; - (*events)[i].ykey = thisvertex[1]; - eventheapinsert(*eventheap, i, *events + i); - } - *freeevents = (struct event *) NULL; - for (i = maxevents - 1; i >= m->invertices; i--) { - (*events)[i].eventptr = (VOID *) *freeevents; - *freeevents = *events + i; - } -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -int rightofhyperbola(struct mesh *m, struct otri *fronttri, vertex newsite) -#else /* not ANSI_DECLARATORS */ -int rightofhyperbola(m, fronttri, newsite) -struct mesh *m; -struct otri *fronttri; -vertex newsite; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex leftvertex, rightvertex; - REAL dxa, dya, dxb, dyb; - - m->hyperbolacount++; - - dest(*fronttri, leftvertex); - apex(*fronttri, rightvertex); - if ((leftvertex[1] < rightvertex[1]) || - ((leftvertex[1] == rightvertex[1]) && - (leftvertex[0] < rightvertex[0]))) { - if (newsite[0] >= rightvertex[0]) { - return 1; - } - } else { - if (newsite[0] <= leftvertex[0]) { - return 0; - } - } - dxa = leftvertex[0] - newsite[0]; - dya = leftvertex[1] - newsite[1]; - dxb = rightvertex[0] - newsite[0]; - dyb = rightvertex[1] - newsite[1]; - return dya * (dxb * dxb + dyb * dyb) > dyb * (dxa * dxa + dya * dya); -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -REAL circletop(struct mesh *m, vertex pa, vertex pb, vertex pc, REAL ccwabc) -#else /* not ANSI_DECLARATORS */ -REAL circletop(m, pa, pb, pc, ccwabc) -struct mesh *m; -vertex pa; -vertex pb; -vertex pc; -REAL ccwabc; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL xac, yac, xbc, ybc, xab, yab; - REAL aclen2, bclen2, ablen2; - - m->circletopcount++; - - xac = pa[0] - pc[0]; - yac = pa[1] - pc[1]; - xbc = pb[0] - pc[0]; - ybc = pb[1] - pc[1]; - xab = pa[0] - pb[0]; - yab = pa[1] - pb[1]; - aclen2 = xac * xac + yac * yac; - bclen2 = xbc * xbc + ybc * ybc; - ablen2 = xab * xab + yab * yab; - return pc[1] + (xac * bclen2 - xbc * aclen2 + sqrt(aclen2 * bclen2 * ablen2)) - / (2.0 * ccwabc); -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -void check4deadevent(struct otri *checktri, struct event **freeevents, - struct event **eventheap, int *heapsize) -#else /* not ANSI_DECLARATORS */ -void check4deadevent(checktri, freeevents, eventheap, heapsize) -struct otri *checktri; -struct event **freeevents; -struct event **eventheap; -int *heapsize; -#endif /* not ANSI_DECLARATORS */ - -{ - struct event *deadevent; - vertex eventvertex; - int eventnum; - - org(*checktri, eventvertex); - if (eventvertex != (vertex) NULL) { - deadevent = (struct event *) eventvertex; - eventnum = deadevent->heapposition; - deadevent->eventptr = (VOID *) *freeevents; - *freeevents = deadevent; - eventheapdelete(eventheap, *heapsize, eventnum); - (*heapsize)--; - setorg(*checktri, NULL); - } -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -struct splaynode *splay(struct mesh *m, struct splaynode *splaytree, - vertex searchpoint, struct otri *searchtri) -#else /* not ANSI_DECLARATORS */ -struct splaynode *splay(m, splaytree, searchpoint, searchtri) -struct mesh *m; -struct splaynode *splaytree; -vertex searchpoint; -struct otri *searchtri; -#endif /* not ANSI_DECLARATORS */ - -{ - struct splaynode *child, *grandchild; - struct splaynode *lefttree, *righttree; - struct splaynode *leftright; - vertex checkvertex; - int rightofroot, rightofchild; - - if (splaytree == (struct splaynode *) NULL) { - return (struct splaynode *) NULL; - } - dest(splaytree->keyedge, checkvertex); - if (checkvertex == splaytree->keydest) { - rightofroot = rightofhyperbola(m, &splaytree->keyedge, searchpoint); - if (rightofroot) { - otricopy(splaytree->keyedge, *searchtri); - child = splaytree->rchild; - } else { - child = splaytree->lchild; - } - if (child == (struct splaynode *) NULL) { - return splaytree; - } - dest(child->keyedge, checkvertex); - if (checkvertex != child->keydest) { - child = splay(m, child, searchpoint, searchtri); - if (child == (struct splaynode *) NULL) { - if (rightofroot) { - splaytree->rchild = (struct splaynode *) NULL; - } else { - splaytree->lchild = (struct splaynode *) NULL; - } - return splaytree; - } - } - rightofchild = rightofhyperbola(m, &child->keyedge, searchpoint); - if (rightofchild) { - otricopy(child->keyedge, *searchtri); - grandchild = splay(m, child->rchild, searchpoint, searchtri); - child->rchild = grandchild; - } else { - grandchild = splay(m, child->lchild, searchpoint, searchtri); - child->lchild = grandchild; - } - if (grandchild == (struct splaynode *) NULL) { - if (rightofroot) { - splaytree->rchild = child->lchild; - child->lchild = splaytree; - } else { - splaytree->lchild = child->rchild; - child->rchild = splaytree; - } - return child; - } - if (rightofchild) { - if (rightofroot) { - splaytree->rchild = child->lchild; - child->lchild = splaytree; - } else { - splaytree->lchild = grandchild->rchild; - grandchild->rchild = splaytree; - } - child->rchild = grandchild->lchild; - grandchild->lchild = child; - } else { - if (rightofroot) { - splaytree->rchild = grandchild->lchild; - grandchild->lchild = splaytree; - } else { - splaytree->lchild = child->rchild; - child->rchild = splaytree; - } - child->lchild = grandchild->rchild; - grandchild->rchild = child; - } - return grandchild; - } else { - lefttree = splay(m, splaytree->lchild, searchpoint, searchtri); - righttree = splay(m, splaytree->rchild, searchpoint, searchtri); - - pooldealloc(&m->splaynodes, (VOID *) splaytree); - if (lefttree == (struct splaynode *) NULL) { - return righttree; - } else if (righttree == (struct splaynode *) NULL) { - return lefttree; - } else if (lefttree->rchild == (struct splaynode *) NULL) { - lefttree->rchild = righttree->lchild; - righttree->lchild = lefttree; - return righttree; - } else if (righttree->lchild == (struct splaynode *) NULL) { - righttree->lchild = lefttree->rchild; - lefttree->rchild = righttree; - return lefttree; - } else { -/* printf("Holy Toledo!!!\n"); */ - leftright = lefttree->rchild; - while (leftright->rchild != (struct splaynode *) NULL) { - leftright = leftright->rchild; - } - leftright->rchild = righttree; - return lefttree; - } - } -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -struct splaynode *splayinsert(struct mesh *m, struct splaynode *splayroot, - struct otri *newkey, vertex searchpoint) -#else /* not ANSI_DECLARATORS */ -struct splaynode *splayinsert(m, splayroot, newkey, searchpoint) -struct mesh *m; -struct splaynode *splayroot; -struct otri *newkey; -vertex searchpoint; -#endif /* not ANSI_DECLARATORS */ - -{ - struct splaynode *newsplaynode; - - newsplaynode = (struct splaynode *) poolalloc(&m->splaynodes); - otricopy(*newkey, newsplaynode->keyedge); - dest(*newkey, newsplaynode->keydest); - if (splayroot == (struct splaynode *) NULL) { - newsplaynode->lchild = (struct splaynode *) NULL; - newsplaynode->rchild = (struct splaynode *) NULL; - } else if (rightofhyperbola(m, &splayroot->keyedge, searchpoint)) { - newsplaynode->lchild = splayroot; - newsplaynode->rchild = splayroot->rchild; - splayroot->rchild = (struct splaynode *) NULL; - } else { - newsplaynode->lchild = splayroot->lchild; - newsplaynode->rchild = splayroot; - splayroot->lchild = (struct splaynode *) NULL; - } - return newsplaynode; -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -struct splaynode *circletopinsert(struct mesh *m, struct behavior *b, - struct splaynode *splayroot, - struct otri *newkey, - vertex pa, vertex pb, vertex pc, REAL topy) -#else /* not ANSI_DECLARATORS */ -struct splaynode *circletopinsert(m, b, splayroot, newkey, pa, pb, pc, topy) -struct mesh *m; -struct behavior *b; -struct splaynode *splayroot; -struct otri *newkey; -vertex pa; -vertex pb; -vertex pc; -REAL topy; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL ccwabc; - REAL xac, yac, xbc, ybc; - REAL aclen2, bclen2; - REAL searchpoint[2]; - struct otri dummytri; - - ccwabc = counterclockwise(m, b, pa, pb, pc); - xac = pa[0] - pc[0]; - yac = pa[1] - pc[1]; - xbc = pb[0] - pc[0]; - ybc = pb[1] - pc[1]; - aclen2 = xac * xac + yac * yac; - bclen2 = xbc * xbc + ybc * ybc; - searchpoint[0] = pc[0] - (yac * bclen2 - ybc * aclen2) / (2.0 * ccwabc); - searchpoint[1] = topy; - return splayinsert(m, splay(m, splayroot, (vertex) searchpoint, &dummytri), - newkey, (vertex) searchpoint); -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -struct splaynode *frontlocate(struct mesh *m, struct splaynode *splayroot, - struct otri *bottommost, vertex searchvertex, - struct otri *searchtri, int *farright) -#else /* not ANSI_DECLARATORS */ -struct splaynode *frontlocate(m, splayroot, bottommost, searchvertex, - searchtri, farright) -struct mesh *m; -struct splaynode *splayroot; -struct otri *bottommost; -vertex searchvertex; -struct otri *searchtri; -int *farright; -#endif /* not ANSI_DECLARATORS */ - -{ - int farrightflag; - triangle ptr; /* Temporary variable used by onext(). */ - - otricopy(*bottommost, *searchtri); - splayroot = splay(m, splayroot, searchvertex, searchtri); - - farrightflag = 0; - while (!farrightflag && rightofhyperbola(m, searchtri, searchvertex)) { - onextself(*searchtri); - farrightflag = otriequal(*searchtri, *bottommost); - } - *farright = farrightflag; - return splayroot; -} - -#endif /* not REDUCED */ - -#ifndef REDUCED - -#ifdef ANSI_DECLARATORS -long sweeplinedelaunay(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -long sweeplinedelaunay(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct event **eventheap; - struct event *events; - struct event *freeevents; - struct event *nextevent; - struct event *newevent; - struct splaynode *splayroot; - struct otri bottommost; - struct otri searchtri; - struct otri fliptri; - struct otri lefttri, righttri, farlefttri, farrighttri; - struct otri inserttri; - vertex firstvertex, secondvertex; - vertex nextvertex, lastvertex; - vertex connectvertex; - vertex leftvertex, midvertex, rightvertex; - REAL lefttest, righttest; - int heapsize; - int check4events, farrightflag; - triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */ - - poolinit(&m->splaynodes, sizeof(struct splaynode), SPLAYNODEPERBLOCK, - SPLAYNODEPERBLOCK, POINTER, 0); - splayroot = (struct splaynode *) NULL; - - if (b->verbose) { - printf(" Placing vertices in event heap.\n"); - } - createeventheap(m, &eventheap, &events, &freeevents); - heapsize = m->invertices; - - if (b->verbose) { - printf(" Forming triangulation.\n"); - } - maketriangle(m, b, &lefttri); - maketriangle(m, b, &righttri); - bond(lefttri, righttri); - lnextself(lefttri); - lprevself(righttri); - bond(lefttri, righttri); - lnextself(lefttri); - lprevself(righttri); - bond(lefttri, righttri); - firstvertex = (vertex) eventheap[0]->eventptr; - eventheap[0]->eventptr = (VOID *) freeevents; - freeevents = eventheap[0]; - eventheapdelete(eventheap, heapsize, 0); - heapsize--; - do { - if (heapsize == 0) { - printf("Error: Input vertices are all identical.\n"); - exit(1); - } - secondvertex = (vertex) eventheap[0]->eventptr; - eventheap[0]->eventptr = (VOID *) freeevents; - freeevents = eventheap[0]; - eventheapdelete(eventheap, heapsize, 0); - heapsize--; - if ((firstvertex[0] == secondvertex[0]) && - (firstvertex[1] == secondvertex[1])) { - if (!b->quiet) { - printf( -"Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n", - secondvertex[0], secondvertex[1]); - } - setvertextype(secondvertex, UNDEADVERTEX); - m->undeads++; - } - } while ((firstvertex[0] == secondvertex[0]) && - (firstvertex[1] == secondvertex[1])); - setorg(lefttri, firstvertex); - setdest(lefttri, secondvertex); - setorg(righttri, secondvertex); - setdest(righttri, firstvertex); - lprev(lefttri, bottommost); - lastvertex = secondvertex; - while (heapsize > 0) { - nextevent = eventheap[0]; - eventheapdelete(eventheap, heapsize, 0); - heapsize--; - check4events = 1; - if (nextevent->xkey < m->xmin) { - decode(nextevent->eventptr, fliptri); - oprev(fliptri, farlefttri); - check4deadevent(&farlefttri, &freeevents, eventheap, &heapsize); - onext(fliptri, farrighttri); - check4deadevent(&farrighttri, &freeevents, eventheap, &heapsize); - - if (otriequal(farlefttri, bottommost)) { - lprev(fliptri, bottommost); - } - flip(m, b, &fliptri); - setapex(fliptri, NULL); - lprev(fliptri, lefttri); - lnext(fliptri, righttri); - sym(lefttri, farlefttri); - - if (randomnation(SAMPLERATE) == 0) { - symself(fliptri); - dest(fliptri, leftvertex); - apex(fliptri, midvertex); - org(fliptri, rightvertex); - splayroot = circletopinsert(m, b, splayroot, &lefttri, leftvertex, - midvertex, rightvertex, nextevent->ykey); - } - } else { - nextvertex = (vertex) nextevent->eventptr; - if ((nextvertex[0] == lastvertex[0]) && - (nextvertex[1] == lastvertex[1])) { - if (!b->quiet) { - printf( -"Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n", - nextvertex[0], nextvertex[1]); - } - setvertextype(nextvertex, UNDEADVERTEX); - m->undeads++; - check4events = 0; - } else { - lastvertex = nextvertex; - - splayroot = frontlocate(m, splayroot, &bottommost, nextvertex, - &searchtri, &farrightflag); -/* - otricopy(bottommost, searchtri); - farrightflag = 0; - while (!farrightflag && rightofhyperbola(m, &searchtri, nextvertex)) { - onextself(searchtri); - farrightflag = otriequal(searchtri, bottommost); - } -*/ - - check4deadevent(&searchtri, &freeevents, eventheap, &heapsize); - - otricopy(searchtri, farrighttri); - sym(searchtri, farlefttri); - maketriangle(m, b, &lefttri); - maketriangle(m, b, &righttri); - dest(farrighttri, connectvertex); - setorg(lefttri, connectvertex); - setdest(lefttri, nextvertex); - setorg(righttri, nextvertex); - setdest(righttri, connectvertex); - bond(lefttri, righttri); - lnextself(lefttri); - lprevself(righttri); - bond(lefttri, righttri); - lnextself(lefttri); - lprevself(righttri); - bond(lefttri, farlefttri); - bond(righttri, farrighttri); - if (!farrightflag && otriequal(farrighttri, bottommost)) { - otricopy(lefttri, bottommost); - } - - if (randomnation(SAMPLERATE) == 0) { - splayroot = splayinsert(m, splayroot, &lefttri, nextvertex); - } else if (randomnation(SAMPLERATE) == 0) { - lnext(righttri, inserttri); - splayroot = splayinsert(m, splayroot, &inserttri, nextvertex); - } - } - } - nextevent->eventptr = (VOID *) freeevents; - freeevents = nextevent; - - if (check4events) { - apex(farlefttri, leftvertex); - dest(lefttri, midvertex); - apex(lefttri, rightvertex); - lefttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex); - if (lefttest > 0.0) { - newevent = freeevents; - freeevents = (struct event *) freeevents->eventptr; - newevent->xkey = m->xminextreme; - newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex, - lefttest); - newevent->eventptr = (VOID *) encode(lefttri); - eventheapinsert(eventheap, heapsize, newevent); - heapsize++; - setorg(lefttri, newevent); - } - apex(righttri, leftvertex); - org(righttri, midvertex); - apex(farrighttri, rightvertex); - righttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex); - if (righttest > 0.0) { - newevent = freeevents; - freeevents = (struct event *) freeevents->eventptr; - newevent->xkey = m->xminextreme; - newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex, - righttest); - newevent->eventptr = (VOID *) encode(farrighttri); - eventheapinsert(eventheap, heapsize, newevent); - heapsize++; - setorg(farrighttri, newevent); - } - } - } - - pooldeinit(&m->splaynodes); - lprevself(bottommost); - return removeghosts(m, b, &bottommost); -} - -#endif /* not REDUCED */ - -/** **/ -/** **/ -/********* Sweepline Delaunay triangulation ends here *********/ - -/********* General mesh construction routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* delaunay() Form a Delaunay triangulation. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -long delaunay(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -long delaunay(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - long hulledges; - - m->eextras = 0; - initializetrisubpools(m, b); - -#ifdef REDUCED - if (!b->quiet) { - printf( - "Constructing Delaunay triangulation by divide-and-conquer method.\n"); - } - hulledges = divconqdelaunay(m, b); -#else /* not REDUCED */ - if (!b->quiet) { - printf("Constructing Delaunay triangulation "); - if (b->incremental) { - printf("by incremental method.\n"); - } else if (b->sweepline) { - printf("by sweepline method.\n"); - } else { - printf("by divide-and-conquer method.\n"); - } - } - if (b->incremental) { - hulledges = incrementaldelaunay(m, b); - } else if (b->sweepline) { - hulledges = sweeplinedelaunay(m, b); - } else { - hulledges = divconqdelaunay(m, b); - } -#endif /* not REDUCED */ - - if (m->triangles.items == 0) { - /* The input vertices were all collinear, so there are no triangles. */ - return 0l; - } else { - return hulledges; - } -} - -/*****************************************************************************/ -/* */ -/* reconstruct() Reconstruct a triangulation from its .ele (and possibly */ -/* .poly) file. Used when the -r switch is used. */ -/* */ -/* Reads an .ele file and reconstructs the original mesh. If the -p switch */ -/* is used, this procedure will also read a .poly file and reconstruct the */ -/* subsegments of the original mesh. If the -a switch is used, this */ -/* procedure will also read an .area file and set a maximum area constraint */ -/* on each triangle. */ -/* */ -/* Vertices that are not corners of triangles, such as nodes on edges of */ -/* subparametric elements, are discarded. */ -/* */ -/* This routine finds the adjacencies between triangles (and subsegments) */ -/* by forming one stack of triangles for each vertex. Each triangle is on */ -/* three different stacks simultaneously. Each triangle's subsegment */ -/* pointers are used to link the items in each stack. This memory-saving */ -/* feature makes the code harder to read. The most important thing to keep */ -/* in mind is that each triangle is removed from a stack precisely when */ -/* the corresponding pointer is adjusted to refer to a subsegment rather */ -/* than the next triangle of the stack. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -int reconstruct(struct mesh *m, struct behavior *b, int *trianglelist, - REAL *triangleattriblist, REAL *trianglearealist, - int elements, int corners, int attribs, - int *segmentlist,int *segmentmarkerlist, int numberofsegments) -#else /* not ANSI_DECLARATORS */ -int reconstruct(m, b, trianglelist, triangleattriblist, trianglearealist, - elements, corners, attribs, segmentlist, segmentmarkerlist, - numberofsegments) -struct mesh *m; -struct behavior *b; -int *trianglelist; -REAL *triangleattriblist; -REAL *trianglearealist; -int elements; -int corners; -int attribs; -int *segmentlist; -int *segmentmarkerlist; -int numberofsegments; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -long reconstruct(struct mesh *m, struct behavior *b, char *elefilename, - char *areafilename, char *polyfilename, FILE *polyfile) -#else /* not ANSI_DECLARATORS */ -long reconstruct(m, b, elefilename, areafilename, polyfilename, polyfile) -struct mesh *m; -struct behavior *b; -char *elefilename; -char *areafilename; -char *polyfilename; -FILE *polyfile; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - int vertexindex; - int attribindex; -#else /* not TRILIBRARY */ - FILE *elefile; - FILE *areafile; - char inputline[INPUTLINESIZE]; - char *stringptr; - int areaelements; -#endif /* not TRILIBRARY */ - struct otri triangleloop; - struct otri triangleleft; - struct otri checktri; - struct otri checkleft; - struct otri checkneighbor; - struct osub subsegloop; - triangle *vertexarray; - triangle *prevlink; - triangle nexttri; - vertex tdest, tapex; - vertex checkdest, checkapex; - vertex shorg; - vertex killvertex; - REAL area; - int corner[3]; - int end[2]; - int killvertexindex; - int incorners; - int segmentmarkers; - int boundmarker; - int aroundvertex; - long hullsize; - int notfound; - long elementnumber, segmentnumber; - int i, j; - triangle ptr; /* Temporary variable used by sym(). */ - -#ifdef TRILIBRARY - m->inelements = elements; - incorners = corners; - if (incorners < 3) { - printf("Error: Triangles must have at least 3 vertices.\n"); - exit(1); - } - m->eextras = attribs; -#else /* not TRILIBRARY */ - /* Read the triangles from an .ele file. */ - if (!b->quiet) { - printf("Opening %s.\n", elefilename); - } - elefile = fopen(elefilename, "r"); - if (elefile == (FILE *) NULL) { - printf(" Error: Cannot access file %s.\n", elefilename); - exit(1); - } - /* Read number of triangles, number of vertices per triangle, and */ - /* number of triangle attributes from .ele file. */ - stringptr = readline(inputline, elefile, elefilename); - m->inelements = (int) strtol(stringptr, &stringptr, 0); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - incorners = 3; - } else { - incorners = (int) strtol(stringptr, &stringptr, 0); - if (incorners < 3) { - printf("Error: Triangles in %s must have at least 3 vertices.\n", - elefilename); - exit(1); - } - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - m->eextras = 0; - } else { - m->eextras = (int) strtol(stringptr, &stringptr, 0); - } -#endif /* not TRILIBRARY */ - - initializetrisubpools(m, b); - - /* Create the triangles. */ - for (elementnumber = 1; elementnumber <= m->inelements; elementnumber++) { - maketriangle(m, b, &triangleloop); - /* Mark the triangle as living. */ - triangleloop.tri[3] = (triangle) triangleloop.tri; - } - - if (b->poly) { -#ifdef TRILIBRARY - m->insegments = numberofsegments; - segmentmarkers = segmentmarkerlist != (int *) NULL; -#else /* not TRILIBRARY */ - /* Read number of segments and number of segment */ - /* boundary markers from .poly file. */ - stringptr = readline(inputline, polyfile, b->inpolyfilename); - m->insegments = (int) strtol(stringptr, &stringptr, 0); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - segmentmarkers = 0; - } else { - segmentmarkers = (int) strtol(stringptr, &stringptr, 0); - } -#endif /* not TRILIBRARY */ - - /* Create the subsegments. */ - for (segmentnumber = 1; segmentnumber <= m->insegments; segmentnumber++) { - makesubseg(m, &subsegloop); - /* Mark the subsegment as living. */ - subsegloop.ss[2] = (subseg) subsegloop.ss; - } - } - -#ifdef TRILIBRARY - vertexindex = 0; - attribindex = 0; -#else /* not TRILIBRARY */ - if (b->vararea) { - /* Open an .area file, check for consistency with the .ele file. */ - if (!b->quiet) { - printf("Opening %s.\n", areafilename); - } - areafile = fopen(areafilename, "r"); - if (areafile == (FILE *) NULL) { - printf(" Error: Cannot access file %s.\n", areafilename); - exit(1); - } - stringptr = readline(inputline, areafile, areafilename); - areaelements = (int) strtol(stringptr, &stringptr, 0); - if (areaelements != m->inelements) { - printf("Error: %s and %s disagree on number of triangles.\n", - elefilename, areafilename); - exit(1); - } - } -#endif /* not TRILIBRARY */ - - if (!b->quiet) { - printf("Reconstructing mesh.\n"); - } - /* Allocate a temporary array that maps each vertex to some adjacent */ - /* triangle. I took care to allocate all the permanent memory for */ - /* triangles and subsegments first. */ - vertexarray = (triangle *) - trimalloc(m->vertices.items * (int) sizeof(triangle)); - /* Each vertex is initially unrepresented. */ - for (i = 0; i < m->vertices.items; i++) { - vertexarray[i] = (triangle) m->dummytri; - } - - if (b->verbose) { - printf(" Assembling triangles.\n"); - } - /* Read the triangles from the .ele file, and link */ - /* together those that share an edge. */ - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - elementnumber = b->firstnumber; - while (triangleloop.tri != (triangle *) NULL) { -#ifdef TRILIBRARY - /* Copy the triangle's three corners. */ - for (j = 0; j < 3; j++) { - corner[j] = trianglelist[vertexindex++]; - if ((corner[j] < b->firstnumber) || - (corner[j] >= b->firstnumber + m->invertices)) { - printf("Error: Triangle %ld has an invalid vertex index.\n", - elementnumber); - exit(1); - } - } -#else /* not TRILIBRARY */ - /* Read triangle number and the triangle's three corners. */ - stringptr = readline(inputline, elefile, elefilename); - for (j = 0; j < 3; j++) { - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Triangle %ld is missing vertex %d in %s.\n", - elementnumber, j + 1, elefilename); - exit(1); - } else { - corner[j] = (int) strtol(stringptr, &stringptr, 0); - if ((corner[j] < b->firstnumber) || - (corner[j] >= b->firstnumber + m->invertices)) { - printf("Error: Triangle %ld has an invalid vertex index.\n", - elementnumber); - exit(1); - } - } - } -#endif /* not TRILIBRARY */ - - /* Find out about (and throw away) extra nodes. */ - for (j = 3; j < incorners; j++) { -#ifdef TRILIBRARY - killvertexindex = trianglelist[vertexindex++]; -#else /* not TRILIBRARY */ - stringptr = findfield(stringptr); - if (*stringptr != '\0') { - killvertexindex = (int) strtol(stringptr, &stringptr, 0); -#endif /* not TRILIBRARY */ - if ((killvertexindex >= b->firstnumber) && - (killvertexindex < b->firstnumber + m->invertices)) { - /* Delete the non-corner vertex if it's not already deleted. */ - killvertex = getvertex(m, b, killvertexindex); - if (vertextype(killvertex) != DEADVERTEX) { - vertexdealloc(m, killvertex); - } - } -#ifndef TRILIBRARY - } -#endif /* not TRILIBRARY */ - } - - /* Read the triangle's attributes. */ - for (j = 0; j < m->eextras; j++) { -#ifdef TRILIBRARY - setelemattribute(triangleloop, j, triangleattriblist[attribindex++]); -#else /* not TRILIBRARY */ - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - setelemattribute(triangleloop, j, 0); - } else { - setelemattribute(triangleloop, j, - (REAL) strtod(stringptr, &stringptr)); - } -#endif /* not TRILIBRARY */ - } - - if (b->vararea) { -#ifdef TRILIBRARY - area = trianglearealist[elementnumber - b->firstnumber]; -#else /* not TRILIBRARY */ - /* Read an area constraint from the .area file. */ - stringptr = readline(inputline, areafile, areafilename); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - area = -1.0; /* No constraint on this triangle. */ - } else { - area = (REAL) strtod(stringptr, &stringptr); - } -#endif /* not TRILIBRARY */ - setareabound(triangleloop, area); - } - - /* Set the triangle's vertices. */ - triangleloop.orient = 0; - setorg(triangleloop, getvertex(m, b, corner[0])); - setdest(triangleloop, getvertex(m, b, corner[1])); - setapex(triangleloop, getvertex(m, b, corner[2])); - /* Try linking the triangle to others that share these vertices. */ - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - /* Take the number for the origin of triangleloop. */ - aroundvertex = corner[triangleloop.orient]; - /* Look for other triangles having this vertex. */ - nexttri = vertexarray[aroundvertex - b->firstnumber]; - /* Link the current triangle to the next one in the stack. */ - triangleloop.tri[6 + triangleloop.orient] = nexttri; - /* Push the current triangle onto the stack. */ - vertexarray[aroundvertex - b->firstnumber] = encode(triangleloop); - decode(nexttri, checktri); - if (checktri.tri != m->dummytri) { - dest(triangleloop, tdest); - apex(triangleloop, tapex); - /* Look for other triangles that share an edge. */ - do { - dest(checktri, checkdest); - apex(checktri, checkapex); - if (tapex == checkdest) { - /* The two triangles share an edge; bond them together. */ - lprev(triangleloop, triangleleft); - bond(triangleleft, checktri); - } - if (tdest == checkapex) { - /* The two triangles share an edge; bond them together. */ - lprev(checktri, checkleft); - bond(triangleloop, checkleft); - } - /* Find the next triangle in the stack. */ - nexttri = checktri.tri[6 + checktri.orient]; - decode(nexttri, checktri); - } while (checktri.tri != m->dummytri); - } - } - triangleloop.tri = triangletraverse(m); - elementnumber++; - } - -#ifdef TRILIBRARY - vertexindex = 0; -#else /* not TRILIBRARY */ - fclose(elefile); - if (b->vararea) { - fclose(areafile); - } -#endif /* not TRILIBRARY */ - - hullsize = 0; /* Prepare to count the boundary edges. */ - if (b->poly) { - if (b->verbose) { - printf(" Marking segments in triangulation.\n"); - } - /* Read the segments from the .poly file, and link them */ - /* to their neighboring triangles. */ - boundmarker = 0; - traversalinit(&m->subsegs); - subsegloop.ss = subsegtraverse(m); - segmentnumber = b->firstnumber; - while (subsegloop.ss != (subseg *) NULL) { -#ifdef TRILIBRARY - end[0] = segmentlist[vertexindex++]; - end[1] = segmentlist[vertexindex++]; - if (segmentmarkers) { - boundmarker = segmentmarkerlist[segmentnumber - b->firstnumber]; - } -#else /* not TRILIBRARY */ - /* Read the endpoints of each segment, and possibly a boundary marker. */ - stringptr = readline(inputline, polyfile, b->inpolyfilename); - /* Skip the first (segment number) field. */ - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Segment %ld has no endpoints in %s.\n", segmentnumber, - polyfilename); - exit(1); - } else { - end[0] = (int) strtol(stringptr, &stringptr, 0); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Segment %ld is missing its second endpoint in %s.\n", - segmentnumber, polyfilename); - exit(1); - } else { - end[1] = (int) strtol(stringptr, &stringptr, 0); - } - if (segmentmarkers) { - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - boundmarker = 0; - } else { - boundmarker = (int) strtol(stringptr, &stringptr, 0); - } - } -#endif /* not TRILIBRARY */ - for (j = 0; j < 2; j++) { - if ((end[j] < b->firstnumber) || - (end[j] >= b->firstnumber + m->invertices)) { - printf("Error: Segment %ld has an invalid vertex index.\n", - segmentnumber); - exit(1); - } - } - - /* set the subsegment's vertices. */ - subsegloop.ssorient = 0; - setsorg(subsegloop, getvertex(m, b, end[0])); - setsdest(subsegloop, getvertex(m, b, end[1])); - setmark(subsegloop, boundmarker); - /* Try linking the subsegment to triangles that share these vertices. */ - for (subsegloop.ssorient = 0; subsegloop.ssorient < 2; - subsegloop.ssorient++) { - /* Take the number for the destination of subsegloop. */ - aroundvertex = end[1 - subsegloop.ssorient]; - /* Look for triangles having this vertex. */ - prevlink = &vertexarray[aroundvertex - b->firstnumber]; - nexttri = vertexarray[aroundvertex - b->firstnumber]; - decode(nexttri, checktri); - sorg(subsegloop, shorg); - notfound = 1; - /* Look for triangles having this edge. Note that I'm only */ - /* comparing each triangle's destination with the subsegment; */ - /* each triangle's apex is handled through a different vertex. */ - /* Because each triangle appears on three vertices' lists, each */ - /* occurrence of a triangle on a list can (and does) represent */ - /* an edge. In this way, most edges are represented twice, and */ - /* every triangle-subsegment bond is represented once. */ - while (notfound && (checktri.tri != m->dummytri)) { - dest(checktri, checkdest); - if (shorg == checkdest) { - /* We have a match. Remove this triangle from the list. */ - *prevlink = checktri.tri[6 + checktri.orient]; - /* Bond the subsegment to the triangle. */ - tsbond(checktri, subsegloop); - /* Check if this is a boundary edge. */ - sym(checktri, checkneighbor); - if (checkneighbor.tri == m->dummytri) { - /* The next line doesn't insert a subsegment (because there's */ - /* already one there), but it sets the boundary markers of */ - /* the existing subsegment and its vertices. */ - insertsubseg(m, b, &checktri, 1); - hullsize++; - } - notfound = 0; - } - /* Find the next triangle in the stack. */ - prevlink = &checktri.tri[6 + checktri.orient]; - nexttri = checktri.tri[6 + checktri.orient]; - decode(nexttri, checktri); - } - } - subsegloop.ss = subsegtraverse(m); - segmentnumber++; - } - } - - /* Mark the remaining edges as not being attached to any subsegment. */ - /* Also, count the (yet uncounted) boundary edges. */ - for (i = 0; i < m->vertices.items; i++) { - /* Search the stack of triangles adjacent to a vertex. */ - nexttri = vertexarray[i]; - decode(nexttri, checktri); - while (checktri.tri != m->dummytri) { - /* Find the next triangle in the stack before this */ - /* information gets overwritten. */ - nexttri = checktri.tri[6 + checktri.orient]; - /* No adjacent subsegment. (This overwrites the stack info.) */ - tsdissolve(checktri); - sym(checktri, checkneighbor); - if (checkneighbor.tri == m->dummytri) { - insertsubseg(m, b, &checktri, 1); - hullsize++; - } - decode(nexttri, checktri); - } - } - - trifree((VOID *) vertexarray); - return hullsize; -} - -#endif /* not CDT_ONLY */ - -/** **/ -/** **/ -/********* General mesh construction routines end here *********/ - -/********* Segment insertion begins here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* finddirection() Find the first triangle on the path from one point */ -/* to another. */ -/* */ -/* Finds the triangle that intersects a line segment drawn from the */ -/* origin of `searchtri' to the point `searchpoint', and returns the result */ -/* in `searchtri'. The origin of `searchtri' does not change, even though */ -/* the triangle returned may differ from the one passed in. This routine */ -/* is used to find the direction to move in to get from one point to */ -/* another. */ -/* */ -/* The return value notes whether the destination or apex of the found */ -/* triangle is collinear with the two points in question. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -enum finddirectionresult finddirection(struct mesh *m, struct behavior *b, - struct otri *searchtri, - vertex searchpoint) -#else /* not ANSI_DECLARATORS */ -enum finddirectionresult finddirection(m, b, searchtri, searchpoint) -struct mesh *m; -struct behavior *b; -struct otri *searchtri; -vertex searchpoint; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri checktri; - vertex startvertex; - vertex leftvertex, rightvertex; - REAL leftccw, rightccw; - int leftflag, rightflag; - triangle ptr; /* Temporary variable used by onext() and oprev(). */ - - org(*searchtri, startvertex); - dest(*searchtri, rightvertex); - apex(*searchtri, leftvertex); - /* Is `searchpoint' to the left? */ - leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex); - leftflag = leftccw > 0.0; - /* Is `searchpoint' to the right? */ - rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex); - rightflag = rightccw > 0.0; - if (leftflag && rightflag) { - /* `searchtri' faces directly away from `searchpoint'. We could go left */ - /* or right. Ask whether it's a triangle or a boundary on the left. */ - onext(*searchtri, checktri); - if (checktri.tri == m->dummytri) { - leftflag = 0; - } else { - rightflag = 0; - } - } - while (leftflag) { - /* Turn left until satisfied. */ - onextself(*searchtri); - if (searchtri->tri == m->dummytri) { - printf("Internal error in finddirection(): Unable to find a\n"); - printf(" triangle leading from (%.12g, %.12g) to", startvertex[0], - startvertex[1]); - printf(" (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]); - internalerror(); - } - apex(*searchtri, leftvertex); - rightccw = leftccw; - leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex); - leftflag = leftccw > 0.0; - } - while (rightflag) { - /* Turn right until satisfied. */ - oprevself(*searchtri); - if (searchtri->tri == m->dummytri) { - printf("Internal error in finddirection(): Unable to find a\n"); - printf(" triangle leading from (%.12g, %.12g) to", startvertex[0], - startvertex[1]); - printf(" (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]); - internalerror(); - } - dest(*searchtri, rightvertex); - leftccw = rightccw; - rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex); - rightflag = rightccw > 0.0; - } - if (leftccw == 0.0) { - return LEFTCOLLINEAR; - } else if (rightccw == 0.0) { - return RIGHTCOLLINEAR; - } else { - return WITHIN; - } -} - -/*****************************************************************************/ -/* */ -/* segmentintersection() Find the intersection of an existing segment */ -/* and a segment that is being inserted. Insert */ -/* a vertex at the intersection, splitting an */ -/* existing subsegment. */ -/* */ -/* The segment being inserted connects the apex of splittri to endpoint2. */ -/* splitsubseg is the subsegment being split, and MUST adjoin splittri. */ -/* Hence, endpoints of the subsegment being split are the origin and */ -/* destination of splittri. */ -/* */ -/* On completion, splittri is a handle having the newly inserted */ -/* intersection point as its origin, and endpoint1 as its destination. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void segmentintersection(struct mesh *m, struct behavior *b, - struct otri *splittri, struct osub *splitsubseg, - vertex endpoint2) -#else /* not ANSI_DECLARATORS */ -void segmentintersection(m, b, splittri, splitsubseg, endpoint2) -struct mesh *m; -struct behavior *b; -struct otri *splittri; -struct osub *splitsubseg; -vertex endpoint2; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex endpoint1; - vertex torg, tdest; - vertex leftvertex, rightvertex; - vertex newvertex; - enum insertvertexresult success; - enum finddirectionresult collinear; - REAL ex, ey; - REAL tx, ty; - REAL etx, ety; - REAL split, denom; - int i; - triangle ptr; /* Temporary variable used by onext(). */ - - /* Find the other three segment endpoints. */ - apex(*splittri, endpoint1); - org(*splittri, torg); - dest(*splittri, tdest); - /* Segment intersection formulae; see the Antonio reference. */ - tx = tdest[0] - torg[0]; - ty = tdest[1] - torg[1]; - ex = endpoint2[0] - endpoint1[0]; - ey = endpoint2[1] - endpoint1[1]; - etx = torg[0] - endpoint2[0]; - ety = torg[1] - endpoint2[1]; - denom = ty * ex - tx * ey; - if (denom == 0.0) { - printf("Internal error in segmentintersection():"); - printf(" Attempt to find intersection of parallel segments.\n"); - internalerror(); - } - split = (ey * etx - ex * ety) / denom; - /* Create the new vertex. */ - newvertex = (vertex) poolalloc(&m->vertices); - /* Interpolate its coordinate and attributes. */ - for (i = 0; i < 2 + m->nextras; i++) { - newvertex[i] = torg[i] + split * (tdest[i] - torg[i]); - } - setvertexmark(newvertex, mark(*splitsubseg)); - setvertextype(newvertex, INPUTVERTEX); - if (b->verbose > 1) { - printf( - " Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n", - torg[0], torg[1], tdest[0], tdest[1], newvertex[0], newvertex[1]); - } - /* Insert the intersection vertex. This should always succeed. */ - success = insertvertex(m, b, newvertex, splittri, splitsubseg, 0, 0, 0.0); - if (success != SUCCESSFULVERTEX) { - printf("Internal error in segmentintersection():\n"); - printf(" Failure to split a segment.\n"); - internalerror(); - } - if (m->steinerleft > 0) { - m->steinerleft--; - } - /* Inserting the vertex may have caused edge flips. We wish to rediscover */ - /* the edge connecting endpoint1 to the new intersection vertex. */ - collinear = finddirection(m, b, splittri, endpoint1); - dest(*splittri, rightvertex); - apex(*splittri, leftvertex); - if ((leftvertex[0] == endpoint1[0]) && (leftvertex[1] == endpoint1[1])) { - onextself(*splittri); - } else if ((rightvertex[0] != endpoint1[0]) || - (rightvertex[1] != endpoint1[1])) { - printf("Internal error in segmentintersection():\n"); - printf(" Topological inconsistency after splitting a segment.\n"); - internalerror(); - } - /* `splittri' should have destination endpoint1. */ -} - -/*****************************************************************************/ -/* */ -/* scoutsegment() Scout the first triangle on the path from one endpoint */ -/* to another, and check for completion (reaching the */ -/* second endpoint), a collinear vertex, or the */ -/* intersection of two segments. */ -/* */ -/* Returns one if the entire segment is successfully inserted, and zero if */ -/* the job must be finished by conformingedge() or constrainededge(). */ -/* */ -/* If the first triangle on the path has the second endpoint as its */ -/* destination or apex, a subsegment is inserted and the job is done. */ -/* */ -/* If the first triangle on the path has a destination or apex that lies on */ -/* the segment, a subsegment is inserted connecting the first endpoint to */ -/* the collinear vertex, and the search is continued from the collinear */ -/* vertex. */ -/* */ -/* If the first triangle on the path has a subsegment opposite its origin, */ -/* then there is a segment that intersects the segment being inserted. */ -/* Their intersection vertex is inserted, splitting the subsegment. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -int scoutsegment(struct mesh *m, struct behavior *b, struct otri *searchtri, - vertex endpoint2, int newmark) -#else /* not ANSI_DECLARATORS */ -int scoutsegment(m, b, searchtri, endpoint2, newmark) -struct mesh *m; -struct behavior *b; -struct otri *searchtri; -vertex endpoint2; -int newmark; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri crosstri; - struct osub crosssubseg; - vertex leftvertex, rightvertex; - enum finddirectionresult collinear; - subseg sptr; /* Temporary variable used by tspivot(). */ - - collinear = finddirection(m, b, searchtri, endpoint2); - dest(*searchtri, rightvertex); - apex(*searchtri, leftvertex); - if (((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) || - ((rightvertex[0] == endpoint2[0]) && (rightvertex[1] == endpoint2[1]))) { - /* The segment is already an edge in the mesh. */ - if ((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) { - lprevself(*searchtri); - } - /* Insert a subsegment, if there isn't already one there. */ - insertsubseg(m, b, searchtri, newmark); - return 1; - } else if (collinear == LEFTCOLLINEAR) { - /* We've collided with a vertex between the segment's endpoints. */ - /* Make the collinear vertex be the triangle's origin. */ - lprevself(*searchtri); - insertsubseg(m, b, searchtri, newmark); - /* Insert the remainder of the segment. */ - return scoutsegment(m, b, searchtri, endpoint2, newmark); - } else if (collinear == RIGHTCOLLINEAR) { - /* We've collided with a vertex between the segment's endpoints. */ - insertsubseg(m, b, searchtri, newmark); - /* Make the collinear vertex be the triangle's origin. */ - lnextself(*searchtri); - /* Insert the remainder of the segment. */ - return scoutsegment(m, b, searchtri, endpoint2, newmark); - } else { - lnext(*searchtri, crosstri); - tspivot(crosstri, crosssubseg); - /* Check for a crossing segment. */ - if (crosssubseg.ss == m->dummysub) { - return 0; - } else { - /* Insert a vertex at the intersection. */ - segmentintersection(m, b, &crosstri, &crosssubseg, endpoint2); - otricopy(crosstri, *searchtri); - insertsubseg(m, b, searchtri, newmark); - /* Insert the remainder of the segment. */ - return scoutsegment(m, b, searchtri, endpoint2, newmark); - } - } -} - -/*****************************************************************************/ -/* */ -/* conformingedge() Force a segment into a conforming Delaunay */ -/* triangulation by inserting a vertex at its midpoint, */ -/* and recursively forcing in the two half-segments if */ -/* necessary. */ -/* */ -/* Generates a sequence of subsegments connecting `endpoint1' to */ -/* `endpoint2'. `newmark' is the boundary marker of the segment, assigned */ -/* to each new splitting vertex and subsegment. */ -/* */ -/* Note that conformingedge() does not always maintain the conforming */ -/* Delaunay property. Once inserted, segments are locked into place; */ -/* vertices inserted later (to force other segments in) may render these */ -/* fixed segments non-Delaunay. The conforming Delaunay property will be */ -/* restored by enforcequality() by splitting encroached subsegments. */ -/* */ -/*****************************************************************************/ - -#ifndef REDUCED -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void conformingedge(struct mesh *m, struct behavior *b, - vertex endpoint1, vertex endpoint2, int newmark) -#else /* not ANSI_DECLARATORS */ -void conformingedge(m, b, endpoint1, endpoint2, newmark) -struct mesh *m; -struct behavior *b; -vertex endpoint1; -vertex endpoint2; -int newmark; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri searchtri1, searchtri2; - struct osub brokensubseg; - vertex newvertex; - vertex midvertex1, midvertex2; - enum insertvertexresult success; - int i; - subseg sptr; /* Temporary variable used by tspivot(). */ - - if (b->verbose > 2) { - printf("Forcing segment into triangulation by recursive splitting:\n"); - printf(" (%.12g, %.12g) (%.12g, %.12g)\n", endpoint1[0], endpoint1[1], - endpoint2[0], endpoint2[1]); - } - /* Create a new vertex to insert in the middle of the segment. */ - newvertex = (vertex) poolalloc(&m->vertices); - /* Interpolate coordinates and attributes. */ - for (i = 0; i < 2 + m->nextras; i++) { - newvertex[i] = 0.5 * (endpoint1[i] + endpoint2[i]); - } - setvertexmark(newvertex, newmark); - setvertextype(newvertex, SEGMENTVERTEX); - /* No known triangle to search from. */ - searchtri1.tri = m->dummytri; - /* Attempt to insert the new vertex. */ - success = insertvertex(m, b, newvertex, &searchtri1, (struct osub *) NULL, - 0, 0, 0.0); - if (success == DUPLICATEVERTEX) { - if (b->verbose > 2) { - printf(" Segment intersects existing vertex (%.12g, %.12g).\n", - newvertex[0], newvertex[1]); - } - /* Use the vertex that's already there. */ - vertexdealloc(m, newvertex); - org(searchtri1, newvertex); - } else { - if (success == VIOLATINGVERTEX) { - if (b->verbose > 2) { - printf(" Two segments intersect at (%.12g, %.12g).\n", - newvertex[0], newvertex[1]); - } - /* By fluke, we've landed right on another segment. Split it. */ - tspivot(searchtri1, brokensubseg); - success = insertvertex(m, b, newvertex, &searchtri1, &brokensubseg, - 0, 0, 0.0); - if (success != SUCCESSFULVERTEX) { - printf("Internal error in conformingedge():\n"); - printf(" Failure to split a segment.\n"); - internalerror(); - } - } - /* The vertex has been inserted successfully. */ - if (m->steinerleft > 0) { - m->steinerleft--; - } - } - otricopy(searchtri1, searchtri2); - /* `searchtri1' and `searchtri2' are fastened at their origins to */ - /* `newvertex', and will be directed toward `endpoint1' and `endpoint2' */ - /* respectively. First, we must get `searchtri2' out of the way so it */ - /* won't be invalidated during the insertion of the first half of the */ - /* segment. */ - finddirection(m, b, &searchtri2, endpoint2); - if (!scoutsegment(m, b, &searchtri1, endpoint1, newmark)) { - /* The origin of searchtri1 may have changed if a collision with an */ - /* intervening vertex on the segment occurred. */ - org(searchtri1, midvertex1); - conformingedge(m, b, midvertex1, endpoint1, newmark); - } - if (!scoutsegment(m, b, &searchtri2, endpoint2, newmark)) { - /* The origin of searchtri2 may have changed if a collision with an */ - /* intervening vertex on the segment occurred. */ - org(searchtri2, midvertex2); - conformingedge(m, b, midvertex2, endpoint2, newmark); - } -} - -#endif /* not CDT_ONLY */ -#endif /* not REDUCED */ - -/*****************************************************************************/ -/* */ -/* delaunayfixup() Enforce the Delaunay condition at an edge, fanning out */ -/* recursively from an existing vertex. Pay special */ -/* attention to stacking inverted triangles. */ -/* */ -/* This is a support routine for inserting segments into a constrained */ -/* Delaunay triangulation. */ -/* */ -/* The origin of fixuptri is treated as if it has just been inserted, and */ -/* the local Delaunay condition needs to be enforced. It is only enforced */ -/* in one sector, however, that being the angular range defined by */ -/* fixuptri. */ -/* */ -/* This routine also needs to make decisions regarding the "stacking" of */ -/* triangles. (Read the description of constrainededge() below before */ -/* reading on here, so you understand the algorithm.) If the position of */ -/* the new vertex (the origin of fixuptri) indicates that the vertex before */ -/* it on the polygon is a reflex vertex, then "stack" the triangle by */ -/* doing nothing. (fixuptri is an inverted triangle, which is how stacked */ -/* triangles are identified.) */ -/* */ -/* Otherwise, check whether the vertex before that was a reflex vertex. */ -/* If so, perform an edge flip, thereby eliminating an inverted triangle */ -/* (popping it off the stack). The edge flip may result in the creation */ -/* of a new inverted triangle, depending on whether or not the new vertex */ -/* is visible to the vertex three edges behind on the polygon. */ -/* */ -/* If neither of the two vertices behind the new vertex are reflex */ -/* vertices, fixuptri and fartri, the triangle opposite it, are not */ -/* inverted; hence, ensure that the edge between them is locally Delaunay. */ -/* */ -/* `leftside' indicates whether or not fixuptri is to the left of the */ -/* segment being inserted. (Imagine that the segment is pointing up from */ -/* endpoint1 to endpoint2.) */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void delaunayfixup(struct mesh *m, struct behavior *b, - struct otri *fixuptri, int leftside) -#else /* not ANSI_DECLARATORS */ -void delaunayfixup(m, b, fixuptri, leftside) -struct mesh *m; -struct behavior *b; -struct otri *fixuptri; -int leftside; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri neartri; - struct otri fartri; - struct osub faredge; - vertex nearvertex, leftvertex, rightvertex, farvertex; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - lnext(*fixuptri, neartri); - sym(neartri, fartri); - /* Check if the edge opposite the origin of fixuptri can be flipped. */ - if (fartri.tri == m->dummytri) { - return; - } - tspivot(neartri, faredge); - if (faredge.ss != m->dummysub) { - return; - } - /* Find all the relevant vertices. */ - apex(neartri, nearvertex); - org(neartri, leftvertex); - dest(neartri, rightvertex); - apex(fartri, farvertex); - /* Check whether the previous polygon vertex is a reflex vertex. */ - if (leftside) { - if (counterclockwise(m, b, nearvertex, leftvertex, farvertex) <= 0.0) { - /* leftvertex is a reflex vertex too. Nothing can */ - /* be done until a convex section is found. */ - return; - } - } else { - if (counterclockwise(m, b, farvertex, rightvertex, nearvertex) <= 0.0) { - /* rightvertex is a reflex vertex too. Nothing can */ - /* be done until a convex section is found. */ - return; - } - } - if (counterclockwise(m, b, rightvertex, leftvertex, farvertex) > 0.0) { - /* fartri is not an inverted triangle, and farvertex is not a reflex */ - /* vertex. As there are no reflex vertices, fixuptri isn't an */ - /* inverted triangle, either. Hence, test the edge between the */ - /* triangles to ensure it is locally Delaunay. */ - if (incircle(m, b, leftvertex, farvertex, rightvertex, nearvertex) <= - 0.0) { - return; - } - /* Not locally Delaunay; go on to an edge flip. */ - } /* else fartri is inverted; remove it from the stack by flipping. */ - flip(m, b, &neartri); - lprevself(*fixuptri); /* Restore the origin of fixuptri after the flip. */ - /* Recursively process the two triangles that result from the flip. */ - delaunayfixup(m, b, fixuptri, leftside); - delaunayfixup(m, b, &fartri, leftside); -} - -/*****************************************************************************/ -/* */ -/* constrainededge() Force a segment into a constrained Delaunay */ -/* triangulation by deleting the triangles it */ -/* intersects, and triangulating the polygons that */ -/* form on each side of it. */ -/* */ -/* Generates a single subsegment connecting `endpoint1' to `endpoint2'. */ -/* The triangle `starttri' has `endpoint1' as its origin. `newmark' is the */ -/* boundary marker of the segment. */ -/* */ -/* To insert a segment, every triangle whose interior intersects the */ -/* segment is deleted. The union of these deleted triangles is a polygon */ -/* (which is not necessarily monotone, but is close enough), which is */ -/* divided into two polygons by the new segment. This routine's task is */ -/* to generate the Delaunay triangulation of these two polygons. */ -/* */ -/* You might think of this routine's behavior as a two-step process. The */ -/* first step is to walk from endpoint1 to endpoint2, flipping each edge */ -/* encountered. This step creates a fan of edges connected to endpoint1, */ -/* including the desired edge to endpoint2. The second step enforces the */ -/* Delaunay condition on each side of the segment in an incremental manner: */ -/* proceeding along the polygon from endpoint1 to endpoint2 (this is done */ -/* independently on each side of the segment), each vertex is "enforced" */ -/* as if it had just been inserted, but affecting only the previous */ -/* vertices. The result is the same as if the vertices had been inserted */ -/* in the order they appear on the polygon, so the result is Delaunay. */ -/* */ -/* In truth, constrainededge() interleaves these two steps. The procedure */ -/* walks from endpoint1 to endpoint2, and each time an edge is encountered */ -/* and flipped, the newly exposed vertex (at the far end of the flipped */ -/* edge) is "enforced" upon the previously flipped edges, usually affecting */ -/* only one side of the polygon (depending upon which side of the segment */ -/* the vertex falls on). */ -/* */ -/* The algorithm is complicated by the need to handle polygons that are not */ -/* convex. Although the polygon is not necessarily monotone, it can be */ -/* triangulated in a manner similar to the stack-based algorithms for */ -/* monotone polygons. For each reflex vertex (local concavity) of the */ -/* polygon, there will be an inverted triangle formed by one of the edge */ -/* flips. (An inverted triangle is one with negative area - that is, its */ -/* vertices are arranged in clockwise order - and is best thought of as a */ -/* wrinkle in the fabric of the mesh.) Each inverted triangle can be */ -/* thought of as a reflex vertex pushed on the stack, waiting to be fixed */ -/* later. */ -/* */ -/* A reflex vertex is popped from the stack when a vertex is inserted that */ -/* is visible to the reflex vertex. (However, if the vertex behind the */ -/* reflex vertex is not visible to the reflex vertex, a new inverted */ -/* triangle will take its place on the stack.) These details are handled */ -/* by the delaunayfixup() routine above. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void constrainededge(struct mesh *m, struct behavior *b, - struct otri *starttri, vertex endpoint2, int newmark) -#else /* not ANSI_DECLARATORS */ -void constrainededge(m, b, starttri, endpoint2, newmark) -struct mesh *m; -struct behavior *b; -struct otri *starttri; -vertex endpoint2; -int newmark; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri fixuptri, fixuptri2; - struct osub crosssubseg; - vertex endpoint1; - vertex farvertex; - REAL area; - int collision; - int done; - triangle ptr; /* Temporary variable used by sym() and oprev(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - org(*starttri, endpoint1); - lnext(*starttri, fixuptri); - flip(m, b, &fixuptri); - /* `collision' indicates whether we have found a vertex directly */ - /* between endpoint1 and endpoint2. */ - collision = 0; - done = 0; - do { - org(fixuptri, farvertex); - /* `farvertex' is the extreme point of the polygon we are "digging" */ - /* to get from endpoint1 to endpoint2. */ - if ((farvertex[0] == endpoint2[0]) && (farvertex[1] == endpoint2[1])) { - oprev(fixuptri, fixuptri2); - /* Enforce the Delaunay condition around endpoint2. */ - delaunayfixup(m, b, &fixuptri, 0); - delaunayfixup(m, b, &fixuptri2, 1); - done = 1; - } else { - /* Check whether farvertex is to the left or right of the segment */ - /* being inserted, to decide which edge of fixuptri to dig */ - /* through next. */ - area = counterclockwise(m, b, endpoint1, endpoint2, farvertex); - if (area == 0.0) { - /* We've collided with a vertex between endpoint1 and endpoint2. */ - collision = 1; - oprev(fixuptri, fixuptri2); - /* Enforce the Delaunay condition around farvertex. */ - delaunayfixup(m, b, &fixuptri, 0); - delaunayfixup(m, b, &fixuptri2, 1); - done = 1; - } else { - if (area > 0.0) { /* farvertex is to the left of the segment. */ - oprev(fixuptri, fixuptri2); - /* Enforce the Delaunay condition around farvertex, on the */ - /* left side of the segment only. */ - delaunayfixup(m, b, &fixuptri2, 1); - /* Flip the edge that crosses the segment. After the edge is */ - /* flipped, one of its endpoints is the fan vertex, and the */ - /* destination of fixuptri is the fan vertex. */ - lprevself(fixuptri); - } else { /* farvertex is to the right of the segment. */ - delaunayfixup(m, b, &fixuptri, 0); - /* Flip the edge that crosses the segment. After the edge is */ - /* flipped, one of its endpoints is the fan vertex, and the */ - /* destination of fixuptri is the fan vertex. */ - oprevself(fixuptri); - } - /* Check for two intersecting segments. */ - tspivot(fixuptri, crosssubseg); - if (crosssubseg.ss == m->dummysub) { - flip(m, b, &fixuptri); /* May create inverted triangle at left. */ - } else { - /* We've collided with a segment between endpoint1 and endpoint2. */ - collision = 1; - /* Insert a vertex at the intersection. */ - segmentintersection(m, b, &fixuptri, &crosssubseg, endpoint2); - done = 1; - } - } - } - } while (!done); - /* Insert a subsegment to make the segment permanent. */ - insertsubseg(m, b, &fixuptri, newmark); - /* If there was a collision with an interceding vertex, install another */ - /* segment connecting that vertex with endpoint2. */ - if (collision) { - /* Insert the remainder of the segment. */ - if (!scoutsegment(m, b, &fixuptri, endpoint2, newmark)) { - constrainededge(m, b, &fixuptri, endpoint2, newmark); - } - } -} - -/*****************************************************************************/ -/* */ -/* insertsegment() Insert a PSLG segment into a triangulation. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void insertsegment(struct mesh *m, struct behavior *b, - vertex endpoint1, vertex endpoint2, int newmark) -#else /* not ANSI_DECLARATORS */ -void insertsegment(m, b, endpoint1, endpoint2, newmark) -struct mesh *m; -struct behavior *b; -vertex endpoint1; -vertex endpoint2; -int newmark; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri searchtri1, searchtri2; - triangle encodedtri; - vertex checkvertex; - triangle ptr; /* Temporary variable used by sym(). */ - - if (b->verbose > 1) { - printf(" Connecting (%.12g, %.12g) to (%.12g, %.12g).\n", - endpoint1[0], endpoint1[1], endpoint2[0], endpoint2[1]); - } - - /* Find a triangle whose origin is the segment's first endpoint. */ - checkvertex = (vertex) NULL; - encodedtri = vertex2tri(endpoint1); - if (encodedtri != (triangle) NULL) { - decode(encodedtri, searchtri1); - org(searchtri1, checkvertex); - } - if (checkvertex != endpoint1) { - /* Find a boundary triangle to search from. */ - searchtri1.tri = m->dummytri; - searchtri1.orient = 0; - symself(searchtri1); - /* Search for the segment's first endpoint by point location. */ - if (locate(m, b, endpoint1, &searchtri1) != ONVERTEX) { - printf( - "Internal error in insertsegment(): Unable to locate PSLG vertex\n"); - printf(" (%.12g, %.12g) in triangulation.\n", - endpoint1[0], endpoint1[1]); - internalerror(); - } - } - /* Remember this triangle to improve subsequent point location. */ - otricopy(searchtri1, m->recenttri); - /* Scout the beginnings of a path from the first endpoint */ - /* toward the second. */ - if (scoutsegment(m, b, &searchtri1, endpoint2, newmark)) { - /* The segment was easily inserted. */ - return; - } - /* The first endpoint may have changed if a collision with an intervening */ - /* vertex on the segment occurred. */ - org(searchtri1, endpoint1); - - /* Find a triangle whose origin is the segment's second endpoint. */ - checkvertex = (vertex) NULL; - encodedtri = vertex2tri(endpoint2); - if (encodedtri != (triangle) NULL) { - decode(encodedtri, searchtri2); - org(searchtri2, checkvertex); - } - if (checkvertex != endpoint2) { - /* Find a boundary triangle to search from. */ - searchtri2.tri = m->dummytri; - searchtri2.orient = 0; - symself(searchtri2); - /* Search for the segment's second endpoint by point location. */ - if (locate(m, b, endpoint2, &searchtri2) != ONVERTEX) { - printf( - "Internal error in insertsegment(): Unable to locate PSLG vertex\n"); - printf(" (%.12g, %.12g) in triangulation.\n", - endpoint2[0], endpoint2[1]); - internalerror(); - } - } - /* Remember this triangle to improve subsequent point location. */ - otricopy(searchtri2, m->recenttri); - /* Scout the beginnings of a path from the second endpoint */ - /* toward the first. */ - if (scoutsegment(m, b, &searchtri2, endpoint1, newmark)) { - /* The segment was easily inserted. */ - return; - } - /* The second endpoint may have changed if a collision with an intervening */ - /* vertex on the segment occurred. */ - org(searchtri2, endpoint2); - -#ifndef REDUCED -#ifndef CDT_ONLY - if (b->splitseg) { - /* Insert vertices to force the segment into the triangulation. */ - conformingedge(m, b, endpoint1, endpoint2, newmark); - } else { -#endif /* not CDT_ONLY */ -#endif /* not REDUCED */ - /* Insert the segment directly into the triangulation. */ - constrainededge(m, b, &searchtri1, endpoint2, newmark); -#ifndef REDUCED -#ifndef CDT_ONLY - } -#endif /* not CDT_ONLY */ -#endif /* not REDUCED */ -} - -/*****************************************************************************/ -/* */ -/* markhull() Cover the convex hull of a triangulation with subsegments. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void markhull(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void markhull(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri hulltri; - struct otri nexttri; - struct otri starttri; - triangle ptr; /* Temporary variable used by sym() and oprev(). */ - - /* Find a triangle handle on the hull. */ - hulltri.tri = m->dummytri; - hulltri.orient = 0; - symself(hulltri); - /* Remember where we started so we know when to stop. */ - otricopy(hulltri, starttri); - /* Go once counterclockwise around the convex hull. */ - do { - /* Create a subsegment if there isn't already one here. */ - insertsubseg(m, b, &hulltri, 1); - /* To find the next hull edge, go clockwise around the next vertex. */ - lnextself(hulltri); - oprev(hulltri, nexttri); - while (nexttri.tri != m->dummytri) { - otricopy(nexttri, hulltri); - oprev(hulltri, nexttri); - } - } while (!otriequal(hulltri, starttri)); -} - -/*****************************************************************************/ -/* */ -/* formskeleton() Create the segments of a triangulation, including PSLG */ -/* segments and edges on the convex hull. */ -/* */ -/* The PSLG segments are read from a .poly file. The return value is the */ -/* number of segments in the file. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void formskeleton(struct mesh *m, struct behavior *b, int *segmentlist, - int *segmentmarkerlist, int numberofsegments) -#else /* not ANSI_DECLARATORS */ -void formskeleton(m, b, segmentlist, segmentmarkerlist, numberofsegments) -struct mesh *m; -struct behavior *b; -int *segmentlist; -int *segmentmarkerlist; -int numberofsegments; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void formskeleton(struct mesh *m, struct behavior *b, - FILE *polyfile, char *polyfilename) -#else /* not ANSI_DECLARATORS */ -void formskeleton(m, b, polyfile, polyfilename) -struct mesh *m; -struct behavior *b; -FILE *polyfile; -char *polyfilename; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - char polyfilename[6]; - int index; -#else /* not TRILIBRARY */ - char inputline[INPUTLINESIZE]; - char *stringptr; -#endif /* not TRILIBRARY */ - vertex endpoint1, endpoint2; - int segmentmarkers; - int end1, end2; - int boundmarker; - int i; - - if (b->poly) { - if (!b->quiet) { - printf("Recovering segments in Delaunay triangulation.\n"); - } -#ifdef TRILIBRARY - strcpy(polyfilename, "input"); - m->insegments = numberofsegments; - segmentmarkers = segmentmarkerlist != (int *) NULL; - index = 0; -#else /* not TRILIBRARY */ - /* Read the segments from a .poly file. */ - /* Read number of segments and number of boundary markers. */ - stringptr = readline(inputline, polyfile, polyfilename); - m->insegments = (int) strtol(stringptr, &stringptr, 0); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - segmentmarkers = 0; - } else { - segmentmarkers = (int) strtol(stringptr, &stringptr, 0); - } -#endif /* not TRILIBRARY */ - /* If the input vertices are collinear, there is no triangulation, */ - /* so don't try to insert segments. */ - if (m->triangles.items == 0) { - return; - } - - /* If segments are to be inserted, compute a mapping */ - /* from vertices to triangles. */ - if (m->insegments > 0) { - makevertexmap(m, b); - if (b->verbose) { - printf(" Recovering PSLG segments.\n"); - } - } - - boundmarker = 0; - /* Read and insert the segments. */ - for (i = 0; i < m->insegments; i++) { -#ifdef TRILIBRARY - end1 = segmentlist[index++]; - end2 = segmentlist[index++]; - if (segmentmarkers) { - boundmarker = segmentmarkerlist[i]; - } -#else /* not TRILIBRARY */ - stringptr = readline(inputline, polyfile, b->inpolyfilename); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Segment %d has no endpoints in %s.\n", - b->firstnumber + i, polyfilename); - exit(1); - } else { - end1 = (int) strtol(stringptr, &stringptr, 0); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Segment %d is missing its second endpoint in %s.\n", - b->firstnumber + i, polyfilename); - exit(1); - } else { - end2 = (int) strtol(stringptr, &stringptr, 0); - } - if (segmentmarkers) { - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - boundmarker = 0; - } else { - boundmarker = (int) strtol(stringptr, &stringptr, 0); - } - } -#endif /* not TRILIBRARY */ - if ((end1 < b->firstnumber) || - (end1 >= b->firstnumber + m->invertices)) { - if (!b->quiet) { - printf("Warning: Invalid first endpoint of segment %d in %s.\n", - b->firstnumber + i, polyfilename); - } - } else if ((end2 < b->firstnumber) || - (end2 >= b->firstnumber + m->invertices)) { - if (!b->quiet) { - printf("Warning: Invalid second endpoint of segment %d in %s.\n", - b->firstnumber + i, polyfilename); - } - } else { - endpoint1 = getvertex(m, b, end1); - endpoint2 = getvertex(m, b, end2); - if ((endpoint1[0] == endpoint2[0]) && (endpoint1[1] == endpoint2[1])) { - if (!b->quiet) { - printf("Warning: Endpoints of segment %d are coincident in %s.\n", - b->firstnumber + i, polyfilename); - } - } else { - insertsegment(m, b, endpoint1, endpoint2, boundmarker); - } - } - } - } else { - m->insegments = 0; - } - if (b->convex || !b->poly) { - /* Enclose the convex hull with subsegments. */ - if (b->verbose) { - printf(" Enclosing convex hull with segments.\n"); - } - markhull(m, b); - } -} - -/** **/ -/** **/ -/********* Segment insertion ends here *********/ - -/********* Carving out holes and concavities begins here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* infecthull() Virally infect all of the triangles of the convex hull */ -/* that are not protected by subsegments. Where there are */ -/* subsegments, set boundary markers as appropriate. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void infecthull(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void infecthull(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri hulltri; - struct otri nexttri; - struct otri starttri; - struct osub hullsubseg; - triangle **deadtriangle; - vertex horg, hdest; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - if (b->verbose) { - printf(" Marking concavities (external triangles) for elimination.\n"); - } - /* Find a triangle handle on the hull. */ - hulltri.tri = m->dummytri; - hulltri.orient = 0; - symself(hulltri); - /* Remember where we started so we know when to stop. */ - otricopy(hulltri, starttri); - /* Go once counterclockwise around the convex hull. */ - do { - /* Ignore triangles that are already infected. */ - if (!infected(hulltri)) { - /* Is the triangle protected by a subsegment? */ - tspivot(hulltri, hullsubseg); - if (hullsubseg.ss == m->dummysub) { - /* The triangle is not protected; infect it. */ - if (!infected(hulltri)) { - infect(hulltri); - deadtriangle = (triangle **) poolalloc(&m->viri); - *deadtriangle = hulltri.tri; - } - } else { - /* The triangle is protected; set boundary markers if appropriate. */ - if (mark(hullsubseg) == 0) { - setmark(hullsubseg, 1); - org(hulltri, horg); - dest(hulltri, hdest); - if (vertexmark(horg) == 0) { - setvertexmark(horg, 1); - } - if (vertexmark(hdest) == 0) { - setvertexmark(hdest, 1); - } - } - } - } - /* To find the next hull edge, go clockwise around the next vertex. */ - lnextself(hulltri); - oprev(hulltri, nexttri); - while (nexttri.tri != m->dummytri) { - otricopy(nexttri, hulltri); - oprev(hulltri, nexttri); - } - } while (!otriequal(hulltri, starttri)); -} - -/*****************************************************************************/ -/* */ -/* plague() Spread the virus from all infected triangles to any neighbors */ -/* not protected by subsegments. Delete all infected triangles. */ -/* */ -/* This is the procedure that actually creates holes and concavities. */ -/* */ -/* This procedure operates in two phases. The first phase identifies all */ -/* the triangles that will die, and marks them as infected. They are */ -/* marked to ensure that each triangle is added to the virus pool only */ -/* once, so the procedure will terminate. */ -/* */ -/* The second phase actually eliminates the infected triangles. It also */ -/* eliminates orphaned vertices. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void plague(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void plague(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri testtri; - struct otri neighbor; - triangle **virusloop; - triangle **deadtriangle; - struct osub neighborsubseg; - vertex testvertex; - vertex norg, ndest; - vertex deadorg, deaddest, deadapex; - int killorg; - triangle ptr; /* Temporary variable used by sym() and onext(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - if (b->verbose) { - printf(" Marking neighbors of marked triangles.\n"); - } - /* Loop through all the infected triangles, spreading the virus to */ - /* their neighbors, then to their neighbors' neighbors. */ - traversalinit(&m->viri); - virusloop = (triangle **) traverse(&m->viri); - while (virusloop != (triangle **) NULL) { - testtri.tri = *virusloop; - /* A triangle is marked as infected by messing with one of its pointers */ - /* to subsegments, setting it to an illegal value. Hence, we have to */ - /* temporarily uninfect this triangle so that we can examine its */ - /* adjacent subsegments. */ - uninfect(testtri); - if (b->verbose > 2) { - /* Assign the triangle an orientation for convenience in */ - /* checking its vertices. */ - testtri.orient = 0; - org(testtri, deadorg); - dest(testtri, deaddest); - apex(testtri, deadapex); - printf(" Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - deadorg[0], deadorg[1], deaddest[0], deaddest[1], - deadapex[0], deadapex[1]); - } - /* Check each of the triangle's three neighbors. */ - for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) { - /* Find the neighbor. */ - sym(testtri, neighbor); - /* Check for a subsegment between the triangle and its neighbor. */ - tspivot(testtri, neighborsubseg); - /* Check if the neighbor is nonexistent or already infected. */ - if ((neighbor.tri == m->dummytri) || infected(neighbor)) { - if (neighborsubseg.ss != m->dummysub) { - /* There is a subsegment separating the triangle from its */ - /* neighbor, but both triangles are dying, so the subsegment */ - /* dies too. */ - subsegdealloc(m, neighborsubseg.ss); - if (neighbor.tri != m->dummytri) { - /* Make sure the subsegment doesn't get deallocated again */ - /* later when the infected neighbor is visited. */ - uninfect(neighbor); - tsdissolve(neighbor); - infect(neighbor); - } - } - } else { /* The neighbor exists and is not infected. */ - if (neighborsubseg.ss == m->dummysub) { - /* There is no subsegment protecting the neighbor, so */ - /* the neighbor becomes infected. */ - if (b->verbose > 2) { - org(neighbor, deadorg); - dest(neighbor, deaddest); - apex(neighbor, deadapex); - printf( - " Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - deadorg[0], deadorg[1], deaddest[0], deaddest[1], - deadapex[0], deadapex[1]); - } - infect(neighbor); - /* Ensure that the neighbor's neighbors will be infected. */ - deadtriangle = (triangle **) poolalloc(&m->viri); - *deadtriangle = neighbor.tri; - } else { /* The neighbor is protected by a subsegment. */ - /* Remove this triangle from the subsegment. */ - stdissolve(neighborsubseg); - /* The subsegment becomes a boundary. Set markers accordingly. */ - if (mark(neighborsubseg) == 0) { - setmark(neighborsubseg, 1); - } - org(neighbor, norg); - dest(neighbor, ndest); - if (vertexmark(norg) == 0) { - setvertexmark(norg, 1); - } - if (vertexmark(ndest) == 0) { - setvertexmark(ndest, 1); - } - } - } - } - /* Remark the triangle as infected, so it doesn't get added to the */ - /* virus pool again. */ - infect(testtri); - virusloop = (triangle **) traverse(&m->viri); - } - - if (b->verbose) { - printf(" Deleting marked triangles.\n"); - } - - traversalinit(&m->viri); - virusloop = (triangle **) traverse(&m->viri); - while (virusloop != (triangle **) NULL) { - testtri.tri = *virusloop; - - /* Check each of the three corners of the triangle for elimination. */ - /* This is done by walking around each vertex, checking if it is */ - /* still connected to at least one live triangle. */ - for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) { - org(testtri, testvertex); - /* Check if the vertex has already been tested. */ - if (testvertex != (vertex) NULL) { - killorg = 1; - /* Mark the corner of the triangle as having been tested. */ - setorg(testtri, NULL); - /* Walk counterclockwise about the vertex. */ - onext(testtri, neighbor); - /* Stop upon reaching a boundary or the starting triangle. */ - while ((neighbor.tri != m->dummytri) && - (!otriequal(neighbor, testtri))) { - if (infected(neighbor)) { - /* Mark the corner of this triangle as having been tested. */ - setorg(neighbor, NULL); - } else { - /* A live triangle. The vertex survives. */ - killorg = 0; - } - /* Walk counterclockwise about the vertex. */ - onextself(neighbor); - } - /* If we reached a boundary, we must walk clockwise as well. */ - if (neighbor.tri == m->dummytri) { - /* Walk clockwise about the vertex. */ - oprev(testtri, neighbor); - /* Stop upon reaching a boundary. */ - while (neighbor.tri != m->dummytri) { - if (infected(neighbor)) { - /* Mark the corner of this triangle as having been tested. */ - setorg(neighbor, NULL); - } else { - /* A live triangle. The vertex survives. */ - killorg = 0; - } - /* Walk clockwise about the vertex. */ - oprevself(neighbor); - } - } - if (killorg) { - if (b->verbose > 1) { - printf(" Deleting vertex (%.12g, %.12g)\n", - testvertex[0], testvertex[1]); - } - setvertextype(testvertex, UNDEADVERTEX); - m->undeads++; - } - } - } - - /* Record changes in the number of boundary edges, and disconnect */ - /* dead triangles from their neighbors. */ - for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) { - sym(testtri, neighbor); - if (neighbor.tri == m->dummytri) { - /* There is no neighboring triangle on this edge, so this edge */ - /* is a boundary edge. This triangle is being deleted, so this */ - /* boundary edge is deleted. */ - m->hullsize--; - } else { - /* Disconnect the triangle from its neighbor. */ - dissolve(neighbor); - /* There is a neighboring triangle on this edge, so this edge */ - /* becomes a boundary edge when this triangle is deleted. */ - m->hullsize++; - } - } - /* Return the dead triangle to the pool of triangles. */ - triangledealloc(m, testtri.tri); - virusloop = (triangle **) traverse(&m->viri); - } - /* Empty the virus pool. */ - poolrestart(&m->viri); -} - -/*****************************************************************************/ -/* */ -/* regionplague() Spread regional attributes and/or area constraints */ -/* (from a .poly file) throughout the mesh. */ -/* */ -/* This procedure operates in two phases. The first phase spreads an */ -/* attribute and/or an area constraint through a (segment-bounded) region. */ -/* The triangles are marked to ensure that each triangle is added to the */ -/* virus pool only once, so the procedure will terminate. */ -/* */ -/* The second phase uninfects all infected triangles, returning them to */ -/* normal. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void regionplague(struct mesh *m, struct behavior *b, - REAL attribute, REAL area) -#else /* not ANSI_DECLARATORS */ -void regionplague(m, b, attribute, area) -struct mesh *m; -struct behavior *b; -REAL attribute; -REAL area; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri testtri; - struct otri neighbor; - triangle **virusloop; - triangle **regiontri; - struct osub neighborsubseg; - vertex regionorg, regiondest, regionapex; - triangle ptr; /* Temporary variable used by sym() and onext(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - if (b->verbose > 1) { - printf(" Marking neighbors of marked triangles.\n"); - } - /* Loop through all the infected triangles, spreading the attribute */ - /* and/or area constraint to their neighbors, then to their neighbors' */ - /* neighbors. */ - traversalinit(&m->viri); - virusloop = (triangle **) traverse(&m->viri); - while (virusloop != (triangle **) NULL) { - testtri.tri = *virusloop; - /* A triangle is marked as infected by messing with one of its pointers */ - /* to subsegments, setting it to an illegal value. Hence, we have to */ - /* temporarily uninfect this triangle so that we can examine its */ - /* adjacent subsegments. */ - uninfect(testtri); - if (b->regionattrib) { - /* Set an attribute. */ - setelemattribute(testtri, m->eextras, attribute); - } - if (b->vararea) { - /* Set an area constraint. */ - setareabound(testtri, area); - } - if (b->verbose > 2) { - /* Assign the triangle an orientation for convenience in */ - /* checking its vertices. */ - testtri.orient = 0; - org(testtri, regionorg); - dest(testtri, regiondest); - apex(testtri, regionapex); - printf(" Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - regionorg[0], regionorg[1], regiondest[0], regiondest[1], - regionapex[0], regionapex[1]); - } - /* Check each of the triangle's three neighbors. */ - for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) { - /* Find the neighbor. */ - sym(testtri, neighbor); - /* Check for a subsegment between the triangle and its neighbor. */ - tspivot(testtri, neighborsubseg); - /* Make sure the neighbor exists, is not already infected, and */ - /* isn't protected by a subsegment. */ - if ((neighbor.tri != m->dummytri) && !infected(neighbor) - && (neighborsubseg.ss == m->dummysub)) { - if (b->verbose > 2) { - org(neighbor, regionorg); - dest(neighbor, regiondest); - apex(neighbor, regionapex); - printf(" Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - regionorg[0], regionorg[1], regiondest[0], regiondest[1], - regionapex[0], regionapex[1]); - } - /* Infect the neighbor. */ - infect(neighbor); - /* Ensure that the neighbor's neighbors will be infected. */ - regiontri = (triangle **) poolalloc(&m->viri); - *regiontri = neighbor.tri; - } - } - /* Remark the triangle as infected, so it doesn't get added to the */ - /* virus pool again. */ - infect(testtri); - virusloop = (triangle **) traverse(&m->viri); - } - - /* Uninfect all triangles. */ - if (b->verbose > 1) { - printf(" Unmarking marked triangles.\n"); - } - traversalinit(&m->viri); - virusloop = (triangle **) traverse(&m->viri); - while (virusloop != (triangle **) NULL) { - testtri.tri = *virusloop; - uninfect(testtri); - virusloop = (triangle **) traverse(&m->viri); - } - /* Empty the virus pool. */ - poolrestart(&m->viri); -} - -/*****************************************************************************/ -/* */ -/* carveholes() Find the holes and infect them. Find the area */ -/* constraints and infect them. Infect the convex hull. */ -/* Spread the infection and kill triangles. Spread the */ -/* area constraints. */ -/* */ -/* This routine mainly calls other routines to carry out all these */ -/* functions. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void carveholes(struct mesh *m, struct behavior *b, REAL *holelist, int holes, - REAL *regionlist, int regions) -#else /* not ANSI_DECLARATORS */ -void carveholes(m, b, holelist, holes, regionlist, regions) -struct mesh *m; -struct behavior *b; -REAL *holelist; -int holes; -REAL *regionlist; -int regions; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri searchtri; - struct otri triangleloop; - struct otri *regiontris; - triangle **holetri; - triangle **regiontri; - vertex searchorg, searchdest; - enum locateresult intersect; - int i; - triangle ptr; /* Temporary variable used by sym(). */ - - if (!(b->quiet || (b->noholes && b->convex))) { - printf("Removing unwanted triangles.\n"); - if (b->verbose && (holes > 0)) { - printf(" Marking holes for elimination.\n"); - } - } - - if (regions > 0) { - /* Allocate storage for the triangles in which region points fall. */ - regiontris = (struct otri *) - trimalloc(regions * (int) sizeof(struct otri)); - } - - if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) { - /* Initialize a pool of viri to be used for holes, concavities, */ - /* regional attributes, and/or regional area constraints. */ - poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, VIRUSPERBLOCK, - POINTER, 0); - } - - if (!b->convex) { - /* Mark as infected any unprotected triangles on the boundary. */ - /* This is one way by which concavities are created. */ - infecthull(m, b); - } - - if ((holes > 0) && !b->noholes) { - /* Infect each triangle in which a hole lies. */ - for (i = 0; i < 2 * holes; i += 2) { - /* Ignore holes that aren't within the bounds of the mesh. */ - if ((holelist[i] >= m->xmin) && (holelist[i] <= m->xmax) - && (holelist[i + 1] >= m->ymin) && (holelist[i + 1] <= m->ymax)) { - /* Start searching from some triangle on the outer boundary. */ - searchtri.tri = m->dummytri; - searchtri.orient = 0; - symself(searchtri); - /* Ensure that the hole is to the left of this boundary edge; */ - /* otherwise, locate() will falsely report that the hole */ - /* falls within the starting triangle. */ - org(searchtri, searchorg); - dest(searchtri, searchdest); - if (counterclockwise(m, b, searchorg, searchdest, &holelist[i]) > - 0.0) { - /* Find a triangle that contains the hole. */ - intersect = locate(m, b, &holelist[i], &searchtri); - if ((intersect != OUTSIDE) && (!infected(searchtri))) { - /* Infect the triangle. This is done by marking the triangle */ - /* as infected and including the triangle in the virus pool. */ - infect(searchtri); - holetri = (triangle **) poolalloc(&m->viri); - *holetri = searchtri.tri; - } - } - } - } - } - - /* Now, we have to find all the regions BEFORE we carve the holes, because */ - /* locate() won't work when the triangulation is no longer convex. */ - /* (Incidentally, this is the reason why regional attributes and area */ - /* constraints can't be used when refining a preexisting mesh, which */ - /* might not be convex; they can only be used with a freshly */ - /* triangulated PSLG.) */ - if (regions > 0) { - /* Find the starting triangle for each region. */ - for (i = 0; i < regions; i++) { - regiontris[i].tri = m->dummytri; - /* Ignore region points that aren't within the bounds of the mesh. */ - if ((regionlist[4 * i] >= m->xmin) && (regionlist[4 * i] <= m->xmax) && - (regionlist[4 * i + 1] >= m->ymin) && - (regionlist[4 * i + 1] <= m->ymax)) { - /* Start searching from some triangle on the outer boundary. */ - searchtri.tri = m->dummytri; - searchtri.orient = 0; - symself(searchtri); - /* Ensure that the region point is to the left of this boundary */ - /* edge; otherwise, locate() will falsely report that the */ - /* region point falls within the starting triangle. */ - org(searchtri, searchorg); - dest(searchtri, searchdest); - if (counterclockwise(m, b, searchorg, searchdest, ®ionlist[4 * i]) > - 0.0) { - /* Find a triangle that contains the region point. */ - intersect = locate(m, b, ®ionlist[4 * i], &searchtri); - if ((intersect != OUTSIDE) && (!infected(searchtri))) { - /* Record the triangle for processing after the */ - /* holes have been carved. */ - otricopy(searchtri, regiontris[i]); - } - } - } - } - } - - if (m->viri.items > 0) { - /* Carve the holes and concavities. */ - plague(m, b); - } - /* The virus pool should be empty now. */ - - if (regions > 0) { - if (!b->quiet) { - if (b->regionattrib) { - if (b->vararea) { - printf("Spreading regional attributes and area constraints.\n"); - } else { - printf("Spreading regional attributes.\n"); - } - } else { - printf("Spreading regional area constraints.\n"); - } - } - if (b->regionattrib && !b->refine) { - /* Assign every triangle a regional attribute of zero. */ - traversalinit(&m->triangles); - triangleloop.orient = 0; - triangleloop.tri = triangletraverse(m); - while (triangleloop.tri != (triangle *) NULL) { - setelemattribute(triangleloop, m->eextras, 0.0); - triangleloop.tri = triangletraverse(m); - } - } - for (i = 0; i < regions; i++) { - if (regiontris[i].tri != m->dummytri) { - /* Make sure the triangle under consideration still exists. */ - /* It may have been eaten by the virus. */ - if (!deadtri(regiontris[i].tri)) { - /* Put one triangle in the virus pool. */ - infect(regiontris[i]); - regiontri = (triangle **) poolalloc(&m->viri); - *regiontri = regiontris[i].tri; - /* Apply one region's attribute and/or area constraint. */ - regionplague(m, b, regionlist[4 * i + 2], regionlist[4 * i + 3]); - /* The virus pool should be empty now. */ - } - } - } - if (b->regionattrib && !b->refine) { - /* Note the fact that each triangle has an additional attribute. */ - m->eextras++; - } - } - - /* Free up memory. */ - if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) { - pooldeinit(&m->viri); - } - if (regions > 0) { - trifree((VOID *) regiontris); - } -} - -/** **/ -/** **/ -/********* Carving out holes and concavities ends here *********/ - -/********* Mesh quality maintenance begins here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* tallyencs() Traverse the entire list of subsegments, and check each */ -/* to see if it is encroached. If so, add it to the list. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void tallyencs(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void tallyencs(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct osub subsegloop; - int dummy; - - traversalinit(&m->subsegs); - subsegloop.ssorient = 0; - subsegloop.ss = subsegtraverse(m); - while (subsegloop.ss != (subseg *) NULL) { - /* If the segment is encroached, add it to the list. */ - dummy = checkseg4encroach(m, b, &subsegloop, 0.0); - subsegloop.ss = subsegtraverse(m); - } -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* precisionerror() Print an error message for precision problems. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -void precisionerror() -{ - printf("Try increasing the area criterion and/or reducing the minimum\n"); - printf(" allowable angle so that tiny triangles are not created.\n"); -#ifdef SINGLE - printf("Alternatively, try recompiling me with double precision\n"); - printf(" arithmetic (by removing \"#define SINGLE\" from the\n"); - printf(" source file or \"-DSINGLE\" from the makefile).\n"); -#endif /* SINGLE */ -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* splitencsegs() Split all the encroached subsegments. */ -/* */ -/* Each encroached subsegment is repaired by splitting it - inserting a */ -/* vertex at or near its midpoint. Newly inserted vertices may encroach */ -/* upon other subsegments; these are also repaired. */ -/* */ -/* `triflaws' is a flag that specifies whether one should take note of new */ -/* bad triangles that result from inserting vertices to repair encroached */ -/* subsegments. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void splitencsegs(struct mesh *m, struct behavior *b, int triflaws) -#else /* not ANSI_DECLARATORS */ -void splitencsegs(m, b, triflaws) -struct mesh *m; -struct behavior *b; -int triflaws; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri enctri; - struct otri testtri; - struct osub testsh; - struct osub currentenc; - struct badsubseg *encloop; - vertex eorg, edest, eapex; - vertex newvertex; - enum insertvertexresult success; - REAL segmentlength, nearestpoweroftwo; - REAL split; - REAL multiplier, divisor; - int acuteorg, acuteorg2, acutedest, acutedest2; - int dummy; - int i; - triangle ptr; /* Temporary variable used by stpivot(). */ - subseg sptr; /* Temporary variable used by snext(). */ - - /* Note that steinerleft == -1 if an unlimited number */ - /* of Steiner points is allowed. */ - while ((m->badsubsegs.items > 0) && (m->steinerleft != 0)) { - traversalinit(&m->badsubsegs); - encloop = badsubsegtraverse(m); - while ((encloop != (struct badsubseg *) NULL) && (m->steinerleft != 0)) { - sdecode(encloop->encsubseg, currentenc); - sorg(currentenc, eorg); - sdest(currentenc, edest); - /* Make sure that this segment is still the same segment it was */ - /* when it was determined to be encroached. If the segment was */ - /* enqueued multiple times (because several newly inserted */ - /* vertices encroached it), it may have already been split. */ - if (!deadsubseg(currentenc.ss) && - (eorg == encloop->subsegorg) && (edest == encloop->subsegdest)) { - /* To decide where to split a segment, we need to know if the */ - /* segment shares an endpoint with an adjacent segment. */ - /* The concern is that, if we simply split every encroached */ - /* segment in its center, two adjacent segments with a small */ - /* angle between them might lead to an infinite loop; each */ - /* vertex added to split one segment will encroach upon the */ - /* other segment, which must then be split with a vertex that */ - /* will encroach upon the first segment, and so on forever. */ - /* To avoid this, imagine a set of concentric circles, whose */ - /* radii are powers of two, about each segment endpoint. */ - /* These concentric circles determine where the segment is */ - /* split. (If both endpoints are shared with adjacent */ - /* segments, split the segment in the middle, and apply the */ - /* concentric circles for later splittings.) */ - - /* Is the origin shared with another segment? */ - stpivot(currentenc, enctri); - lnext(enctri, testtri); - tspivot(testtri, testsh); - acuteorg = testsh.ss != m->dummysub; - /* Is the destination shared with another segment? */ - lnextself(testtri); - tspivot(testtri, testsh); - acutedest = testsh.ss != m->dummysub; - - /* If we're using diametral lenses (rather than diametral circles) */ - /* to define encroachment, delete free vertices from the */ - /* subsegment's diametral circle. */ - if (!b->nolenses && !acuteorg && !acutedest) { - apex(enctri, eapex); - while ((vertextype(eapex) == FREEVERTEX) && - ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) + - (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) { - deletevertex(m, b, &testtri); - stpivot(currentenc, enctri); - apex(enctri, eapex); - lprev(enctri, testtri); - } - } - - /* Now, check the other side of the segment, if there's a triangle */ - /* there. */ - sym(enctri, testtri); - if (testtri.tri != m->dummytri) { - /* Is the destination shared with another segment? */ - lnextself(testtri); - tspivot(testtri, testsh); - acutedest2 = testsh.ss != m->dummysub; - acutedest = acutedest || acutedest2; - /* Is the origin shared with another segment? */ - lnextself(testtri); - tspivot(testtri, testsh); - acuteorg2 = testsh.ss != m->dummysub; - acuteorg = acuteorg || acuteorg2; - - /* Delete free vertices from the subsegment's diametral circle. */ - if (!b->nolenses && !acuteorg2 && !acutedest2) { - org(testtri, eapex); - while ((vertextype(eapex) == FREEVERTEX) && - ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) + - (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) { - deletevertex(m, b, &testtri); - sym(enctri, testtri); - apex(testtri, eapex); - lprevself(testtri); - } - } - } - - /* Use the concentric circles if exactly one endpoint is shared */ - /* with another adjacent segment. */ - if (acuteorg || acutedest) { - segmentlength = sqrt((edest[0] - eorg[0]) * (edest[0] - eorg[0]) + - (edest[1] - eorg[1]) * (edest[1] - eorg[1])); - /* Find the power of two that most evenly splits the segment. */ - /* The worst case is a 2:1 ratio between subsegment lengths. */ - nearestpoweroftwo = 1.0; - while (segmentlength > 3.0 * nearestpoweroftwo) { - nearestpoweroftwo *= 2.0; - } - while (segmentlength < 1.5 * nearestpoweroftwo) { - nearestpoweroftwo *= 0.5; - } - /* Where do we split the segment? */ - split = nearestpoweroftwo / segmentlength; - if (acutedest) { - split = 1.0 - split; - } - } else { - /* If we're not worried about adjacent segments, split */ - /* this segment in the middle. */ - split = 0.5; - } - - /* Create the new vertex. */ - newvertex = (vertex) poolalloc(&m->vertices); - /* Interpolate its coordinate and attributes. */ - for (i = 0; i < 2 + m->nextras; i++) { - newvertex[i] = eorg[i] + split * (edest[i] - eorg[i]); - } - - if (!b->noexact) { - /* Roundoff in the above calculation may yield a `newvertex' */ - /* that is not precisely collinear with `eorg' and `edest'. */ - /* Improve collinearity by one step of iterative refinement. */ - multiplier = counterclockwise(m, b, eorg, edest, newvertex); - divisor = ((eorg[0] - edest[0]) * (eorg[0] - edest[0]) + - (eorg[1] - edest[1]) * (eorg[1] - edest[1])); - if ((multiplier != 0.0) && (divisor != 0.0)) { - multiplier = multiplier / divisor; - /* Watch out for NANs. */ - if (multiplier == multiplier) { - newvertex[0] += multiplier * (edest[1] - eorg[1]); - newvertex[1] += multiplier * (eorg[0] - edest[0]); - } - } - } - - setvertexmark(newvertex, mark(currentenc)); - setvertextype(newvertex, SEGMENTVERTEX); - if (b->verbose > 1) { - printf( - " Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n", - eorg[0], eorg[1], edest[0], edest[1], - newvertex[0], newvertex[1]); - } - /* Check whether the new vertex lies on an endpoint. */ - if (((newvertex[0] == eorg[0]) && (newvertex[1] == eorg[1])) || - ((newvertex[0] == edest[0]) && (newvertex[1] == edest[1]))) { - printf("Error: Ran out of precision at (%.12g, %.12g).\n", - newvertex[0], newvertex[1]); - printf("I attempted to split a segment to a smaller size than\n"); - printf(" can be accommodated by the finite precision of\n"); - printf(" floating point arithmetic.\n"); - precisionerror(); - exit(1); - } - /* Insert the splitting vertex. This should always succeed. */ - success = insertvertex(m, b, newvertex, &enctri, ¤tenc, - 1, triflaws, 0.0); - if ((success != SUCCESSFULVERTEX) && (success != ENCROACHINGVERTEX)) { - printf("Internal error in splitencsegs():\n"); - printf(" Failure to split a segment.\n"); - internalerror(); - } - if (m->steinerleft > 0) { - m->steinerleft--; - } - /* Check the two new subsegments to see if they're encroached. */ - dummy = checkseg4encroach(m, b, ¤tenc, 0.0); - snextself(currentenc); - dummy = checkseg4encroach(m, b, ¤tenc, 0.0); - } - - badsubsegdealloc(m, encloop); - encloop = badsubsegtraverse(m); - } - } -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* tallyfaces() Test every triangle in the mesh for quality measures. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void tallyfaces(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void tallyfaces(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri triangleloop; - - if (b->verbose) { - printf(" Making a list of bad triangles.\n"); - } - traversalinit(&m->triangles); - triangleloop.orient = 0; - triangleloop.tri = triangletraverse(m); - while (triangleloop.tri != (triangle *) NULL) { - /* If the triangle is bad, enqueue it. */ - testtriangle(m, b, &triangleloop); - triangleloop.tri = triangletraverse(m); - } -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* splittriangle() Inserts a vertex at the circumcenter of a triangle. */ -/* Deletes the newly inserted vertex if it encroaches */ -/* upon a segment. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void splittriangle(struct mesh *m, struct behavior *b, - struct badtriang *badtri) -#else /* not ANSI_DECLARATORS */ -void splittriangle(m, b, badtri) -struct mesh *m; -struct behavior *b; -struct badtriang *badtri; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri badotri; - vertex borg, bdest, bapex; - vertex newvertex; - REAL xi, eta; - REAL minedge; - enum insertvertexresult success; - int errorflag; - int i; - - decode(badtri->poortri, badotri); - org(badotri, borg); - dest(badotri, bdest); - apex(badotri, bapex); - /* Make sure that this triangle is still the same triangle it was */ - /* when it was tested and determined to be of bad quality. */ - /* Subsequent transformations may have made it a different triangle. */ - if (!deadtri(badotri.tri) && (borg == badtri->triangorg) && - (bdest == badtri->triangdest) && (bapex == badtri->triangapex)) { - if (b->verbose > 1) { - printf(" Splitting this triangle at its circumcenter:\n"); - printf(" (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", borg[0], - borg[1], bdest[0], bdest[1], bapex[0], bapex[1]); - } - - errorflag = 0; - /* Create a new vertex at the triangle's circumcenter. */ - newvertex = (vertex) poolalloc(&m->vertices); - findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, &minedge, - 1); - - /* Check whether the new vertex lies on a triangle vertex. */ - if (((newvertex[0] == borg[0]) && (newvertex[1] == borg[1])) || - ((newvertex[0] == bdest[0]) && (newvertex[1] == bdest[1])) || - ((newvertex[0] == bapex[0]) && (newvertex[1] == bapex[1]))) { - if (!b->quiet) { - printf( - "Warning: New vertex (%.12g, %.12g) falls on existing vertex.\n", - newvertex[0], newvertex[1]); - errorflag = 1; - } - vertexdealloc(m, newvertex); - } else { - for (i = 2; i < 2 + m->nextras; i++) { - /* Interpolate the vertex attributes at the circumcenter. */ - newvertex[i] = borg[i] + xi * (bdest[i] - borg[i]) - + eta * (bapex[i] - borg[i]); - } - /* The new vertex must be in the interior, and therefore is a */ - /* free vertex with a marker of zero. */ - setvertexmark(newvertex, 0); - setvertextype(newvertex, FREEVERTEX); - - /* Ensure that the handle `badotri' does not represent the longest */ - /* edge of the triangle. This ensures that the circumcenter must */ - /* fall to the left of this edge, so point location will work. */ - /* (If the angle org-apex-dest exceeds 90 degrees, then the */ - /* circumcenter lies outside the org-dest edge, and eta is */ - /* negative. Roundoff error might prevent eta from being */ - /* negative when it should be, so I test eta against xi.) */ - if (eta < xi) { - lprevself(badotri); - } - - /* Insert the circumcenter, searching from the edge of the triangle, */ - /* and maintain the Delaunay property of the triangulation. */ - success = insertvertex(m, b, newvertex, &badotri, (struct osub *) NULL, - 1, 1, minedge); - if (success == SUCCESSFULVERTEX) { - if (m->steinerleft > 0) { - m->steinerleft--; - } - } else if (success == ENCROACHINGVERTEX) { - /* If the newly inserted vertex encroaches upon a subsegment, */ - /* delete the new vertex. */ - undovertex(m, b); - if (b->verbose > 1) { - printf(" Rejecting (%.12g, %.12g).\n", newvertex[0], newvertex[1]); - } - vertexdealloc(m, newvertex); - } else if (success == VIOLATINGVERTEX) { - /* Failed to insert the new vertex, but some subsegment was */ - /* marked as being encroached. */ - vertexdealloc(m, newvertex); - } else { /* success == DUPLICATEVERTEX */ - /* Couldn't insert the new vertex because a vertex is already there. */ - if (!b->quiet) { - printf( - "Warning: New vertex (%.12g, %.12g) falls on existing vertex.\n", - newvertex[0], newvertex[1]); - errorflag = 1; - } - vertexdealloc(m, newvertex); - } - } - if (errorflag) { - if (b->verbose) { - printf(" The new vertex is at the circumcenter of triangle\n"); - printf(" (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", - borg[0], borg[1], bdest[0], bdest[1], bapex[0], bapex[1]); - } - printf("This probably means that I am trying to refine triangles\n"); - printf(" to a smaller size than can be accommodated by the finite\n"); - printf(" precision of floating point arithmetic. (You can be\n"); - printf(" sure of this if I fail to terminate.)\n"); - precisionerror(); - } - } -} - -#endif /* not CDT_ONLY */ - -/*****************************************************************************/ -/* */ -/* enforcequality() Remove all the encroached subsegments and bad */ -/* triangles from the triangulation. */ -/* */ -/*****************************************************************************/ - -#ifndef CDT_ONLY - -#ifdef ANSI_DECLARATORS -void enforcequality(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void enforcequality(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct badtriang *badtri; - int i; - - if (!b->quiet) { - printf("Adding Steiner points to enforce quality.\n"); - } - /* Initialize the pool of encroached subsegments. */ - poolinit(&m->badsubsegs, sizeof(struct badsubseg), BADSUBSEGPERBLOCK, - BADSUBSEGPERBLOCK, POINTER, 0); - if (b->verbose) { - printf(" Looking for encroached subsegments.\n"); - } - /* Test all segments to see if they're encroached. */ - tallyencs(m, b); - if (b->verbose && (m->badsubsegs.items > 0)) { - printf(" Splitting encroached subsegments.\n"); - } - /* Fix encroached subsegments without noting bad triangles. */ - splitencsegs(m, b, 0); - /* At this point, if we haven't run out of Steiner points, the */ - /* triangulation should be (conforming) Delaunay. */ - - /* Next, we worry about enforcing triangle quality. */ - if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) { - /* Initialize the pool of bad triangles. */ - poolinit(&m->badtriangles, sizeof(struct badtriang), BADTRIPERBLOCK, - BADTRIPERBLOCK, POINTER, 0); - /* Initialize the queues of bad triangles. */ - for (i = 0; i < 64; i++) { - m->queuefront[i] = (struct badtriang *) NULL; - } - m->firstnonemptyq = -1; - /* Test all triangles to see if they're bad. */ - tallyfaces(m, b); - /* Initialize the pool of recently flipped triangles. */ - poolinit(&m->flipstackers, sizeof(struct flipstacker), FLIPSTACKERPERBLOCK, - FLIPSTACKERPERBLOCK, POINTER, 0); - m->checkquality = 1; - if (b->verbose) { - printf(" Splitting bad triangles.\n"); - } - while ((m->badtriangles.items > 0) && (m->steinerleft != 0)) { - /* Fix one bad triangle by inserting a vertex at its circumcenter. */ - badtri = dequeuebadtriang(m); - splittriangle(m, b, badtri); - if (m->badsubsegs.items > 0) { - /* Put bad triangle back in queue for another try later. */ - enqueuebadtriang(m, b, badtri); - /* Fix any encroached subsegments that resulted. */ - /* Record any new bad triangles that result. */ - splitencsegs(m, b, 1); - } else { - /* Return the bad triangle to the pool. */ - pooldealloc(&m->badtriangles, (VOID *) badtri); - } - } - } - /* At this point, if we haven't run out of Steiner points, the */ - /* triangulation should be (conforming) Delaunay and have no */ - /* low-quality triangles. */ - - /* Might we have run out of Steiner points too soon? */ - if (!b->quiet && (m->badsubsegs.items > 0) && (m->steinerleft == 0)) { - printf("\nWarning: I ran out of Steiner points, but the mesh has\n"); - if (m->badsubsegs.items == 1) { - printf(" an encroached subsegment, and therefore might not be truly\n"); - } else { - printf(" %ld encroached subsegments, and therefore might not be truly\n" - , m->badsubsegs.items); - } - printf(" Delaunay. If the Delaunay property is important to you,\n"); - printf(" try increasing the number of Steiner points (controlled by\n"); - printf(" the -S switch) slightly and try again.\n\n"); - } -} - -#endif /* not CDT_ONLY */ - -/** **/ -/** **/ -/********* Mesh quality maintenance ends here *********/ - -/*****************************************************************************/ -/* */ -/* highorder() Create extra nodes for quadratic subparametric elements. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void highorder(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void highorder(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri triangleloop, trisym; - struct osub checkmark; - vertex newvertex; - vertex torg, tdest; - int i; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - - if (!b->quiet) { - printf("Adding vertices for second-order triangles.\n"); - } - /* The following line ensures that dead items in the pool of nodes */ - /* cannot be allocated for the extra nodes associated with high */ - /* order elements. This ensures that the primary nodes (at the */ - /* corners of elements) will occur earlier in the output files, and */ - /* have lower indices, than the extra nodes. */ - m->vertices.deaditemstack = (VOID *) NULL; - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - /* To loop over the set of edges, loop over all triangles, and look at */ - /* the three edges of each triangle. If there isn't another triangle */ - /* adjacent to the edge, operate on the edge. If there is another */ - /* adjacent triangle, operate on the edge only if the current triangle */ - /* has a smaller pointer than its neighbor. This way, each edge is */ - /* considered only once. */ - while (triangleloop.tri != (triangle *) NULL) { - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - sym(triangleloop, trisym); - if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) { - org(triangleloop, torg); - dest(triangleloop, tdest); - /* Create a new node in the middle of the edge. Interpolate */ - /* its attributes. */ - newvertex = (vertex) poolalloc(&m->vertices); - for (i = 0; i < 2 + m->nextras; i++) { - newvertex[i] = 0.5 * (torg[i] + tdest[i]); - } - /* Set the new node's marker to zero or one, depending on */ - /* whether it lies on a boundary. */ - setvertexmark(newvertex, trisym.tri == m->dummytri); - setvertextype(newvertex, - trisym.tri == m->dummytri ? FREEVERTEX : SEGMENTVERTEX); - if (b->usesegments) { - tspivot(triangleloop, checkmark); - /* If this edge is a segment, transfer the marker to the new node. */ - if (checkmark.ss != m->dummysub) { - setvertexmark(newvertex, mark(checkmark)); - setvertextype(newvertex, SEGMENTVERTEX); - } - } - if (b->verbose > 1) { - printf(" Creating (%.12g, %.12g).\n", newvertex[0], newvertex[1]); - } - /* Record the new node in the (one or two) adjacent elements. */ - triangleloop.tri[m->highorderindex + triangleloop.orient] = - (triangle) newvertex; - if (trisym.tri != m->dummytri) { - trisym.tri[m->highorderindex + trisym.orient] = (triangle) newvertex; - } - } - } - triangleloop.tri = triangletraverse(m); - } -} - -/********* File I/O routines begin here *********/ -/** **/ -/** **/ - -/*****************************************************************************/ -/* */ -/* readline() Read a nonempty line from a file. */ -/* */ -/* A line is considered "nonempty" if it contains something that looks like */ -/* a number. Comments (prefaced by `#') are ignored. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -#ifdef ANSI_DECLARATORS -char *readline(char *string, FILE *infile, char *infilename) -#else /* not ANSI_DECLARATORS */ -char *readline(string, infile, infilename) -char *string; -FILE *infile; -char *infilename; -#endif /* not ANSI_DECLARATORS */ - -{ - char *result; - - /* Search for something that looks like a number. */ - do { - result = fgets(string, INPUTLINESIZE, infile); - if (result == (char *) NULL) { - printf(" Error: Unexpected end of file in %s.\n", infilename); - exit(1); - } - /* Skip anything that doesn't look like a number, a comment, */ - /* or the end of a line. */ - while ((*result != '\0') && (*result != '#') - && (*result != '.') && (*result != '+') && (*result != '-') - && ((*result < '0') || (*result > '9'))) { - result++; - } - /* If it's a comment or end of line, read another line and try again. */ - } while ((*result == '#') || (*result == '\0')); - return result; -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* findfield() Find the next field of a string. */ -/* */ -/* Jumps past the current field by searching for whitespace, then jumps */ -/* past the whitespace to find the next field. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -#ifdef ANSI_DECLARATORS -char *findfield(char *string) -#else /* not ANSI_DECLARATORS */ -char *findfield(string) -char *string; -#endif /* not ANSI_DECLARATORS */ - -{ - char *result; - - result = string; - /* Skip the current field. Stop upon reaching whitespace. */ - while ((*result != '\0') && (*result != '#') - && (*result != ' ') && (*result != '\t')) { - result++; - } - /* Now skip the whitespace and anything else that doesn't look like a */ - /* number, a comment, or the end of a line. */ - while ((*result != '\0') && (*result != '#') - && (*result != '.') && (*result != '+') && (*result != '-') - && ((*result < '0') || (*result > '9'))) { - result++; - } - /* Check for a comment (prefixed with `#'). */ - if (*result == '#') { - *result = '\0'; - } - return result; -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* readnodes() Read the vertices from a file, which may be a .node or */ -/* .poly file. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void readnodes(struct mesh *m, struct behavior *b, char *nodefilename, - char *polyfilename, FILE **polyfile) -#else /* not ANSI_DECLARATORS */ -void readnodes(m, b, nodefilename, polyfilename, polyfile) -struct mesh *m; -struct behavior *b; -char *nodefilename; -char *polyfilename; -FILE **polyfile; -#endif /* not ANSI_DECLARATORS */ - -{ - FILE *infile; - vertex vertexloop; - char inputline[INPUTLINESIZE]; - char *stringptr; - char *infilename; - REAL x, y; - int firstnode; - int nodemarkers; - int currentmarker; - int i, j; - - if (b->poly) { - /* Read the vertices from a .poly file. */ - if (!b->quiet) { - printf("Opening %s.\n", polyfilename); - } - *polyfile = fopen(polyfilename, "r"); - if (*polyfile == (FILE *) NULL) { - printf(" Error: Cannot access file %s.\n", polyfilename); - exit(1); - } - /* Read number of vertices, number of dimensions, number of vertex */ - /* attributes, and number of boundary markers. */ - stringptr = readline(inputline, *polyfile, polyfilename); - m->invertices = (int) strtol(stringptr, &stringptr, 0); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - m->mesh_dim = 2; - } else { - m->mesh_dim = (int) strtol(stringptr, &stringptr, 0); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - m->nextras = 0; - } else { - m->nextras = (int) strtol(stringptr, &stringptr, 0); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - nodemarkers = 0; - } else { - nodemarkers = (int) strtol(stringptr, &stringptr, 0); - } - if (m->invertices > 0) { - infile = *polyfile; - infilename = polyfilename; - m->readnodefile = 0; - } else { - /* If the .poly file claims there are zero vertices, that means that */ - /* the vertices should be read from a separate .node file. */ - m->readnodefile = 1; - infilename = nodefilename; - } - } else { - m->readnodefile = 1; - infilename = nodefilename; - *polyfile = (FILE *) NULL; - } - - if (m->readnodefile) { - /* Read the vertices from a .node file. */ - if (!b->quiet) { - printf("Opening %s.\n", nodefilename); - } - infile = fopen(nodefilename, "r"); - if (infile == (FILE *) NULL) { - printf(" Error: Cannot access file %s.\n", nodefilename); - exit(1); - } - /* Read number of vertices, number of dimensions, number of vertex */ - /* attributes, and number of boundary markers. */ - stringptr = readline(inputline, infile, nodefilename); - m->invertices = (int) strtol(stringptr, &stringptr, 0); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - m->mesh_dim = 2; - } else { - m->mesh_dim = (int) strtol(stringptr, &stringptr, 0); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - m->nextras = 0; - } else { - m->nextras = (int) strtol(stringptr, &stringptr, 0); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - nodemarkers = 0; - } else { - nodemarkers = (int) strtol(stringptr, &stringptr, 0); - } - } - - if (m->invertices < 3) { - printf("Error: Input must have at least three input vertices.\n"); - exit(1); - } - if (m->mesh_dim != 2) { - printf("Error: Triangle only works with two-dimensional meshes.\n"); - exit(1); - } - if (m->nextras == 0) { - b->weighted = 0; - } - - initializevertexpool(m, b); - - /* Read the vertices. */ - for (i = 0; i < m->invertices; i++) { - vertexloop = (vertex) poolalloc(&m->vertices); - stringptr = readline(inputline, infile, infilename); - if (i == 0) { - firstnode = (int) strtol(stringptr, &stringptr, 0); - if ((firstnode == 0) || (firstnode == 1)) { - b->firstnumber = firstnode; - } - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Vertex %d has no x coordinate.\n", b->firstnumber + i); - exit(1); - } - x = (REAL) strtod(stringptr, &stringptr); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Vertex %d has no y coordinate.\n", b->firstnumber + i); - exit(1); - } - y = (REAL) strtod(stringptr, &stringptr); - vertexloop[0] = x; - vertexloop[1] = y; - /* Read the vertex attributes. */ - for (j = 2; j < 2 + m->nextras; j++) { - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - vertexloop[j] = 0.0; - } else { - vertexloop[j] = (REAL) strtod(stringptr, &stringptr); - } - } - if (nodemarkers) { - /* Read a vertex marker. */ - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - setvertexmark(vertexloop, 0); - } else { - currentmarker = (int) strtol(stringptr, &stringptr, 0); - setvertexmark(vertexloop, currentmarker); - } - } else { - /* If no markers are specified in the file, they default to zero. */ - setvertexmark(vertexloop, 0); - } - setvertextype(vertexloop, INPUTVERTEX); - /* Determine the smallest and largest x and y coordinates. */ - if (i == 0) { - m->xmin = m->xmax = x; - m->ymin = m->ymax = y; - } else { - m->xmin = (x < m->xmin) ? x : m->xmin; - m->xmax = (x > m->xmax) ? x : m->xmax; - m->ymin = (y < m->ymin) ? y : m->ymin; - m->ymax = (y > m->ymax) ? y : m->ymax; - } - } - if (m->readnodefile) { - fclose(infile); - } - - /* Nonexistent x value used as a flag to mark circle events in sweepline */ - /* Delaunay algorithm. */ - m->xminextreme = 10 * m->xmin - 9 * m->xmax; -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* transfernodes() Read the vertices from memory. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void transfernodes(struct mesh *m, struct behavior *b, REAL *pointlist, - REAL *pointattriblist, int *pointmarkerlist, - int numberofpoints, int numberofpointattribs) -#else /* not ANSI_DECLARATORS */ -void transfernodes(m, b, pointlist, pointattriblist, pointmarkerlist, - numberofpoints, numberofpointattribs) -struct mesh *m; -struct behavior *b; -REAL *pointlist; -REAL *pointattriblist; -int *pointmarkerlist; -int numberofpoints; -int numberofpointattribs; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex vertexloop; - REAL x, y; - int i, j; - int coordindex; - int attribindex; - - m->invertices = numberofpoints; - m->mesh_dim = 2; - m->nextras = numberofpointattribs; - m->readnodefile = 0; - if (m->invertices < 3) { - printf("Error: Input must have at least three input vertices.\n"); - exit(1); - } - if (m->nextras == 0) { - b->weighted = 0; - } - - initializevertexpool(m, b); - - /* Read the vertices. */ - coordindex = 0; - attribindex = 0; - for (i = 0; i < m->invertices; i++) { - vertexloop = (vertex) poolalloc(&m->vertices); - /* Read the vertex coordinates. */ - x = vertexloop[0] = pointlist[coordindex++]; - y = vertexloop[1] = pointlist[coordindex++]; - /* Read the vertex attributes. */ - for (j = 0; j < numberofpointattribs; j++) { - vertexloop[2 + j] = pointattriblist[attribindex++]; - } - if (pointmarkerlist != (int *) NULL) { - /* Read a vertex marker. */ - setvertexmark(vertexloop, pointmarkerlist[i]); - } else { - /* If no markers are specified, they default to zero. */ - setvertexmark(vertexloop, 0); - } - setvertextype(vertexloop, INPUTVERTEX); - /* Determine the smallest and largest x and y coordinates. */ - if (i == 0) { - m->xmin = m->xmax = x; - m->ymin = m->ymax = y; - } else { - m->xmin = (x < m->xmin) ? x : m->xmin; - m->xmax = (x > m->xmax) ? x : m->xmax; - m->ymin = (y < m->ymin) ? y : m->ymin; - m->ymax = (y > m->ymax) ? y : m->ymax; - } - } - - /* Nonexistent x value used as a flag to mark circle events in sweepline */ - /* Delaunay algorithm. */ - m->xminextreme = 10 * m->xmin - 9 * m->xmax; -} - -#endif /* TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* readholes() Read the holes, and possibly regional attributes and area */ -/* constraints, from a .poly file. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void readholes(struct mesh *m, struct behavior *b, - FILE *polyfile, char *polyfilename, REAL **hlist, int *holes, - REAL **rlist, int *regions) -#else /* not ANSI_DECLARATORS */ -void readholes(m, b, polyfile, polyfilename, hlist, holes, rlist, regions) -struct mesh *m; -struct behavior *b; -FILE *polyfile; -char *polyfilename; -REAL **hlist; -int *holes; -REAL **rlist; -int *regions; -#endif /* not ANSI_DECLARATORS */ - -{ - REAL *holelist; - REAL *regionlist; - char inputline[INPUTLINESIZE]; - char *stringptr; - int index; - int i; - - /* Read the holes. */ - stringptr = readline(inputline, polyfile, polyfilename); - *holes = (int) strtol(stringptr, &stringptr, 0); - if (*holes > 0) { - holelist = (REAL *) trimalloc(2 * *holes * (int) sizeof(REAL)); - *hlist = holelist; - for (i = 0; i < 2 * *holes; i += 2) { - stringptr = readline(inputline, polyfile, polyfilename); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Hole %d has no x coordinate.\n", - b->firstnumber + (i >> 1)); - exit(1); - } else { - holelist[i] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Hole %d has no y coordinate.\n", - b->firstnumber + (i >> 1)); - exit(1); - } else { - holelist[i + 1] = (REAL) strtod(stringptr, &stringptr); - } - } - } else { - *hlist = (REAL *) NULL; - } - -#ifndef CDT_ONLY - if ((b->regionattrib || b->vararea) && !b->refine) { - /* Read the area constraints. */ - stringptr = readline(inputline, polyfile, polyfilename); - *regions = (int) strtol(stringptr, &stringptr, 0); - if (*regions > 0) { - regionlist = (REAL *) trimalloc(4 * *regions * (int) sizeof(REAL)); - *rlist = regionlist; - index = 0; - for (i = 0; i < *regions; i++) { - stringptr = readline(inputline, polyfile, polyfilename); - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Region %d has no x coordinate.\n", - b->firstnumber + i); - exit(1); - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf("Error: Region %d has no y coordinate.\n", - b->firstnumber + i); - exit(1); - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - printf( - "Error: Region %d has no region attribute or area constraint.\n", - b->firstnumber + i); - exit(1); - } else { - regionlist[index++] = (REAL) strtod(stringptr, &stringptr); - } - stringptr = findfield(stringptr); - if (*stringptr == '\0') { - regionlist[index] = regionlist[index - 1]; - } else { - regionlist[index] = (REAL) strtod(stringptr, &stringptr); - } - index++; - } - } - } else { - /* Set `*regions' to zero to avoid an accidental free() later. */ - *regions = 0; - *rlist = (REAL *) NULL; - } -#endif /* not CDT_ONLY */ - - fclose(polyfile); -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* finishfile() Write the command line to the output file so the user */ -/* can remember how the file was generated. Close the file. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void finishfile(FILE *outfile, int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void finishfile(outfile, argc, argv) -FILE *outfile; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -{ - int i; - - fprintf(outfile, "# Generated by"); - for (i = 0; i < argc; i++) { - fprintf(outfile, " "); - fputs(argv[i], outfile); - } - fprintf(outfile, "\n"); - fclose(outfile); -} - -#endif /* not TRILIBRARY */ - -/*****************************************************************************/ -/* */ -/* writenodes() Number the vertices and write them to a .node file. */ -/* */ -/* To save memory, the vertex numbers are written over the boundary markers */ -/* after the vertices are written to a file. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writenodes(struct mesh *m, struct behavior *b, REAL **pointlist, - REAL **pointattriblist, int **pointmarkerlist) -#else /* not ANSI_DECLARATORS */ -void writenodes(m, b, pointlist, pointattriblist, pointmarkerlist) -struct mesh *m; -struct behavior *b; -REAL **pointlist; -REAL **pointattriblist; -int **pointmarkerlist; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void writenodes(struct mesh *m, struct behavior *b, char *nodefilename, - int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writenodes(m, b, nodefilename, argc, argv) -struct mesh *m; -struct behavior *b; -char *nodefilename; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - REAL *plist; - REAL *palist; - int *pmlist; - int coordindex; - int attribindex; -#else /* not TRILIBRARY */ - FILE *outfile; -#endif /* not TRILIBRARY */ - vertex vertexloop; - long outvertices; - int vertexnumber; - int i; - - if (b->jettison) { - outvertices = m->vertices.items - m->undeads; - } else { - outvertices = m->vertices.items; - } - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing vertices.\n"); - } - /* Allocate memory for output vertices if necessary. */ - if (*pointlist == (REAL *) NULL) { - *pointlist = (REAL *) trimalloc(outvertices * 2 * sizeof(REAL)); - } - /* Allocate memory for output vertex attributes if necessary. */ - if ((m->nextras > 0) && (*pointattriblist == (REAL *) NULL)) { - *pointattriblist = (REAL *) trimalloc(outvertices * m->nextras * - sizeof(REAL)); - } - /* Allocate memory for output vertex markers if necessary. */ - if (!b->nobound && (*pointmarkerlist == (int *) NULL)) { - *pointmarkerlist = (int *) trimalloc(outvertices * sizeof(int)); - } - plist = *pointlist; - palist = *pointattriblist; - pmlist = *pointmarkerlist; - coordindex = 0; - attribindex = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", nodefilename); - } - outfile = fopen(nodefilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", nodefilename); - exit(1); - } - /* Number of vertices, number of dimensions, number of vertex attributes, */ - /* and number of boundary markers (zero or one). */ - fprintf(outfile, "%ld %d %d %d\n", outvertices, m->mesh_dim, - m->nextras, 1 - b->nobound); -#endif /* not TRILIBRARY */ - - traversalinit(&m->vertices); - vertexnumber = b->firstnumber; - vertexloop = vertextraverse(m); - while (vertexloop != (vertex) NULL) { - if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) { -#ifdef TRILIBRARY - /* X and y coordinates. */ - plist[coordindex++] = vertexloop[0]; - plist[coordindex++] = vertexloop[1]; - /* Vertex attributes. */ - for (i = 0; i < m->nextras; i++) { - palist[attribindex++] = vertexloop[2 + i]; - } - if (!b->nobound) { - /* Copy the boundary marker. */ - pmlist[vertexnumber - b->firstnumber] = vertexmark(vertexloop); - } -#else /* not TRILIBRARY */ - /* Vertex number, x and y coordinates. */ - fprintf(outfile, "%4d %.17g %.17g", vertexnumber, vertexloop[0], - vertexloop[1]); - for (i = 0; i < m->nextras; i++) { - /* Write an attribute. */ - fprintf(outfile, " %.17g", vertexloop[i + 2]); - } - if (b->nobound) { - fprintf(outfile, "\n"); - } else { - /* Write the boundary marker. */ - fprintf(outfile, " %d\n", vertexmark(vertexloop)); - } -#endif /* not TRILIBRARY */ - - setvertexmark(vertexloop, vertexnumber); - vertexnumber++; - } - vertexloop = vertextraverse(m); - } - -#ifndef TRILIBRARY - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ -} - -/*****************************************************************************/ -/* */ -/* numbernodes() Number the vertices. */ -/* */ -/* Each vertex is assigned a marker equal to its number. */ -/* */ -/* Used when writenodes() is not called because no .node file is written. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void numbernodes(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void numbernodes(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - vertex vertexloop; - int vertexnumber; - - traversalinit(&m->vertices); - vertexnumber = b->firstnumber; - vertexloop = vertextraverse(m); - while (vertexloop != (vertex) NULL) { - setvertexmark(vertexloop, vertexnumber); - if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) { - vertexnumber++; - } - vertexloop = vertextraverse(m); - } -} - -/*****************************************************************************/ -/* */ -/* writeelements() Write the triangles to an .ele file. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writeelements(struct mesh *m, struct behavior *b, - int **trianglelist, REAL **triangleattriblist) -#else /* not ANSI_DECLARATORS */ -void writeelements(m, b, trianglelist, triangleattriblist) -struct mesh *m; -struct behavior *b; -int **trianglelist; -REAL **triangleattriblist; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void writeelements(struct mesh *m, struct behavior *b, char *elefilename, - int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writeelements(m, b, elefilename, argc, argv) -struct mesh *m; -struct behavior *b; -char *elefilename; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - int *tlist; - REAL *talist; - int vertexindex; - int attribindex; -#else /* not TRILIBRARY */ - FILE *outfile; -#endif /* not TRILIBRARY */ - struct otri triangleloop; - vertex p1, p2, p3; - vertex mid1, mid2, mid3; - long elementnumber; - int i; - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing triangles.\n"); - } - /* Allocate memory for output triangles if necessary. */ - if (*trianglelist == (int *) NULL) { - *trianglelist = (int *) trimalloc(m->triangles.items * - ((b->order + 1) * (b->order + 2) / 2) * - sizeof(int)); - } - /* Allocate memory for output triangle attributes if necessary. */ - if ((m->eextras > 0) && (*triangleattriblist == (REAL *) NULL)) { - *triangleattriblist = (REAL *) trimalloc(m->triangles.items * m->eextras * - sizeof(REAL)); - } - tlist = *trianglelist; - talist = *triangleattriblist; - vertexindex = 0; - attribindex = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", elefilename); - } - outfile = fopen(elefilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", elefilename); - exit(1); - } - /* Number of triangles, vertices per triangle, attributes per triangle. */ - fprintf(outfile, "%ld %d %d\n", m->triangles.items, - (b->order + 1) * (b->order + 2) / 2, m->eextras); -#endif /* not TRILIBRARY */ - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - triangleloop.orient = 0; - elementnumber = b->firstnumber; - while (triangleloop.tri != (triangle *) NULL) { - org(triangleloop, p1); - dest(triangleloop, p2); - apex(triangleloop, p3); - if (b->order == 1) { -#ifdef TRILIBRARY - tlist[vertexindex++] = vertexmark(p1); - tlist[vertexindex++] = vertexmark(p2); - tlist[vertexindex++] = vertexmark(p3); -#else /* not TRILIBRARY */ - /* Triangle number, indices for three vertices. */ - fprintf(outfile, "%4ld %4d %4d %4d", elementnumber, - vertexmark(p1), vertexmark(p2), vertexmark(p3)); -#endif /* not TRILIBRARY */ - } else { - mid1 = (vertex) triangleloop.tri[m->highorderindex + 1]; - mid2 = (vertex) triangleloop.tri[m->highorderindex + 2]; - mid3 = (vertex) triangleloop.tri[m->highorderindex]; -#ifdef TRILIBRARY - tlist[vertexindex++] = vertexmark(p1); - tlist[vertexindex++] = vertexmark(p2); - tlist[vertexindex++] = vertexmark(p3); - tlist[vertexindex++] = vertexmark(mid1); - tlist[vertexindex++] = vertexmark(mid2); - tlist[vertexindex++] = vertexmark(mid3); -#else /* not TRILIBRARY */ - /* Triangle number, indices for six vertices. */ - fprintf(outfile, "%4ld %4d %4d %4d %4d %4d %4d", elementnumber, - vertexmark(p1), vertexmark(p2), vertexmark(p3), vertexmark(mid1), - vertexmark(mid2), vertexmark(mid3)); -#endif /* not TRILIBRARY */ - } - -#ifdef TRILIBRARY - for (i = 0; i < m->eextras; i++) { - talist[attribindex++] = elemattribute(triangleloop, i); - } -#else /* not TRILIBRARY */ - for (i = 0; i < m->eextras; i++) { - fprintf(outfile, " %.17g", elemattribute(triangleloop, i)); - } - fprintf(outfile, "\n"); -#endif /* not TRILIBRARY */ - - triangleloop.tri = triangletraverse(m); - elementnumber++; - } - -#ifndef TRILIBRARY - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ -} - -/*****************************************************************************/ -/* */ -/* writepoly() Write the segments and holes to a .poly file. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writepoly(struct mesh *m, struct behavior *b, - int **segmentlist, int **segmentmarkerlist) -#else /* not ANSI_DECLARATORS */ -void writepoly(m, b, segmentlist, segmentmarkerlist) -struct mesh *m; -struct behavior *b; -int **segmentlist; -int **segmentmarkerlist; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void writepoly(struct mesh *m, struct behavior *b, char *polyfilename, - REAL *holelist, int holes, REAL *regionlist, int regions, - int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writepoly(m, b, polyfilename, holelist, holes, regionlist, regions, - argc, argv) -struct mesh *m; -struct behavior *b; -char *polyfilename; -REAL *holelist; -int holes; -REAL *regionlist; -int regions; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - int *slist; - int *smlist; - int index; -#else /* not TRILIBRARY */ - FILE *outfile; - long holenumber, regionnumber; -#endif /* not TRILIBRARY */ - struct osub subsegloop; - vertex endpoint1, endpoint2; - long subsegnumber; - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing segments.\n"); - } - /* Allocate memory for output segments if necessary. */ - if (*segmentlist == (int *) NULL) { - *segmentlist = (int *) trimalloc(m->subsegs.items * 2 * sizeof(int)); - } - /* Allocate memory for output segment markers if necessary. */ - if (!b->nobound && (*segmentmarkerlist == (int *) NULL)) { - *segmentmarkerlist = (int *) trimalloc(m->subsegs.items * sizeof(int)); - } - slist = *segmentlist; - smlist = *segmentmarkerlist; - index = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", polyfilename); - } - outfile = fopen(polyfilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", polyfilename); - exit(1); - } - /* The zero indicates that the vertices are in a separate .node file. */ - /* Followed by number of dimensions, number of vertex attributes, */ - /* and number of boundary markers (zero or one). */ - fprintf(outfile, "%d %d %d %d\n", 0, m->mesh_dim, m->nextras, - 1 - b->nobound); - /* Number of segments, number of boundary markers (zero or one). */ - fprintf(outfile, "%ld %d\n", m->subsegs.items, 1 - b->nobound); -#endif /* not TRILIBRARY */ - - traversalinit(&m->subsegs); - subsegloop.ss = subsegtraverse(m); - subsegloop.ssorient = 0; - subsegnumber = b->firstnumber; - while (subsegloop.ss != (subseg *) NULL) { - sorg(subsegloop, endpoint1); - sdest(subsegloop, endpoint2); -#ifdef TRILIBRARY - /* Copy indices of the segment's two endpoints. */ - slist[index++] = vertexmark(endpoint1); - slist[index++] = vertexmark(endpoint2); - if (!b->nobound) { - /* Copy the boundary marker. */ - smlist[subsegnumber - b->firstnumber] = mark(subsegloop); - } -#else /* not TRILIBRARY */ - /* Segment number, indices of its two endpoints, and possibly a marker. */ - if (b->nobound) { - fprintf(outfile, "%4ld %4d %4d\n", subsegnumber, - vertexmark(endpoint1), vertexmark(endpoint2)); - } else { - fprintf(outfile, "%4ld %4d %4d %4d\n", subsegnumber, - vertexmark(endpoint1), vertexmark(endpoint2), mark(subsegloop)); - } -#endif /* not TRILIBRARY */ - - subsegloop.ss = subsegtraverse(m); - subsegnumber++; - } - -#ifndef TRILIBRARY -#ifndef CDT_ONLY - fprintf(outfile, "%d\n", holes); - if (holes > 0) { - for (holenumber = 0; holenumber < holes; holenumber++) { - /* Hole number, x and y coordinates. */ - fprintf(outfile, "%4ld %.17g %.17g\n", b->firstnumber + holenumber, - holelist[2 * holenumber], holelist[2 * holenumber + 1]); - } - } - if (regions > 0) { - fprintf(outfile, "%d\n", regions); - for (regionnumber = 0; regionnumber < regions; regionnumber++) { - /* Region number, x and y coordinates, attribute, maximum area. */ - fprintf(outfile, "%4ld %.17g %.17g %.17g %.17g\n", - b->firstnumber + regionnumber, - regionlist[4 * regionnumber], regionlist[4 * regionnumber + 1], - regionlist[4 * regionnumber + 2], - regionlist[4 * regionnumber + 3]); - } - } -#endif /* not CDT_ONLY */ - - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ -} - -/*****************************************************************************/ -/* */ -/* writeedges() Write the edges to an .edge file. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writeedges(struct mesh *m, struct behavior *b, - int **edgelist, int **edgemarkerlist) -#else /* not ANSI_DECLARATORS */ -void writeedges(m, b, edgelist, edgemarkerlist) -struct mesh *m; -struct behavior *b; -int **edgelist; -int **edgemarkerlist; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void writeedges(struct mesh *m, struct behavior *b, char *edgefilename, - int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writeedges(m, b, edgefilename, argc, argv) -struct mesh *m; -struct behavior *b; -char *edgefilename; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - int *elist; - int *emlist; - int index; -#else /* not TRILIBRARY */ - FILE *outfile; -#endif /* not TRILIBRARY */ - struct otri triangleloop, trisym; - struct osub checkmark; - vertex p1, p2; - long edgenumber; - triangle ptr; /* Temporary variable used by sym(). */ - subseg sptr; /* Temporary variable used by tspivot(). */ - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing edges.\n"); - } - /* Allocate memory for edges if necessary. */ - if (*edgelist == (int *) NULL) { - *edgelist = (int *) trimalloc(m->edges * 2 * sizeof(int)); - } - /* Allocate memory for edge markers if necessary. */ - if (!b->nobound && (*edgemarkerlist == (int *) NULL)) { - *edgemarkerlist = (int *) trimalloc(m->edges * sizeof(int)); - } - elist = *edgelist; - emlist = *edgemarkerlist; - index = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", edgefilename); - } - outfile = fopen(edgefilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", edgefilename); - exit(1); - } - /* Number of edges, number of boundary markers (zero or one). */ - fprintf(outfile, "%ld %d\n", m->edges, 1 - b->nobound); -#endif /* not TRILIBRARY */ - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - edgenumber = b->firstnumber; - /* To loop over the set of edges, loop over all triangles, and look at */ - /* the three edges of each triangle. If there isn't another triangle */ - /* adjacent to the edge, operate on the edge. If there is another */ - /* adjacent triangle, operate on the edge only if the current triangle */ - /* has a smaller pointer than its neighbor. This way, each edge is */ - /* considered only once. */ - while (triangleloop.tri != (triangle *) NULL) { - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - sym(triangleloop, trisym); - if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) { - org(triangleloop, p1); - dest(triangleloop, p2); -#ifdef TRILIBRARY - elist[index++] = vertexmark(p1); - elist[index++] = vertexmark(p2); -#endif /* TRILIBRARY */ - if (b->nobound) { -#ifndef TRILIBRARY - /* Edge number, indices of two endpoints. */ - fprintf(outfile, "%4ld %d %d\n", edgenumber, - vertexmark(p1), vertexmark(p2)); -#endif /* not TRILIBRARY */ - } else { - /* Edge number, indices of two endpoints, and a boundary marker. */ - /* If there's no subsegment, the boundary marker is zero. */ - if (b->usesegments) { - tspivot(triangleloop, checkmark); - if (checkmark.ss == m->dummysub) { -#ifdef TRILIBRARY - emlist[edgenumber - b->firstnumber] = 0; -#else /* not TRILIBRARY */ - fprintf(outfile, "%4ld %d %d %d\n", edgenumber, - vertexmark(p1), vertexmark(p2), 0); -#endif /* not TRILIBRARY */ - } else { -#ifdef TRILIBRARY - emlist[edgenumber - b->firstnumber] = mark(checkmark); -#else /* not TRILIBRARY */ - fprintf(outfile, "%4ld %d %d %d\n", edgenumber, - vertexmark(p1), vertexmark(p2), mark(checkmark)); -#endif /* not TRILIBRARY */ - } - } else { -#ifdef TRILIBRARY - emlist[edgenumber - b->firstnumber] = trisym.tri == m->dummytri; -#else /* not TRILIBRARY */ - fprintf(outfile, "%4ld %d %d %d\n", edgenumber, - vertexmark(p1), vertexmark(p2), trisym.tri == m->dummytri); -#endif /* not TRILIBRARY */ - } - } - edgenumber++; - } - } - triangleloop.tri = triangletraverse(m); - } - -#ifndef TRILIBRARY - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ -} - -/*****************************************************************************/ -/* */ -/* writevoronoi() Write the Voronoi diagram to a .v.node and .v.edge */ -/* file. */ -/* */ -/* The Voronoi diagram is the geometric dual of the Delaunay triangulation. */ -/* Hence, the Voronoi vertices are listed by traversing the Delaunay */ -/* triangles, and the Voronoi edges are listed by traversing the Delaunay */ -/* edges. */ -/* */ -/* WARNING: In order to assign numbers to the Voronoi vertices, this */ -/* procedure messes up the subsegments or the extra nodes of every */ -/* element. Hence, you should call this procedure last. */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writevoronoi(struct mesh *m, struct behavior *b, REAL **vpointlist, - REAL **vpointattriblist, int **vpointmarkerlist, - int **vedgelist, int **vedgemarkerlist, REAL **vnormlist) -#else /* not ANSI_DECLARATORS */ -void writevoronoi(m, b, vpointlist, vpointattriblist, vpointmarkerlist, - vedgelist, vedgemarkerlist, vnormlist) -struct mesh *m; -struct behavior *b; -REAL **vpointlist; -REAL **vpointattriblist; -int **vpointmarkerlist; -int **vedgelist; -int **vedgemarkerlist; -REAL **vnormlist; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void writevoronoi(struct mesh *m, struct behavior *b, char *vnodefilename, - char *vedgefilename, int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writevoronoi(m, b, vnodefilename, vedgefilename, argc, argv) -struct mesh *m; -struct behavior *b; -char *vnodefilename; -char *vedgefilename; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - REAL *plist; - REAL *palist; - int *elist; - REAL *normlist; - int coordindex; - int attribindex; -#else /* not TRILIBRARY */ - FILE *outfile; -#endif /* not TRILIBRARY */ - struct otri triangleloop, trisym; - vertex torg, tdest, tapex; - REAL circumcenter[2]; - REAL xi, eta; - REAL dum; - long vnodenumber, vedgenumber; - int p1, p2; - int i; - triangle ptr; /* Temporary variable used by sym(). */ - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing Voronoi vertices.\n"); - } - /* Allocate memory for Voronoi vertices if necessary. */ - if (*vpointlist == (REAL *) NULL) { - *vpointlist = (REAL *) trimalloc(m->triangles.items * 2 * sizeof(REAL)); - } - /* Allocate memory for Voronoi vertex attributes if necessary. */ - if (*vpointattriblist == (REAL *) NULL) { - *vpointattriblist = (REAL *) trimalloc(m->triangles.items * m->nextras * - sizeof(REAL)); - } - *vpointmarkerlist = (int *) NULL; - plist = *vpointlist; - palist = *vpointattriblist; - coordindex = 0; - attribindex = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", vnodefilename); - } - outfile = fopen(vnodefilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", vnodefilename); - exit(1); - } - /* Number of triangles, two dimensions, number of vertex attributes, */ - /* no markers. */ - fprintf(outfile, "%ld %d %d %d\n", m->triangles.items, 2, m->nextras, 0); -#endif /* not TRILIBRARY */ - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - triangleloop.orient = 0; - vnodenumber = b->firstnumber; - while (triangleloop.tri != (triangle *) NULL) { - org(triangleloop, torg); - dest(triangleloop, tdest); - apex(triangleloop, tapex); - findcircumcenter(m, b, torg, tdest, tapex, circumcenter, &xi, &eta, &dum, - 0); -#ifdef TRILIBRARY - /* X and y coordinates. */ - plist[coordindex++] = circumcenter[0]; - plist[coordindex++] = circumcenter[1]; - for (i = 2; i < 2 + m->nextras; i++) { - /* Interpolate the vertex attributes at the circumcenter. */ - palist[attribindex++] = torg[i] + xi * (tdest[i] - torg[i]) - + eta * (tapex[i] - torg[i]); - } -#else /* not TRILIBRARY */ - /* Voronoi vertex number, x and y coordinates. */ - fprintf(outfile, "%4ld %.17g %.17g", vnodenumber, circumcenter[0], - circumcenter[1]); - for (i = 2; i < 2 + m->nextras; i++) { - /* Interpolate the vertex attributes at the circumcenter. */ - fprintf(outfile, " %.17g", torg[i] + xi * (tdest[i] - torg[i]) - + eta * (tapex[i] - torg[i])); - } - fprintf(outfile, "\n"); -#endif /* not TRILIBRARY */ - - * (int *) (triangleloop.tri + 6) = (int) vnodenumber; - triangleloop.tri = triangletraverse(m); - vnodenumber++; - } - -#ifndef TRILIBRARY - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing Voronoi edges.\n"); - } - /* Allocate memory for output Voronoi edges if necessary. */ - if (*vedgelist == (int *) NULL) { - *vedgelist = (int *) trimalloc(m->edges * 2 * sizeof(int)); - } - *vedgemarkerlist = (int *) NULL; - /* Allocate memory for output Voronoi norms if necessary. */ - if (*vnormlist == (REAL *) NULL) { - *vnormlist = (REAL *) trimalloc(m->edges * 2 * sizeof(REAL)); - } - elist = *vedgelist; - normlist = *vnormlist; - coordindex = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", vedgefilename); - } - outfile = fopen(vedgefilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", vedgefilename); - exit(1); - } - /* Number of edges, zero boundary markers. */ - fprintf(outfile, "%ld %d\n", m->edges, 0); -#endif /* not TRILIBRARY */ - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - vedgenumber = b->firstnumber; - /* To loop over the set of edges, loop over all triangles, and look at */ - /* the three edges of each triangle. If there isn't another triangle */ - /* adjacent to the edge, operate on the edge. If there is another */ - /* adjacent triangle, operate on the edge only if the current triangle */ - /* has a smaller pointer than its neighbor. This way, each edge is */ - /* considered only once. */ - while (triangleloop.tri != (triangle *) NULL) { - for (triangleloop.orient = 0; triangleloop.orient < 3; - triangleloop.orient++) { - sym(triangleloop, trisym); - if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) { - /* Find the number of this triangle (and Voronoi vertex). */ - p1 = * (int *) (triangleloop.tri + 6); - if (trisym.tri == m->dummytri) { - org(triangleloop, torg); - dest(triangleloop, tdest); -#ifdef TRILIBRARY - /* Copy an infinite ray. Index of one endpoint, and -1. */ - elist[coordindex] = p1; - normlist[coordindex++] = tdest[1] - torg[1]; - elist[coordindex] = -1; - normlist[coordindex++] = torg[0] - tdest[0]; -#else /* not TRILIBRARY */ - /* Write an infinite ray. Edge number, index of one endpoint, -1, */ - /* and x and y coordinates of a vector representing the */ - /* direction of the ray. */ - fprintf(outfile, "%4ld %d %d %.17g %.17g\n", vedgenumber, - p1, -1, tdest[1] - torg[1], torg[0] - tdest[0]); -#endif /* not TRILIBRARY */ - } else { - /* Find the number of the adjacent triangle (and Voronoi vertex). */ - p2 = * (int *) (trisym.tri + 6); - /* Finite edge. Write indices of two endpoints. */ -#ifdef TRILIBRARY - elist[coordindex] = p1; - normlist[coordindex++] = 0.0; - elist[coordindex] = p2; - normlist[coordindex++] = 0.0; -#else /* not TRILIBRARY */ - fprintf(outfile, "%4ld %d %d\n", vedgenumber, p1, p2); -#endif /* not TRILIBRARY */ - } - vedgenumber++; - } - } - triangleloop.tri = triangletraverse(m); - } - -#ifndef TRILIBRARY - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ -} - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writeneighbors(struct mesh *m, struct behavior *b, int **neighborlist) -#else /* not ANSI_DECLARATORS */ -void writeneighbors(m, b, neighborlist) -struct mesh *m; -struct behavior *b; -int **neighborlist; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -void writeneighbors(struct mesh *m, struct behavior *b, char *neighborfilename, - int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writeneighbors(m, b, neighborfilename, argc, argv) -struct mesh *m; -struct behavior *b; -char *neighborfilename; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ -#ifdef TRILIBRARY - int *nlist; - int index; -#else /* not TRILIBRARY */ - FILE *outfile; -#endif /* not TRILIBRARY */ - struct otri triangleloop, trisym; - long elementnumber; - int neighbor1, neighbor2, neighbor3; - triangle ptr; /* Temporary variable used by sym(). */ - -#ifdef TRILIBRARY - if (!b->quiet) { - printf("Writing neighbors.\n"); - } - /* Allocate memory for neighbors if necessary. */ - if (*neighborlist == (int *) NULL) { - *neighborlist = (int *) trimalloc(m->triangles.items * 3 * sizeof(int)); - } - nlist = *neighborlist; - index = 0; -#else /* not TRILIBRARY */ - if (!b->quiet) { - printf("Writing %s.\n", neighborfilename); - } - outfile = fopen(neighborfilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", neighborfilename); - exit(1); - } - /* Number of triangles, three neighbors per triangle. */ - fprintf(outfile, "%ld %d\n", m->triangles.items, 3); -#endif /* not TRILIBRARY */ - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - triangleloop.orient = 0; - elementnumber = b->firstnumber; - while (triangleloop.tri != (triangle *) NULL) { - * (int *) (triangleloop.tri + 6) = (int) elementnumber; - triangleloop.tri = triangletraverse(m); - elementnumber++; - } - * (int *) (m->dummytri + 6) = -1; - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - elementnumber = b->firstnumber; - while (triangleloop.tri != (triangle *) NULL) { - triangleloop.orient = 1; - sym(triangleloop, trisym); - neighbor1 = * (int *) (trisym.tri + 6); - triangleloop.orient = 2; - sym(triangleloop, trisym); - neighbor2 = * (int *) (trisym.tri + 6); - triangleloop.orient = 0; - sym(triangleloop, trisym); - neighbor3 = * (int *) (trisym.tri + 6); -#ifdef TRILIBRARY - nlist[index++] = neighbor1; - nlist[index++] = neighbor2; - nlist[index++] = neighbor3; -#else /* not TRILIBRARY */ - /* Triangle number, neighboring triangle numbers. */ - fprintf(outfile, "%4ld %d %d %d\n", elementnumber, - neighbor1, neighbor2, neighbor3); -#endif /* not TRILIBRARY */ - - triangleloop.tri = triangletraverse(m); - elementnumber++; - } - -#ifndef TRILIBRARY - finishfile(outfile, argc, argv); -#endif /* not TRILIBRARY */ -} - -/*****************************************************************************/ -/* */ -/* writeoff() Write the triangulation to an .off file. */ -/* */ -/* OFF stands for the Object File Format, a format used by the Geometry */ -/* Center's Geomview package. */ -/* */ -/*****************************************************************************/ - -#ifndef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void writeoff(struct mesh *m, struct behavior *b, char *offfilename, - int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -void writeoff(m, b, offfilename, argc, argv) -struct mesh *m; -struct behavior *b; -char *offfilename; -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -{ - FILE *outfile; - struct otri triangleloop; - vertex vertexloop; - vertex p1, p2, p3; - long outvertices; - - if (!b->quiet) { - printf("Writing %s.\n", offfilename); - } - - if (b->jettison) { - outvertices = m->vertices.items - m->undeads; - } else { - outvertices = m->vertices.items; - } - - outfile = fopen(offfilename, "w"); - if (outfile == (FILE *) NULL) { - printf(" Error: Cannot create file %s.\n", offfilename); - exit(1); - } - /* Number of vertices, triangles, and edges. */ - fprintf(outfile, "OFF\n%ld %ld %ld\n", outvertices, m->triangles.items, - m->edges); - - /* Write the vertices. */ - traversalinit(&m->vertices); - vertexloop = vertextraverse(m); - while (vertexloop != (vertex) NULL) { - if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) { - /* The "0.0" is here because the OFF format uses 3D coordinates. */ - fprintf(outfile, " %.17g %.17g %.17g\n", vertexloop[0], vertexloop[1], - 0.0); - } - vertexloop = vertextraverse(m); - } - - /* Write the triangles. */ - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - triangleloop.orient = 0; - while (triangleloop.tri != (triangle *) NULL) { - org(triangleloop, p1); - dest(triangleloop, p2); - apex(triangleloop, p3); - /* The "3" means a three-vertex polygon. */ - fprintf(outfile, " 3 %4d %4d %4d\n", vertexmark(p1) - 1, - vertexmark(p2) - 1, vertexmark(p3) - 1); - triangleloop.tri = triangletraverse(m); - } - finishfile(outfile, argc, argv); -} - -#endif /* not TRILIBRARY */ - -/** **/ -/** **/ -/********* File I/O routines end here *********/ - -/*****************************************************************************/ -/* */ -/* quality_statistics() Print statistics about the quality of the mesh. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void quality_statistics(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void quality_statistics(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - struct otri triangleloop; - vertex p[3]; - REAL cossquaretable[8]; - REAL ratiotable[16]; - REAL dx[3], dy[3]; - REAL edgelength[3]; - REAL dotproduct; - REAL cossquare; - REAL triarea; - REAL shortest, longest; - REAL trilongest2; - REAL smallestarea, biggestarea; - REAL triminaltitude2; - REAL minaltitude; - REAL triaspect2; - REAL worstaspect; - REAL smallestangle, biggestangle; - REAL radconst, degconst; - int angletable[18]; - int aspecttable[16]; - int aspectindex; - int tendegree; - int acutebiggest; - int i, ii, j, k; - - printf("Mesh quality statistics:\n\n"); - radconst = PI / 18.0; - degconst = 180.0 / PI; - for (i = 0; i < 8; i++) { - cossquaretable[i] = cos(radconst * (REAL) (i + 1)); - cossquaretable[i] = cossquaretable[i] * cossquaretable[i]; - } - for (i = 0; i < 18; i++) { - angletable[i] = 0; - } - - ratiotable[0] = 1.5; ratiotable[1] = 2.0; - ratiotable[2] = 2.5; ratiotable[3] = 3.0; - ratiotable[4] = 4.0; ratiotable[5] = 6.0; - ratiotable[6] = 10.0; ratiotable[7] = 15.0; - ratiotable[8] = 25.0; ratiotable[9] = 50.0; - ratiotable[10] = 100.0; ratiotable[11] = 300.0; - ratiotable[12] = 1000.0; ratiotable[13] = 10000.0; - ratiotable[14] = 100000.0; ratiotable[15] = 0.0; - for (i = 0; i < 16; i++) { - aspecttable[i] = 0; - } - - worstaspect = 0.0; - minaltitude = m->xmax - m->xmin + m->ymax - m->ymin; - minaltitude = minaltitude * minaltitude; - shortest = minaltitude; - longest = 0.0; - smallestarea = minaltitude; - biggestarea = 0.0; - worstaspect = 0.0; - smallestangle = 0.0; - biggestangle = 2.0; - acutebiggest = 1; - - traversalinit(&m->triangles); - triangleloop.tri = triangletraverse(m); - triangleloop.orient = 0; - while (triangleloop.tri != (triangle *) NULL) { - org(triangleloop, p[0]); - dest(triangleloop, p[1]); - apex(triangleloop, p[2]); - trilongest2 = 0.0; - - for (i = 0; i < 3; i++) { - j = plus1mod3[i]; - k = minus1mod3[i]; - dx[i] = p[j][0] - p[k][0]; - dy[i] = p[j][1] - p[k][1]; - edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i]; - if (edgelength[i] > trilongest2) { - trilongest2 = edgelength[i]; - } - if (edgelength[i] > longest) { - longest = edgelength[i]; - } - if (edgelength[i] < shortest) { - shortest = edgelength[i]; - } - } - - triarea = counterclockwise(m, b, p[0], p[1], p[2]); - if (triarea < smallestarea) { - smallestarea = triarea; - } - if (triarea > biggestarea) { - biggestarea = triarea; - } - triminaltitude2 = triarea * triarea / trilongest2; - if (triminaltitude2 < minaltitude) { - minaltitude = triminaltitude2; - } - triaspect2 = trilongest2 / triminaltitude2; - if (triaspect2 > worstaspect) { - worstaspect = triaspect2; - } - aspectindex = 0; - while ((triaspect2 > ratiotable[aspectindex] * ratiotable[aspectindex]) - && (aspectindex < 15)) { - aspectindex++; - } - aspecttable[aspectindex]++; - - for (i = 0; i < 3; i++) { - j = plus1mod3[i]; - k = minus1mod3[i]; - dotproduct = dx[j] * dx[k] + dy[j] * dy[k]; - cossquare = dotproduct * dotproduct / (edgelength[j] * edgelength[k]); - tendegree = 8; - for (ii = 7; ii >= 0; ii--) { - if (cossquare > cossquaretable[ii]) { - tendegree = ii; - } - } - if (dotproduct <= 0.0) { - angletable[tendegree]++; - if (cossquare > smallestangle) { - smallestangle = cossquare; - } - if (acutebiggest && (cossquare < biggestangle)) { - biggestangle = cossquare; - } - } else { - angletable[17 - tendegree]++; - if (acutebiggest || (cossquare > biggestangle)) { - biggestangle = cossquare; - acutebiggest = 0; - } - } - } - triangleloop.tri = triangletraverse(m); - } - - shortest = sqrt(shortest); - longest = sqrt(longest); - minaltitude = sqrt(minaltitude); - worstaspect = sqrt(worstaspect); - smallestarea *= 0.5; - biggestarea *= 0.5; - if (smallestangle >= 1.0) { - smallestangle = 0.0; - } else { - smallestangle = degconst * acos(sqrt(smallestangle)); - } - if (biggestangle >= 1.0) { - biggestangle = 180.0; - } else { - if (acutebiggest) { - biggestangle = degconst * acos(sqrt(biggestangle)); - } else { - biggestangle = 180.0 - degconst * acos(sqrt(biggestangle)); - } - } - - printf(" Smallest area: %16.5g | Largest area: %16.5g\n", - smallestarea, biggestarea); - printf(" Shortest edge: %16.5g | Longest edge: %16.5g\n", - shortest, longest); - printf(" Shortest altitude: %12.5g | Largest aspect ratio: %8.5g\n\n", - minaltitude, worstaspect); - - printf(" Triangle aspect ratio histogram:\n"); - printf(" 1.1547 - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n", - ratiotable[0], aspecttable[0], ratiotable[7], ratiotable[8], - aspecttable[8]); - for (i = 1; i < 7; i++) { - printf(" %6.6g - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n", - ratiotable[i - 1], ratiotable[i], aspecttable[i], - ratiotable[i + 7], ratiotable[i + 8], aspecttable[i + 8]); - } - printf(" %6.6g - %-6.6g : %8d | %6.6g - : %8d\n", - ratiotable[6], ratiotable[7], aspecttable[7], ratiotable[14], - aspecttable[15]); - printf(" (Aspect ratio is longest edge divided by shortest altitude)\n\n"); - - printf(" Smallest angle: %15.5g | Largest angle: %15.5g\n\n", - smallestangle, biggestangle); - - printf(" Angle histogram:\n"); - for (i = 0; i < 9; i++) { - printf(" %3d - %3d degrees: %8d | %3d - %3d degrees: %8d\n", - i * 10, i * 10 + 10, angletable[i], - i * 10 + 90, i * 10 + 100, angletable[i + 9]); - } - printf("\n"); -} - -/*****************************************************************************/ -/* */ -/* statistics() Print all sorts of cool facts. */ -/* */ -/*****************************************************************************/ - -#ifdef ANSI_DECLARATORS -void statistics(struct mesh *m, struct behavior *b) -#else /* not ANSI_DECLARATORS */ -void statistics(m, b) -struct mesh *m; -struct behavior *b; -#endif /* not ANSI_DECLARATORS */ - -{ - printf("\nStatistics:\n\n"); - printf(" Input vertices: %d\n", m->invertices); - if (b->refine) { - printf(" Input triangles: %d\n", m->inelements); - } - if (b->poly) { - printf(" Input segments: %d\n", m->insegments); - if (!b->refine) { - printf(" Input holes: %d\n", m->holes); - } - } - - printf("\n Mesh vertices: %ld\n", m->vertices.items - m->undeads); - printf(" Mesh triangles: %ld\n", m->triangles.items); - printf(" Mesh edges: %ld\n", m->edges); - printf(" Mesh exterior boundary edges: %ld\n", m->hullsize); - if (b->poly || b->refine) { - printf(" Mesh interior boundary edges: %ld\n", - m->subsegs.items - m->hullsize); - printf(" Mesh subsegments (constrained edges): %ld\n", - m->subsegs.items); - } - printf("\n"); - - if (b->verbose) { - quality_statistics(m, b); - printf("Memory allocation statistics:\n\n"); - printf(" Maximum number of vertices: %ld\n", m->vertices.maxitems); - printf(" Maximum number of triangles: %ld\n", m->triangles.maxitems); - if (m->subsegs.maxitems > 0) { - printf(" Maximum number of subsegments: %ld\n", m->subsegs.maxitems); - } - if (m->viri.maxitems > 0) { - printf(" Maximum number of viri: %ld\n", m->viri.maxitems); - } - if (m->badsubsegs.maxitems > 0) { - printf(" Maximum number of encroached subsegments: %ld\n", - m->badsubsegs.maxitems); - } - if (m->badtriangles.maxitems > 0) { - printf(" Maximum number of bad triangles: %ld\n", - m->badtriangles.maxitems); - } - if (m->flipstackers.maxitems > 0) { - printf(" Maximum number of stacked triangle flips: %ld\n", - m->flipstackers.maxitems); - } - if (m->splaynodes.maxitems > 0) { - printf(" Maximum number of splay tree nodes: %ld\n", - m->splaynodes.maxitems); - } - printf(" Approximate heap memory use (bytes): %ld\n\n", - m->vertices.maxitems * m->vertices.itembytes + - m->triangles.maxitems * m->triangles.itembytes + - m->subsegs.maxitems * m->subsegs.itembytes + - m->viri.maxitems * m->viri.itembytes + - m->badsubsegs.maxitems * m->badsubsegs.itembytes + - m->badtriangles.maxitems * m->badtriangles.itembytes + - m->flipstackers.maxitems * m->flipstackers.itembytes + - m->splaynodes.maxitems * m->splaynodes.itembytes); - - printf("Algorithmic statistics:\n\n"); - if (!b->weighted) { - printf(" Number of incircle tests: %ld\n", m->incirclecount); - } else { - printf(" Number of 3D orientation tests: %ld\n", m->orient3dcount); - } - printf(" Number of 2D orientation tests: %ld\n", m->counterclockcount); - if (m->hyperbolacount > 0) { - printf(" Number of right-of-hyperbola tests: %ld\n", - m->hyperbolacount); - } - if (m->circletopcount > 0) { - printf(" Number of circle top computations: %ld\n", - m->circletopcount); - } - if (m->circumcentercount > 0) { - printf(" Number of triangle circumcenter computations: %ld\n", - m->circumcentercount); - } - printf("\n"); - } -} - -/*****************************************************************************/ -/* */ -/* main() or triangulate() Gosh, do everything. */ -/* */ -/* The sequence is roughly as follows. Many of these steps can be skipped, */ -/* depending on the command line switches. */ -/* */ -/* - Initialize constants and parse the command line. */ -/* - Read the vertices from a file and either */ -/* - triangulate them (no -r), or */ -/* - read an old mesh from files and reconstruct it (-r). */ -/* - Insert the PSLG segments (-p), and possibly segments on the convex */ -/* hull (-c). */ -/* - Read the holes (-p), regional attributes (-pA), and regional area */ -/* constraints (-pa). Carve the holes and concavities, and spread the */ -/* regional attributes and area constraints. */ -/* - Enforce the constraints on minimum angle (-q) and maximum area (-a). */ -/* Also enforce the conforming Delaunay property (-q and -a). */ -/* - Compute the number of edges in the resulting mesh. */ -/* - Promote the mesh's linear triangles to higher order elements (-o). */ -/* - Write the output files and print the statistics. */ -/* - Check the consistency and Delaunay property of the mesh (-C). */ -/* */ -/*****************************************************************************/ - -#ifdef TRILIBRARY - -#ifdef ANSI_DECLARATORS -void triangulate(char *triswitches, struct triangulateio *in, - struct triangulateio *out, struct triangulateio *vorout) -#else /* not ANSI_DECLARATORS */ -void triangulate(triswitches, in, out, vorout) -char *triswitches; -struct triangulateio *in; -struct triangulateio *out; -struct triangulateio *vorout; -#endif /* not ANSI_DECLARATORS */ - -#else /* not TRILIBRARY */ - -#ifdef ANSI_DECLARATORS -int main(int argc, char **argv) -#else /* not ANSI_DECLARATORS */ -int main(argc, argv) -int argc; -char **argv; -#endif /* not ANSI_DECLARATORS */ - -#endif /* not TRILIBRARY */ - -{ - struct mesh m; - struct behavior b; - REAL *holearray; /* Array of holes. */ - REAL *regionarray; /* Array of regional attributes and area constraints. */ -#ifndef TRILIBRARY - FILE *polyfile; -#endif /* not TRILIBRARY */ -#ifndef NO_TIMER - /* Variables for timing the performance of Triangle. The types are */ - /* defined in sys/time.h. */ - struct timeval tv0, tv1, tv2, tv3, tv4, tv5, tv6; - struct timezone tz; -#endif /* not NO_TIMER */ - -#ifndef NO_TIMER - gettimeofday(&tv0, &tz); -#endif /* not NO_TIMER */ - - triangleinit(&m); -#ifdef TRILIBRARY - parsecommandline(1, &triswitches, &b); -#else /* not TRILIBRARY */ - parsecommandline(argc, argv, &b); -#endif /* not TRILIBRARY */ - m.steinerleft = b.steiner; - -#ifdef TRILIBRARY - transfernodes(&m, &b, in->pointlist, in->pointattributelist, - in->pointmarkerlist, in->numberofpoints, - in->numberofpointattributes); -#else /* not TRILIBRARY */ - readnodes(&m, &b, b.innodefilename, b.inpolyfilename, &polyfile); -#endif /* not TRILIBRARY */ - -#ifndef NO_TIMER - if (!b.quiet) { - gettimeofday(&tv1, &tz); - } -#endif /* not NO_TIMER */ - -#ifdef CDT_ONLY - m.hullsize = delaunay(&m, &b); /* Triangulate the vertices. */ -#else /* not CDT_ONLY */ - if (b.refine) { - /* Read and reconstruct a mesh. */ -#ifdef TRILIBRARY - m.hullsize = reconstruct(&m, &b, in->trianglelist, - in->triangleattributelist, in->trianglearealist, - in->numberoftriangles, in->numberofcorners, - in->numberoftriangleattributes, - in->segmentlist, in->segmentmarkerlist, - in->numberofsegments); -#else /* not TRILIBRARY */ - m.hullsize = reconstruct(&m, &b, b.inelefilename, b.areafilename, - b.inpolyfilename, polyfile); -#endif /* not TRILIBRARY */ - } else { - m.hullsize = delaunay(&m, &b); /* Triangulate the vertices. */ - } -#endif /* not CDT_ONLY */ - -#ifndef NO_TIMER - if (!b.quiet) { - gettimeofday(&tv2, &tz); - if (b.refine) { - printf("Mesh reconstruction"); - } else { - printf("Delaunay"); - } - printf(" milliseconds: %ld\n", 1000l * (tv2.tv_sec - tv1.tv_sec) + - (tv2.tv_usec - tv1.tv_usec) / 1000l); - } -#endif /* not NO_TIMER */ - - /* Ensure that no vertex can be mistaken for a triangular bounding */ - /* box vertex in insertvertex(). */ - m.infvertex1 = (vertex) NULL; - m.infvertex2 = (vertex) NULL; - m.infvertex3 = (vertex) NULL; - - if (b.usesegments) { - m.checksegments = 1; /* Segments will be introduced next. */ - if (!b.refine) { - /* Insert PSLG segments and/or convex hull segments. */ -#ifdef TRILIBRARY - formskeleton(&m, &b, in->segmentlist, - in->segmentmarkerlist, in->numberofsegments); -#else /* not TRILIBRARY */ - formskeleton(&m, &b, polyfile, b.inpolyfilename); -#endif /* not TRILIBRARY */ - } - } - -#ifndef NO_TIMER - if (!b.quiet) { - gettimeofday(&tv3, &tz); - if (b.usesegments && !b.refine) { - printf("Segment milliseconds: %ld\n", - 1000l * (tv3.tv_sec - tv2.tv_sec) + - (tv3.tv_usec - tv2.tv_usec) / 1000l); - } - } -#endif /* not NO_TIMER */ - - if (b.poly && (m.triangles.items > 0)) { -#ifdef TRILIBRARY - holearray = in->holelist; - m.holes = in->numberofholes; - regionarray = in->regionlist; - m.regions = in->numberofregions; -#else /* not TRILIBRARY */ - readholes(&m, &b, polyfile, b.inpolyfilename, &holearray, &m.holes, - ®ionarray, &m.regions); -#endif /* not TRILIBRARY */ - if (!b.refine) { - /* Carve out holes and concavities. */ - carveholes(&m, &b, holearray, m.holes, regionarray, m.regions); - } - } else { - /* Without a PSLG, there can be no holes or regional attributes */ - /* or area constraints. The following are set to zero to avoid */ - /* an accidental free() later. */ - m.holes = 0; - m.regions = 0; - } - -#ifndef NO_TIMER - if (!b.quiet) { - gettimeofday(&tv4, &tz); - if (b.poly && !b.refine) { - printf("Hole milliseconds: %ld\n", 1000l * (tv4.tv_sec - tv3.tv_sec) + - (tv4.tv_usec - tv3.tv_usec) / 1000l); - } - } -#endif /* not NO_TIMER */ - -#ifndef CDT_ONLY - if (b.quality && (m.triangles.items > 0)) { - enforcequality(&m, &b); /* Enforce angle and area constraints. */ - } -#endif /* not CDT_ONLY */ - -#ifndef NO_TIMER - if (!b.quiet) { - gettimeofday(&tv5, &tz); -#ifndef CDT_ONLY - if (b.quality) { - printf("Quality milliseconds: %ld\n", - 1000l * (tv5.tv_sec - tv4.tv_sec) + - (tv5.tv_usec - tv4.tv_usec) / 1000l); - } -#endif /* not CDT_ONLY */ - } -#endif /* not NO_TIMER */ - - /* Calculate the number of edges. */ - m.edges = (3l * m.triangles.items + m.hullsize) / 2l; - - if (b.order > 1) { - highorder(&m, &b); /* Promote elements to higher polynomial order. */ - } - if (!b.quiet) { - printf("\n"); - } - -#ifdef TRILIBRARY - out->numberofpoints = m.vertices.items; - out->numberofpointattributes = m.nextras; - out->numberoftriangles = m.triangles.items; - out->numberofcorners = (b.order + 1) * (b.order + 2) / 2; - out->numberoftriangleattributes = m.eextras; - out->numberofedges = m.edges; - if (b.usesegments) { - out->numberofsegments = m.subsegs.items; - } else { - out->numberofsegments = m.hullsize; - } - if (vorout != (struct triangulateio *) NULL) { - vorout->numberofpoints = m.triangles.items; - vorout->numberofpointattributes = m.nextras; - vorout->numberofedges = m.edges; - } -#endif /* TRILIBRARY */ - /* If not using iteration numbers, don't write a .node file if one was */ - /* read, because the original one would be overwritten! */ - if (b.nonodewritten || (b.noiterationnum && m.readnodefile)) { - if (!b.quiet) { -#ifdef TRILIBRARY - printf("NOT writing vertices.\n"); -#else /* not TRILIBRARY */ - printf("NOT writing a .node file.\n"); -#endif /* not TRILIBRARY */ - } - numbernodes(&m, &b); /* We must remember to number the vertices. */ - } else { - /* writenodes() numbers the vertices too. */ -#ifdef TRILIBRARY - writenodes(&m, &b, &out->pointlist, &out->pointattributelist, - &out->pointmarkerlist); -#else /* not TRILIBRARY */ - writenodes(&m, &b, b.outnodefilename, argc, argv); -#endif /* TRILIBRARY */ - } - if (b.noelewritten) { - if (!b.quiet) { -#ifdef TRILIBRARY - printf("NOT writing triangles.\n"); -#else /* not TRILIBRARY */ - printf("NOT writing an .ele file.\n"); -#endif /* not TRILIBRARY */ - } - } else { -#ifdef TRILIBRARY - writeelements(&m, &b, &out->trianglelist, &out->triangleattributelist); -#else /* not TRILIBRARY */ - writeelements(&m, &b, b.outelefilename, argc, argv); -#endif /* not TRILIBRARY */ - } - /* The -c switch (convex switch) causes a PSLG to be written */ - /* even if none was read. */ - if (b.poly || b.convex) { - /* If not using iteration numbers, don't overwrite the .poly file. */ - if (b.nopolywritten || b.noiterationnum) { - if (!b.quiet) { -#ifdef TRILIBRARY - printf("NOT writing segments.\n"); -#else /* not TRILIBRARY */ - printf("NOT writing a .poly file.\n"); -#endif /* not TRILIBRARY */ - } - } else { -#ifdef TRILIBRARY - writepoly(&m, &b, &out->segmentlist, &out->segmentmarkerlist); - out->numberofholes = m.holes; - out->numberofregions = m.regions; - if (b.poly) { - out->holelist = in->holelist; - out->regionlist = in->regionlist; - } else { - out->holelist = (REAL *) NULL; - out->regionlist = (REAL *) NULL; - } -#else /* not TRILIBRARY */ - writepoly(&m, &b, b.outpolyfilename, holearray, m.holes, regionarray, - m.regions, argc, argv); -#endif /* not TRILIBRARY */ - } - } -#ifndef TRILIBRARY -#ifndef CDT_ONLY - if (m.regions > 0) { - trifree((VOID *) regionarray); - } -#endif /* not CDT_ONLY */ - if (m.holes > 0) { - trifree((VOID *) holearray); - } - if (b.geomview) { - writeoff(&m, &b, b.offfilename, argc, argv); - } -#endif /* not TRILIBRARY */ - if (b.edgesout) { -#ifdef TRILIBRARY - writeedges(&m, &b, &out->edgelist, &out->edgemarkerlist); -#else /* not TRILIBRARY */ - writeedges(&m, &b, b.edgefilename, argc, argv); -#endif /* not TRILIBRARY */ - } - if (b.voronoi) { -#ifdef TRILIBRARY - writevoronoi(&m, &b, &vorout->pointlist, &vorout->pointattributelist, - &vorout->pointmarkerlist, &vorout->edgelist, - &vorout->edgemarkerlist, &vorout->normlist); -#else /* not TRILIBRARY */ - writevoronoi(&m, &b, b.vnodefilename, b.vedgefilename, argc, argv); -#endif /* not TRILIBRARY */ - } - if (b.neighbors) { -#ifdef TRILIBRARY - writeneighbors(&m, &b, &out->neighborlist); -#else /* not TRILIBRARY */ - writeneighbors(&m, &b, b.neighborfilename, argc, argv); -#endif /* not TRILIBRARY */ - } - - if (!b.quiet) { -#ifndef NO_TIMER - gettimeofday(&tv6, &tz); - printf("\nOutput milliseconds: %ld\n", - 1000l * (tv6.tv_sec - tv5.tv_sec) + - (tv6.tv_usec - tv5.tv_usec) / 1000l); - printf("Total running milliseconds: %ld\n", - 1000l * (tv6.tv_sec - tv0.tv_sec) + - (tv6.tv_usec - tv0.tv_usec) / 1000l); -#endif /* not NO_TIMER */ - - statistics(&m, &b); - } - -#ifndef REDUCED - if (b.docheck) { - checkmesh(&m, &b); - checkdelaunay(&m, &b); - } -#endif /* not REDUCED */ - - triangledeinit(&m, &b); -#ifndef TRILIBRARY - return 0; -#endif /* not TRILIBRARY */ -} diff --git a/Triangle/triangle.h b/Triangle/triangle.h deleted file mode 100644 index 5b2c5995af..0000000000 --- a/Triangle/triangle.h +++ /dev/null @@ -1,282 +0,0 @@ -/*****************************************************************************/ -/* */ -/* (triangle.h) */ -/* */ -/* Include file for programs that call Triangle. */ -/* */ -/* Accompanies Triangle Versions 1.3 and 1.4 */ -/* July 19, 1996 */ -/* */ -/* Copyright 1996 */ -/* Jonathan Richard Shewchuk */ -/* 2360 Woolsey #H */ -/* Berkeley, California 94705-1927 */ -/* jrs@cs.berkeley.edu */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* How to call Triangle from another program */ -/* */ -/* */ -/* If you haven't read Triangle's instructions (run "triangle -h" to read */ -/* them), you won't understand what follows. */ -/* */ -/* Triangle must be compiled into an object file (triangle.o) with the */ -/* TRILIBRARY symbol defined (preferably by using the -DTRILIBRARY compiler */ -/* switch). The makefile included with Triangle will do this for you if */ -/* you run "make trilibrary". The resulting object file can be called via */ -/* the procedure triangulate(). */ -/* */ -/* If the size of the object file is important to you, you may wish to */ -/* generate a reduced version of triangle.o. The REDUCED symbol gets rid */ -/* of all features that are primarily of research interest. Specifically, */ -/* the -DREDUCED switch eliminates Triangle's -i, -F, -s, and -C switches. */ -/* The CDT_ONLY symbol gets rid of all meshing algorithms above and beyond */ -/* constrained Delaunay triangulation. Specifically, the -DCDT_ONLY switch */ -/* eliminates Triangle's -r, -q, -a, -S, and -s switches. */ -/* */ -/* IMPORTANT: These definitions (TRILIBRARY, REDUCED, CDT_ONLY) must be */ -/* made in the makefile or in triangle.c itself. Putting these definitions */ -/* in this file will not create the desired effect. */ -/* */ -/* */ -/* The calling convention for triangulate() follows. */ -/* */ -/* void triangulate(triswitches, in, out, vorout) */ -/* char *triswitches; */ -/* struct triangulateio *in; */ -/* struct triangulateio *out; */ -/* struct triangulateio *vorout; */ -/* */ -/* `triswitches' is a string containing the command line switches you wish */ -/* to invoke. No initial dash is required. Some suggestions: */ -/* */ -/* - You'll probably find it convenient to use the `z' switch so that */ -/* points (and other items) are numbered from zero. This simplifies */ -/* indexing, because the first item of any type always starts at index */ -/* [0] of the corresponding array, whether that item's number is zero or */ -/* one. */ -/* - You'll probably want to use the `Q' (quiet) switch in your final code, */ -/* but you can take advantage of Triangle's printed output (including the */ -/* `V' switch) while debugging. */ -/* - If you are not using the `q' or `a' switches, then the output points */ -/* will be identical to the input points, except possibly for the */ -/* boundary markers. If you don't need the boundary markers, you should */ -/* use the `N' (no nodes output) switch to save memory. (If you do need */ -/* boundary markers, but need to save memory, a good nasty trick is to */ -/* set out->pointlist equal to in->pointlist before calling triangulate(),*/ -/* so that Triangle overwrites the input points with identical copies.) */ -/* - The `I' (no iteration numbers) and `g' (.off file output) switches */ -/* have no effect when Triangle is compiled with TRILIBRARY defined. */ -/* */ -/* `in', `out', and `vorout' are descriptions of the input, the output, */ -/* and the Voronoi output. If the `v' (Voronoi output) switch is not used, */ -/* `vorout' may be NULL. `in' and `out' may never be NULL. */ -/* */ -/* Certain fields of the input and output structures must be initialized, */ -/* as described below. */ -/* */ -/*****************************************************************************/ - -/*****************************************************************************/ -/* */ -/* The `triangulateio' structure. */ -/* */ -/* Used to pass data into and out of the triangulate() procedure. */ -/* */ -/* */ -/* Arrays are used to store points, triangles, markers, and so forth. In */ -/* all cases, the first item in any array is stored starting at index [0]. */ -/* However, that item is item number `1' unless the `z' switch is used, in */ -/* which case it is item number `0'. Hence, you may find it easier to */ -/* index points (and triangles in the neighbor list) if you use the `z' */ -/* switch. Unless, of course, you're calling Triangle from a Fortran */ -/* program. */ -/* */ -/* Description of fields (except the `numberof' fields, which are obvious): */ -/* */ -/* `pointlist': An array of point coordinates. The first point's x */ -/* coordinate is at index [0] and its y coordinate at index [1], followed */ -/* by the coordinates of the remaining points. Each point occupies two */ -/* REALs. */ -/* `pointattributelist': An array of point attributes. Each point's */ -/* attributes occupy `numberofpointattributes' REALs. */ -/* `pointmarkerlist': An array of point markers; one int per point. */ -/* */ -/* `trianglelist': An array of triangle corners. The first triangle's */ -/* first corner is at index [0], followed by its other two corners in */ -/* counterclockwise order, followed by any other nodes if the triangle */ -/* represents a nonlinear element. Each triangle occupies */ -/* `numberofcorners' ints. */ -/* `triangleattributelist': An array of triangle attributes. Each */ -/* triangle's attributes occupy `numberoftriangleattributes' REALs. */ -/* `trianglearealist': An array of triangle area constraints; one REAL per */ -/* triangle. Input only. */ -/* `neighborlist': An array of triangle neighbors; three ints per */ -/* triangle. Output only. */ -/* */ -/* `segmentlist': An array of segment endpoints. The first segment's */ -/* endpoints are at indices [0] and [1], followed by the remaining */ -/* segments. Two ints per segment. */ -/* `segmentmarkerlist': An array of segment markers; one int per segment. */ -/* */ -/* `holelist': An array of holes. The first hole's x and y coordinates */ -/* are at indices [0] and [1], followed by the remaining holes. Two */ -/* REALs per hole. Input only, although the pointer is copied to the */ -/* output structure for your convenience. */ -/* */ -/* `regionlist': An array of regional attributes and area constraints. */ -/* The first constraint's x and y coordinates are at indices [0] and [1], */ -/* followed by the regional attribute and index [2], followed by the */ -/* maximum area at index [3], followed by the remaining area constraints. */ -/* Four REALs per area constraint. Note that each regional attribute is */ -/* used only if you select the `A' switch, and each area constraint is */ -/* used only if you select the `a' switch (with no number following), but */ -/* omitting one of these switches does not change the memory layout. */ -/* Input only, although the pointer is copied to the output structure for */ -/* your convenience. */ -/* */ -/* `edgelist': An array of edge endpoints. The first edge's endpoints are */ -/* at indices [0] and [1], followed by the remaining edges. Two ints per */ -/* edge. Output only. */ -/* `edgemarkerlist': An array of edge markers; one int per edge. Output */ -/* only. */ -/* `normlist': An array of normal vectors, used for infinite rays in */ -/* Voronoi diagrams. The first normal vector's x and y magnitudes are */ -/* at indices [0] and [1], followed by the remaining vectors. For each */ -/* finite edge in a Voronoi diagram, the normal vector written is the */ -/* zero vector. Two REALs per edge. Output only. */ -/* */ -/* */ -/* Any input fields that Triangle will examine must be initialized. */ -/* Furthermore, for each output array that Triangle will write to, you */ -/* must either provide space by setting the appropriate pointer to point */ -/* to the space you want the data written to, or you must initialize the */ -/* pointer to NULL, which tells Triangle to allocate space for the results. */ -/* The latter option is preferable, because Triangle always knows exactly */ -/* how much space to allocate. The former option is provided mainly for */ -/* people who need to call Triangle from Fortran code, though it also makes */ -/* possible some nasty space-saving tricks, like writing the output to the */ -/* same arrays as the input. */ -/* */ -/* Triangle will not free() any input or output arrays, including those it */ -/* allocates itself; that's up to you. */ -/* */ -/* Here's a guide to help you decide which fields you must initialize */ -/* before you call triangulate(). */ -/* */ -/* `in': */ -/* */ -/* - `pointlist' must always point to a list of points; `numberofpoints' */ -/* and `numberofpointattributes' must be properly set. */ -/* `pointmarkerlist' must either be set to NULL (in which case all */ -/* markers default to zero), or must point to a list of markers. If */ -/* `numberofpointattributes' is not zero, `pointattributelist' must */ -/* point to a list of point attributes. */ -/* - If the `r' switch is used, `trianglelist' must point to a list of */ -/* triangles, and `numberoftriangles', `numberofcorners', and */ -/* `numberoftriangleattributes' must be properly set. If */ -/* `numberoftriangleattributes' is not zero, `triangleattributelist' */ -/* must point to a list of triangle attributes. If the `a' switch is */ -/* used (with no number following), `trianglearealist' must point to a */ -/* list of triangle area constraints. `neighborlist' may be ignored. */ -/* - If the `p' switch is used, `segmentlist' must point to a list of */ -/* segments, `numberofsegments' must be properly set, and */ -/* `segmentmarkerlist' must either be set to NULL (in which case all */ -/* markers default to zero), or must point to a list of markers. */ -/* - If the `p' switch is used without the `r' switch, then */ -/* `numberofholes' and `numberofregions' must be properly set. If */ -/* `numberofholes' is not zero, `holelist' must point to a list of */ -/* holes. If `numberofregions' is not zero, `regionlist' must point to */ -/* a list of region constraints. */ -/* - If the `p' switch is used, `holelist', `numberofholes', */ -/* `regionlist', and `numberofregions' is copied to `out'. (You can */ -/* nonetheless get away with not initializing them if the `r' switch is */ -/* used.) */ -/* - `edgelist', `edgemarkerlist', `normlist', and `numberofedges' may be */ -/* ignored. */ -/* */ -/* `out': */ -/* */ -/* - `pointlist' must be initialized (NULL or pointing to memory) unless */ -/* the `N' switch is used. `pointmarkerlist' must be initialized */ -/* unless the `N' or `B' switch is used. If `N' is not used and */ -/* `in->numberofpointattributes' is not zero, `pointattributelist' must */ -/* be initialized. */ -/* - `trianglelist' must be initialized unless the `E' switch is used. */ -/* `neighborlist' must be initialized if the `n' switch is used. If */ -/* the `E' switch is not used and (`in->numberofelementattributes' is */ -/* not zero or the `A' switch is used), `elementattributelist' must be */ -/* initialized. `trianglearealist' may be ignored. */ -/* - `segmentlist' must be initialized if the `p' or `c' switch is used, */ -/* and the `P' switch is not used. `segmentmarkerlist' must also be */ -/* initialized under these circumstances unless the `B' switch is used. */ -/* - `edgelist' must be initialized if the `e' switch is used. */ -/* `edgemarkerlist' must be initialized if the `e' switch is used and */ -/* the `B' switch is not. */ -/* - `holelist', `regionlist', `normlist', and all scalars may be ignored.*/ -/* */ -/* `vorout' (only needed if `v' switch is used): */ -/* */ -/* - `pointlist' must be initialized. If `in->numberofpointattributes' */ -/* is not zero, `pointattributelist' must be initialized. */ -/* `pointmarkerlist' may be ignored. */ -/* - `edgelist' and `normlist' must both be initialized. */ -/* `edgemarkerlist' may be ignored. */ -/* - Everything else may be ignored. */ -/* */ -/* After a call to triangulate(), the valid fields of `out' and `vorout' */ -/* will depend, in an obvious way, on the choice of switches used. Note */ -/* that when the `p' switch is used, the pointers `holelist' and */ -/* `regionlist' are copied from `in' to `out', but no new space is */ -/* allocated; be careful that you don't free() the same array twice. On */ -/* the other hand, Triangle will never copy the `pointlist' pointer (or any */ -/* others); new space is allocated for `out->pointlist', or if the `N' */ -/* switch is used, `out->pointlist' remains uninitialized. */ -/* */ -/* All of the meaningful `numberof' fields will be properly set; for */ -/* instance, `numberofedges' will represent the number of edges in the */ -/* triangulation whether or not the edges were written. If segments are */ -/* not used, `numberofsegments' will indicate the number of boundary edges. */ -/* */ -/*****************************************************************************/ - -struct triangulateio { - REAL *pointlist; /* In / out */ - REAL *pointattributelist; /* In / out */ - int *pointmarkerlist; /* In / out */ - int numberofpoints; /* In / out */ - int numberofpointattributes; /* In / out */ - - int *trianglelist; /* In / out */ - REAL *triangleattributelist; /* In / out */ - REAL *trianglearealist; /* In only */ - int *neighborlist; /* Out only */ - int numberoftriangles; /* In / out */ - int numberofcorners; /* In / out */ - int numberoftriangleattributes; /* In / out */ - - int *segmentlist; /* In / out */ - int *segmentmarkerlist; /* In / out */ - int numberofsegments; /* In / out */ - - REAL *holelist; /* In / pointer to array copied out */ - int numberofholes; /* In / copied out */ - - REAL *regionlist; /* In / pointer to array copied out */ - int numberofregions; /* In / copied out */ - - int *edgelist; /* Out only */ - int *edgemarkerlist; /* Not used with Voronoi diagram; out only */ - REAL *normlist; /* Used only with Voronoi diagram; out only */ - int numberofedges; /* Out only */ -}; - -#ifdef ANSI_DECLARATORS -void triangulate(char *, struct triangulateio *, struct triangulateio *, - struct triangulateio *); -#else /* not ANSI_DECLARATORS */ -void triangulate(); -#endif /* not ANSI_DECLARATORS */ -- GitLab