From 310cb00b134522f887816476e0c1eb25bf961ad4 Mon Sep 17 00:00:00 2001 From: Joachim Schoeberl Date: Mon, 12 Jan 2009 23:40:13 +0000 Subject: [PATCH] autotools --- AUTHORS | 1 + COPYING | 340 + ChangeLog | 0 INSTALL | 167 + Makefile.am | 2 + Makefile.cvs | 8 + Makefile.in | 640 + NEWS | 0 README | 0 TODO | 0 config.guess | 1363 ++ config.h.in | 59 + config.sub | 1470 ++ configure | 17764 ++++++++++++++++++++++++ configure.in | 13 + depcomp | 441 + install-sh | 276 + libsrc/Makefile.am | 4 + libsrc/Makefile.in | 492 + libsrc/csg/Makefile.am | 7 + libsrc/csg/Makefile.in | 471 + libsrc/csg/algprim.cpp | 1685 +++ libsrc/csg/algprim.hpp | 439 + libsrc/csg/brick.cpp | 526 + libsrc/csg/brick.hpp | 120 + libsrc/csg/bspline2d.cpp | 242 + libsrc/csg/csg.hpp | 51 + libsrc/csg/csgeom.cpp | 1422 ++ libsrc/csg/csgeom.hpp | 309 + libsrc/csg/csgparser.cpp | 1332 ++ libsrc/csg/csgparser.hpp | 107 + libsrc/csg/curve2d.cpp | 78 + libsrc/csg/curve2d.hpp | 59 + libsrc/csg/edgeflw.cpp | 1820 +++ libsrc/csg/edgeflw.hpp | 104 + libsrc/csg/explicitcurve2d.cpp | 160 + libsrc/csg/explicitcurve2d.hpp | 109 + libsrc/csg/extrusion.cpp | 940 ++ libsrc/csg/extrusion.hpp | 144 + libsrc/csg/gencyl.cpp | 209 + libsrc/csg/gencyl.hpp | 64 + libsrc/csg/genmesh.cpp | 854 ++ libsrc/csg/geoml.hpp | 16 + libsrc/csg/identify.cpp | 1672 +++ libsrc/csg/identify.hpp | 204 + libsrc/csg/manifold.cpp | 14 + libsrc/csg/manifold.hpp | 22 + libsrc/csg/meshsurf.cpp | 210 + libsrc/csg/meshsurf.hpp | 95 + libsrc/csg/polyhedra.cpp | 738 + libsrc/csg/polyhedra.hpp | 99 + libsrc/csg/revolution.cpp | 904 ++ libsrc/csg/revolution.hpp | 149 + libsrc/csg/singularref.cpp | 217 + libsrc/csg/singularref.hpp | 78 + libsrc/csg/solid.cpp | 1716 +++ libsrc/csg/solid.hpp | 241 + libsrc/csg/specpoin.cpp | 1794 +++ libsrc/csg/specpoin.hpp | 174 + libsrc/csg/spline3d.cpp | 355 + libsrc/csg/spline3d.hpp | 92 + libsrc/csg/surface.cpp | 568 + libsrc/csg/surface.hpp | 357 + libsrc/csg/triapprox.cpp | 59 + libsrc/csg/triapprox.hpp | 57 + libsrc/general/Makefile.am | 6 + libsrc/general/Makefile.in | 462 + libsrc/general/array.cpp | 75 + libsrc/general/array.hpp | 638 + libsrc/general/autodiff.hpp | 351 + libsrc/general/autoptr.hpp | 31 + libsrc/general/bitarray.cpp | 132 + libsrc/general/bitarray.hpp | 222 + libsrc/general/dynamicmem.cpp | 205 + libsrc/general/dynamicmem.hpp | 95 + libsrc/general/flags.cpp | 330 + libsrc/general/flags.hpp | 83 + libsrc/general/hashtabl.cpp | 327 + libsrc/general/hashtabl.hpp | 1322 ++ libsrc/general/moveablemem.cpp | 271 + libsrc/general/moveablemem.hpp | 99 + libsrc/general/myadt.hpp | 46 + libsrc/general/mystring.cpp | 426 + libsrc/general/mystring.hpp | 216 + libsrc/general/netgenout.hpp | 184 + libsrc/general/ngexception.cpp | 33 + libsrc/general/ngexception.hpp | 30 + libsrc/general/optmem.cpp | 64 + libsrc/general/optmem.hpp | 59 + libsrc/general/parthreads.cpp | 40 + libsrc/general/parthreads.hpp | 129 + libsrc/general/profiler.cpp | 112 + libsrc/general/profiler.hpp | 62 + libsrc/general/seti.cpp | 70 + libsrc/general/seti.hpp | 45 + libsrc/general/sort.cpp | 75 + libsrc/general/sort.hpp | 42 + libsrc/general/spbita2d.cpp | 172 + libsrc/general/spbita2d.hpp | 56 + libsrc/general/stack.hpp | 112 + libsrc/general/symbolta.cpp | 52 + libsrc/general/symbolta.hpp | 158 + libsrc/general/table.cpp | 193 + libsrc/general/table.hpp | 223 + libsrc/general/template.hpp | 448 + libsrc/geom2d/Makefile.am | 5 + libsrc/geom2d/Makefile.in | 445 + libsrc/geom2d/genmesh2d.cpp | 270 + libsrc/geom2d/geom2dmesh.cpp | 85 + libsrc/geom2d/geom2dmesh.hpp | 49 + libsrc/geom2d/geometry2d.hpp | 20 + libsrc/geom2d/spline.cpp | 360 + libsrc/geom2d/spline.hpp | 1041 ++ libsrc/geom2d/spline2d.hpp | 234 + libsrc/geom2d/splinegeometry.cpp | 1252 ++ libsrc/geom2d/splinegeometry.hpp | 140 + libsrc/geom2d/splinegeometry2.hpp | 103 + libsrc/gprim/Makefile.am | 5 + libsrc/gprim/Makefile.in | 448 + libsrc/gprim/adtree.cpp | 2165 +++ libsrc/gprim/adtree.hpp | 481 + libsrc/gprim/geom2d.cpp | 489 + libsrc/gprim/geom2d.hpp | 885 ++ libsrc/gprim/geom3d.cpp | 731 + libsrc/gprim/geom3d.hpp | 733 + libsrc/gprim/geomfuncs.cpp | 111 + libsrc/gprim/geomfuncs.hpp | 157 + libsrc/gprim/geomobjects.hpp | 359 + libsrc/gprim/geomobjects2.hpp | 366 + libsrc/gprim/geomops.hpp | 391 + libsrc/gprim/geomops2.hpp | 428 + libsrc/gprim/geomtest3d.cpp | 1150 ++ libsrc/gprim/geomtest3d.hpp | 80 + libsrc/gprim/gprim.hpp | 26 + libsrc/gprim/transform3d.cpp | 173 + libsrc/gprim/transform3d.hpp | 190 + libsrc/include/Makefile.am | 2 + libsrc/include/Makefile.in | 331 + libsrc/include/acisgeom.hpp | 3 + libsrc/include/csg.hpp | 1 + libsrc/include/geometry2d.hpp | 1 + libsrc/include/gprim.hpp | 1 + libsrc/include/incvis.hpp | 32 + libsrc/include/linalg.hpp | 1 + libsrc/include/meshing.hpp | 1 + libsrc/include/myadt.hpp | 1 + libsrc/include/mydefs.hpp | 29 + libsrc/include/mystdlib.h | 104 + libsrc/include/occgeom.hpp | 1 + libsrc/include/opti.hpp | 1 + libsrc/include/parallel.hpp | 1 + libsrc/include/stepgeom.hpp | 10 + libsrc/include/stepreader.hpp | 1 + libsrc/include/stlgeom.hpp | 1 + libsrc/include/visual.hpp | 1 + libsrc/interface/Makefile.am | 9 + libsrc/interface/Makefile.in | 476 + libsrc/interface/importsolution.cpp | 129 + libsrc/interface/nginterface.cpp | 2467 ++++ libsrc/interface/nginterface.h | 434 + libsrc/interface/printdest.cpp | 11 + libsrc/interface/read_fnf_mesh.cpp | 446 + libsrc/interface/readtetmesh.cpp | 797 ++ libsrc/interface/readuser.cpp | 416 + libsrc/interface/writeabaqus.cpp | 237 + libsrc/interface/writediffpack.cpp | 296 + libsrc/interface/writedolfin.cpp | 69 + libsrc/interface/writeelmer.cpp | 131 + libsrc/interface/writefeap.cpp | 220 + libsrc/interface/writefluent.cpp | 193 + libsrc/interface/writegmsh.cpp | 200 + libsrc/interface/writejcm.cpp | 430 + libsrc/interface/writepermas.cpp | 208 + libsrc/interface/writetecplot.cpp | 127 + libsrc/interface/writetet.cpp | 1096 ++ libsrc/interface/writetochnog.cpp | 108 + libsrc/interface/writeuser.cpp | 910 ++ libsrc/interface/writeuser.hpp | 145 + libsrc/interface/wuchemnitz.cpp | 313 + libsrc/linalg/Makefile.am | 4 + libsrc/linalg/Makefile.in | 442 + libsrc/linalg/densemat.cpp | 1444 ++ libsrc/linalg/densemat.hpp | 286 + libsrc/linalg/linalg.hpp | 33 + libsrc/linalg/polynomial.cpp | 216 + libsrc/linalg/polynomial.hpp | 45 + libsrc/linalg/vector.cpp | 786 ++ libsrc/linalg/vector.hpp | 138 + libsrc/meshing/Makefile.am | 11 + libsrc/meshing/Makefile.in | 505 + libsrc/meshing/adfront2.cpp | 466 + libsrc/meshing/adfront2.hpp | 264 + libsrc/meshing/adfront3.cpp | 876 ++ libsrc/meshing/adfront3.hpp | 319 + libsrc/meshing/bisect.cpp | 4051 ++++++ libsrc/meshing/bisect.hpp | 99 + libsrc/meshing/boundarylayer.cpp | 92 + libsrc/meshing/boundarylayer.hpp | 9 + libsrc/meshing/classifyhpel.hpp | 1713 +++ libsrc/meshing/clusters.cpp | 267 + libsrc/meshing/clusters.hpp | 42 + libsrc/meshing/curvedelems.hpp | 868 ++ libsrc/meshing/curvedelems_new.cpp | 3169 +++++ libsrc/meshing/curvedelems_new.hpp | 209 + libsrc/meshing/delaunay.cpp | 1676 +++ libsrc/meshing/findip.hpp | 192 + libsrc/meshing/findip2.hpp | 95 + libsrc/meshing/geomsearch.cpp | 263 + libsrc/meshing/geomsearch.hpp | 117 + libsrc/meshing/global.cpp | 53 + libsrc/meshing/global.hpp | 54 + libsrc/meshing/hpref_hex.hpp | 236 + libsrc/meshing/hpref_prism.hpp | 3405 +++++ libsrc/meshing/hpref_pyramid.hpp | 118 + libsrc/meshing/hpref_quad.hpp | 2082 +++ libsrc/meshing/hpref_segm.hpp | 122 + libsrc/meshing/hpref_tet.hpp | 3128 +++++ libsrc/meshing/hpref_trig.hpp | 776 ++ libsrc/meshing/hprefinement.cpp | 1955 +++ libsrc/meshing/hprefinement.hpp | 319 + libsrc/meshing/improve2.cpp | 831 ++ libsrc/meshing/improve2.hpp | 102 + libsrc/meshing/improve2gen.cpp | 455 + libsrc/meshing/improve3.cpp | 2820 ++++ libsrc/meshing/improve3.hpp | 99 + libsrc/meshing/localh.cpp | 680 + libsrc/meshing/localh.hpp | 145 + libsrc/meshing/meshclass.cpp | 5506 ++++++++ libsrc/meshing/meshclass.hpp | 777 ++ libsrc/meshing/meshfunc.cpp | 725 + libsrc/meshing/meshfunc.hpp | 41 + libsrc/meshing/meshfunc2d.cpp | 61 + libsrc/meshing/meshing.hpp | 86 + libsrc/meshing/meshing2.cpp | 1890 +++ libsrc/meshing/meshing2.hpp | 156 + libsrc/meshing/meshing3.cpp | 1292 ++ libsrc/meshing/meshing3.hpp | 130 + libsrc/meshing/meshtool.cpp | 1002 ++ libsrc/meshing/meshtool.hpp | 83 + libsrc/meshing/meshtype.cpp | 2669 ++++ libsrc/meshing/meshtype.hpp | 1229 ++ libsrc/meshing/msghandler.cpp | 226 + libsrc/meshing/msghandler.hpp | 53 + libsrc/meshing/netrule2.cpp | 229 + libsrc/meshing/netrule3.cpp | 1140 ++ libsrc/meshing/parser2.cpp | 603 + libsrc/meshing/parser3.cpp | 1019 ++ libsrc/meshing/prism2rls.cpp | 457 + libsrc/meshing/prism2rls_2.cpp | 446 + libsrc/meshing/pyramid2rls.cpp | 309 + libsrc/meshing/pyramidrls.cpp | 263 + libsrc/meshing/quadrls.cpp | 887 ++ libsrc/meshing/refine.cpp | 749 + libsrc/meshing/ruler2.cpp | 641 + libsrc/meshing/ruler2.hpp | 167 + libsrc/meshing/ruler3.cpp | 1137 ++ libsrc/meshing/ruler3.hpp | 210 + libsrc/meshing/secondorder.cpp | 486 + libsrc/meshing/smoothing2.5.cpp | 265 + libsrc/meshing/smoothing2.cpp | 985 ++ libsrc/meshing/smoothing3.cpp | 1908 +++ libsrc/meshing/specials.cpp | 193 + libsrc/meshing/specials.hpp | 16 + libsrc/meshing/tetrarls.cpp | 1466 ++ libsrc/meshing/topology.cpp | 1507 ++ libsrc/meshing/topology.hpp | 326 + libsrc/meshing/triarls.cpp | 468 + libsrc/meshing/validate.cpp | 587 + libsrc/meshing/validate.hpp | 17 + libsrc/meshing/zrefine.cpp | 741 + libsrc/occ/Makefile.am | 6 + libsrc/occ/Makefile.in | 476 + libsrc/occ/Partition_Inter2d.cxx | 677 + libsrc/occ/Partition_Inter3d.cxx | 945 ++ libsrc/occ/Partition_Loop.cxx | 473 + libsrc/occ/Partition_Loop2d.cxx | 1143 ++ libsrc/occ/Partition_Loop3d.cxx | 356 + libsrc/occ/Partition_Spliter.cxx | 2167 +++ libsrc/occ/occconstruction.cpp | 154 + libsrc/occ/occgenmesh.cpp | 1540 ++ libsrc/occ/occgeom.cpp | 1536 ++ libsrc/occ/occmeshsurf.cpp | 735 + libsrc/opti/Makefile.am | 4 + libsrc/opti/Makefile.in | 442 + libsrc/opti/bfgs.cpp | 410 + libsrc/opti/linopt.cpp | 73 + libsrc/opti/linsearch.cpp | 351 + libsrc/opti/opti.hpp | 142 + libsrc/parallel/Makefile.am | 2 + libsrc/parallel/Makefile.in | 331 + libsrc/parallel/parallel.hpp | 274 + libsrc/parallel/parallelfunc.hpp | 15 + libsrc/parallel/parallelinterface.hpp | 52 + libsrc/parallel/paralleltop.hpp | 267 + libsrc/stlgeom/Makefile.am | 5 + libsrc/stlgeom/Makefile.in | 449 + libsrc/stlgeom/meshstlsurface.cpp | 1133 ++ libsrc/stlgeom/meshstlsurface.hpp | 121 + libsrc/stlgeom/stlgeom.cpp | 3471 +++++ libsrc/stlgeom/stlgeom.hpp | 450 + libsrc/stlgeom/stlgeomchart.cpp | 798 ++ libsrc/stlgeom/stlgeommesh.cpp | 1590 +++ libsrc/stlgeom/stlline.cpp | 780 ++ libsrc/stlgeom/stlline.hpp | 188 + libsrc/stlgeom/stltool.cpp | 1288 ++ libsrc/stlgeom/stltool.hpp | 271 + libsrc/stlgeom/stltopology.cpp | 1067 ++ libsrc/stlgeom/stltopology.hpp | 362 + libsrc/visualization/Makefile.am | 6 + libsrc/visualization/Makefile.in | 451 + libsrc/visualization/meshdoc.cpp | 620 + libsrc/visualization/meshdoc.hpp | 37 + libsrc/visualization/mvdraw.cpp | 1464 ++ libsrc/visualization/mvdraw.hpp | 327 + libsrc/visualization/soldata.hpp | 58 + libsrc/visualization/stlmeshing.cpp | 1076 ++ libsrc/visualization/vispar.hpp | 102 + libsrc/visualization/visual.hpp | 26 + libsrc/visualization/vscsg.cpp | 265 + libsrc/visualization/vsfieldlines.cpp | 722 + libsrc/visualization/vsmesh.cpp | 3674 +++++ libsrc/visualization/vsocc.cpp | 752 + libsrc/visualization/vssolution.cpp | 4980 +++++++ libsrc/visualization/vssolution.hpp | 414 + ltmain.sh | 8406 +++++++++++ missing | 336 + mkinstalldirs | 111 + ng/Makefile.am | 14 + ng/Makefile.in | 490 + ng/demoview.cpp | 442 + ng/demoview.hpp | 146 + ng/ng_acis.hpp | 193 + ng/ngappinit.cpp | 533 + ng/ngpkg.cpp | 5096 +++++++ ng/onetcl.cpp | 8276 +++++++++++ 335 files changed, 208368 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.cvs create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100755 depcomp create mode 100755 install-sh create mode 100644 libsrc/Makefile.am create mode 100644 libsrc/Makefile.in create mode 100644 libsrc/csg/Makefile.am create mode 100644 libsrc/csg/Makefile.in create mode 100644 libsrc/csg/algprim.cpp create mode 100644 libsrc/csg/algprim.hpp create mode 100644 libsrc/csg/brick.cpp create mode 100644 libsrc/csg/brick.hpp create mode 100644 libsrc/csg/bspline2d.cpp create mode 100644 libsrc/csg/csg.hpp create mode 100644 libsrc/csg/csgeom.cpp create mode 100644 libsrc/csg/csgeom.hpp create mode 100644 libsrc/csg/csgparser.cpp create mode 100644 libsrc/csg/csgparser.hpp create mode 100644 libsrc/csg/curve2d.cpp create mode 100644 libsrc/csg/curve2d.hpp create mode 100644 libsrc/csg/edgeflw.cpp create mode 100644 libsrc/csg/edgeflw.hpp create mode 100644 libsrc/csg/explicitcurve2d.cpp create mode 100644 libsrc/csg/explicitcurve2d.hpp create mode 100644 libsrc/csg/extrusion.cpp create mode 100644 libsrc/csg/extrusion.hpp create mode 100644 libsrc/csg/gencyl.cpp create mode 100644 libsrc/csg/gencyl.hpp create mode 100644 libsrc/csg/genmesh.cpp create mode 100644 libsrc/csg/geoml.hpp create mode 100644 libsrc/csg/identify.cpp create mode 100644 libsrc/csg/identify.hpp create mode 100644 libsrc/csg/manifold.cpp create mode 100644 libsrc/csg/manifold.hpp create mode 100644 libsrc/csg/meshsurf.cpp create mode 100644 libsrc/csg/meshsurf.hpp create mode 100644 libsrc/csg/polyhedra.cpp create mode 100644 libsrc/csg/polyhedra.hpp create mode 100644 libsrc/csg/revolution.cpp create mode 100644 libsrc/csg/revolution.hpp create mode 100644 libsrc/csg/singularref.cpp create mode 100644 libsrc/csg/singularref.hpp create mode 100644 libsrc/csg/solid.cpp create mode 100644 libsrc/csg/solid.hpp create mode 100644 libsrc/csg/specpoin.cpp create mode 100644 libsrc/csg/specpoin.hpp create mode 100644 libsrc/csg/spline3d.cpp create mode 100644 libsrc/csg/spline3d.hpp create mode 100644 libsrc/csg/surface.cpp create mode 100644 libsrc/csg/surface.hpp create mode 100644 libsrc/csg/triapprox.cpp create mode 100644 libsrc/csg/triapprox.hpp create mode 100644 libsrc/general/Makefile.am create mode 100644 libsrc/general/Makefile.in create mode 100644 libsrc/general/array.cpp create mode 100644 libsrc/general/array.hpp create mode 100644 libsrc/general/autodiff.hpp create mode 100644 libsrc/general/autoptr.hpp create mode 100644 libsrc/general/bitarray.cpp create mode 100644 libsrc/general/bitarray.hpp create mode 100644 libsrc/general/dynamicmem.cpp create mode 100644 libsrc/general/dynamicmem.hpp create mode 100644 libsrc/general/flags.cpp create mode 100644 libsrc/general/flags.hpp create mode 100644 libsrc/general/hashtabl.cpp create mode 100644 libsrc/general/hashtabl.hpp create mode 100644 libsrc/general/moveablemem.cpp create mode 100644 libsrc/general/moveablemem.hpp create mode 100644 libsrc/general/myadt.hpp create mode 100644 libsrc/general/mystring.cpp create mode 100644 libsrc/general/mystring.hpp create mode 100644 libsrc/general/netgenout.hpp create mode 100644 libsrc/general/ngexception.cpp create mode 100644 libsrc/general/ngexception.hpp create mode 100644 libsrc/general/optmem.cpp create mode 100644 libsrc/general/optmem.hpp create mode 100644 libsrc/general/parthreads.cpp create mode 100644 libsrc/general/parthreads.hpp create mode 100644 libsrc/general/profiler.cpp create mode 100644 libsrc/general/profiler.hpp create mode 100644 libsrc/general/seti.cpp create mode 100644 libsrc/general/seti.hpp create mode 100644 libsrc/general/sort.cpp create mode 100644 libsrc/general/sort.hpp create mode 100644 libsrc/general/spbita2d.cpp create mode 100644 libsrc/general/spbita2d.hpp create mode 100644 libsrc/general/stack.hpp create mode 100644 libsrc/general/symbolta.cpp create mode 100644 libsrc/general/symbolta.hpp create mode 100644 libsrc/general/table.cpp create mode 100644 libsrc/general/table.hpp create mode 100644 libsrc/general/template.hpp create mode 100644 libsrc/geom2d/Makefile.am create mode 100644 libsrc/geom2d/Makefile.in create mode 100644 libsrc/geom2d/genmesh2d.cpp create mode 100644 libsrc/geom2d/geom2dmesh.cpp create mode 100644 libsrc/geom2d/geom2dmesh.hpp create mode 100644 libsrc/geom2d/geometry2d.hpp create mode 100644 libsrc/geom2d/spline.cpp create mode 100644 libsrc/geom2d/spline.hpp create mode 100644 libsrc/geom2d/spline2d.hpp create mode 100644 libsrc/geom2d/splinegeometry.cpp create mode 100644 libsrc/geom2d/splinegeometry.hpp create mode 100644 libsrc/geom2d/splinegeometry2.hpp create mode 100644 libsrc/gprim/Makefile.am create mode 100644 libsrc/gprim/Makefile.in create mode 100644 libsrc/gprim/adtree.cpp create mode 100644 libsrc/gprim/adtree.hpp create mode 100644 libsrc/gprim/geom2d.cpp create mode 100644 libsrc/gprim/geom2d.hpp create mode 100644 libsrc/gprim/geom3d.cpp create mode 100644 libsrc/gprim/geom3d.hpp create mode 100644 libsrc/gprim/geomfuncs.cpp create mode 100644 libsrc/gprim/geomfuncs.hpp create mode 100644 libsrc/gprim/geomobjects.hpp create mode 100644 libsrc/gprim/geomobjects2.hpp create mode 100644 libsrc/gprim/geomops.hpp create mode 100644 libsrc/gprim/geomops2.hpp create mode 100644 libsrc/gprim/geomtest3d.cpp create mode 100644 libsrc/gprim/geomtest3d.hpp create mode 100644 libsrc/gprim/gprim.hpp create mode 100644 libsrc/gprim/transform3d.cpp create mode 100644 libsrc/gprim/transform3d.hpp create mode 100644 libsrc/include/Makefile.am create mode 100644 libsrc/include/Makefile.in create mode 100644 libsrc/include/acisgeom.hpp create mode 100644 libsrc/include/csg.hpp create mode 100644 libsrc/include/geometry2d.hpp create mode 100644 libsrc/include/gprim.hpp create mode 100644 libsrc/include/incvis.hpp create mode 100644 libsrc/include/linalg.hpp create mode 100644 libsrc/include/meshing.hpp create mode 100644 libsrc/include/myadt.hpp create mode 100644 libsrc/include/mydefs.hpp create mode 100644 libsrc/include/mystdlib.h create mode 100644 libsrc/include/occgeom.hpp create mode 100644 libsrc/include/opti.hpp create mode 100644 libsrc/include/parallel.hpp create mode 100644 libsrc/include/stepgeom.hpp create mode 100644 libsrc/include/stepreader.hpp create mode 100644 libsrc/include/stlgeom.hpp create mode 100644 libsrc/include/visual.hpp create mode 100644 libsrc/interface/Makefile.am create mode 100644 libsrc/interface/Makefile.in create mode 100644 libsrc/interface/importsolution.cpp create mode 100644 libsrc/interface/nginterface.cpp create mode 100644 libsrc/interface/nginterface.h create mode 100644 libsrc/interface/printdest.cpp create mode 100644 libsrc/interface/read_fnf_mesh.cpp create mode 100644 libsrc/interface/readtetmesh.cpp create mode 100644 libsrc/interface/readuser.cpp create mode 100644 libsrc/interface/writeabaqus.cpp create mode 100644 libsrc/interface/writediffpack.cpp create mode 100644 libsrc/interface/writedolfin.cpp create mode 100644 libsrc/interface/writeelmer.cpp create mode 100644 libsrc/interface/writefeap.cpp create mode 100644 libsrc/interface/writefluent.cpp create mode 100644 libsrc/interface/writegmsh.cpp create mode 100644 libsrc/interface/writejcm.cpp create mode 100644 libsrc/interface/writepermas.cpp create mode 100644 libsrc/interface/writetecplot.cpp create mode 100644 libsrc/interface/writetet.cpp create mode 100644 libsrc/interface/writetochnog.cpp create mode 100644 libsrc/interface/writeuser.cpp create mode 100644 libsrc/interface/writeuser.hpp create mode 100644 libsrc/interface/wuchemnitz.cpp create mode 100644 libsrc/linalg/Makefile.am create mode 100644 libsrc/linalg/Makefile.in create mode 100644 libsrc/linalg/densemat.cpp create mode 100644 libsrc/linalg/densemat.hpp create mode 100644 libsrc/linalg/linalg.hpp create mode 100644 libsrc/linalg/polynomial.cpp create mode 100644 libsrc/linalg/polynomial.hpp create mode 100644 libsrc/linalg/vector.cpp create mode 100644 libsrc/linalg/vector.hpp create mode 100644 libsrc/meshing/Makefile.am create mode 100644 libsrc/meshing/Makefile.in create mode 100644 libsrc/meshing/adfront2.cpp create mode 100644 libsrc/meshing/adfront2.hpp create mode 100644 libsrc/meshing/adfront3.cpp create mode 100644 libsrc/meshing/adfront3.hpp create mode 100644 libsrc/meshing/bisect.cpp create mode 100644 libsrc/meshing/bisect.hpp create mode 100644 libsrc/meshing/boundarylayer.cpp create mode 100644 libsrc/meshing/boundarylayer.hpp create mode 100644 libsrc/meshing/classifyhpel.hpp create mode 100644 libsrc/meshing/clusters.cpp create mode 100644 libsrc/meshing/clusters.hpp create mode 100644 libsrc/meshing/curvedelems.hpp create mode 100644 libsrc/meshing/curvedelems_new.cpp create mode 100644 libsrc/meshing/curvedelems_new.hpp create mode 100644 libsrc/meshing/delaunay.cpp create mode 100644 libsrc/meshing/findip.hpp create mode 100644 libsrc/meshing/findip2.hpp create mode 100644 libsrc/meshing/geomsearch.cpp create mode 100644 libsrc/meshing/geomsearch.hpp create mode 100644 libsrc/meshing/global.cpp create mode 100644 libsrc/meshing/global.hpp create mode 100644 libsrc/meshing/hpref_hex.hpp create mode 100644 libsrc/meshing/hpref_prism.hpp create mode 100644 libsrc/meshing/hpref_pyramid.hpp create mode 100644 libsrc/meshing/hpref_quad.hpp create mode 100644 libsrc/meshing/hpref_segm.hpp create mode 100644 libsrc/meshing/hpref_tet.hpp create mode 100644 libsrc/meshing/hpref_trig.hpp create mode 100644 libsrc/meshing/hprefinement.cpp create mode 100644 libsrc/meshing/hprefinement.hpp create mode 100644 libsrc/meshing/improve2.cpp create mode 100644 libsrc/meshing/improve2.hpp create mode 100644 libsrc/meshing/improve2gen.cpp create mode 100644 libsrc/meshing/improve3.cpp create mode 100644 libsrc/meshing/improve3.hpp create mode 100644 libsrc/meshing/localh.cpp create mode 100644 libsrc/meshing/localh.hpp create mode 100644 libsrc/meshing/meshclass.cpp create mode 100644 libsrc/meshing/meshclass.hpp create mode 100644 libsrc/meshing/meshfunc.cpp create mode 100644 libsrc/meshing/meshfunc.hpp create mode 100644 libsrc/meshing/meshfunc2d.cpp create mode 100644 libsrc/meshing/meshing.hpp create mode 100644 libsrc/meshing/meshing2.cpp create mode 100644 libsrc/meshing/meshing2.hpp create mode 100644 libsrc/meshing/meshing3.cpp create mode 100644 libsrc/meshing/meshing3.hpp create mode 100644 libsrc/meshing/meshtool.cpp create mode 100644 libsrc/meshing/meshtool.hpp create mode 100644 libsrc/meshing/meshtype.cpp create mode 100644 libsrc/meshing/meshtype.hpp create mode 100644 libsrc/meshing/msghandler.cpp create mode 100644 libsrc/meshing/msghandler.hpp create mode 100644 libsrc/meshing/netrule2.cpp create mode 100644 libsrc/meshing/netrule3.cpp create mode 100644 libsrc/meshing/parser2.cpp create mode 100644 libsrc/meshing/parser3.cpp create mode 100644 libsrc/meshing/prism2rls.cpp create mode 100644 libsrc/meshing/prism2rls_2.cpp create mode 100644 libsrc/meshing/pyramid2rls.cpp create mode 100644 libsrc/meshing/pyramidrls.cpp create mode 100644 libsrc/meshing/quadrls.cpp create mode 100644 libsrc/meshing/refine.cpp create mode 100644 libsrc/meshing/ruler2.cpp create mode 100644 libsrc/meshing/ruler2.hpp create mode 100644 libsrc/meshing/ruler3.cpp create mode 100644 libsrc/meshing/ruler3.hpp create mode 100644 libsrc/meshing/secondorder.cpp create mode 100644 libsrc/meshing/smoothing2.5.cpp create mode 100644 libsrc/meshing/smoothing2.cpp create mode 100644 libsrc/meshing/smoothing3.cpp create mode 100644 libsrc/meshing/specials.cpp create mode 100644 libsrc/meshing/specials.hpp create mode 100644 libsrc/meshing/tetrarls.cpp create mode 100644 libsrc/meshing/topology.cpp create mode 100644 libsrc/meshing/topology.hpp create mode 100644 libsrc/meshing/triarls.cpp create mode 100644 libsrc/meshing/validate.cpp create mode 100644 libsrc/meshing/validate.hpp create mode 100644 libsrc/meshing/zrefine.cpp create mode 100644 libsrc/occ/Makefile.am create mode 100644 libsrc/occ/Makefile.in create mode 100644 libsrc/occ/Partition_Inter2d.cxx create mode 100644 libsrc/occ/Partition_Inter3d.cxx create mode 100644 libsrc/occ/Partition_Loop.cxx create mode 100644 libsrc/occ/Partition_Loop2d.cxx create mode 100644 libsrc/occ/Partition_Loop3d.cxx create mode 100644 libsrc/occ/Partition_Spliter.cxx create mode 100644 libsrc/occ/occconstruction.cpp create mode 100644 libsrc/occ/occgenmesh.cpp create mode 100644 libsrc/occ/occgeom.cpp create mode 100644 libsrc/occ/occmeshsurf.cpp create mode 100644 libsrc/opti/Makefile.am create mode 100644 libsrc/opti/Makefile.in create mode 100644 libsrc/opti/bfgs.cpp create mode 100644 libsrc/opti/linopt.cpp create mode 100644 libsrc/opti/linsearch.cpp create mode 100644 libsrc/opti/opti.hpp create mode 100644 libsrc/parallel/Makefile.am create mode 100644 libsrc/parallel/Makefile.in create mode 100644 libsrc/parallel/parallel.hpp create mode 100644 libsrc/parallel/parallelfunc.hpp create mode 100644 libsrc/parallel/parallelinterface.hpp create mode 100644 libsrc/parallel/paralleltop.hpp create mode 100644 libsrc/stlgeom/Makefile.am create mode 100644 libsrc/stlgeom/Makefile.in create mode 100644 libsrc/stlgeom/meshstlsurface.cpp create mode 100644 libsrc/stlgeom/meshstlsurface.hpp create mode 100644 libsrc/stlgeom/stlgeom.cpp create mode 100644 libsrc/stlgeom/stlgeom.hpp create mode 100644 libsrc/stlgeom/stlgeomchart.cpp create mode 100644 libsrc/stlgeom/stlgeommesh.cpp create mode 100644 libsrc/stlgeom/stlline.cpp create mode 100644 libsrc/stlgeom/stlline.hpp create mode 100644 libsrc/stlgeom/stltool.cpp create mode 100644 libsrc/stlgeom/stltool.hpp create mode 100644 libsrc/stlgeom/stltopology.cpp create mode 100644 libsrc/stlgeom/stltopology.hpp create mode 100644 libsrc/visualization/Makefile.am create mode 100644 libsrc/visualization/Makefile.in create mode 100644 libsrc/visualization/meshdoc.cpp create mode 100644 libsrc/visualization/meshdoc.hpp create mode 100644 libsrc/visualization/mvdraw.cpp create mode 100644 libsrc/visualization/mvdraw.hpp create mode 100644 libsrc/visualization/soldata.hpp create mode 100644 libsrc/visualization/stlmeshing.cpp create mode 100644 libsrc/visualization/vispar.hpp create mode 100644 libsrc/visualization/visual.hpp create mode 100644 libsrc/visualization/vscsg.cpp create mode 100644 libsrc/visualization/vsfieldlines.cpp create mode 100644 libsrc/visualization/vsmesh.cpp create mode 100644 libsrc/visualization/vsocc.cpp create mode 100644 libsrc/visualization/vssolution.cpp create mode 100644 libsrc/visualization/vssolution.hpp create mode 100644 ltmain.sh create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 ng/Makefile.am create mode 100644 ng/Makefile.in create mode 100644 ng/demoview.cpp create mode 100644 ng/demoview.hpp create mode 100644 ng/ng_acis.hpp create mode 100644 ng/ngappinit.cpp create mode 100644 ng/ngpkg.cpp create mode 100644 ng/onetcl.cpp diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..d0c98081 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Joachim Schoeberl diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..5b6e7c66 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), 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 Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. 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. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..02a4a074 --- /dev/null +++ b/INSTALL @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..77f113d3 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2 @@ + +SUBDIRS = libsrc ng diff --git a/Makefile.cvs b/Makefile.cvs new file mode 100644 index 00000000..d1607023 --- /dev/null +++ b/Makefile.cvs @@ -0,0 +1,8 @@ +default: all + +all: + aclocal + autoheader + automake + autoconf + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..c0a70b36 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,640 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS COPYING COPYING.LIB ChangeLog \ + INSTALL NEWS TODO config.guess config.sub depcomp install-sh \ + ltmain.sh missing mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = libsrc ng +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d $(distdir) || mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-exec-am: + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \ + distclean distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/README b/README new file mode 100644 index 00000000..e69de29b diff --git a/TODO b/TODO new file mode 100644 index 00000000..e69de29b diff --git a/config.guess b/config.guess new file mode 100755 index 00000000..5145e357 --- /dev/null +++ b/config.guess @@ -0,0 +1,1363 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-10-21' + +# This file 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# This shell variable is my proudest work .. or something. --bje + +set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; +(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) + || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; +dummy=$tmpdir/dummy ; +files="$dummy.c $dummy.o $dummy.rel $dummy" ; +trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $files ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; +unset files' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + eval $set_cc_for_build + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null + if test "$?" = 0 ; then + case `$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; + esac + fi + rm -f $dummy.s $dummy && rmdir $tmpdir + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy && rmdir $tmpdir + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c && rmdir $tmpdir + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 +rm -f $dummy.c $dummy && rmdir $tmpdir + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..28161880 --- /dev/null +++ b/config.h.in @@ -0,0 +1,59 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..1dea9b79 --- /dev/null +++ b/config.sub @@ -0,0 +1,1470 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-09-05' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39 | mipstx39el \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 00000000..221887f6 --- /dev/null +++ b/configure @@ -0,0 +1,17764 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.63. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell bug-autoconf@gnu.org about your system, + echo including any error possibly output before this message. + echo This can help us improve future autoconf versions. + echo Configuration will now proceed without shell functions. +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$lt_ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +ECHO=${lt_ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<_LT_EOF +$* +_LT_EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$lt_ECHO"; then + if test "X${echo_test_string+set}" != Xset; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if { echo_test_string=`eval $cmd`; } 2>/dev/null && + { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null + then + break + fi + done + fi + + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : + else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$ECHO" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + ECHO='print -r' + elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + ECHO='printf %s\n' + if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && + echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + ECHO="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + ECHO="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + ECHO=echo + fi + fi + fi + fi + fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +lt_ECHO=$ECHO +if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="configure.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +lt_ECHO +RANLIB +AR +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { $as_echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { $as_echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 + { (exit 1); exit 1; }; } ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { $as_echo "$as_me: error: working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.63 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.63. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers config.h" + +am__api_version='1.10' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + +done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +$as_echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:$LINENO: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=netgen + VERSION=5.0 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:$LINENO: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C++ compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + fi + fi +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:$LINENO: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.6' +macro_revision='1.3012' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ $as_echo "$as_me:$LINENO: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +$as_echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:$LINENO: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +$as_echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +{ $as_echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + $as_unset ac_script || ac_script= + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable sed could be found in \$PATH" >&5 +$as_echo "$as_me: error: no acceptable sed could be found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:$LINENO: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if test "${ac_cv_path_FGREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +$as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:$LINENO: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test "${lt_cv_path_NM+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$ac_tool_prefix"; then + for ac_prog in "dumpbin -symbols" "link -dump -symbols" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DUMPBIN+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:$LINENO: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in "dumpbin -symbols" "link -dump -symbols" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if test "${lt_cv_nm_interface+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:4804: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:4807: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:4810: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:$LINENO: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ + = "XX$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:$LINENO: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:$LINENO: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:$LINENO: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:$LINENO: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:$LINENO: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:$LINENO: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:$LINENO: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 6016 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + lt_cv_cc_needs_belf=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_cc_needs_belf=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:$LINENO: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:$LINENO: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LIPO+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:$LINENO: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:$LINENO: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL64+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:$LINENO: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:$LINENO: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + lt_cv_ld_exported_symbols_list=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_ld_exported_symbols_list=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:$LINENO: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +_lt_caught_CXX_error=yes; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:$LINENO: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if test "${lt_cv_objdir+set}" = set; then + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + + + + + + + + + + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:$LINENO: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + { $as_echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8588: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:8592: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl*) + # IBM XL C 8.0/Fortran 10.1 on PPC + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:8927: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:8931: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:9032: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:9036: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:9087: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:9091: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:$LINENO: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag= + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat >conftest.$ac_ext <<_ACEOF +int foo(void) {} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +$as_echo "$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then + shlibpath_overrides_runpath=yes +fi + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:$LINENO: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_dl_dlopen=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + { $as_echo "$as_me:$LINENO: checking for shl_load" >&5 +$as_echo_n "checking for shl_load... " >&6; } +if test "${ac_cv_func_shl_load+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_shl_load || defined __stub___shl_load +choke me +#endif + +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_func_shl_load=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shl_load=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +$as_echo "$ac_cv_func_shl_load" >&6; } +if test "x$ac_cv_func_shl_load" = x""yes; then + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_dld_shl_load=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_shl_load=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = x""yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + { $as_echo "$as_me:$LINENO: checking for dlopen" >&5 +$as_echo_n "checking for dlopen... " >&6; } +if test "${ac_cv_func_dlopen+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_dlopen || defined __stub___dlopen +choke me +#endif + +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_func_dlopen=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_dlopen=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +$as_echo "$ac_cv_func_dlopen" >&6; } +if test "x$ac_cv_func_dlopen" = x""yes; then + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_dl_dlopen=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_svld_dlopen=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_svld_dlopen=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = x""yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_dld_dld_link=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_dld_link=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = x""yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 11887 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 11983 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:$LINENO: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:$LINENO: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:$LINENO: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC="$lt_save_CC" + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +$as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=echo + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5]* | *pgcpp\ [1-5]*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 will use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + xl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=echo + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC*) + # IBM XL 8.0 on PPC + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac +{ $as_echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_prog_compiler_pic_CXX" >&6; } + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14003: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:14007: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14102: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14106: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14154: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14158: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:$LINENO: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + +{ $as_echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +$as_echo "$archive_cmds_need_lc_CXX" >&6; } + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # Some binutils ld are patched to set DT_RUNPATH + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then + shlibpath_overrides_runpath=yes +fi + +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +ac_config_files="$ac_config_files Makefile libsrc/Makefile libsrc/csg/Makefile libsrc/general/Makefile libsrc/geom2d/Makefile libsrc/gprim/Makefile libsrc/include/Makefile libsrc/interface/Makefile libsrc/linalg/Makefile libsrc/meshing/Makefile libsrc/occ/Makefile libsrc/opti/Makefile libsrc/parallel/Makefile libsrc/stlgeom/Makefile libsrc/visualization/Makefile ng/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.63. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTION]... [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.63, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { $as_echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { $as_echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' +macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' +enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' +pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' +host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' +host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' +host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' +build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' +build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' +build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' +SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' +Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' +GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' +EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' +FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' +LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' +NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' +LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' +ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' +exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' +lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' +reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' +AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' +STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' +RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' +compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' +GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' +SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' +ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' +need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' +LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' +libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' +need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' +version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' +runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' +libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' +soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' +finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' +old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' +striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' +predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' +postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# Quote evaled strings. +for var in SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +SHELL \ +ECHO \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_flag_spec_ld_CXX \ +hardcode_libdir_separator_CXX \ +fix_srcfile_path_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX; do + case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Fix-up fallback echo if it was mangled by the above quoting rules. +case \$lt_ECHO in +*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` + ;; +esac + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "libsrc/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/Makefile" ;; + "libsrc/csg/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/csg/Makefile" ;; + "libsrc/general/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/general/Makefile" ;; + "libsrc/geom2d/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/geom2d/Makefile" ;; + "libsrc/gprim/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/gprim/Makefile" ;; + "libsrc/include/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/include/Makefile" ;; + "libsrc/interface/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/interface/Makefile" ;; + "libsrc/linalg/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/linalg/Makefile" ;; + "libsrc/meshing/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/meshing/Makefile" ;; + "libsrc/occ/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/occ/Makefile" ;; + "libsrc/opti/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/opti/Makefile" ;; + "libsrc/parallel/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/parallel/Makefile" ;; + "libsrc/stlgeom/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/stlgeom/Makefile" ;; + "libsrc/visualization/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/visualization/Makefile" ;; + "ng/Makefile") CONFIG_FILES="$CONFIG_FILES ng/Makefile" ;; + + *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + $as_echo "$as_me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=' ' +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 +$as_echo "$as_me: error: could not setup config files machinery" >&2;} + { (exit 1); exit 1; }; } +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 +$as_echo "$as_me: error: could not setup config headers machinery" >&2;} + { (exit 1); exit 1; }; } +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 +$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + ac_file_inputs="$ac_file_inputs '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 +$as_echo "$as_me: error: could not create -" >&2;} + { (exit 1); exit 1; }; } + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that does not interpret backslashes. +ECHO=$lt_ECHO + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "X${3}" \ + | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..f597e94c --- /dev/null +++ b/configure.in @@ -0,0 +1,13 @@ +AC_INIT(configure.in) + +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE(netgen, 5.0) + +AC_LANG_CPLUSPLUS +AC_PROG_CXX +AM_PROG_LIBTOOL + +AC_OUTPUT(Makefile libsrc/Makefile libsrc/csg/Makefile libsrc/general/Makefile \ + libsrc/geom2d/Makefile libsrc/gprim/Makefile libsrc/include/Makefile libsrc/interface/Makefile \ + libsrc/linalg/Makefile libsrc/meshing/Makefile libsrc/occ/Makefile libsrc/opti/Makefile \ + libsrc/parallel/Makefile libsrc/stlgeom/Makefile libsrc/visualization/Makefile ng/Makefile) diff --git a/depcomp b/depcomp new file mode 100755 index 00000000..4c20c6c9 --- /dev/null +++ b/depcomp @@ -0,0 +1,441 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 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 to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. This file always lives in the current directory. + # Also, the AIX compiler puts `$object:' at the start of each line; + # $object doesn't have directory information. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Must come before tru64. + + # Intel's C compiler understands `-MD -MF file'. However + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 AIX compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + + tmpdepfile1="$object.d" + tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` + if test "$libtool" = yes; then + "$@" -Wc,-MD + else + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + test -z "$dashmflag" && dashmflag=-M + ( IFS=" " + case " $* " in + *" --mode=compile "*) # this is libtool, let us make it quiet + for arg + do # cycle over the arguments + case "$arg" in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + # X makedepend + ( + shift + cleared=no + for arg in "$@"; do + case $cleared in no) + set ""; shift + cleared=yes + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift;; + -*) + ;; + *) + set fnord "$@" "$arg"; shift;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tail +3 "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/install-sh b/install-sh new file mode 100755 index 00000000..36f96f3e --- /dev/null +++ b/install-sh @@ -0,0 +1,276 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "$0: no input file specified" >&2 + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d "$dst" ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "$0: $src does not exist" >&2 + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "$0: no destination specified" >&2 + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d "$dst" ] + then + dst=$dst/`basename "$src"` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-$defaultIFS}" + +oIFS=$IFS +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS=$oIFS + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp=$pathcomp$1 + shift + + if [ ! -d "$pathcomp" ] ; + then + $mkdirprog "$pathcomp" + else + : + fi + + pathcomp=$pathcomp/ +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd "$dst" && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename "$dst"` + else + : + fi + +# Make a couple of temp file names in the proper directory. + + dsttmp=$dstdir/#inst.$$# + rmtmp=$dstdir/#rm.$$# + +# Trap to clean up temp files at exit. + + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + +# Move or copy the file name to the temp name + + $doit $instcmd "$src" "$dsttmp" && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && + +# Now remove or move aside any old file at destination location. We try this +# two ways since rm can't unlink itself on some systems and the destination +# file might be busy for other reasons. In this case, the final cleanup +# might fail but the new file should still install successfully. + +{ + if [ -f "$dstdir/$dstfile" ] + then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || + $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || + { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi +} && + +# Now rename the file to the real destination. + + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + +fi && + +# The final little trick to "correctly" pass the exit status to the exit trap. + +{ + (exit 0); exit +} diff --git a/libsrc/Makefile.am b/libsrc/Makefile.am new file mode 100644 index 00000000..670022e2 --- /dev/null +++ b/libsrc/Makefile.am @@ -0,0 +1,4 @@ +INCLUDES = +METASOURCES = AUTO +SUBDIRS = csg general geom2d gprim include interface linalg meshing occ opti \ + parallel stlgeom visualization diff --git a/libsrc/Makefile.in b/libsrc/Makefile.in new file mode 100644 index 00000000..34af53a1 --- /dev/null +++ b/libsrc/Makefile.in @@ -0,0 +1,492 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = +METASOURCES = AUTO +SUBDIRS = csg general geom2d gprim include interface linalg meshing occ opti \ + parallel stlgeom visualization + +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-exec-am: + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/csg/Makefile.am b/libsrc/csg/Makefile.am new file mode 100644 index 00000000..3b2a3d6d --- /dev/null +++ b/libsrc/csg/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libcsg.a +libcsg_a_SOURCES = algprim.cpp brick.cpp bspline2d.cpp csgeom.cpp csgparser.cpp \ + curve2d.cpp edgeflw.cpp explicitcurve2d.cpp extrusion.cpp gencyl.cpp genmesh.cpp \ + identify.cpp manifold.cpp meshsurf.cpp polyhedra.cpp revolution.cpp singularref.cpp \ + solid.cpp specpoin.cpp spline3d.cpp surface.cpp triapprox.cpp diff --git a/libsrc/csg/Makefile.in b/libsrc/csg/Makefile.in new file mode 100644 index 00000000..7634144c --- /dev/null +++ b/libsrc/csg/Makefile.in @@ -0,0 +1,471 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/csg +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libcsg_a_AR = $(AR) $(ARFLAGS) +libcsg_a_LIBADD = +am_libcsg_a_OBJECTS = algprim.$(OBJEXT) brick.$(OBJEXT) \ + bspline2d.$(OBJEXT) csgeom.$(OBJEXT) csgparser.$(OBJEXT) \ + curve2d.$(OBJEXT) edgeflw.$(OBJEXT) explicitcurve2d.$(OBJEXT) \ + extrusion.$(OBJEXT) gencyl.$(OBJEXT) genmesh.$(OBJEXT) \ + identify.$(OBJEXT) manifold.$(OBJEXT) meshsurf.$(OBJEXT) \ + polyhedra.$(OBJEXT) revolution.$(OBJEXT) singularref.$(OBJEXT) \ + solid.$(OBJEXT) specpoin.$(OBJEXT) spline3d.$(OBJEXT) \ + surface.$(OBJEXT) triapprox.$(OBJEXT) +libcsg_a_OBJECTS = $(am_libcsg_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libcsg_a_SOURCES) +DIST_SOURCES = $(libcsg_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libcsg.a +libcsg_a_SOURCES = algprim.cpp brick.cpp bspline2d.cpp csgeom.cpp csgparser.cpp \ + curve2d.cpp edgeflw.cpp explicitcurve2d.cpp extrusion.cpp gencyl.cpp genmesh.cpp \ + identify.cpp manifold.cpp meshsurf.cpp polyhedra.cpp revolution.cpp singularref.cpp \ + solid.cpp specpoin.cpp spline3d.cpp surface.cpp triapprox.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/csg/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/csg/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libcsg.a: $(libcsg_a_OBJECTS) $(libcsg_a_DEPENDENCIES) + -rm -f libcsg.a + $(libcsg_a_AR) libcsg.a $(libcsg_a_OBJECTS) $(libcsg_a_LIBADD) + $(RANLIB) libcsg.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algprim.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brick.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bspline2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csgeom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csgparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curve2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edgeflw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/explicitcurve2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extrusion.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gencyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genmesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identify.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manifold.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshsurf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedra.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revolution.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/singularref.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specpoin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spline3d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triapprox.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/csg/algprim.cpp b/libsrc/csg/algprim.cpp new file mode 100644 index 00000000..c4370313 --- /dev/null +++ b/libsrc/csg/algprim.cpp @@ -0,0 +1,1685 @@ +#include + + +#include +#include + + +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; + } + + + 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) + { + eps_base = 1e-8; + + 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 (const char *& classname, + ARRAY & 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 & 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 + { + const Plane * ps2 = dynamic_cast(&s2); + + if(ps2) + { + Point<3> pp2 = ps2->GetSurfacePoint(); + Vec<3> n2 = s2.GetNormalVector(pp2); + + if(fabs(n*n2) < 1.-eps_base) + return 0; + + if (fabs (s2.CalcFunctionValue(p)) > eps) return 0; + } + else + { + //(*testout) << "pos1" << endl; + if (fabs (s2.CalcFunctionValue(p)) > eps) return 0; + Vec<3> hv1, hv2; + hv1 = n.GetNormal (); + hv2 = Cross (n, hv1); + + Point<3> hp = p + hv1; + //(*testout) << "pos2" << endl; + //(*testout) << "eps " << eps << " s2.CalcFunctionValue(hp) " << s2.CalcFunctionValue(hp) << endl; + if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0; + //(*testout) << "pos3" << endl; + hp = p + hv2; + if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0; + } + + //(*testout) << "pos4" << endl; + Vec<3> n1, n2; + n1 = GetNormalVector (p); + n2 = s2.GetNormalVector (p); + inv = (n1 * n2 < 0); + //(*testout) << "inv " << inv << endl; + 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> pp; + + 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++) + { + pp = box.GetPointNr (i); + val = Plane::CalcFunctionValue (pp); + 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++) + { + pp = box.GetPointNr (i); + val = Plane::CalcFunctionValue (pp); + 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 (const char *& classname, ARRAY & 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 & 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 (&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 n = int(facets) + 1; + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double 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 (int j = 0; j < n; j++) + for (int 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); + } + + double Ellipsoid :: MaxCurvature () const + { + const double a2 = v1.Length2(); + const double b2 = v2.Length2(); + const double c2 = v3.Length2(); + + return max3 ( sqrt(a2)/min2(b2,c2), sqrt(b2)/min2(a2,c2), sqrt(c2)/min2(a2,b2) ); + } + + Point<3> Ellipsoid :: GetSurfacePoint () const + { + return a + v1; + } + + + + void Ellipsoid :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int n = int(facets) + 1; + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double 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 (int j = 0; j < n; j++) + for (int 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 (ARRAY & coeffs) + { + SetPrimitiveData(coeffs); + } + + Cylinder :: Cylinder (const Point<3> & aa, const Point<3> & ab, double ar) + { + a = aa; + b = ab; + vab = (b - a); + vab /= vab.Length(); + r = ar; + + // ( - 2 + + // - ^2 + 2 - ^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 (const char *& classname, ARRAY & 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 & 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 (&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(); + + // ( - 2 + + // - ^2 + 2 - ^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 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 (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double bg = double(j) / n; + + Point<3> p = a + (bg * lvab) + + ((r * cos(lg)) * n1) + + ((r * sin(lg)) * n2); + + tas.AddPoint (p); + } + + for (int j = 0; j < n; j++) + for (int 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; + if(avl.Length2() > avs.Length2()) + { + vl = avl; + vs = avs; + } + else + { + vl = avs; + vs = avl; + } + + 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 = pow(va * hvl,2) + pow(va * hvs,2) - 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/min(vs.Length2 (),vl.Length2()); + } + + double EllipticCylinder :: MaxCurvature () const + { + double aa = vs.Length(); + double bb = vl.Length(); + + return max2(bb/(aa*aa),aa/(bb*bb)); + } + + double EllipticCylinder :: MaxCurvatureLoc (const Point<3> & /* c */, + double /* rad */) const + { +#ifdef JOACHIMxxx + cout << "max curv local" << endl; + return 0.02; +#endif + + // saubere Loesung wird noch notwendig !!! + double aa = vs.Length(); + double bb = vl.Length(); + return max2(bb/(aa*aa),aa/(bb*bb)); + } + + + + Point<3> EllipticCylinder :: GetSurfacePoint () const + { + return a + vl; + } + + + + void EllipticCylinder :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int n = int(facets) + 1; + + Vec<3> axis = Cross (vl, vs); + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double bg = double(j) / n; + + Point<3> p = a + (bg * axis) + + cos(lg) * vl + sin(lg) * vs; + + tas.AddPoint (p); + } + + for (int j = 0; j < n; j++) + for (int 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 (const char *& classname, ARRAY & 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 & 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; + + + double maxr = max2(ra,rb); + cxx /= maxr; cyy /= maxr; czz /= maxr; + cxy /= maxr; cxz /= maxr; cyz /= maxr; + cx /= maxr; cy /= maxr; cz /= maxr; + c1 /= maxr; + + + // (*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()) *max2(ra,rb) + 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/(4*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)); + } + } + + + + + + + + + + /// Torus + /// Lorenzo Codecasa (codecasa@elet.polimi.it) + /// April 27th, 2005 + /// + /// begin... + Torus :: Torus (const Point<3> & ac, const Vec<3> & an, double aR, double ar) + { + c = ac; + n = an; + R = aR; + r = ar; + } + + void Torus :: GetPrimitiveData (const char *& classname, ARRAY & coeffs) const + { + classname = "torus"; + coeffs.SetSize (8); + coeffs.Elem(1) = c(0); + coeffs.Elem(2) = c(1); + coeffs.Elem(3) = c(2); + coeffs.Elem(4) = n(0); + coeffs.Elem(5) = n(1); + coeffs.Elem(6) = n(2); + coeffs.Elem(7) = R; + coeffs.Elem(8) = r; + } + + void Torus :: SetPrimitiveData (ARRAY & coeffs) + { + c(0) = coeffs.Elem(1); + c(1) = coeffs.Elem(2); + c(2) = coeffs.Elem(3); + n(0) = coeffs.Elem(4); + n(1) = coeffs.Elem(5); + n(2) = coeffs.Elem(6); + R = coeffs.Elem(7); + r = coeffs.Elem(8); + } + + Primitive * Torus :: CreateDefault () + { + return new Torus (Point<3> (0,0,0), Vec<3> (0,0,1), 2, 1); + } + + Primitive * Torus :: Copy () const + { + return new Torus (c, n, R, r); + } + + void Torus :: Transform (Transformation<3> & trans) + { + Point<3> hc; + trans.Transform (c, hc); + c = hc; + + Vec<3> hn; + trans.Transform (n, hn); + n = hn; + } + + int Torus :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const Torus * torus2 = dynamic_cast (&s2); + + if (!torus2) return 0; + + if (fabs (torus2->R - R) > eps) return 0; + + if (fabs (torus2->r - r) > eps) return 0; + + Vec<3> v2 = torus2->n - n; + if ( v2 * v2 > eps ) return 0; + + v2 = torus2->c - c; + if ( v2 * v2 > eps ) return 0; + + inv = 0; + return 1; + } + + double Torus :: CalcFunctionValue (const Point<3> & point) const + { + Vec<3> v1 = point - c; + double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2); + double a3 = a1 + R * R - r * r; + double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + return ( a3 * a3 -4 * R * R * ( a1 - a2 * a2 / a4 ) ) / ( R * R * R ); + } + + void Torus :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + Vec<3> v1 = point - c; + double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2); + double a3 = a1 - R * R - r * r; + double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + grad(0) = ( 4 * a3 * v1(0) + 8 * R * R * a2 / a4 * n(0) ) / ( R * R * R ); + grad(1) = ( 4 * a3 * v1(1) + 8 * R * R * a2 / a4 * n(1) ) / ( R * R * R ); + grad(2) = ( 4 * a3 * v1(2) + 8 * R * R * a2 / a4 * n(2) ) / ( R * R * R ); + } + + void Torus :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const + { + Vec<3> v1 = point - c; + double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a3 = a1 - R * R - r * r; + double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + hesse(0,0) = ( 4 * a3 + 8 * (v1(0) * v1(0) + (R * n(0)) * (R * n(0)) / a4 ) ) / ( R * R * R ); + hesse(1,1) = ( 4 * a3 + 8 * (v1(1) * v1(1) + (R * n(1)) * (R * n(1)) / a4 ) ) / ( R * R * R ); + hesse(2,2) = ( 4 * a3 + 8 * (v1(2) * v1(2) + (R * n(2)) * (R * n(2)) / a4 ) ) / ( R * R * R ); + hesse(0,1) = hesse(1,0) = 8 * (v1(0) * v1(1) + (R * n(0)) * (R * n(1)) / a4 ) / ( R * R * R ); + hesse(1,2) = hesse(2,1) = 8 * (v1(1) * v1(2) + (R * n(1)) * (R * n(2)) / a4) / ( R * R * R ); + hesse(0,2) = hesse(2,0) = 8 * (v1(0) * v1(2) + (R * n(0)) * (R * n(2)) / a4) / ( R * R * R ); + } + + double Torus :: HesseNorm () const + { + return ( 2 / r + 2 / ( R - r ) ); + } + + Point<3> Torus :: GetSurfacePoint () const + { + Vec<3> vn = n.GetNormal(); + return c + ( R + r ) * vn.Normalize(); + } + + /// void Torus :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) + /// { + /// } + + /// void Torus :: ToPlane (const Point<3> & p, + /// Point<2> & pplane, + /// double h, int & zone) const + /// { + /// } + + /// void Torus :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const + /// { + /// } + + /// void Torus :: Project (Point<3> & p) const + /// { + /// } + + INSOLID_TYPE Torus :: BoxInSolid (const BoxSphere<3> & box) const + { + Vec<3> v1 = box.Center() - c; + double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2); + double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + + double dist = sqrt( a1 + R * R - 2 * R * sqrt( a1 - a2 * a2 / a4) ); + + if (dist - box.Diam()/2 > r) return IS_OUTSIDE; + if (dist + box.Diam()/2 < r) return IS_INSIDE; + return DOES_INTERSECT; + } + + void Torus :: GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int N = int(facets) + 1; + + Vec<3> lvab = n ; + lvab.Normalize(); + + Vec<3> n1 = lvab.GetNormal(); + n1.Normalize(); + + Vec<3> n2 = Cross(lvab, n1); + n2.Normalize(); + + for (int j = 0; j <= N; j++) + for (int i = 0; i <= N; i++) + { + double lg = 2 * M_PI * double (i) / N; + double bg = 2 * M_PI * double(j) / N; + + Point<3> p = c + ( R + r * cos(lg) ) * ( cos(bg) * n1 + sin(bg) * n2 ) + r * sin(lg) * n; + tas.AddPoint (p); + } + + for (int j = 0; j < N; j++) + for (int 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)); + } + } + + void Torus :: Read (istream & ist) + { + ist >> c(0) >> c(1) >> c(2) >> n(0) >> n(1) >> n(2) >> R >> r; + } + + void Torus :: Print (ostream & ost) const + { + ost << c(0) << " " << c(1) << " " << c(2) << " " + << n(0) << " " << n(1) << " " << n(2) << " " + << R << " " << r << endl; + } + + /// end... + + + + + + + + + + + + + + + + +} diff --git a/libsrc/csg/algprim.hpp b/libsrc/csg/algprim.hpp new file mode 100644 index 00000000..6a669b68 --- /dev/null +++ b/libsrc/csg/algprim.hpp @@ -0,0 +1,439 @@ +#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; + + double eps_base; + +public: + /// + Plane (const Point<3> & ap, Vec<3> an); + + virtual void GetPrimitiveData (const char *& classname, + ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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 (const char *& classname, + ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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); + Cylinder (ARRAY & coeffs); + + virtual void GetPrimitiveData (const char *& classname, ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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 (const char *& classname, ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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; + + + virtual double MaxCurvature () const; + + virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + double /* rad */) 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 double MaxCurvature () 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 (const char *& classname, ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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(); +}; + + + + + + + + +/// Torus +/// Lorenzo Codecasa (codecasa@elet.polimi.it) +/// April 27th, 2005 +/// +/// begin... +class Torus : public OneSurfacePrimitive +{ + /// center of the torus + Point<3> c; + /// vector normal to the symmetry plane of the torus + Vec<3> n; + /// Large radius of the torus + double R; + /// Small radius of the torus + double r; + +public: + /// OK + Torus (const Point<3> & ac, const Vec<3> & an, double aR, double ar); + /// OK + const Point<3> & Center () const { return c; } + /// OK + const Vec<3> & NormalToPlane () const { return n; } + /// OK + double LargeRadius () const { return R; } + /// OK + double SmallRadius () const { return r; } + /// OK + virtual double CalcFunctionValue (const Point<3> & point) const; + /// OK + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + /// OK + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + /// OK + virtual double HesseNorm () const; + /// OK + virtual Point<3> GetSurfacePoint () const; + /// OK + virtual void GetPrimitiveData (const char *& classname, + ARRAY & coeffs) const; + /// OK + virtual void SetPrimitiveData (ARRAY & coeffs); + /// OK + static Primitive * CreateDefault (); + /// OK + virtual Primitive * Copy () const; + /// OK + virtual void Transform (Transformation<3> & trans); + /// OK + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + /// OK + /// virtual void DefineTangentialPlane (const Point<3> & ap1, + // const Point<3> & ap2); + /// OK + /// virtual void ToPlane (const Point<3> & p3d, + /// Point<2> & pplane, + /// double h, int & zone) const; + /// OK + /// virtual void FromPlane (const Point<2> & pplane, + // Point<3> & p, double h) const; + /// OK + /// virtual void Project (Point<3> & p) const; + /// OK + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// OK + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + /// OK + virtual void Print (ostream & ist) const; + /// OK + virtual void Read (istream & ist); +}; + +/// ...end + + + + + + + + +#endif diff --git a/libsrc/csg/brick.cpp b/libsrc/csg/brick.cpp new file mode 100644 index 00000000..014538ac --- /dev/null +++ b/libsrc/csg/brick.cpp @@ -0,0 +1,526 @@ +#include + +#include +#include + +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)); +} + + + +Primitive * Brick :: Copy () const +{ + return new Brick (p1, p2, p3, p4); +} + +void Brick :: Transform (Transformation<3> & trans) +{ + trans.Transform (p1); + trans.Transform (p2); + trans.Transform (p3); + trans.Transform (p4); + + CalcData(); +} + + + + + + + + + +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; + + Point<3> p[8]; + for (int j = 0; j < 8; j++) + p[j] = box.GetPointNr(j); + + 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]->Plane::CalcFunctionValue (p[j]); + + 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] -> Plane::CalcFunctionValue (p); + for (int i = 1; i < 6; i++) + { + double val = faces[i] -> Plane::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 result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid(p, v, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; + + /* + 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); + */ +} + + + + + +INSOLID_TYPE Brick :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid2(p, v1, v2, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; +} + +INSOLID_TYPE Brick :: VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid3(p, v1, v2, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; +} + +INSOLID_TYPE Brick :: VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid4(p, v, v2, m, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; +} + + + + + + + + + + + + + + + + + + + +void Brick :: +GetPrimitiveData (const char *& classname, ARRAY & 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 & 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 data(6); + for (i = 0; i < 6; i++) + { + const Point<3> lp1 = pi[lface[i][0]-1]; + const Point<3> lp2 = pi[lface[i][1]-1]; + const Point<3> lp3 = pi[lface[i][2]-1]; + + Vec<3> n = Cross ((lp2-lp1), (lp3-lp1)); + n.Normalize(); + + for (j = 0; j < 3; j++) + { + data[j] = lp1(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; + Point<3> p[8]; + for(int j=0;j<8;j++) + p[j]=box.GetPointNr(j); + + 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]->Plane::CalcFunctionValue (p[j]); + if (val > 0) hasout = 1; + else if (val < 0) hasin = 1; + if (hasout && hasin) break; + } + 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/libsrc/csg/brick.hpp b/libsrc/csg/brick.hpp new file mode 100644 index 00000000..a5238075 --- /dev/null +++ b/libsrc/csg/brick.hpp @@ -0,0 +1,120 @@ +#ifndef FILE_BRICK +#define FILE_BRICK + + +/**************************************************************************/ +/* File: brick.hpp */ +/* 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 faces; + ARRAY faces; + +public: + Brick (Point<3> ap1, Point<3> ap2, Point<3> ap3, Point<3> ap4); + virtual ~Brick (); + static Primitive * CreateDefault (); + + virtual Primitive * Copy () const; + virtual void Transform (Transformation<3> & trans); + + + 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 INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + 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 (const char *& classname, ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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/libsrc/csg/bspline2d.cpp b/libsrc/csg/bspline2d.cpp new file mode 100644 index 00000000..93b5e896 --- /dev/null +++ b/libsrc/csg/bspline2d.cpp @@ -0,0 +1,242 @@ +#include + +#include + +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/libsrc/csg/csg.hpp b/libsrc/csg/csg.hpp new file mode 100644 index 00000000..792219d1 --- /dev/null +++ b/libsrc/csg/csg.hpp @@ -0,0 +1,51 @@ +#ifndef FILE_CSG +#define FILE_CSG + +/* *************************************************************************/ +/* File: geoml.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 21. Jun. 98 */ +/* *************************************************************************/ + +#include +#include +#include + +#include + +namespace netgen +{ +#include "surface.hpp" +#include "solid.hpp" +#include "identify.hpp" +#include "singularref.hpp" +#include "csgeom.hpp" +#include "csgparser.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/libsrc/csg/csgeom.cpp b/libsrc/csg/csgeom.cpp new file mode 100644 index 00000000..ec0ca6e9 --- /dev/null +++ b/libsrc/csg/csgeom.cpp @@ -0,0 +1,1422 @@ +#include +#include + +#include +#include + + +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); + + bcname = "default"; + } + + 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(""), ideps(1e-9) + { + ; + } + + CSGeometry :: CSGeometry (const string & afilename) + : boundingbox (default_boundingbox), + identicsurfaces (100), filename(afilename), ideps(1e-9) + { + changeval++; + } + + CSGeometry :: ~CSGeometry () + { + Clean(); + } + + + void CSGeometry :: Clean () + { + ARRAY< Solid* > to_delete; + + for (int i = 0; i < solids.Size(); i++) + if(!to_delete.Contains(solids[i]->S1())) + to_delete.Append(solids[i]->S1()); + for (int i = 0; i < solids.Size(); i++) + if(!to_delete.Contains(solids[i])) + to_delete.Append(solids[i]); + for(int i = 0; i < to_delete.Size(); i++) + delete to_delete[i]; + + /* + 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 < splinecurves2d.Size(); i++) + delete splinecurves2d[i]; + splinecurves2d.DeleteAll(); + + /* + for (int i = 0; i < surfaces.Size(); i++) + delete surfaces[i]; + surfaces.DeleteAll (); + */ + for(int i = 0; iGetPrimitive(); + if (prim) + { + const char * classname; + ARRAY 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 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 :: SaveSurfaces (ostream & out) + { + if(singfaces.Size() > 0 || singedges.Size() > 0 || singpoints.Size() > 0) + { + PrintMessage(3,"Singular faces/edges/points => no csg-information in .vol file"); + return; + } + + + + ARRAY coeffs; + const char * classname; + + out << "csgsurfaces " << GetNSurf() << "\n"; + for(int i=0; i (GetSurface(i)); + const ExtrusionFace * ef = dynamic_cast< const ExtrusionFace * > (GetSurface(i)); + const RevolutionFace * rf = dynamic_cast< const RevolutionFace * > (GetSurface(i)); + + + if(sp) + { + sp->GetPrimitiveData(classname,coeffs); + + out << classname << " "; + } + else if(ef) + { + out << "extrusionface "; + ef->GetRawData(coeffs); + } + else if(rf) + { + out << "revolutionface "; + rf->GetRawData(coeffs); + } + else + throw NgException ("Cannot write csg surface. Please, contact developers!"); + + + out << coeffs.Size() << "\n"; + for(int j=0; j coeffs; + string classname; + int nsurfaces,size; + + in >> classname; + + if(classname == "csgsurfaces") + in >> nsurfaces; + else + nsurfaces = atoi(classname.c_str()); + + Point<3> dummypoint(0,0,0); + Vec<3> dummyvec(0,0,0); + double dummydouble(0.1); + + for(int i=0; i> classname; + in >> size; + + coeffs.SetSize(size); + + for(int j=0; j> coeffs[j]; + + if(classname == "plane") + { + Plane * plane = new Plane(dummypoint,dummyvec); + plane->SetPrimitiveData(coeffs); + + AddSurface(plane); + delete_them.Append(plane); + } + + else if(classname == "sphere") + { + Sphere * sphere = new Sphere(dummypoint,dummydouble); + sphere->SetPrimitiveData(coeffs); + + AddSurface(sphere); + delete_them.Append(sphere); + } + + else if(classname == "cylinder") + { + Cylinder * cylinder = new Cylinder(coeffs); + + AddSurface(cylinder); + delete_them.Append(cylinder); + } + + else if(classname == "cone") + { + Cone * cone = new Cone(dummypoint,dummypoint,dummydouble,dummydouble); + cone->SetPrimitiveData(coeffs); + + AddSurface(cone); + delete_them.Append(cone); + } + + else if(classname == "extrusionface") + { + ExtrusionFace * ef = + new ExtrusionFace(coeffs); + + AddSurface(ef); + delete_them.Append(ef); + } + + else if(classname == "revolutionface") + { + RevolutionFace * rf = + new RevolutionFace(coeffs); + + AddSurface(rf); + delete_them.Append(rf); + } + } + } + + + + + + + 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) + { + (*testout) << "Adding surface " << name << endl; + 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); + surf2prim.Append (prim); + } + } + + 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; + } + + + + + void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<2> * spl) + { + splinecurves2d.Set(name,spl); + } + void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<3> * spl) + { + splinecurves3d.Set(name,spl); + } + + + const SplineGeometry<2> * CSGeometry :: GetSplineCurve2d (const string & name) const + { + if (splinecurves2d.Used(name.c_str())) + return splinecurves2d.Get(name.c_str()); + else + return NULL; + } + const SplineGeometry<3> * CSGeometry :: GetSplineCurve3d (const string & name) const + { + if (splinecurves3d.Used(name.c_str())) + return splinecurves3d.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 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.StringFlagDefined ("bcname") ) + { + solid->GetSurfaceIndices (surfind); + string bcn = flags.GetStringFlag("bcname", "default"); + for (i = 0; i < surfind.Size(); i++) + { + if(surfaces[surfind[i]]->GetBCName() == "default") + surfaces[surfind[i]]->SetBCName(bcn); + } + } + + if (flags.StringListFlagDefined ("bcname")) + { + const ARRAY & bcname = flags.GetStringListFlag("bcname"); + + Polyhedra * polyh; + if(solid->S1()) + polyh = dynamic_cast(solid->S1()->GetPrimitive()); + else + polyh = dynamic_cast(solid->GetPrimitive()); + + if(polyh) + { + ARRAY < ARRAY * > polysurfs; + polyh->GetPolySurfs(polysurfs); + if(bcname.Size() != polysurfs.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size() + << " surfaces and should get " << bcname.Size() << " bc-names!" << endl; + + for ( i = 0; i < min2(polysurfs.Size(),bcname.Size()); i++) + { + for (int j = 0; j < polysurfs[i]->Size(); j++) + { + if(surfaces[(*polysurfs[i])[j]]->GetBCName() == "default") + surfaces[(*polysurfs[i])[j]]->SetBCName(bcname[i]); + } + delete polysurfs[i]; + } + } + else + { + solid->GetSurfaceIndices (surfind); + if(bcname.Size() != surfind.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size() + << " surfaces and should get " << bcname.Size() << " bc-names!" << endl; + + for (i = 0; i < min2(surfind.Size(),bcname.Size()); i++) + { + if(surfaces[surfind[i]]->GetBCName() == "default") + surfaces[surfind[i]]->SetBCName(bcname[i]); + } + } + } + + 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); + } + } + + if (flags.NumListFlagDefined ("bc")) + { + const ARRAY & bcnum = flags.GetNumListFlag("bc"); + + Polyhedra * polyh; + if(solid->S1()) + polyh = dynamic_cast(solid->S1()->GetPrimitive()); + else + polyh = dynamic_cast(solid->GetPrimitive()); + + if(polyh) + { + ARRAY < ARRAY * > polysurfs; + polyh->GetPolySurfs(polysurfs); + if(bcnum.Size() != polysurfs.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size() + << " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl; + + for ( i = 0; i < min2(polysurfs.Size(),bcnum.Size()); i++) + { + for (int j = 0; j < polysurfs[i]->Size(); j++) + { + if ( surfaces[(*polysurfs[i])[j]]->GetBCProperty() == -1 ) + surfaces[(*polysurfs[i])[j]]->SetBCProperty(int(bcnum[i])); + } + delete polysurfs[i]; + } + } + else + { + solid->GetSurfaceIndices (surfind); + if(bcnum.Size() != surfind.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size() + << " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl; + + for (i = 0; i < min2(surfind.Size(),bcnum.Size()); i++) + { + if (surfaces[surfind[i]]->GetBCProperty() == -1) + surfaces[surfind[i]]->SetBCProperty(int(bcnum[i])); + } + } + } + + } + + void CSGeometry :: FindIdenticSurfaces (double eps) + { + int inv; + int nsurf = GetNSurf(); + + isidenticto.SetSize(nsurf); + for (int i = 0; i < nsurf; i++) + isidenticto[i] = i; + + //(*testout) << "jetzt!" << endl; + for (int i = 0; i < nsurf; i++) + for (int j = i+1; j < nsurf; j++) + { + //(*testout) << "surf" << i << " surf" << j << endl; + 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 :: + GetSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + ARRAY & locsurf) const + { + ReducePrimitiveIterator rpi(box); + UnReducePrimitiveIterator urpi; + + ((Solid*)sol) -> IterateSolid (rpi); + sol -> GetSurfaceIndices (locsurf); + ((Solid*)sol) -> IterateSolid (urpi); + + 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); + } + } + + + + + void CSGeometry :: + GetIndependentSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + ARRAY & 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 & locsurf) const + { + cout << "very dangerous" << endl; + Point<3> p2 = p + 1e-2 * v; + BoxSphere<3> box (p2, p2); + box.Increase (1e-3); + box.CalcDiamCenter(); + GetIndependentSurfaceIndices (sol, box, locsurf); + } + + + void CSGeometry :: + GetIndependentSurfaceIndices (ARRAY & locsurf) const + { + 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); + } + } + + + + + + + + + + void CSGeometry :: + CalcTriangleApproximation(const Box<3> & aboundingbox, + 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 surfind; + IndexSet iset(GetNSurf()); + + 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, aboundingbox, 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); + //(*testout) << "point " << tas.GetPoint(k) << " normal " << n << endl; + //cout << "added point, normal=" << n << endl; + } + + + 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, iset); + 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, + IndexSet & iset) + { + + //tams.AddTriangle (tria); + //(*testout) << "tria " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2]) + // << " ( " << tria[0] << " " << tria[1] << " " << tria[2] << ")" < surfused(GetNSurf()); + + ReducePrimitiveIterator rpi(box); + UnReducePrimitiveIterator urpi; + + locsol -> IterateSolid (rpi); + // locsol -> GetSurfaceIndices (lsurfi); + + + // IndexSet iset(GetNSurf()); + locsol -> GetSurfaceIndices (iset); + const ARRAY & 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); + //(*testout) << "pos1 " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2]) << endl; + 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); + + // + /* + static int nos=0; + if(!onsurface[j]) + { + nos++; + cout << "NOT ON SURFACE!! "<< nos << endl; + } + */ + } + + 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; + + double l2(100),l1(100); + if ( fabs (f1-f2) > 1e-20 ) + { + l2 = -f1/(f2-f1); + 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; + +// if(fabs(pn(0)) > 4 || fabs(pn(1)) > 4 || fabs(pn(2)) > 4) +// { +// cout << "p1 " << p1 << " p2 " << p2 +// << " f1 " << f1 << " f2 " << f2 +// << " l1 " << l1 << " l2 " << l2 +// << " pn " << pn << endl; + +// } + + + //GetSurface (surfind)->Project (pn); + + 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]); + //(*testout) << "pos2 " << tams.GetPoint(ntria[0]) << " - " << tams.GetPoint(ntria[1]) << " - " << tams.GetPoint(ntria[2]) << endl + // << "( " << ntria[0] << " - " << ntria[1] << " - " << ntria[2] << ")" << endl; + 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) + { + //cout << "returning" << endl; + 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, iset); + + delete nsol; + } + } + } + + + + + class ClearVisitedIt : public SolidIterator + { + public: + ClearVisitedIt () { ; } + virtual ~ClearVisitedIt () { ; } + + virtual void Do (Solid * sol) + { + sol -> visited = 0; + } + }; + + + void CSGeometry :: + IterateAllSolids (SolidIterator & it, bool 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/libsrc/csg/csgeom.hpp b/libsrc/csg/csgeom.hpp new file mode 100644 index 00000000..a71c9c03 --- /dev/null +++ b/libsrc/csg/csgeom.hpp @@ -0,0 +1,309 @@ +#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 + string bcname; + +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; } + + void SetBCName (string abc) { bcname = abc; } + const string GetBCName () const { return bcname; } +}; + + +/** + CSGeometry has the whole geometric information + */ +class CSGeometry +{ +private: + /// all surfaces + SYMBOLTABLE surfaces; + +public: + /// primitive of surface + ARRAY surf2prim; + +private: + ARRAY delete_them; + + /// all named solids + SYMBOLTABLE solids; + + /// all 2d splinecurves + SYMBOLTABLE< SplineGeometry<2>* > splinecurves2d; + /// all 3d splinecurves + SYMBOLTABLE< SplineGeometry<3>* > splinecurves3d; + + /// all top level objects: solids and surfaces + ARRAY toplevelobjects; + + /// additional points specified by user + ARRAY > userpoints; + ARRAY userpoints_ref_factor; + + mutable ARRAY > identpoints; + + /// triangular approximation of top level objects + ARRAY 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 identicsurfaces; + ARRAY isidenticto; + /// identification of boundaries (periodic, thin domains, ...) + + double ideps; + + + /// filename of inputfile + string filename; + + +public: + CSGeometry (); + CSGeometry (const string & afilename); + ~CSGeometry (); + + void Clean (); + + void Save (ostream & ost); + void Load (istream & ist); + + void SaveSurfaces (ostream & out); + void LoadSurfaces (istream & in); + + 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) const { return solids[i]; } + const SYMBOLTABLE & GetSolids () const { return solids; } + + + void SetSplineCurve (const char * name, SplineGeometry<2> * spl); + void SetSplineCurve (const char * name, SplineGeometry<3> * spl); + const SplineGeometry<2> * GetSplineCurve2d (const string & name) const; + const SplineGeometry<3> * GetSplineCurve3d (const string & name) const; + + + 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, double ref_factor = 0) + { userpoints.Append (p); userpoints_ref_factor.Append (ref_factor); } + int GetNUserPoints () const + { return userpoints.Size(); } + const Point<3> & GetUserPoint (int nr) const + { return userpoints[nr]; } + double GetUserPointRefFactor (int nr) const + { return userpoints_ref_factor[nr]; } + + void AddIdentPoint (const Point<3> & p) const + { identpoints.Append(p);} + int GetNIdentPoints (void) const + { return identpoints.Size();} + const Point<3> & GetIdentPoint(int nr) const + { return identpoints[nr]; } + void DeleteIdentPoints(void) const + { identpoints.DeleteAll();} + + + // quick implementations: + ARRAY singfaces; + ARRAY singedges; + ARRAY singpoints; + ARRAY identifications; + + int GetNIdentifications (void) const { return identifications.Size(); } + void AddIdentification (Identification * ident); + + + /// + void CalcTriangleApproximation(const Box<3> & boundingbox, + double detail, double facets); + + /// + void FindIdenticSurfaces (double eps); + /// + void GetSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + ARRAY & locsurf) const; + /// + void GetIndependentSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + ARRAY & locsurf) const; + /// + void GetIndependentSurfaceIndices (const Solid * sol, + const Point<3> & p, Vec<3> & v, + ARRAY & locsurf) const; + /// + void GetIndependentSurfaceIndices (ARRAY & 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, bool only_once = false); + + void RefineTriangleApprox (Solid * locsol, + int surfind, + const BoxSphere<3> & box, + double detail, + const TATriangle & tria, + TriangleApproximation & tams, + IndexSet & iset); + + 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; + + void SetIdEps(double eps){ideps = eps;} + double GetIdEps(void) const {return ideps;} + + class BCModification { + public: + int si; + int tlonr; + int bcnr; + string * bcname; + }; + + ARRAY bcmodifications; + +}; +#endif + diff --git a/libsrc/csg/csgparser.cpp b/libsrc/csg/csgparser.cpp new file mode 100644 index 00000000..c9e4a928 --- /dev/null +++ b/libsrc/csg/csgparser.cpp @@ -0,0 +1,1332 @@ +#include +#include + +#include +#include + + +namespace netgen +{ + //using namespace netgen; + + + static kwstruct defkw[] = + { + { TOK_RECO, "algebraic3d" }, + { TOK_SOLID, "solid" }, + { TOK_TLO, "tlo" }, + { TOK_CURVE2D, "curve2d" }, + { TOK_CURVE3D, "curve3d" }, + { 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" }, + { TOK_BOUNDARYCONDITIONNAME, "boundaryconditionname" }, + { TOK_DEFINE, "define" }, + { TOK_CONSTANT, "constant" }, + { TOKEN_TYPE(0), 0 } + }; + + 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_TORUS, "torus" }, + + { 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), 0 } + }; + + static CSGeometry * geom; + + + 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; + } + if (ch == '\n') + linenum++; + + + // 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 + int inputface = 0; + while (1) + { + ARRAY pnums,cleaned_pnums; + for(int i=0; i<3; i++) + { + pnums.Append((int) (ParseNumber (scan))); + if(i<2) + ParseChar (scan, ','); + } + + if (scan.GetToken() == TOK_COMMA) + { + ParseChar (scan, ','); + pnums.Append((int) (ParseNumber (scan))); + } + + for(int i=0; iAddFace(cleaned_pnums[0]-1, + cleaned_pnums[1]-1, + cleaned_pnums[2]-1, + inputface); + } + else if(cleaned_pnums.Size() == 4) + { + polyhedron->AddFace(cleaned_pnums[0]-1, + cleaned_pnums[1]-1, + cleaned_pnums[2]-1, + inputface); + polyhedron->AddFace(cleaned_pnums[0]-1, + cleaned_pnums[2]-1, + cleaned_pnums[3]-1, + inputface); + } + else + { + ostringstream msg; + msg << "Something wrong with polyhedron face:"; + for(int i=0; iAddSurfaces (polyhedron); + return new Solid (polyhedron); + } + + + case TOK_REVOLUTION: + { + Point<3> p0,p1; + + scan.ReadNext(); + scan >> '(' >> p0 >> ';' >> p1 >> ';'; + + string spline = scan.GetStringValue(); + + scan.ReadNext(); + scan >> ')'; + + if(!geom->GetSplineCurve2d(spline)) + { + scan.Error ( string("2D Spline curve not found: ") + spline ); + break; + } + + Primitive * nprim = new Revolution(p0,p1, + *(geom->GetSplineCurve2d(spline))); + + geom->AddSurfaces (nprim); + return new Solid(nprim); + } + + + case TOK_EXTRUSION: + { + scan.ReadNext(); + scan >> '('; + string epath = scan.GetStringValue(); + scan.ReadNext(); + scan >> ';'; + string profile = scan.GetStringValue(); + + + scan.ReadNext(); + Vec<3> z_dir; + scan >> ';' >> z_dir(0) >> ',' >> z_dir(1) >> ',' >> z_dir(2) >> ')'; + + if(!geom->GetSplineCurve2d(profile)) + { + scan.Error ( string("2D Spline curve not found: ") + profile ); + break; + } + if(!geom->GetSplineCurve3d(epath)) + { + scan.Error ( string("2D Spline curve not found: ") + epath ); + break; + } + + Primitive * nprim = new Extrusion(*(geom->GetSplineCurve3d(epath)), + *(geom->GetSplineCurve2d(profile)), + z_dir); + geom->AddSurfaces (nprim); + return new Solid(nprim); + } + + + /// Torus + /// Lorenzo Codecasa (codecasa@elet.polimi.it) + /// April 27th, 2005 + /// + /// begin... + case TOK_TORUS: + { + Point<3> pc; + Vec<3> vn; + double R, r; + + scan.ReadNext(); + scan >> '(' >> pc >> ';' >> vn >> ';' >> R >> ';' >> r >> ')'; + + OneSurfacePrimitive * surf = new Torus ( pc, vn, R, r ); + geom->AddSurfaces (surf); + return new Solid (surf); + } + /// ..end + + + + + 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_ROTATE: + { + Point<3> c; + Vec<3> v; + scan.ReadNext(); + + scan >> '(' >> c >> ';' >> v >> ';'; + + Solid * sol1 = ParseSolid (scan); + + ParseChar (scan, ')'); + + Solid * nsol = sol1 -> Copy(*geom); + Transformation<3> trans(c,v(0),v(1),v(2)); + 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 (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(); + + if(scan.GetToken() == '-' || scan.GetToken() == TOK_NUM) + { + ARRAY vals; + vals.Append (ParseNumber(scan)); + while (scan.GetToken() == ',') + { + scan.ReadNext(); + vals.Append (ParseNumber(scan)); + } + ParseChar (scan, ']'); + flags.SetFlag (name.c_str(), vals); + } + else + { // string list + ARRAY vals; + string val = scan.GetStringValue(); + vals.Append(new char[val.size()+1]); + strcpy(vals.Last(),val.c_str()); + scan.ReadNext(); + + while (scan.GetToken() == ',') + { + scan.ReadNext(); + val = scan.GetStringValue(); + vals.Append(new char[val.size()+1]); + strcpy(vals.Last(),val.c_str()); + scan.ReadNext(); + } + ParseChar (scan, ']'); + flags.SetFlag (name.c_str(), vals); + for(int i=0; iGetSolid (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 & 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 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 & 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))); + if ( flags.StringFlagDefined("bcname") ) + tlo->SetBCName ( flags.GetStringFlag ("bcname", "default") ); + } + } + + 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 si1, si2; + geom->GetSolid(name1)->GetSurfaceIndices(si1); + geom->GetSolid(name2)->GetSurfaceIndices(si2); + + const TopLevelObject * domain = 0; + if (flags.StringFlagDefined ("tlo")) + { + domain = + geom->GetTopLevelObject (geom->GetSolid(flags.GetStringFlag ("tlo",""))); + if (!domain) + scan.Error ("identification needs undefined 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 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); + int factor = int(flags.GetNumFlag("factor",1)); + // cout << "Singular Face with factor " << factor << endl; + PrintMessageCR (3, "Singular Face with factor ", factor); + + ParseChar (scan, ';'); + + const Solid * sol = geom->GetSolid(name2); + + if(!sol) + scan.Error ("unknown solid in singular face definition"); + else + for (int i = 0; i < geom->GetNTopLevelObjects(); i++) + if (name1 == geom->GetTopLevelObject (i)->GetSolid()->Name()) + geom->singfaces.Append (new SingularFace (i+1, sol,factor)); + + break; + } + + case TOK_EDGE: + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + Flags flags; + ParseFlags (scan, flags); + int factor = int(flags.GetNumFlag("factor",1)); + double maxhinit = flags.GetNumFlag("maxh",-1); + ParseChar (scan, ';'); + + const Solid * s1 = geom->GetSolid(name1); + const Solid * s2 = geom->GetSolid(name2); + PrintMessageCR (3, "Singular Edge with factor ", factor); + + int domnr = -1; + if (flags.StringFlagDefined ("tlo")) + { + const Solid * sol = + geom->GetSolid(flags.GetStringFlag ("tlo","")); + + for (int i = 0; i < geom->GetNTopLevelObjects(); i++) + if (geom->GetTopLevelObject(i)->GetSolid() == sol) + domnr = i; + + // cout << "domnr = " << domnr; + } + + if(!s1 || !s2) + scan.Error ("unknown solid ins singular edge definition"); + else + geom->singedges.Append (new SingularEdge (1, domnr, + *geom, s1, s2, factor, + maxhinit)); + 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); + int factor = int(flags.GetNumFlag("factor",1)); + ParseChar (scan, ';'); + + const Solid * s1 = geom->GetSolid(name1); + const Solid * s2 = geom->GetSolid(name2); + const Solid * s3 = geom->GetSolid(name3); + // cout << "Singular Point with factor " << factor << endl; + PrintMessageCR (3, "Singular Point with factor ", factor); + geom->singpoints.Append (new SingularPoint (1, s1, s2, s3, factor)); + 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, ')'); + + + Flags flags; + ParseFlags (scan, flags); + int factor = int(flags.GetNumFlag("factor",0)); + + ParseChar (scan, ';'); + + geom->AddUserPoint (p, factor); + } + + 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_CURVE2D) + { + scan.ReadNext(); + + + if (scan.GetToken() != TOK_STRING) + scan.Error ("name identifier expected"); + string curvename = scan.GetStringValue(); + + scan.ReadNext(); + + ParseChar (scan, '='); + ParseChar (scan, '('); + + SplineGeometry<2> * newspline = new SplineGeometry<2>; + newspline->CSGLoad(scan); + + ParseChar (scan, ')'); + ParseChar (scan, ';'); + + geom->SetSplineCurve(curvename.c_str(),newspline); + + PrintMessage (4, "define 2d curve ", curvename); + } + + else if (scan.GetToken() == TOK_CURVE3D) + { + scan.ReadNext(); + + + if (scan.GetToken() != TOK_STRING) + scan.Error ("name identifier expected"); + string curvename = scan.GetStringValue(); + + scan.ReadNext(); + + ParseChar (scan, '='); + ParseChar (scan, '('); + + SplineGeometry<3> * newspline = new SplineGeometry<3>; + newspline->CSGLoad(scan); + + ParseChar (scan, ')'); + ParseChar (scan, ';'); + + geom->SetSplineCurve(curvename.c_str(),newspline); + + PrintMessage (4, "define 3d curve ", curvename); + } + + 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; + bcm.bcname = NULL; + ARRAY si; + + geom->GetSolid(name1)->GetSurfaceIndices(si); + if(si.Size() == 0) + { + string errstring = "solid \""; errstring += name1; errstring += "\" has no surfaces"; + scan.Error (errstring); + } + + bcm.tlonr = -1; + int i; + for (i = 0; i < geom->GetNTopLevelObjects(); i++) + if (string (geom->GetTopLevelObject(i)->GetSolid()->Name()) + == name2) + { + bcm.tlonr = i; + break; + } + if(bcm.tlonr == -1) + { + string errstring = "tlo \""; errstring += name2; errstring += "\" not found"; + scan.Error(errstring); + } + + + bcm.bcnr = num; + for (i = 0; i < si.Size(); i++) + { + bcm.si = si[i]; + geom->bcmodifications.Append (bcm); + } + } + + else if (scan.GetToken() == TOK_BOUNDARYCONDITIONNAME) + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + string bcname = scan.GetStringValue(); + scan.ReadNext(); + ParseChar(scan, ';'); + + + CSGeometry::BCModification bcm; + bcm.bcname = NULL; + + + ARRAY si; + + geom->GetSolid(name1)->GetSurfaceIndices(si); + if(si.Size() == 0) + { + string errstring = "solid \""; errstring += name1; errstring += "\" has no surfaces"; + scan.Error (errstring); + } + + bcm.tlonr = -1; + int i; + for (i = 0; i < geom->GetNTopLevelObjects(); i++) + if (string (geom->GetTopLevelObject(i)->GetSolid()->Name()) + == name2) + { + bcm.tlonr = i; + break; + } + if(bcm.tlonr == -1) + { + string errstring = "tlo \""; errstring += name2; errstring += "\" not found"; + scan.Error(errstring); + } + + + bcm.bcnr = -1; + for (i = 0; i < si.Size(); i++) + { + bcm.si = si[i]; + geom->bcmodifications.Append (bcm); + geom->bcmodifications.Last().bcname = new string(bcname); + } + } + + else if (scan.GetToken() == TOK_DEFINE) + { + scan.ReadNext(); + string name; + double val; + + switch (scan.GetToken()) + { + case TOK_CONSTANT: + scan.ReadNext(); + + name = scan.GetStringValue(); + scan.ReadNext(); + + ParseChar(scan, '='); + val = ParseNumber(scan); + + if(name == "identprec") + geom->SetIdEps(val); + + + + break; + default: + scan.Error ("keyword 'constant' expected"); + } + } + + + else + { + cout << "read unidentified token " << scan.GetToken() + << " (as char: \"" << char(scan.GetToken()) << "\")" + << " string = " << scan.GetStringValue() << endl; + scan.ReadNext(); + } + } + } + catch (string errstr) + { + cout << "caught error " << errstr << endl; + throw NgException (errstr); + } + + + + (*testout) << geom->GetNTopLevelObjects() << " TLOs:" << endl; + for (int i = 0; i < geom->GetNTopLevelObjects(); i++) + { + const TopLevelObject * tlo = geom->GetTopLevelObject(i); + if (tlo->GetSolid()) + (*testout) << i << ": " << *tlo->GetSolid() << endl; + } + + (*testout) << geom->GetNSurf() << " Surfaces" << endl; + for (int i = 0; i < geom->GetNSurf(); i++) + (*testout) << i << ": " << *geom->GetSurface(i) << 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/libsrc/csg/csgparser.hpp b/libsrc/csg/csgparser.hpp new file mode 100644 index 00000000..1f8dab1d --- /dev/null +++ b/libsrc/csg/csgparser.hpp @@ -0,0 +1,107 @@ +#ifndef _CSGPARSER_HPP +#define _CSGPARSER_HPP + + + + +//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_CURVE2D, TOK_CURVE3D, TOK_BOUNDINGBOX, + TOK_BOUNDARYCONDITION, TOK_BOUNDARYCONDITIONNAME, + TOK_DEFINE, TOK_CONSTANT, + TOK_END }; + + struct kwstruct + { + TOKEN_TYPE kw; + const char * name; + }; + + enum PRIMITIVE_TYPE + { + TOK_SPHERE = 1, TOK_CYLINDER, TOK_PLANE, TOK_ELLIPTICCYLINDER, + TOK_ELLIPSOID, TOK_CONE, + TOK_ORTHOBRICK, TOK_POLYHEDRON, + TOK_TORUS, + TOK_TUBE, TOK_GENCYL, TOK_EXTRUSION, TOK_REVOLUTION, + + TOK_TRANSLATE, TOK_MULTITRANSLATE, TOK_ROTATE, TOK_MULTIROTATE + }; + + struct primstruct + { + PRIMITIVE_TYPE kw; + const char * name; + }; + + + 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 & operator>> (CSGScanner & scan, char ch); + CSGScanner & operator>> (CSGScanner & scan, double & d); + CSGScanner & operator>> (CSGScanner & scan, int & i); + CSGScanner & operator>> (CSGScanner & scan, Point<3> & p); + CSGScanner & operator>> (CSGScanner & scan, Vec<3> & v); + + + +//} + + + + + + + + + +#endif // _CSGPARSER_HPP diff --git a/libsrc/csg/curve2d.cpp b/libsrc/csg/curve2d.cpp new file mode 100644 index 00000000..7091e87a --- /dev/null +++ b/libsrc/csg/curve2d.cpp @@ -0,0 +1,78 @@ +#include + +#include +#include + +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/libsrc/csg/curve2d.hpp b/libsrc/csg/curve2d.hpp new file mode 100644 index 00000000..917bd532 --- /dev/null +++ b/libsrc/csg/curve2d.hpp @@ -0,0 +1,59 @@ +#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/libsrc/csg/edgeflw.cpp b/libsrc/csg/edgeflw.cpp new file mode 100644 index 00000000..ca802f51 --- /dev/null +++ b/libsrc/csg/edgeflw.cpp @@ -0,0 +1,1820 @@ +#include +#include +#include + +#undef DEVELOP +// #define DEVELOP + +namespace netgen +{ + + EdgeCalculation :: + EdgeCalculation (const CSGeometry & ageometry, + ARRAY & aspecpoints) + : geometry(ageometry), specpoints(aspecpoints) + { + Box<3> bbox = geometry.BoundingBox(); + + 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); + + ideps = 1e-9; + } + + EdgeCalculation :: ~EdgeCalculation() + { + delete searchtree; + delete meshpoint_tree; + } + + + void EdgeCalculation :: Calc(double h, Mesh & mesh) + { + PrintMessage (1, "Find edges"); + PushStatus ("Find edges"); + + + for (int i = 1; i <= mesh.GetNP(); i++) + meshpoint_tree->Insert (mesh.Point(i), i); + + + // add all special points before edge points (important for periodic identification) + // JS, Jan 2007 + const double di=1e-7*geometry.MaxSize(); + ARRAY locsearch; + + for (int i = 0; i < specpoints.Size(); i++) + if (specpoints[i].unconditional) + { + Point<3> p = specpoints[i].p; + meshpoint_tree -> GetIntersecting (p-Vec<3> (di,di,di), + p+Vec<3> (di,di,di), locsearch); + + if (locsearch.Size() == 0) + { + PointIndex pi = mesh.AddPoint (p, specpoints[i].GetLayer(), FIXEDPOINT); + meshpoint_tree -> Insert (p, pi); + } + } + + /* + // slow version + for (int i = 0; i < specpoints.Size(); i++) + if (specpoints[i].unconditional) + { + Point<3> p = specpoints[i].p; + bool found = false; + for (int j = 1; j <= mesh.GetNP(); j++) + if (Dist (p, mesh.Point(j)) < 1e-8) + found = true; + if (!found) + mesh.AddPoint (p, specpoints[i].GetLayer(), FIXEDPOINT); + } + */ + + + + CalcEdges1 (h, mesh); + SplitEqualOneSegEdges (mesh); + FindClosedSurfaces (h, mesh); + PrintMessage (3, cntedge, " edges found"); + + PopStatus (); + } + + + + + + void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh) + { + ARRAY hsp(specpoints.Size()); + ARRAY glob2hsp(specpoints.Size()); + ARRAY startpoints, endpoints; + + + int pos, ep; + int layer; + + Point<3> p, np; + int pi1, s1, s2, s1_orig, s2_orig; + + ARRAY > edgepoints; + ARRAY curvelength; + int copyedge = 0, copyfromedge = -1, copyedgeidentification = -1; + + ARRAY locsurfind, locind; + + 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; + } + + //for(int i=0; i identification_used(100); // identification i already used for startpoint j + + mesh.GetIdentifications().Delete(); + + TABLE specpoint2surface(specpoints.Size()); + if (geometry.identifications.Size()) + { + for (int i = 0; i < specpoints.Size(); i++) + for (int j = 0; j < geometry.GetNSurf(); j++) + if (geometry.GetSurface(j)->PointOnSurface (specpoints[i].p)) + specpoint2surface.Add (i, j); + } + + TABLE specpoint2tlo(specpoints.Size()); + if (geometry.identifications.Size()) + { + for (int i = 0; i < specpoints.Size(); i++) + for (int j = 0; j < geometry.GetNTopLevelObjects(); j++) + { + const TopLevelObject * tlo = geometry.GetTopLevelObject (j); + if (tlo->GetSolid() && tlo->GetSolid()->VectorIn (specpoints[i].p,specpoints[i].v)) + //if (tlo->GetSolid() && tlo->GetSolid()->IsIn (specpoints[i].p)) + { +#ifdef DEVELOP + (*testout) << "point " << specpoints[i].p << " v " <GetSolid()->Name() << endl; +#endif + specpoint2tlo.Add (i, j); + } + } + } + + for (int i = 0; i < specpoints.Size(); i++) + specpoints[i].nr = i; + + while (hsp.Size()) + { + SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size()); + +#ifdef DEVELOP + (*testout) << "hsp.Size() " << hsp.Size() << " specpoints.Size() " << specpoints.Size() << endl; + (*testout) << endl << "edge nr " << cntedge+1 << endl; +#endif + + edgepoints.SetSize (0); + curvelength.SetSize (0); + + + pi1 = 0; + copyedge = 0; + // identifyable point available ? + + + for (int i = 0; i < geometry.identifications.Size() && !pi1; i++) + for (int j = checkedcopy; j < startpoints.Size() && !pi1; j++) + { +#ifdef DEVELOP + (*testout) << "checking point " << specpoints[startpoints[j]].p + << ", v = " << specpoints[startpoints[j]].v + << " for copying (i,j = " << i << ", " << j << ")" << endl; +#endif + if (geometry.identifications[i]->IdentifyableCandidate (specpoints[startpoints[j]]) && + geometry.identifications[i]->IdentifyableCandidate (specpoints[endpoints[j]])) + + + { + int pi1cand = 0; + double mindist = 1e10; + + for (int k = 0; k < hsp.Size() && !pi1; k++) + { + //(*testout) << " ? identifyable with " << specpoints[hsp[k]].p + //<< ", v = " << specpoints[hsp[k]].v + // << endl; + if (identification_used.Used (INDEX_2(i, startpoints[j])) || + identification_used.Used (INDEX_2(i, hsp[k]))) + { + //(*testout) << "failed at pos0" << endl; + continue; + } + + if (geometry.identifications[i] + ->Identifyable(specpoints[startpoints[j]], specpoints[hsp[k]], specpoint2tlo, specpoint2surface) || + geometry.identifications[i] + ->Identifyable(specpoints[hsp[k]], specpoints[startpoints[j]], specpoint2tlo, specpoint2surface)) + { +#ifdef DEVELOP + (*testout) << "identifyable: " << specpoints[hsp[k]].p << ", v = " << specpoints[hsp[k]].v + << " and " << specpoints[startpoints[j]].p << ", v = " << specpoints[startpoints[j]].v + << " (identification " << i+1 << ")" << endl; +#endif + + 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) + { + // no unconditional points available, choose first conitional + 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*geometry.MaxSize() && + (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) << "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; + s1_orig = specpoints[hsp.Get(pi1)].s1_orig; + s2_orig = specpoints[hsp.Get(pi1)].s2_orig; + + + // 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)); + double 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 refedges; + ARRAY refedgesinv; + + + AnalyzeEdge (s1_orig, s2_orig, 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; + if (refedgesinv.Size()) + (*testout) << "inv[1] = " << refedgesinv.Get(1) << endl; +#endif + + if (refedges.Size() == 0) + throw NgException ("Problem in edge detection"); + + + if (!copyedge) + { + // (*testout) << "store edge" << endl; + // int oldnseg = mesh.GetNSeg(); + + if (!shortedge) + StoreEdge (refedges, refedgesinv, + edgepoints, curvelength, layer, mesh); + else + StoreShortEdge (refedges, refedgesinv, + edgepoints, curvelength, layer, mesh); + + for(int i = 0; i < refedges.Size(); i++) + { + refedges[i].surfnr1 = geometry.GetSurfaceClassRepresentant(refedges[i].surfnr1); + refedges[i].surfnr2 = geometry.GetSurfaceClassRepresentant(refedges[i].surfnr2); + } + + + /* + 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); + } + + +// for(int i=0; i osedges(cntedge); + INDEX_2_HASHTABLE 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)--; + } + + // flag one segment edges + for (int i = 0; i < cntedge; i++) + osedges[i] = (osedges[i] > 0) ? 1 : 0; + + 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; + + (*testout) << "Point on edge" << endl + << "seg = " << i2 << ", p = " << pi << endl + << "pos = " << p << ", projected = " << hp << endl + << "seg is = " << mesh.Point(i2.I1()) << " - " << mesh.Point(i2.I2()) << endl; + } + } + } + } + + + // 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(), EDGEPOINT); + 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 & hsp, + double h, const Mesh & mesh, + ARRAY > & edgepoints, + ARRAY & curvelength) + { + int s1, s2, s1_rep, s2_rep; + double len, steplen, cursteplen, loch; + Point<3> p, np, pnp; + Vec<3> a1, a2, t; + + ARRAY locind; + + double size = geometry.MaxSize(); + double epspointdist2 = size * 1e-6; + epspointdist2 = sqr (epspointdist2); + int uselocalh = mparam.uselocalh; + + + s1_rep = specpoints[hsp.Get(pi1)].s1; + s2_rep = specpoints[hsp.Get(pi1)].s2; + s1 = specpoints[hsp.Get(pi1)].s1_orig; + s2 = specpoints[hsp.Get(pi1)].s2_orig; + + p = specpoints[hsp.Get(pi1)].p; + //ProjectToEdge (geometry.GetSurface(s1), + // geometry.GetSurface(s2), 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; + + // (*testout) << "geometry.GetSurface(s1) -> LocH (p, 3, 1, h) " << geometry.GetSurface(s1) -> LocH (p, 3, 1, h) + // << " geometry.GetSurface(s2) -> LocH (p, 3, 1, h) " << geometry.GetSurface(s2) -> LocH (p, 3, 1, h) << endl; + + 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); + // (*testout) << "lh " << lh << endl; + 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*size) + { + 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_rep) -> LocH (np, 3, 1, h), + geometry.GetSurface(s2_rep) -> LocH (np, 3, 1, h)); + loch = max2 (loch, mparam.minh); + + 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 s1_rep, int s2_rep, int pos, int layer, + const ARRAY > & edgepoints, + ARRAY & refedges, + ARRAY & refedgesinv) + { + int j, k, l; + int hi; + Point<3> hp; + Vec<3> t, a1, a2, m, n; + Segment seg; + Solid * locsol; + ARRAY locsurfind, locsurfind2; + + ARRAY edges_priority; + + double size = geometry.MaxSize(); + bool debug = 0; + +#ifdef DEVELOP + debug = 1; +#endif + + if (debug) + { + (*testout) << "debug edge !!!" << endl; + (*testout) << "edgepoints = " << edgepoints << endl; + (*testout) << "s1, s2 = " << s1_rep << " - " << s2_rep << endl; + } + + refedges.SetSize(0); + refedgesinv.SetSize(0); + hp = Center (edgepoints[0], edgepoints[1]); + ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp); + + if (debug) + *testout << "hp = " << hp << endl; + + geometry.GetSurface(s1) -> CalcGradient (hp, a1); + geometry.GetSurface(s2) -> CalcGradient (hp, a2); + t = Cross (a1, a2); + t.Normalize(); + if (!pos) t *= -1; + + + for (int 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, locsurfind, size*ideps); + + //*testout << "hp = " << hp << endl; + //(*testout) << "locsol: " << endl; + //if (locsol) locsol->Print(*testout); + //(*testout) << endl; + + + if (!locsol) continue; + + BoxSphere<3> boxp (hp, hp); + boxp.Increase (1e-8*size); + boxp.CalcDiamCenter(); + + ReducePrimitiveIterator rpi(boxp); + UnReducePrimitiveIterator urpi; + + ((Solid*)locsol) -> IterateSolid (rpi); + + locsol -> CalcSurfaceInverse (); + + if (!surf) + { + locsol -> GetTangentialSurfaceIndices (hp,locsurfind,ideps*size); + } + 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) ) > ideps*size) + 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 (debug) + *testout << "n1 = " << n << endl; + if (geometry.GetSurface (lsi)->Inverse()) + n *= -1; + + if (fabs (t * n) > 1e-4) continue; + if (debug) + { + (*testout) << "face " << locsurfind[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); + if (debug) + { + (*testout) << "rn = " << rn << endl; + } + + //if( n*rn < 0) + // rn *= -1; + + bool sameasref = ((n * rn) > 0); + + //m = Cross (t, rn); + m = Cross (t, n); if(!sameasref) m*=-1.; + + m.Normalize(); + + + if (debug) + (*testout) << "m = " << m << endl; + + + //bool founddirection = false; + //int k; + double eps = 1e-8*size; + + ARRAY pre_ok(2); + + do + { + eps *= 0.5; + pre_ok[0] = (locsol -> VectorIn2 (hp, m, n, eps) == IS_OUTSIDE && + locsol -> VectorIn2 (hp, m, -1. * n, eps) == IS_INSIDE); + pre_ok[1] = (locsol -> VectorIn2 (hp, -1.*m, n, eps) == IS_OUTSIDE && + locsol -> VectorIn2 (hp, -1.*m, -1. * n, eps) == IS_INSIDE); + } + while(pre_ok[0] && pre_ok[1] && eps > 1e-16*size); + + if (debug) + { + *testout << "eps = " << eps << ", size = " << size << endl; + *testout << "pre_ok[0,1] = " << pre_ok[0] << "," << pre_ok[1] << endl; + } + + eps = 1e-8*size; + + + for (k = 1; k <= 2; k ++) + { + bool edgeinv = (k == 2); + + if (debug) + { + (*testout) << "onface(" << hp << ", " << m << ")= " << flush; + (*testout) << locsol->OnFace (hp, m, eps) << flush; + (*testout) << " n " << n << flush; + (*testout) << " vec2in = " + << locsol -> VectorIn2 (hp, m, n, eps) << " and " + << locsol -> VectorIn2 (hp, m, -1 * n, eps) << endl; + } + + // if (locsol -> OnFace (hp, m)) + + + // one side must be inside, the other must be outside + bool ok = (pre_ok[k-1] || + (locsol -> VectorIn2 (hp, m, n, eps) == IS_OUTSIDE && + locsol -> VectorIn2 (hp, m, -1 * n, eps) == IS_INSIDE)); + + if (debug) + (*testout) << "ok (before) " << ok << endl; + + // compute second order approximation + // curve = hp + t m + t*t/2 m2 + Vec<3> grad, m2; + Mat<3> hesse; + geometry.GetSurface(lsi) -> CalcGradient (hp, grad); + geometry.GetSurface(lsi) -> CalcHesse (hp, hesse); + double fac = -(m * (hesse * m)) / (grad * grad); + m2 = fac * grad; + // (*testout) << "hp = " << hp << ", m = " << m << ", m2 = " << m2 << endl; + + Solid * locsol2; + locsol -> TangentialSolid3 (hp, m, m2, locsol2, locsurfind2, ideps*size); + if (!locsol2) ok = 0; + delete locsol2; + + + if (ok) + { + if (debug) + (*testout) << "is true" << endl; + hi = 0; + for (l = 1; !hi && l <= refedges.Size(); l++) + { + if (refedges.Get(l).si == rlsi && // JS sept 2006 + // if (refedges.Get(l).si == lsi && + refedgesinv.Get(l) == edgeinv) + { + hi = l; + } + } + + if (!hi) + { + seg.si = rlsi; // JS Sept 2006 + // seg.si = lsi; + seg.domin = -1; + seg.domout = -1; + seg.tlosurf = -1; + //seg.surfnr1 = s1_rep; + //seg.surfnr2 = s2_rep; + seg.surfnr1 = s1; + seg.surfnr2 = s2; + hi = refedges.Append (seg); + refedgesinv.Append (edgeinv); + edges_priority.Append((pre_ok[k-1]) ? 1 : 0); + } + else + { + if(edges_priority[hi-1] / 10 == -i-1) + edges_priority[hi-1] = 10*(i+1); + else + edges_priority[hi-1] = -10*(i+1); + } + + if (!surf) + { + if (sameasref) + refedges.Elem(hi).domin = i; + else + refedges.Elem(hi).domout = i; + } + else + refedges.Elem(hi).tlosurf = i; + + if(pre_ok[k-1]) + edges_priority[hi-1] = 1; + + + 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 + << ", priority = " << edges_priority[hi-1] + << ", hi = " << hi + << endl; + } + else + { + if (debug) + (*testout) << "is false" << endl; + } + m *= -1; + } + } + delete locsol; + } + + + if (debug) + { + *testout << "Refsegments, before delete: " << endl << refedges << endl; + *testout << "inv: " << endl << refedgesinv << endl; + } + + BitArray todelete(refedges.Size()); + todelete.Clear(); + + + for(int i=0; i edges_priority[j]) + { + todelete.Set(j); + } + } + } + + } + + int num = refedges.Size(); + + for(int i=refedges.Size()-1; num>2 && i>=0; i--) + if(todelete.Test(i)) + { + refedges.Delete(i); + refedgesinv.Delete(i); + num--; + } + + + if (debug) + { + *testout << "Refsegments: " << endl << refedges << endl; + } + } + + + + void EdgeCalculation :: + StoreEdge (const ARRAY & refedges, + const ARRAY & refedgesinv, + const ARRAY > & edgepoints, + const ARRAY & 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); + + (*testout) << "s1 " << refedges.Get(1).surfnr1 << " s2 " << refedges.Get(1).surfnr2 + << " rs1 " << geometry.GetSurfaceClassRepresentant(refedges.Get(1).surfnr1) + << " rs2 " << geometry.GetSurfaceClassRepresentant(refedges.Get(1).surfnr2) << endl; + + len = curvelength.Last(); + ne = int (len + 0.5); + if (ne == 0) ne = 1; + if (Dist (edgepoints.Get(1), edgepoints.Last()) < 1e-8*geometry.MaxSize() && + 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; + } + */ + + const double di=1e-7*geometry.MaxSize(); + + ARRAY locsearch; + meshpoint_tree -> GetIntersecting (p-Vec<3> (di,di,di), + p+Vec<3> (di,di,di), locsearch); + if (locsearch.Size()) + lastpi = locsearch[0]; + + + + if (lastpi == -1) + { + lastpi = mesh.AddPoint (p, layer, FIXEDPOINT); + meshpoint_tree -> Insert (p, lastpi); + // (*testout) << "test1, store point " << lastpi << ", p = " << p << endl; + } + + 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> (di,di,di), + np+Vec<3> (di,di,di), locsearch); + if (locsearch.Size()) + thispi = locsearch[0]; + } + + if (thispi == -1) + { + ProjectToEdge (surf1, surf2, np); + thispi = mesh.AddPoint (np, layer, (i==ne) ? FIXEDPOINT : EDGEPOINT); + + meshpoint_tree -> Insert (np, thispi); + // (*testout) << "test2, store point " << thispi << ", p = " << np << endl; + } + + 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 " << mesh[seg.p1] << "-" << mesh[seg.p2] << endl; + //(*testout) << "refedge " << k << " surf1 " << seg.surfnr1 << " surf2 " << seg.surfnr2 << " inv " << refedgesinv.Get(k) << 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 & refedges, + const ARRAY & refedgesinv, + const ARRAY > & edgepoints, + const ARRAY & 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*geometry.MaxSize()) + { + pi1 = pi; + break; + } + + if (pi1 == -1) + { + pi1 = mesh.AddPoint (p, layer, FIXEDPOINT); + meshpoint_tree -> Insert (p, pi1); + // (*testout) << "test3, store point " << pi1 << ", p = " << p << endl; + } + + p = edgepoints.Last(); + PointIndex pi2 = -1; + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + + if (Dist (mesh[pi], p) < 1e-6*geometry.MaxSize()) + { + pi2 = pi; + break; + } + if (pi2==-1) + { + pi2 = mesh.AddPoint (p, layer, FIXEDPOINT); + meshpoint_tree -> Insert (p, pi2); + // (*testout) << "test4, store point " << pi2 << ", p = " << p << endl; + } + + /* + + 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); + } + */ + + // (*testout) << "short edge " << pi1 << " - " << pi2 << endl; + + 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 & refedges, + const ARRAY & 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; + + double size = geometry.MaxSize(); + + // 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*size) + frompi = pi; + if (Dist2 (mesh[pi], top) <= 1e-16*size) + topi = pi; + } + + + if (topi == -1) + { + topi = mesh.AddPoint (top, layer, FIXEDPOINT); + 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); + } +#ifdef DEVELOP + (*testout) << "adding identification " << mesh[frompi] << "; " << mesh[topi] + << " (id " << copyedgeidentification <<")" << endl; +#endif + + + /* + (*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); + + //(*testout) << "copy edge, pts = " << npi1 << " - " << npi2 << endl; + + 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(0); + + BitArray pointatsurface (nsurf); + Point<3> p1, p2; + Vec<3> nv, tv; + Solid * tansol; + ARRAY tansurfind; + // const Solid * sol; + + double size = geometry.MaxSize(); + 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, tansurfind, ideps*size); + 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, EDGEPOINT); + mesh.AddPoint (p2, layer, EDGEPOINT); + 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/libsrc/csg/edgeflw.hpp b/libsrc/csg/edgeflw.hpp new file mode 100644 index 00000000..ad386183 --- /dev/null +++ b/libsrc/csg/edgeflw.hpp @@ -0,0 +1,104 @@ +#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 & specpoints, + double h, Mesh & mesh); + + + + + +class EdgeCalculation +{ + const CSGeometry & geometry; + ARRAY & specpoints; + Point3dTree * searchtree; + Point3dTree * meshpoint_tree; + int cntedge; + + double ideps; + +public: + EdgeCalculation (const CSGeometry & ageometry, + ARRAY & aspecpoints); + + ~EdgeCalculation(); + + void SetIdEps(const double epsin) {ideps = epsin;} + + void Calc(double h, Mesh & mesh); + + +private: + void CalcEdges1 (double h, Mesh & mesh); + + + void FollowEdge (int pi1, int & ep, int & pos, + // const ARRAY & hsp, + const ARRAY & hsp, + double h, const Mesh & mesh, + ARRAY > & edgepoints, + ARRAY & curvelength); + + + void AnalyzeEdge (int s1, int s2, int s1_rep, int s2_rep, int pos, int layer, + const ARRAY > & edgepoints, + ARRAY & refedges, + ARRAY & refedgesinv); + + void StoreEdge (const ARRAY & refedges, + const ARRAY & refedgesinv, + const ARRAY > & edgepoints, + const ARRAY & curvelength, + int layer, + Mesh & mesh); + + void StoreShortEdge (const ARRAY & refedges, + const ARRAY & refedgesinv, + const ARRAY > & edgepoints, + const ARRAY & curvelength, + int layer, + Mesh & mesh); + + void CopyEdge (const ARRAY & refedges, + const ARRAY & 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/libsrc/csg/explicitcurve2d.cpp b/libsrc/csg/explicitcurve2d.cpp new file mode 100644 index 00000000..81c0e7ac --- /dev/null +++ b/libsrc/csg/explicitcurve2d.cpp @@ -0,0 +1,160 @@ +#include +#include + +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(-1); + 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/libsrc/csg/explicitcurve2d.hpp b/libsrc/csg/explicitcurve2d.hpp new file mode 100644 index 00000000..af405aed --- /dev/null +++ b/libsrc/csg/explicitcurve2d.hpp @@ -0,0 +1,109 @@ +#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 > points; + /// + ARRAY 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/libsrc/csg/extrusion.cpp b/libsrc/csg/extrusion.cpp new file mode 100644 index 00000000..51f1e57e --- /dev/null +++ b/libsrc/csg/extrusion.cpp @@ -0,0 +1,940 @@ +#include + +#include +#include + + +namespace netgen +{ + + void ExtrusionFace :: Init(void) + { + p0.SetSize(path->GetNSplines()); + x_dir.SetSize(path->GetNSplines()); + y_dir.SetSize(path->GetNSplines()); + z_dir.SetSize(path->GetNSplines()); + loc_z_dir.SetSize(path->GetNSplines()); + spline3_path.SetSize(path->GetNSplines()); + line_path.SetSize(path->GetNSplines()); + + for(int i=0; iGetNSplines(); i++) + { + spline3_path[i] = dynamic_cast < const SplineSeg3<3>* >(&path->GetSpline(i)); + line_path[i] = dynamic_cast < const LineSeg<3>* >(&path->GetSpline(i)); + + if(line_path[i]) + { + y_dir[i] = line_path[i]->EndPI() - line_path[i]->StartPI(); + y_dir[i].Normalize(); + z_dir[i] = glob_z_direction; + Orthogonalize(y_dir[i],z_dir[i]); + x_dir[i] = Cross(y_dir[i],z_dir[i]); + loc_z_dir[i] = z_dir[i]; + } + else + { + z_dir[i] = glob_z_direction; + loc_z_dir[i] = glob_z_direction; + } + } + + profile->GetCoeff(profile_spline_coeff); + latest_point3d = -1.111e30; + + } + + + ExtrusionFace :: ExtrusionFace(const SplineSeg<2> * profile_in, + const SplineGeometry<3> * path_in, + const Vec<3> & z_direction) : + profile(profile_in), path(path_in), glob_z_direction(z_direction) + { + deletable = false; + + Init(); + } + + ExtrusionFace :: ExtrusionFace(const ARRAY & raw_data) + { + deletable = true; + + int pos=0; + + ARRAY< Point<2> > p(3); + + int ptype = int(raw_data[pos]); pos++; + + for(int i=0; i(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1)); + //(*testout) << "appending LineSeg<2> " << p[0] + // << " to " << p[1] << endl; + } + else if(ptype == 3) + { + profile = new SplineSeg3<2>(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1), + GeomPoint<2>(p[2],1)); + //(*testout) << "appending SplineSeg<3> " + // << p[0] << " -- " << p[1] << " -- " << p[2] << endl; + } + + path = new SplineGeometry<3>; + pos = const_cast< SplineGeometry<3> *>(path)->Load(raw_data,pos); + + for(int i=0; i<3; i++) + { + glob_z_direction(i) = raw_data[pos]; + pos++; + } + + //(*testout) << "read glob_z_direction " << glob_z_direction << endl; + + Init(); + + } + + ExtrusionFace :: ~ExtrusionFace() + { + if(deletable) + { + delete profile; + delete path; + } + } + + + int ExtrusionFace :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const ExtrusionFace * ext2 = dynamic_cast(&s2); + + if(!ext2) return 0; + + if(ext2 == this) + return 1; + + return 0; + } + + void ExtrusionFace :: Orthogonalize(const Vec<3> & v1, Vec<3> & v2) const + { + v2 -= (v1*v2)*v1; + v2.Normalize(); + } + + + void ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d, + int & seg, double & t) const + { + if(Dist2(point3d,latest_point3d) < 1e-25*Dist2(path->GetSpline(0).StartPI(),path->GetSpline(0).EndPI())) + { + point2d = latest_point2d; + seg = latest_seg; + t = latest_t; + return; + } + + latest_point3d = point3d; + + double cutdist(-1); + + + + + ARRAY mindist(path->GetNSplines()); + + for(int i=0; iGetNSplines(); i++) + { + + double auxcut(-1); + double auxmin(-1); + + if(spline3_path[i]) + { + Point<3> startp(path->GetSpline(i).StartPI()); + Point<3> endp(path->GetSpline(i).EndPI()); + Point<3> tanp(spline3_path[i]->TangentPoint()); + double da,db,dc; + + double l; + Vec<3> dir = endp-startp; + l = dir.Length(); dir *= 1./l; + Vec<3> topoint = point3d - startp; + double s = topoint * dir; + if(s<=0) + da = topoint.Length(); + else if(s>=l) + da = Dist(endp,point3d); + else + da = sqrt(topoint.Length2() - s*s); + + dir = tanp - startp; + l = dir.Length(); dir *= 1./l; + topoint = point3d - startp; + s = topoint * dir; + if(s<=0) + db = topoint.Length(); + else if(s>=l) + db = Dist(tanp,point3d); + else + db = sqrt(topoint.Length2() - s*s); + + dir = endp - tanp; + l = dir.Length(); dir *= 1./l; + topoint = point3d - tanp; + s = topoint * dir; + if(s<=0) + dc = topoint.Length(); + else if(s>=l) + dc = Dist(endp,point3d); + else + dc = sqrt(topoint.Length2() - s*s); + + if(da > db && da > dc) + auxcut = da; + else + auxcut = max2(da,min2(db,dc)); + + auxmin = min3(da,db,dc); + } + else if(line_path[i]) + { + double l; + Vec<3> dir = path->GetSpline(i).EndPI() - path->GetSpline(i).StartPI(); + l = dir.Length(); dir *= 1./l; + Vec<3> topoint = point3d - path->GetSpline(i).StartPI(); + double s = topoint * dir; + if(s<=0) + auxcut = topoint.Length(); + else if(s>=l) + auxcut = Dist(path->GetSpline(i).EndPI(),point3d); + else + auxcut = sqrt(topoint.Length2() - s*s); + + auxmin = auxcut; + } + + + mindist[i] = auxmin; + + if(i==0 || auxcut < cutdist) + cutdist = auxcut; + + + + + /* + double d1 = Dist2(point3d,path.GetSpline(i).StartPI()); + double d2 = Dist2(point3d,path.GetSpline(i).EndPI()); + if(d1 <= d2) + { + mindist[i] = d1; + if(i==0 || d2 < cutdist) + cutdist = d2; + } + else + { + mindist[i] = d2; + if(i==0 || d1 < cutdist) + cutdist = d1; + } + */ + } + + + //(*testout) << " cutdist " << cutdist << " mindist " << mindist << endl; + + + Point<2> testpoint2d; + Point<3> testpoint3d; + + double minproj(-1); + bool minproj_set(false); + + + //(*testout) << "point "<< point3d << " candidates: "; + for(int i=0; iGetNSplines(); i++) + { + if(mindist[i] > cutdist) continue; + //(*testout) << i << " "; + + double thist = CalcProj(point3d,testpoint2d,i); + testpoint3d = p0[i] + testpoint2d(0)*x_dir[i] + testpoint2d(1)*loc_z_dir[i]; + double d = Dist2(point3d,testpoint3d); + //(*testout) << "(d="< & point3d, Point<2> & point2d, + const int seg) const + { + double t(-1); + + if(line_path[seg]) + { + point2d(0) = (point3d-line_path[seg]->StartPI())*x_dir[seg]; + point2d(1) = (point3d-line_path[seg]->StartPI())*z_dir[seg]; + double l = Dist(line_path[seg]->StartPI(), + line_path[seg]->EndPI()); + t = min2(max2((point3d - line_path[seg]->StartPI()) * y_dir[seg],0.), + l); + p0[seg] = line_path[seg]->StartPI() + t*y_dir[seg]; + t *= 1./l; + } + else if(spline3_path[seg]) + { + spline3_path[seg]->Project(point3d,p0[seg],t); + + y_dir[seg] = spline3_path[seg]->GetTangent(t); y_dir[seg].Normalize(); + loc_z_dir[seg] = z_dir[seg]; + Orthogonalize(y_dir[seg],loc_z_dir[seg]); + x_dir[seg] = Cross(y_dir[seg],loc_z_dir[seg]); + Vec<3> dir = point3d-p0[seg]; + point2d(0) = x_dir[seg]*dir; + point2d(1) = loc_z_dir[seg]*dir; + } + return t; + } + + double ExtrusionFace :: CalcFunctionValue (const Point<3> & point) const + { + Point<2> p; + + double dummyd; + int dummyi; + + CalcProj(point,p,dummyi,dummyd); + //(*testout) << "spline " << dummyi << " t " << dummyd << endl; + + return profile_spline_coeff(0)*p(0)*p(0) + profile_spline_coeff(1)*p(1)*p(1) + + profile_spline_coeff(2)*p(0)*p(1) + profile_spline_coeff(3)*p(0) + + profile_spline_coeff(4)*p(1) + profile_spline_coeff(5); + } + + + void ExtrusionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + int i; + Point<2> p2d; + + double t_path; + int seg; + CalcProj(point,p2d,seg,t_path); + + Point<3> phi; + Vec<3> phip,phipp,phi_minus_point; + + path->GetSpline(seg).GetDerivatives(t_path,phi,phip,phipp); + + phi_minus_point = phi-point; + + Vec<3> grad_t = phip; + + double facA = phipp*phi_minus_point + phip*phip; + + grad_t *= 1./facA; + + ARRAY < Vec<3> > dphi_dX(3); + + for(i=0; i<3; i++) + dphi_dX[i] = grad_t(i)*phip; + + ARRAY < Vec<3> > dy_dir_dX(3); + + double lphip = phip.Length(); + + dy_dir_dX[0] = dy_dir_dX[1] = dy_dir_dX[2] = + (1./lphip) * phipp - ((phip*phipp)/pow(lphip,3)) * phip; + + for(i=0; i<3; i++) + dy_dir_dX[i] *= grad_t(i); + + ARRAY < Vec<3> > dx_dir_dX(3); + + for(i=0; i<3; i++) + dx_dir_dX[i] = Cross(dy_dir_dX[i],z_dir[seg]); + + Vec<3> grad_xbar; + + for(i=0; i<3; i++) + grad_xbar(i) = -1.*(phi_minus_point * dx_dir_dX[i]) + x_dir[seg](i) - x_dir[seg] * dphi_dX[i]; + + double zy = z_dir[seg]*y_dir[seg]; + + Vec<3> grad_ybar; + Vec<3> aux = z_dir[seg] - zy*y_dir[seg]; + + for(i=0; i<3; i++) + grad_ybar(i) = ( (z_dir[seg]*dy_dir_dX[i])*y_dir[seg] + zy*dy_dir_dX[i] ) * phi_minus_point + + aux[i] - + aux * dphi_dX[i]; + + + const double dFdxbar = 2.*profile_spline_coeff(0)*p2d(0) + + profile_spline_coeff(2)*p2d(1) + profile_spline_coeff(3); + + const double dFdybar = 2.*profile_spline_coeff(1)*p2d(1) + + profile_spline_coeff(2)*p2d(0) + profile_spline_coeff(4); + + + grad = dFdxbar * grad_xbar + dFdybar * grad_ybar; + } + + void ExtrusionFace :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const + { + const double eps = 1e-7*Dist(path->GetSpline(0).StartPI(),path->GetSpline(0).EndPI()); + + /* + Point<3> auxpoint1(point),auxpoint2(point); + Vec<3> auxvec,auxgrad1,auxgrad2; + + for(int i=0; i<3; i++) + { + auxpoint1(i) -= eps; + auxpoint2(i) += eps; + CalcGradient(auxpoint1,auxgrad1); + CalcGradient(auxpoint2,auxgrad2); + auxvec = (1./(2.*eps)) * (auxgrad2-auxgrad1); + for(int j=0; j<3; j++) + hesse(i,j) = auxvec(j); + auxpoint1(i) = point(i); + auxpoint2(i) = point(i); + } + */ + + + Vec<3> grad; + CalcGradient(point,grad); + + Point<3> auxpoint(point); + Vec<3> auxvec,auxgrad; + + for(int i=0; i<3; i++) + { + auxpoint(i) -= eps; + CalcGradient(auxpoint,auxgrad); + auxvec = (1./eps) * (grad-auxgrad); + for(int j=0; j<3; j++) + hesse(i,j) = auxvec(j); + auxpoint(i) = point(i); + } + + + + for(int i=0; i<3; i++) + for(int j=i+1; j<3; j++) + hesse(i,j) = hesse(j,i) = 0.5*(hesse(i,j)+hesse(j,i)); + } + + + + double ExtrusionFace :: HesseNorm () const + { + return fabs(profile_spline_coeff(0) + profile_spline_coeff(1)) + + sqrt(pow(profile_spline_coeff(0)+profile_spline_coeff(1),2)+4.*pow(profile_spline_coeff(2),2)); + } + + double ExtrusionFace :: MaxCurvature () const + { + double retval,actmax; + + retval = profile->MaxCurvature(); + for(int i=0; iGetNSplines(); i++) + { + actmax = path->GetSpline(i).MaxCurvature(); + if(actmax > retval) + retval = actmax; + } + + return 2.*retval; + } + + + void ExtrusionFace :: Project (Point<3> & p) const + { + double dummyt; + int seg; + Point<2> p2d; + + CalcProj(p,p2d,seg,dummyt); + + profile->Project(p2d,p2d,profile_par); + + p = p0[seg] + p2d(0)*x_dir[seg] + p2d(1)*loc_z_dir[seg]; + + Vec<2> tangent2d = profile->GetTangent(profile_par); + profile_tangent = tangent2d(0)*x_dir[seg] + tangent2d(1)*y_dir[seg]; + } + + + + Point<3> ExtrusionFace :: GetSurfacePoint () const + { + p0[0] = path->GetSpline(0).GetPoint(0.5); + if(!line_path[0]) + { + y_dir[0] = path->GetSpline(0).GetTangent(0.5); + y_dir[0].Normalize(); + loc_z_dir[0] = z_dir[0]; + Orthogonalize(y_dir[0],loc_z_dir[0]); + x_dir[0] = Cross(y_dir[0],loc_z_dir[0]); + } + + Point<2> locpoint = profile->GetPoint(0.5); + + return p0[0] + locpoint(0)*x_dir[0] + locpoint(1)*loc_z_dir[0]; + } + + bool ExtrusionFace :: BoxIntersectsFace(const Box<3> & box) const + { + Point<3> center = box.Center(); + + Project(center); + + //(*testout) << "box.Center() " << box.Center() << " projected " << center << " diam " << box.Diam() + // << " dist " << Dist(box.Center(),center) << endl; + + return (Dist(box.Center(),center) < 0.5*box.Diam()); + } + + + void ExtrusionFace :: LineIntersections ( const Point<3> & p, + const Vec<3> & v, + const double eps, + int & before, + int & after, + bool & intersecting ) const + { + Point<2> p2d; + Vec<2> v2d; + + intersecting = false; + + double segt; + int seg; + + CalcProj(p,p2d,seg,segt); + + if(seg == 0 && segt < 1e-20) + { + Vec<3> v1,v2; + v1 = path->GetSpline(0).GetTangent(0); + v2 = p-p0[seg]; + if(v1*v2 < -eps) + return; + } + if(seg == path->GetNSplines()-1 && 1.-segt < 1e-20) + { + Vec<3> v1,v2; + v1 = path->GetSpline(seg).GetTangent(1); + v2 = p-p0[seg]; + if(v1*v2 > eps) + return; + } + + v2d(0) = v * x_dir[seg]; + v2d(1) = v * loc_z_dir[seg]; + + Vec<2> n(v2d(1),-v2d(0)); + ARRAY < Point<2> > ips; + + + profile->LineIntersections(v2d(1), + -v2d(0), + -v2d(1)*p2d(0) + v2d(0)*p2d(1), + ips,eps); + int comp; + + if(fabs(v2d(0)) >= fabs(v2d(1))) + comp = 0; + else + comp = 1; + + //(*testout) << "p2d " << p2d; + + for(int i=0; i eps) + after++; + else + intersecting = true; + } + //(*testout) << endl; + } + + void ExtrusionFace :: Print (ostream & str) const{} + + INSOLID_TYPE ExtrusionFace :: VecInFace ( const Point<3> & p, + const Vec<3> & v, + const double eps ) const + { + + Vec<3> normal1; + CalcGradient(p,normal1); normal1.Normalize(); + + double d1 = normal1*v; + + + if(d1 > eps) + return IS_OUTSIDE; + if(d1 < -eps) + return IS_INSIDE; + + + return DOES_INTERSECT; + + /* + Point<2> p2d; + + double t_path; + int seg; + CalcProj(p,p2d,seg,t_path); + + double t; + profile.Project(p2d,p2d,t); + + + + Vec<2> profile_tangent = profile.GetTangent(t); + + double d; + + Vec<3> normal1; + CalcGradient(p,normal1); normal1.Normalize(); + + double d1 = normal1*v; + + Vec<2> v2d; + + v2d(0) = v*x_dir[seg]; + v2d(1) = v*loc_z_dir[seg]; + + + Vec<2> normal(-profile_tangent(1),profile_tangent(0)); + + //d = normal*v2d; + + + d = d1; + + + if(d > eps) + return IS_OUTSIDE; + if(d < -eps) + return IS_INSIDE; + + + return DOES_INTERSECT; + */ + } + + + void ExtrusionFace :: GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const + { + int n = int(facets) + 1; + + int i,j,k; + + + int nump = 0; + for(k=0; kGetNSplines(); k++) + { + for(i=0; i<=n; i++) + { + Point<3> origin = path->GetSpline(k).GetPoint(double(i)/double(n)); + if(!line_path[k]) + { + y_dir[k] = path->GetSpline(k).GetTangent(double(i)/double(n)); + y_dir[k].Normalize(); + } + loc_z_dir[k] = z_dir[k]; + Orthogonalize(y_dir[k],loc_z_dir[k]); + if(!line_path[k]) + x_dir[k] = Cross(y_dir[k],loc_z_dir[k]); + + for(j=0; j<=n; j++) + { + Point<2> locp = profile->GetPoint(double(j)/double(n)); + tas.AddPoint(origin + locp(0)*x_dir[k] + locp(1)*loc_z_dir[k]); + nump++; + } + } + } + + for(k=0; kGetNSplines(); k++) + for(i=0; i & data) const + { + data.DeleteAll(); + profile->GetRawData(data); + path->GetRawData(data); + for(int i=0; i<3; i++) + data.Append(glob_z_direction[i]); + //(*testout) << "written raw data " << data << endl; + } + + + + Extrusion :: Extrusion(const SplineGeometry<3> & path_in, + const SplineGeometry<2> & profile_in, + const Vec<3> & z_dir) : + path(path_in), profile(profile_in), z_direction(z_dir) + { + surfaceactive.SetSize(0); + surfaceids.SetSize(0); + + for(int j=0; j & box) const + { + for(int i=0; iBoxIntersectsFace(box)) + return DOES_INTERSECT; + } + + return PointInSolid(box.Center(),0); + } + + + INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p, + const double eps, + ARRAY * const facenums) const + { + Vec<3> random_vec(-0.4561,0.7382,0.4970247); + + int before(0), after(0); + bool intersects(false); + bool does_intersect(false); + + for(int i=0; iLineIntersections(p,random_vec,eps,before,after,intersects); + + //(*testout) << "intersects " << intersects << " before " << before << " after " << after << endl; + if(intersects) + { + if(facenums) + { + facenums->Append(i); + does_intersect = true; + } + else + return DOES_INTERSECT; + } + } + + if(does_intersect) + return DOES_INTERSECT; + + + if(before % 2 == 0) + return IS_OUTSIDE; + + return IS_INSIDE; + } + + + INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p, + double eps) const + { + return PointInSolid(p,eps,NULL); + } + + INSOLID_TYPE Extrusion :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const + { + ARRAY facenums; + INSOLID_TYPE pInSolid = PointInSolid(p,eps,&facenums); + + if(pInSolid != DOES_INTERSECT) + return pInSolid; + + + double d(0); + + if(facenums.Size() == 1) + { + Vec<3> normal; + faces[facenums[0]]->CalcGradient(p,normal); + normal.Normalize(); + d = normal*v; + + latestfacenum = facenums[0]; + } + else if (facenums.Size() == 2) + { + Vec<3> checkvec; + + Point<3> dummy(p); + faces[facenums[0]]->Project(dummy); + if(fabs(faces[facenums[0]]->GetProfilePar()) < 0.1) + { + int aux = facenums[0]; + facenums[0] = facenums[1]; facenums[1] = aux; + } + + checkvec = faces[facenums[0]]->GetYDir(); + + Vec<3> n0, n1; + faces[facenums[0]]->CalcGradient(p,n0); + faces[facenums[1]]->CalcGradient(p,n1); + n0.Normalize(); + n1.Normalize(); + + + Vec<3> t = Cross(n0,n1); + if(checkvec*t < 0) t*= (-1.); + + Vec<3> t0 = Cross(n0,t); + Vec<3> t1 = Cross(t,n1); + + t0.Normalize(); + t1.Normalize(); + + + const double t0v = t0*v; + const double t1v = t1*v; + + if(t0v > t1v) + { + latestfacenum = facenums[0]; + d = n0*v; + } + else + { + latestfacenum = facenums[1]; + d = n1*v; + } + + if(fabs(t0v) < eps && fabs(t1v) < eps) + latestfacenum = -1; + } + + else + { + cerr << "WHY ARE THERE " << facenums.Size() << " FACES?" << endl; + } + + if(d > eps) + return IS_OUTSIDE; + if(d < -eps) + return IS_INSIDE; + + return DOES_INTERSECT; + } + + + + // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid + INSOLID_TYPE Extrusion :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const + { + INSOLID_TYPE retval; + retval = VecInSolid(p,v1,eps); + + // *testout << "extr, vecinsolid=" << int(retval) << endl; + + if(retval != DOES_INTERSECT) + return retval; + + if(latestfacenum >= 0) + return faces[latestfacenum]->VecInFace(p,v2,0); + else + return VecInSolid(p,v2,eps); + } + + + int Extrusion :: GetNSurfaces() const + { + return faces.Size(); + } + + Surface & Extrusion :: GetSurface (int i) + { + return *faces[i]; + } + + const Surface & Extrusion :: GetSurface (int i) const + { + return *faces[i]; + } + + + void Extrusion :: Reduce (const BoxSphere<3> & box) + { + for(int i=0; iBoxIntersectsFace(box); + } + + void Extrusion :: UnReduce () + { + for(int i=0; i * profile; + const SplineGeometry<3> * path; + Vec<3> glob_z_direction; + + bool deletable; + + ARRAY< const SplineSeg3<3> * > spline3_path; + ARRAY< const LineSeg<3> * > line_path; + + mutable ARRAY < Vec<3> > x_dir, y_dir, z_dir, loc_z_dir; + mutable ARRAY < Point<3> > p0; + + mutable Vec<3> profile_tangent; + mutable double profile_par; + + mutable Vector profile_spline_coeff; + + mutable int latest_seg; + mutable double latest_t; + mutable Point<2> latest_point2d; + mutable Point<3> latest_point3d; + + +private: + void Orthogonalize(const Vec<3> & v1, Vec<3> & v2) const; + + void Init(void); + +public: + double CalcProj(const Point<3> & point3d, Point<2> & point2d, + const int seg) const; + void CalcProj(const Point<3> & point3d, Point<2> & point2d, + int & seg, double & t) const; + +public: + ExtrusionFace(const SplineSeg<2> * profile_in, + const SplineGeometry<3> * path_in, + const Vec<3> & z_direction); + + ExtrusionFace(const ARRAY & raw_data); + + + ~ExtrusionFace(); + + 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 double MaxCurvature () const; + //virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + // double /* rad */) const; + + virtual void Project (Point<3> & p) const; + + virtual Point<3> GetSurfacePoint () const; + virtual void Print (ostream & str) const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const; + + const SplineGeometry<3> & GetPath(void) const {return *path;} + const SplineSeg<2> & GetProfile(void) const {return *profile;} + + bool BoxIntersectsFace(const Box<3> & box) const; + + void LineIntersections ( const Point<3> & p, + const Vec<3> & v, + const double eps, + int & before, + int & after, + bool & intersecting ) const; + + INSOLID_TYPE VecInFace ( const Point<3> & p, + const Vec<3> & v, + const double eps ) const; + + const Vec<3> & GetYDir ( void ) const {return y_dir[latest_seg];} + const Vec<3> & GetProfileTangent (void) const {return profile_tangent;} + double GetProfilePar(void) const {return profile_par;} + + void GetRawData(ARRAY & data) const; +}; + + + +class Extrusion : public Primitive +{ +private: + const SplineGeometry<3> & path; + const SplineGeometry<2> & profile; + + const Vec<3> & z_direction; + + ARRAY faces; + + mutable int latestfacenum; + +public: + Extrusion(const SplineGeometry<3> & path_in, + const SplineGeometry<2> & profile_in, + const Vec<3> & z_dir); + ~Extrusion(); + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const; + INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps, + ARRAY * const facenums) 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; + virtual Surface & GetSurface (int i = 0); + virtual const Surface & GetSurface (int i = 0) const; + + + virtual void Reduce (const BoxSphere<3> & box); + virtual void UnReduce (); + +}; + + +#endif //_EXTRUSION_HPP diff --git a/libsrc/csg/gencyl.cpp b/libsrc/csg/gencyl.cpp new file mode 100644 index 00000000..2879e580 --- /dev/null +++ b/libsrc/csg/gencyl.cpp @@ -0,0 +1,209 @@ +#include +#include + + +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(0, 0) = (1 - curvpp(0) * curvpp(0) ) / dist; + h2d(0, 1) = h2d(1, 0) = (- curvpp(0) * curvpp(1) ) / dist; + h2d(1, 1) = (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/libsrc/csg/gencyl.hpp b/libsrc/csg/gencyl.hpp new file mode 100644 index 00000000..424c867a --- /dev/null +++ b/libsrc/csg/gencyl.hpp @@ -0,0 +1,64 @@ +#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/libsrc/csg/genmesh.cpp b/libsrc/csg/genmesh.cpp new file mode 100644 index 00000000..3a56cca7 --- /dev/null +++ b/libsrc/csg/genmesh.cpp @@ -0,0 +1,854 @@ +#include + + +#include + +#include +#include +#include + + +namespace netgen +{ + ARRAY specpoints; + static ARRAY spoints; + +#define TCL_OK 0 +#define TCL_ERROR 1 + + + + static void FindPoints (CSGeometry & geom, Mesh & mesh) + { + PrintMessage (1, "Start Findpoints"); + + const char * savetask = multithread.task; + multithread.task = "Find points"; + + for (int i = 0; i < geom.GetNUserPoints(); i++) + { + mesh.AddPoint(geom.GetUserPoint (i)); + mesh.Points().Last().Singularity (geom.GetUserPointRefFactor(i)); + mesh.AddLockedPoint (PointIndex (i+1)); + } + + SpecialPointCalculation spc; + + spc.SetIdEps(geom.GetIdEps()); + + 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, const bool setmeshsize = false) + { + EdgeCalculation ec (geom, specpoints); + ec.SetIdEps(geom.GetIdEps()); + ec.Calc (mparam.maxh, mesh); + + for (int i = 0; i < geom.singedges.Size(); i++) + { + geom.singedges[i]->FindPointsOnEdge (mesh); + if(setmeshsize) + geom.singedges[i]->SetMeshSize(mesh,10.*geom.BoundingBox().Diam()); + } + for (int i = 0; i < geom.singpoints.Size(); i++) + geom.singpoints[i]->FindPoints (mesh); + + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + //(*testout) << "segment " << mesh.LineSegment(i) << endl; + int ok = 0; + for (int k = 1; k <= mesh.GetNFD(); k++) + if (mesh.GetFaceDescriptor(k).SegmentFits (mesh.LineSegment(i))) + { + ok = k; + //(*testout) << "fits to " << k << endl; + } + + if (!ok) + { + ok = mesh.AddFaceDescriptor (FaceDescriptor (mesh.LineSegment(i))); + //(*testout) << "did not find, now " << ok << endl; + } + + //(*testout) << "change from " << mesh.LineSegment(i).si; + mesh.LineSegment(i).si = ok; + //(*testout) << " to " << mesh.LineSegment(i).si << endl; + } + + if (geom.identifications.Size()) + { + PrintMessage (3, "Find Identifications"); + for (int i = 0; i < geom.identifications.Size(); i++) + { + geom.identifications[i]->IdentifyPoints (mesh); + //(*testout) << "identification " << i << " is " + // << *geom.identifications[i] << endl; + + } + for (int i = 0; i < geom.identifications.Size(); i++) + geom.identifications[i]->IdentifyFaces (mesh); + } + + + // find intersecting segments + PrintMessage (3, "Check intersecting edges"); + + Point3d pmin, pmax; + mesh.GetBox (pmin, pmax); + Box3dTree segtree (pmin, pmax); + + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + if (mesh[si].seginfo) + { + Box<3> hbox; + hbox.Set (mesh[mesh[si].p1]); + hbox.Add (mesh[mesh[si].p2]); + segtree.Insert (hbox.PMin(), hbox.PMax(), si); + } + } + + ARRAY loc; + if (!ec.point_on_edge_problem) + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + if (!mesh[si].seginfo) continue; + + Box<3> hbox; + hbox.Set (mesh[mesh[si].p1]); + hbox.Add (mesh[mesh[si].p2]); + hbox.Increase (1e-6); + segtree.GetIntersecting (hbox.PMin(), hbox.PMax(), loc); + + // for (SegmentIndex sj = 0; sj < si; sj++) + for (int j = 0; j < loc.Size(); j++) + { + SegmentIndex sj = loc[j]; + if (sj >= si) continue; + 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 jj = 0; jj < 3; jj++) + { + mat(jj,0) = vi(jj); + mat(jj,1) = -vj(jj); + rhs(jj) = pj1(jj)-pi1(jj); + } + + mat.Solve (rhs, sol); + + //(*testout) << "mat " << mat << endl << "rhs " << rhs << endl << "sol " << sol << endl; + + 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; + + //(*testout) << "ip " << ip << endl; + + Point<3> pip = ip; + ProjectToEdge (geom.GetSurface (mesh[si].surfnr1), + geom.GetSurface (mesh[si].surfnr2), pip); + + //(*testout) << "Dist (ip, pip_si) " << Dist (ip, pip) << endl; + if (Dist (ip, pip) > 1e-6*geom.MaxSize()) continue; + pip = ip; + ProjectToEdge (geom.GetSurface (mesh[sj].surfnr1), + geom.GetSurface (mesh[sj].surfnr2), pip); + + //(*testout) << "Dist (ip, pip_sj) " << Dist (ip, pip) << endl; + if (Dist (ip, pip) > 1e-6*geom.MaxSize()) continue; + + + + cout << "Intersection at " << ip << endl; + + geom.AddUserPoint (ip); + spoints.Append (MeshPoint (ip, mesh[mesh[si].p1].GetLayer())); + mesh.AddPoint (ip); + + (*testout) << "found intersection at " << ip << endl; + (*testout) << "sol = " << sol << endl; + (*testout) << "res = " << (rhs - mat*sol) << endl; + (*testout) << "segs = " << pi1 << " - " << pi2 << endl; + (*testout) << "and = " << pj1 << " - " << pj2 << endl << endl; + } + } + } + } + + + + + + + static void MeshSurface (CSGeometry & geom, Mesh & mesh) + { + const char * savetask = multithread.task; + multithread.task = "Surface meshing"; + + ARRAY segments; + int noldp = mesh.GetNP(); + + double starttime = GetTime(); + + // find master faces from identified + ARRAY masterface(mesh.GetNFD()); + for (int i = 1; i <= mesh.GetNFD(); i++) + masterface.Elem(i) = i; + + ARRAY 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++) + { + bool increased = false; + + 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); + increased = true; + } + + 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)) + { + if(geom.bcmodifications[l].bcname == NULL) + fd.SetBCProperty (geom.bcmodifications[l].bcnr); + else + { + if(!increased) + { + bccnt++; + fd.SetBCProperty (bccnt); + increased = true; + } + } + } + } + } + + mesh.SetNBCNames( bccnt ); + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + const Surface * surf = geom.GetSurface(fd.SurfNr()); + if (fd.TLOSurface() ) + { + int bcp = fd.BCProperty(); + string nextbcname = geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetBCName(); + if ( nextbcname != "default" ) + mesh.SetBCName ( bcp - 1 , nextbcname ); + } + else // if (surf -> GetBCProperty() != -1) + { + int bcp = fd.BCProperty(); + string nextbcname = surf->GetBCName(); + if ( nextbcname != "default" ) + mesh.SetBCName ( bcp - 1, nextbcname ); + } + } + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + fd.SetBCName ( mesh.GetBCNamePtr ( fd.BCProperty() - 1 ) ); + } + + + //!! + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + //const Surface * surf = geom.GetSurface(fd.SurfNr()); + + 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) && + geom.bcmodifications[l].bcname != NULL + ) + { + int bcp = fd.BCProperty(); + mesh.SetBCName ( bcp - 1, *(geom.bcmodifications[l].bcname) ); + fd.SetBCName ( mesh.GetBCNamePtr ( bcp - 1) ); + } + } + } + + for(int k = 0; k 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++) + { + //if(surf->PointOnSurface(mesh[pi])) + meshing.AddPoint (mesh[pi], pi, NULL, + (surf->PointOnSurface(mesh[pi])!=0)); + } + + segments.SetSize (0); + + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + if (mesh[si].si == k) + { + segments.Append (mesh[si]); + (*testout) << "appending segment " << mesh[si] << endl; + //<< " from " << mesh[mesh[si][0]] + // << " to " < + 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 (mparam.elsizeweight); + 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 (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + meshopt.ImproveMesh (mesh); + } + + { + MeshOptimize2dSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + meshopt.CombineImprove (mesh); + // mesh.CalcSurfacesOfNode(); + } + + if (multithread.terminate) return; + { + MeshOptimize2dSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + 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); + mesh->SetMinimalH (mparam.minh); + + ARRAY 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, true); + 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, true); + 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/libsrc/csg/geoml.hpp b/libsrc/csg/geoml.hpp new file mode 100644 index 00000000..e7974ad2 --- /dev/null +++ b/libsrc/csg/geoml.hpp @@ -0,0 +1,16 @@ +#ifndef FILE_GEOML +#define FILE_GEOML + +/* *************************************************************************/ +/* File: geoml.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 21. Jun. 98 */ +/* *************************************************************************/ + +#include + +#include +#include +#include +#include +#endif diff --git a/libsrc/csg/identify.cpp b/libsrc/csg/identify.cpp new file mode 100644 index 00000000..b6e8e539 --- /dev/null +++ b/libsrc/csg/identify.cpp @@ -0,0 +1,1672 @@ +#include +#include + +#include +#include +#include + + +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 & points) +{ + ; +} +*/ + + +int Identification :: +Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) 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 & segs, + Mesh & mesh, const Surface * surf) +{ + cout << "Identification::BuildSurfaceElements called for base-class" << endl; + ; +} + + +void Identification :: +BuildVolumeElements (ARRAY & surfels, + class Mesh & mesh) +{ + ; +} + +void Identification :: +GetIdentifiedFaces (ARRAY & 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 & 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 TABLE & specpoint2solid, + const TABLE & specpoint2surface) 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-6) + 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); + + mesh.GetIdentifications().SetType(nr,Identifications::PERIODIC); + + /* + (*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; + */ + } + } + } + + mesh.GetIdentifications().SetType(nr,Identifications::PERIODIC); +} + + +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 & segs, + Mesh & mesh, const Surface * surf) +{ + int found = 0; + int fother; + + int facei = segs.Get(1).si; + int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); + + if (geom.GetSurface(surfnr) == s1 || + geom.GetSurface(surfnr) == s2) + { + ARRAY copy_points; + + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + INDEX_2 fpair (facei, sel.GetIndex()); + fpair.Sort(); + if (identfaces.Used (fpair)) + { + for (int k = 0; k < sel.GetNP(); k++) + if (!copy_points.Contains (sel[k])) + copy_points.Append (sel[k]); + } + } + BubbleSort (copy_points); + for (int k = 0; k < copy_points.Size(); k++) + GetIdentifiedPoint (mesh, copy_points[k]); + + + + for (int 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(sel.GetType()); + newel.SetIndex (facei); + for (int k = 0; k < sel.GetNP(); k++) + newel[k] = GetIdentifiedPoint (mesh, sel[k]); + + Vec<3> nt = Cross (Point<3> (mesh[newel[1]])- Point<3> (mesh[newel[0]]), + Point<3> (mesh[newel[2]])- Point<3> (mesh[newel[0]])); + + Vec<3> nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh[newel[0]]); + if (nsurf * nt < 0) + Swap (newel[0], newel[2]); + + mesh.AddSurfaceElement (newel); + } + } + } + + if (found) + { + // (*mycout) << " copy face " << facei << " from face " << fother; + PrintMessage (4, " 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"); + for(int i=0; i0 && slices[i] <= slices[i-1]) || + (slices[i] >= 1)) + throw NgException ("slices have to be in ascending order, between 0 and 1"); + + // eps_n = 1e-3; + eps_n = 1e-6; + + dom_surf_valid = 0; + + if (domain) + for (int i = 0; i < geom.GetNTopLevelObjects(); i++) + if (domain == geom.GetTopLevelObject(i)) + dom_nr = i; + + usedirection = flags.NumListFlagDefined("direction"); + if(usedirection) + { + for(int i=0; i<3; i++) + direction(i) = flags.GetNumListFlag("direction")[i]; + + direction.Normalize(); + } +} + +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 & 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 TABLE & specpoint2solid, + const TABLE & specpoint2surface) const +{ + //(*testout) << "identcheck: " << sp1.p << "; " << sp2.p << endl; + + if (!dom_surf_valid) + { + const_cast (dom_surf_valid) = 1; + ARRAY & hsurf = const_cast&> (domain_surfaces); + + if (domain) + { + BoxSphere<3> hbox (geom.BoundingBox()); + geom.GetIndependentSurfaceIndices (domain->GetSolid(), hbox, hsurf); + //(*testout) << "surfs of identification " << nr << ": " << endl << hsurf << endl; + } + else + { + hsurf.SetSize (geom.GetNSurf()); + for (int j = 0; j < hsurf.Size(); j++) + hsurf[j] = j; + } + } + + if (domain) + { + bool has1 = 0, has2 = 0; + for (int i = 0; i < specpoint2solid[sp1.nr].Size(); i++) + if (specpoint2solid[sp1.nr][i] == dom_nr) + { has1 = 1; break; } + for (int i = 0; i < specpoint2solid[sp2.nr].Size(); i++) + if (specpoint2solid[sp2.nr][i] == dom_nr) + { has2 = 1; break; } + + if (!has1 || !has2) + { + //(*testout) << "failed at pos1" << endl; + return 0; + } + } + + if (!s1->PointOnSurface (sp1.p)) + { + //(*testout) << "failed at pos2" << endl; + return 0; + } + +// (*testout) << "sp1 " << sp1.p << " sp2 " << sp2.p << endl +// << "specpoint2solid[sp1.nr] " << specpoint2solid[sp1.nr] << endl +// << "specpoint2solid[sp2.nr] " << specpoint2solid[sp2.nr] << endl; + + + Vec<3> n1 = s1->GetNormalVector (sp1.p); + n1.Normalize(); + if ( fabs(n1 * sp1.v) > eps_n) + { + //(*testout) << "failed at pos3" << endl; + return 0; + } + + if (!s2->PointOnSurface(sp2.p)) + { + //(*testout) << "failed at pos4" << endl; + return 0; + } + + + Vec<3> n2 = s2->GetNormalVector (sp2.p); + n2.Normalize(); + if ( fabs(n2 * sp2.v) > eps_n) + { + //(*testout) << "failed at pos5" << endl; + return 0; + } + + // must have joint surface + bool joint = 0; + + int j = 0, k = 0; + while (1) + { + int snr1 = specpoint2surface[sp1.nr][j]; + int snr2 = specpoint2surface[sp2.nr][k]; + if (snr1 < snr2) + { + j++; + if (j == specpoint2surface[sp1.nr].Size()) break; + } + else if (snr2 < snr1) + { + k++; + if (k == specpoint2surface[sp2.nr].Size()) break; + } + else + { + bool dom_surf = 0; + for (int l = 0; l < domain_surfaces.Size(); l++) + if (domain_surfaces[l] == snr1) + dom_surf = 1; + + if (dom_surf) + { + Vec<3> hn1 = geom.GetSurface(snr1)->GetNormalVector (sp1.p); + Vec<3> hn2 = geom.GetSurface(snr1)->GetNormalVector (sp2.p); + + if (hn1 * hn2 > 0) + { + joint = 1; + break; + } + } + + j++; + if (j == specpoint2surface[sp1.nr].Size()) break; + k++; + if (k == specpoint2surface[sp2.nr].Size()) break; + } + } + + if (!joint) + { + //(*testout) << "failed at pos6" << endl; + return 0; + } + + Vec<3> v = sp2.p - sp1.p; + double vl = v.Length(); + double cl = (usedirection) ? fabs(v*direction) : fabs (v*n1); + + + if(cl <= (1-eps_n*eps_n) * vl) + { + //(*testout) << "failed at pos7" << endl; + return 0; + } + + double dl; + + if(usedirection) + { + Vec<3> v1 = sp1.v - (sp1.v*direction)*direction; v1.Normalize(); + Vec<3> v2 = sp2.v - (sp2.v*direction)*direction; v2.Normalize(); + + dl = (v1 - v2).Length(); + } + else + dl = (sp1.v - sp2.v).Length(); + + if (dl < 0.1) + return 1; + + + //(*testout) << "failed at pos8" << endl; + return 0; +} + +int CloseSurfaceIdentification :: +Identifyable (const Point<3> & p1, const Point<3> & p2) const +{ +// if (domain) +// if (!domain->GetSolid()->IsIn (p1) || !domain->GetSolid()->IsIn (p2)) +// return 0; + return (s1->PointOnSurface (p1) && s2->PointOnSurface (p2)); +} + + + + +int CloseSurfaceIdentification :: +IdentifyableCandidate (const SpecialPoint & sp1) const +{ + if (domain) + if (!domain->GetSolid()->IsIn (sp1.p)) + return 0; + + 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 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) << endl + << "surf2: " << (*s2) << endl; + + cerr << "GetIdenfifiedPoint: Not possible" << endl; + throw NgException ("GetIdenfifiedPoint: Not possible"); + } + + // project to other surface + Point<3> hp = p; + if(usedirection) + snew->SkewProject(hp,direction); + else + snew->Project (hp); + + //(*testout) << "projecting " << p << " to " << hp << endl; + + int newpi = 0; + for (int 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); + //(*testout) << "add identification(1) " << pi << " - " << newpi << ", " << nr << endl; + } + else + { + mesh.GetIdentifications().Add (newpi, pi, nr); + //(*testout) << "add identification(2) " << newpi << " - " << pi << ", " << nr << endl; + } + mesh.GetIdentifications().SetType(nr,Identifications::CLOSESURFACES); + + + /* + (*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 np = mesh.GetNP(); + + ARRAY points_on_surf2; + + for (int i2 = 1; i2 <= np; i2++) + if (s2->PointOnSurface (mesh.Point(i2))) + points_on_surf2.Append (i2); + + ARRAY surfs_of_p1; + + for (int i1 = 1; i1 <= np; i1++) + { + Point<3> p1 = mesh.Point(i1); + // (*testout) << "p1 = " << i1 << " = " << p1 << endl; + if (domain && !domain->GetSolid()->IsIn (p1)) + continue; + + //if(domain) (*testout) << "p1 is in " << domain->GetSolid()->Name() << endl; + + if (s1->PointOnSurface (p1)) + { + int candi2 = 0; + double mindist = 1e10; + + Vec<3> n1; + n1 = s1->GetNormalVector (p1); + n1.Normalize(); + + surfs_of_p1.SetSize(0); + for (int jj = 0; jj < domain_surfaces.Size(); jj++) + { + int j = domain_surfaces[jj]; + if (geom.GetSurface(j) -> PointOnSurface(p1)) + surfs_of_p1.Append (j); + } + //(*testout) << " surfs of p1 = " << endl << surfs_of_p1 << endl; + + for (int ii2 = 0; ii2 < points_on_surf2.Size(); ii2++) + { + int i2 = points_on_surf2[ii2]; + if (i2 == i1) continue; + const Point<3> p2 = mesh.Point(i2); + + Vec<3> n = p2 - p1; + n.Normalize(); + + bool joint = 0; + for (int jj = 0; jj < surfs_of_p1.Size(); jj++) + { + int j = surfs_of_p1[jj]; + if (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(usedirection) + { + if (fabs (n*direction) > 0.9) + { + Vec<3> p1p2 = p2-p1; + double ndist = p1p2.Length2() - pow(p1p2*direction,2); + if(ndist < mindist) + { + candi2 = i2; + mindist = ndist; + } + } + + } + else + { + 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, nr = " << nr << ", p1 = " + << i1 << " = " + << mesh[PointIndex(i1)] << ", p2 = " << candi2 << " = " + << mesh[PointIndex(candi2)] << endl; + */ + mesh.GetIdentifications().Add (i1, candi2, nr); + mesh.GetIdentifications().SetType(nr,Identifications::CLOSESURFACES); + //(*testout) << "add identification " << i1 << " - " << candi2 << ", " << nr << endl; + } + } + } +} + + + +void CloseSurfaceIdentification :: IdentifyFaces (class Mesh & mesh) +{ + int fi1, fi2, side; + int s1rep, s2rep; + + for (int i = 0; i < geom.GetNSurf(); i++) + { + if (geom.GetSurface (i) == s1) + s1rep = geom.GetSurfaceClassRepresentant(i); + if (geom.GetSurface (i) == s2) + s2rep = geom.GetSurfaceClassRepresentant(i); + } + + ARRAY segs_on_face1, segs_on_face2; + + identfaces.DeleteData(); + + //(*testout) << "identify faces, nr = " << nr << endl; + + for (int i = 1; i <= mesh.GetNFD(); i++) + { + int surfi = mesh.GetFaceDescriptor(i).SurfNr(); + if (s1rep != surfi) continue; + + + if (domain && + domain != geom.GetTopLevelObject (mesh.GetFaceDescriptor(i).DomainIn()-1) && + domain != geom.GetTopLevelObject (mesh.GetFaceDescriptor(i).DomainOut()-1)) + continue; + + for (int j = 1; j <= mesh.GetNFD(); j++) + { + int surfj = mesh.GetFaceDescriptor(j).SurfNr(); + + if (surfi == surfj) continue; + if (s2rep != surfj) continue; + + + int idok = 1; + + for (side = 1; side <= 2 && idok; side++) + { + if (side == 1) + { + fi1 = i; + fi2 = j; + } + else + { + fi1 = j; + fi2 = i; + } + + + segs_on_face1.SetSize(0); + segs_on_face2.SetSize(0); + + for (int k = 1; k <= mesh.GetNSeg(); k++) + { + if (mesh.LineSegment(k).si == fi1) + segs_on_face1.Append (k); + if (mesh.LineSegment(k).si == fi2) + segs_on_face2.Append (k); + } + + + for (int k = 1; k <= mesh.GetNSeg(); k++) + { + const Segment & seg1 = mesh.LineSegment(k); + if (seg1.si != fi1) + continue; + + int foundother = 0; + /* + for (int l = 1; l <= mesh.GetNSeg(); l++) + { + const Segment & seg2 = mesh.LineSegment(l); + if (seg2.si != fi2) + continue; + */ + for (int ll = 0; ll < segs_on_face2.Size(); ll++) + { + int l = segs_on_face2[ll]; + const Segment & seg2 = mesh.LineSegment(l); + + 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) << "Identification " << nr << ", identify faces " << i << " and " << j << endl; + INDEX_2 fpair(i,j); + fpair.Sort(); + identfaces.Set (fpair, 1); + } + } + } +} + + + +void CloseSurfaceIdentification :: +BuildSurfaceElements (ARRAY & segs, + Mesh & mesh, const Surface * surf) +{ + bool found = 0; + int cntquads = 0; + + ARRAY identmap; + identmap = 0; + + mesh.GetIdentifications().GetMap (nr, identmap); + + for (int i = PointIndex::BASE; i < identmap.Size()+PointIndex::BASE; i++) + if (identmap[i]) identmap[identmap[i]] = i; + + + //(*testout) << "identification nr = " << nr << endl; + //(*testout) << "surf = " << (*surf) << endl; + //(*testout) << "domain = " << domain->GetSolid()->Name() << endl; + //(*testout) << "segs = " << endl << segs << endl; + //(*testout) << "identmap = " << endl << identmap << endl; + + //ARRAY foundseg(segs.Size()); + //foundseg = false; + + // insert quad layer: + for (int i1 = 0; i1 < segs.Size(); i1++) + { + const Segment & s1 = segs[i1]; + if (identmap[s1.p1] && identmap[s1.p2]) + for (int i2 = 0; i2 < i1; i2++) + { + const Segment & s2 = segs[i2]; + //(*testout) << "checking " << s1 << " and " << s2 << " for ident." << endl; + + if(domain && !((s1.domin == dom_nr || + s1.domout == dom_nr) && + (s2.domin == dom_nr || + s2.domout == dom_nr))) + continue; + + 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(s1.p1, s1.p2, s2.p1, s2.p2); + + Vec<3> n = Cross (mesh[el[1]] - mesh[el[0]], + mesh[el[3]] - mesh[el[0]]); + + Vec<3> ns = surf->GetNormalVector (mesh[el[0]]); + + if (n * ns < 0) + { + Swap (el.PNum(1), el.PNum(2)); + Swap (el.PNum(3), el.PNum(4)); + } + + mesh.AddSurfaceElement (el); +// (*testout) << "(id nr "<< nr <<") 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 = true; + //foundseg[i1]=foundseg[i2] = true; + cntquads++; + } + } + } + if (found) + { + PrintMessage(3, "insert quad layer of ", cntquads, + " elements at face ", segs.Get(1).si); + //ARRAY aux; + //for(int i=0; i & segs, + Mesh & mesh, const Surface * surf) +{ + // copy mesh + + + // (*testout) << "copy trig face, identnr = " << nr << endl; + // (*testout) << "identfaces = " << endl << identfaces << endl; + + if (!segs.Size()) return; + + bool found = 0; + + int fother; + int facei = segs.Get(1).si; + int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); + + + bool foundid = 0; + for (INDEX_2_HASHTABLE::Iterator it = identfaces.Begin(); + it != identfaces.End(); it++) + { + INDEX_2 i2; + int data; + identfaces.GetData (it, i2, data); + if (i2.I1() == facei || i2.I2() == facei) + foundid = 1; + } + + /* + for (int i = 1; i <= identfaces.GetNBags(); i++) + for (int 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) << "identface = " << i2 << endl; + (*testout) << "face " << i2.I1() << " = " << mesh.GetFaceDescriptor(i2.I1()) << endl; + (*testout) << "face " << i2.I2() << " = " << mesh.GetFaceDescriptor(i2.I2()) << endl; + } + */ + + if (foundid) + { + // (*testout) << "surfaces found" << endl; + // copy surface + for (int 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(sel.GetType()); + newel.SetIndex (facei); + for (int k = 1; k <= sel.GetNP(); 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; + PrintMessage (4, " copy face ", facei, " from face ", fother); + segs.SetSize(0); + } +} + + + + + + + + + + + + + + +void CloseSurfaceIdentification :: +BuildVolumeElements (ARRAY & 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 & 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 TABLE & specpoint2solid, + const TABLE & specpoint2surface) 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); + mesh.GetIdentifications().SetType(nr,Identifications::CLOSEEDGES); + } + } +} + +void CloseEdgesIdentification :: +BuildSurfaceElements (ARRAY & 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(QUAD); + 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/libsrc/csg/identify.hpp b/libsrc/csg/identify.hpp new file mode 100644 index 00000000..651ef39f --- /dev/null +++ b/libsrc/csg/identify.hpp @@ -0,0 +1,204 @@ + +#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 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 & points); + + /// can identify both special points (fixed direction) + /// (identified points, same tangent) + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) 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 & segs, + class Mesh & mesh, + const Surface * surf); + + /// insert volume elements in thin layers + virtual void BuildVolumeElements (ARRAY & surfels, + class Mesh & mesh); + + /// get list of identified faces + virtual void GetIdentifiedFaces (ARRAY & 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 & points); + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) 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 & segs, + class Mesh & mesh, + const Surface * surf); +}; + + +/// +class TopLevelObject; +class CloseSurfaceIdentification : public Identification +{ + const Surface * s1; + const Surface * s2; + const TopLevelObject * domain; + /// + int dom_nr; + /// 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 slices; + /// used only for domain-local identification: + ARRAY domain_surfaces; + /// + bool dom_surf_valid; + + /// + Vec<3> direction; + /// + bool usedirection; +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 & points); + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) 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 & GetSlices () const { return slices; } + virtual void IdentifyPoints (class Mesh & mesh); + virtual void IdentifyFaces (class Mesh & mesh); + virtual void BuildSurfaceElements (ARRAY & segs, + class Mesh & mesh, + const Surface * surf); + void BuildSurfaceElements2 (ARRAY & segs, + class Mesh & mesh, + const Surface * surf); + + virtual void BuildVolumeElements (ARRAY & surfels, + class Mesh & mesh); + + int RefLevels () const { return ref_levels; } + int RefLevels1 () const { return ref_levels_s1; } + int RefLevels2 () const { return ref_levels_s2; } + + bool IsSkewIdentification(void) const {return usedirection;} + const Vec<3> & GetDirection(void) const {return direction;} + + const Surface & GetSurface1(void) const + { return *s1;} + const Surface & GetSurface2(void) const + { return *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 & points); + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const; + + + virtual void IdentifyPoints (class Mesh & mesh); + virtual void BuildSurfaceElements (ARRAY & segs, + class Mesh & mesh, + const Surface * surf); +}; + +#endif diff --git a/libsrc/csg/manifold.cpp b/libsrc/csg/manifold.cpp new file mode 100644 index 00000000..9733389d --- /dev/null +++ b/libsrc/csg/manifold.cpp @@ -0,0 +1,14 @@ +#include + +namespace netgen +{ +Manifold :: Manifold () +{ + ; +} + +Manifold :: ~Manifold () +{ + ; +} +} diff --git a/libsrc/csg/manifold.hpp b/libsrc/csg/manifold.hpp new file mode 100644 index 00000000..5deb7236 --- /dev/null +++ b/libsrc/csg/manifold.hpp @@ -0,0 +1,22 @@ +#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/libsrc/csg/meshsurf.cpp b/libsrc/csg/meshsurf.cpp new file mode 100644 index 00000000..af2575b6 --- /dev/null +++ b/libsrc/csg/meshsurf.cpp @@ -0,0 +1,210 @@ +#include + +#include +#include + + + +namespace netgen +{ + /* +Meshing2Surfaces :: Meshing2Surfaces (const Surface & asurface) + : surface(asurface) +{ + ; +} + */ +Meshing2Surfaces :: Meshing2Surfaces (const Surface & asurf, + const Box<3> & abb) + : Meshing2(abb), surface(asurf) +{ + ; +} + + +void Meshing2Surfaces :: DefineTransformation (const Point3d & p1, const 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, Point<3> & p) const +{ + Point<3> hp = p; + geometry.GetSurface(surfind)->Project (hp); + p = hp; +} + +void MeshOptimize2dSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, + Point<3> & p) const +{ + Point<3> hp = p; + ProjectToEdge ( geometry.GetSurface(surfind), + geometry.GetSurface(surfind2), hp); + p = hp; +} + + +void MeshOptimize2dSurfaces :: +GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & 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) +{ + if(geometry.GetNSurf() == 0) + *testout << endl + << "WARNING: Intializing 2D refinement with 0-surface geometry" << endl + << "==========================================================" << endl + << endl << endl; +} + +RefinementSurfaces :: ~RefinementSurfaces () +{ + ; +} + +void RefinementSurfaces :: +PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & 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 Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) +{ + Point<3> hnewp = p1+secpoint*(p2-p1); + //(*testout) << "hnewp " << hnewp << " s1 " << surfi1 << " s2 " << surfi2 << endl; + if (surfi1 != -1 && surfi2 != -1 && surfi1 != surfi2) + { + netgen::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; + //(*testout) << "hnewp (a1) " << hnewp << endl; + } + else if (surfi1 != -1) + { + geometry.GetSurface (surfi1) -> Project (hnewp); + //(*testout) << "hnewp (a2) " << hnewp << endl; + } + + newp = hnewp; +}; + +Vec<3> RefinementSurfaces :: GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const +{ + Vec<3> n1 = geometry.GetSurface (surfi1)->GetNormalVector (p); + Vec<3> n2 = geometry.GetSurface (surfi2)->GetNormalVector (p); + Vec<3> tau = Cross (n1, n2).Normalize(); + return tau; +} + +Vec<3> RefinementSurfaces :: GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const +{ + return geometry.GetSurface (surfi1)->GetNormalVector (p); +} + + + +void RefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) +{ + if (surfi != -1) + geometry.GetSurface (surfi) -> Project (p); +}; + +void RefinementSurfaces :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const +{ + netgen::ProjectToEdge (geometry.GetSurface(surfi1), + geometry.GetSurface(surfi2), + p); + +} + + +} diff --git a/libsrc/csg/meshsurf.hpp b/libsrc/csg/meshsurf.hpp new file mode 100644 index 00000000..840600b0 --- /dev/null +++ b/libsrc/csg/meshsurf.hpp @@ -0,0 +1,95 @@ +#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 (const Point3d & p1, const 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, Point<3> & p) const; + /// + virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const; + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const; +}; + + + + + +class RefinementSurfaces : public Refinement +{ + const CSGeometry & geometry; + +public: + RefinementSurfaces (const CSGeometry & ageometry); + virtual ~RefinementSurfaces (); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi); + + virtual Vec<3> GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const; + + virtual Vec<3> GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const; + + + virtual void ProjectToSurface (Point<3> & p, int surfi); + + virtual void ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const; + +}; + + + +#endif + diff --git a/libsrc/csg/polyhedra.cpp b/libsrc/csg/polyhedra.cpp new file mode 100644 index 00000000..c82819e9 --- /dev/null +++ b/libsrc/csg/polyhedra.cpp @@ -0,0 +1,738 @@ +#include + +#include +#include + +namespace netgen +{ + +Polyhedra::Face::Face (int pi1, int pi2, int pi3, + const ARRAY > & points, + int ainputnr) +{ + inputnr = ainputnr; + + 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); + eps_base1 = 1e-8; +} + +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; + //(*testout) << "face " << i << endl; + + 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; + + //(*testout) << "still in loop" << endl; + + double dist2 = MinDistTP2 (p1, p2, p3, box.Center()); + //(*testout) << "p1 " << p1 << " p2 " << p2 << " p3 " << p3 << endl + // << " box.Center " << box.Center() << " box.Diam() " << box.Diam() << endl + // << " dist2 " << dist2 << " sqr(box.Diam()/2) " << sqr(box.Diam()/2) << endl; + if (dist2 < sqr (box.Diam()/2)) + { + //(*testout) << "DOES_INTERSECT" << endl; + return DOES_INTERSECT; + } + }; + + return PointInSolid (box.Center(), 1e-3 * box.Diam()); +} + + +INSOLID_TYPE Polyhedra :: PointInSolid (const Point<3> & p, + double eps) const +{ + //(*testout) << "PointInSolid p " << p << " eps " << eps << endl; + //(*testout) << "bbox " << poly_bbox << endl; + + if((p(0) > poly_bbox.PMax()(0) + eps) || (p(0) < poly_bbox.PMin()(0) - eps) || + (p(1) > poly_bbox.PMax()(1) + eps) || (p(1) < poly_bbox.PMin()(1) - eps) || + (p(2) > poly_bbox.PMax()(2) + eps) || (p(2) < poly_bbox.PMin()(2) - eps)) + { + //(*testout) << "returning IS_OUTSIDE" << endl; + return IS_OUTSIDE; + } + + Vec<3> n, v1, v2; + + // random (?) numbers: + n(0) = -0.424621; + n(1) = 0.15432; + n(2) = 0.89212238; + + int cnt = 0; + + 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].nn * v0; + + if(fabs(lam3) < eps) + { + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + { + //(*testout) << "returning DOES_INTERSECT" << endl; + return DOES_INTERSECT; + } + } + else + { + lam3 = -(faces[i].n * v0) / (faces[i].n * n); + + if (lam3 < 0) continue; + + Vec<3> rs = v0 + lam3 * n; + + double lam1 = (faces[i].w1 * rs); + double lam2 = (faces[i].w2 * rs); + if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1) + cnt++; + } + + } + + //(*testout) << " cnt = " << cnt%2 << endl; + return (cnt % 2) ? IS_INSIDE : IS_OUTSIDE; +} + + + + +void Polyhedra :: GetTangentialSurfaceIndices (const Point<3> & p, + ARRAY & surfind, double eps) const +{ + 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].nn * v0); // n->nn + + if (fabs (lam3) > eps) continue; + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + if (!surfind.Contains (GetSurfaceId(i))) + surfind.Append (GetSurfaceId(i)); + } + +} + + + +INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const +{ + ARRAY point_on_faces; + INSOLID_TYPE res(DOES_INTERSECT); + + 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].nn * v0); // n->nn + + + if (fabs (lam3) > eps) continue; + //(*testout) << "lam3 <= eps" << endl; + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + { + point_on_faces.Append(i); + + double scal = vn * faces[i].nn; // n->nn + + res = DOES_INTERSECT; + if (scal > eps_base1) res = IS_OUTSIDE; + if (scal < -eps_base1) res = IS_INSIDE; + } + } + + //(*testout) << "point_on_faces.Size() " << point_on_faces.Size() + // << " res " << res << endl; + + if (point_on_faces.Size() == 0) + return PointInSolid (p, 0); + if (point_on_faces.Size() == 1) + return res; + + + + + double mindist(0); + bool first = true; + + for(int i=0; i eps && (first || dist < mindist)) + { + mindist = dist; + first = false; + } + } + } + + Point<3> p2 = p + (1e-2*mindist) * vn; + res = PointInSolid (p2, eps); + + // (*testout) << "mindist " << mindist << " res " << res << endl; + + return res; + + +} + + +/* +INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + INSOLID_TYPE res; + + res = VecInSolid(p,v1,eps); + if(res != DOES_INTERSECT) + return res; + + int point_on_n_faces = 0; + + 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; + + cerr << "primitive::vecinsolid2 makes nonsense for polyhedra" << endl; + + return Primitive :: VecInSolid2 (p, v1, v2, eps); +} +*/ + + + +INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + //(*testout) << "VecInSolid2 eps " << eps << endl; + INSOLID_TYPE res = VecInSolid(p,v1,eps); + //(*testout) << "VecInSolid = " < v1n = v1; + v1n.Normalize(); + Vec<3> v2n = v2 - (v2 * v1n) * v1n; + v2n.Normalize(); + + double cosv2, cosv2max = -1; + + + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + if (fabs (faces[i].nn * v0) > eps) continue; // n->nn + if (fabs (v1n * faces[i].nn) > eps_base1) continue; // n->nn + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + { + // v1 is in face + + Point<3> fc = Center (points[faces[i].pnums[0]], + points[faces[i].pnums[1]], + points[faces[i].pnums[2]]); + + Vec<3> vpfc = fc - p; + cosv2 = (v2n * vpfc) / vpfc.Length(); + if (cosv2 > cosv2max) + { + cosv2max = cosv2; + point_on_n_faces++; + + double scal2 = v2n * faces[i].nn; // n->nn + res = DOES_INTERSECT; + if (scal2 > eps_base1) res = IS_OUTSIDE; + if (scal2 < -eps_base1) res = IS_INSIDE; + + } + } + } + + if (point_on_n_faces >= 1) + return res; + + (*testout) << "primitive::vecinsolid2 makes nonsense for polyhedra" << endl; + cerr << "primitive::vecinsolid2 makes nonsense for polyhedra" << endl; + + return Primitive :: VecInSolid2 (p, v1, v2, eps); +} + + + +void Polyhedra :: GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + ARRAY & surfind, double eps) const +{ + Vec<3> v1n = v1; + v1n.Normalize(); + Vec<3> v2n = v2; // - (v2 * v1n) * v1n; + v2n.Normalize(); + + + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + if (fabs (v0 * faces[i].nn) > eps) continue; // n->nn + if (fabs (v1n * faces[i].nn) > eps_base1) continue; // n->nn + if (fabs (v2n * faces[i].nn) > eps_base1) continue; // n->nn + + double lam01 = (faces[i].w1 * v0); + double lam02 = (faces[i].w2 * v0); + double lam03 = 1-lam01-lam02; + double lam11 = (faces[i].w1 * v1); + double lam12 = (faces[i].w2 * v1); + double lam13 = -lam11-lam12; + double lam21 = (faces[i].w1 * v2); + double lam22 = (faces[i].w2 * v2); + double lam23 = -lam21-lam22; + + bool ok1 = lam01 > eps_base1 || + (lam01 > -eps_base1 && lam11 > eps_base1) || + (lam01 > -eps_base1 && lam11 > -eps_base1 && lam21 > eps_base1); + + bool ok2 = lam02 > eps_base1 || + (lam02 > -eps_base1 && lam12 > eps_base1) || + (lam02 > -eps_base1 && lam12 > -eps_base1 && lam22 > eps_base1); + + bool ok3 = lam03 > eps_base1 || + (lam03 > -eps_base1 && lam13 > eps_base1) || + (lam03 > -eps_base1 && lam13 > -eps_base1 && lam23 > eps_base1); + + if (ok1 && ok2 && ok3) + { + if (!surfind.Contains (GetSurfaceId(faces[i].planenr))) + surfind.Append (GetSurfaceId(faces[i].planenr)); + } + } +} + + + + + + + + + + + + +void Polyhedra :: GetPrimitiveData (const char *& classname, + ARRAY & 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 & /* 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) +{ + if(points.Size() == 0) + poly_bbox.Set(p); + else + poly_bbox.Add(p); + + return points.Append (p); +} + +int Polyhedra :: AddFace (int pi1, int pi2, int pi3, int inputnum) +{ + (*testout) << "polyhedra, add face " << pi1 << ", " << pi2 << ", " << pi3 << endl; + + if(pi1 == pi2 || pi2 == pi3 || pi3 == pi1) + { + ostringstream msg; + msg << "Illegal point numbers for polyhedron face: " << pi1+1 << ", " << pi2+1 << ", " << pi3+1; + throw NgException(msg.str()); + } + + faces.Append (Face (pi1, pi2, pi3, points, inputnum)); + + 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-9*max3(v1.Length(),v2.Length(),Dist(p2,p3)))) +// { +// if (!inverse) +// identicto = i; +// } +// // cout << "is identic = " << identicto << endl; +// identicto = -1; // changed April 10, JS + +// 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; + } + +// (*testout) << "is plane nr " << faces.Last().planenr << endl; + + 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; +} + + +void Polyhedra :: GetPolySurfs(ARRAY < ARRAY * > & polysurfs) +{ + int maxnum = -1; + + for(int i = 0; i maxnum) + maxnum = faces[i].inputnr; + } + + polysurfs.SetSize(maxnum+1); + for(int i=0; i; + + for(int i = 0; iAppend(faces[i].planenr); +} + + +void Polyhedra::CalcSpecialPoints (ARRAY > & pts) const +{ + for (int i = 0; i < points.Size(); i++) + pts.Append (points[i]); +} + + +void Polyhedra :: AnalyzeSpecialPoint (const Point<3> & /* pt */, + ARRAY > & /* specpts */) const +{ + ; +} + +Vec<3> Polyhedra :: SpecialPointTangentialVector (const Point<3> & p, int s1, int s2) const +{ + const double eps = 1e-10*poly_bbox.Diam(); + + for (int fi1 = 0; fi1 < faces.Size(); fi1++) + for (int fi2 = 0; fi2 < faces.Size(); fi2++) + { + int si1 = faces[fi1].planenr; + int si2 = faces[fi2].planenr; + + if (surfaceids[si1] != s1 || surfaceids[si2] != s2) continue; + + //(*testout) << "check pair fi1/fi2 " << fi1 << "/" << fi2 << endl; + + Vec<3> n1 = GetSurface(si1) . GetNormalVector (p); + Vec<3> n2 = GetSurface(si2) . GetNormalVector (p); + Vec<3> t = Cross (n1, n2); + + //(*testout) << "t = " << t << endl; + + + /* + int samepts = 0; + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + if (Dist(points[faces[fi1].pnums[j]], + points[faces[fi2].pnums[k]]) < eps) + samepts++; + if (samepts < 2) continue; + */ + + bool shareedge = false; + for(int j = 0; !shareedge && j < 3; j++) + { + Vec<3> v1 = points[faces[fi1].pnums[(j+1)%3]] - points[faces[fi1].pnums[j]]; + double smax = v1.Length(); + v1 *= 1./smax; + + int pospos; + if(fabs(v1(0)) > 0.5) + pospos = 0; + else if(fabs(v1(1)) > 0.5) + pospos = 1; + else + pospos = 2; + + double sp = (p(pospos) - points[faces[fi1].pnums[j]](pospos)) / v1(pospos); + if(sp < -eps || sp > smax+eps) + continue; + + for (int k = 0; !shareedge && k < 3; k ++) + { + Vec<3> v2 = points[faces[fi2].pnums[(k+1)%3]] - points[faces[fi2].pnums[k]]; + v2.Normalize(); + if(v2 * v1 > 0) + v2 -= v1; + else + v2 += v1; + + //(*testout) << "v2.Length2() " << v2.Length2() << endl; + + if(v2.Length2() > 1e-18) + continue; + + double sa,sb; + + sa = (points[faces[fi2].pnums[k]](pospos) - points[faces[fi1].pnums[j]](pospos)) / v1(pospos); + sb = (points[faces[fi2].pnums[(k+1)%3]](pospos) - points[faces[fi1].pnums[j]](pospos)) / v1(pospos); + + + if(Dist(points[faces[fi1].pnums[j]] + sa*v1, points[faces[fi2].pnums[k]]) > eps) + continue; + + if(sa > sb) + { + double aux = sa; sa = sb; sb = aux; + } + + //testout->precision(20); + //(*testout) << "sa " << sa << " sb " << sb << " smax " << smax << " sp " << sp << " v1 " << v1 << endl; + //testout->precision(8); + + + shareedge = (sa < -eps && sb > eps) || + (sa < smax-eps && sb > smax+eps) || + (sa > -eps && sb < smax+eps); + + if(!shareedge) + continue; + + sa = max2(sa,0.); + sb = min2(sb,smax); + + if(sp < sa+eps) + shareedge = (t * v1 > 0); + else if (sp > sb-eps) + shareedge = (t * v1 < 0); + + } + } + if (!shareedge) continue; + + t.Normalize(); + + + return t; + } + + return Vec<3> (0,0,0); +} + + +} + + diff --git a/libsrc/csg/polyhedra.hpp b/libsrc/csg/polyhedra.hpp new file mode 100644 index 00000000..2fcd05d9 --- /dev/null +++ b/libsrc/csg/polyhedra.hpp @@ -0,0 +1,99 @@ +#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; + + int inputnr; + + 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 > & points, + int ainputnr); + }; + + ARRAY > points; + ARRAY faces; + ARRAY planes; + Box<3> poly_bbox; + + double eps_base1; + +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 void GetTangentialSurfaceIndices (const Point<3> & p, + ARRAY & surfind, double eps) const; + + + virtual void GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + ARRAY & surfind, double eps) const; + + virtual void CalcSpecialPoints (ARRAY > & pts) const; + virtual void AnalyzeSpecialPoint (const Point<3> & pt, + ARRAY > & specpts) const; + virtual Vec<3> SpecialPointTangentialVector (const Point<3> & p, int s1, int s2) 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 (const char *& classname, ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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, int inputnum); + + void GetPolySurfs(ARRAY < ARRAY * > & polysurfs); + +protected: + int FaceBoxIntersection (int fnr, const BoxSphere<3> & box) const; + // void CalcData(); +}; + +#endif diff --git a/libsrc/csg/revolution.cpp b/libsrc/csg/revolution.cpp new file mode 100644 index 00000000..4096260c --- /dev/null +++ b/libsrc/csg/revolution.cpp @@ -0,0 +1,904 @@ +#include + +#include +#include + +namespace netgen +{ + void RevolutionFace :: Init(void) + { + const LineSeg<2> * line = dynamic_cast*>(spline); + const SplineSeg3<2> * spline3 = dynamic_cast*>(spline); + + if(line) + { + checklines_start.Append(new Point<2>(line->StartPI())); + checklines_vec.Append(new Vec<2>(line->EndPI() - line->StartPI())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + } + else if (spline3) + { + checklines_start.Append(new Point<2>(spline3->EndPI())); + checklines_start.Append(new Point<2>(spline3->TangentPoint())); + checklines_start.Append(new Point<2>(spline3->StartPI())); + checklines_vec.Append(new Vec<2>(spline3->StartPI() - spline3->EndPI())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + checklines_vec.Append(new Vec<2>(spline3->EndPI() - spline3->TangentPoint())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + checklines_vec.Append(new Vec<2>(spline3->TangentPoint() - spline3->StartPI())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + + } + + for(int i=0; i); + (*checklines_normal.Last())(0) = - (*checklines_vec[i])(1); + (*checklines_normal.Last())(1) = (*checklines_vec[i])(0); + checklines_normal.Last()->Normalize(); + } + } + + RevolutionFace :: RevolutionFace(const SplineSeg<2> & spline_in, + const Point<3> & p, + const Vec<3> & vec, + bool first, + bool last, + const int id_in) : + spline(&spline_in), p0(p), v_axis(vec), isfirst(first), islast(last), id(id_in) + { + deletable = false; + Init(); + } + + + RevolutionFace :: RevolutionFace(const ARRAY & raw_data) + { + deletable = true; + + int pos = 0; + + ARRAY< Point<2> > p(3); + + int stype = int(raw_data[pos]); pos++; + + for(int i=0; i(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1)); + //(*testout) << "appending LineSeg<2> " << p[0] + // << " to " << p[1] << endl; + } + else if(stype == 3) + { + spline = new SplineSeg3<2>(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1), + GeomPoint<2>(p[2],1)); + //(*testout) << "appending SplineSeg<3> " + // << p[0] << " -- " << p[1] << " -- " << p[2] << endl; + } + + for(int i=0; i<3; i++) + { + p0(i) = raw_data[pos]; + pos++; + } + for(int i=0; i<3; i++) + { + v_axis(i) = raw_data[pos]; + pos++; + } + isfirst = (raw_data[pos] > 0.9); + pos++; + islast = (raw_data[pos] < 0.1); + pos++; + + + } + + + RevolutionFace :: ~RevolutionFace() + { + for(int i=0; i & point3d, Point<2> & point2d, + const Vec<3> & vector3d, Vec<2> & vector2d) const + { + Vec<3> pmp0 = point3d-p0; + CalcProj0(pmp0,point2d); + Vec<3> y=pmp0-point2d(0)*v_axis; y.Normalize(); + vector2d(0) = vector3d*v_axis; + vector2d(1) = vector3d*y; + } + + + void RevolutionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d) const + { + Vec<3> pmp0 = point3d-p0; + CalcProj0(pmp0,point2d); + } + + void RevolutionFace :: CalcProj0(const Vec<3> & point3d_minus_p0, Point<2> & point2d) const + { + point2d(0) = point3d_minus_p0 * v_axis; + point2d(1) = sqrt( point3d_minus_p0 * point3d_minus_p0 - point2d(0)*point2d(0) ); + } + + + int RevolutionFace ::IsIdentic (const Surface & s2, int & inv, double eps) const + { + const RevolutionFace * rev2 = dynamic_cast(&s2); + + if(!rev2) return 0; + + if(rev2 == this) + return 1; + + return 0; + } + + double RevolutionFace :: CalcFunctionValue (const Point<3> & point) const + { + if(spline_coefficient.Size() == 0) + spline->GetCoeff(spline_coefficient); + + Point<2> p; + CalcProj(point,p); + + return spline_coefficient(0)*p(0)*p(0) + spline_coefficient(1)*p(1)*p(1) + + spline_coefficient(2)*p(0)*p(1) + spline_coefficient(3)*p(0) + + spline_coefficient(4)*p(1) + spline_coefficient(5); + } + + void RevolutionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + if(spline_coefficient.Size() == 0) + spline->GetCoeff(spline_coefficient); + + Vec<3> point_minus_p0 = point-p0; + + Point<2> p; + CalcProj0(point_minus_p0,p); + + const double dFdxbar = 2.*spline_coefficient(0)*p(0) + spline_coefficient(2)*p(1) + spline_coefficient(3); + + if(fabs(p(1)) > 1e-10) + { + const double dFdybar = 2.*spline_coefficient(1)*p(1) + spline_coefficient(2)*p(0) + spline_coefficient(4); + + grad(0) = dFdxbar*v_axis(0) + dFdybar * ( point_minus_p0(0)-v_axis(0)*p(0) )/p(1); + grad(1) = dFdxbar*v_axis(1) + dFdybar * ( point_minus_p0(1)-v_axis(1)*p(0) )/p(1); + grad(2) = dFdxbar*v_axis(2) + dFdybar * ( point_minus_p0(2)-v_axis(2)*p(0) )/p(1); + //(*testout) << "grad1("< 1e-10) + { + double aux = spline_coefficient(0)-spline_coefficient(1); + + hesse(0,0) = aux*v_axis(0)*v_axis(0) + spline_coefficient(1); + hesse(0,0) = aux*v_axis(1)*v_axis(1) + spline_coefficient(1); + hesse(0,0) = aux*v_axis(2)*v_axis(2) + spline_coefficient(1); + + hesse(0,1) = hesse(1,0) = aux*v_axis(0)*v_axis(1); + hesse(0,2) = hesse(2,0) = aux*v_axis(0)*v_axis(2); + hesse(1,2) = hesse(2,1) = aux*v_axis(1)*v_axis(2); + //(*testout) << "hesse2: " << hesse < 1e-10) + return 2.*max2(fabs(spline_coefficient(0)),fabs(spline_coefficient(1))); + + + double alpha = fabs(spline_coefficient(2)*(spline->StartPI()(0)-spline->EndPI()(0))) / + max2(fabs(spline->StartPI()(1)),fabs(spline->EndPI()(1))); + + return max2(2.*fabs(spline_coefficient(0))+sqrt(2.)*fabs(spline_coefficient(2)), + 2.*fabs(spline_coefficient(1))+spline_coefficient(2)+1.5*alpha); + } + + double RevolutionFace :: MaxCurvature() const + { + double retval = spline->MaxCurvature(); + + ARRAY < Point<2> > checkpoints; + + const SplineSeg3<2> * ss3 = dynamic_cast *>(spline); + const LineSeg<2> * ls = dynamic_cast *>(spline); + + if(ss3) + { + checkpoints.Append(ss3->StartPI()); + checkpoints.Append(ss3->TangentPoint()); + checkpoints.Append(ss3->TangentPoint()); + checkpoints.Append(ss3->EndPI()); + } + else if(ls) + { + checkpoints.Append(ls->StartPI()); + checkpoints.Append(ls->EndPI()); + } + + for(int i=0; i v = checkpoints[i+1]-checkpoints[i]; + Vec<2> n(v(1),-v(0)); n.Normalize(); + + //if(ss3) + // (*testout) << "n " << n << endl; + + if(fabs(n(1)) < 1e-15) + continue; + + double t1 = -checkpoints[i](1)/n(1); + double t2 = -checkpoints[i+1](1)/n(1); + + double c1 = (t1 > 0) ? (1./t1) : -1; + double c2 = (t2 > 0) ? (1./t2) : -1; + + //if(ss3) + // (*testout) << "t1 " << t1 << " t2 " << t2 << " c1 " << c1 << " c2 " << c2 << endl; + + if(c1 > retval) + retval = c1; + if(c2 > retval) + retval = c2; + } + + //if(ss3) + // (*testout) << "curvature " << retval << endl; + + return retval; + + /* + + + // find smallest y value of spline: + ARRAY testt; + + if(!isfirst) + testt.Append(0); + if(!islast) + testt.Append(1); + + const SplineSegment3 * s3 = dynamic_cast(&spline); + + if(s3) + { + double denom = (2.-sqrt(2.))*(s3->EndPI()(1) - s3->StartPI()(1)); + + if(fabs(denom) < 1e-20) + testt.Append(0.5); + else + { + double sD = sqrt(pow(s3->TangentPoint()(1) - s3->StartPI()(1),2)+ + pow(s3->TangentPoint()(1) - s3->EndPI()(1),2)); + testt.Append((s3->StartPI()(1)*(sqrt(2.)-1.) - sqrt(2.)*s3->TangentPoint()(1) + s3->EndPI()(1) + sD)/denom); + testt.Append((s3->StartPI()(1)*(sqrt(2.)-1.) - sqrt(2.)*s3->TangentPoint()(1) + s3->EndPI()(1) - sD)/denom); + } + } + + double miny = fabs(spline.GetPoint(testt[0])(1)); + for(int i=1; i & p) const + { + Point<2> p2d; + + CalcProj(p,p2d); + + const Vec<3> y = (p-p0)-p2d(0)*v_axis; + const double yl = y.Length(); + + double dummy; + + spline->Project(p2d,p2d,dummy); + + p = p0 + p2d(0)*v_axis; + + if(yl > 1e-20*Dist(spline->StartPI(),spline->EndPI())) + p+= (p2d(1)/yl)*y; + } + + + + + Point<3> RevolutionFace :: GetSurfacePoint () const + { + Vec<3> random_vec(0.760320,-0.241175,0.60311534); + + Vec<3> n = Cross(v_axis,random_vec); n.Normalize(); + + Point<2> sp = spline->GetPoint(0.5); + + Point<3> retval = p0 + sp(0)*v_axis + sp(1)*n; + + return retval; + } + + + void RevolutionFace :: Print (ostream & str) const + { + if(spline_coefficient.Size() == 0) + spline->GetCoeff(spline_coefficient); + + str << p0(0) << " " << p0(1) << " " << p0(2) << " " + << v_axis(0) << " " << v_axis(1) << " " << v_axis(2) << " "; + for(int i=0; i<6; i++) str << spline_coefficient(i) << " "; + str << endl; + } + + + void RevolutionFace :: GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const + { + Vec<3> random_vec(0.760320,-0.241175,0.60311534); + + Vec<3> v1 = Cross(v_axis,random_vec); v1.Normalize(); + Vec<3> v2 = Cross(v1,v_axis); v2.Normalize(); + + int n = int(2.*facets) + 1; + + int i,j; + double phi; + Point<3> p; + + for(i=0; i<=n; i++) + { + Point<2> sp = spline->GetPoint(double(i)/double(n)); + for(j=0; j<=n; j++) + { + phi = 2.*M_PI*double(j)/double(n); + + p = p0 + sp(0)*v_axis + sp(1)*cos(phi)*v1 + sp(1)*sin(phi)*v2; + tas.AddPoint(p); + } + } + + for(i=0; i & box) const + { + Point<3> center = box.Center(); + + Project(center); + + return (Dist(box.Center(),center) < 0.5*box.Diam()); + } + + + /* + bool RevolutionFace :: BoxIntersectsFace (const BoxSphere<3> & box, bool & uncertain) const + { + Point<2> c,pmin,pmax; + CalcProj(box.Center(),c); + double aux = box.Diam()/sqrt(8.); + pmin(0) = c(0)-aux; pmin(1) = c(1)-aux; + pmax(0) = c(0)+aux; pmax(1) = c(1)+aux; + + BoxSphere<2> box2d(pmin,pmax); + return BoxIntersectsFace(box2d, uncertain); + } + + bool RevolutionFace :: BoxIntersectsFace (const BoxSphere<2> & box, bool & uncertain) const + { + const LineSegment * line = dynamic_cast(&spline); + const SplineSegment3 * spline3 = dynamic_cast(&spline); + + bool always_right = true, always_left = true; + + bool retval = false; + bool thisint; + bool intdirect = false; + bool inttangent = false; + uncertain = false; + + if(line) inttangent = true; + + for(int i=0; i b = box.Center()- (*checklines_start[i]); + + double d; + + double checkdist = b * (*checklines_vec[i]); + double ncomp = b * (*checklines_normal[i]); + + if(checkdist < 0) + d = b.Length(); + else if (checkdist > 1) + { + if(spline3) + d = Dist(box.Center(),*checklines_start[(i+1)%3]); + else + d = Dist(box.Center(),(*checklines_start[i]) + + pow(checklines_vec[i]->Length(),2)*(*checklines_vec[i])); + } + else + d = fabs(ncomp); + + thisint = (box.Diam() >= 2.*d); + retval = retval || thisint; + if(thisint) + { + if(i==0) + intdirect = true; + else + inttangent = true; + } + + if(ncomp > 0) always_right = false; + else if(ncomp < 0) always_left = false; + } + + if(retval && !(intdirect && inttangent)) + uncertain = true; + + if(!retval && spline3 && (always_right || always_left)) + { + retval = true; + uncertain = true; + } + + return retval; + } + */ + + + INSOLID_TYPE RevolutionFace :: PointInFace (const Point<3> & p, const double eps) const + { + Point<2> p2d; + CalcProj(p,p2d); + + double val = spline_coefficient(0)*p2d(0)*p2d(0) + spline_coefficient(1)*p2d(1)*p2d(1) + spline_coefficient(2)*p2d(0)*p2d(1) + + spline_coefficient(3)*p2d(0) + spline_coefficient(4)*p2d(1) + spline_coefficient(5); + + if(val > eps) + return IS_OUTSIDE; + if(val < -eps) + return IS_INSIDE; + + return DOES_INTERSECT; + } + + + + void RevolutionFace :: GetRawData(ARRAY & data) const + { + data.DeleteAll(); + spline->GetRawData(data); + for(int i=0; i<3; i++) + data.Append(p0(i)); + for(int i=0; i<3; i++) + data.Append(v_axis(i)); + data.Append((isfirst) ? 1. : 0.); + data.Append((islast) ? 1. : 0.); + } + + + + Revolution :: Revolution(const Point<3> & p0_in, + const Point<3> & p1_in, + const SplineGeometry2d & spline_in) : + p0(p0_in), p1(p1_in), splinecurve(spline_in), + nsplines(spline_in.GetNSplines()) + { + surfaceactive.SetSize(0); + surfaceids.SetSize(0); + + v_axis = p1-p0; + + v_axis.Normalize(); + + if(splinecurve.GetSpline(0).StartPI()(1) <= 0. && + splinecurve.GetSpline(nsplines-1).EndPI()(1) <= 0.) + type = 2; + else if (Dist(splinecurve.GetSpline(0).StartPI(), + splinecurve.GetSpline(nsplines-1).EndPI()) < 1e-7) + type = 1; + else + cerr << "Surface of revolution cannot be constructed" << endl; + + for(int i=0; i & box) const + { + for(int i=0; iBoxIntersectsFace(box)) + return DOES_INTERSECT; + + + return PointInSolid(box.Center(),0); + + + /* + Point<2> c,pmin,pmax; + faces[0]->CalcProj(box.Center(),c); + double aux = box.Diam()/sqrt(8.); + pmin(0) = c(0)-aux; pmin(1) = c(1)-aux; + pmax(0) = c(0)+aux; pmax(1) = c(1)+aux; + + + BoxSphere<2> box2d(pmin,pmax); + + bool intersection = false; + bool uncertain = true; + + for(int i=0; !(intersection && !uncertain) && iBoxIntersectsFace(box2d,thisuncertain); + intersection = intersection || thisintersects; + if(thisintersects && !thisuncertain) + uncertain = false; + } + + if(intersection) + { + if(!uncertain) + return DOES_INTERSECT; + else + { + ARRAY < Point<3> > pext(2); + Point<3> p; + + pext[0] = box.PMin(); + pext[1] = box.PMax(); + + INSOLID_TYPE position; + bool firsttime = true; + + for(int i=0; i<2; i++) + for(int j=0; j<2; j++) + for(int k=0; k<2; k++) + { + p(0) = pext[i](0); + p(1) = pext[j](1); + p(2) = pext[k](2); + INSOLID_TYPE ppos = PointInSolid(p,0); + if(ppos == DOES_INTERSECT) + return DOES_INTERSECT; + + if(firsttime) + { + firsttime = false; + position = ppos; + } + if(position != ppos) + return DOES_INTERSECT; + } + return position; + + } + } + + return PointInSolid(box.Center(),0); + */ + } + + INSOLID_TYPE Revolution :: PointInSolid (const Point<3> & p, + double eps) const + { + Point<2> p2d; + faces[0]->CalcProj(p,p2d); + + int intersections_before(0), intersections_after(0); + double randomx = 7.42357; + double randomy = 1.814756; + randomx *= 1./sqrt(randomx*randomx+randomy*randomy); + randomy *= 1./sqrt(randomx*randomx+randomy*randomy); + + + const double a = randomy; + const double b = -randomx; + const double c = -a*p2d(0)-b*p2d(1); + + ARRAY < Point<2> > points; + + //(*testout) << "face intersections at: " << endl; + for(int i=0; iGetSpline().LineIntersections(a,b,c,points,eps); + + for(int j=0; j eps ) + intersections_after++; + else + { + intersecting_face = i; + return DOES_INTERSECT; + } + } + } + + if(intersections_before % 2 == 0) + return IS_OUTSIDE; + else + return IS_INSIDE; + } + + INSOLID_TYPE Revolution :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const + { + INSOLID_TYPE pInSolid = PointInSolid(p,eps); + + if(pInSolid != DOES_INTERSECT) + { + //(*testout) << "pInSolid" << endl; + return pInSolid; + } + + ARRAY intersecting_faces; + + for(int i=0; iPointInFace(p,eps) == DOES_INTERSECT) + intersecting_faces.Append(i); + + Vec<3> hv; + + if(intersecting_faces.Size() == 1) + { + faces[intersecting_faces[0]]->CalcGradient(p,hv); + + double hv1; + hv1 = v * hv; + + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + return DOES_INTERSECT; + } + else if(intersecting_faces.Size() == 2) + { + Point<2> p2d; + Vec<2> v2d; + faces[intersecting_faces[0]]->CalcProj(p,p2d,v,v2d); + + if(Dist(faces[intersecting_faces[0]]->GetSpline().StartPI(),p2d) < + Dist(faces[intersecting_faces[0]]->GetSpline().EndPI(),p2d)) + { + int aux = intersecting_faces[0]; + intersecting_faces[0] = intersecting_faces[1]; + intersecting_faces[1] = aux; + } + + const SplineSeg3<2> * splinesegment3 = + dynamic_cast *>(&faces[intersecting_faces[0]]->GetSpline()); + const LineSeg<2> * linesegment = + dynamic_cast *>(&faces[intersecting_faces[0]]->GetSpline()); + + Vec<2> t1,t2; + + if(linesegment) + t1 = linesegment->StartPI() - linesegment->EndPI(); + else if(splinesegment3) + t1 = splinesegment3->TangentPoint() - splinesegment3->EndPI(); + + linesegment = + dynamic_cast *>(&faces[intersecting_faces[1]]->GetSpline()); + splinesegment3 = + dynamic_cast *>(&faces[intersecting_faces[1]]->GetSpline()); + + if(linesegment) + t2 = linesegment->EndPI() - linesegment->StartPI(); + else if(splinesegment3) + t2 = splinesegment3->TangentPoint() - splinesegment3->StartPI(); + + t1.Normalize(); + t2.Normalize(); + + double d1 = v2d*t1; + double d2 = v2d*t2; + + Vec<2> n; + + if(d1 > d2) + { + n(0) = t1(1); + n(1) = -t1(0); + } + else + { + n(0) = -t2(1); + n(1) = t2(0); + } + + double d = v2d*n; + + if(d > eps) + return IS_OUTSIDE; + else if (d < -eps) + return IS_INSIDE; + else + return DOES_INTERSECT; + + + } + else + { + cerr << "Jo gibt's denn des?" << endl; + } + + return DOES_INTERSECT; + } + + INSOLID_TYPE Revolution :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const + { + INSOLID_TYPE ret1 = VecInSolid(p,v1,eps); + if(ret1 != DOES_INTERSECT) + return ret1; + + return VecInSolid(p,v2,eps); + } + + int Revolution :: GetNSurfaces() const + { + return faces.Size(); + } + + Surface & Revolution :: GetSurface (int i) + { + return *faces[i]; + } + + const Surface & Revolution :: GetSurface (int i) const + { + return *faces[i]; + } + + + void Revolution :: Reduce (const BoxSphere<3> & box) + { + //bool dummy; + for(int i=0; iBoxIntersectsFace(box)); + //surfaceactive[i] = (faces[i]->BoxIntersectsFace(box,dummy)); + } + + void Revolution :: UnReduce () + { + for(int i=0; i * spline; + bool deletable; + + Point<3> p0; + Vec<3> v_axis; + + int id; + + mutable Vector spline_coefficient; + + + ARRAY < Vec<2>* > checklines_vec; + ARRAY < Point<2>* > checklines_start; + ARRAY < Vec<2>* > checklines_normal; + +private: + void Init (void); + +public: + void CalcProj(const Point<3> & point3d, Point<2> & point2d) const; + void CalcProj(const Point<3> & point3d, Point<2> & point2d, + const Vec<3> & vector3d, Vec<2> & vector2d) const; + void CalcProj0(const Vec<3> & point3d_minus_p0, Point<2> & point2d) const; + +public: + RevolutionFace(const SplineSeg<2> & spline_in, + const Point<3> & p, + const Vec<3> & vec, + bool first = false, + bool last = false, + const int id_in = 0); + + RevolutionFace(const ARRAY & raw_data); + + ~RevolutionFace(); + + 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 double MaxCurvature () const; + //virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + // double /* rad */) const; + + virtual void Project (Point<3> & p) const; + + virtual Point<3> GetSurfacePoint () const; + virtual void Print (ostream & str) const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const; + + bool BoxIntersectsFace (const Box<3> & box) const; + /* + bool BoxIntersectsFace (const BoxSphere<2> & box, bool & uncertain) const; + bool BoxIntersectsFace (const BoxSphere<3> & box, bool & uncertain) const; + */ + + const SplineSeg<2> & GetSpline(void) const {return *spline;} + + INSOLID_TYPE PointInFace (const Point<3> & p, const double eps) const; + + void GetRawData(ARRAY & data) const; + +}; + + + +/* + + Primitive of revolution + +*/ + + +class Revolution : public Primitive +{ +private: + Point<3> p0,p1; + Vec<3> v_axis; + const SplineGeometry2d & splinecurve; + const int nsplines; + + // 1 ... torus-like + // 2 ... sphere-like + int type; + + + ARRAY faces; + + mutable int intersecting_face; + +public: + Revolution(const Point<3> & p0_in, + const Point<3> & p1_in, + const SplineGeometry2d & spline_in); + + ~Revolution(); + + + /* + 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; + 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; + virtual Surface & GetSurface (int i = 0); + virtual const Surface & GetSurface (int i = 0) const; + + + virtual void Reduce (const BoxSphere<3> & box); + virtual void UnReduce (); + + +}; + + + +#endif diff --git a/libsrc/csg/singularref.cpp b/libsrc/csg/singularref.cpp new file mode 100644 index 00000000..4fbfdeef --- /dev/null +++ b/libsrc/csg/singularref.cpp @@ -0,0 +1,217 @@ +#include +#include + +#include +#include +#include + +namespace netgen +{ + + SingularEdge :: SingularEdge (double abeta, int adomnr, + const CSGeometry & ageom, + const Solid * asol1, + const Solid * asol2, double sf, + const double maxh_at_initialization) + : geom(ageom), domnr(adomnr) + { + beta = abeta; + maxhinit = maxh_at_initialization; + + 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; + factor = sf; +} + +void SingularEdge :: FindPointsOnEdge (class Mesh & mesh) +{ + (*testout) << "find points on edge" << endl; + points.SetSize(0); + segms.SetSize(0); + + + ARRAY si1, si2; + sol1->GetSurfaceIndices (si1); + sol2->GetSurfaceIndices (si2); + + for (int i = 0; i < si1.Size(); i++) + si1[i] = geom.GetSurfaceClassRepresentant(si1[i]); + for (int i = 0; i < si2.Size(); i++) + si2[i] = geom.GetSurfaceClassRepresentant(si2[i]); + + + 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 (domnr != -1 && domnr != mesh[si].domin && domnr != mesh[si].domout) + continue; + + /* + bool onedge = 1; + for (int j = 0; j < 2; j++) + { + int surfi = (j == 0) ? mesh[si].surfnr1 : mesh[si].surfnr2; + surfi = geom.GetSurfaceClassRepresentant(surfi); + if (!si1.Contains(surfi) && !si2.Contains(surfi)) + onedge = 0; + } + */ + int surfi1 = geom.GetSurfaceClassRepresentant(mesh[si].surfnr1); + int surfi2 = geom.GetSurfaceClassRepresentant(mesh[si].surfnr2); + + if (si1.Contains(surfi1) && si2.Contains(surfi2) || + si1.Contains(surfi2) && si2.Contains(surfi1)) + + // 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 = factor; + mesh[si].singedge_right = factor; + } + } + + /* + (*testout) << "Singular edge 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); + if(maxhinit > 0 && maxhinit < hloc) + { + hloc = maxhinit; + if(points.Size() > 1) + { + for (int i = 0; i < points.Size()-1; i++) + mesh.RestrictLocalHLine(points[i],points[i+1],hloc); + } + else + { + for (int i = 0; i < points.Size(); i++) + mesh.RestrictLocalH (points[i], hloc); + } + } + else + { + 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, double sf) +{ + beta = abeta; + sol1 = asol1; + sol2 = asol2; + sol3 = asol3; + factor = sf; +} + + +void SingularPoint :: FindPoints (class Mesh & mesh) +{ + points.SetSize(0); + ARRAY surfk, surf; + + + for (PointIndex pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + { + if (mesh[pi].Type() != FIXEDPOINT) continue; + const Point<3> p = mesh[pi]; + + (*testout) << "check singular point" << p << endl; + + if (sol1->IsIn (p) && sol2->IsIn(p) && sol3->IsIn(p) && + !sol1->IsStrictIn (p) && !sol2->IsStrictIn(p) && !sol3->IsStrictIn(p)) + { + surf.SetSize (0); + for (int k = 1; k <= 3; k++) + { + const Solid * solk(NULL); + Solid *tansol; + switch (k) + { + case 1: solk = sol1; break; + case 2: solk = sol2; break; + case 3: solk = sol3; break; + } + + solk -> TangentialSolid (p, tansol, surfk, 1e-3); + (*testout) << "Tansol = " << *tansol << endl; + + if (!tansol) continue; + + ReducePrimitiveIterator rpi(Box<3> (p-Vec<3> (1e-3,1e-3,1e-3), + p+Vec<3> (1e-3,1e-3,1e-3))); + UnReducePrimitiveIterator urpi; + + tansol -> IterateSolid (rpi); + tansol->GetSurfaceIndices (surfk); + tansol -> IterateSolid (urpi); + + (*testout) << "surfinds = " << surfk << endl; + + for (int i = 0; i < surfk.Size(); i++) + if (!surf.Contains (surfk[i])) + surf.Append (surfk[i]); + + delete tansol; + } + + if (surf.Size() < 3) continue; + + points.Append (p); + PrintMessage (5, "Point (", p(0), ", ", p(1), ", ", p(2), ") is singular"); + mesh[pi].Singularity(factor); + } + } +} + + +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/libsrc/csg/singularref.hpp b/libsrc/csg/singularref.hpp new file mode 100644 index 00000000..a0c72833 --- /dev/null +++ b/libsrc/csg/singularref.hpp @@ -0,0 +1,78 @@ +#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; + double factor; + // ARRAY > points; + // ARRAY segms; +public: + SingularFace (int adomnr, const Solid * asol, double sf) + : domnr(adomnr), sol(asol), factor(sf) { ; } + const Solid * GetSolid() const { return sol; } + int GetDomainNr () const { return domnr; } +}; + + +/// +class SingularEdge +{ +public: + double beta; + int domnr; + const CSGeometry& geom; + const Solid *sol1, *sol2; + ARRAY > points; + ARRAY segms; + double factor; + + double maxhinit; +public: + SingularEdge (double abeta, int adomnr, + const CSGeometry & ageom, + const Solid * asol1, const Solid * asol2, double sf, + const double maxh_at_initialization = -1); + void FindPointsOnEdge (class Mesh & mesh); + void SetMeshSize (class Mesh & mesh, double globalh); +}; + + +/// +class SingularPoint +{ +public: + double beta; + const Solid *sol1, *sol2, *sol3; + ARRAY > points; + double factor; + +public: + SingularPoint (double abeta, const Solid * asol1, const Solid * asol2, + const Solid * asol3, double sf); + void FindPoints (class Mesh & mesh); + void SetMeshSize (class Mesh & mesh, double globalh); +}; + + +#endif diff --git a/libsrc/csg/solid.cpp b/libsrc/csg/solid.cpp new file mode 100644 index 00000000..8c7cf9cd --- /dev/null +++ b/libsrc/csg/solid.cpp @@ -0,0 +1,1716 @@ +#include + +#include +#include + + +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(NULL); + 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) ? true : false; + } + 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) != IS_OUTSIDE); // Is this correct???? + 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 & solids); + static Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE & solids); + static Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE & 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 & 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; + for (int i = int(strlen(str))-1; i >= 0; i--) + ist.putback (str[i]); + + return s1; + } + + Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE & 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; + for (int i = int(strlen(str))-1; i >= 0; i--) + ist.putback (str[i]); + + return s1; + } + + Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE & 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 & 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 & bounds) const + { + int in, strin; + bounds.SetSize (0); + RecBoundaries (p, bounds, in, strin); + } + + void Solid :: RecBoundaries (const Point<3> & p, ARRAY & 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 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 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, ARRAY & surfids, double eps) const + { + int in, strin; + RecTangentialSolid (p, tansol, surfids, in, strin, eps); + surfids.SetSize (0); + if (tansol) + tansol -> GetTangentialSurfaceIndices (p, surfids, eps); + } + + + void Solid :: RecTangentialSolid (const Point<3> & p, Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + + 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, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid (p, tansol2, surfids, in2, strin2, eps); + + 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, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid (p, tansol2, surfids, in2, strin2, eps); + + 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, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialSolid (p, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + void Solid :: TangentialSolid2 (const Point<3> & p, + const Vec<3> & t, + Solid *& tansol, ARRAY & surfids, double eps) const + { + int in, strin; + surfids.SetSize (0); + RecTangentialSolid2 (p, t, tansol, surfids, in, strin, eps); + if (tansol) + tansol -> GetTangentialSurfaceIndices2 (p, t, surfids, eps); + } + + void Solid :: RecTangentialSolid2 (const Point<3> & p, const Vec<3> & t, + Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) 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, eps); + if (ist == DOES_INTERSECT) + ist = prim->VecInSolid (p, t, eps); + + 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, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid2 (p, t, tansol2, surfids, in2, strin2, eps); + + 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, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid2 (p, t, tansol2, surfids, in2, strin2, eps); + + 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, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialSolid2 (p, t, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + + + + + void Solid :: TangentialSolid3 (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, + Solid *& tansol, ARRAY & surfids, + double eps) const + { + int in, strin; + surfids.SetSize (0); + RecTangentialSolid3 (p, t, t2, tansol, surfids, in, strin, eps); + + if (tansol) + tansol -> GetTangentialSurfaceIndices3 (p, t, t2, surfids, eps); + } + + void Solid :: RecTangentialSolid3 (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, + Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + + if (ist == DOES_INTERSECT) + { + //(*testout) << "Calling VecInSolid3..." << endl; + ist = prim->VecInSolid3 (p, t, t2, eps); + //(*testout) << "...done" << endl; + } + 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 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid3 (p, t, t2, tansol2, surfids, in2, strin2, eps); + + 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 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid3 (p, t, t2, tansol2, surfids, in2, strin2, eps); + + 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 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialSolid3 (p, t, t2, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + + + + + + + + void Solid :: TangentialEdgeSolid (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, const Vec<3> & m, + Solid *& tansol, ARRAY & surfids, + double eps) const + { + int in, strin; + surfids.SetSize (0); + + // *testout << "tangentialedgesolid,sol = " << (*this) << endl; + RecTangentialEdgeSolid (p, t, t2, m, tansol, surfids, in, strin, eps); + + if (tansol) + tansol -> RecGetTangentialEdgeSurfaceIndices (p, t, t2, m, surfids, eps); + } + + void Solid :: RecTangentialEdgeSolid (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, const Vec<3> & m, + Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + + /* + (*testout) << "tangedgesolid, p = " << p << ", t = " << t + << " for prim " << typeid (*prim).name() + << " with surf " << prim->GetSurface() << endl; + (*testout) << "ist = " << ist << endl; + */ + + if (ist == DOES_INTERSECT) + ist = prim->VecInSolid4 (p, t, t2, m, eps); + + // (*testout) << "ist2 = " << ist << endl; + + 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 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialEdgeSolid (p, t, t2, m, tansol2, surfids, in2, strin2, eps); + + 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 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialEdgeSolid (p, t, t2, m, tansol2, surfids, in2, strin2, eps); + + 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 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + + + + + + + + + + + + + int Solid :: Edge (const Point<3> & p, const Vec<3> & v, double eps) const + { + int in, strin, faces; + RecEdge (p, v, in, strin, faces, eps); + return faces >= 2; + } + + int Solid :: OnFace (const Point<3> & p, const Vec<3> & v, double eps) const + { + int in, strin, faces; + RecEdge (p, v, in, strin, faces, eps); + return faces >= 1; + } + + + void Solid :: RecEdge (const Point<3> & p, const Vec<3> & v, + int & in, int & strin, int & faces, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->VecInSolid (p, v, eps); + 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) < eps && 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, eps); + s2 -> RecEdge (p, v, in2, strin2, faces2, eps); + + 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, eps); + s2 -> RecEdge (p, v, in2, strin2, faces2, eps); + + 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, eps); + in = !strin1; + strin = !in1; + break; + } + case ROOT: + { + s1 -> RecEdge (p, v, in, strin, faces, eps); + break; + } + } + } + + + void Solid :: CalcSurfaceInverse () + { + CalcSurfaceInverseRec (0); + } + + void Solid :: CalcSurfaceInverseRec (int inv) + { + switch (op) + { + case TERM: case TERM_REF: + { + bool priminv; + for (int i = 0; i < prim->GetNSurfaces(); i++) + { + priminv = (prim->SurfaceInverted(i) != 0); + if (inv) priminv = !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; + } + } + + /* + if (redsol) + (*testout) << "getrecsolid, redsol = " << endl << (*redsol) << endl; + else + (*testout) << "redsol is null" << endl; + */ + + 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 & surfind) const + { + surfind.SetSize (0); + RecGetSurfaceIndices (surfind); + } + + void Solid :: RecGetSurfaceIndices (ARRAY & 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 :: GetTangentialSurfaceIndices (const Point<3> & p, ARRAY & surfind, double eps) const + { + surfind.SetSize (0); + RecGetTangentialSurfaceIndices (p, surfind, eps); + } + + void Solid :: RecGetTangentialSurfaceIndices (const Point<3> & p, ARRAY & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + /* + for (int j = 0; j < prim->GetNSurfaces(); j++) + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + */ + prim->GetTangentialSurfaceIndices (p, surfind, eps); + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialSurfaceIndices (p, surfind, eps); + s2 -> RecGetTangentialSurfaceIndices (p, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialSurfaceIndices (p, surfind, eps); + break; + } + } + } + + + + + + + void Solid :: GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, + ARRAY & surfind, double eps) const + { + surfind.SetSize (0); + RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + } + + void Solid :: RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, + ARRAY & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + for (int j = 0; j < prim->GetNSurfaces(); j++) + { + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + prim->GetSurface(j).CalcGradient (p, grad); + if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2()) + { + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + } + } + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + s2 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + break; + } + } + } + + + + + + + + + void Solid :: GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + ARRAY & surfind, double eps) const + { + surfind.SetSize (0); + RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + } + + void Solid :: RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + ARRAY & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + for (int j = 0; j < prim->GetNSurfaces(); j++) + { + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + prim->GetSurface(j).CalcGradient (p, grad); + if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2()) + { + // (*testout) << "p2" << endl; + Mat<3> hesse; + prim->GetSurface(j).CalcHesse (p, hesse); + double hv2 = v2 * grad + v * (hesse * v); + + if (fabs (hv2) < 1e-6) + { + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + } + } + } + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + s2 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + break; + } + } + } + + + + + + void Solid :: RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m, + ARRAY & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + // *testout << "check vecinsolid4, p = " << p << ", v = " << v << "; m = " << m << endl; + if (prim->VecInSolid4 (p, v, v2, m, eps) == DOES_INTERSECT) + { + prim->GetTangentialVecSurfaceIndices2 (p, v, m, surfind, eps); + /* + for (int j = 0; j < prim->GetNSurfaces(); j++) + { + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + prim->GetSurface(j).CalcGradient (p, grad); + *testout << "grad = " << grad << endl; + if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2() && + sqr (grad * m) < 1e-6 * m.Length2() * grad.Length2() ) // new, 18032006 JS + + { + *testout << "add surf " << prim->GetSurfaceId(j) << endl; + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + } + } + } + */ + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps); + s2 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps); + 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; + } + } + } + + + void Solid :: CalcOnePrimitiveSpecialPoints (const Box<3> & box, ARRAY > & pts) const + { + double eps = 1e-8 * box.Diam (); + + pts.SetSize (0); + this -> RecCalcOnePrimitiveSpecialPoints (pts); + for (int i = pts.Size()-1; i >= 0; i--) + { + if (!IsIn (pts[i],eps) || IsStrictIn (pts[i],eps)) + pts.Delete (i); + } + } + + void Solid :: RecCalcOnePrimitiveSpecialPoints (ARRAY > & pts) const + { + switch (op) + { + case TERM: case TERM_REF: + { + prim -> CalcSpecialPoints (pts); + break; + } + case UNION: + case SECTION: + { + s1 -> RecCalcOnePrimitiveSpecialPoints (pts); + s2 -> RecCalcOnePrimitiveSpecialPoints (pts); + break; + } + case SUB: + case ROOT: + { + s1 -> RecCalcOnePrimitiveSpecialPoints (pts); + break; + } + } + } + + + + + BlockAllocator Solid :: ball(sizeof (Solid)); +} diff --git a/libsrc/csg/solid.hpp b/libsrc/csg/solid.hpp new file mode 100644 index 00000000..cae1a554 --- /dev/null +++ b/libsrc/csg/solid.hpp @@ -0,0 +1,241 @@ +#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 & bounds) const; + int NumPrimitives () const; + void GetSurfaceIndices (ARRAY & surfind) const; + void GetSurfaceIndices (IndexSet & iset) const; + + void GetTangentialSurfaceIndices (const Point<3> & p, ARRAY & surfids, double eps) const; + void GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, ARRAY & surfids, double eps) const; + void GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, ARRAY & surfids, double eps) 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) const; + bool VectorIn2Rec (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + double eps) const; + + + /// compute localization in point p + void TangentialSolid (const Point<3> & p, Solid *& tansol, ARRAY & surfids, double eps) const; + + /// compute localization in point p tangential to vector t + void TangentialSolid2 (const Point<3> & p, const Vec<3> & t, + Solid *& tansol, ARRAY & surfids, double eps) const; + + /** compute localization in point p, with second order approximation to edge + p + s t + s*s/2 t2 **/ + void TangentialSolid3 (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2, + Solid *& tansol, ARRAY & surfids, double eps) const; + + + + /** tangential solid, which follows the edge + p + s t + s*s/2 t2 + with second order, and the neighbouring face + p + s t + s*s/2 t2 + r m + with first order + **/ + void TangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2, + const Vec<3> & m, + Solid *& tansol, ARRAY & surfids, double eps) const; + + + void CalcOnePrimitiveSpecialPoints (const Box<3> & box, ARRAY > & pts) const; + + /// + int Edge (const Point<3> & p, const Vec<3> & v, double eps) const; + /// + int OnFace (const Point<3> & p, const Vec<3> & v, double eps) 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 & 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 & bounds, + int & in, int & strin) const; + /// + void RecTangentialSolid (const Point<3> & p, Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const; + + void RecTangentialSolid2 (const Point<3> & p, const Vec<3> & vec, + Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const; + /// + void RecTangentialSolid3 (const Point<3> & p, const Vec<3> & vec,const Vec<3> & vec2, + Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const; + /// + void RecTangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2, + const Vec<3> & m, + Solid *& tansol, ARRAY & surfids, + int & in, int & strin, double eps) const; + + /// + void RecEdge (const Point<3> & p, const Vec<3> & v, + int & in, int & strin, int & faces, double eps) const; + /// + void CalcSurfaceInverseRec (int inv); + /// + Solid * RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const; + /// + void RecGetSurfaceIndices (ARRAY & surfind) const; + void RecGetTangentialSurfaceIndices (const Point<3> & p, ARRAY & surfids, double eps) const; + void RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, ARRAY & surfids, double eps) const; + void RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + ARRAY & surfids, double eps) const; + void RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m, + ARRAY & surfids, double eps) const; + void RecGetSurfaceIndices (IndexSet & iset) const; + + void RecCalcOnePrimitiveSpecialPoints (ARRAY > & pts) 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/libsrc/csg/specpoin.cpp b/libsrc/csg/specpoin.cpp new file mode 100644 index 00000000..a6cc9b26 --- /dev/null +++ b/libsrc/csg/specpoin.cpp @@ -0,0 +1,1794 @@ +#include +#include +#include + + +/* + 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 +*/ + + +#undef DEVELOP +//#define DEVELOP + + +namespace netgen +{ + ARRAY > boxes; + + + 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; + s1_orig = sp.s1_orig; + s2_orig = sp.s2_orig; + layer = sp.layer; + unconditional = sp.unconditional; + } + + SpecialPoint & SpecialPoint :: operator= (const SpecialPoint & sp) + { + p = sp.p; + v = sp.v; + s1 = sp.s1; + s2 = sp.s2; + s1_orig = sp.s1_orig; + s2_orig = sp.s2_orig; + layer = sp.layer; + unconditional = sp.unconditional; + return *this; + } + + + void SpecialPoint :: Print (ostream & str) const + { + str << "p = " << p << " v = " << v + << " s1/s2 = " << s1 << "/" << s2; + str << " layer = " << layer + << " unconditional = " << unconditional + << endl; + } + + + static ARRAY numprim_hist; + + SpecialPointCalculation :: SpecialPointCalculation () + { + ideps = 1e-9; + } + + void SpecialPointCalculation :: + CalcSpecialPoints (const CSGeometry & ageometry, + ARRAY & 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; + + if (tlo->GetSolid()) + { + ARRAY > hpts; + tlo->GetSolid()->CalcOnePrimitiveSpecialPoints (box, hpts); + // if (hpts.Size()) + // cout << "oneprimitivespecialpoints = " << hpts << endl; + for (int j = 0; j < hpts.Size(); j++) + AddPoint (hpts[j], tlo->GetLayer()); + } + + CalcSpecialPointsRec (tlo->GetSolid(), tlo->GetLayer(), + box, 1, 1, 1); + } + + + geometry->DeleteIdentPoints(); + for (int i = 0; i < geometry->GetNIdentifications(); i++) + { + CloseSurfaceIdentification * ident = + dynamic_cast(geometry->identifications[i]); + + if(!ident || !ident->IsSkewIdentification()) + continue; + + for(int j=0; jSize(); j++) + { + if(fabs(ident->GetSurface1().CalcFunctionValue((*points)[j])) < 1e-15) + { + Point<3> auxpoint = (*points)[j]; + ident->GetSurface2().SkewProject(auxpoint,ident->GetDirection()); + geometry->AddIdentPoint(auxpoint); + geometry->AddIdentPoint((*points)[j]); + AddPoint (auxpoint,1); + +#ifdef DEVELOP + (*testout) << "added identpoint " << auxpoint << "; proj. of " + << (*points)[j] << endl; +#endif + break; + } + } + } + + + // 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) + { + // boxes.Append (box); + +#ifdef DEVELOP + *testout << "lev " << level << ", box = " << box << endl; + *testout << "calccp = " << calccp << ", calcep = " << calcep << endl; + *testout << "locsol = " << *sol << endl; +#endif + + if (multithread.terminate) + { + *testout << "boxes = " << boxes << endl; + *testout << "boxesinlevel = " << boxesinlevel << endl; + 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 = 0, sureexp = 0; // sure ... + + static ARRAY 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(); + +#ifdef DEVELOP + (*testout) << "numprim = " << numprim << endl; +#endif + + numprim_hist[numprim]++; + + Point<3> p = box.Center(); + + + // explicit solution for planes only and at most one quadratic + if (numprim <= 5) + { + int nplane = 0, nquad = 0, quadi = -1; + const QuadraticSurface *qsurf = 0, *qsurfi; + + for (int i = 0; i < numprim; i++) + { + qsurfi = dynamic_cast + (geometry->GetSurface(locsurf[i])); + + if (qsurfi) nquad++; + if (dynamic_cast (qsurfi)) + nplane++; + else + { + quadi = i; + qsurf = qsurfi; + } + } + + /* + if (nquad == numprim && nplane == numprim-2) + return; + */ + +#ifdef DEVELOP + (*testout) << "nquad " << nquad << " nplane " << nplane << endl; +#endif + + if (nquad == numprim && nplane >= numprim-1) + { + ARRAY > pts; + ARRAY surfids; + + for (int k1 = 0; k1 < numprim - 2; k1++) + for (int k2 = k1 + 1; k2 < numprim - 1; k2++) + for (int k3 = k2 + 1; k3 < numprim; k3++) + if (k1 != quadi && k2 != quadi && k3 != quadi) + { + ComputeCrossPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + dynamic_cast (geometry->GetSurface(locsurf[k2])), + dynamic_cast (geometry->GetSurface(locsurf[k3])), + pts); + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + + if(!tansol) + continue; + + bool ok1 = false, ok2 = false, ok3 = false; + int rep1 = geometry->GetSurfaceClassRepresentant(locsurf[k1]); + int rep2 = geometry->GetSurfaceClassRepresentant(locsurf[k2]); + int rep3 = geometry->GetSurfaceClassRepresentant(locsurf[k3]); + for(int jj=0; jjGetSurfaceClassRepresentant(surfids[jj]); + if(actrep == rep1) ok1 = true; + if(actrep == rep2) ok2 = true; + if(actrep == rep3) ok3 = true; + } + + + if (tansol && ok1 && ok2 && ok3) + // if (sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size)) + { + if (AddPoint (pts[j], layer)) + (*testout) << "cross point found, 1: " << pts[j] << endl; + } + delete tansol; + } + } + + + if (qsurf) + { + for (int k1 = 0; k1 < numprim - 1; k1++) + for (int k2 = k1 + 1; k2 < numprim; k2++) + if (k1 != quadi && k2 != quadi) + { + ComputeCrossPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + dynamic_cast (geometry->GetSurface(locsurf[k2])), + qsurf, pts); + //(*testout) << "checking pot. crosspoints: " << pts << endl; + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + + if(!tansol) + continue; + + bool ok1 = false, ok2 = false, ok3 = true;//false; + int rep1 = geometry->GetSurfaceClassRepresentant(locsurf[k1]); + int rep2 = geometry->GetSurfaceClassRepresentant(locsurf[k2]); + //int rep3 = geometry->GetSurfaceClassRepresentant(quadi); + for(int jj=0; jjGetSurfaceClassRepresentant(surfids[jj]); + if(actrep == rep1) ok1 = true; + if(actrep == rep2) ok2 = true; + //if(actrep == rep3) ok3 = true; + } + + + if (tansol && ok1 && ok2 && ok3) + //if (sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size) ) + { + if (AddPoint (pts[j], layer)) + (*testout) << "cross point found, 2: " << pts[j] << endl; + } + delete tansol; + } + } + + + for (int k1 = 0; k1 < numprim; k1++) + if (k1 != quadi) + { + ComputeExtremalPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + qsurf, pts); + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + if (tansol) + // sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size) ) + { + if (AddPoint (pts[j], layer)) + (*testout) << "extremal point found, 1: " << pts[j] << endl; + } + delete tansol; + } + } + } + + return; + } + } + + + + 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)), box ); + + 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; + } + +#ifdef DEVELOP + (*testout) << "dec = " << decision << ", surcp = " << surecrossp << endl; +#endif + + 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)), box ) ) + { + + 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*size); + + if (pp(0) > box.PMin()(0) - 1e-5*size && + pp(0) < box.PMax()(0) + 1e-5*size && + pp(1) > box.PMin()(1) - 1e-5*size && + pp(1) < box.PMax()(1) + 1e-5*size && + pp(2) > box.PMin()(2) - 1e-5*size && + pp(2) < box.PMax()(2) + 1e-5*size && + sol -> IsIn (pp, 1e-6*size) && !sol->IsStrictIn (pp, 1e-6*size) && + !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*size); + boxp.CalcDiamCenter(); + ARRAY locsurf2; + + geometry -> GetIndependentSurfaceIndices (sol, boxp, locsurf2); + + bool found1 = false, found2 = false, found3 = false; + for (int i = 0; i < locsurf2.Size(); i++) + { + if (locsurf2[i] == locsurf.Get(k1)) found1 = true; + if (locsurf2[i] == locsurf.Get(k2)) found2 = true; + if (locsurf2[i] == locsurf.Get(k3)) found3 = true; + } + + 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; + + // (*testout) << "l = " << level << "locsize = " << locsurf.Size() << " possexp = " << possibleexp << "\n"; + if (possibleexp && (numprim <= 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; + } + } + + // (*testout) << "l = " << level << " dec/sureexp = " << decision << sureexp << endl; + + 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, 1e-6*size) && !sol->IsStrictIn (pp, 1e-6*size) ) + { + if (AddPoint (pp, layer)) + (*testout) << "Extremal point found: " << pp << endl;//"(eps="<<1e-9*size<<")"<< endl; + } + } + } + } + } + if (decision) + possibleexp = 0; + } + + + // (*testout) << "l = " << level << " poss cp/ep sure exp = " << possiblecrossp << " " << possibleexp << " " << sureexp << "\n"; + 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 BoxSphere<3> & box) + { + Vec<3> grad, rs, x; + Mat<3> jacobi, inv; + Point<3> p = box.Center(); + + 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); + + +#ifdef DEVELOP + *testout << "check Newton: " << "beta = " << beta << ", gamma = " << gamma << ", eta = " << eta << endl; + double rad = 1.0 / (beta * gamma); + *testout << "rad = " << rad << endl; +#endif + + return (beta * gamma * eta < 0.1) && (2 > box.Diam()*beta*gamma); + } + 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; + +#ifdef DEVELOP + *testout << "CrossPointNewton, err = " << sol.Length2() << endl; +#endif + 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); + + //(*testout) << "p " << p << " f1 " << vrs(0) << " f2 " << vrs(1) << " g1 " << g1 << " g2 " << g2 << endl; + + 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); + + /* + (*testout) << "p " << p << " f1 " << rs(0) << " f2 " << rs(1) << endl + << " jacobi " << jacobi << endl + << " rhs " << rs << endl; + */ + + jacobi.Solve (rs, x); + + if (Abs2 (x) < 1e-24 && i > 1) + { + i = 1; + } + + + double minval(Abs2(rs)),minfac(1); + double startval(minval); + for(double fac = 1; fac > 1e-7; fac *= 0.6) + { + Point<3> testpoint = p-fac*x; + + rs(0) = f1->CalcFunctionValue (testpoint); + rs(1) = f2->CalcFunctionValue (testpoint); + + f1 -> CalcGradient (testpoint, g1); + f2 -> CalcGradient (testpoint, g2); + + v = Cross (g1, g2); + + rs(2) = v(dir-1); + + double val = Abs2(rs); + + if(val < minval) + { + minfac = fac; + if(val < 0.5 * startval) + break; + minval = val; + } + + } + p -= minfac*x; + + + //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 :: + ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const Plane * plane3, + ARRAY > & pts) + { + Mat<3> mat; + Vec<3> rhs, sol; + Point<3> p0(0,0,0); + + pts.SetSize (0); + for (int i = 0; i < 3; i++) + { + const Plane * pi(NULL); + switch (i) + { + case 0: pi = plane1; break; + case 1: pi = plane2; break; + case 2: pi = plane3; break; + } + + double val; + Vec<3> hvec; + val = pi -> CalcFunctionValue(p0); + pi -> CalcGradient (p0, hvec); + + for (int j = 0; j < 3; j++) + mat(i,j) = hvec(j); + rhs(i) = -val; + } + + if (fabs (Det (mat)) > 1e-8) + { + mat.Solve (rhs, sol); + pts.Append (Point<3> (sol)); + } + } + + + + + + void SpecialPointCalculation :: + ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const QuadraticSurface * quadric, + ARRAY > & pts) + { + Mat<2,3> mat; + Mat<3,2> inv; + Vec<2> rhs; + Vec<3> sol, t; + Point<3> p0(0,0,0); + + pts.SetSize (0); + for (int i = 0; i < 2; i++) + { + const Plane * pi(NULL); + switch (i) + { + case 0: pi = plane1; break; + case 1: pi = plane2; break; + } + + double val; + Vec<3> hvec; + val = pi -> CalcFunctionValue(p0); + pi -> CalcGradient (p0, hvec); + + for (int j = 0; j < 3; j++) + mat(i,j) = hvec(j); + rhs(i) = -val; + } + CalcInverse (mat, inv); + sol = inv * rhs; + t = Cross (mat.Row(0), mat.Row(1)); + + if (t.Length() > 1e-8) + { + Point<3> p (sol); + // quadratic on p + s t = 0 + double quad_a; + Vec<3> quad_b; + Mat<3> quad_c; + + quad_a = quadric -> CalcFunctionValue(p); + quadric -> CalcGradient (p, quad_b); + quadric -> CalcHesse (p, quad_c); + + double a, b, c; + a = quad_a; + b = quad_b * t; + c = 0.5 * t * (quad_c * t); + + // a + s b + s^2 c = 0; + double disc = b*b-4*a*c; + if (disc > 1e-10 * fabs (b)) + { + disc = sqrt (disc); + double s1 = (-b-disc) / (2*c); + double s2 = (-b+disc) / (2*c); + + pts.Append (p + s1 * t); + pts.Append (p + s2 * t); + } + } + } + + + + + + + + + + + + + void SpecialPointCalculation :: + ComputeExtremalPoints (const Plane * plane, + const QuadraticSurface * quadric, + ARRAY > & 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 false; + + points->Append (MeshPoint(p, layer)); + PrintMessageCR (3, "Found points ", points->Size()); + return true; + } + + + + + + + + void SpecialPointCalculation :: + AnalyzeSpecialPoints (const CSGeometry & ageometry, + ARRAY & apoints, + ARRAY & specpoints) + { + ARRAY surfind, rep_surfind, surfind2, rep_surfind2, surfind3; + + ARRAY > normalvecs; + Vec<3> nsurf; + + ARRAY specpoint2point; + specpoints.SetSize (0); + + geometry = &ageometry; + + double geomsize = ageometry.MaxSize(); + + (*testout) << "AnalyzeSpecialPoints\n"; + + if (!apoints.Size()) return; + + + +#ifdef VERTSORT + for (int i = 0; i < apoints.Size(); i++) + for (int j = 0; j < apoints.Size()-1; j++) + if (apoints[j](2) > apoints[j+1](2)) + swap (apoints[j], apoints[j+1]); +#endif + + + + + + + + Box<3> bbox (apoints[0], apoints[0]); + for (int i = 1; i < apoints.Size(); i++) + bbox.Add (apoints[i]); + bbox.Increase (0.1 * bbox.Diam()); + + //testout->precision(20); + (*testout) << "bbox = " << bbox << endl; + (*testout) << "points = " << apoints << endl; + + Point3dTree searchtree (bbox.PMin(), bbox.PMax()); + ARRAY locsearch; + + for (int si = 0; si < ageometry.GetNTopLevelObjects(); si++) + { + const TopLevelObject * tlo = ageometry.GetTopLevelObject(si); + + const Solid * sol = tlo->GetSolid(); + const Surface * surf = tlo->GetSurface(); + + + for (int i = 0; i < apoints.Size(); i++) + { + Point<3> p = apoints[i]; + +#ifdef DEVELOP + *testout << " test point " << p << endl; +#endif + + if (tlo->GetLayer() != apoints[i].GetLayer()) + continue; + + Solid * locsol; + sol -> TangentialSolid (p, locsol, surfind, ideps*geomsize); + + + + rep_surfind.SetSize (surfind.Size()); + int num_indep_surfs = 0; + + for (int j = 0; j < surfind.Size(); j++) + { + rep_surfind[j] = ageometry.GetSurfaceClassRepresentant (surfind[j]); + bool found = false; + for (int k = 0; !found && k < j; k++) + found = (rep_surfind[k] == rep_surfind[j]); + if(!found) + num_indep_surfs++; + } + + +#ifdef DEVELOP + *testout << "surfs = " << surfind << endl; + *testout << "rep_surfs = " << rep_surfind << endl; +#endif + + 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*geomsize); + box.CalcDiamCenter(); + ageometry.GetIndependentSurfaceIndices (locsol, box, surfind); + */ + + // ageometry.GetIndependentSurfaceIndices (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 = 0; k < normalvecs.Size(); k++) + { + if (rep_surfind[j] == rep_surfind[k]) continue; + //if (j == k) continue; + + Vec<3> t; + + if (dynamic_cast (ageometry.surf2prim[surfind[j]]) && + ageometry.surf2prim[surfind[j]] == + ageometry.surf2prim[surfind[k]]) + { + t = ageometry.surf2prim[surfind[j]] -> + SpecialPointTangentialVector (p, surfind[j], surfind[k]); + } + else + { + t = Cross (normalvecs[j], normalvecs[k]); + } + + + if (Abs2 (t) < 1e-8) + continue; + +#ifdef DEVELOP + *testout << " tangential vector " << t << endl; +#endif + + t.Normalize(); + + + // try tangential direction t + if (surf && fabs (nsurf * t) > 1e-6) + continue; + + +#ifdef DEVELOP + *testout << " j " << j << " k " << k << endl; +#endif + + if (!surf) + { + // compute second order approximation + // c(s) = p + s t + s*s/2 t2 + Vec<3> gradj, gradk; + Mat<3> hessej, hessek; + ageometry.GetSurface (surfind[j]) -> CalcGradient (p, gradj); + ageometry.GetSurface (surfind[k]) -> CalcGradient (p, gradk); + ageometry.GetSurface (surfind[j]) -> CalcHesse (p, hessej); + ageometry.GetSurface (surfind[k]) -> CalcHesse (p, hessek); + + Vec<2> rhs; + Vec<3> t2; + Mat<2,3> mat; + Mat<3,2> inv; + for (int l = 0; l < 3; l++) + { + mat(0,l) = gradj(l); + mat(1,l) = gradk(l); + } + rhs(0) = -t * (hessej * t); + rhs(1) = -t * (hessek * t); + + CalcInverse (mat, inv); + t2 = inv * rhs; + + + /* + ageometry.GetIndependentSurfaceIndices + (locsol, p, t, surfind2); + */ + + Solid * locsol2; + locsol -> TangentialSolid3 (p, t, t2, locsol2, surfind2, ideps*geomsize); + if (!locsol2) continue; + + // locsol2 -> GetTangentialSurfaceIndices3 (p, t, t2, surfind2, 1e-9*geomsize); + + rep_surfind2.SetSize (surfind2.Size()); + for (int j2 = 0; j2 < surfind2.Size(); j2++) + rep_surfind2[j2] = ageometry.GetSurfaceClassRepresentant (surfind2[j2]); + +#ifdef DEVELOP + (*testout) << "surfind2 = " << endl << surfind2 << endl; +#endif + ARRAY surfind2_aux(surfind2); + ageometry.GetIndependentSurfaceIndices (surfind2_aux); +#ifdef DEVELOP + (*testout) << "surfind2,rep = " << endl << surfind2_aux << endl; +#endif + + bool ok = true; + + // intersecting surfaces must be in second order tangential solid + /* + if (!surfind2.Contains(surfind[j]) || + !surfind2.Contains(surfind[k])) + ok = false; + */ + if (!surfind2_aux.Contains(rep_surfind[j]) || + !surfind2_aux.Contains(rep_surfind[k])) + ok = false; + +#ifdef DEVELOP + (*testout) << "ok,1 = " << ok << endl; +#endif + + // there must be 2 different tangential faces to the edge + int cnt_tang_faces = 0; + for (int l = 0; l < surfind2.Size(); l++) + { + Vec<3> nv = + ageometry.GetSurface(surfind2[l]) -> GetNormalVector(p); + + + Vec<3> m1 = Cross (t, nv); + Vec<3> m2 = -m1; + bool isface1 = 0, isface2 = 0; + + Solid * locsol3; + + // locsol2 -> TangentialSolid2 (p, m1, locsol3, surfind3, 1e-9*geomsize); + locsol -> TangentialEdgeSolid (p, t, t2, m1, locsol3, surfind3, ideps*geomsize); + + //ageometry.GetIndependentSurfaceIndices (surfind3); + + if (surfind3.Contains(surfind2[l])) + isface1 = 1; + delete locsol3; + + // locsol2 -> TangentialSolid2 (p, m2, locsol3, surfind3, 1e-9*geomsize); + locsol -> TangentialEdgeSolid (p, t, t2, m2, locsol3, surfind3, ideps*geomsize); + + // ageometry.GetIndependentSurfaceIndices (surfind3); + + + if (surfind3.Contains(surfind2[l])) + isface2 = 1; + delete locsol3; + + if (isface1 != isface2) + cnt_tang_faces++; + } + +#ifdef DEVELOP + (*testout) << "cnt_tang = " << cnt_tang_faces << endl; +#endif + + if (cnt_tang_faces < 1) + ok = false; + + delete locsol2; + if (!ok) continue; + } + + + // edge must be on tangential surface + bool isedge = + locsol->VectorIn (p, t) && + !locsol->VectorStrictIn (p, t); + +#ifdef DEVELOP + (*testout) << "isedge,1 = " << isedge << "\n"; +#endif + + // there must exist at least two different faces on edge + if (isedge) + { + // *testout << "succ 1" << endl; + 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; + + bool isface = + (locsol->VectorIn (p, t2a, 1e-6*geomsize) && + !locsol->VectorStrictIn (p, t2a, 1e-6*geomsize)) + || + (locsol->VectorIn (p, t2b, 1e-6*geomsize) && + !locsol->VectorStrictIn (p, t2b, 1e-6*geomsize)); + + /* + 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) + { +#ifdef DEVELOP + *testout << "success" << endl; +#endif + int spi = -1; + + const double searchradius = 1e-4*geomsize;//1e-5*geomsize; + searchtree.GetIntersecting (apoints[i]-Vec3d(searchradius,searchradius,searchradius), + apoints[i]+Vec3d(searchradius,searchradius,searchradius), + locsearch); + + for (int m = 0; m < locsearch.Size(); m++) + { + if (Dist2 (specpoints[locsearch[m]].p, apoints[i]) < 1e-10*geomsize + && 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); + } + + if(!specpoints[spi].unconditional) + { + specpoints[spi].p = apoints[i]; + specpoints[spi].v = t; + //if (surfind.Size() >= 3) + if (num_indep_surfs >= 3) + specpoints[spi].unconditional = 1; + specpoints[spi].s1 = rep_surfind[j]; + specpoints[spi].s2 = rep_surfind[k]; + specpoints[spi].s1_orig = surfind[j]; + specpoints[spi].s2_orig = surfind[k]; + specpoints[spi].layer = apoints[i].GetLayer(); + for (int up = 0; up < geometry->GetNUserPoints(); up++) + if (Dist (geometry->GetUserPoint(up), apoints[i]) < 1e-8*geomsize) + specpoints[spi].unconditional = 1; + for (int ip = 0; ip < geometry->GetNIdentPoints(); ip++) + if (Dist (geometry->GetIdentPoint(ip), apoints[i]) < 1e-8*geomsize) + specpoints[spi].unconditional = 1; + } + } + + } + + delete locsol; + } + } + + /* + BitArray testuncond (specpoints.Size()); + testuncond.Clear(); + for(int i = 0; i same; + same.Append(i); + + for(int j = i+1; j p; + /// tangential to edge + Vec<3> v; + /// + int layer; + /// point must be used in mesh + bool unconditional; + + /// surfaces defining edge + int s1, s2; + /// if s1 and s2 are only representatives, then these are the original indices + int s1_orig, s2_orig; + int nr; + /// + SpecialPoint () : p(0,0,0), v(0,0,0), layer(0), unconditional(0), s1(0), s2(0), s1_orig(0), s2_orig(0) + { ; } + + /// + SpecialPoint (const SpecialPoint & sp2); + + /// + SpecialPoint & operator= (const SpecialPoint & sp2); + + /// + void Print (ostream & str) const; + + + int GetLayer() const { return layer; } + + /// + bool HasSurfaces (int as1, int as2) const + { + return ( (s1 == as1 && s2 == as2) || (s1 == as2 && s2 == as1) ); + } +}; + +inline ostream & operator<< (ostream & ost, const SpecialPoint & sp) +{ + sp.Print (ost); + return ost; +} + + + + +/// +class SpecialPointCalculation +{ +private: + /// + const CSGeometry * geometry; + /// + ARRAY * points; + /// + ARRAY boxesinlevel; + + /// + double size; + /// + double relydegtest; // maximal dimension of bisection intervall for + /// test of degeneration parameters + double cpeps1, epeps1, epeps2, epspointdist2; + + double ideps; + +public: + + /// + SpecialPointCalculation (); + + /// + void SetIdEps(const double epsin) {ideps = epsin;} + + /// + void CalcSpecialPoints (const CSGeometry & ageometry, + ARRAY & points); + /// + void AnalyzeSpecialPoints (const CSGeometry & geometry, + ARRAY & points, + ARRAY & 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 BoxSphere<3> & box); + /// + 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 > & pts); + + void ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const Plane * plane3, + ARRAY > & pts); + + void ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const QuadraticSurface * quadratic, + ARRAY > & pts); +}; + +#endif + + diff --git a/libsrc/csg/spline3d.cpp b/libsrc/csg/spline3d.cpp new file mode 100644 index 00000000..b89e7f70 --- /dev/null +++ b/libsrc/csg/spline3d.cpp @@ -0,0 +1,355 @@ +#include + +#include + +#include +#include + + +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(0); + 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/libsrc/csg/spline3d.hpp b/libsrc/csg/spline3d.hpp new file mode 100644 index 00000000..75378845 --- /dev/null +++ b/libsrc/csg/spline3d.hpp @@ -0,0 +1,92 @@ +/// +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 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/libsrc/csg/surface.cpp b/libsrc/csg/surface.cpp new file mode 100644 index 00000000..290c4f5d --- /dev/null +++ b/libsrc/csg/surface.cpp @@ -0,0 +1,568 @@ +#include + +#include +#include + +#include +#include + + +namespace netgen +{ +Surface :: Surface () +{ + maxh = 1e10; + name = new char[7]; + strcpy (name, "noname"); + bcprop = -1; + bcname = "default"; +} + +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; + } +} + +void Surface :: SkewProject (Point<3> & p, const Vec<3> & direction) const +{ + Point<3> startp(p); + double t_old(0),t_new(1); + Vec<3> grad; + for(int i=0; fabs(t_old-t_new) > 1e-20 && i<15; i++) + { + t_old = t_new; + CalcGradient(p,grad); + t_new = t_old - CalcFunctionValue(p)/(grad*direction); + p = startp + t_new*direction; + } +} + + +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 (const char *& classname, + ARRAY & coeffs) const +{ + classname = "undef"; + coeffs.SetSize (0); +} + +void Primitive :: SetPrimitiveData (ARRAY & 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(); + + + stringstream ost; + ost << "Primitve::CreatePrimitive not implemented for " << classname << endl; + throw NgException (ost.str()); +} + + +Primitive * Primitive :: Copy () const +{ + stringstream ost; + ost << "Primitve::Copy not implemented for " << typeid(*this).name() << endl; + throw NgException (ost.str()); +} + + +void Primitive :: Transform (Transformation<3> & trans) +{ + stringstream ost; + ost << "Primitve::Transform not implemented for " << typeid(*this).name() << endl; + throw NgException (ost.str()); +} + +void Primitive :: GetTangentialSurfaceIndices (const Point<3> & p, + ARRAY & surfind, double eps) const +{ + for (int j = 0; j < GetNSurfaces(); j++) + if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps) + if (!surfind.Contains (GetSurfaceId(j))) + surfind.Append (GetSurfaceId(j)); +} + + +void Primitive :: +GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v, + ARRAY & surfind, double eps) const +{ + cout << "get tangvecsurfind not implemented" << endl; + surfind.SetSize (0); +} + +void Primitive :: +GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + ARRAY & surfind, double eps) const +{ + for (int j = 0; j < GetNSurfaces(); j++) + { + if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + GetSurface(j).CalcGradient (p, grad); + if (sqr (grad * v1) < 1e-6 * v1.Length2() * grad.Length2() && + sqr (grad * v2) < 1e-6 * v2.Length2() * grad.Length2() ) // new, 18032006 JS + { + if (!surfind.Contains (GetSurfaceId(j))) + surfind.Append (GetSurfaceId(j)); + } + } + } +} + + + + +INSOLID_TYPE Primitive :: +VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + //(*testout) << "Primitive::VecInSolid2" << endl; + 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; +} + +INSOLID_TYPE Primitive :: +VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + //(*testout) << "Primitive::VecInSolid3" << endl; + return VecInSolid (p, v1, eps); +} + +INSOLID_TYPE Primitive :: +VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const +{ + return VecInSolid2 (p, v, m, eps); +} + + + + + +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 +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + + Vec<3> hv; + 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 +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + Vec<3> hv; + + GetSurface(0).CalcGradient (p, hv); + + hv1 = v1 * hv; + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + double hv2 = v2 * hv; + if (hv2 <= 0) + return IS_INSIDE; + else + return IS_OUTSIDE; +} + + + +INSOLID_TYPE OneSurfacePrimitive :: +VecInSolid3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + double eps) const +{ + //(*testout) << "OneSurfacePrimitive::VecInSolid3" << endl; + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + Vec<3> grad; + GetSurface(0).CalcGradient (p, grad); + + hv1 = v * grad; + if (hv1 <= -eps) return IS_INSIDE; + if (hv1 >= eps) return IS_OUTSIDE; + + Mat<3> hesse; + GetSurface(0).CalcHesse (p, hesse); + + double hv2 = v2 * grad + v * (hesse * v); + + if (hv2 <= -eps) return IS_INSIDE; + if (hv2 >= eps) return IS_OUTSIDE; + + return DOES_INTERSECT; +} + + + + +INSOLID_TYPE OneSurfacePrimitive :: +VecInSolid4 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + const Vec<3> & m, + double eps) const +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + Vec<3> grad; + GetSurface(0).CalcGradient (p, grad); + + hv1 = v * grad; + if (hv1 <= -eps) return IS_INSIDE; + if (hv1 >= eps) return IS_OUTSIDE; + + Mat<3> hesse; + GetSurface(0).CalcHesse (p, hesse); + + double hv2 = v2 * grad + v * (hesse * v); + + if (hv2 <= -eps) return IS_INSIDE; + if (hv2 >= eps) return IS_OUTSIDE; + + + double hv3 = m * grad; + if (hv3 <= -eps) return IS_INSIDE; + if (hv3 >= eps) return IS_OUTSIDE; + + return DOES_INTERSECT; +} + + + + + + + +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); + + double alpha = fabs(a1*a2)/sqrt(a1.Length2()*a2.Length2()); + if(fabs(1.-alpha) < 1e-6) + { + if(fabs(rs(0)) >= fabs(rs(1))) + f1 -> Project(hp); + else + f2 -> Project(hp); + } + else + { + + 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/libsrc/csg/surface.hpp b/libsrc/csg/surface.hpp new file mode 100644 index 00000000..c5e7b768 --- /dev/null +++ b/libsrc/csg/surface.hpp @@ -0,0 +1,357 @@ +#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; + /// + string bcname; + +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 void SkewProject(Point<3> & p, const Vec<3> & direction) 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 + + string GetBCName() const { return bcname; } + + void SetBCName( string abc ) { bcname = abc; } + }; + + +inline ostream & operator<< (ostream & ost, const Surface & surf) +{ + surf.Print(ost); + return ost; +} + + + +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 void GetTangentialSurfaceIndices (const Point<3> & p, + ARRAY & surfind, double eps) const; + + 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; + + // checks if p + s v1 + s*s/2 v2 is inside + virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + // like VecInSolid2, but second order approximation + virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const; + + virtual void GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v, + ARRAY & surfind, double eps) const; + + virtual void GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + ARRAY & surfind, double eps) const; + + + virtual void CalcSpecialPoints (ARRAY > & /* pts */) const { ; } + virtual void AnalyzeSpecialPoint (const Point<3> & /* pt */, + ARRAY > & /* specpts */) const { ; } + virtual Vec<3> SpecialPointTangentialVector (const Point<3> & /* p */, + int /* s1 */, int /* s2 */) const + { return Vec<3> (0,0,0); } + + + virtual int GetNSurfaces() const = 0; + virtual Surface & GetSurface (int i = 0) = 0; + virtual const Surface & GetSurface (int i = 0) const = 0; + + ARRAY surfaceids; + ARRAY 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 (const char *& classname, + ARRAY & coeffs) const; + virtual void SetPrimitiveData (ARRAY & 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 INSOLID_TYPE VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + 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/libsrc/csg/triapprox.cpp b/libsrc/csg/triapprox.cpp new file mode 100644 index 00000000..40371615 --- /dev/null +++ b/libsrc/csg/triapprox.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include +#include + + +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 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/libsrc/csg/triapprox.hpp b/libsrc/csg/triapprox.hpp new file mode 100644 index 00000000..7b2db16b --- /dev/null +++ b/libsrc/csg/triapprox.hpp @@ -0,0 +1,57 @@ +#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 > points; + ARRAY > normals; + ARRAY 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/libsrc/general/Makefile.am b/libsrc/general/Makefile.am new file mode 100644 index 00000000..f72b062a --- /dev/null +++ b/libsrc/general/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libgeneral.a +libgeneral_a_SOURCES = array.cpp bitarray.cpp dynamicmem.cpp flags.cpp \ + hashtabl.cpp moveablemem.cpp mystring.cpp ngexception.cpp optmem.cpp parthreads.cpp \ + profiler.cpp seti.cpp sort.cpp spbita2d.cpp symbolta.cpp table.cpp diff --git a/libsrc/general/Makefile.in b/libsrc/general/Makefile.in new file mode 100644 index 00000000..080a04e7 --- /dev/null +++ b/libsrc/general/Makefile.in @@ -0,0 +1,462 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/general +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libgeneral_a_AR = $(AR) $(ARFLAGS) +libgeneral_a_LIBADD = +am_libgeneral_a_OBJECTS = array.$(OBJEXT) bitarray.$(OBJEXT) \ + dynamicmem.$(OBJEXT) flags.$(OBJEXT) hashtabl.$(OBJEXT) \ + moveablemem.$(OBJEXT) mystring.$(OBJEXT) ngexception.$(OBJEXT) \ + optmem.$(OBJEXT) parthreads.$(OBJEXT) profiler.$(OBJEXT) \ + seti.$(OBJEXT) sort.$(OBJEXT) spbita2d.$(OBJEXT) \ + symbolta.$(OBJEXT) table.$(OBJEXT) +libgeneral_a_OBJECTS = $(am_libgeneral_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgeneral_a_SOURCES) +DIST_SOURCES = $(libgeneral_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libgeneral.a +libgeneral_a_SOURCES = array.cpp bitarray.cpp dynamicmem.cpp flags.cpp \ + hashtabl.cpp moveablemem.cpp mystring.cpp ngexception.cpp optmem.cpp parthreads.cpp \ + profiler.cpp seti.cpp sort.cpp spbita2d.cpp symbolta.cpp table.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/general/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/general/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libgeneral.a: $(libgeneral_a_OBJECTS) $(libgeneral_a_DEPENDENCIES) + -rm -f libgeneral.a + $(libgeneral_a_AR) libgeneral.a $(libgeneral_a_OBJECTS) $(libgeneral_a_LIBADD) + $(RANLIB) libgeneral.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitarray.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamicmem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtabl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/moveablemem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mystring.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngexception.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optmem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parthreads.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seti.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sort.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spbita2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbolta.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/general/array.cpp b/libsrc/general/array.cpp new file mode 100644 index 00000000..95d711a9 --- /dev/null +++ b/libsrc/general/array.cpp @@ -0,0 +1,75 @@ +#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 +#include +#include + + +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 (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/libsrc/general/array.hpp b/libsrc/general/array.hpp new file mode 100644 index 00000000..91b53f96 --- /dev/null +++ b/libsrc/general/array.hpp @@ -0,0 +1,638 @@ +#ifndef FILE_ARRAY +#define FILE_ARRAY + +/**************************************************************************/ +/* File: array.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + + + + +// template class IndirectArray; + + + +/** + 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 FlatArray +{ +protected: + /// the size + int size; + /// the data + T * data; +public: + + /// provide size and memory + FlatArray (int asize, T * adata) + : size(asize), data(adata) { ; } + + /// the size + int Size() const { return size; } + + int Begin() const { return BASE; } + int End() const { return size+BASE; } + + /* + /// access array. + 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. BASE-based + 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]; + } + + /* + template + IndirectArray operator[] (const FlatArray & ind) + { return IndirectArray (*this, ind); } + */ + + /// Access array, one-based (old fashioned) + 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]; + } + + /// Access array, one-based (old fashioned) + 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]; + } + + /// Access array, one-based (old fashioned) + 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 first element + T & First () const + { + return data[0]; + } + + + /// access last element. check by macro CHECK_RANGE + 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; + } + + /// takes range starting from position start of end-start elements + const FlatArray Range (int start, int end) + { + return FlatArray (end-start, data+start); + } + + /// first position of element elem, returns -1 if element not contained in array + int Pos(const T & elem) const + { + int pos = -1; + for(int i=0; pos==-1 && i < this->size; i++) + if(elem == data[i]) pos = i; + return pos; + } + + /// does the array contain element elem ? + bool Contains(const T & elem) const + { + return ( Pos(elem) >= 0 ); + } +}; + + + +// print array +template +inline ostream & operator<< (ostream & s, const FlatArray & a) +{ + for (int i = a.Begin(); i < a.End(); i++) + s << i << ": " << a[i] << endl; + return s; +} + + + +/** + Dynamic array container. + + ARRAY 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 ARRAY : public FlatArray +{ +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 (asize, asize ? new T[asize] : 0) + { + allocsize = asize; + ownmem = 1; + } + + /// Generate array in user data + ARRAY(int asize, T* adata) + : FlatArray (asize, adata) + { + allocsize = asize; + ownmem = 0; + } + + /// array copy + explicit ARRAY (const ARRAY & a2) + : FlatArray (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; + } + + template + void Append (FlatArray a2) + { + if (this->size+a2.Size() > allocsize) + ReSize (this->size+a2.Size()); + for (int i = 0; i < a2.Size(); i++) + this->data[this->size+i] = a2[i+B2]; + this->size += a2.Size(); + } + + + /* + template + void Append (const IndirectArray & a2) + { + if (this->size+a2.Size() > allocsize) + ReSize (this->size+a2.Size()); + for (int i = 0; i < a2.Size(); i++) + this->data[this->size+i] = a2[i+B2]; + this->size += a2.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::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; + } + + /// array copy + ARRAY & operator= (const FlatArray & 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 ArrayMem : public ARRAY +{ + // T mem[S]; // Intel C++ calls dummy constructor + // 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 (S, static_cast (static_cast(&mem[0]))) + { + this->size = asize; + if (asize > S) + { + this->data = new T[asize]; + this->ownmem = 1; + } + // this->SetSize (asize); + } + + ArrayMem & operator= (const T & val) + { + ARRAY::operator= (val); + return *this; + } +}; + + + + + +/* +template +class IndirectArray +{ + const FlatArray & array; + const FlatArray & ia; + +public: + IndirectArray (const FlatArray & aa, const FlatArray & aia) + : array(aa), ia(aia) { ; } + int Size() const { return ia.Size(); } + const T & operator[] (int i) const { return array[ia[i]]; } +}; +*/ + + + + + + + + + + +/// +template +class MoveableArray +{ + int size; + int allocsize; + MoveableMem 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-BASE]; } + + /// + const T & operator[] (int i) const + { return ((const T*)data)[i-BASE]; } + + /// + 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; + } + + + MoveableArray & Copy (const MoveableArray & a2) + { + SetSize (a2.Size()); + for (int i = 0; i < this->size; i++) + data[i] = a2.data[i]; + return *this; + } + + /// array copy + MoveableArray & operator= (const MoveableArray & a2) + { + return Copy(a2); + } + + + void SetName (const char * aname) + { + data.SetName(aname); + } +private: + /// + //MoveableArray & operator= (MoveableArray &); //??? + /// + //MoveableArray (const MoveableArray &); //??? +}; + + +template +inline ostream & operator<< (ostream & ost, MoveableArray & a) +{ + for (int i = 0; i < a.Size(); i++) + ost << i << ": " << a[i] << endl; + return ost; +} + + +/// bubble sort array +template +inline void BubbleSort (const FlatArray & data) +{ + T hv; + for (int i = 0; i < data.Size(); i++) + for (int j = i+1; j < data.Size(); j++) + if (data[i] > data[j]) + { + hv = data[i]; + data[i] = data[j]; + data[j] = hv; + } +} +/// bubble sort array +template +inline void BubbleSort (FlatArray & data, FlatArray & slave) +{ + T hv; + S hvs; + for (int i = 0; i < data.Size(); i++) + for (int j = i+1; j < data.Size(); j++) + if (data[i] > data[j]) + { + hv = data[i]; + data[i] = data[j]; + data[j] = hv; + + hvs = slave[i]; + slave[i] = slave[j]; + slave[j] = hvs; + } +} + + +template +void Intersection (const FlatArray & in1, const FlatArray & in2, + ARRAY & out) +{ + out.SetSize(0); + for(int i=0; i +void Intersection (const FlatArray & in1, const FlatArray & in2, const FlatArray & in3, + ARRAY & out) +{ + out.SetSize(0); + for(int i=0; i +class AutoDiff +{ + SCAL val; + SCAL dval[D]; +public: + + typedef AutoDiff TELEM; + typedef SCAL TSCAL; + + + /// elements are undefined + AutoDiff () throw() { }; + // { val = 0; for (int i = 0; i < D; i++) dval[i] = 0; } // ! + + /// copy constructor + AutoDiff (const AutoDiff & ad2) throw() + { + val = ad2.val; + for (int i = 0; i < D; i++) + dval[i] = ad2.dval[i]; + } + + /// initial object with constant value + AutoDiff (SCAL aval) throw() + { + val = aval; + for (int i = 0; i < D; i++) + dval[i] = 0; + } + + /// init object with (val, e_diffindex) + AutoDiff (SCAL aval, int diffindex) throw() + { + val = aval; + for (int i = 0; i < D; i++) + dval[i] = 0; + dval[diffindex] = 1; + } + + /// assign constant value + AutoDiff & operator= (SCAL aval) throw() + { + val = aval; + for (int i = 0; i < D; i++) + dval[i] = 0; + return *this; + } + + /// returns value + SCAL Value() const throw() { return val; } + + /// returns partial derivative + SCAL DValue (int i) const throw() { return dval[i]; } + + /// access value + SCAL & Value() throw() { return val; } + + /// accesses partial derivative + SCAL & DValue (int i) throw() { return dval[i]; } + + /// + AutoDiff & operator+= (const AutoDiff & y) throw() + { + val += y.val; + for (int i = 0; i < D; i++) + dval[i] += y.dval[i]; + return *this; + } + + /// + AutoDiff & operator-= (const AutoDiff & y) throw() + { + val -= y.val; + for (int i = 0; i < D; i++) + dval[i] -= y.dval[i]; + return *this; + + } + + /// + AutoDiff & operator*= (const AutoDiff & y) throw() + { + for (int i = 0; i < D; i++) + { + // dval[i] *= y.val; + // dval[i] += val * y.dval[i]; + dval[i] = dval[i] * y.val + val * y.dval[i]; + } + val *= y.val; + return *this; + } + + /// + AutoDiff & operator*= (const SCAL & y) throw() + { + val *= y; + for (int i = 0; i < D; i++) + dval[i] *= y; + return *this; + } + + /// + AutoDiff & operator/= (const SCAL & y) throw() + { + SCAL iy = 1.0 / y; + val *= iy; + for (int i = 0; i < D; i++) + dval[i] *= iy; + return *this; + } + + /// + bool operator== (SCAL val2) throw() + { + return val == val2; + } + + /// + bool operator!= (SCAL val2) throw() + { + return val != val2; + } + + /// + bool operator< (SCAL val2) throw() + { + return val < val2; + } + + /// + bool operator> (SCAL val2) throw() + { + return val > val2; + } +}; + + +//@{ AutoDiff helper functions. + +/// prints AutoDiff +template +inline ostream & operator<< (ostream & ost, const AutoDiff & x) +{ + ost << x.Value() << ", D = "; + for (int i = 0; i < D; i++) + ost << x.DValue(i) << " "; + return ost; +} + +/// AutoDiff plus AutoDiff +template +inline AutoDiff operator+ (const AutoDiff & x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value () = x.Value()+y.Value(); + // AutoDiff res(x.Value()+y.Value()); + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i) + y.DValue(i); + return res; +} + + +/// AutoDiff minus AutoDiff +template +inline AutoDiff operator- (const AutoDiff & x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x.Value()-y.Value(); + // AutoDiff res (x.Value()-y.Value()); + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i) - y.DValue(i); + return res; +} + +/// double plus AutoDiff +template +inline AutoDiff operator+ (double x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x+y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = y.DValue(i); + return res; +} + +/// AutoDiff plus double +template +inline AutoDiff operator+ (const AutoDiff & y, double x) throw() +{ + AutoDiff res; + res.Value() = x+y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = y.DValue(i); + return res; +} + + +/// minus AutoDiff +template +inline AutoDiff operator- (const AutoDiff & x) throw() +{ + AutoDiff res; + res.Value() = -x.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = -x.DValue(i); + return res; +} + +/// AutoDiff minus double +template +inline AutoDiff operator- (const AutoDiff & x, double y) throw() +{ + AutoDiff res; + res.Value() = x.Value()-y; + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i); + return res; +} + +/// +template +inline AutoDiff operator- (double x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x-y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = -y.DValue(i); + return res; +} + + +/// double times AutoDiff +template +inline AutoDiff operator* (double x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x*y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = x*y.DValue(i); + return res; +} + +/// AutoDiff times double +template +inline AutoDiff operator* (const AutoDiff & y, double x) throw() +{ + AutoDiff res; + res.Value() = x*y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = x*y.DValue(i); + return res; +} + +/// AutoDiff times AutoDiff +template +inline AutoDiff operator* (const AutoDiff & x, const AutoDiff & y) throw() +{ + AutoDiff res; + SCAL hx = x.Value(); + SCAL hy = y.Value(); + + res.Value() = hx*hy; + for (int i = 0; i < D; i++) + res.DValue(i) = hx*y.DValue(i) + hy*x.DValue(i); + + return res; +} + +/// AutoDiff times AutoDiff +template +inline AutoDiff sqr (const AutoDiff & x) throw() +{ + AutoDiff res; + SCAL hx = x.Value(); + res.Value() = hx*hx; + hx *= 2; + for (int i = 0; i < D; i++) + res.DValue(i) = hx*x.DValue(i); + return res; +} + +/// Inverse of AutoDiff +template +inline AutoDiff Inv (const AutoDiff & x) +{ + AutoDiff res(1.0 / x.Value()); + for (int i = 0; i < D; i++) + res.DValue(i) = -x.DValue(i) / (x.Value() * x.Value()); + return res; +} + + +/// AutoDiff div AutoDiff +template +inline AutoDiff operator/ (const AutoDiff & x, const AutoDiff & y) +{ + return x * Inv (y); +} + +/// AutoDiff div double +template +inline AutoDiff operator/ (const AutoDiff & x, double y) +{ + return (1/y) * x; +} + +/// double div AutoDiff +template +inline AutoDiff operator/ (double x, const AutoDiff & y) +{ + return x * Inv(y); +} + + + + +template +inline AutoDiff fabs (const AutoDiff & x) +{ + double abs = fabs (x.Value()); + AutoDiff res( abs ); + if (abs != 0.0) + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i) / abs; + else + for (int i = 0; i < D; i++) + res.DValue(i) = 0.0; + return res; +} + +//@} + +#endif diff --git a/libsrc/general/autoptr.hpp b/libsrc/general/autoptr.hpp new file mode 100644 index 00000000..b9084140 --- /dev/null +++ b/libsrc/general/autoptr.hpp @@ -0,0 +1,31 @@ +#ifndef FILE_AUTOPTR +#define FILE_AUTOPTR + +/**************************************************************************/ +/* File: autoptr.hpp */ +/* Author: STL, Joachim Schoeberl */ +/* Date: 29. Dec. 02 */ +/**************************************************************************/ + +template +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/libsrc/general/bitarray.cpp b/libsrc/general/bitarray.cpp new file mode 100644 index 00000000..1c36e5fc --- /dev/null +++ b/libsrc/general/bitarray.cpp @@ -0,0 +1,132 @@ +/**************************************************************************/ +/* File: bitarray.cc */ +/* Autho: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + data type BitArray +*/ + +#include +#include + + +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 + void BitArrayChar :: Set () + { + data = 1; + } + + template + void BitArrayChar :: Clear () + { + data = 0; + } + + + template + void BitArrayChar :: Invert () + { + for (int i = BASE; i < data.Size()+BASE; i++) + data[i] = 1 - data[i]; + } + + template + void BitArrayChar :: And (const BitArrayChar & ba2) + { + for (int i = BASE; i < data.Size()+BASE; i++) + data[i] &= ba2.data[i]; + } + + + template + void BitArrayChar :: 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/libsrc/general/bitarray.hpp b/libsrc/general/bitarray.hpp new file mode 100644 index 00000000..ee3478da --- /dev/null +++ b/libsrc/general/bitarray.hpp @@ -0,0 +1,222 @@ +#ifndef FILE_BitArray +#define FILE_BitArray + +/**************************************************************************/ +/* File: bitarray.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +#include + +/** + 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); + /// + INDEX Size () const + { + return size; + } + + /// + void Set (); + /// + void Set (INDEX i) + { + data[Addr(i)] |= Mask(i); + } + + void Clear (); + + + void Clear (INDEX i) + { + data[Addr(i)] &= ~Mask(i); + } + + bool Test (INDEX i) const + { + return (data[i / CHAR_BIT] & (char(1) << (i % CHAR_BIT) ) ) ? true : false; + } + + /// + void Invert (); + /// + void And (const BitArray & ba2); + /// + void Or (const BitArray & ba2); +private: + /// + inline unsigned char Mask (INDEX i) const + { + return char(1) << (i % CHAR_BIT); + } + /// + inline INDEX Addr (INDEX i) const + { + return (i / CHAR_BIT); + } + + /// + 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 << int (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 +class BitArrayChar +{ + /// + ARRAY 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 +inline ostream & operator<< (ostream & s, const BitArrayChar & 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/libsrc/general/dynamicmem.cpp b/libsrc/general/dynamicmem.cpp new file mode 100644 index 00000000..051aa8e9 --- /dev/null +++ b/libsrc/general/dynamicmem.cpp @@ -0,0 +1,205 @@ +#include +#include + +#ifdef SSE +#include +#endif + +#include +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]; + + if (!ptr) + { + cerr << "BaseynamicMem, cannot allocate " << s << " bytes" << endl; + Print (); + throw ("BaseDynamicMem::Alloc: out of memory"); + } + // ptr = (char*)malloc (s); + // ptr = (char*) _mm_malloc (s,16); + } + + void BaseDynamicMem :: ReAlloc (size_t s) + { + if (size == s) return; + + char * old = ptr; + ptr = new char[s]; + + if (!ptr) + { + cerr << "BaseynamicMem, cannot Reallocate " << s << " bytes" << endl; + Print (); + throw ("BaseDynamicMem::Alloc: out of memory"); + } + + + // ptr = (char*)malloc(s); + // ptr = (char*) _mm_malloc (s,16); + memmove (ptr, old, (s < size) ? s : size); + delete [] old; + // free (old); + // _mm_free (old); + size = s; + } + + void BaseDynamicMem :: Free () + { + delete [] ptr; + // free (ptr); + // _mm_free (ptr); + ptr = 0; + } + + void BaseDynamicMem :: Swap (BaseDynamicMem & m2) + { + size_t 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; + size_t mem = 0; + int cnt = 0; + while (p) + { + mem += p->size; + cnt++; + + cout << setw(10) << p->size << " Bytes"; + cout << ", addr = " << (void*)p->ptr; + 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; + } + + +#ifdef __INTEL_COMPILER +#pragma warning(push) +#pragma warning(disable:1684) +#endif + + void BaseDynamicMem :: GetUsed (int nr, char * ch) + { + BaseDynamicMem * p = first; + + for (int i = 0; i < nr; i++) + ch[i] = '0'; + + while (p) + { + long unsigned hptr = (long unsigned) (p->ptr); + // uintptr_t hptr = reinterpret_cast(p->ptr); //?? + + hptr /= (1024*1024); + hptr /= (4096/nr); + + size_t blocks = p->size / (1024*1024); + blocks /= (4096/nr); + + // cout << "ptr = " << (void*)(p->ptr) << ", size = " << p->size << ", hptr = " << hptr << " blocks = " << blocks << endl; + + for (size_t i = 0; i <= blocks; i++) + ch[hptr+i] = '1'; + + p = p->next; + } + + { + + BaseMoveableMem * pm = BaseMoveableMem::first; + while (pm) + { + long unsigned hptr = (long unsigned) p->ptr; + // uintptr_t hptr = reinterpret_cast(pm->ptr); + + hptr /= (1024*1024); + hptr /= (4096/nr); + + size_t blocks = pm->size / (1024*1024); + blocks /= (4096/nr); + + // cout << "moveable, ptr = " << (void*)(pm->ptr) << ", size = " << pm->size << ", hptr = " << hptr << " blocks = " << blocks << endl; + + for (size_t i = 0; i <= blocks; i++) + ch[hptr+i] = '1'; + + pm = pm->next; + } + } + + + + } + +#ifdef __INTEL_COMPILER +#pragma warning(pop) +#endif + +} diff --git a/libsrc/general/dynamicmem.hpp b/libsrc/general/dynamicmem.hpp new file mode 100644 index 00000000..483c9a7f --- /dev/null +++ b/libsrc/general/dynamicmem.hpp @@ -0,0 +1,95 @@ +#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 (); + static void GetUsed (int nr, char * ch); +}; + + +template +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 (BaseDynamicMem::Ptr()); + } + + T * Ptr() + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + + operator const T* () const + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + + operator T* () + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + + void Swap (DynamicMem & m2) + { + BaseDynamicMem::Swap (m2); + } +protected: + DynamicMem (const DynamicMem & m); + DynamicMem & operator= (const DynamicMem & m); +}; + +#endif diff --git a/libsrc/general/flags.cpp b/libsrc/general/flags.cpp new file mode 100644 index 00000000..b6b5ccf2 --- /dev/null +++ b/libsrc/general/flags.cpp @@ -0,0 +1,330 @@ +/**************************************************************************/ +/* File: flags.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 10. Oct. 96 */ +/**************************************************************************/ + +/* + Datatype Flags +*/ + +#include +#include + +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 & val) + { + ARRAY * strarray = new ARRAY; + 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 & val) + { + ARRAY * numarray = new ARRAY; + 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&)numflags).Elem(name); + else + return NULL; + } + + double * Flags :: GetNumFlagPtr (const char * name) + { + if (numflags.Used (name)) + return & ((SYMBOLTABLE&)numflags).Elem(name); + else + return NULL; + } + + bool Flags :: GetDefineFlag (const char * name) const + { + return defflags.Used (name); + } + + + const ARRAY & + Flags :: GetStringListFlag (const char * name) const + { + if (strlistflags.Used (name)) + return *strlistflags.Get(name); + else + { + static ARRAY hstra(0); + return hstra; + } + } + + const ARRAY & + Flags ::GetNumListFlag (const char * name) const + { + if (numlistflags.Used (name)) + return *numlistflags.Get(name); + else + { + static ARRAY hnuma(0); + return hnuma; + } + } + + + bool Flags :: StringFlagDefined (const char * name) const + { + return strflags.Used (name); + } + + bool Flags :: NumFlagDefined (const char * name) const + { + return numflags.Used (name); + } + + bool Flags :: StringListFlagDefined (const char * name) const + { + return strlistflags.Used (name); + } + + bool 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/libsrc/general/flags.hpp b/libsrc/general/flags.hpp new file mode 100644 index 00000000..59c365ee --- /dev/null +++ b/libsrc/general/flags.hpp @@ -0,0 +1,83 @@ +#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 strflags; + /// + SYMBOLTABLE numflags; + /// + SYMBOLTABLE defflags; + /// + SYMBOLTABLE*> strlistflags; + /// + SYMBOLTABLE*> 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 & val); + /// Sets double array flag + void SetFlag (const char * name, const ARRAY & 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 + bool GetDefineFlag (const char * name) const; + /// Returns string list flag, empty array if not exist + const ARRAY & GetStringListFlag (const char * name) const; + /// Returns num list flag, empty array if not exist + const ARRAY & GetNumListFlag (const char * name) const; + + + /// Test, if string flag is defined + bool StringFlagDefined (const char * name) const; + /// Test, if num flag is defined + bool NumFlagDefined (const char * name) const; + /// Test, if string list flag is defined + bool StringListFlagDefined (const char * name) const; + /// Test, if num list flag is defined + bool NumListFlagDefined (const char * name) const; +}; + +#endif + diff --git a/libsrc/general/hashtabl.cpp b/libsrc/general/hashtabl.cpp new file mode 100644 index 00000000..d5b77f3c --- /dev/null +++ b/libsrc/general/hashtabl.cpp @@ -0,0 +1,327 @@ +/**************************************************************************/ +/* File: hashtabl.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type HASHTABLE +*/ + +#include +#include +#include + +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_CLOSED_HASHTABLE :: + BASE_INDEX_CLOSED_HASHTABLE (int size) + : hash(size) + { + hash.SetName ("index-hashtable, hash"); + + invalid = -1; + for (int i = 1; i <= size; i++) + hash.Elem(i) = invalid; + } + + void BASE_INDEX_CLOSED_HASHTABLE :: + BaseSetSize (int size) + { + hash.SetSize(size); + for (int i = 1; i <= size; i++) + hash.Elem(i) = invalid; + } + + int BASE_INDEX_CLOSED_HASHTABLE :: + Position2 (const INDEX & ind) const + { + int i = HashValue(ind); + while (1) + { + i++; + if (i > hash.Size()) i = 1; + if (hash.Get(i) == ind) return i; + if (hash.Get(i) == invalid) return 0; + } + } + + int BASE_INDEX_CLOSED_HASHTABLE :: + PositionCreate2 (const INDEX & ind, int & apos) + { + int i = HashValue(ind); + int startpos = i; + while (1) + { + i++; + if (i > hash.Size()) i = 1; + if (hash.Get(i) == ind) + { + apos = i; + return 0; + } + if (hash.Get(i) == invalid) + { + hash.Elem(i) = ind; + apos = i; + return 1; + } + if (i == startpos) + throw NgException ("Try to set new element in full closed hashtable"); + } + } + + int BASE_INDEX_CLOSED_HASHTABLE :: UsedElements () const + { + int n = hash.Size(); + int cnt = 0; + for (int i = 1; i <= n; i++) + if (hash.Get(i) != invalid) + cnt++; + return cnt; + } + + + + + + + + + + + + BASE_INDEX_2_CLOSED_HASHTABLE :: + BASE_INDEX_2_CLOSED_HASHTABLE (int size) + : hash(size) + { + hash.SetName ("i2-hashtable, hash"); + + invalid = -1; + for (int i = 1; i <= size; i++) + hash.Elem(i).I1() = invalid; + } + + void BASE_INDEX_2_CLOSED_HASHTABLE :: + BaseSetSize (int size) + { + hash.SetSize(size); + for (int i = 1; i <= size; i++) + hash.Elem(i).I1() = invalid; + } + + + int BASE_INDEX_2_CLOSED_HASHTABLE :: + Position2 (const INDEX_2 & ind) const + { + int 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 = HashValue(ind); + int startpos = i; + 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; + } + if (i == startpos) + throw NgException ("Try to set new element in full closed hashtable"); + } + } + + int BASE_INDEX_2_CLOSED_HASHTABLE :: UsedElements () const + { + int n = hash.Size(); + int cnt = 0; + for (int i = 1; i <= n; i++) + if (hash.Get(i).I1() != invalid) + cnt++; + return cnt; + } + + + + + + + + + void BASE_INDEX_3_CLOSED_HASHTABLE :: + BaseSetSize (int size) + { + hash.SetSize(size); + for (int i = 0; i < size; i++) + hash[i].I1() = invalid; + } + + bool BASE_INDEX_3_CLOSED_HASHTABLE :: + PositionCreate2 (const INDEX_3 & ind, int & apos) + { + int i = HashValue(ind); + int startpos = i; + while (1) + { + /* + i++; + if (i >= hash.Size()) i = 0; + */ + i = (i+1) % hash.Size(); + if (hash[i] == ind) + { + apos = i; + return false; + } + if (hash[i].I1() == invalid) + { + hash[i] = ind; + apos = i; + return true; + } + if (i == startpos) + throw NgException ("Try to set new element in full closed hashtable"); + } + } +} + diff --git a/libsrc/general/hashtabl.hpp b/libsrc/general/hashtabl.hpp new file mode 100644 index 00000000..bc1781b9 --- /dev/null +++ b/libsrc/general/hashtabl.hpp @@ -0,0 +1,1322 @@ +#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 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 INDEX_HASHTABLE : private BASE_INDEX_HASHTABLE +{ + /// + TABLE 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 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 INDEX_2_HASHTABLE : public BASE_INDEX_2_HASHTABLE +{ + /// + TABLE 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); + } + + + void DeleteData () + { + int n = hash.Size(); + hash.SetSize (n); + cont.SetSize (n); + } + + + 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 +inline ostream & operator<< (ostream & ost, const INDEX_2_HASHTABLE & ht) +{ + for (typename INDEX_2_HASHTABLE::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 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 INDEX_3_HASHTABLE : private BASE_INDEX_3_HASHTABLE +{ + /// + TABLE 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 (); + + + + + + + + + + class Iterator + { + const INDEX_3_HASHTABLE & ht; + int bagnr, pos; + public: + Iterator (const INDEX_3_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_3 & ahash, T & acont) const + { + ahash = hash[it.BagNr()][it.Pos()]; + acont = cont[it.BagNr()][it.Pos()]; + } + + const INDEX_3 & 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 +inline ostream & operator<< (ostream & ost, const INDEX_3_HASHTABLE & ht) +{ + for (typename INDEX_3_HASHTABLE::Iterator it = ht.Begin(); + it != ht.End(); it++) + { + ost << ht.GetHash(it) << ": " << ht.GetData(it) << endl; + } + + return ost; +} + + + + + + + + + + + + + + + + + + + + + + + + +/// Closed Hashing HT + +class BASE_INDEX_CLOSED_HASHTABLE +{ +protected: + /// + MoveableArray hash; + /// + int invalid; +public: + /// + BASE_INDEX_CLOSED_HASHTABLE (int size); + + int Size() const { return hash.Size(); } + int UsedPos (int pos) const { return ! (hash.Get(pos) == invalid); } + int UsedElements () const; + + /// + int HashValue (const INDEX & ind) const + { + return ind % hash.Size() + 1; + } + + + int Position (const INDEX & ind) const + { + int i = HashValue(ind); + while (1) + { + if (hash.Get(i) == ind) return i; + if (hash.Get(i) == invalid) return 0; + i++; + if (i > hash.Size()) i = 1; + } + } + + // returns 1, if new postion is created + int PositionCreate (const INDEX & ind, int & apos) + { + int i = HashValue (ind); + if (hash.Get(i) == ind) + { + apos = i; + return 0; + } + if (hash.Get(i) == invalid) + { + hash.Elem(i) = ind; + apos = i; + return 1; + } + return PositionCreate2 (ind, apos); + } + +protected: + int Position2 (const INDEX & ind) const; + int PositionCreate2 (const INDEX & ind, int & apos); + void BaseSetSize (int asize); +}; + + +template +class INDEX_CLOSED_HASHTABLE : public BASE_INDEX_CLOSED_HASHTABLE +{ + /// + MoveableArray cont; + +public: + /// + INDEX_CLOSED_HASHTABLE (int size) + : BASE_INDEX_CLOSED_HASHTABLE(size), cont(size) + { + cont.SetName ("ind-hashtable, contents"); + } + + + void Set (const INDEX & ahash, const T & acont) + { + int pos; + PositionCreate (ahash, pos); + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; + } + + const T & Get (const INDEX & ahash) const + { + int pos = Position (ahash); + return cont.Get(pos); + } + + /// + bool Used (const INDEX & ahash) const + { + int pos = Position (ahash); + return (pos != 0); + } + + + /// + inline void SetData (int pos, const INDEX & ahash, const T & acont) + { + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; + } + + /// + void GetData (int pos, INDEX & ahash, T & acont) const + { + ahash = hash.Get(pos); + acont = cont.Get(pos); + } + + /// + inline void SetData (int pos, const T & acont) + { + cont.Elem(pos) = acont; + } + + /// + void GetData (int pos, T & acont) const + { + acont = cont.Get(pos); + } + + /// + const T & GetData (int pos) { return cont.Get(pos); } + /// + inline void SetSize (int size) + { + BaseSetSize(size); + cont.SetSize(size); + } + + /// + inline void DeleteData () + { SetSize (cont.Size()); } + + void SetName (const char * aname) + { + cont.SetName(aname); + hash.SetName(aname); + } +}; + + + + + + + +/// Closed Hashing HT + +class BASE_INDEX_2_CLOSED_HASHTABLE +{ +protected: + /// + MoveableArray 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; + } + } + + // 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 INDEX_2_CLOSED_HASHTABLE : public BASE_INDEX_2_CLOSED_HASHTABLE +{ + /// + MoveableArray 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 hash; + int invalid; + +protected: + // public: //SZ + BASE_INDEX_3_CLOSED_HASHTABLE (int size) + : hash(size) + { + hash.SetName ("i3-hashtable, hash"); + invalid = -1; + for (int i = 0; i < size; i++) + hash[i].I1() = invalid; + } + +public: + int Size() const + { + return hash.Size(); + } + + bool UsedPos (int pos) const + { + return ! (hash[pos].I1() == invalid); + } + + int UsedElements () const + { + int n = hash.Size(); + int cnt = 0; + for (int i = 0; i < n; i++) + if (hash[i].I1() != invalid) + cnt++; + return cnt; + } + + int HashValue (const INDEX_3 & ind) const + { + return (ind.I1() + 15 * ind.I2() + 41 * ind.I3()) % hash.Size(); + } + + int Position (const INDEX_3 & ind) const + { + int i = HashValue(ind); + while (1) + { + if (hash[i] == ind) return i; + if (hash[i].I1() == invalid) return -1; + i = (i+1) % hash.Size(); + } + } + + int Costs (const INDEX_3 & ind) const + { + int i = HashValue(ind); + int c = 1; + while (1) + { + if (hash[i] == ind) return c; + if (hash[i].I1() == invalid) return c; + i = (i+1) % hash.Size(); + c++; + } + } + + + + // returns true, if new postion is created + bool PositionCreate (const INDEX_3 & ind, int & apos) + { + int i = HashValue (ind); + if (hash[i] == ind) + { + apos = i; + return false; + } + if (hash[i].I1() == invalid) + { + hash[i] = ind; + apos = i; + return true; + } + return PositionCreate2 (ind, apos); + } + +protected: + bool PositionCreate2 (const INDEX_3 & ind, int & apos); + void BaseSetSize (int asize); +}; + + + +template +class INDEX_3_CLOSED_HASHTABLE : public BASE_INDEX_3_CLOSED_HASHTABLE +{ + MoveableArray cont; + +public: + INDEX_3_CLOSED_HASHTABLE (int size) + : BASE_INDEX_3_CLOSED_HASHTABLE(size), cont(size) + { + cont.SetName ("i3-hashtable, contents"); + } + + void Set (const INDEX_3 & ahash, const T & acont) + { + int pos; + PositionCreate (ahash, pos); + hash[pos] = ahash; + cont[pos] = acont; + } + + const T & Get (const INDEX_3 & ahash) const + { + return cont[Position (ahash)]; + } + + bool Used (const INDEX_3 & ahash) const + { + return (Position (ahash) != -1); + } + + void SetData (int pos, const INDEX_3 & ahash, const T & acont) + { + hash[pos] = ahash; + cont[pos] = acont; + } + + void GetData (int pos, INDEX_3 & ahash, T & acont) const + { + ahash = hash[pos]; + acont = cont[pos]; + } + + void SetData (int pos, const T & acont) + { + cont[pos] = acont; + } + + void GetData (int pos, T & acont) const + { + acont = cont[pos]; + } + + const T & GetData (int pos) const + { + return cont[pos]; + } + + void SetSize (int size) + { + BaseSetSize(size); + cont.SetSize(size); + } + + void PrintMemInfo (ostream & ost) const + { + cout << "Hashtable: " << Size() + << " entries of size " << sizeof(INDEX_3) << " + " << sizeof(T) + << " = " << Size() * (sizeof(INDEX_3) + sizeof(T)) << " bytes" << endl; + + } + + void DeleteData () + { + SetSize (cont.Size()); + } + + void SetName (const char * aname) + { + cont.SetName(aname); + hash.SetName(aname); + } +}; + + + + + + + + + + + + + + + + + +template +inline INDEX_3_HASHTABLE :: INDEX_3_HASHTABLE (int size) + : BASE_INDEX_3_HASHTABLE (size), cont(size) +{ + ; +} + +template +inline int INDEX_3_HASHTABLE :: 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 +inline void INDEX_3_HASHTABLE :: 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 +inline const T & INDEX_3_HASHTABLE :: Get (const INDEX_3 & ahash) const +{ + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + return cont.Get (bnr, pos); +} + +template +inline bool INDEX_3_HASHTABLE :: Used (const INDEX_3 & ahash) const +{ + return (Position (HashValue (ahash), ahash)) ? 1 : 0; +} + +template +inline int INDEX_3_HASHTABLE :: GetNBags () const +{ + return cont.Size(); +} + +template +inline int INDEX_3_HASHTABLE :: GetBagSize (int bnr) const +{ + return cont.EntrySize (bnr); +} + +template +inline void INDEX_3_HASHTABLE :: GetData (int bnr, int colnr, INDEX_3 & ahash, T & acont) const +{ + ahash = hash.Get(bnr, colnr); + acont = cont.Get(bnr, colnr); +} + +template +inline void INDEX_3_HASHTABLE :: SetData (int bnr, int colnr, const INDEX_3 & ahash, const T & acont) +{ + hash.Set(bnr, colnr, ahash); + cont.Set(bnr, colnr, acont); +} + +template +inline void INDEX_3_HASHTABLE :: SetSize (int size) +{ + hash.SetSize (size); + cont.SetSize (size); +} + +template +inline void INDEX_3_HASHTABLE :: DeleteData () +{ + int n = hash.Size(); + hash.SetSize (n); + cont.SetSize (n); +} + +template +inline void INDEX_3_HASHTABLE :: PrepareSet (const INDEX_3 & ahash) +{ + int bnr = HashValue (ahash); + hash.IncSizePrepare (bnr-1); + cont.IncSizePrepare (bnr-1); +} + + +template +inline void INDEX_3_HASHTABLE :: AllocateElements () +{ + hash.AllocateElementsOneBlock(); + cont.AllocateElementsOneBlock(); +} + + + +template +inline void INDEX_3_HASHTABLE :: PrintMemInfo (ostream & ost) const + { + ost << "Hash: " << endl; + hash.PrintMemInfo (ost); + ost << "Cont: " << endl; + cont.PrintMemInfo (ost); + } + + + + + +template +inline INDEX_HASHTABLE :: INDEX_HASHTABLE (int size) + : BASE_INDEX_HASHTABLE (size), cont(size) + { + ; + } + +template +inline void INDEX_HASHTABLE :: 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 +inline const T & INDEX_HASHTABLE :: Get (const INDEX & ahash) const + { + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + return cont.Get (bnr, pos); + } + +template +inline bool INDEX_HASHTABLE :: Used (const INDEX & ahash) const + { + return (Position (HashValue (ahash), ahash)) ? 1 : 0; + } + +template +inline int INDEX_HASHTABLE :: GetNBags () const + { + return hash.Size(); + } + +template +inline int INDEX_HASHTABLE :: GetBagSize (int bnr) const + { + return hash.EntrySize(bnr); + } + +template +inline void INDEX_HASHTABLE :: GetData (int bnr, int colnr, INDEX & ahash, T & acont) const + { + ahash = hash.Get(bnr, colnr); + acont = cont.Get(bnr, colnr); + } + +template +inline void INDEX_HASHTABLE :: PrintMemInfo (ostream & ost) const + { + ost << "Hash: " << endl; + hash.PrintMemInfo (ost); + ost << "Cont: " << endl; + cont.PrintMemInfo (ost); + } + + + + + + + + + + + + + + + +/* *********** Closed Hashing ************************* */ + + + +template +inline INDEX_2_CLOSED_HASHTABLE :: +INDEX_2_CLOSED_HASHTABLE (int size) + : BASE_INDEX_2_CLOSED_HASHTABLE(size), cont(size) +{ + cont.SetName ("i2-hashtable, contents"); +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +Set (const INDEX_2 & ahash, const T & acont) +{ + int pos; + PositionCreate (ahash, pos); + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline const T & INDEX_2_CLOSED_HASHTABLE :: +Get (const INDEX_2 & ahash) const +{ + int pos = Position (ahash); + return cont.Get(pos); +} + +template +inline bool INDEX_2_CLOSED_HASHTABLE :: +Used (const INDEX_2 & ahash) const +{ + int pos = Position (ahash); + return (pos != 0); +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +SetData (int pos, const INDEX_2 & ahash, const T & acont) +{ + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +GetData (int pos, INDEX_2 & ahash, T & acont) const +{ + ahash = hash.Get(pos); + acont = cont.Get(pos); +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +SetData (int pos, const T & acont) +{ + cont.Elem(pos) = acont; +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +GetData (int pos, T & acont) const +{ + acont = cont.Get(pos); +} + + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +SetSize (int size) +{ + BaseSetSize(size); + cont.SetSize(size); +} + + + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +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 +inline INDEX_3_CLOSED_HASHTABLE :: +INDEX_3_CLOSED_HASHTABLE (int size) + : BASE_INDEX_3_CLOSED_HASHTABLE(size), cont(size) +{ + cont.SetName ("i3-hashtable, contents"); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +Set (const INDEX_3 & ahash, const T & acont) +{ + int pos; + PositionCreate (ahash, pos); + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline const T & INDEX_3_CLOSED_HASHTABLE :: +Get (const INDEX_3 & ahash) const +{ + int pos = Position (ahash); + return cont[pos]; +} + +template +inline bool INDEX_3_CLOSED_HASHTABLE :: +Used (const INDEX_3 & ahash) const +{ + int pos = Position (ahash); + return (pos != 0); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +SetData (int pos, const INDEX_3 & ahash, const T & acont) +{ + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +GetData (int pos, INDEX_3 & ahash, T & acont) const +{ + ahash = hash.Get(pos); + acont = cont.Get(pos); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +SetData (int pos, const T & acont) +{ + cont.Elem(pos) = acont; +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +GetData (int pos, T & acont) const +{ + acont = cont.Get(pos); +} + +template +inline const T & INDEX_3_CLOSED_HASHTABLE :: +GetData (int pos) const +{ + return cont.Get(pos); +} + + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +SetSize (int size) +{ + BaseSetSize(size); + cont.SetSize(size); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +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/libsrc/general/moveablemem.cpp b/libsrc/general/moveablemem.cpp new file mode 100644 index 00000000..e7f3c1da --- /dev/null +++ b/libsrc/general/moveablemem.cpp @@ -0,0 +1,271 @@ +#include +#include + +#include +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); + ptr = new char[s]; + + if (!ptr) + { + cerr << "BaseynamicMem, cannot allocate " << s << " bytes" << endl; + Print (); + throw ("BaseDynamicMem::Alloc: out of memory"); + } + + return; + } + + + used += s - size; + + size_t 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); + largeblock = new char[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 = new char[s]; + + if (!ptr) + { + cerr << "BaseynamicMem, cannot Reallocate " << s << " bytes" << endl; + Print (); + throw ("BaseDynamicMem::Alloc: out of memory"); + } + + + + memmove (ptr, old, (s < size) ? s : size); + //free (old); + delete [] old; + size = s; + return; + } + + Alloc (s); +} + +void BaseMoveableMem :: MoveTo (size_t newpos) +{ + // cout << "move block, oldpos = " << pos << "; newpos = " << newpos + // << ", size = " << size << endl; + static size_t 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); + delete [] 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() +{ + size_t 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; + long int mem = 0; + int cnt = 0; + while (p) + { + mem += long(p->size); + cnt++; + + cout << setw(10) << p->size << " Bytes"; + cout << ", pos = " << p->pos; + cout << ", addr = " << (void*)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/libsrc/general/moveablemem.hpp b/libsrc/general/moveablemem.hpp new file mode 100644 index 00000000..b0761ee2 --- /dev/null +++ b/libsrc/general/moveablemem.hpp @@ -0,0 +1,99 @@ +#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; } + char * Ptr() const { return ptr; } + void Swap (BaseMoveableMem & m2) throw(); +public: + void SetName (const char * aname); + static void Print (); + + friend class BaseDynamicMem; +}; + + + + +template +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 (BaseMoveableMem::Ptr()); + } + + T * Ptr() + { + return reinterpret_cast (BaseMoveableMem::Ptr()); + } + + operator T* () const + { + return reinterpret_cast (BaseMoveableMem::Ptr()); + } + + operator T* () + { + return reinterpret_cast (BaseMoveableMem::Ptr()); + } + + void Swap (MoveableMem & m2) + { + BaseMoveableMem::Swap (m2); + } +protected: + MoveableMem (const MoveableMem & m) { ; } + MoveableMem & operator= (const MoveableMem & m) { ; } +}; + +#endif diff --git a/libsrc/general/myadt.hpp b/libsrc/general/myadt.hpp new file mode 100644 index 00000000..ec074029 --- /dev/null +++ b/libsrc/general/myadt.hpp @@ -0,0 +1,46 @@ +#ifndef FILE_MYADT +#define FILE_MYADT + +/**************************************************************************/ +/* File: myadt.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + include for all abstract data types +*/ + + + +#include "../include/mystdlib.h" +#include "../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" +#include "profiler.hpp" +#include "netgenout.hpp" + +} + +#endif diff --git a/libsrc/general/mystring.cpp b/libsrc/general/mystring.cpp new file mode 100644 index 00000000..dc59c80e --- /dev/null +++ b/libsrc/general/mystring.cpp @@ -0,0 +1,426 @@ + +//************************************************************** +// +// 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 +#include + +#include +#include + + +namespace netgen +{ + + void ReadEnclString(istream & in, string & str, const char encl) + { + char currchar; + str = ""; + + in.get(currchar); + while(in && (currchar == ' ' || currchar == '\t' || currchar == '\n') ) + in.get(currchar); + + if(currchar == encl) + { + in.get(currchar); + while(in && currchar != encl) + { + str += currchar; + in.get(currchar); + } + } + else + { + in.putback(currchar); + in >> str; + } + } + + + + + + +void DefaultStringErrHandler() +{ + cerr << "Error : string operation out of range\n" << flush; +} + +void (*MyStr::ErrHandler)() = DefaultStringErrHandler; + + /* +MyStr::MyStr() +{ + length = 0; + str = shortstr; + str[0] = 0; +} + */ + +MyStr::MyStr(const char *s) +{ + length = unsigned(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 = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + +MyStr::MyStr(void * p) +{ + char buffer[32]; + sprintf(buffer, "%p", p); + length = unsigned(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 = unsigned(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 = unsigned(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 = unsigned(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 = unsigned(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 string & st) +{ + length = unsigned(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; + } + unsigned 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; + } +} + +string MyStr::cpp_string(void) const +{ + string aux(str,length); + return aux; +} + +/* +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/libsrc/general/mystring.hpp b/libsrc/general/mystring.hpp new file mode 100644 index 00000000..434ba9a3 --- /dev/null +++ b/libsrc/general/mystring.hpp @@ -0,0 +1,216 @@ + +//************************************************************** +// +// 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; + + +// extract string str which is enclosed by the given character encl from a given string in +void ReadEnclString(istream & in, string & str, const char encl); + + +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(void *); + MyStr(long); + MyStr(double); + MyStr(const Point3d& p); + MyStr(const Vec3d& p); + MyStr(const 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(); + string cpp_string(void) const; + + //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/libsrc/general/netgenout.hpp b/libsrc/general/netgenout.hpp new file mode 100644 index 00000000..2338445a --- /dev/null +++ b/libsrc/general/netgenout.hpp @@ -0,0 +1,184 @@ +#ifndef NETGEN_OUT_STREAM_HPP__ +#define NETGEN_OUT_STREAM_HPP__ + +// #include +// #include +// #include + +#ifdef PARALLEL +extern int id; +extern int ntasks; +#endif +extern int printmessage_importance; + + + +class Imp +{ + int importance; +public: + Imp () : importance(0) { ; } + + Imp ( int aimportance ) : importance(aimportance) { ; } + + int GetImp () const { return importance; } +}; + + +class Proc +{ + int proc; +public: + Proc () : proc(0) { ; } + + Proc ( int aproc ) : proc(aproc) { ; } + + int GetProc () const { return proc; } +}; + +class Procs +{ + const netgen::FlatArray procs; + +public: + + Procs ( const netgen::FlatArray & aprocs ) : procs (aprocs) { ; } + + const netgen::FlatArray & GetProcs () const { return procs; } +}; + + + +class NetgenOutStream +{ + ostream * out; + + bool print; + bool printheader; + + +public: + NetgenOutStream() : + out(&std::cout), + print(1), + printheader(1) + { + ; + } + + NetgenOutStream(ostream * aout, Imp imp ) : + out(aout), + printheader(1) + { + if ( netgen::printmessage_importance >= imp.GetImp() ) + print = true; + else + print = false; + } + + NetgenOutStream(ostream * aout, Proc proc ) : + out(aout), + printheader(1) + { +#ifdef PARALLEL + if ( netgen::id == proc.GetProc() ) + print = true; + else + print = false; +#else + if ( 0 == proc.GetProc() ) + print = true; + else + print = false; + +#endif + } + + NetgenOutStream(ostream * aout, Procs & procs ) : + out(aout), + printheader(1) + { +#ifdef PARALLEL + if ( procs.GetProcs().Contains(netgen::id) ) + print = true; + else + print = false; +#else + if ( procs.GetProcs().Contains(0) ) + print = true; + else + print = false; + +#endif + } + + ostream & OStream () + { + return *out; + } + + template + NetgenOutStream & operator<< (T & var) + { + if ( print ) + { +#ifdef PARALLEL + if ( printheader ) + { + *out << "proc " << netgen::id << ": "; + printheader = false; + } +#endif + *out << var; + } + return (*this); + } + + NetgenOutStream& operator<< (ostream& ( *pf )(ostream&)) + { + if ( print ) + *out << (*pf) ; + + return (*this); + } + + NetgenOutStream& operator<< (ios& ( *pf )(ios&)) + { + if ( print) + *out << (*pf) ; + + printheader = 1; + + return (*this); + } + + NetgenOutStream& operator<< (ios_base& ( *pf )(ios_base&)) + { + if (print ) + *out << (*pf) ; + return (*this); + } + + +}; + + +NetgenOutStream operator<< ( ostream & ost, Imp imp ); +NetgenOutStream operator<< ( ostream & ost, Proc proc ); +NetgenOutStream operator<< ( ostream & ost, Procs & procs ); +// { +// return ( NetgenOutStream ( &ost, imp.GetImp() ) ); +// } + +// template +// NetgenOutStream& operator<< (NetgenOutStream& out, T c ) +// { +// out.OStream() << c << endl; +// return out; +// } + + + + + +#endif diff --git a/libsrc/general/ngexception.cpp b/libsrc/general/ngexception.cpp new file mode 100644 index 00000000..2496f6b3 --- /dev/null +++ b/libsrc/general/ngexception.cpp @@ -0,0 +1,33 @@ +/**************************************************************************/ +/* File: ngexception.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 16. Jan. 02 */ +/**************************************************************************/ + +#include + +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/libsrc/general/ngexception.hpp b/libsrc/general/ngexception.hpp new file mode 100644 index 00000000..56c561aa --- /dev/null +++ b/libsrc/general/ngexception.hpp @@ -0,0 +1,30 @@ +#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/libsrc/general/optmem.cpp b/libsrc/general/optmem.cpp new file mode 100644 index 00000000..d3f939ac --- /dev/null +++ b/libsrc/general/optmem.cpp @@ -0,0 +1,64 @@ +/**************************************************************************/ +/* File: optmem.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 04. Apr. 97 */ +/**************************************************************************/ + +/* + Abstract data type ARRAY +*/ + + +#include +#include + +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++) + for (int i = 0; i < bablocks.Size(); i++) + delete [] bablocks[i]; + } + + void * BlockAllocator :: Alloc () + { + // return new char[size]; + if (!freelist) + { + // cout << "freelist = " << freelist << endl; + // 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/libsrc/general/optmem.hpp b/libsrc/general/optmem.hpp new file mode 100644 index 00000000..0015b20b --- /dev/null +++ b/libsrc/general/optmem.hpp @@ -0,0 +1,59 @@ +#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 bablocks; +public: + /// + BlockAllocator (unsigned asize, unsigned ablocks = 100); + /// + ~BlockAllocator (); + /// + + void * Alloc (); + /* + { + if (!freelist) + Alloc2(); + + void * p = freelist; + // freelist = *(void**)freelist; + freelist = *static_cast (freelist); + + return p; + } + */ + + + /// + void Free (void * p) + { + *(void**)p = freelist; + freelist = p; + } + + +private: + // void Alloc2 (); +}; + + + +#endif diff --git a/libsrc/general/parthreads.cpp b/libsrc/general/parthreads.cpp new file mode 100644 index 00000000..81e9d0b6 --- /dev/null +++ b/libsrc/general/parthreads.cpp @@ -0,0 +1,40 @@ +/**************************************************************************/ +/* File: parthreads.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + + +#include +#include + +/* + +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/libsrc/general/parthreads.hpp b/libsrc/general/parthreads.hpp new file mode 100644 index 00000000..a00ff9e2 --- /dev/null +++ b/libsrc/general/parthreads.hpp @@ -0,0 +1,129 @@ +#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 _MSC_VER + +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 + +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 = false) + : 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 = true; + } + void UnLock () + { + pthread_mutex_unlock (&mut); + locked = false; + } + /* + int TryLock () + { + return pthread_mutex_trylock (&mut); + } + */ +}; + +#endif + +#endif + +#endif diff --git a/libsrc/general/profiler.cpp b/libsrc/general/profiler.cpp new file mode 100644 index 00000000..f6b35664 --- /dev/null +++ b/libsrc/general/profiler.cpp @@ -0,0 +1,112 @@ +/**************************************************************************/ +/* File: profiler.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 19. Apr. 2002 */ +/**************************************************************************/ + + +#include + +namespace netgen +{ + //using namespace netgen; + + long int NgProfiler::tottimes[SIZE]; + long int NgProfiler::starttimes[SIZE]; + long int NgProfiler::counts[SIZE]; + string NgProfiler::names[SIZE]; + int NgProfiler::usedcounter[SIZE]; + + + NgProfiler :: NgProfiler() + { + for (int i = 0; i < SIZE; i++) + { + tottimes[i] = 0; + usedcounter[i] = 0; + } + + total_timer = CreateTimer ("total CPU time"); + StartTimer (total_timer); + } + + NgProfiler :: ~NgProfiler() + { + StopTimer (total_timer); + + //ofstream prof; + //prof.open("ng.prof"); + + // ofstream-constructor may be called after STL-stuff is destructed, + // which leads to an "order of destruction"-problem, + // thus we use the C-variant: + + char filename[100]; +#ifdef PARALLEL + sprintf (filename, "netgen.prof.%d", id); +#else + sprintf (filename, "netgen.prof"); +#endif + + FILE *prof = fopen(filename,"w"); + Print (prof); + fclose(prof); + } + + +// void NgProfiler :: Print (ostream & prof) +// { +// for (int i = 0; i < SIZE; i++) +// if (counts[i] != 0 || usedcounter[i] != 0) +// { +// prof.setf (ios::fixed, ios::floatfield); +// prof.setf (ios::showpoint); + +// prof // << "job " << setw(3) << i +// << "calls " << setw(8) << counts[i] +// << ", time " << setprecision(2) << setw(6) << double(tottimes[i]) / CLOCKS_PER_SEC << " sec"; + +// if (usedcounter[i]) +// prof << " " << names[i]; +// else +// prof << " " << i; + +// prof << endl; +// } +// } + + + void NgProfiler :: Print (FILE * prof) + { + for (int i = 0; i < SIZE; i++) + if (counts[i] != 0 || usedcounter[i] != 0) + { + //fprintf(prof,"job %3i calls %8i, time %6.2f sec",i,counts[i],double(tottimes[i]) / CLOCKS_PER_SEC); + fprintf(prof,"calls %8li, time %6.2f sec",counts[i],double(tottimes[i]) / CLOCKS_PER_SEC); + if(usedcounter[i]) + fprintf(prof," %s",names[i].c_str()); + else + fprintf(prof," %i",i); + fprintf(prof,"\n"); + } + } + + int NgProfiler :: CreateTimer (const string & name) + { + for (int i = SIZE-1; i > 0; i--) + if(names[i] == name) + return i; + + for (int i = SIZE-1; i > 0; i--) + if (!usedcounter[i]) + { + usedcounter[i] = 1; + names[i] = name; + return i; + } + return -1; + } + + + NgProfiler prof; +} diff --git a/libsrc/general/profiler.hpp b/libsrc/general/profiler.hpp new file mode 100644 index 00000000..b08708be --- /dev/null +++ b/libsrc/general/profiler.hpp @@ -0,0 +1,62 @@ +#ifndef FILE_NG_PROFILER +#define FILE_NG_PROFILER + +/**************************************************************************/ +/* File: profiler.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 5. Jan. 2005 */ +/**************************************************************************/ + + + +#ifdef VTRACE +#include "vt_user.h" +#else + #define VT_USER_START(n) + #define VT_USER_END(n) + #define VT_TRACER(n) +#endif + + + +class NgProfiler +{ + enum { SIZE = 1000 }; + + static long int tottimes[SIZE]; + static long int starttimes[SIZE]; + static long int counts[SIZE]; + static string names[SIZE]; + static int usedcounter[SIZE]; + + int total_timer; +public: + NgProfiler(); + ~NgProfiler(); + static int CreateTimer (const string & name); + + static void StartTimer (int nr) + { + starttimes[nr] = clock(); counts[nr]++; + VT_USER_START (const_cast (names[nr].c_str())); + } + static void StopTimer (int nr) + { + tottimes[nr] += clock()-starttimes[nr]; + VT_USER_END (const_cast (names[nr].c_str())); + } + + //static void Print (ostream & ost); + static void Print (FILE * prof); + + class RegionTimer + { + int nr; + public: + RegionTimer (int anr) : nr(anr) + { StartTimer (nr); } + ~RegionTimer () { StopTimer (nr); } + }; +}; + +#endif diff --git a/libsrc/general/seti.cpp b/libsrc/general/seti.cpp new file mode 100644 index 00000000..e7f5b2ea --- /dev/null +++ b/libsrc/general/seti.cpp @@ -0,0 +1,70 @@ +#include +#include + + +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/libsrc/general/seti.hpp b/libsrc/general/seti.hpp new file mode 100644 index 00000000..4ca0b8eb --- /dev/null +++ b/libsrc/general/seti.hpp @@ -0,0 +1,45 @@ +#ifndef FILE_SETI +#define FILE_SETI + + +/**************************************************************************/ +/* File: seti.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Mar. 98 */ +/**************************************************************************/ + +/** + Set of Integers + */ +class IndexSet +{ + ARRAY 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 & Array() { return set; } +}; + +#endif + diff --git a/libsrc/general/sort.cpp b/libsrc/general/sort.cpp new file mode 100644 index 00000000..264a132a --- /dev/null +++ b/libsrc/general/sort.cpp @@ -0,0 +1,75 @@ +/**************************************************************************/ +/* File: sort.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 07. Jan. 00 */ +/**************************************************************************/ + +/* + Sorting +*/ + + +#include +#include +#include + +namespace netgen +{ + +void Sort (const ARRAY & values, + ARRAY & 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 & values, + ARRAY & 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 & values, + ARRAY & 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/libsrc/general/sort.hpp b/libsrc/general/sort.hpp new file mode 100644 index 00000000..f65aa24f --- /dev/null +++ b/libsrc/general/sort.hpp @@ -0,0 +1,42 @@ +#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 & values, + ARRAY & order); + +extern void QickSort (const ARRAY & values, + ARRAY & order); + + + + +template +inline void BubbleSort (int size, T * data) +{ + T hv; + for (int i = 0; i < size; i++) + for (int j = i+1; j < size; j++) + if (data[i] > data[j]) + { + hv = data[i]; + data[i] = data[j]; + data[j] = hv; + } +} + +template +inline void BubbleSort (ARRAY & data) +{ + if(data.Size() > 0) + BubbleSort (data.Size(), &data[data.Begin()]); +} + +#endif diff --git a/libsrc/general/spbita2d.cpp b/libsrc/general/spbita2d.cpp new file mode 100644 index 00000000..5badfe9a --- /dev/null +++ b/libsrc/general/spbita2d.cpp @@ -0,0 +1,172 @@ +/**************************************************************************/ +/* File: spbita2d.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Implementation of sparse 2 dimensional bitarray +*/ + + +#include +#include + +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/libsrc/general/spbita2d.hpp b/libsrc/general/spbita2d.hpp new file mode 100644 index 00000000..db656653 --- /dev/null +++ b/libsrc/general/spbita2d.hpp @@ -0,0 +1,56 @@ +#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/libsrc/general/stack.hpp b/libsrc/general/stack.hpp new file mode 100644 index 00000000..db8dfad2 --- /dev/null +++ b/libsrc/general/stack.hpp @@ -0,0 +1,112 @@ +#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 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 elems; + /// + INDEX size; +}; + + + + +/* + + Stack class, based on a resizable array + + */ + +template +inline STACK :: STACK (INDEX asize, INDEX ainc) + : elems(asize, ainc) +{ + size = 0; +} + + +template +inline STACK :: ~STACK () +{ + ; +} + + +template +inline void STACK :: Push (const T & el) +{ + if (size < elems.Size()) + elems.Elem(++size) = el; + else + { + elems.Append(el); + size++; + } +} + + +template +inline T & STACK :: Pop () +{ + return elems.Elem(size--); +} + + +template +const inline T & STACK :: Top () const +{ + return elems.Get(size); +} + +template +inline int STACK :: IsEmpty () const +{ + return (size == 0); +} + + +template +inline void STACK :: MakeEmpty () +{ + size = 0; +} + + + +#endif diff --git a/libsrc/general/symbolta.cpp b/libsrc/general/symbolta.cpp new file mode 100644 index 00000000..bd35ac7c --- /dev/null +++ b/libsrc/general/symbolta.cpp @@ -0,0 +1,52 @@ +/**************************************************************************/ +/* File: symbolta.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type Symbol Table +*/ + +#include +#include + + +#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/libsrc/general/symbolta.hpp b/libsrc/general/symbolta.hpp new file mode 100644 index 00000000..38895dee --- /dev/null +++ b/libsrc/general/symbolta.hpp @@ -0,0 +1,158 @@ +#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 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 SYMBOLTABLE : public BASE_SYMBOLTABLE +{ +private: + /// Associated data + ARRAY 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 bool 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 & operator= (SYMBOLTABLE &); +}; + + + + +template +inline SYMBOLTABLE :: SYMBOLTABLE () +{ + ; +} + + +template +inline INDEX SYMBOLTABLE :: Size() const +{ + return data.Size(); +} + +template +inline T & SYMBOLTABLE :: Elem (const char * name) +{ + int i = Index (name); + if (i) + return data.Elem (i); + else + return data.Elem(1); +} + +template +inline const T & SYMBOLTABLE :: Get (const char * name) const +{ + int i; + i = Index (name); + if (i) + return data.Get(i); + else + return data.Get(1); +} + +template +inline const T & SYMBOLTABLE :: Get (int i) const +{ + return data.Get(i); +} + +template +inline const char* SYMBOLTABLE :: GetName (int i) const +{ + return names.Get(i); +} + +template +inline void SYMBOLTABLE :: 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 +inline bool SYMBOLTABLE :: Used (const char * name) const +{ + return (Index(name)) ? true : false; +} + +template +inline void SYMBOLTABLE :: DeleteAll () +{ + DelNames(); + data.DeleteAll(); +} + + +#endif diff --git a/libsrc/general/table.cpp b/libsrc/general/table.cpp new file mode 100644 index 00000000..b6168374 --- /dev/null +++ b/libsrc/general/table.cpp @@ -0,0 +1,193 @@ +/**************************************************************************/ +/* File: table.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type TABLE +*/ + +#include +#include + +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 & 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 :: ChangeSize (int size) + { + int oldsize = data.Size(); + if (size == oldsize) + return; + + if (size < oldsize) + for (int i = size; i < oldsize; i++) + delete [] (char*)data[i].col; + + data.SetSize(size); + + for (int i = oldsize; 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; + } + + void BASE_TABLE :: SetElementSizesToMaxSizes () + { + for (int i = 0; i < data.Size(); i++) + data[i].size = data[i].maxsize; + } + +} diff --git a/libsrc/general/table.hpp b/libsrc/general/table.hpp new file mode 100644 index 00000000..f9ed02f1 --- /dev/null +++ b/libsrc/general/table.hpp @@ -0,0 +1,223 @@ +#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 data; + char * oneblock; + +public: + /// + BASE_TABLE (int size); + /// + BASE_TABLE (const FlatArray & entrysizes, int elemsize); + /// + ~BASE_TABLE (); + /// + void SetSize (int size); + /// + void ChangeSize (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; + + void SetElementSizesToMaxSizes (); +}; + + + + + + + +/** + 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 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 maximal element size table + inline TABLE (const FlatArray & entrysizes) + : BASE_TABLE (FlatArray (entrysizes.Size(), const_cast(&entrysizes[BASE])), + sizeof(T)) + { ; } + + /// Changes Size of table to size, deletes data + inline void SetSize (int size) + { + BASE_TABLE::SetSize (size); + } + + /// Changes Size of table to size, keep data + inline void ChangeSize (int size) + { + BASE_TABLE::ChangeSize (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 enough memory + 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 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 (data[i-BASE].size, (T*)data[i-BASE].col); + } +}; + + +template +inline ostream & operator<< (ostream & ost, const TABLE & table) +{ + for (int i = BASE; i < table.Size()+BASE; i++) + { + ost << i << ": "; + FlatArray row = table[i]; + ost << "(" << row.Size() << ") "; + for (int j = 0; j < row.Size(); j++) + ost << row[j] << " "; + ost << endl; + } + return ost; +} + +#endif + diff --git a/libsrc/general/template.hpp b/libsrc/general/template.hpp new file mode 100644 index 00000000..9fb378a7 --- /dev/null +++ b/libsrc/general/template.hpp @@ -0,0 +1,448 @@ +#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 +/** 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 +inline void Swap (T & a, T & b) +{ + T temp = a; + a = b; + b = temp; +} + +/* +template +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) + { + if (i1 > i2) Swap (i1, i2); + if (i2 > i3) Swap (i2, i3); + if (i1 > i2) Swap (i1, i2); + return INDEX_3 (i1, i2, i3); + } + + 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 +inline T min2 (T a, T b) +{ + /// + return (a < b) ? a : b; +} +/// +template +inline T max2 (T a, T b) +{ + /// + return (a > b) ? a : b; +} +/// +template +inline T min3 (T a, T b, T c) +{ + /// + return (a < b) ? (a < c) ? a : c + : (b < c) ? b : c; +} +/// +template +inline T max3 (T a, T b, T c) +{ + /// + return (a > b) ? ((a > c) ? a : c) + : ((b > c) ? b : c); +} + +/// + +/// +template +inline int sgn (T a) +{ + return (a > 0) ? 1 : ( ( a < 0) ? -1 : 0 ); +} + +/// +template +inline T sqr (const T a) +{ + return a * a; +} + +/// +template +inline T pow3 (const T a) +{ + return a * a * a; +} + + + +/* +template +void BubbleSort (int size, T * data); + +template +void MergeSort (int size, T * data, T * help); +*/ + + + + + +#endif diff --git a/libsrc/geom2d/Makefile.am b/libsrc/geom2d/Makefile.am new file mode 100644 index 00000000..2da8b3b7 --- /dev/null +++ b/libsrc/geom2d/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libgeom2d.a +libgeom2d_a_SOURCES = genmesh2d.cpp geom2dmesh.cpp spline.cpp \ + splinegeometry.cpp diff --git a/libsrc/geom2d/Makefile.in b/libsrc/geom2d/Makefile.in new file mode 100644 index 00000000..b4f9a874 --- /dev/null +++ b/libsrc/geom2d/Makefile.in @@ -0,0 +1,445 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/geom2d +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libgeom2d_a_AR = $(AR) $(ARFLAGS) +libgeom2d_a_LIBADD = +am_libgeom2d_a_OBJECTS = genmesh2d.$(OBJEXT) geom2dmesh.$(OBJEXT) \ + spline.$(OBJEXT) splinegeometry.$(OBJEXT) +libgeom2d_a_OBJECTS = $(am_libgeom2d_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgeom2d_a_SOURCES) +DIST_SOURCES = $(libgeom2d_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libgeom2d.a +libgeom2d_a_SOURCES = genmesh2d.cpp geom2dmesh.cpp spline.cpp \ + splinegeometry.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/geom2d/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/geom2d/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libgeom2d.a: $(libgeom2d_a_OBJECTS) $(libgeom2d_a_DEPENDENCIES) + -rm -f libgeom2d.a + $(libgeom2d_a_AR) libgeom2d.a $(libgeom2d_a_OBJECTS) $(libgeom2d_a_LIBADD) + $(RANLIB) libgeom2d.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genmesh2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom2dmesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splinegeometry.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/geom2d/genmesh2d.cpp b/libsrc/geom2d/genmesh2d.cpp new file mode 100644 index 00000000..a63e2a14 --- /dev/null +++ b/libsrc/geom2d/genmesh2d.cpp @@ -0,0 +1,270 @@ +#include +#include +#include +#include "meshing.hpp" + +namespace netgen +{ + + // static ARRAY > points2; + // static ARRAY lp1, lp2; + + + extern void Optimize2d (Mesh & mesh, MeshingParameters & mp); + + + + + + + + void MeshFromSpline2D (SplineGeometry2d & geometry, + Mesh *& mesh, + MeshingParameters & mp) + { + PrintMessage (1, "Generate Mesh from spline geometry"); + + double h = mp.maxh; + + Box<2> bbox = geometry.GetBoundingBox (); + + if (bbox.Diam() < h) + { + h = bbox.Diam(); + mp.maxh = h; + } + + mesh = new Mesh; + mesh->SetDimension (2); + + geometry.PartitionBoundary (h, *mesh); + + // marks mesh points for hp-refinement + for (int i = 0; i < geometry.GetNP(); i++) + if (geometry.GetPoint(i).hpref) + { + double mindist = 1e99; + PointIndex mpi(0); + 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].Singularity(1.); + } + + + int maxdomnr = 0; + for (SegmentIndex 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 (int i = 1; i <= maxdomnr; i++) + mesh->AddFaceDescriptor (FaceDescriptor (i, 0, 0, i)); + + // set ARRAY bcnames... + // number of bcnames + int maxsegmentindex = 0; + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + if ( (*mesh)[si].si > maxsegmentindex) maxsegmentindex = (*mesh)[si].si; + } + + mesh->SetNBCNames(maxsegmentindex); + + for ( int sindex = 0; sindex < maxsegmentindex; sindex++ ) + { + mesh->SetBCName ( sindex, geometry.GetBCName( sindex+1 ) ); + } + + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + (*mesh)[si].SetBCName ( (*mesh).GetBCNamePtr( (*mesh)[si].si-1 ) ); + } + 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 + + int hquad = mparam.quad; + + + for (int domnr = 1; domnr <= maxdomnr; domnr++) + if (geometry.GetDomainTensorMeshing (domnr)) + { // tensor product mesh + + ARRAY nextpi(bnp); + ARRAY si1(bnp), si2(bnp); + PointIndex firstpi; + + nextpi = -1; + si1 = -1; + si2 = -1; + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + int p1 = -1, p2 = -2; + + if ( (*mesh)[si].domin == domnr) + { p1 = (*mesh)[si].p1; p2 = (*mesh)[si].p2; } + if ( (*mesh)[si].domout == domnr) + { p1 = (*mesh)[si].p2; p2 = (*mesh)[si].p1; } + + if (p1 == -1) continue; + + nextpi[p1] = p2; // counter-clockwise + + int index = (*mesh)[si].si; + if (si1[p1] != index && si2[p1] != index) + { si2[p1] = si1[p1]; si1[p1] = index; } + if (si1[p2] != index && si2[p2] != index) + { si2[p2] = si1[p2]; si1[p2] = index; } + } + + PointIndex c1(0), c2, c3, c4; // 4 corner points + int nex = 1, ney = 1; + + for (PointIndex pi = 1; pi <= si2.Size(); pi++) + if (si2[pi] != -1) + { c1 = pi; break; } + + for (c2 = nextpi[c1]; si2[c2] == -1; c2 = nextpi[c2], nex++); + for (c3 = nextpi[c2]; si2[c3] == -1; c3 = nextpi[c3], ney++); + for (c4 = nextpi[c3]; si2[c4] == -1; c4 = nextpi[c4]); + + + + ARRAY pts ( (nex+1) * (ney+1) ); // x ... inner loop + pts = -1; + + for (PointIndex pi = c1, i = 0; pi != c2; pi = nextpi[pi], i++) + pts[i] = pi; + for (PointIndex pi = c2, i = 0; pi != c3; pi = nextpi[pi], i++) + pts[(nex+1)*i+nex] = pi; + for (PointIndex pi = c3, i = 0; pi != c4; pi = nextpi[pi], i++) + pts[(nex+1)*(ney+1)-i-1] = pi; + for (PointIndex pi = c4, i = 0; pi != c1; pi = nextpi[pi], i++) + pts[(nex+1)*(ney-i)] = pi; + + + for (PointIndex pix = nextpi[c1], ix = 0; pix != c2; pix = nextpi[pix], ix++) + for (PointIndex piy = nextpi[c2], iy = 0; piy != c3; piy = nextpi[piy], iy++) + { + Point<3> p = (*mesh)[pix] + ( (*mesh)[piy] - (*mesh)[c2] ); + pts[(nex+1)*(iy+1) + ix+1] = mesh -> AddPoint (p , 1, FIXEDPOINT); + } + + for (int i = 0; i < ney; i++) + for (int j = 0; j < nex; j++) + { + Element2d el(QUAD); + el[0] = pts[i*(nex+1)+j]; + el[1] = pts[i*(nex+1)+j+1]; + el[2] = pts[(i+1)*(nex+1)+j+1]; + el[3] = pts[(i+1)*(nex+1)+j]; + el.SetIndex (domnr); + + mesh -> AddSurfaceElement (el); + } + } + + + + + for (int domnr = 1; domnr <= maxdomnr; domnr++) + { + if (geometry.GetDomainTensorMeshing (domnr)) continue; + + if ( geometry.GetDomainMaxh ( domnr ) > 0 ) + h = geometry.GetDomainMaxh(domnr); + + + PrintMessage (3, "Meshing domain ", domnr, " / ", maxdomnr); + + int oldnf = mesh->GetNSE(); + + mparam.quad = hquad || geometry.GetDomainQuadMeshing (domnr); + + Meshing2 meshing (Box<3> (pmin, pmax)); + + for (PointIndex pi = PointIndex::BASE; pi < bnp+PointIndex::BASE; pi++) + meshing.AddPoint ( (*mesh)[pi], pi); + + + PointGeomInfo gi; + gi.trignum = 1; + for (SegmentIndex 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 (SurfaceElementIndex sei = oldnf; sei < mesh->GetNSE(); sei++) + (*mesh)[sei].SetIndex (domnr); + + + // astrid + char * material; + geometry.GetMaterial( domnr, material ); + if ( material ) + { + (*mesh).SetMaterial ( domnr, material ); + } + + } + + mparam.quad = hquad; + + + + 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/libsrc/geom2d/geom2dmesh.cpp b/libsrc/geom2d/geom2dmesh.cpp new file mode 100644 index 00000000..2ff13d82 --- /dev/null +++ b/libsrc/geom2d/geom2dmesh.cpp @@ -0,0 +1,85 @@ +#include + +#include +#include +#include + +namespace netgen +{ + + Refinement2d :: Refinement2d (const SplineGeometry2d & ageometry) + : Refinement(), geometry(ageometry) + { + ; + } + + Refinement2d :: ~Refinement2d () + { + ; + } + + + void Refinement2d :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) + { + newp = p1+secpoint*(p2-p1); + newgi.trignum = 1; + } + + + + void Refinement2d :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & 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); + }; + + + + Vec<3> Refinement2d :: GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const + { + Vec<2> t2d = geometry.GetSplines().Get(ap1.edgenr) -> GetTangent(ap1.dist); + return Vec<3> (t2d(0), t2d(1), 0); + } + + Vec<3> Refinement2d :: GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const + { + return Vec<3> (0,0,1); + } + + + void Refinement2d :: ProjectToSurface (Point<3> & p, int surfi, const PointGeomInfo & /* gi */) + { + p(2) = 0; + } + + + void Refinement2d :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & egi) const + { + Point<2> p2d (p(0), p(1)), pp; + double t; + geometry.GetSplines().Get(egi.edgenr) -> Project (p2d, pp, t); + p = Point<3> (pp(0), pp(1), 0); + } +} diff --git a/libsrc/geom2d/geom2dmesh.hpp b/libsrc/geom2d/geom2dmesh.hpp new file mode 100644 index 00000000..88971043 --- /dev/null +++ b/libsrc/geom2d/geom2dmesh.hpp @@ -0,0 +1,49 @@ +#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 Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi); + + + virtual Vec<3> GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const; + + virtual Vec<3> GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const; + + virtual void ProjectToSurface (Point<3> & p, int surfi, const PointGeomInfo & /* gi */); + + virtual void ProjectToEdge (Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & egi) const; +}; + + + + + + +#endif diff --git a/libsrc/geom2d/geometry2d.hpp b/libsrc/geom2d/geometry2d.hpp new file mode 100644 index 00000000..6601f58f --- /dev/null +++ b/libsrc/geom2d/geometry2d.hpp @@ -0,0 +1,20 @@ +#ifndef FILE_GEOMETRY2D +#define FILE_GEOMETRY2D + +/* *************************************************************************/ +/* File: geometry2d.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + +#include +#include + +namespace netgen +{ +#include "spline.hpp" +#include "splinegeometry.hpp" +#include "geom2dmesh.hpp" +} + +#endif diff --git a/libsrc/geom2d/spline.cpp b/libsrc/geom2d/spline.cpp new file mode 100644 index 00000000..f77c4875 --- /dev/null +++ b/libsrc/geom2d/spline.cpp @@ -0,0 +1,360 @@ +/* + +Spline curve for Mesh generator + +*/ + +#include +#include +#include +#include + +namespace netgen +{ +#include "spline.hpp" + + /* + template<> void SplineSeg3<2> :: Project (const Point<2> point, Point<2> & point_on_curve, double & t) const + { + double t_old = 0; + t = 0.5; + + Point<2> phi; + Vec<2> phip,phipp,phimp; + + int i=0; + + while(fabs(t-t_old) > 1e-8 && i<10) + { + GetDerivatives(t,phi,phip,phipp); + + t_old = t; + + phimp = phi-point; + + t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.); + + i++; + } + + if(i<10) + { + point_on_curve = GetPoint(t); + + double dist = Dist(point,point_on_curve); + + phi = GetPoint(0); + double auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 0.; + point_on_curve = phi; + dist = auxdist; + } + phi = GetPoint(1); + auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 1.; + point_on_curve = phi; + dist = auxdist; + } + + } + else + { + double t0 = 0; + double t1 = 0.5; + double t2 = 1.; + + double d0,d1,d2; + + + //(*testout) << "2d newtonersatz" << endl; + while(t2-t0 > 1e-8) + { + + phi = GetPoint(t0); d0 = Dist(phi,point); + phi = GetPoint(t1); d1 = Dist(phi,point); + phi = GetPoint(t2); d2 = Dist(phi,point); + + double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2); + + if(a <= 0) + { + if(d0 < d2) + t2 -= 0.3*(t2-t0); + else + t0 += 0.3*(t2-t0); + + t1 = 0.5*(t2+t0); + } + else + { + double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0); + + double auxt1 = -0.5*b/a; + + if(auxt1 < t0) + { + t2 -= 0.4*(t2-t0); + t0 = max2(0.,t0-0.1*(t2-t0)); + } + else if (auxt1 > t2) + { + t0 += 0.4*(t2-t0); + t2 = min2(1.,t2+0.1*(t2-t0)); + } + else + { + t1 = auxt1; + auxt1 = 0.25*(t2-t0); + t0 = max2(0.,t1-auxt1); + t2 = min2(1.,t1+auxt1); + } + + t1 = 0.5*(t2+t0); + } + + } + + + phi = GetPoint(t0); d0 = Dist(phi,point); + phi = GetPoint(t1); d1 = Dist(phi,point); + phi = GetPoint(t2); d2 = Dist(phi,point); + + double mind = d0; + t = t0; + if(d1 < mind) + { + t = t1; + mind = d1; + } + if(d2 < mind) + { + t = t2; + mind = d2; + } + + point_on_curve = GetPoint(t); + + } + } + + template<> void SplineSeg3<3> :: Project (const Point<3> point, Point<3> & point_on_curve, double & t) const + { + double t_old = -1; + + if(proj_latest_t > 0. && proj_latest_t < 1.) + t = proj_latest_t; + else + t = 0.5; + + Point<3> phi; + Vec<3> phip,phipp,phimp; + + int i=0; + + while(fabs(t-t_old) > 1e-8 && t > -0.5 && t < 1.5 && i<10) + { + GetDerivatives(t,phi,phip,phipp); + + t_old = t; + + phimp = phi-point; + + //t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.); + t -= (phip*phimp)/(phipp*phimp + phip*phip); + + i++; + } + + //if(i<10 && t > 0. && t < 1.) + if(i<10 && t > -0.4 && t < 1.4) + { + if(t < 0) + t = 0.; + if(t > 1) + t = 1.; + + point_on_curve = GetPoint(t); + + double dist = Dist(point,point_on_curve); + + phi = GetPoint(0); + double auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 0.; + point_on_curve = phi; + dist = auxdist; + } + phi = GetPoint(1); + auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 1.; + point_on_curve = phi; + dist = auxdist; + } + } + else + { + double t0 = 0; + double t1 = 0.5; + double t2 = 1.; + + double d0,d1,d2; + + + //(*testout) << "newtonersatz" << endl; + while(t2-t0 > 1e-8) + { + + phi = GetPoint(t0); d0 = Dist(phi,point); + phi = GetPoint(t1); d1 = Dist(phi,point); + phi = GetPoint(t2); d2 = Dist(phi,point); + + double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2); + + if(a <= 0) + { + if(d0 < d2) + t2 -= 0.3*(t2-t0); + else + t0 += 0.3*(t2-t0); + + t1 = 0.5*(t2+t0); + } + else + { + double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0); + + double auxt1 = -0.5*b/a; + + if(auxt1 < t0) + { + t2 -= 0.4*(t2-t0); + t0 = max2(0.,t0-0.1*(t2-t0)); + } + else if (auxt1 > t2) + { + t0 += 0.4*(t2-t0); + t2 = min2(1.,t2+0.1*(t2-t0)); + } + else + { + t1 = auxt1; + auxt1 = 0.25*(t2-t0); + t0 = max2(0.,t1-auxt1); + t2 = min2(1.,t1+auxt1); + } + + t1 = 0.5*(t2+t0); + } + + } + + + phi = GetPoint(t0); d0 = Dist(phi,point); + phi = GetPoint(t1); d1 = Dist(phi,point); + phi = GetPoint(t2); d2 = Dist(phi,point); + + double mind = d0; + t = t0; + if(d1 < mind) + { + t = t1; + mind = d1; + } + if(d2 < mind) + { + t = t2; + mind = d2; + } + + point_on_curve = GetPoint(t); + } + //(*testout) << " latest_t " << proj_latest_t << " t " << t << endl; + + proj_latest_t = t; + } + */ + + void CalcPartition (double l, double h, double r1, double r2, + double ra, double elto0, ARRAY & 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); + } + + template<> + double SplineSeg3<2> :: MaxCurvature(void) const + { + Vec<2> v1 = p1-p2; + Vec<2> v2 = p3-p2; + double l1 = v1.Length(); + double l2 = v2.Length(); + + double cosalpha = (v1*v2)/(l1*l2); + + + return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha)); + } + + template<> + double SplineSeg3<3> :: MaxCurvature(void) const + { + Vec<3> v1 = p1-p2; + Vec<3> v2 = p3-p2; + double l1 = v1.Length(); + double l2 = v2.Length(); + + double cosalpha = v1*v2/(l1*l2); + + + return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha)); + } + + + + +} diff --git a/libsrc/geom2d/spline.hpp b/libsrc/geom2d/spline.hpp new file mode 100644 index 00000000..d5ae3777 --- /dev/null +++ b/libsrc/geom2d/spline.hpp @@ -0,0 +1,1041 @@ +#ifndef FILE_SPLINE_HPP +#define FILE_SPLINE_HPP + +/**************************************************************************/ +/* File: spline.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 24. Jul. 96 */ +/**************************************************************************/ + + +void CalcPartition (double l, double h, double r1, double r2, + double ra, double elto0, ARRAY & points); + +/* + Spline curves for 2D mesh generation +*/ + + +/// Geometry point +template < int D > +class GeomPoint : public Point +{ +public: + /// refinement to point + double refatpoint; + bool hpref; + + GeomPoint () + { ; } + + /// + GeomPoint (double ax, double ay, double aref = 1, bool ahpref=false) + : Point (ax, ay), refatpoint(aref), hpref(ahpref) { ; } + GeomPoint (double ax, double ay, double az, double aref, bool ahpref=false) + : Point (ax, ay, az), refatpoint(aref), hpref(ahpref) { ; } + GeomPoint (const Point & ap, double aref = 1, bool ahpref=false) + : Point(ap), refatpoint(aref), hpref(ahpref) { ; } +}; + + + +/// base class for 2d - segment +template < int D > +class SplineSeg +{ +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 GetPoint (double t) const = 0; + /// returns a (not necessarily uniform) tangent vector for 0 <= t <= 1 + virtual Vec GetTangent (const double t) const + { cerr << "GetTangent not implemented for spline base-class" << endl; Vec dummy; return dummy;} + virtual void GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const {;} + /// partitionizes curve + void Partition (double h, double elto0, + Mesh & mesh, Point3dTree & searchtree, int segnr) const; + /// returns initial point on curve + virtual const GeomPoint & StartPI () const = 0; + /// returns terminal point on curve + virtual const GeomPoint & 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 */ + void PrintCoeff (ostream & ost) const; + + virtual void GetCoeff (Vector & coeffs) const = 0; + + virtual void GetPoints (int n, ARRAY > & points); + + /** calculates (2D) lineintersections: + for lines $$ a x + b y + c = 0 $$ the interecting points are calculated + and stored in points */ + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const + {points.SetSize(0);} + + virtual double MaxCurvature(void) const = 0; + + virtual string GetType(void) const {return "splinebase";} + + virtual void Project (const Point point, Point & point_on_curve, double & t) const + { cerr << "Project not implemented for spline base-class" << endl;} + + virtual void GetRawData (ARRAY & data) const + { cerr << "GetRawData not implemented for spline base-class" << endl;} + +}; + + +/// Straight line form p1 to p2 +template< int D > +class LineSeg : public SplineSeg +{ + /// + GeomPoint p1, p2; + //const GeomPoint &p1, &p2; +public: + /// + LineSeg (const GeomPoint & ap1, const GeomPoint & ap2); + /// + virtual double Length () const; + /// + virtual Point GetPoint (double t) const; + /// + virtual Vec GetTangent (const double t) const; + + + virtual void GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const; + /// + virtual const GeomPoint & StartPI () const { return p1; }; + /// + virtual const GeomPoint & EndPI () const { return p2; } + /// + virtual void GetCoeff (Vector & coeffs) const; + + virtual string GetType(void) const {return "line";} + + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const; + + virtual double MaxCurvature(void) const {return 0;} + + virtual void Project (const Point point, Point & point_on_curve, double & t) const; + + virtual void GetRawData (ARRAY & data) const; +}; + + +/// curve given by a rational, quadratic spline (including ellipses) +template< int D > +class SplineSeg3 : public SplineSeg +{ + /// + GeomPoint p1, p2, p3; + //const GeomPoint &p1, &p2, &p3; + + mutable double proj_latest_t; +public: + /// + SplineSeg3 (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3); + /// + virtual Point GetPoint (double t) const; + /// + virtual Vec GetTangent (const double t) const; + + + virtual void GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const; + /// + virtual const GeomPoint & StartPI () const { return p1; }; + /// + virtual const GeomPoint & EndPI () const { return p3; } + /// + virtual void GetCoeff (Vector & coeffs) const; + + virtual string GetType(void) const {return "spline3";} + + const GeomPoint & TangentPoint (void) const { return p2; } + + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const; + + virtual double MaxCurvature(void) const; + + virtual void Project (const Point point, Point & point_on_curve, double & t) const; + + virtual void GetRawData (ARRAY & data) const; +}; + + +// Gundolf Haase 8/26/97 +/// A circle +template < int D > +class CircleSeg : public SplineSeg +{ + /// +private: + GeomPoint p1, p2, p3; + //const GeomPoint &p1, &p2, &p3; + Point pm; + double radius, w1,w3; +public: + /// + CircleSeg (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3); + /// + virtual Point GetPoint (double t) const; + /// + virtual const GeomPoint & StartPI () const { return p1; } + /// + virtual const GeomPoint & EndPI () const { return p3; } + /// + virtual void GetCoeff (Vector & coeffs) const; + /// + double Radius() const { return radius; } + /// + double StartAngle() const { return w1; } + /// + double EndAngle() const { return w3; } + /// + const Point & MidPoint(void) const {return pm; } + + virtual string GetType(void) const {return "circle";} + + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const; + + virtual double MaxCurvature(void) const {return 1./radius;} +}; + + + + + + +/// +template +class DiscretePointsSeg : public SplineSeg +{ + ARRAY > pts; + GeomPoint p1, p2; +public: + /// + DiscretePointsSeg (const ARRAY > & apts); + /// + virtual ~DiscretePointsSeg (); + /// + virtual Point GetPoint (double t) const; + /// + virtual const GeomPoint & StartPI () const { return p1; }; + /// + virtual const GeomPoint & EndPI () const { return p2; } + /// + virtual void GetCoeff (Vector & coeffs) const {;} + + virtual double MaxCurvature(void) const {return 1;} +}; + + + + + + + +// calculates length of spline-curve +template +double SplineSeg :: Length () const +{ + Point 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 +template +void SplineSeg :: 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 p, pold, mark, oldmark; + ARRAY 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 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; + } +} + + +template +void SplineSeg :: GetPoints (int n, ARRAY > & points) +{ + points.SetSize (n); + if (n >= 2) + for (int i = 0; i < n; i++) + points[i] = GetPoint(double(i) / (n-1)); +} + +template +void SplineSeg :: PrintCoeff (ostream & ost) const +{ + Vector u(6); + + GetCoeff(u); + + for ( int i=0; i<6; i++) + ost << u[i] << " "; + ost << endl; +} + + + +/* + Implementation of line-segment from p1 to p2 +*/ + + +template +LineSeg :: LineSeg (const GeomPoint & ap1, + const GeomPoint & ap2) + : p1(ap1), p2(ap2) +{ + ; +} + + +template +Point LineSeg :: GetPoint (double t) const +{ + return p1 + t * (p2 - p1); +} + +template +Vec LineSeg :: GetTangent (const double t) const +{ + return p2-p1; +} + +template +void LineSeg :: GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const +{ + first = p2 - p1; + point = p1 + t * first; + second = 0; +} + + +template +double LineSeg :: Length () const +{ + return Dist (p1, p2); +} + + +template +void LineSeg :: GetCoeff (Vector & coeffs) const +{ + coeffs.SetSize(6); + + double dx = p2(0) - p1(0); + double dy = p2(1) - p1(1); + + coeffs[0] = coeffs[1] = coeffs[2] = 0; + coeffs[3] = -dy; + coeffs[4] = dx; + coeffs[5] = -dx * p1(1) + dy * p1(0); +} + + + +template +void LineSeg :: LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const +{ + points.SetSize(0); + + double denom = -a*p2(0)+a*p1(0)-b*p2(1)+b*p1(1); + if(fabs(denom) < 1e-20) + return; + + double t = (a*p1(0)+b*p1(1)+c)/denom; + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); +} + + + +template +void LineSeg :: Project (const Point point, Point & point_on_curve, double & t) const +{ + Vec v = p2-p1; + double l = v.Length(); + v *= 1./l; + t = (point-p1)*v; + + if(t<0) t = 0; + if(t>l) t = l; + + point_on_curve = p1+t*v; + + t *= 1./l; +} + + +template +void LineSeg :: GetRawData (ARRAY & data) const +{ + data.Append(2); + for(int i=0; i +void SplineSeg3 :: Project (const Point point, Point & point_on_curve, double & t) const +{ + double t_old = -1; + + if(proj_latest_t > 0. && proj_latest_t < 1.) + t = proj_latest_t; + else + t = 0.5; + + Point phi; + Vec phip,phipp,phimp; + + int i=0; + + while(t > -0.5 && t < 1.5 && i<20 && fabs(t-t_old) > 1e-15 ) + { + GetDerivatives(t,phi,phip,phipp); + + t_old = t; + + phimp = phi-point; + + //t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.); + t -= (phip*phimp)/(phipp*phimp + phip*phip); + + i++; + } + + //if(i<10 && t > 0. && t < 1.) + if(i<20 && t > -0.4 && t < 1.4) + { + if(t < 0) + { + t = 0.; + } + if(t > 1) + { + t = 1.; + } + + point_on_curve = GetPoint(t); + + double dist = Dist(point,point_on_curve); + + phi = GetPoint(0); + double auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 0.; + point_on_curve = phi; + dist = auxdist; + } + phi = GetPoint(1); + auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 1.; + point_on_curve = phi; + dist = auxdist; + } + } + else + { + double t0 = 0; + double t1 = 0.5; + double t2 = 1.; + + double d0,d1,d2; + + + //(*testout) << "newtonersatz" << endl; + while(t2-t0 > 1e-8) + { + + phi = GetPoint(t0); d0 = Dist(phi,point); + phi = GetPoint(t1); d1 = Dist(phi,point); + phi = GetPoint(t2); d2 = Dist(phi,point); + + double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2); + + if(a <= 0) + { + if(d0 < d2) + t2 -= 0.3*(t2-t0); + else + t0 += 0.3*(t2-t0); + + t1 = 0.5*(t2+t0); + } + else + { + double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0); + + double auxt1 = -0.5*b/a; + + if(auxt1 < t0) + { + t2 -= 0.4*(t2-t0); + t0 = max2(0.,t0-0.1*(t2-t0)); + } + else if (auxt1 > t2) + { + t0 += 0.4*(t2-t0); + t2 = min2(1.,t2+0.1*(t2-t0)); + } + else + { + t1 = auxt1; + auxt1 = 0.25*(t2-t0); + t0 = max2(0.,t1-auxt1); + t2 = min2(1.,t1+auxt1); + } + + t1 = 0.5*(t2+t0); + } + + } + + + phi = GetPoint(t0); d0 = Dist(phi,point); + phi = GetPoint(t1); d1 = Dist(phi,point); + phi = GetPoint(t2); d2 = Dist(phi,point); + + double mind = d0; + t = t0; + if(d1 < mind) + { + t = t1; + mind = d1; + } + if(d2 < mind) + { + t = t2; + mind = d2; + } + + point_on_curve = GetPoint(t); + } + //(*testout) << " latest_t " << proj_latest_t << " t " << t << endl; + + proj_latest_t = t; +} + + + + +template +SplineSeg3 :: SplineSeg3 (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3) + : p1(ap1), p2(ap2), p3(ap3) +{ + proj_latest_t = 0.5; +} + +template +Point SplineSeg3 :: 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; + + if(D==3) + { + double z = p1(2) * b1 + p2(2) * b2 + p3(2) * b3; + return Point (x/w, y/w, z/w); + } + else + return Point (x/w, y/w); +} + + + +template +void SplineSeg3 :: GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const +{ + Vec v1(p1), v2(p2), v3(p3); + + double b1 = (1.-t)*(1.-t); + double b2 = sqrt(2.)*t*(1.-t); + double b3 = t*t; + double w = b1+b2+b3; + b1 *= 1./w; b2 *= 1./w; b3 *= 1./w; + + double b1p = 2.*(t-1.); + double b2p = sqrt(2.)*(1.-2.*t); + double b3p = 2.*t; + const double wp = b1p+b2p+b3p; + const double fac1 = wp/w; + b1p *= 1./w; b2p *= 1./w; b3p *= 1./w; + + const double b1pp = 2.; + const double b2pp = -2.*sqrt(2.); + const double b3pp = 2.; + const double wpp = b1pp+b2pp+b3pp; + const double fac2 = (wpp*w-2.*wp*wp)/(w*w); + + for(int i=0; i +Vec SplineSeg3 :: GetTangent (const double t) const +{ + const double b1 = (1.-t)*((sqrt(2.)-2.)*t-sqrt(2.)); + const double b2 = sqrt(2.)*(1.-2.*t); + const double b3 = t*((sqrt(2.)-2)*t+2.); + + + Vec retval; + for(int i=0; i +void SplineSeg3 :: GetCoeff (Vector & u) const +{ + double t; + int i; + Point p; + DenseMatrix a(6, 6); + DenseMatrix ata(6, 6); + Vector f(6); + + u.SetSize(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); +} + +/* +template +double SplineSeg3 :: MaxCurvature(void) const +{ + Vec v1 = p1-p2; + Vec v2 = p3-p2; + double l1 = v1.Length(); + double l2 = v2.Length(); + (*testout) << "v1 " << v1 << " v2 " << v2 << endl; + + double cosalpha = v1*v2/(l1*l2); + + (*testout) << "cosalpha " << cosalpha << endl; + + return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha)); +} +*/ + + +template +void SplineSeg3 :: LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const +{ + points.SetSize(0); + + double t; + + const double c1 = a*p1(0) - sqrt(2.)*a*p2(0) + a*p3(0) + + b*p1(1) - sqrt(2.)*b*p2(1) + b*p3(1) + + (2.-sqrt(2.))*c; + const double c2 = -2.*a*p1(0) + sqrt(2.)*a*p2(0) -2.*b*p1(1) + sqrt(2.)*b*p2(1) + (sqrt(2.)-2.)*c; + const double c3 = a*p1(0) + b*p1(1) + c; + + if(fabs(c1) < 1e-20) + { + if(fabs(c2) < 1e-20) + return; + + t = -c3/c2; + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + return; + } + + const double discr = c2*c2-4.*c1*c3; + + if(discr < 0) + return; + + if(fabs(discr/(c1*c1)) < 1e-14) + { + t = -0.5*c2/c1; + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + return; + } + + t = (-c2 + sqrt(discr))/(2.*c1); + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + + t = (-c2 - sqrt(discr))/(2.*c1); + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); +} + + +template < int D > +void SplineSeg3 :: GetRawData (ARRAY & data) const +{ + data.Append(3); + for(int i=0; i +CircleSeg :: CircleSeg (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3) + : p1(ap1), p2(ap2), p3(ap3) +{ + Vec v1,v2; + + v1 = p1 - p2; + v2 = p3 - p2; + + Point p1t(p1+v1); + Point p2t(p3+v2); + + // works only in 2D!!!!!!!!! + + Line2d g1t,g2t; + + g1t.P1() = Point<2>(p1(0),p1(1)); + g1t.P2() = Point<2>(p1t(0),p1t(1)); + g2t.P1() = Point<2>(p3(0),p3(1)); + g2t.P2() = Point<2>(p2t(0),p2t(1)); + + Point<2> mp = CrossPoint (g1t,g2t); + + pm(0) = mp(0); pm(1) = mp(1); + radius = Dist(pm,StartPI()); + Vec2d auxv; + auxv.X() = p1(0)-pm(0); auxv.Y() = p1(1)-pm(1); + w1 = Angle(auxv); + auxv.X() = p3(0)-pm(0); auxv.Y() = p3(1)-pm(1); + w3 = Angle(auxv); + if ( fabs(w3-w1) > M_PI ) + { + if ( w3>M_PI ) w3 -= 2*M_PI; + if ( w1>M_PI ) w1 -= 2*M_PI; + } +} + + +template +Point CircleSeg :: GetPoint (double t) const +{ + if (t >= 1.0) { return p3; } + + double phi = StartAngle() + t*(EndAngle()-StartAngle()); + Vec tmp(cos(phi),sin(phi)); + + return pm + Radius()*tmp; +} + +template +void CircleSeg :: GetCoeff (Vector & coeff) const +{ + coeff[0] = coeff[1] = 1.0; + coeff[2] = 0.0; + coeff[3] = -2.0 * pm[0]; + coeff[4] = -2.0 * pm[1]; + coeff[5] = sqr(pm[0]) + sqr(pm[1]) - sqr(Radius()); +} + + +template +void CircleSeg :: LineIntersections (const double a, const double b, const double c, + ARRAY < Point > & points, const double eps) const +{ + points.SetSize(0); + + double px=0,py=0; + + if(fabs(b) > 1e-20) + py = -c/b; + else + px = -c/a; + + const double c1 = a*a + b*b; + const double c2 = 2. * ( a*(py-pm(1)) - b*(px-pm(0))); + const double c3 = pow(px-pm(0),2) + pow(py-pm(1),2) - pow(Radius(),2); + + const double discr = c2*c2 - 4*c1*c3; + + if(discr < 0) + return; + + ARRAY t; + + if(fabs(discr) < 1e-20) + t.Append(-0.5*c2/c1); + else + { + t.Append((-c2+sqrt(discr))/(2.*c1)); + t.Append((-c2-sqrt(discr))/(2.*c1)); + } + + for(int i=0; i p (px-t[i]*b,py+t[i]*a); + + double angle = atan2(p(1),p(0))+M_PI; + + if(angle > StartAngle()-eps && angle < EndAngle()+eps) + points.Append(p); + } +} + + + + +template +DiscretePointsSeg :: DiscretePointsSeg (const ARRAY > & apts) + : pts (apts) +{ + for(int i=0; i +DiscretePointsSeg :: ~DiscretePointsSeg () +{ ; } + +template +Point DiscretePointsSeg :: 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 pts[segnr] + rest*Vec(pts[segnr+1]-pts[segnr]); +} + + + +typedef GeomPoint<2> GeomPoint2d; +typedef SplineSeg<2> SplineSegment; +typedef LineSeg<2> LineSegment; +typedef SplineSeg3<2> SplineSegment3; +typedef CircleSeg<2> CircleSegment; +typedef DiscretePointsSeg<2> DiscretePointsSegment; + + + + +#endif diff --git a/libsrc/geom2d/spline2d.hpp b/libsrc/geom2d/spline2d.hpp new file mode 100644 index 00000000..39ab309d --- /dev/null +++ b/libsrc/geom2d/spline2d.hpp @@ -0,0 +1,234 @@ + + + + +das File sollte nicht mehr verwendet werden ---> spline.hpp + + + + + + + +#ifndef FILE_SPLINE2D +#define FILE_SPLINE2D + +/**************************************************************************/ +/* File: spline2d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 24. Jul. 96 */ +/**************************************************************************/ + + +/* + Spline curves for 2D mesh generation + */ + +#include "spline.hpp" + + +//#define OLDSPLINEVERSION +#ifdef OLDSPLINEVERSION + +/// 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 */ + void PrintCoeff (ostream & ost) const; + + virtual void GetCoeff (Vector & coeffs) const = 0; + + virtual void GetPoints (int n, ARRAY > & points); + + /** calculates lineintersections: + for lines $$ a x + b y + c = 0 $$ the interecting points are calculated + and stored in points */ + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point<2> > & points, const double eps) const + {points.SetSize(0);} + + virtual double MaxCurvature(void) const = 0; + + 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 void GetCoeff (Vector & coeffs) const; + + virtual string GetType(void) const {return "line";} + + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point<2> > & points, const double eps) const; + + virtual double MaxCurvature(void) const {return 0;} +}; + + +/// 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 void GetCoeff (Vector & coeffs) const; + + virtual string GetType(void) const {return "spline3";} + + const GeomPoint2d & TangentPoint (void) const { return p2; } + + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point<2> > & points, const double eps) const; + + virtual double MaxCurvature(void) const; +}; + + +// 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; + virtual void GetCoeff (Vector & coeffs) const; + /// + double Radius() const { return radius; } + /// + double StartAngle() const { return w1; } + /// + double EndAngle() const { return w3; } + /// + const Point<2> & MidPoint(void) const {return pm; } + + virtual string GetType(void) const {return "circle";} + + virtual void LineIntersections (const double a, const double b, const double c, + ARRAY < Point<2> > & points, const double eps) const; + + virtual double MaxCurvature(void) const {return 1./radius;} +}; + + + + + + +/// +class DiscretePointsSegment : public SplineSegment +{ + ARRAY > pts; + GeomPoint2d p1, p2; +public: + /// + DiscretePointsSegment (const ARRAY > & 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 { ; } + virtual void GetCoeff (Vector & coeffs) const {;} + + virtual double MaxCurvature(void) const {return 1;} +}; + + +#endif + +#endif diff --git a/libsrc/geom2d/splinegeometry.cpp b/libsrc/geom2d/splinegeometry.cpp new file mode 100644 index 00000000..013421e0 --- /dev/null +++ b/libsrc/geom2d/splinegeometry.cpp @@ -0,0 +1,1252 @@ +/* + +2d Spline curve for Mesh generator + +*/ + + +#include +#include +#include +#include "meshing.hpp" + +namespace netgen +{ + + //using namespace netgen; + +template +void SplineGeometry :: LoadDataV2 ( ifstream & infile ) +{ + PrintMessage (1, "Load 2D Geometry V2"); + int nump, leftdom, rightdom; + Point x; + int hi1, hi2, hi3; + double hd; + char buf[50], ch; + int pointnr; + + string keyword; + + ARRAY < GeomPoint > infilepoints (0); + ARRAY pointnrs (0); + nump = 0; + int numdomains = 0; + + + TestComment ( infile ); + // refinement factor + infile >> elto0; + TestComment ( infile ); + + + // test if next ch is a letter, i.e. new keyword starts + bool ischar = false; + + while ( infile.good() ) + { + infile >> keyword; + + ischar = false; + + if ( keyword == "points" ) + { + PrintMessage (3, "load points"); + infile.get(ch); + infile.putback(ch); + + // test if ch is a letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + + while ( ! ischar ) + { + TestComment ( infile ); + infile >> pointnr; + // pointnrs 1-based + if ( pointnr > nump ) nump = pointnr; + pointnrs.Append(pointnr); + + for(int j=0; j> x(j); + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + + Flags flags; + + + // get flags, + ch = 'a'; + // infile >> ch; + do + { + infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + 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); + + if ( hd == 1 ) + hd = flags.GetNumFlag ( "ref", 1.0); + // geompoints.Append (GeomPoint(x, hd)); + + infilepoints.Append ( GeomPoint(x, hd) ); + infilepoints.Last().hpref = flags.GetDefineFlag ("hpref"); + + TestComment(infile); + infile.get(ch); + infile.putback(ch); + + // test if letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + } + + // infile.putback (ch); + + geompoints.SetSize(nump); + for ( int i = 0; i < nump; i++ ) + { + geompoints[pointnrs[i] - 1] = infilepoints[i]; + geompoints[pointnrs[i] - 1].hpref = infilepoints[i].hpref; + } + TestComment(infile); + } + + else if ( keyword == "segments" ) + { + PrintMessage (3, "load segments"); + + bcnames.SetSize(0); + infile.get(ch); + infile.putback(ch); + int i = 0; + + // test if ch is a letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + + while ( !ischar ) //ch != 'p' && ch != 'm' ) + { + i++; + TestComment ( infile ); + + SplineSeg * spline = 0; + TestComment ( infile ); + + infile >> leftdom >> rightdom; + + if ( leftdom > numdomains ) numdomains = leftdom; + if ( rightdom > numdomains ) numdomains = rightdom; + + + infile >> buf; + // type of spline segement + if (strcmp (buf, "2") == 0) + { // a line + infile >> hi1 >> hi2; + spline = new LineSeg(geompoints[hi1-1], + geompoints[hi2-1]); + } + else if (strcmp (buf, "3") == 0) + { // a rational spline + infile >> hi1 >> hi2 >> hi3; + spline = new SplineSeg3 (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "4") == 0) + { // an arc + infile >> hi1 >> hi2 >> hi3; + spline = new CircleSeg (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + break; + } + else if (strcmp (buf, "discretepoints") == 0) + { + int npts; + infile >> npts; + ARRAY< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + + spline = new DiscretePointsSeg (pts); + } + + // infile >> spline->reffak; + spline -> leftdom = leftdom; + spline -> rightdom = rightdom; + splines.Append (spline); + + + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + infile >> ch; + + // get refinement parameter, if it is there + //infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + infile >> ch ; + } + + // get flags, + Flags flags; + 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)); + splines.Last()->reffak = flags.GetNumFlag ("ref", 1 ); + if ( hd != 1 ) + splines.Last()->reffak = hd; + + if ( flags.StringFlagDefined("bcname") ) + { + int mybc = splines.Last()->bc-1; + for ( int ii = bcnames.Size(); ii <= mybc; ii++ ) + bcnames.Append ( new string ("default")); + if ( bcnames[mybc] ) delete bcnames[mybc]; + bcnames[mybc] = new string (flags.GetStringFlag("bcname","") ); + } + + TestComment(infile); + infile.get(ch); + infile.putback(ch); + + // test if ch is a letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + + } + + infile.get(ch); + infile.putback(ch); + + + } + else if ( keyword == "materials" ) + { + TestComment ( infile ); + int domainnr; + char material[100]; + + if ( !infile.good() ) + return; + + materials.SetSize(numdomains) ; + maxh.SetSize ( numdomains ) ; + for ( int i = 0; i < numdomains; i++) + maxh[i] = 1000; + quadmeshing.SetSize ( numdomains ); + quadmeshing = false; + tensormeshing.SetSize ( numdomains ); + tensormeshing = false; + + + TestComment ( infile ); + + for ( int i=0; i> domainnr; + infile >> material; + + strcpy (materials[domainnr-1], material); + + 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); + + maxh[domainnr-1] = flags.GetNumFlag ( "maxh", 1000); + if (flags.GetDefineFlag("quad")) quadmeshing[domainnr-1] = true; + if (flags.GetDefineFlag("tensor")) tensormeshing[domainnr-1] = true; + } + } + } + return; +} + + + + + + + +// check if comments in a .in2d file... +// template +// void SplineGeometry :: TestComment ( ifstream & infile ) +// { +// bool comment = true; +// char ch; +// infile.get(ch); +// infile.putback(ch); +// int ii = 0; +// while ( comment == true && ii < 100) +// { +// infile.get(ch); +// if ( ch == '#' ) +// while ( ch != '\n') +// { +// infile.get(ch); +// comment = false; +// } +// else if ( ch == '\n' ) +// { +// comment = true; +// ii ++; +// } +// else +// { +// infile.putback(ch); +// comment = false; +// } +// +// infile.get(ch) ; +// if ( ch == '\n' || ch == '#' ) +// { +// comment = true; +// } +// infile.putback(ch); +// if ( !comment ) break; +// } +// cerr << "** comment done" << endl; +// cerr << " * last char was " << ch << endl; +// return; +// +// } + +// herbert: fixed TestComment +template +void SplineGeometry :: TestComment ( ifstream & infile ) +{ + bool comment = true; + char ch; + while ( comment == true && !infile.eof() ) { + infile.get(ch); + if ( ch == '#' ) { // skip comments + while ( ch != '\n' && !infile.eof() ) { + infile.get(ch); + } + } + else if ( ch == '\n' ) { // skip empty lines + ; + } + else if ( isspace(ch) ) { // skip whitespaces + ; + } + else { // end of comment + infile.putback(ch); + comment = false; + } + } + return; +} + + + +template +SplineGeometry :: ~SplineGeometry() +{ + for(int i=0; i +int SplineGeometry :: Load (const ARRAY & raw_data, const int startpos) +{ + int pos = startpos; + if(raw_data[pos] != D) + throw NgException("wrong dimension of spline raw_data"); + + pos++; + + elto0 = raw_data[pos]; pos++; + + splines.SetSize(int(raw_data[pos])); + pos++; + + ARRAY< Point > pts(3); + + for(int i=0; i(GeomPoint(pts[0],1), + GeomPoint(pts[1],1)); + //(*testout) << "appending line segment " + // << pts[0] << " -- " << pts[1] << endl; + } + else if (type == 3) + { + splines[i] = new SplineSeg3(GeomPoint(pts[0],1), + GeomPoint(pts[1],1), + GeomPoint(pts[2],1)); + //(*testout) << "appending spline segment " + // << pts[0] << " -- " << pts[1] << " -- " << pts[2] << endl; + + } + else + throw NgException("something wrong with spline raw data"); + + } + return pos; +} + +template +void SplineGeometry :: GetRawData (ARRAY & raw_data) const +{ + raw_data.Append(D); + raw_data.Append(elto0); + + + raw_data.Append(splines.Size()); + for(int i=0; iGetRawData(raw_data); + + +} + +template +void SplineGeometry :: CSGLoad (CSGScanner & scan) +{ + double hd; + Point x; + int nump, numseg; + + //scan.ReadNext(); + scan >> nump >> ';'; + + hd = 1; + geompoints.SetSize(nump); + for(int i = 0; i> x(0) >> ',' >> x(1) >> ';'; + else if(D==3) + scan >> x(0) >> ',' >> x(1) >> ',' >> x(2) >> ';'; + + geompoints[i] = GeomPoint(x,hd); + } + + scan >> numseg;// >> ';'; + + splines.SetSize(numseg); + + int pnums,pnum1,pnum2,pnum3; + + + for(int i = 0; i> ';' >> pnums >> ','; + if (pnums == 2) + { + scan >> pnum1 >> ',' >> pnum2;// >> ';'; + splines[i] = new LineSeg(geompoints[pnum1-1], + geompoints[pnum2-1]); + } + else if (pnums == 3) + { + scan >> pnum1 >> ',' >> pnum2 >> ',' + >> pnum3;// >> ';'; + splines[i] = new SplineSeg3(geompoints[pnum1-1], + geompoints[pnum2-1], + geompoints[pnum3-1]); + } + else if (pnums == 4) + { + scan >> pnum1 >> ',' >> pnum2 >> ',' + >> pnum3;// >> ';'; + splines[i] = new CircleSeg(geompoints[pnum1-1], + geompoints[pnum2-1], + geompoints[pnum3-1]); + + } + + } +} + + + + +template +void SplineGeometry :: Load (const char * filename) +{ + + ifstream infile; + Point x; + char buf[50]; + + + infile.open (filename); + + if ( ! infile.good() ) + throw NgException(string ("Input file '") + + string (filename) + + string ("' not available!")); + + TestComment ( infile ); + + infile >> buf; // file recognition + + tensormeshing.SetSize(0); + quadmeshing.SetSize(0); + + TestComment ( infile ); + if ( strcmp (buf, "splinecurves2dnew") == 0 ) + { + LoadDataNew ( infile ); + } + else if ( strcmp (buf, "splinecurves2dv2") == 0 ) + { + LoadDataV2 ( infile ); + } + else + { + LoadData(infile ); + } + infile.close(); +} + + +template +void SplineGeometry :: LoadDataNew ( ifstream & infile ) +{ + + int nump, numseg, leftdom, rightdom; + Point x; + int hi1, hi2, hi3; + double hd; + char buf[50], ch; + int pointnr; + + + TestComment ( infile ); + infile >> elto0; + TestComment ( infile ); + + infile >> nump; + geompoints.SetSize(nump); + + for (int i = 0; i < nump; i++) + { + TestComment ( infile ); + infile >> pointnr; + if ( pointnr > nump ) + { + throw NgException(string ("Point number greater than total number of points") ); + } + for(int j=0; j> x(j); + + + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + + Flags flags; + + + // get flags, + ch = 'a'; + // infile >> ch; + do + { + + infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + 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); + + if ( hd == 1 ) + hd = flags.GetNumFlag ( "ref", 1.0); + // geompoints.Append (GeomPoint(x, hd)); + geompoints[pointnr-1] = GeomPoint(x, hd); + geompoints[pointnr-1].hpref = flags.GetDefineFlag ("hpref"); + } + + TestComment ( infile ); + + infile >> numseg; + bcnames.SetSize(numseg); + for ( int i = 0; i < numseg; i++ ) + bcnames[i] = 0;//new"default"; + + SplineSeg * spline = 0; + for (int i = 0; i < numseg; i++) + { + TestComment ( infile ); + + 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 LineSeg (geompoints[hi1-1], + geompoints[hi2-1]); + } + else if (strcmp (buf, "3") == 0) + { // a rational spline + infile >> hi1 >> hi2 >> hi3; + spline = new SplineSeg3 (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "4") == 0) + { // an arc + infile >> hi1 >> hi2 >> hi3; + spline = new CircleSeg (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); +// break; + } + else if (strcmp (buf, "discretepoints") == 0) + { + int npts; + infile >> npts; + ARRAY< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + + spline = new DiscretePointsSeg (pts); + } + + // infile >> spline->reffak; + spline -> leftdom = leftdom; + spline -> rightdom = rightdom; + splines.Append (spline); + + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + infile >> ch; + + // get refinement parameter, if it is there + // infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + infile >> ch ; + } + + Flags flags; + 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)); + splines.Last()->reffak = flags.GetNumFlag ("ref", 1 ); + + if ( flags.StringFlagDefined("bcname") ) + { + int mybc = splines.Last()->bc-1; + if ( bcnames[mybc] ) delete bcnames[mybc]; + bcnames[mybc] = new string (flags.GetStringFlag("bcname","") ); + } + + if ( hd != 1 ) + splines.Last()->reffak = hd; + } + if ( !infile.good() ) + return; + TestComment ( infile ); + int numdomains; + int domainnr; + char material[100]; + + if ( !infile.good() ) + return; + + infile >> numdomains; + materials.SetSize(numdomains) ; + maxh.SetSize ( numdomains ) ; + for ( int i = 0; i < numdomains; i++) + maxh[i] = 1000; + + TestComment ( infile ); + + for ( int i=0; i> domainnr; + infile >> material; + strcpy(materials[domainnr-1], material); + + 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); + + maxh[domainnr-1] = flags.GetNumFlag ( "maxh", 1000); + } + return; +} + + + +template +void SplineGeometry :: LoadData ( ifstream & infile ) +{ + + int nump, numseg, leftdom, rightdom; + Point x; + int hi1, hi2, hi3; + double hd; + char buf[50], ch; + + materials.SetSize(0); + maxh.SetSize(0); + infile >> elto0; + + TestComment ( infile ); + + infile >> nump; + for (int i = 0; i < nump; i++) + { + TestComment ( infile ); + for(int j=0; j> x(j); + infile >> 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 (GeomPoint(x, hd)); + geompoints.Last().hpref = flags.GetDefineFlag ("hpref"); + } + + PrintMessage (3, nump, " points loaded"); + TestComment ( infile ); + + infile >> numseg; + bcnames.SetSize(numseg); + for ( int i = 0; i < numseg; i++ ) + bcnames[i] = 0; // "default"; + + SplineSeg * spline = 0; + + PrintMessage (3, numseg, " segments loaded"); + for (int i = 0; i < numseg; i++) + { + TestComment ( infile ); + + infile >> leftdom >> rightdom; + + // cout << "add spline " << i << ", left = " << leftdom << ", right = " << rightdom << endl; + + infile >> buf; + // type of spline segement + if (strcmp (buf, "2") == 0) + { // a line + infile >> hi1 >> hi2; + spline = new LineSeg(geompoints[hi1-1], + geompoints[hi2-1]); + } + else if (strcmp (buf, "3") == 0) + { // a rational spline + infile >> hi1 >> hi2 >> hi3; + spline = new SplineSeg3 (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "4") == 0) + { // an arc + infile >> hi1 >> hi2 >> hi3; + spline = new CircleSeg (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); +// break; + } + else if (strcmp (buf, "discretepoints") == 0) + { + int npts; + infile >> npts; + ARRAY< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + + spline = new DiscretePointsSeg (pts); + } + + 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)); + if ( flags.StringFlagDefined("bcname") ) + { + int mybc = splines.Last()->bc-1; + if ( bcnames[mybc] ) delete bcnames[mybc]; + bcnames[mybc] = new string (flags.GetStringFlag("bcname","") ); + } + } +} + + + +template +void SplineGeometry :: PartitionBoundary (double h, Mesh & mesh2d) +{ + Box bbox; + GetBoundingBox (bbox); + double dist = Dist (bbox.PMin(), bbox.PMax()); + Point<3> pmin; + Point<3> pmax; + + pmin(2) = -dist; pmax(2) = dist; + for(int j=0;j0) + cout << "searchtree from " << pmin << " to " << pmax << endl; + Point3dTree searchtree (pmin, pmax); + + for (int i = 0; i < splines.Size(); i++) + if (splines[i]->copyfrom == -1) + { + // astrid - set boundary meshsize to domain meshsize h + // if no domain mesh size is given, the max h value from the bounding box is used + double minimum = min2 ( GetDomainMaxh ( splines[i]->leftdom ), GetDomainMaxh ( splines[i]->rightdom ) ); + double maximum = max2 ( GetDomainMaxh ( splines[i]->leftdom ), GetDomainMaxh ( splines[i]->rightdom ) ); + minimum = min2 ( minimum, h ); + maximum = min2 ( maximum, h); + if ( minimum > 0 ) + splines[i]->Partition(minimum, elto0, mesh2d, searchtree, i+1); + else if ( maximum > 0 ) + splines[i]->Partition(maximum, elto0, mesh2d, searchtree, i+1); + else + splines[i]->Partition(h, elto0, mesh2d, searchtree, i+1); + } + else + { + CopyEdgeMesh (splines[i]->copyfrom, i+1, mesh2d, searchtree); + } +} + + +template +void SplineGeometry :: CopyEdgeMesh (int from, int to, Mesh & mesh, Point3dTree & searchtree) +{ + int i; + + ARRAY mappoints (mesh.GetNP()); + ARRAY param (mesh.GetNP()); + mappoints = -1; + param = 0; + + Point3d pmin, pmax; + mesh.GetBox (pmin, pmax); + double diam2 = Dist2(pmin, pmax); + + if (printmessage_importance>0) + 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; + } + } + + bool mapped = false; + for (i = 1; i <= mappoints.Size(); i++) + { + if (mappoints.Get(i) != -1) + { + Point newp = splines.Get(to)->GetPoint (param.Get(i)); + Point<3> newp3; + for(int j=0; jbc; + 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); + } + } +} + + +template +void SplineGeometry :: GetBoundingBox (Box & box) const +{ + if (!splines.Size()) + { + Point auxp = 0.; + box.Set (auxp); + return; + } + + ARRAY > 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]); + } +} + +template +void SplineGeometry :: SetGrading (const double grading) +{ elto0 = grading;} + +template +void SplineGeometry :: AppendPoint (const double x, const double y, const double reffac, const bool hpref) +{ + geompoints.Append (GeomPoint(x, y, reffac)); + geompoints.Last().hpref = hpref; +} + +template +void SplineGeometry :: AppendPoint (const Point & p, const double reffac, const bool hpref) +{ + geompoints.Append (GeomPoint(p, reffac)); + geompoints.Last().hpref = hpref; +} + + + + +template +void SplineGeometry :: AppendSegment(SplineSeg * 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); +} + +template +void SplineGeometry :: 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) +{ + SplineSeg * spline = new LineSeg(geompoints[n1],geompoints[n2]); + AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); +} + +template +void SplineGeometry :: 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) +{ + SplineSeg * spline = new SplineSeg3(geompoints[n1],geompoints[n2],geompoints[n3]); + AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); +} + +template +void SplineGeometry :: 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) +{ + SplineSeg * spline = new CircleSeg(geompoints[n1],geompoints[n2],geompoints[n3]); + AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); +} + +template +void SplineGeometry :: AppendDiscretePointsSegment (const ARRAY< Point > & points, const int leftdomain, const int rightdomain, + const int bc, + const double reffac, const bool hprefleft, const bool hprefright, + const int copyfrom) +{ + SplineSeg * spline = new DiscretePointsSeg(points); + AppendSegment(spline,leftdomain,rightdomain,bc,reffac,hprefleft,hprefright,copyfrom); +} + + + template + void SplineGeometry :: GetMaterial( const int domnr, char* & material ) + { + if ( materials.Size() >= domnr) + material = materials[domnr-1]; + else material = 0; + return; + } + + + + template + double SplineGeometry :: GetDomainMaxh( const int domnr ) + { + if ( maxh.Size() >= domnr && domnr > 0) + return maxh[domnr-1]; + else + return -1; + } + + + template + string SplineGeometry :: GetBCName( const int bcnr ) const + { + string bcname; + if ( bcnames.Size() >= bcnr) + if ( bcnames[bcnr-1] ) + bcname = *bcnames[bcnr-1]; + else bcname = "default"; + return bcname; + } + +template +string * SplineGeometry :: BCNamePtr( const int bcnr ) +{ + if ( bcnr > bcnames.Size() ) + return 0; + else + return bcnames[bcnr-1]; +} + + + + template class SplineGeometry<2>; + template class SplineGeometry<3>; +} + + diff --git a/libsrc/geom2d/splinegeometry.hpp b/libsrc/geom2d/splinegeometry.hpp new file mode 100644 index 00000000..eb01ef86 --- /dev/null +++ b/libsrc/geom2d/splinegeometry.hpp @@ -0,0 +1,140 @@ +/* + + +JS, Nov 2007 + + +The 2D/3D template-base classes should go into the libsrc/gprim directory + +in geom2d only 2D - Geometry classes (with material properties etc.) + + +*/ + + + + + +#ifndef _FILE_SPLINEGEOMETRY +#define _FILE_SPLINEGEOMETRY +#include "../csg/csgparser.hpp" + +/// +extern void LoadBoundarySplines (const char * filename, + ARRAY < GeomPoint<2> > & geompoints, + ARRAY < SplineSeg<2>* > & splines, + double & elto0); +/// +extern void PartitionBoundary (const ARRAY < SplineSeg<2>* > & splines, + double h, double elto0, + Mesh & mesh2d); + + +// allow to turn off messages: cover all couts !! +extern int printmessage_importance; + +template < int D > +class SplineGeometry +{ + ARRAY < GeomPoint > geompoints; + ARRAY < SplineSeg* > splines; + double elto0; + ARRAY materials; + ARRAY bcnames; + ARRAY maxh; + ARRAY quadmeshing; + ARRAY tensormeshing; + +private: + void AppendSegment(SplineSeg * spline, const int leftdomain, const int rightdomain, + const int bc, + const double reffac, const bool hprefleft, const bool hprefright, + const int copyfrom); + +public: + ~SplineGeometry(); + + int Load (const ARRAY & raw_data, const int startpos = 0); + void Load (const char * filename); + void CSGLoad (CSGScanner & scan); + + void LoadData( ifstream & infile ); + void LoadDataNew ( ifstream & infile ); + void LoadDataV2 ( ifstream & infile ); + + void PartitionBoundary (double h, Mesh & mesh2d); + + void GetRawData (ARRAY & raw_data) const; + + void CopyEdgeMesh (int from, int to, Mesh & mesh2d, Point3dTree & searchtree); + + const ARRAY*> & GetSplines () const + { return splines; } + + int GetNSplines (void) const { return splines.Size(); } + string GetSplineType (const int i) const { return splines[i]->GetType(); } + SplineSeg & GetSpline (const int i) {return *splines[i];} + const SplineSeg & GetSpline (const int i) const {return *splines[i];} + + void GetBoundingBox (Box & box) const; + Box GetBoundingBox () const + { Box box; GetBoundingBox (box); return box; } + + int GetNP () const { return geompoints.Size(); } + const GeomPoint & 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 AppendPoint (const Point & p, 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 > & 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 TestComment ( ifstream & infile ) ; + void GetMaterial( const int domnr, char* & material ); + + double GetDomainMaxh ( const int domnr ); + bool GetDomainQuadMeshing ( int domnr ) + { + if ( quadmeshing.Size() ) return quadmeshing[domnr-1]; + else return false; + } + bool GetDomainTensorMeshing ( int domnr ) + { + if ( tensormeshing.Size() ) return tensormeshing[domnr-1]; + else return false; + } + + string GetBCName ( const int bcnr ) const; + + string * BCNamePtr ( const int bcnr ); +}; + + +void MeshFromSpline2D (SplineGeometry<2> & geometry, + Mesh *& mesh, + MeshingParameters & mp); + + + +typedef SplineGeometry<2> SplineGeometry2d; + + +#endif // _FILE_SPLINEGEOMETRY diff --git a/libsrc/geom2d/splinegeometry2.hpp b/libsrc/geom2d/splinegeometry2.hpp new file mode 100644 index 00000000..88166df9 --- /dev/null +++ b/libsrc/geom2d/splinegeometry2.hpp @@ -0,0 +1,103 @@ + + +OLD IMPLEMENTATION, NOT USED ANYMORE! + + + + +#ifndef FILE_SPLINEGEOMETRY2 +#define FILE_SPLINEGEOMETRY2 + +/**************************************************************************/ +/* File: splinegeometry2.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 24. Jul. 96 */ +/**************************************************************************/ + +#include "splinegeometry.hpp" + +#ifdef OLDSPLINEGEOMETRY + + +/// +extern void LoadBoundarySplines (const char * filename, + ARRAY & geompoints, + ARRAY & splines, + double & elto0); +/// +extern void PartitionBoundary (const ARRAY & splines, + double h, double elto0, + Mesh & mesh2d); + + +class CSGScanner; + +class SplineGeometry2d +{ + ARRAY geompoints; + ARRAY 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 CSGLoad (CSGScanner & scan); + void PartitionBoundary (double h, Mesh & mesh2d); + + void CopyEdgeMesh (int from, int to, Mesh & mesh2d, Point3dTree & searchtree); + + const ARRAY & GetSplines () const + { return splines; } + + int GetNSplines (void) const { return splines.Size(); } + string GetSplineType (const int i) const { return splines[i]->GetType(); } + SplineSegment & GetSpline (const int i) {return *splines[i];} + const SplineSegment & GetSpline (const int i) const {return *splines[i];} + + 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 + +#endif diff --git a/libsrc/gprim/Makefile.am b/libsrc/gprim/Makefile.am new file mode 100644 index 00000000..e30edbc1 --- /dev/null +++ b/libsrc/gprim/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libgprim.a +libgprim_a_SOURCES = adtree.cpp geom2d.cpp geom3d.cpp geomfuncs.cpp \ + geomtest3d.cpp transform3d.cpp diff --git a/libsrc/gprim/Makefile.in b/libsrc/gprim/Makefile.in new file mode 100644 index 00000000..b3b647a1 --- /dev/null +++ b/libsrc/gprim/Makefile.in @@ -0,0 +1,448 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/gprim +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libgprim_a_AR = $(AR) $(ARFLAGS) +libgprim_a_LIBADD = +am_libgprim_a_OBJECTS = adtree.$(OBJEXT) geom2d.$(OBJEXT) \ + geom3d.$(OBJEXT) geomfuncs.$(OBJEXT) geomtest3d.$(OBJEXT) \ + transform3d.$(OBJEXT) +libgprim_a_OBJECTS = $(am_libgprim_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgprim_a_SOURCES) +DIST_SOURCES = $(libgprim_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libgprim.a +libgprim_a_SOURCES = adtree.cpp geom2d.cpp geom3d.cpp geomfuncs.cpp \ + geomtest3d.cpp transform3d.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/gprim/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/gprim/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libgprim.a: $(libgprim_a_OBJECTS) $(libgprim_a_DEPENDENCIES) + -rm -f libgprim.a + $(libgprim_a_AR) libgprim.a $(libgprim_a_OBJECTS) $(libgprim_a_LIBADD) + $(RANLIB) libgprim.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adtree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom3d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geomfuncs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geomtest3d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform3d.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/gprim/adtree.cpp b/libsrc/gprim/adtree.cpp new file mode 100644 index 00000000..0b5a3197 --- /dev/null +++ b/libsrc/gprim/adtree.cpp @@ -0,0 +1,2165 @@ +#include + + +#include +// class DenseMatrix; +#include + +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(NULL); + ADTreeNode *next; + int dir; + int lr(1); + + 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 & 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(NULL); + ADTreeNode3 *next; + int dir; + int lr(0); + + 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 & pis) const + { + static ARRAY stack(1000); + static ARRAY 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 & pis) const + { + static ARRAY stack(1000); + static ARRAY 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 & pis) const + { + static ARRAY stack(1000); + static ARRAY 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 & pis) const + { + static ARRAY 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 & pis) const + { + static ARRAY 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(NULL); + ADTreeNode6 *next; + int dir; + int lr(0); + + 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 & pis) const + { + static ARRAY stack(10000); + + stack.SetSize (10000); + pis.SetSize(0); + + stack[0].node = root; + stack[0].dir = 0; + int stacks = 0; + + while (stacks >= 0) + { + ADTreeNode6 * node = stack[stacks].node; + int dir = stack[stacks].dir; + + stacks--; + + if (node->pi != -1) + { + 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) % 6; + + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack[stacks].node = node->left; + stack[stacks].dir = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack[stacks].node = node->right; + stack[stacks].dir = 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 & pis) const + { + static ARRAY 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 & 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 & 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/libsrc/gprim/adtree.hpp b/libsrc/gprim/adtree.hpp new file mode 100644 index 00000000..4cac0f29 --- /dev/null +++ b/libsrc/gprim/adtree.hpp @@ -0,0 +1,481 @@ +#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 "../include/mystdlib.h" +#include "../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 ela; + const ADTreeCriterion * criterion; + + ARRAY stack; + ARRAY 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 & pis) const; + void SetCriterion (ADTreeCriterion & acriterion); + void Reset (); + int Next (); + void GetMatch (ARRAY & 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 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 & 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 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 & 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 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 & 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 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 & 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 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 & 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 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 & 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 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 & 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 & 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 Insert (const Box<3> & box, int pi) + { + Insert (box.PMin(), box.PMax(), pi); + } + void DeleteElement (int pi) + { tree->DeleteElement(pi); } + void GetIntersecting (const Point3d & pmin, const Point3d & pmax, + ARRAY & pis) const; + + const ADTree6 & Tree() const { return *tree; }; +}; +#endif diff --git a/libsrc/gprim/geom2d.cpp b/libsrc/gprim/geom2d.cpp new file mode 100644 index 00000000..34263348 --- /dev/null +++ b/libsrc/gprim/geom2d.cpp @@ -0,0 +1,489 @@ +#include + +#include +#include + +#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= -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/libsrc/gprim/geom2d.hpp b/libsrc/gprim/geom2d.hpp new file mode 100644 index 00000000..1d4bcb3a --- /dev/null +++ b/libsrc/gprim/geom2d.hpp @@ -0,0 +1,885 @@ +#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); +Point2d CrossPoint (const Line2d & l1, const Line2d & 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); +double Dist2 (const Point2d & p1, const Point2d & p2); + +/// +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 bool 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; + } /** + Points counter-clock-wise ? + Are the points (p1, p2, p3) counter-clock-wise ? + */ + friend inline bool CCW (const Point2d & p1, const Point2d & p2, const Point2d & p3, double eps) + { + // return Cross (p2 - p1, p3 - p2) > 0; + double ax = p2.px - p1.px; + double ay = p2.py - p1.py; + double bx = p3.px - p2.px; + double by = p3.py - p2.py; + + return ax*by - ay*bx > eps*eps*max2(ax*ax+ay*ay,bx*bx+by*by); + } + + /// + 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 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/libsrc/gprim/geom3d.cpp b/libsrc/gprim/geom3d.cpp new file mode 100644 index 00000000..71970ffe --- /dev/null +++ b/libsrc/gprim/geom3d.cpp @@ -0,0 +1,731 @@ +#include +#include + +#include +#include + +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) +{ + // changed by MW + double matrix[3][3]; + double locrhs[3]; + int retval = 0; + + for(int i=0; i<3; i++) + { + matrix[i][0] = col1.X(i+1); + matrix[i][1] = col2.X(i+1); + matrix[i][2] = col3.X(i+1); + locrhs[i] = rhs.X(i+1); + } + + for(int i=0; i<2; i++) + { + int pivot = i; + double maxv = fabs(matrix[i][i]); + for(int j=i+1; j<3; j++) + if(fabs(matrix[j][i]) > maxv) + { + maxv = fabs(matrix[j][i]); + pivot = j; + } + + if(fabs(maxv) > 1e-40) + { + if(pivot != i) + { + swap(matrix[i][0],matrix[pivot][0]); + swap(matrix[i][1],matrix[pivot][1]); + swap(matrix[i][2],matrix[pivot][2]); + swap(locrhs[i],locrhs[pivot]); + } + for(int j=i+1; j<3; j++) + { + double fac = matrix[j][i] / matrix[i][i]; + + for(int k=i+1; k<3; k++) + matrix[j][k] -= fac*matrix[i][k]; + locrhs[j] -= fac*locrhs[i]; + } + } + else + retval = 1; + } + + if(fabs(matrix[2][2]) < 1e-40) + retval = 1; + + if(retval != 0) + return retval; + + + for(int i=2; i>=0; i--) + { + double sum = locrhs[i]; + for(int j=2; j>i; j--) + sum -= matrix[i][j]*sol.X(j+1); + + sol.X(i+1) = sum/matrix[i][i]; + } + + return 0; + + + + + + /* + double 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; + */ + /* + 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 & p, + ARRAY & 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/libsrc/gprim/geom3d.hpp b/libsrc/gprim/geom3d.hpp new file mode 100644 index 00000000..9c6ffae4 --- /dev/null +++ b/libsrc/gprim/geom3d.hpp @@ -0,0 +1,733 @@ +#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); + +inline double Dist2 (const Point3d & p1, const Point3d & p2); + +/// 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 & p, ARRAY & pp) const; + /// + void FromPlain (const Point3d & pp, Point3d & p) const; +}; + + + +#endif diff --git a/libsrc/gprim/geomfuncs.cpp b/libsrc/gprim/geomfuncs.cpp new file mode 100644 index 00000000..b2ac8382 --- /dev/null +++ b/libsrc/gprim/geomfuncs.cpp @@ -0,0 +1,111 @@ +#include + +#include +#include + +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/libsrc/gprim/geomfuncs.hpp b/libsrc/gprim/geomfuncs.hpp new file mode 100644 index 00000000..4c8a51ee --- /dev/null +++ b/libsrc/gprim/geomfuncs.hpp @@ -0,0 +1,157 @@ +#ifndef FILE_GEOMFUNCS +#define FILE_GEOMFUNCS + +/* *************************************************************************/ +/* File: geomfuncs.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +template +inline double Abs (const Vec & v) +{ + double sum = 0; + for (int i = 0; i < D; i++) + sum += v(i) * v(i); + return sqrt (sum); +} + + +template +inline double Abs2 (const Vec & v) +{ + double sum = 0; + for (int i = 0; i < D; i++) + sum += v(i) * v(i); + return sum; +} + + + +template +inline double Dist (const Point & a, const Point & b) +{ + return Abs (a-b); +} + +template +inline double Dist2 (const Point & a, const Point & b) +{ + return Abs2 (a-b); +} + + +template +inline Point Center (const Point & a, const Point & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = 0.5 * (a(i) + b(i)); + return res; +} + +template +inline Point Center (const Point & a, const Point & b, const Point & c) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = (1.0/3.0) * (a(i) + b(i) + c(i)); + return res; +} + +template +inline Point Center (const Point & a, const Point & b, const Point & c, const Point & d) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = (1.0/4.0) * (a(i) + b(i) + c(i) + d(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) ); +} + + +inline double Determinant (const Vec<3> & col1, + const Vec<3> & col2, + const Vec<3> & col3) +{ + return + col1(0) * ( col2(1) * col3(2) - col2(2) * col3(1)) + + col1(1) * ( col2(2) * col3(0) - col2(0) * col3(2)) + + col1(2) * ( col2(0) * col3(1) - col2(1) * col3(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 +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/libsrc/gprim/geomobjects.hpp b/libsrc/gprim/geomobjects.hpp new file mode 100644 index 00000000..87c38d9b --- /dev/null +++ b/libsrc/gprim/geomobjects.hpp @@ -0,0 +1,359 @@ +#ifndef FILE_OBJECTS +#define FILE_OBJECTS + +/* *************************************************************************/ +/* File: geomobjects.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + + +template class Vec; +template class Point; + + +template +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 & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Point (const Vec & v) + { for (int i = 0; i < D; i++) x[i] = v(i); } + + + Point & operator= (const Point & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + Point & operator= (double val) + { + for (int i = 0; i < D; i++) x[i] = val; + 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 +class Vec +{ + +protected: + double x[D]; + +public: + Vec () { ; } // for (int i = 0; i < D; i++) x[i] = 0; } + 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 & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Vec (const Point & p) + { for (int i = 0; i < D; i++) x[i] = p(i); } + + Vec (const Vec & p1, const Vec & p2) + { for(int i=0; i & 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 & Normalize () + { + double l = Length(); + if (l != 0) + for (int i = 0; i < D; i++) + x[i] /= l; + return *this; + } + + Vec GetNormal () const; +}; + + + + + +template +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 Col (int i) const + { + Vec hv; + for (int j = 0; j < H; j++) + hv(j) = x[j*W+i]; + return hv; + } + + Vec Row (int i) const + { + Vec hv; + for (int j = 0; j < W; j++) + hv(j) = x[i*W+j]; + return hv; + } + + void Solve (const Vec & rhs, Vec & sol) const + { + Mat inv; + CalcInverse (*this, inv); + sol = inv * rhs; + } +}; + + + + +template +class Box +{ +protected: + Point pmin, pmax; +public: + Box () { ; } + Box ( const Point & p1, const Point & p2) + { + for (int i = 0; i < D; i++) + { + pmin(i) = min2(p1(i), p2(i)); + pmax(i) = max2(p1(i), p2(i)); + } + } + + enum EB_TYPE { EMPTY_BOX = 1 }; + Box ( EB_TYPE et ) + { + pmin = Point<3> (1e99, 1e99, 1e99); + pmax = Point<3> (-1e99, -1e99, -1e99); + } + + const Point & PMin () const { return pmin; } + const Point & PMax () const { return pmax; } + + void Set (const Point & p) + { pmin = pmax = p; } + + void Add (const Point & 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 Center () const + { + Point 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 GetPointNr (int nr) const + { + Point p; + for (int i = 0; i < D; i++) + { + p(i) = (nr & 1) ? pmax(i) : pmin(i); + nr >>= 1; + } + return p; + } + + + bool Intersect (const Box & 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 & 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 +class BoxSphere : public Box +{ +protected: + /// + Point c; + /// + double diam; + /// + double inner; +public: + /// + BoxSphere () { }; + /// + BoxSphere (const Box & box) + : Box (box) + { + CalcDiamCenter(); + }; + + /// + BoxSphere ( Point apmin, Point apmax ) + : Box (apmin, apmax) + { + CalcDiamCenter(); + } + + /// + const Point & 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::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/libsrc/gprim/geomobjects2.hpp b/libsrc/gprim/geomobjects2.hpp new file mode 100644 index 00000000..014a3852 --- /dev/null +++ b/libsrc/gprim/geomobjects2.hpp @@ -0,0 +1,366 @@ +#ifndef FILE_OBJECTS +#define FILE_OBJECTS + +/* *************************************************************************/ +/* File: geomobjects.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + +template +class VecExpr +{ +public: + VecExpr () { ; } + double operator() (int i) const { return static_cast (*this) (i); } +}; + + +template class Vec; +template class Point; + + +template +class Point : public VecExpr > +{ + +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 & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Point (const Vec & v) + { for (int i = 0; i < D; i++) x[i] = v(i); } + + + template + explicit Point (const VecExpr & expr) + { + for (int i = 0; i < D; i++) x[i] = expr(i); + } + + Point & operator= (const Point & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + template + Point & operator= (const VecExpr & 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 +class Vec : public VecExpr > +{ + +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 & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Vec (const Point & p) + { for (int i = 0; i < D; i++) x[i] = p(i); } + + template + explicit Vec (const VecExpr & expr) + { + for (int i = 0; i < D; i++) x[i] = expr(i); + } + + + Vec & operator= (const Vec & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + template + Vec & operator= (const VecExpr & 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 & Normalize () + { + double l = Length(); + if (l != 0) + for (int i = 0; i < D; i++) + x[i] /= l; + return *this; + } + + Vec GetNormal () const; +}; + + + + + +template +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 Col (int i) const + { + Vec hv; + for (int j = 0; j < H; j++) + hv(j) = x[j*W+i]; + return hv; + } + + Vec Row (int i) const + { + Vec hv; + for (int j = 0; j < W; j++) + hv(j) = x[i*W+j]; + return hv; + } + + void Solve (const Vec & rhs, Vec & sol) const + { + Mat inv; + CalcInverse (*this, inv); + sol = inv * rhs; + } +}; + + + + +template +class Box +{ +protected: + Point pmin, pmax; +public: + Box () { ; } + Box ( const Point & p1, const Point & p2) + { + for (int i = 0; i < D; i++) + { + pmin(i) = min2(p1(i), p2(i)); + pmax(i) = max2(p1(i), p2(i)); + } + } + + const Point & PMin () const { return pmin; } + const Point & PMax () const { return pmax; } + + void Set (const Point & p) + { pmin = pmax = p; } + + void Add (const Point & 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 Center () const + { + Point 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 GetPointNr (int nr) const + { + Point p; + for (int i = 0; i < D; i++) + { + p(i) = (nr & 1) ? pmax(i) : pmin(i); + nr >>= 1; + } + return p; + } + + + bool Intersect (const Box & 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 & 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 +class BoxSphere : public Box +{ +protected: + /// + Point c; + /// + double diam; + /// + double inner; +public: + /// + BoxSphere () { }; + /// + BoxSphere ( Point pmin, Point pmax ) + : Box (pmin, pmax) + { + CalcDiamCenter(); + } + + /// + const Point & 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::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/libsrc/gprim/geomops.hpp b/libsrc/gprim/geomops.hpp new file mode 100644 index 00000000..755f35a8 --- /dev/null +++ b/libsrc/gprim/geomops.hpp @@ -0,0 +1,391 @@ +#ifndef FILE_GEOMOPS +#define FILE_GEOMOPS + +/* *************************************************************************/ +/* File: geomops.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +/* + +Point - Vector operations + + */ + + +template +inline Vec operator+ (const Vec & a, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; +} + + + +template +inline Point operator+ (const Point & a, const Vec & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; +} + + + +template +inline Vec operator- (const Point & a, const Point & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + +template +inline Point operator- (const Point & a, const Vec & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + +template +inline Vec operator- (const Vec & a, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + + + +template +inline Vec operator* (double s, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = s * b(i); + return res; +} + + +template +inline double operator* (const Vec & a, const Vec & b) +{ + double sum = 0; + for (int i = 0; i < D; i++) + sum += a(i) * b(i); + return sum; +} + + + +template +inline Vec operator- (const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = -b(i); + return res; +} + + +template +inline Point & operator+= (Point & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + +template +inline Vec & operator+= (Vec & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + + +template +inline Point & operator-= (Point & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + +template +inline Vec & operator-= (Vec & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + + + +template +inline Vec & operator*= (Vec & a, double s) +{ + for (int i = 0; i < D; i++) + a(i) *= s; + return a; +} + + +template +inline Vec & operator/= (Vec & a, double s) +{ + for (int i = 0; i < D; i++) + a(i) /= s; + return a; +} + + + + +// Matrix - Vector operations + +/* +template +inline Vec operator* (const Mat & m, const Vec & v) +{ + Vec 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 +inline Mat operator* (const Mat & a, const Mat & b) +{ + Mat 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 +inline Mat Trans (const Mat & m) +{ + Mat res; + for (int i = 0; i < H; i++) + for (int j = 0; j < W; j++) + res(j,i) = m(i,j); + return res; +} + + + + + + + + + + + +template +inline ostream & operator<< (ostream & ost, const Vec & a) +{ + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Point & a) +{ + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Box & b) +{ + ost << b.PMin() << " - " << b.PMax(); + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Mat & 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/libsrc/gprim/geomops2.hpp b/libsrc/gprim/geomops2.hpp new file mode 100644 index 00000000..c615da14 --- /dev/null +++ b/libsrc/gprim/geomops2.hpp @@ -0,0 +1,428 @@ +#ifndef FILE_GEOMOPS +#define FILE_GEOMOPS + +/* *************************************************************************/ +/* File: geomops.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +/* + +Point - Vector operations + + */ + + + + +template +class SumExpr : public VecExpr > +{ + 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 +inline SumExpr +operator+ (const VecExpr & a, const VecExpr & b) +{ + return SumExpr (static_cast (a), static_cast (b)); +} + +/* +template +inline SumExpr&, const Vec&> +operator+ (const Vec & a, const Vec & b) +{ + return SumExpr&, const Vec&> (a, b); +} +*/ + + + + + +/* +template +inline Vec operator+ (const Vec & a, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; +} +*/ + +template +inline Point operator+ (const Point & a, const Vec & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; +} + + +template +inline Vec operator- (const Point & a, const Point & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + +template +inline Point operator- (const Point & a, const Vec & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + +template +inline Vec operator- (const Vec & a, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + + +template +inline Vec operator* (double s, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = s * b(i); + return res; +} + + +template +inline double operator* (const Vec & a, const Vec & b) +{ + double sum = 0; + for (int i = 0; i < D; i++) + sum += a(i) * b(i); + return sum; +} + + + +template +inline Vec operator- (const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = -b(i); + return res; +} + + +template +inline Point & operator+= (Point & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + + +template +inline Point & operator+= (Point & a, const VecExpr & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + +template +inline Vec & operator+= (Vec & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + + + + + +template +inline Point & operator-= (Point & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + +template +inline Point & operator-= (Point & a, const VecExpr & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + + + + + +template +inline Vec & operator-= (Vec & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + + + +template +inline Vec & operator*= (Vec & a, double s) +{ + for (int i = 0; i < D; i++) + a(i) *= s; + return a; +} + + +template +inline Vec & operator/= (Vec & a, double s) +{ + for (int i = 0; i < D; i++) + a(i) /= s; + return a; +} + + + + +// Matrix - Vector operations + +/* +template +inline Vec operator* (const Mat & m, const Vec & v) +{ + Vec 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 +inline Mat operator* (const Mat & a, const Mat & b) +{ + Mat 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 +inline Mat Trans (const Mat & m) +{ + Mat res; + for (int i = 0; i < H; i++) + for (int j = 0; j < W; j++) + res(j,i) = m(i,j); + return res; +} + + + + + + + + + + + +template +inline ostream & operator<< (ostream & ost, const Vec & a) +{ + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Point & a) +{ + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Box & b) +{ + ost << b.PMin() << " - " << b.PMax(); + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Mat & 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/libsrc/gprim/geomtest3d.cpp b/libsrc/gprim/geomtest3d.cpp new file mode 100644 index 00000000..20a3be0b --- /dev/null +++ b/libsrc/gprim/geomtest3d.cpp @@ -0,0 +1,1150 @@ +#include +#include + +#include +#include + +namespace netgen +{ +int +IntersectTriangleLine (const Point<3> ** tri, const Point<3> ** 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 Point<3> ** tet, const Point<3> ** 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; + + double eps2 = eps * eps; + int cnt = 0; + + 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; + + + // (*testout) << "tet-trig inters, cnt = " << cnt << endl; + + // cnt .. number of common points + switch (cnt) + { + case 0: + { + 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 Point<3> * 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: + { + 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: + { + // 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: + { + // common face + return 0; + } + } + + (*testout) << "hit, cnt = " << cnt << endl; + return 1; +} + + + + + +int IntersectTetTriangleRef (const Point<3> ** tri, const int * tripi) +{ + int i, j; + double eps = 1e-8; + double eps2 = eps * eps; + + static Point<3> rtetp1(0, 0, 0); + static Point<3> rtetp2(1, 0, 0); + static Point<3> rtetp3(0, 1, 0); + static Point<3> rtetp4(0, 0, 1); + + static const Point<3> * 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; + + + switch (cnt) + { + case 0: + { + Vec3d no, n; + // int inpi[3]; + int pside[3][4]; + + for (j = 0; j < 3; j++) + { + pside[j][0] = (*tri[j])(0) > -eps; + pside[j][1] = (*tri[j])(1) > -eps; + pside[j][2] = (*tri[j])(2) > -eps; + pside[j][3] = (*tri[j])(0) + (*tri[j])(1) + (*tri[j])(2) < 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 Point<3> * 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: + { + 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: + { + // 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: + { + // common face + return 0; + } + } + + (*testout) << "hit, cnt = " << cnt << endl; + return 1; +} + + + + + + + + + + + +int IntersectTriangleTriangle (const Point<3> ** tri1, const Point<3> ** 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 Point<3> * 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 Point<3> ** pts, Point<3> & c) +{ + 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/libsrc/gprim/geomtest3d.hpp b/libsrc/gprim/geomtest3d.hpp new file mode 100644 index 00000000..7ce362d0 --- /dev/null +++ b/libsrc/gprim/geomtest3d.hpp @@ -0,0 +1,80 @@ +#ifndef FILE_GEOMTEST3D +#define FILE_GEOMTEST3D + +/* *************************************************************************/ +/* File: geomtest3d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 13. Feb. 98 */ +/* *************************************************************************/ + + + +extern int +IntersectTriangleLine (const Point<3> ** tri, const Point<3> ** 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 Point<3> ** tet, const Point<3> ** 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 Point<3> ** tri1, const Point<3> ** 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 Point<3> ** pts, Point<3> & 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/libsrc/gprim/gprim.hpp b/libsrc/gprim/gprim.hpp new file mode 100644 index 00000000..0f57ebac --- /dev/null +++ b/libsrc/gprim/gprim.hpp @@ -0,0 +1,26 @@ +#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/libsrc/gprim/transform3d.cpp b/libsrc/gprim/transform3d.cpp new file mode 100644 index 00000000..ea62fffe --- /dev/null +++ b/libsrc/gprim/transform3d.cpp @@ -0,0 +1,173 @@ +#include + +#include +#include +#include + +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/libsrc/gprim/transform3d.hpp b/libsrc/gprim/transform3d.hpp new file mode 100644 index 00000000..2754173e --- /dev/null +++ b/libsrc/gprim/transform3d.hpp @@ -0,0 +1,190 @@ +#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); + } + } + + /// + void Transform (Point3d & p) const + { + Point3d hp; + Transform (p, hp); + p = hp; + } + + /// 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 +class Transformation +{ + Mat m; + Vec v; +public: + /// + Transformation () { m = 0; v = 0; } + + /// Unit tet is mapped to tet descibed by pp + Transformation (const Point * pp); + + /// translation + Transformation (const Vec & translate) + { + v = translate; + m = 0; + for (int i = 0; i < D; i++) + m(i,i) = 1; + } + + // rotation with ... + Transformation (const Point & 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 vc(c); + Transformation tc(vc); + Transformation tcinv(-vc); + // tc.CalcInverse (tcinv); + + Transformation 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 & from, Point & to) const + { + to = Point (v + m * Vec(from)); + } + + void Transform (Point & p) const + { + p = Point (v + m * Vec(p)); + } + + + + /// transform vector, apply only linear part, not offset + void Transform (const Vec & from, Vec & to) const + { + to = m * from; + } +}; + +template +ostream & operator<< (ostream & ost, Transformation & trans); + + + + +#endif diff --git a/libsrc/include/Makefile.am b/libsrc/include/Makefile.am new file mode 100644 index 00000000..4edf2056 --- /dev/null +++ b/libsrc/include/Makefile.am @@ -0,0 +1,2 @@ +INCLUDES = +METASOURCES = AUTO diff --git a/libsrc/include/Makefile.in b/libsrc/include/Makefile.in new file mode 100644 index 00000000..3962dbc1 --- /dev/null +++ b/libsrc/include/Makefile.in @@ -0,0 +1,331 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/include +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = +METASOURCES = AUTO +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/include/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/include/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/include/acisgeom.hpp b/libsrc/include/acisgeom.hpp new file mode 100644 index 00000000..491b7720 --- /dev/null +++ b/libsrc/include/acisgeom.hpp @@ -0,0 +1,3 @@ +#ifdef ACIS +#include "../acisgeom/acisgeom.hpp" +#endif diff --git a/libsrc/include/csg.hpp b/libsrc/include/csg.hpp new file mode 100644 index 00000000..ffd45ef0 --- /dev/null +++ b/libsrc/include/csg.hpp @@ -0,0 +1 @@ +#include "../csg/csg.hpp" diff --git a/libsrc/include/geometry2d.hpp b/libsrc/include/geometry2d.hpp new file mode 100644 index 00000000..bf0965c2 --- /dev/null +++ b/libsrc/include/geometry2d.hpp @@ -0,0 +1 @@ +#include "../geom2d/geometry2d.hpp" diff --git a/libsrc/include/gprim.hpp b/libsrc/include/gprim.hpp new file mode 100644 index 00000000..1e827aaf --- /dev/null +++ b/libsrc/include/gprim.hpp @@ -0,0 +1 @@ +#include "../gprim/gprim.hpp" diff --git a/libsrc/include/incvis.hpp b/libsrc/include/incvis.hpp new file mode 100644 index 00000000..2204fade --- /dev/null +++ b/libsrc/include/incvis.hpp @@ -0,0 +1,32 @@ +// libraries for User interface: + + +#ifndef NOTCL + +#include +#include + +#if TK_MAJOR_VERSION==8 && TK_MINOR_VERSION>=4 +#define tcl_const const +#else +#define tcl_const +#endif + +#endif + +#include +#include +#ifndef NOTCL +#include +// #include "../../togl/togl.h" +#endif + + + + +// part of OpenGL 1.2, but not in Microsoft's OpenGL 1.1 header: +// GL version sould be checked at runtime +#ifndef GL_CLAMP_TO_EDGE +#define GL_CLAMP_TO_EDGE 0x812F +#endif + diff --git a/libsrc/include/linalg.hpp b/libsrc/include/linalg.hpp new file mode 100644 index 00000000..e96bd036 --- /dev/null +++ b/libsrc/include/linalg.hpp @@ -0,0 +1 @@ +#include "../linalg/linalg.hpp" diff --git a/libsrc/include/meshing.hpp b/libsrc/include/meshing.hpp new file mode 100644 index 00000000..e41a88f9 --- /dev/null +++ b/libsrc/include/meshing.hpp @@ -0,0 +1 @@ +#include <../meshing/meshing.hpp> diff --git a/libsrc/include/myadt.hpp b/libsrc/include/myadt.hpp new file mode 100644 index 00000000..d36bef05 --- /dev/null +++ b/libsrc/include/myadt.hpp @@ -0,0 +1 @@ +#include <../general/myadt.hpp> diff --git a/libsrc/include/mydefs.hpp b/libsrc/include/mydefs.hpp new file mode 100644 index 00000000..c34ce56a --- /dev/null +++ b/libsrc/include/mydefs.hpp @@ -0,0 +1,29 @@ +#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/libsrc/include/mystdlib.h b/libsrc/include/mystdlib.h new file mode 100644 index 00000000..939a268e --- /dev/null +++ b/libsrc/include/mystdlib.h @@ -0,0 +1,104 @@ +#ifndef FILE_MYSTDLIB +#define FILE_MYSTDLIB + + +#include +#include +#include +#include + +#ifdef OLDCINCLUDE + +// e.g., CC compiler on SGI +#include +#include +#include +#include +#include +#include + +#else + +// new standard +#include +#include +#include +#include +#include +#include +#include +#endif + + + +#include +#include +#include + +#ifdef PARALLEL +#undef SEEK_SET +#undef SEEK_CUR +#undef SEEK_END +#include +#endif + +#ifdef _OPENMP +#include +#endif + + +#ifdef METIS +namespace metis { extern "C" { +#include +} } +#endif + + + +#ifndef NO_PARALLEL_THREADS +#ifndef WIN32 +#include +#endif +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + +/*** Windows headers ***/ +#ifdef _MSC_VER +# define WIN32_LEAN_AND_MEAN +# ifndef NO_PARALLEL_THREADS +# include +# include +# endif +# include +# undef WIN32_LEAN_AND_MEAN +# include + +#else +# ifndef NO_PARALLEL_THREADS +# include +# endif +#endif + +/* +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/libsrc/include/occgeom.hpp b/libsrc/include/occgeom.hpp new file mode 100644 index 00000000..af258e0d --- /dev/null +++ b/libsrc/include/occgeom.hpp @@ -0,0 +1 @@ +#include "../occ/occgeom.hpp" diff --git a/libsrc/include/opti.hpp b/libsrc/include/opti.hpp new file mode 100644 index 00000000..6b8a0b61 --- /dev/null +++ b/libsrc/include/opti.hpp @@ -0,0 +1 @@ +#include "../opti/opti.hpp" diff --git a/libsrc/include/parallel.hpp b/libsrc/include/parallel.hpp new file mode 100644 index 00000000..4ba662f8 --- /dev/null +++ b/libsrc/include/parallel.hpp @@ -0,0 +1 @@ +#include "../parallel/parallel.hpp" diff --git a/libsrc/include/stepgeom.hpp b/libsrc/include/stepgeom.hpp new file mode 100644 index 00000000..d2c5c5e4 --- /dev/null +++ b/libsrc/include/stepgeom.hpp @@ -0,0 +1,10 @@ +#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/libsrc/include/stepreader.hpp b/libsrc/include/stepreader.hpp new file mode 100644 index 00000000..0214d58d --- /dev/null +++ b/libsrc/include/stepreader.hpp @@ -0,0 +1 @@ +#include "../stepgeom/STEPread.hh" diff --git a/libsrc/include/stlgeom.hpp b/libsrc/include/stlgeom.hpp new file mode 100644 index 00000000..f1eea264 --- /dev/null +++ b/libsrc/include/stlgeom.hpp @@ -0,0 +1 @@ +#include <../stlgeom/stlgeom.hpp> diff --git a/libsrc/include/visual.hpp b/libsrc/include/visual.hpp new file mode 100644 index 00000000..f026f5a4 --- /dev/null +++ b/libsrc/include/visual.hpp @@ -0,0 +1 @@ +#include "../visualization/visual.hpp" diff --git a/libsrc/interface/Makefile.am b/libsrc/interface/Makefile.am new file mode 100644 index 00000000..3e7da00a --- /dev/null +++ b/libsrc/interface/Makefile.am @@ -0,0 +1,9 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface +METASOURCES = AUTO +noinst_LIBRARIES = libinterface.a +libinterface_a_SOURCES = importsolution.cpp nginterface.cpp printdest.cpp \ + read_fnf_mesh.cpp readtetmesh.cpp readuser.cpp writeabaqus.cpp writediffpack.cpp \ + writedolfin.cpp writeelmer.cpp writefeap.cpp writefluent.cpp writegmsh.cpp writejcm.cpp \ + writepermas.cpp writetecplot.cpp writetet.cpp writetochnog.cpp writeuser.cpp \ + wuchemnitz.cpp +noinst_HEADERS = nginterface.h diff --git a/libsrc/interface/Makefile.in b/libsrc/interface/Makefile.in new file mode 100644 index 00000000..94ee8e1f --- /dev/null +++ b/libsrc/interface/Makefile.in @@ -0,0 +1,476 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/interface +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libinterface_a_AR = $(AR) $(ARFLAGS) +libinterface_a_LIBADD = +am_libinterface_a_OBJECTS = importsolution.$(OBJEXT) \ + nginterface.$(OBJEXT) printdest.$(OBJEXT) \ + read_fnf_mesh.$(OBJEXT) readtetmesh.$(OBJEXT) \ + readuser.$(OBJEXT) writeabaqus.$(OBJEXT) \ + writediffpack.$(OBJEXT) writedolfin.$(OBJEXT) \ + writeelmer.$(OBJEXT) writefeap.$(OBJEXT) writefluent.$(OBJEXT) \ + writegmsh.$(OBJEXT) writejcm.$(OBJEXT) writepermas.$(OBJEXT) \ + writetecplot.$(OBJEXT) writetet.$(OBJEXT) \ + writetochnog.$(OBJEXT) writeuser.$(OBJEXT) \ + wuchemnitz.$(OBJEXT) +libinterface_a_OBJECTS = $(am_libinterface_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libinterface_a_SOURCES) +DIST_SOURCES = $(libinterface_a_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface +METASOURCES = AUTO +noinst_LIBRARIES = libinterface.a +libinterface_a_SOURCES = importsolution.cpp nginterface.cpp printdest.cpp \ + read_fnf_mesh.cpp readtetmesh.cpp readuser.cpp writeabaqus.cpp writediffpack.cpp \ + writedolfin.cpp writeelmer.cpp writefeap.cpp writefluent.cpp writegmsh.cpp writejcm.cpp \ + writepermas.cpp writetecplot.cpp writetet.cpp writetochnog.cpp writeuser.cpp \ + wuchemnitz.cpp + +noinst_HEADERS = nginterface.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/interface/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/interface/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libinterface.a: $(libinterface_a_OBJECTS) $(libinterface_a_DEPENDENCIES) + -rm -f libinterface.a + $(libinterface_a_AR) libinterface.a $(libinterface_a_OBJECTS) $(libinterface_a_LIBADD) + $(RANLIB) libinterface.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importsolution.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nginterface.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printdest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read_fnf_mesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readtetmesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readuser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeabaqus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writediffpack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writedolfin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeelmer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writefeap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writefluent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writegmsh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writejcm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writepermas.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writetecplot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writetet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writetochnog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeuser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wuchemnitz.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/interface/importsolution.cpp b/libsrc/interface/importsolution.cpp new file mode 100644 index 00000000..4f9d3e67 --- /dev/null +++ b/libsrc/interface/importsolution.cpp @@ -0,0 +1,129 @@ +// +// Read solution file +// + + +#include + + +#include +#include +#include +#include + +#include "nginterface.h" + +namespace netgen +{ +#include "writeuser.hpp" + + +void ImportSolution (const char * filename) +{ + ifstream inf (filename); + char buf[100], name[1000]; + int i, 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; + soldata.draw_surface = 1; + soldata.draw_volume = 1; + if (strcmp (type, "element") == 0) + { + soldata.soltype = NG_SOLUTION_ELEMENT; + soldata.draw_surface = 0; + } + if (strcmp (type, "surfaceelement") == 0) + { + soldata.soltype = NG_SOLUTION_SURFACE_ELEMENT; + soldata.draw_volume = 0; + } + 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/libsrc/interface/nginterface.cpp b/libsrc/interface/nginterface.cpp new file mode 100644 index 00000000..024c5030 --- /dev/null +++ b/libsrc/interface/nginterface.cpp @@ -0,0 +1,2467 @@ +#include + + +#include +#include +#include +#include + + +#ifdef OCCGEOMETRY +#include +#endif + +#ifdef ACIS +#include +#endif + +#ifdef SOCKETS +#include "../sockets/sockets.hpp" +#endif + +#ifndef NOTCL +#include +#endif + + +#include "nginterface.h" + +// #include + + +// #include + + +namespace netgen +{ +#include "writeuser.hpp" + + extern AutoPtr mesh; +#ifndef NOTCL + extern VisualSceneMesh vsmesh; + extern Tcl_Interp * tcl_interp; +#endif + + extern AutoPtr geometry2d; + extern AutoPtr geometry; + extern STLGeometry * stlgeometry; + +#ifdef OCCGEOMETRY + extern OCCGeometry * occgeometry; +#endif +#ifdef ACIS + extern ACISGeometry * acisgeometry; +#endif + +#ifdef OPENGL + extern VisualSceneSolution vssolution; +#endif + extern CSGeometry * ParseCSG (istream & istr); + +#ifdef SOCKETS + extern AutoPtr clientsocket; + //extern ARRAY< AutoPtr < ServerInfo > > servers; + extern ARRAY< ServerInfo* > servers; +#endif +} + + +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 (const char * filename) +{ + + + if (printmessage_importance>0) + cout << "CALLED NG LOAD GEOMETRY" << endl; + + geometry.Reset (new CSGeometry ()); + geometry2d.Reset (); + +#ifdef OCCGEOMETRY + delete occgeometry; + occgeometry = 0; +#endif +#ifdef ACIS + delete acisgeometry; + acisgeometry = 0; +#endif + + // he: if filename is empty, return + // can be used to reset geometry + if (strcmp(filename,"")==0) + return; + + ifstream infile (filename); + + 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"); + cerr << "Error: input file \"" << filename << "\" not found" << endl; + } + + geometry -> FindIdenticSurfaces(1e-6); + +#ifdef PARALLEL + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + if ( id > 0 ) + { + geometry->CalcTriangleApproximation ( geometry->BoundingBox(), 0.001, 20 ); + return; + } +#endif + + Box<3> box (geometry->BoundingBox()); +#ifdef NOTCL + double detail = 0.001; + double facets = 20; + geometry->CalcTriangleApproximation(box, detail, facets); + +#else + double detail = atof (Tcl_GetVar (tcl_interp, "::geooptions.detail", 0)); + double facets = atof (Tcl_GetVar (tcl_interp, "::geooptions.facets", 0)); + + if (atoi (Tcl_GetVar (tcl_interp, "::geooptions.drawcsg", 0))) + geometry->CalcTriangleApproximation(box, detail, facets); +#endif + } + + 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)) + { + 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 + +#ifdef ACIS + else if ( + strcmp (&filename[strlen(filename)-3], "sat") == 0 || + ( strlen(filename) >= 7 && strcmp ( &filename[ strlen( filename)-7 ], "sat.tet" ) == 0 ) + ) + { + PrintMessage (1, "Load ACIS geometry file ", filename); + acisgeometry = LoadACIS_SAT (filename); + } +#endif + else + { + //throw NgException("Unknown geometry extension"); + cerr << "Error: Unknown geometry extension \"" << filename[strlen(filename)-3] << "\"" << endl; + } + + +} + + +void Ng_LoadMeshFromStream ( istream & input ) +{ + mesh.Reset (new Mesh()); + mesh -> Load(input); + if(input.good()) + { + string auxstring; + input >> auxstring; + if(auxstring == "csgsurfaces") + { + if (geometry) + { + geometry.Reset (new CSGeometry ("")); + } + if (stlgeometry) + { + delete stlgeometry; + stlgeometry = NULL; + } +#ifdef OCCGEOMETRY + if (occgeometry) + { + delete occgeometry; + occgeometry = NULL; + } +#endif +#ifdef ACIS + if (acisgeometry) + { + delete acisgeometry; + acisgeometry = NULL; + } +#endif + geometry2d.Reset (0); + + geometry -> LoadSurfaces(input); + } + } + +} + + + + +void Ng_LoadMesh (const char * filename) +{ + if ( (strlen (filename) > 4) && + strcmp (filename + (strlen (filename)-4), ".vol") != 0 ) + { + mesh.Reset (new Mesh()); + ReadFile(*mesh,filename); + + //mesh->SetGlobalH (mparam.maxh); + //mesh->CalcLocalH(); + return; + } + + ifstream infile(filename); + Ng_LoadMeshFromStream(infile); +} + +void Ng_LoadMeshFromString (char * mesh_as_string) +{ + istringstream instream(mesh_as_string); + Ng_LoadMeshFromStream(instream); +} + + + + +int Ng_GetDimension () +{ + return (mesh) ? mesh->GetDimension() : -1; +} + +int Ng_GetNP () +{ + return (mesh) ? mesh->GetNP() : 0; +} + +int Ng_GetNV () +{ + return (mesh) ? mesh->GetNV() : 0; +} + +int Ng_GetNE () +{ + if(!mesh) return 0; + if (mesh->GetDimension() == 3) + return mesh->GetNE(); + else + return mesh->GetNSE(); +} + +int Ng_GetNSE () +{ + if(!mesh) return 0; + if (mesh->GetDimension() == 3) + return mesh->GetNSE(); + else + return mesh->GetNSeg(); +} + +void Ng_GetPoint (int pi, double * p) +{ + if (pi < 1 || pi > mesh->GetNP()) + { + if (printmessage_importance>0) + cout << "Ng_GetPoint: illegal point " << pi << endl; + return; + } + + 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: + if (printmessage_importance>0) + 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: + { + if (printmessage_importance>0) + 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 + { + 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; + } +} + +void Ng_SetElementIndex(const int ei, const int index) +{ + mesh->VolumeElement(ei).SetIndex(index); +} + +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 (mat); + else + return empty; + } + // add astrid + else + { + int ind = mesh->SurfaceElement(ei).GetIndex(); + ind = mesh->GetFaceDescriptor(ind).BCProperty(); + const char * mat = mesh->GetMaterial ( ind ); + if (mat) + return const_cast (mat); + else + return empty; + } + return 0; +} + +char * Ng_GetDomainMaterial (int dom) +{ + static char empty[] = ""; + // astrid + if ( 1 ) // mesh->GetDimension() == 3) + { + const char * mat = mesh->GetMaterial(dom); + if (mat) + return const_cast (mat); + else + return empty; + } + + return 0; +} + +int Ng_GetUserDataSize (char * id) +{ + ARRAY da; + mesh->GetUserData (id, da); + return da.Size(); +} + +void Ng_GetUserData (char * id, double * data) +{ + ARRAY da; + mesh->GetUserData (id, da); + for (int i = 0; i < da.Size(); i++) + data[i] = da[i]; +} + + +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; +} + +int Ng_GetSurfaceElementSurfaceNumber (int ei) +{ + if (mesh->GetDimension() == 3) + return mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).SurfNr(); + else + return mesh->LineSegment(ei).si; +} +int Ng_GetSurfaceElementFDNumber (int ei) +{ + if (mesh->GetDimension() == 3) + return mesh->SurfaceElement(ei).GetIndex(); + else + return -1; +} + + +char * Ng_GetSurfaceElementBCName (int ei) +{ + if ( mesh->GetDimension() == 3 ) + return const_cast(mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).GetBCName().c_str()); + else + return const_cast(mesh->LineSegment(ei).GetBCName().c_str()); +} + + +// Inefficient (but maybe safer) version: +//void Ng_GetSurfaceElementBCName (int ei, char * name) +//{ +// if ( mesh->GetDimension() == 3 ) +// strcpy(name,mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).GetBCName().c_str()); +// else +// strcpy(name,mesh->LineSegment(ei).GetBCName().c_str()); +//} + +char * Ng_GetBCNumBCName (int bcnr) +{ + return const_cast(mesh->GetBCName(bcnr).c_str()); +} + + +// Inefficient (but maybe safer) version: +//void Ng_GetBCNumBCName (int bcnr, char * name) +//{ +// strcpy(name,mesh->GetBCName(bcnr).c_str()); +//} + +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); + } + } +} + + + +void Ng_SetPointSearchStartElement(const int el) +{ + mesh->SetPointSearchStartElement(el); +} + + +int Ng_FindElementOfPoint (double * p, double * lami, int build_searchtree, + const int * const indices, const int numind) + +{ + ARRAY * dummy(NULL); + int ind = -1; + + if(indices != NULL) + { + dummy = new ARRAY(numind); + for(int i=0; iGetDimension() == 3) + { + Point3d p3d(p[0], p[1], p[2]); + ind = + mesh->GetElementOfPoint(p3d, lami, dummy, build_searchtree != 0); + } + else + { + double lam3[3]; + Point3d p2d(p[0], p[1], 0); + ind = + mesh->GetElementOfPoint(p2d, lam3, dummy, build_searchtree != 0); + + + if(mesh->SurfaceElement(ind).GetType()==QUAD) + { + lami[0] = lam3[0]; + lami[1] = lam3[1]; + } + else + { + lami[0] = 1-lam3[0]-lam3[1]; + lami[1] = lam3[0]; + } + } + + delete dummy; + + return ind; +} + +int Ng_FindSurfaceElementOfPoint (double * p, double * lami, int build_searchtree, + const int * const indices, const int numind) + +{ + ARRAY * dummy(NULL); + int ind = -1; + + if(indices != NULL) + { + dummy = new ARRAY(numind); + for(int i=0; iGetDimension() == 3) + { + Point3d p3d(p[0], p[1], p[2]); + ind = + mesh->GetSurfaceElementOfPoint(p3d, lami, dummy, build_searchtree != 0); + } + else + { + //throw NgException("FindSurfaceElementOfPoint for 2D meshes not yet implemented"); + cerr << "FindSurfaceElementOfPoint for 2D meshes not yet implemented" << endl; + } + + delete dummy; + + return ind; +} + + +int Ng_IsElementCurved (int ei) +{ + if (mesh->GetDimension() == 2) + return mesh->GetCurvedElements().IsSurfaceElementCurved (ei-1); + else + return mesh->GetCurvedElements().IsElementCurved (ei-1); +} + + +int Ng_IsSurfaceElementCurved (int sei) +{ + if (mesh->GetDimension() == 2) + return mesh->GetCurvedElements().IsSegmentCurved (sei-1); + else + return mesh->GetCurvedElements().IsSurfaceElementCurved (sei-1); +} + + + + +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]); + Point<3> xg; + Mat<3,3> dx; + + cout << "call calceltrafo" << endl; + mesh->GetCurvedElements().CalcElementTransformation (xl, ei-1, xg, dx); + cout << "xg = " << xg << endl << ", dx = " << dx << endl; + + + // 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_GetBufferedElementTransformation (int ei, const double * xi, + double * x, double * dxdxi, + void * buffer, int buffervalid) +{ + // buffer = 0; + // buffervalid = 0; + if (mesh->GetDimension() == 2) + { + return Ng_GetElementTransformation (ei, xi, x, dxdxi); + } + else + { + mesh->GetCurvedElements().CalcElementTransformation (reinterpret_cast &> (*xi), + ei-1, + reinterpret_cast &> (*x), + reinterpret_cast &> (*dxdxi), + buffer, (buffervalid != 0)); + + /* + Point<3> xl(xi[0], xi[1], xi[2]); + Point<3> xg; + Mat<3,3> dx; + // buffervalid = 0; + mesh->GetCurvedElements().CalcElementTransformation (xl, ei-1, xg, dx, buffer, buffervalid); + + // 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_GetMultiElementTransformation (int ei, int n, + const double * xi, int sxi, + double * x, int sx, + double * dxdxi, int sdxdxi) +{ + if (mesh->GetDimension() == 2) + { + for (int i = 0; i < n; i++) + { + Point<2> xl(xi[i*sxi], xi[i*sxi+1]); + Point<3> xg; + Mat<3,2> dx; + + mesh->GetCurvedElements().CalcSurfaceTransformation (xl, ei-1, xg, dx); + + if (x) + { + x[i*sx ] = xg(0); + x[i*sx+1] = xg(1); + } + + if (dxdxi) + { + dxdxi[i*sdxdxi ] = dx(0,0); + dxdxi[i*sdxdxi+1] = dx(0,1); + dxdxi[i*sdxdxi+2] = dx(1,0); + dxdxi[i*sdxdxi+3] = dx(1,1); + } + } + } + else + { + mesh->GetCurvedElements().CalcMultiPointElementTransformation (ei-1, n, xi, sxi, x, sx, dxdxi, sdxdxi); + } +} + + + + + + + + +void Ng_GetSurfaceElementTransformation (int sei, const double * xi, + double * x, double * dxdxi) +{ + if (mesh->GetDimension() == 2) + { + Point<3> xg; + Vec<3> dx; + + 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; + + 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); + } + } + } +} + + + + + +int Ng_GetSegmentIndex (int ei) +{ + const Segment & seg = mesh->LineSegment (ei); + return seg.edgenr; +} + + +NG_ELEMENT_TYPE Ng_GetSegment (int ei, int * epi, int * np) +{ + const Segment & seg = mesh->LineSegment (ei); + + epi[0] = seg.p1; + epi[1] = seg.p2; + + if (seg.pmid < 0) + { + if (np) *np = 2; + return NG_SEGM; + } + else + { + epi[2] = seg.pmid; + if (np) *np = 3; + return NG_SEGM3; + } +} + + + + + + +void Ng_GetSurfaceElementNeighbouringDomains(const int selnr, int & in, int & out) +{ + if ( mesh->GetDimension() == 3 ) + { + in = mesh->GetFaceDescriptor(mesh->SurfaceElement(selnr).GetIndex()).DomainIn(); + out = mesh->GetFaceDescriptor(mesh->SurfaceElement(selnr).GetIndex()).DomainOut(); + } + else + { + in = mesh -> LineSegment(selnr) . domin; + out = mesh -> LineSegment(selnr) . domout; + } +} + + +#ifdef PARALLEL +// Is Element ei an element of this processor ?? +bool Ng_IsGhostEl (int ei) +{ + if ( mesh->GetDimension() == 3 ) + return mesh->VolumeElement(ei).IsGhost(); + else + return false; +} + +void Ng_SetGhostEl(const int ei, const bool aisghost ) +{ + if ( mesh -> GetDimension () == 3 ) + mesh -> VolumeElement(ei).SetGhost (aisghost); +} + +bool Ng_IsGhostSEl (int ei) +{ + if ( mesh -> GetDimension () == 3 ) + return mesh->SurfaceElement(ei).IsGhost(); + else + return false; +} + +void Ng_SetGhostSEl(const int ei, const bool aisghost ) +{ + if ( mesh -> GetDimension () == 3 ) + mesh -> SurfaceElement(ei).SetGhost (aisghost); +} + + +bool Ng_IsGhostVert ( int pnum ) +{ + return mesh -> Point ( pnum ).IsGhost() ; +} +bool Ng_IsGhostEdge ( int ednum ) +{ + return mesh -> GetParallelTopology() . IsGhostEdge ( ednum ); +} + +bool Ng_IsGhostFace ( int fanum ) +{ + return mesh -> GetParallelTopology() . IsGhostFace ( fanum ); +} + +// void Ng_SetGhostVert ( const int pnum, const bool aisghost ); +// void Ng_SetGhostEdge ( const int ednum, const bool aisghost ); +// void Ng_SetGhostFace ( const int fanum, const bool aisghost ); + + +bool Ng_IsExchangeEl ( int elnum ) +{ return mesh -> GetParallelTopology() . IsExchangeElement ( elnum ); } + +bool Ng_IsExchangeSEl ( int selnum ) +{ return mesh -> GetParallelTopology() . IsExchangeSEl ( selnum ); } + +void Ng_UpdateOverlap() +{ mesh->UpdateOverlap(); } + +int Ng_Overlap () +{ return mesh->GetParallelTopology() . Overlap(); } + +#endif + +void Ng_SetRefinementFlag (int ei, int flag) +{ + if (mesh->GetDimension() == 3) + { + mesh->VolumeElement(ei).SetRefinementFlag (flag != 0); + mesh->VolumeElement(ei).SetStrongRefinementFlag (flag >= 10); + } + else + { + mesh->SurfaceElement(ei).SetRefinementFlag (flag != 0); + mesh->SurfaceElement(ei).SetStrongRefinementFlag (flag >= 10); + } +} + +void Ng_SetSurfaceRefinementFlag (int ei, int flag) +{ + if (mesh->GetDimension() == 3) + { + mesh->SurfaceElement(ei).SetRefinementFlag (flag != 0); + mesh->SurfaceElement(ei).SetStrongRefinementFlag (flag >= 10); + } +} + + +void Ng_Refine (NG_REFINEMENT_TYPE reftype) +{ + NgLock meshlock (mesh->MajorMutex(), 1); + + 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; + MeshOptimize2d * opt = NULL; + + if (geometry2d) + ref = new Refinement2d(*geometry2d); + else if (stlgeometry) + ref = new RefinementSTLGeometry(*stlgeometry); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif +#ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces (*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } +#endif + else if (geometry && mesh->GetDimension() == 3) + { + ref = new RefinementSurfaces(*geometry); + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + else + { + ref = new Refinement(); + } + + + ref -> Bisect (*mesh, biopt); + + mesh -> UpdateTopology(); + mesh -> GetCurvedElements().SetIsHighOrder (false); + + // mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + delete ref; + delete opt; +} + +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 + { + if (printmessage_importance>0) + 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_HPRefinement (int levels, double parameter) +{ + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); + else + ref = new RefinementSurfaces (*geometry); + + + HPRefinement (*mesh, ref, levels, parameter); +} +*/ + +void Ng_HPRefinement (int levels, double parameter, bool setorders, + bool ref_level) +{ + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); + else + ref = new RefinementSurfaces (*geometry); + + + HPRefinement (*mesh, ref, levels, parameter, setorders, ref_level); +} + + +void Ng_HighOrder (int order, bool rational) +{ + NgLock meshlock (mesh->MajorMutex(), true); + + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif +#ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces (*acisgeometry); + } +#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, rational); + mesh -> SetNextMajorTimeStamp(); + + /* + if(mesh) + mesh -> GetCurvedElements().BuildCurvedElements (ref, order, rational); + */ + + 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 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 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 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 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(); +} + +void Ng_GetElementOrders (int enr, int * ox, int * oy, int * oz) +{ + if (mesh->GetDimension() == 3) + mesh->VolumeElement(enr).GetOrder(*ox, *oy, *oz); + else + mesh->SurfaceElement(enr).GetOrder(*ox, *oy, *oz); +} + +void Ng_SetElementOrder (int enr, int order) +{ + if (mesh->GetDimension() == 3) + return mesh->VolumeElement(enr).SetOrder(order); + else + return mesh->SurfaceElement(enr).SetOrder(order); +} + +void Ng_SetElementOrders (int enr, int ox, int oy, int oz) +{ + if (mesh->GetDimension() == 3) + mesh->VolumeElement(enr).SetOrder(ox, oy, oz); + else + mesh->SurfaceElement(enr).SetOrder(ox, oy); +} + + +int Ng_GetSurfaceElementOrder (int enr) +{ + return mesh->SurfaceElement(enr).GetOrder(); +} + +//HERBERT: falsche Anzahl von Argumenten +//void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy, int * oz) +void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy) +{ + int d; + mesh->SurfaceElement(enr).GetOrder(*ox, *oy, d); +} + +void Ng_SetSurfaceElementOrder (int enr, int order) +{ + return mesh->SurfaceElement(enr).SetOrder(order); +} + +void Ng_SetSurfaceElementOrders (int enr, int ox, int oy) +{ + mesh->SurfaceElement(enr).SetOrder(ox, oy); +} + + +int Ng_GetNLevels () +{ + return (mesh) ? mesh->mglevels : 0; +} + + +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 () +{ +#ifdef OPENGL + vssolution.ClearSolutionData(); +#endif +} + + + +void Ng_Redraw () +{ +#ifdef OPENGL + extern bool nodisplay; // he: global in ngappinit.cpp + if (!nodisplay) + { + vssolution.UpdateSolutionTimeStamp(); + Render(); + } +#endif +} + + +void Ng_SetVisualizationParameter (const char * name, const char * value) +{ +#ifdef OPENGL +#ifndef NOTCL + char buf[100]; + sprintf (buf, "visoptions.%s", name); + if (printmessage_importance>0) + { + cout << "name = " << name << ", value = " << value << endl; + cout << "set tcl-variable " << buf << " to " << value << endl; + } + Tcl_SetVar (tcl_interp, buf, const_cast (value), 0); + Tcl_Eval (tcl_interp, "Ng_Vis_Set parameters;"); +#endif +#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; + + 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); + + if (printmessage_importance>0) + 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) = Point<3> (p); + } + + //firsttime = 0; + Ng_Redraw(); + } +} + + +int Ng_GetNPeriodicVertices (int idnr) +{ + ARRAY apairs; + mesh->GetIdentifications().GetPairs (idnr, apairs); + return apairs.Size(); +} + + +// pairs should be an integer array of 2*npairs +void Ng_GetPeriodicVertices (int idnr, int * pairs) +{ + ARRAY apairs; + mesh->GetIdentifications().GetPairs (idnr, 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 (int idnr) +{ + ARRAY 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(idnr, 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 idnr, int * pairs) +{ + ARRAY 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(idnr, 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); +} + +void Ng_GetStatus (char ** str, double & percent) +{ + MyStr s; + GetStatus(s,percent); + *str = new char[s.Length()+1]; + strcpy(*str,s.c_str()); +} + + +void Ng_SetTerminate(void) +{ + multithread.terminate = 1; +} +void Ng_UnSetTerminate(void) +{ + multithread.terminate = 0; +} + +int Ng_ShouldTerminate(void) +{ + return multithread.terminate; +} + +///// Added by Roman Stainko .... +int Ng_GetVertex_Elements( int vnr, int* elems ) +{ + const MeshTopology& topology = mesh->GetTopology(); + ArrayMem indexArray; + topology.GetVertexElements( vnr, indexArray ); + + for( int i=0; iGetTopology(); + ArrayMem indexArray; + topology.GetVertexSurfaceElements( vnr, indexArray ); + + for( int i=0; iGetTopology(); + ArrayMem indexArray; + topology.GetVertexElements( vnr, indexArray ); + + return indexArray.Size(); +} + +///// Added by Roman Stainko .... +int Ng_GetVertex_NSurfaceElements( int vnr ) +{ + const MeshTopology& topology = mesh->GetTopology(); + ArrayMem indexArray; + topology.GetVertexSurfaceElements( vnr, indexArray ); + + return indexArray.Size(); +} + + + +#ifdef SOCKETS +int Ng_SocketClientOpen( const int port, const char * host ) +{ + try + { + if(host) + clientsocket.Reset(new ClientSocket(port,host)); + else + clientsocket.Reset(new ClientSocket(port)); + } + catch( SocketException e) + { + cerr << e.Description() << endl; + return 0; + } + return 1; +} + +void Ng_SocketClientWrite( const char * write, char** reply) +{ + string output = write; + (*clientsocket) << output; + string sreply; + (*clientsocket) >> sreply; + *reply = new char[sreply.size()+1]; + strcpy(*reply,sreply.c_str()); +} + + +void Ng_SocketClientClose ( void ) +{ + clientsocket.Reset(NULL); +} + + +void Ng_SocketClientGetServerHost ( const int number, char ** host ) +{ + *host = new char[servers[number]->host.size()+1]; + strcpy(*host,servers[number]->host.c_str()); +} + +void Ng_SocketClientGetServerPort ( const int number, int * port ) +{ + *port = servers[number]->port; +} + +void Ng_SocketClientGetServerClientID ( const int number, int * id ) +{ + *id = servers[number]->clientid; +} + +#endif // SOCKETS + + + + +#ifdef PARALLEL +void Ng_SetElementPartition ( const int elnr, const int part ) +{ + mesh->VolumeElement(elnr+1).SetPartition(part); + +} +int Ng_GetElementPartition ( const int elnr ) +{ + return mesh->VolumeElement(elnr+1).GetPartition(); +} +#endif + + +void Ng_InitPointCurve(double red, double green, double blue) +{ + mesh->InitPointCurve(red, green, blue); +} + +void Ng_AddPointCurvePoint(const double * point) +{ + Point3d pt; + pt.X() = point[0]; + pt.Y() = point[1]; + pt.Z() = point[2]; + mesh->AddPointCurvePoint(pt); +} + + +void Ng_SaveMesh ( const char * meshfile ) +{ + mesh -> Save(string(meshfile)); +} + + +int Ng_Bisect_WithInfo ( const char * refinementfile, double ** qualityloss, int * qualityloss_size ) +{ + BisectionOptions biopt; + biopt.outfilename = NULL; // "ngfepp.vol"; + biopt.femcode = "fepp"; + biopt.refinementfilename = refinementfile; + + Refinement * ref; + MeshOptimize2d * opt = NULL; + if (stlgeometry) + ref = new RefinementSTLGeometry(*stlgeometry); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif +#ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces(*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } +#endif + else + { + ref = new RefinementSurfaces(*geometry); + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + + if(!mesh->LocalHFunctionGenerated()) + mesh->CalcLocalH(); + + mesh->LocalHFunction().SetGrading (mparam.grading); + + ARRAY * qualityloss_arr = NULL; + if(qualityloss != NULL) + qualityloss_arr = new ARRAY; + + ref -> Bisect (*mesh, biopt, qualityloss_arr); + + int retval = 0; + + if(qualityloss != NULL) + { + *qualityloss = new double[qualityloss_arr->Size()+1]; + + for(int i = 0; iSize(); i++) + (*qualityloss)[i+1] = (*qualityloss_arr)[i]; + + retval = qualityloss_arr->Size(); + + delete qualityloss_arr; + } + + mesh -> UpdateTopology(); + mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + + multithread.running = 0; + delete ref; + delete opt; + + return retval; +} + +void Ng_Bisect ( const char * refinementfile ) +{ + Ng_Bisect_WithInfo( refinementfile, NULL, NULL ); +} + + + + + +/* + number of nodes of type nt + nt = 0 is Vertex + nt = 1 is Edge + nt = 2 is Face + nt = 3 is Cell +*/ +int Ng_GetNNodes (int nt) +{ + switch (nt) + { + case 0: return mesh -> GetNV(); + case 1: return mesh->GetTopology().GetNEdges(); + case 2: return mesh->GetTopology().GetNFaces(); + case 3: return mesh -> GetNE(); + } + return -1; +} + + +int Ng_GetClosureNodes (int nt, int nodenr, int nodeset, int * nodes) +{ + switch (nt) + { + case 3: // The closure of a cell + { + int cnt = 0; + if (nodeset & 1) // Vertices + { + const Element & el = (*mesh)[ElementIndex(nodenr)]; + for (int i = 0; i < el.GetNP(); i++) + { + nodes[cnt++] = 0; + nodes[cnt++] = el[i] - PointIndex::BASE; + } + } + + if (nodeset & 2) // Edges + { + int edges[12]; + int ned; + ned = mesh->GetTopology().GetElementEdges (nodenr+1, edges, 0); + for (int i = 0; i < ned; i++) + { + nodes[cnt++] = 1; + nodes[cnt++] = edges[i]-1; + } + } + + if (nodeset & 4) // Faces + { + int faces[12]; + int nfa; + nfa = mesh->GetTopology().GetElementFaces (nodenr+1, faces, 0); + for (int i = 0; i < nfa; i++) + { + nodes[cnt++] = 2; + nodes[cnt++] = faces[i]-1; + } + } + + if (nodeset & 8) // Cell + { + nodes[cnt++] = 3; + nodes[cnt++] = nodenr; + } + + return cnt/2; + } + default: + { + cerr << "GetClosureNodes not implemented for Nodetype " << nt << endl; + } + } + return 0; +} + + + +int Ng_GetNElements (int dim) +{ + switch (dim) + { + case 0: return mesh -> GetNV(); + case 1: return mesh -> GetNSeg(); + case 2: return mesh -> GetNSE(); + case 3: return mesh -> GetNE(); + } + return -1; +} + + + + /* + closure nodes of element + nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc + E.g., nodeset = 6 includes edge and face nodes + nodes is pair of integers (nodetype, nodenr) + return value is number of nodes + */ +int Ng_GetElementClosureNodes (int dim, int elementnr, int nodeset, int * nodes) +{ + switch (dim) + { + case 3: // The closure of a volume element = CELL + { + return Ng_GetClosureNodes (3, elementnr, nodeset, nodes); + } + case 2: + { + int cnt = 0; + if (nodeset & 1) // Vertices + { + const Element2d & el = (*mesh)[SurfaceElementIndex(elementnr)]; + for (int i = 0; i < el.GetNP(); i++) + { + nodes[cnt++] = 0; + nodes[cnt++] = el[i] - PointIndex::BASE; + } + } + + if (nodeset & 2) // Edges + { + int edges[12]; + int ned; + ned = mesh->GetTopology().GetSurfaceElementEdges (elementnr+1, edges, 0); + for (int i = 0; i < ned; i++) + { + nodes[cnt++] = 1; + nodes[cnt++] = edges[i]-1; + } + } + + if (nodeset & 4) // Faces + { + int face = mesh->GetTopology().GetSurfaceElementFace (elementnr+1); + nodes[cnt++] = 2; + nodes[cnt++] = face-1; + } + + return cnt/2; + } + default: + { + cerr << "GetClosureNodes not implemented for Element of dimension " << dim << endl; + } + } + return 0; +} diff --git a/libsrc/interface/nginterface.h b/libsrc/interface/nginterface.h new file mode 100644 index 00000000..b0c4c2ba --- /dev/null +++ b/libsrc/interface/nginterface.h @@ -0,0 +1,434 @@ +#ifndef NGINTERFACE +#define NGINTERFACE + + +/**************************************************************************/ +/* File: nginterface.h */ +/* 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 (const char * filename); + + // load netgen mesh + void Ng_LoadMesh (const char * filename); + + // load netgen mesh + void Ng_LoadMeshFromString (const char * mesh_as_string); + + // 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); + + void Ng_SetElementIndex(const int ei, const int index); + + // Get Material of element ei + char * Ng_GetElementMaterial (int ei); + + // Get Material of domain dom + char * Ng_GetDomainMaterial (int dom); + + // Get User Data + int Ng_GetUserDataSize (char * id); + void Ng_GetUserData (char * id, double * data); + + // Get Surface Element Points + NG_ELEMENT_TYPE Ng_GetSurfaceElement (int ei, int * epi, int * np = 0); + + // Get Surface Element Type + NG_ELEMENT_TYPE Ng_GetSurfaceElementType (int ei); + + // Get Surface Element Index + int Ng_GetSurfaceElementIndex (int ei); + + // Get Surface Element Surface Number + int Ng_GetSurfaceElementSurfaceNumber (int ei); + + // Get Surface Element Number + int Ng_GetSurfaceElementFDNumber (int ei); + + // Get BCName for Surface Element + char * Ng_GetSurfaceElementBCName (int ei); + //void Ng_GetSurfaceElementBCName (int ei, char * name); + + // Get BCName for bc-number + char * Ng_GetBCNumBCName (int bcnr); + //void Ng_GetBCNumBCName (int bcnr, char * name); + + // Get normal vector of surface element node + void Ng_GetNormalVector (int sei, int locpi, double * nv); + + + void Ng_SetPointSearchStartElement(int el); + + // Find element of point, returns local coordinates + int Ng_FindElementOfPoint (double * p, double * lami, + int build_searchtrees = 0, + const int * const indices = NULL, const int numind = 0); + + // Find surface element of point, returns local coordinates + int Ng_FindSurfaceElementOfPoint (double * p, double * lami, + int build_searchtrees = 0, + const int * const indices = NULL, const int numind = 0); + + + // is elment ei curved ? + int Ng_IsElementCurved (int ei); + // is elment sei curved ? + int Ng_IsSurfaceElementCurved (int sei); + + /// 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); + + + /// buffer must be at least 100 doubles, alignment of double + void Ng_GetBufferedElementTransformation (int ei, const double * xi, + double * x, double * dxdxi, + void * buffer, int buffervalid); + + + + /// Curved Elemens: + /// xi..local coordinates + /// x ..global coordinates + /// dxdxi...D x D-1 Jacobian matrix (row major storage) + /// curved ...is element curved ? + void Ng_GetSurfaceElementTransformation (int sei, const double * xi, + double * x, double * dxdxi); + + /// Curved Elemens: + /// xi..local coordinates + /// sxi..step xi + /// x ..global coordinates + /// dxdxi...D x D Jacobian matrix (row major storage) + void Ng_GetMultiElementTransformation (int ei, int n, + const double * xi, int sxi, + double * x, int sx, + double * dxdxi, int sdxdxi); + + + + int Ng_GetSegmentIndex (int elnr); + NG_ELEMENT_TYPE Ng_GetSegment (int elnr, int * epi, int * np = 0); + + + + + // 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, bool rational = false); + //void Ng_HPRefinement (int levels, double parameter = 0.125); + void Ng_HPRefinement (int levels, double parameter = 0.125, + bool setorders = true,bool ref_level = false); + // void Ng_HPRefinement (int levels); + // void Ng_HPRefinement (int levels, double parameter); + + + // 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); + void Ng_GetElementOrders (int enr, int * ox, int * oy, int * oz); + + void Ng_SetElementOrder (int enr, int order); + void Ng_SetElementOrders (int enr, int ox, int oy, int oz); + + int Ng_GetSurfaceElementOrder (int enr); + void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy); + + void Ng_SetSurfaceElementOrder (int enr, int order); + void Ng_SetSurfaceElementOrders (int enr, int ox, int oy); + + // Multilevel functions: + + // number of levels: + int Ng_GetNLevels (); + // get two parent nodes (indeed vertices !) 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); + +#ifdef PARALLEL + // Is Element ei an element of this processor ?? + bool Ng_IsGhostEl (int ei); + + void Ng_SetGhostEl(const int ei, const bool aisghost ); + + bool Ng_IsGhostSEl (int ei); + + void Ng_SetGhostSEl(const int ei, const bool aisghost ); + + bool Ng_IsGhostVert ( int pnum ); + bool Ng_IsGhostEdge ( int ednum ); + bool Ng_IsGhostFace ( int fanum ); + + bool Ng_IsExchangeEl ( int elnum ); + bool Ng_IsExchangeSEl ( int selnr ); + + void Ng_UpdateOverlap (); + int Ng_Overlap(); +/* void Ng_SetGhostVert ( const int pnum, const bool aisghost ); */ +/* void Ng_SetGhostEdge ( const int ednum, const bool aisghost ); */ +/* void Ng_SetGhostFace ( const int fanum, const bool aisghost ); */ + +#endif + +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 + { + const 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 (int idnr); + // pairs should be an integer array of 2*npairs + void Ng_GetPeriodicVertices (int idnr, int * pairs); + + // number of periodic edges + int Ng_GetNPeriodicEdges (int idnr); + // pairs should be an integer array of 2*npairs + void Ng_GetPeriodicEdges (int idnr, int * pairs); + + + void Ng_PushStatus (const char * str); + void Ng_PopStatus (); + void Ng_SetThreadPercentage (double percent); + void Ng_GetStatus (char ** str, double & percent); + + void Ng_SetTerminate(void); + void Ng_UnSetTerminate(void); + int Ng_ShouldTerminate(void); + + + //// 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 SOCKETS + int Ng_SocketClientOpen( const int port, const char * host ); + void Ng_SocketClientWrite( const char * write, char ** reply); + void Ng_SocketClientClose ( void ); + void Ng_SocketClientGetServerHost ( const int number, char ** host ); + void Ng_SocketClientGetServerPort ( const int number, int * port ); + void Ng_SocketClientGetServerClientID ( const int number, int * id ); +#endif + + void Ng_InitPointCurve(double red, double green, double blue); + void Ng_AddPointCurvePoint(const double * point); + + +#ifdef PARALLEL + void Ng_SetElementPartition ( int elnr, int part ); + int Ng_GetElementPartition ( int elnr ); +#endif + + void Ng_SaveMesh ( const char * meshfile ); + void Ng_Bisect ( const char * refinementfile ); + + // if qualityloss is not equal to NULL at input, a (1-based) list of qualitylosses (due to projection) + // is saved in *qualityloss, its size is the return value + int Ng_Bisect_WithInfo ( const char * refinementfile, double ** qualityloss); +#ifdef __cplusplus +} +#endif + +#endif + + + + + + +/* + The new node interface ... + it is 0-based ! + */ + +extern "C" { + + /* + number of nodes of type nt + nt = 0 is Vertex + nt = 1 is Edge + nt = 2 is Face + nt = 3 is Cell + */ + int Ng_GetNNodes (int nt); + + /* + closure nodes of node (nt, nodenr): + nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc + E.g., nodeset = 6 includes edge and face nodes + nodes consists of pairs of integers (nodetype, nodenr) + return value is number of nodes + */ + int Ng_GetClosureNodes (int nt, int nodenr, int nodeset, int * nodes); + + + /* + number of dim-dimensional elements + dim = 3 ... volume elements + dim = 2 ... surface elements + dim = 1 ... segments + dim = 0 ... not available + */ + int Ng_GetNElements (int dim); + + /* + closure nodes of dim-dimensional element elmentnr: + nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc + E.g., nodeset = 6 includes edge and face nodes + nodes consists of pairs of integers (nodetype, nodenr) + return value is number of nodes + */ + int Ng_GetElementClosureNodes (int dim, int elementnr, int nodeset, int * nodes); + +} diff --git a/libsrc/interface/printdest.cpp b/libsrc/interface/printdest.cpp new file mode 100644 index 00000000..0db654d9 --- /dev/null +++ b/libsrc/interface/printdest.cpp @@ -0,0 +1,11 @@ +#include +#include + +namespace netgen +{ + //Destination for messages, errors, ... + void Ng_PrintDest(const char * s) + { + (*mycout) << s << flush; + } +} diff --git a/libsrc/interface/read_fnf_mesh.cpp b/libsrc/interface/read_fnf_mesh.cpp new file mode 100644 index 00000000..0f962607 --- /dev/null +++ b/libsrc/interface/read_fnf_mesh.cpp @@ -0,0 +1,446 @@ + +// +// Read Pro/ENGINEER neutral format +// + +#include + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + bool ReadLine (istream & in, string & buf) + { + do + { + buf = ""; + + while (in.good()) + { + char ch = in.get(); + if (ch == '\n') break; + if (ch == '\r') break; + if (ch == '\\') + { + // while (iswhite (ch = in.get() ) + ch = in.get(); // '\n' CR + ch = in.get(); // '\n' LF + } + else + buf += ch; + } + } + while (in.good() && (buf == "" || buf[0] == '#')); + + return in.good(); + } + + + + + + class LoadType + { + public: + int id; + string name; + string placement; + string valuetype; + ARRAY places; + }; + + + + + void ReadFNFFormat (Mesh & mesh, + const string & filename) + { + ifstream fin (filename.c_str()); + + string buf; + + mesh.SetDimension (3); + + while (ReadLine (fin, buf)) + { + stringstream sbuf(buf); + string start_sect, token; char ch; + + sbuf >> start_sect; + + if (start_sect == "%START_SECT") + { + sbuf >> ch >> token; + + if (token == "HEADER") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%TITLE") + { + char ch; + string name; + sbuf >> ch >> name; + cout << "Title: " << name << endl; + } + else if (token == "%STATISTICS") + { + ; + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION HEADER, unknown field: " << buf << endl; + } + } + } + + + else if (token == "ELEM_TYPES") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%ELEM_TYPE") + { + int nr; + string def; + char ch; + sbuf >> nr >> def >> ch; + if (def == "DEF") + { + string classname, type; + sbuf >> classname >> type; + if (classname != "SOLID" || type != "TETRA") + cerr << "Element not supported: " << buf << endl; + } + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION ELEM_TYPE, unknown field: " << buf << endl; + } + } + } + + + else if (token == "COORD_SYSTEMS") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%END_SECT") + { + break; + } + else + { + // cout << "COORD_SYSTEMS, unknown field: " << buf << endl; + } + } + } + + + + else if (token == "MATERIALS") + { + ARRAY young_modulus, poisson_ratio, mass_density; + + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%MATERIAL") + { + int nr; + string prop; + char ch; + double val; + + sbuf >> nr >> prop >> ch; + if (prop == "DEF") + { + ; + } + else + { + sbuf >> val; + if (prop == "YOUNG_MODULUS") + young_modulus.Append (val); + else if (prop == "POISSON_RATIO") + poisson_ratio.Append (val); + else if (prop == "MASS_DENSITY") + mass_density.Append (val); + } + } + else if (token == "%END_SECT") + { + mesh.SetUserData ("YOUNG_MODULUS", young_modulus); + mesh.SetUserData ("POISSON_RATIO", poisson_ratio); + mesh.SetUserData ("MASS_DENSITY", mass_density); + break; + } + else + { + cout << "SECTION MATERIALS, unknown field: " << buf << endl; + } + } + } + + + else if (token == "MESH") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + sbuf >> token; + if (token == "%NODE") + { + string st; + char ch; + int nr, ks_id; + double x,y,z; + sbuf >> nr >> st >> ch >> x >> y >> z >> ks_id; + mesh.AddPoint (Point3d (x,y,z) ); + } + else if (token == "%ELEM") + { + string elemid, def; + char ch; + int elnr, typid, matid; + string propid; + sbuf >> elnr >> def >> ch; + sbuf >> typid >> matid >> propid; + ARRAY pnums; + while (1) + { + int pn; + sbuf >> pn; + if (!sbuf.good()) break; + pnums.Append (pn); + } + int pe2ng [] = { 0, 1, 2, 3, 4, 7, 5, 6, 8, 9 }; + Element el(pnums.Size()); + for (int j = 0; j < pnums.Size(); j++) + el[pe2ng[j]] = pnums[j]; + el.SetIndex (matid); + mesh.AddVolumeElement (el); + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION MESH, unknown: " << buf << endl; + } + } + } + else if (token == "MESH_TOPOLOGY") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token, kw; + int nr; + char ch; + + sbuf >> token; + if (token == "%EDGE") + { + sbuf >> nr >> kw >> ch; + if (kw == "NODES") + { + ARRAY enums; + while (1) + { + int en; + sbuf >> en; + if (!sbuf.good()) break; + enums.Append (en); + } + for (int j = 0; j+2 < enums.Size(); j+=2) + { + Segment seg; + seg.p1 = enums[j]; + seg.p2 = enums[j+2]; + seg.pmid = enums[j+1]; + seg.edgenr = nr; + mesh.AddSegment (seg); + } + } + } + else if (token == "%SURFACE") + { + sbuf >> nr >> kw >> ch; + if (kw == "FACES") + { + ARRAY fnums; + while (1) + { + int fn; + sbuf >> fn; + if (!sbuf.good()) break; + fnums.Append (fn); + } + + FaceDescriptor fd(-1, -1, -1, -1); + fd.SetBCProperty (nr); + mesh.AddFaceDescriptor (fd); + + for (int j = 0; j < fnums.Size(); j += 2) + { + int elnr = fnums[j]; + int fnr = fnums[j+1]; + + const Element & el = mesh.VolumeElement (elnr); + Element2d el2d; + el.GetFace (fnr, el2d); + el2d.SetIndex (nr); + + mesh.AddSurfaceElement (el2d); + } + } + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION MESH, unknown: " << buf << endl; + } + } + } + + + + + else if (token == "LOADS") + { + ARRAY loadtypes; + + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%LOAD_TYPE") + { + string def; + char ch; + + LoadType * lt = new LoadType; + sbuf >> lt->id >> def >> ch >> lt->name >> lt->placement >> lt->valuetype; + + if (lt->name == "DISPLACEMENT") + cout << "loadtype DISPLACEMENT found" << endl; + + if (lt->placement != "FACE" && lt->placement != "EDGE" && lt->placement != "NODE") + cout << "unsupported placement " << lt->placement << endl; + + loadtypes.Append (lt); + } + + else if (token == "%LOAD") + { + int id; + string def; + char ch; + int placement; + int load_type_id, con_case_id; + sbuf >> id >> def >> ch; + + if (def == "DEF") + { + sbuf >> load_type_id >> con_case_id; + } + if (def == "VAL") + { + sbuf >> placement; + for (int i = 0; i < loadtypes.Size(); i++) + if (load_type_id == loadtypes[i]->id) + loadtypes[i]->places.Append (placement); + } + } + + else if (token == "%END_SECT") + { + for (int i = 0; i < loadtypes.Size(); i++) + { + if (loadtypes[i]->placement == "FACE" && loadtypes[i]->name == "DISPLACEMENT") + { + mesh.SetUserData ("CONSTRAINT_DISP_FACE", loadtypes[i]->places); + cout << "constrained faces: " << loadtypes[i]->places << endl; + } + if (loadtypes[i]->placement == "EDGE" && loadtypes[i]->name == "DISPLACEMENT") + { + mesh.SetUserData ("CONSTRAINT_DISP_EDGE", loadtypes[i]->places); + cout << "constrained edges: " << loadtypes[i]->places << endl; + } + if (loadtypes[i]->placement == "NODE" && loadtypes[i]->name == "DISPLACEMENT") + { + mesh.SetUserData ("CONSTRAINT_DISP_NODE", loadtypes[i]->places); + cout << "constrained nodes: " << loadtypes[i]->places << endl; + } + } + break; + } + else + { + cout << "SECTION LOADS, unknown field: " << buf << endl; + } + } + } + + + + else + { + cout << "unknown section " << token << endl; + } + } + else + cout << "parse line: (" << buf << ")" << endl; + } + } +} diff --git a/libsrc/interface/readtetmesh.cpp b/libsrc/interface/readtetmesh.cpp new file mode 100644 index 00000000..4a81e5e7 --- /dev/null +++ b/libsrc/interface/readtetmesh.cpp @@ -0,0 +1,797 @@ + +// +// Read CST file format +// + +#include + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + + + + void ReadTETFormat (Mesh & mesh, + const string & hfilename) + { + const char * filename = hfilename.c_str(); + + cout << "Reading .tet mesh" << endl; + + ifstream in (filename); + + int inputsection = 0; + bool done = false; + + char ch; + string str; + + string version; + + int unitcode; + double tolerance; + double dS1, dS2, alphaDeg, x3D, y3D, z3D; + int nelts,nfaces,nedges,nnodes; + int nperiodicmasternodes,ncornerperiodicmasternodes,ncubicperiodicmasternodes; + int nperiodicmasteredges,ncornerperiodicmasteredges; + int nperiodicmasterfaces; + int nodeid,type,pid; + int dummyint; + int modelverts,modeledges,modelfaces,modelcells; + Point3d p; + int numObj3D,numObj2D,numObj1D,numObj0D; + bool nullstarted; + ARRAY eldom; + int minId3D,minId2D; + int maxId3D(-1), maxId2D(-1), maxId1D(-1), maxId0D(-1); + ARRAY *> segmentdata; + ARRAY tris; + + ARRAY userdata_int; // just save data for 1:1 output + ARRAY userdata_double; + ARRAY point_pids; + ARRAY tetfacedata; + ARRAY uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D; + + while(!done) + { + // skip "//" comment + bool comment = true; + while(comment) + { + ch = in.get(); + while(ch == ' ' || ch == '\n' || ch == '\t' || ch =='\r') + ch = in.get(); + + if(ch != '/') + { + comment = false; + in.putback(ch); + } + else + { + ch = in.get(); + if(ch != '/') + { + comment = false; + in.putback(ch); + in.putback('/'); + } + else + { + in.ignore(10000,'\n'); + } + } + } + + + switch(inputsection) + { + case 0: + // version number + in >> version; + cout << "Version number " << version << endl; + if(version != "1.1" && version != "2" && version != "2.0") + { + cerr << "WARNING: import only tested for versions 1.1 and 2" << endl; + //done = true; + } + userdata_double.Append(atof(version.c_str())); + break; + + case 1: + // unit code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL) + in >> unitcode; + cout << "unit code " << unitcode << endl; + userdata_int.Append(unitcode); + break; + + case 2: + // Geometric coord "zero" tolerance threshold + in >> tolerance; + cout << "tolerance " << tolerance << endl; + userdata_double.Append(tolerance); + break; + + case 3: + // Periodic UnitCell dS1 , dS2 , alphaDeg + in >> dS1 >> dS2 >> alphaDeg; + userdata_double.Append(dS1); + userdata_double.Append(dS2); + userdata_double.Append(alphaDeg); + break; + + case 4: + // Periodic UnitCell origin in global coords (x3D,y3D,z3D) + in >> x3D >> y3D >> z3D; + userdata_double.Append(x3D); + userdata_double.Append(y3D); + userdata_double.Append(z3D); + break; + + case 5: + // Model entity count: Vertices, Edges, Faces, Cells (Version 2) + in >> modelverts >> modeledges >> modelfaces >> modelcells; + userdata_int.Append(modelverts); + userdata_int.Append(modeledges); + userdata_int.Append(modelfaces); + userdata_int.Append(modelcells); + break; + + case 6: + // Topological mesh-entity counts (#elements,#faces,#edges,#nodes) + in >> nelts >> nfaces >> nedges >> nnodes; + cout << nelts << " elements, " << nfaces << " faces, " << nedges << " edges, " << nnodes << " nodes" << endl; + mesh.SetAllocSize(nnodes,2*nedges,nfaces,nelts); + break; + + case 7: + // NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), PID: + { + cout << "read nodes" << endl; + for(int i=0; i> nodeid >> p.X() >> p.Y() >> p.Z() >> type >> pid; + mesh.AddPoint(p); + point_pids.Append(pid); + if(pid > maxId0D) + maxId0D = pid; + //(*testout) << "point " << p << " type " << type << " mastersexist " << mastersexist << endl; + } + } + break; + + case 8: + // Number of Periodic Master Nodes + in >> nperiodicmasternodes; + break; + + case 9: + // MasterNodeID, SlaveNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint; + + in >> dummyint; + } + break; + + case 10: + // Number of Corner Periodic Master Nodes + in >> ncornerperiodicmasternodes; + break; + + case 11: + // MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint; + + for(int j=0; j<3; j++) + in >> dummyint; + } + break; + + case 12: + // Number of Cubic Periodic Master Nodes + in >> ncubicperiodicmasternodes; + break; + + case 13: + //MasterNodeID, 7-SlaveNodeID's, TranslCodes + for(int i=0; i> dummyint; + + for(int j=0; j<7; j++) + in >> dummyint; + } + break; + + case 14: + // EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), PID + cout << "read edges" << endl; + nullstarted = false; + segmentdata.SetSize(nedges); + for(int i=0; i(7); + *segmentdata[i] = -1; + in >> dummyint; + in >> (*segmentdata[i])[0] >> (*segmentdata[i])[1]; + in >> type; + in >> (*segmentdata[i])[2]; + if((*segmentdata[i])[2] > maxId1D) + maxId1D = (*segmentdata[i])[2]; + } + break; + + case 15: + // Number of Periodic Master Edges + in >> nperiodicmasteredges; + break; + + case 16: + // MasterEdgeID, SlaveEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint >> dummyint >> dummyint; + break; + + case 17: + // Number of Corner Periodic Master Edges + in >> ncornerperiodicmasteredges; + break; + + case 18: + // MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint; + for(int j=0; j<3; j++) + in >> dummyint; + for(int j=0; j<3; j++) + in >> dummyint; + } + break; + + case 19: + // FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), PID + { + //Segment seg; + int segnum_ng[3]; + bool neg[3]; + cout << "read faces" << endl; + nullstarted = false; + for(int i=0; i> trinum; + for(int j=0; j<3; j++) + { + in >> segnum; + neg[j] = (segnum<0); + if(!neg[j]) + segnum_ng[j] = segnum-1; + else + segnum_ng[j] = -segnum-1; + + if(neg[j]) + tris.Last()->PNum(j+1) = (*segmentdata[segnum_ng[j]])[1]; + else + tris.Last()->PNum(j+1) = (*segmentdata[segnum_ng[j]])[0]; + + tris.Last()->GeomInfoPi(j+1).trignum = trinum; + } + in >> type; + int faceid; + in >> faceid; + + if(faceid > maxId2D) + maxId2D = faceid; + + if(i==0 || faceid < minId2D) + minId2D = faceid; + + tris.Last()->SetIndex(faceid); + + if(faceid > 0) + { + //if(nullstarted) + // { + // cout << "Faces: Assumption about index 0 wrong (face"<> nperiodicmasterfaces; + break; + + case 21: + // MasterFaceID, SlaveFaceID, TranslCode (1=dS1 2=dS2) + { + Vec<3> randomvec(-1.32834,3.82399,0.5429151); + int maxtransl = -1; + for(int i=0; i nodes1(3),nodes2(3); + ARRAY sortval1(3),sortval2(3); + in >> tri1 >> tri2 >> transl; + + if(transl > maxtransl) + maxtransl = transl; + + + for(int j=0; j<3; j++) + { + nodes1[j] = tris[tri1-1]->PNum(j+1); + sortval1[j] = Vec<3>(mesh[nodes1[j]])*randomvec; + nodes2[j] = tris[tri2-1]->PNum(j+1); + sortval2[j] = Vec<3>(mesh[nodes2[j]])*randomvec; + } + + BubbleSort(sortval1,nodes1); + BubbleSort(sortval2,nodes2); + + for(int j=0; j<3; j++) + mesh.GetIdentifications().Add(nodes1[j],nodes2[j],transl); + + } + for(int i=1; i<= maxtransl; i++) + mesh.GetIdentifications().SetType(i,Identifications::PERIODIC); + } + break; + + case 22: + // ElemID, FaceID0, FaceID1, FaceID2, FaceID3, PID + { + cout << "read elements (1)" << endl; + + //SurfaceElementIndex surf[4]; + bool neg[4]; + int elemid; + int domain; + + eldom.SetSize(nelts); + + for(int i=0; i> elemid; + for(int j=0; j<4;j++) + { + in >> dummyint; + neg[j] = (dummyint < 0); + if(neg[j]) + tetfacedata.Append(-dummyint-1); + //surf[j] = -dummyint-1; + else + tetfacedata.Append(dummyint-1); + tetfacedata.Append(((neg[j]) ? 1 : 0)); + //surf[j] = dummyint-1; + } + + in >> domain; + eldom[i] = domain; + tetfacedata.Append(domain); + + if(i==0 || domain < minId3D) + minId3D = domain; + + if(domain > maxId3D) + maxId3D = domain; + + // for(int j=0; j<4; j++) + // { + // if(mesh.GetNSE() <= surf[j]) + // continue; + + // int faceind = 0; + // for(int k=1; k<=mesh.GetNFD(); k++) + // { + // if(mesh.GetFaceDescriptor(k).SurfNr() == mesh[surf[j]].GetIndex()) + // faceind = k; + // } + // if(faceind) + // { + // if(neg[j]) + // mesh.GetFaceDescriptor(faceind).SetDomainOut(domain); + // else + // mesh.GetFaceDescriptor(faceind).SetDomainIn(domain); + // } + // else + // { + // if(neg[j]) + // faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf[j]].GetIndex(),0,domain,0)); + // else + // faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf[j]].GetIndex(),domain,0,0)); + // mesh.GetFaceDescriptor(faceind).SetBCProperty(mesh[surf[j]].GetIndex()); + // } + // } + } + cout << endl; + + + // ARRAY indextodescriptor(maxId2D+1); + + // for(int i=1; i<=mesh.GetNFD(); i++) + // indextodescriptor[mesh.GetFaceDescriptor(i).SurfNr()] = i; + + + // for(SurfaceElementIndex i=0; i> dummyint; + for(int j=1; j<=4; j++) + in >> el.PNum(j); + swap(el.PNum(1),el.PNum(2)); + + el.SetIndex(eldom[i]); + mesh.AddVolumeElement(el); + } + } + break; + + case 24: + // Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D) + { + in >> numObj3D; + userdata_int.Append(numObj3D); + in >> numObj2D; + userdata_int.Append(numObj2D); + in >> numObj1D; + userdata_int.Append(numObj1D); + in >> numObj0D; + userdata_int.Append(numObj0D); + } + break; + + case 25: + // Number of Ports (Ports are a subset of Object2D list) + { + in >> dummyint; + //userdata_int.Append(dummyint); + } + break; + + case 26: + // Object3D GroupID, #Elems ElemID List + { + uid_to_group_3D.SetSize(maxId3D+1); + uid_to_group_3D = -1; + for(int i=0; i> groupid; + (*testout) << "3d groupid " << groupid << endl; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + + (*testout) << "read " << dummyint << endl; + //userdata_int.Append(dummyint); + + if(dummyint < 0) + dummyint *= -1; + uid_to_group_3D[eldom[dummyint-1]] = groupid; + } + } + } + break; + + case 27: + // Object2D GroupID, #Faces FaceID List + { + ARRAY ports; + //int totnum = 0; + uid_to_group_2D.SetSize(maxId2D+1); + uid_to_group_2D = -1; + + for(int i=0; i> groupid; + (*testout) << "2d groupid " << groupid << endl; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + char port; + while((port = in.get()) == ' ') + ; + + (*testout) << "read " << dummyint << endl; + if(dummyint < 0) + dummyint *= -1; + int uid = tris[dummyint-1]->GetIndex(); + + if(port == 'P' || port == 'p') + { + if(!ports.Contains(uid)) + ports.Append(uid); + } + else + in.putback(port); + + //userdata_int.Append(dummyint); + + uid_to_group_2D[uid] = groupid; + (*testout) << "setting " << uid << endl; + + //totnum++; + } + } + mesh.SetUserData("TETmesh:ports",ports); + } + break; + + case 28: + // Object1D GroupID, #Edges EdgeID List + { + uid_to_group_1D.SetSize(maxId1D+1); + uid_to_group_1D = -1; + + for(int i=0; i> groupid; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + //userdata_int.Append(dummyint); + + if(dummyint < 0) + dummyint *= -1; + uid_to_group_1D[(*segmentdata[dummyint-1])[2]] = groupid; + } + } + } + break; + + case 29: + // Object0D GroupID, #Nodes NodeID List + { + uid_to_group_0D.SetSize(maxId0D+1); + uid_to_group_0D = -1; + for(int i=0; i> groupid; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + //userdata_int.Append(dummyint); + + if(dummyint < 0) + dummyint *= -1; + uid_to_group_0D[point_pids[dummyint-1]] = groupid; + } + } + } + break; + + + + default: + done = true; + + } + + if(inputsection == 4 && version == "1.1") + inputsection++; + + inputsection++; + } + in.close(); + + + mesh.SetUserData("TETmesh:double",userdata_double); + userdata_int.Append(minId2D); + userdata_int.Append(minId3D); + mesh.SetUserData("TETmesh:int",userdata_int); + //if(version == "1.1") + mesh.SetUserData("TETmesh:point_id",point_pids); + + mesh.SetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D); + mesh.SetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D); + mesh.SetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D); + mesh.SetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D); + + + ARRAY surfindices(tris.Size()); + surfindices = -1; + + for(int i=0; iGetIndex() > 0) + surfindices[i] = mesh.AddSurfaceElement(*tris[i]); + } + else + { + if(tris[i]->GetIndex() > 0 && + tris[i]->GetIndex() < minId3D) + { + tris[i]->SetIndex(tris[i]->GetIndex()-minId2D+1); + surfindices[i] = mesh.AddSurfaceElement(*tris[i]); + } + } + delete tris[i]; + } + + + mesh.ClearFaceDescriptors(); + if(atof(version.c_str()) <= 1.999999) + for(int i = 1; i <= maxId2D; i++) + mesh.AddFaceDescriptor(FaceDescriptor(i,0,0,0)); + else + for(int i=minId2D; i indextodescriptor(maxId2D+1); + + // for(int i=1; i<=mesh.GetNFD(); i++) + // indextodescriptor[mesh.GetFaceDescriptor(i).SurfNr()] = i; + + + // for(SurfaceElementIndex i=0; i 0) || + (atof(version.c_str()) > 1.999999 && (*segmentdata[i])[2] > 0 && (*segmentdata[i])[2] < minId2D)) + { + seg.p1 = (*segmentdata[i])[0]; + seg.p2 = (*segmentdata[i])[1]; + seg.edgenr = (*segmentdata[i])[2]; + seg.epgeominfo[0].edgenr = (*segmentdata[i])[2]; + seg.epgeominfo[1].edgenr = (*segmentdata[i])[2]; + seg.si = (*segmentdata[i])[3]-minId2D+1; + seg.surfnr1 = -1;//(*segmentdata[i])[3]; + seg.surfnr2 = -1;//(*segmentdata[i])[4]; + seg.geominfo[0].trignum = (*segmentdata[i])[5]; + seg.geominfo[1].trignum = (*segmentdata[i])[5]; + mesh.AddSegment(seg); + + seg.p1 = (*segmentdata[i])[1]; + seg.p2 = (*segmentdata[i])[0]; + seg.si = (*segmentdata[i])[4]-minId2D+1; + seg.surfnr1 = -1;//(*segmentdata[i])[3]; + seg.surfnr2 = -1;//(*segmentdata[i])[4]; + seg.geominfo[0].trignum = (*segmentdata[i])[6]; + seg.geominfo[1].trignum = (*segmentdata[i])[6]; + mesh.AddSegment(seg); + } + delete segmentdata[i]; + } + + /* + for(int i=mesh.GetNSeg(); i>=1; i--) + if(mesh.LineSegment(i).epgeominfo[0].edgenr == 0 || + mesh.LineSegment(i).epgeominfo[1].edgenr == 0) + mesh.FullDeleteSegment(i); + */ + + mesh.CalcSurfacesOfNode(); + + } +} + + diff --git a/libsrc/interface/readuser.cpp b/libsrc/interface/readuser.cpp new file mode 100644 index 00000000..e962e173 --- /dev/null +++ b/libsrc/interface/readuser.cpp @@ -0,0 +1,416 @@ +// +// Read user dependent output file +// + + +#include + + +#include +#include +#include +#include + +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); + } + + mesh.ClearFaceDescriptors(); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + + in >> nbe; + // int invert = globflags.GetDefineFlag ("invertsurfacemesh"); + for (i = 1; i <= nbe; i++) + { + Element2d el; + int hi; + + el.SetIndex(1); + + // in >> hi; + for (j = 1; j <= 3; j++) + { + in >> el.PNum(j); + // 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); + } + + + 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); + + mesh.ClearFaceDescriptors(); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + + + 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; + } + } + } + + + 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); + } + + mesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); + + 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 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)(0) < 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); + } + } + + + // .tet mesh + if ( (strlen (filename) > 4) && + strcmp (&filename[strlen (filename)-4], ".tet") == 0 ) + { + ReadTETFormat (mesh, filename); + } + + + // .fnf mesh (FNF - PE neutral format) + if ( (strlen (filename) > 4) && + strcmp (&filename[strlen (filename)-4], ".fnf") == 0 ) + { + ReadFNFFormat (mesh, filename); + } + + } + +} + diff --git a/libsrc/interface/writeabaqus.cpp b/libsrc/interface/writeabaqus.cpp new file mode 100644 index 00000000..2564da0b --- /dev/null +++ b/libsrc/interface/writeabaqus.cpp @@ -0,0 +1,237 @@ +// +// Write Abaqus file +// +// + +#include + +#include +#include +#include +#include + +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)(0) << ", "; + outfile << mesh.Point(i)(1) << ", "; + outfile << mesh.Point(i)(2) << "\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); + size_t 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(0); + + ARRAY 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 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/libsrc/interface/writediffpack.cpp b/libsrc/interface/writediffpack.cpp new file mode 100644 index 00000000..64970252 --- /dev/null +++ b/libsrc/interface/writediffpack.cpp @@ -0,0 +1,296 @@ +// +// Write diffpack file +// +// by +// Bartosz Sawicki +// extended by +// Jacques Lechelle +// +#include + +#include +#include +#include +#include + + +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 + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + ARRAY BIname; + ARRAY 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[PointIndex(i)].Type() != 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 BIname; + ARRAY 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[PointIndex(i)].Type() != 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/libsrc/interface/writedolfin.cpp b/libsrc/interface/writedolfin.cpp new file mode 100644 index 00000000..0fe36e94 --- /dev/null +++ b/libsrc/interface/writedolfin.cpp @@ -0,0 +1,69 @@ +// +// Write dolfin file +// +// by +// Kent-Andre Mardal + + +#include + +#include +#include +#include +#include + +namespace netgen +{ + +#include "writeuser.hpp" + + + + void WriteDolfinFormat (const Mesh & mesh, const string & filename) + { + cout << "start writing dolfin export" << endl; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int nsd = mesh.GetDimension(); + int invertsurf = mparam.inverttrigs; + int i, j; + + ofstream outfile (filename.c_str()); + + char str[100]; + outfile.precision(8); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + if ( nsd == 3) { + + outfile << "" <"<" <"<"<"<"<"<"<"<"< + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + + +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; + char str[200]; + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + +#ifdef WIN32 + char a[256]; + sprintf( a, "mkdir %s", filename.c_str() ); + system( a ); +#else + int 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 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 << "2" << "\n"; + outfile_h << "303 " << nse << "\n"; + outfile_h << "504 " << ne << "\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/libsrc/interface/writefeap.cpp b/libsrc/interface/writefeap.cpp new file mode 100644 index 00000000..85681aa0 --- /dev/null +++ b/libsrc/interface/writefeap.cpp @@ -0,0 +1,220 @@ +// +// Write FEAP file +// FEAP by Bob Taylor, Berkely +// +// contact Peter Wriggers or Albrecht Rieger, Hannover +// rieger@ibnm.uni-hannover.de +// + +#include + +#include +#include +#include +#include + +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; + + 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)(0)/scale << " "; + outfile.width(10); + outfile << mesh.Point(i)(1)/scale << " "; + outfile.width(10); + outfile << mesh.Point(i)(2)/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/libsrc/interface/writefluent.cpp b/libsrc/interface/writefluent.cpp new file mode 100644 index 00000000..5c08d598 --- /dev/null +++ b/libsrc/interface/writefluent.cpp @@ -0,0 +1,193 @@ +// +// Write Fluent file +// Johannes Gerstmayr, University Linz +// + +#include + +#include +#include +#include +#include + +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 surfaceelp; + ARRAY surfaceeli; + ARRAY 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).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/libsrc/interface/writegmsh.cpp b/libsrc/interface/writegmsh.cpp new file mode 100644 index 00000000..93def677 --- /dev/null +++ b/libsrc/interface/writegmsh.cpp @@ -0,0 +1,200 @@ +/************************************* + * 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 + +#include +#include +#include +#include + +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/libsrc/interface/writejcm.cpp b/libsrc/interface/writejcm.cpp new file mode 100644 index 00000000..00ef4f9f --- /dev/null +++ b/libsrc/interface/writejcm.cpp @@ -0,0 +1,430 @@ +// +// Write JCMwave file +// 07.07.2005, Sven Burger, ZIB Berlin +// + + +#include +#include +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + +void WriteJCMFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + if (mesh.GetDimension() != 3) + { + cout <<"\n Error: Dimension 3 only supported by this output format!"< identmap1, identmap2, identmap3; + mesh.GetIdentifications().GetMap(1, identmap1); + mesh.GetIdentifications().GetMap(2, identmap2); + mesh.GetIdentifications().GetMap(3, identmap3); + + // number of volume elements + int ne = mesh.GetNE(); + int ntets = 0; + int nprisms = 0; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (el.GetNP() == 4) + { + ntets++; + // Check that no two points on a tetrahedron are identified with each other + for (j = 1; j <= 4; j++) + for (jj = 1; jj <=4; jj++) + { + if (identmap1.Elem(el.PNum(j)) == el.PNum(jj)) + { + cout << "\n Error: two points on a tetrahedron identified (1) with each other" + << "\n REFINE MESH !" << endl; + return; + } + if (identmap2.Elem(el.PNum(j)) == el.PNum(jj)) + { + cout << "\n Error: two points on a tetrahedron identified (2) with each other" + << "\n REFINE MESH !" << endl; + return; + } + if (identmap3.Elem(el.PNum(j)) == el.PNum(jj)) + { + cout << "\n Error: two points on a tetrahedron identified (3) with each other" + << "\n REFINE MESH !" << endl; + return; + } + } + + } + else if (el.GetNP() == 6) + nprisms++; + } + if ( ne != (ntets+nprisms)) + { + cout<< "\n Error in determining number of volume elements!\n" + << "\n Prisms and tetrahedra only implemented in the JCMwave format!\n"< 0) + cout << " Please note: Boundaries at infinity have to carry the bc-attribute '-bc=" + << bc_at_infinity <<"'."< pointsOnTetras; + pointsOnTetras.SetSize (mesh.GetNP()); + pointsOnTetras = 0; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (el.GetNP() == 4) + { + for (j = 1; j <= 4; j++) + pointsOnTetras.Set(el.PNum(j).GetInt(),1); + } + } + + // number of boundary triangles and boundary quadrilaterals + for (i = 1; i <= nse; i++) + { + Element2d el = mesh.SurfaceElement(i); + if (el.GetNP() == 3 && + ( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 || + mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) ) + nbtri++; + else if (el.GetNP() == 4 && + ( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 || + mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) ) + nbquad++; + } + + ofstream outfile (filename.c_str()); + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + outfile << "/* \n"; + outfile << "__BLOBTYPE__=Grid\n"; + outfile << "__OWNER__=JCMwave\n"; + outfile << "SpaceDim=3\n"; + outfile << "ManifoldDim=3\n"; + outfile << "NRefinementSteps=0\n"; + outfile << "NPoints="<NTetrahedra="<NPrisms="<NBoundaryTriangles="<NBoundaryQuadrilaterals="< & p = mesh.Point(i); + outfile << i << "\n"; + outfile << p(0) << "e-6\n"; + outfile << p(1) << "e-6\n"; + outfile << p(2) << "e-6\n\n"; + } + + outfile << "\n"; + outfile << "# Tetrahedra\n"; + counter = 0; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (el.GetNP() == 4) + { + counter++; + dx1 = mesh.Point(el.PNum(2))(0) - mesh.Point(el.PNum(1))(0); + dx2 = mesh.Point(el.PNum(3))(0) - mesh.Point(el.PNum(1))(0); + dx3 = mesh.Point(el.PNum(4))(0) - mesh.Point(el.PNum(1))(0); + dy1 = mesh.Point(el.PNum(2))(1) - mesh.Point(el.PNum(1))(1); + dy2 = mesh.Point(el.PNum(3))(1) - mesh.Point(el.PNum(1))(1); + dy3 = mesh.Point(el.PNum(4))(1) - mesh.Point(el.PNum(1))(1); + dz1 = mesh.Point(el.PNum(2))(2) - mesh.Point(el.PNum(1))(2); + dz2 = mesh.Point(el.PNum(3))(2) - mesh.Point(el.PNum(1))(2); + dz3 = mesh.Point(el.PNum(4))(2) - mesh.Point(el.PNum(1))(2); + vol = (dy1*dz2-dz1*dy2)*dx3 + (dz1*dx2-dx1*dz2)*dy3 + (dx1*dy2-dy1*dx2)*dz3; + + if ( vol > 0 ) + for (j = 1; j <= 4; j++) + outfile << el.PNum(j)<<"\n"; + else + { + for (j = 2; j >= 1; j--) + outfile << el.PNum(j)<<"\n"; + for (j = 3; j <= 4; j++) + outfile << el.PNum(j)<<"\n"; + } + outfile << el.GetIndex() << "\n\n"; + } + } + if ( counter != ntets) + { + cout<< "\n Error in determining number of tetras!\n"< 0) + for (j = 1; j <= 6; j++) + outfile << el.PNum(j)<<"\n"; + else + { + for (j = 3; j >= 1; j--) + outfile << el.PNum(j)<<"\n"; + for (j = 6; j >= 4; j--) + outfile << el.PNum(j)<<"\n"; + } + } + else if ( pointsOnTetras.Get(el.PNum(4)) && + pointsOnTetras.Get(el.PNum(5)) && + pointsOnTetras.Get(el.PNum(6)) ) + { + if ( vol < 0 ) + { + for (j = 4; j <= 6; j++) + outfile << el.PNum(j)<<"\n"; + for (j = 1; j <= 3; j++) + outfile << el.PNum(j)<<"\n"; + } + else + { + for (j = 6; j >= 4; j--) + outfile << el.PNum(j)<<"\n"; + for (j = 3; j >= 1; j--) + outfile << el.PNum(j)<<"\n"; + } + } + else + { + cout << "\n Error in determining prism point numbering!\n"<= 5 ) + jj = jj - 4; + outfile << el.PNum(jj)<<"\n"; + } + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << "\n"; + if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() == bc_at_infinity) + { + outfile << "-2\n\n"; + cout << "\nWarning: Quadrilateral at infinity found (this should not occur)!"<= 5 ) + jj = jj - 4; + outfile << identmap1.Elem(el.PNum(jj))<<"\n"; + } + outfile << "\n"; + } + else if ( identmap2.Elem(el.PNum(1)) && + identmap2.Elem(el.PNum(2)) && + identmap2.Elem(el.PNum(3)) && + identmap2.Elem(el.PNum(4)) ) + { + outfile << "-1\n"; + for (j = 1; j <= 4; j++) + { + jj = j + ct; + if ( jj >= 5 ) + jj = jj - 4; + outfile << identmap2.Elem(el.PNum(jj))<<"\n"; + } + outfile << "\n"; + } + else if ( identmap3.Elem(el.PNum(1)) && + identmap3.Elem(el.PNum(2)) && + identmap3.Elem(el.PNum(3)) && + identmap3.Elem(el.PNum(4)) ) + { + outfile << "-1\n"; + for (j = 1; j <= 4; j++) + { + jj = j + ct; + if ( jj >= 5 ) + jj = jj - 4; + outfile << identmap3.Elem(el.PNum(jj))<<"\n"; + } + outfile << "\n"; + } + else + outfile << "1\n\n"; + } + } + + cout << " JCMwave grid file written." << endl; +} + +} + diff --git a/libsrc/interface/writepermas.cpp b/libsrc/interface/writepermas.cpp new file mode 100644 index 00000000..fc46e87c --- /dev/null +++ b/libsrc/interface/writepermas.cpp @@ -0,0 +1,208 @@ +// +// Write Permas file +// for Intes GmbH, Stuttgart +// + +#include + +#include +#include +#include +#include + +#include + +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(0); + 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)(0) << " "; + outfile << mesh.Point(i)(1) << " "; + outfile << mesh.Point(i)(2) << "\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/libsrc/interface/writetecplot.cpp b/libsrc/interface/writetecplot.cpp new file mode 100644 index 00000000..6f606374 --- /dev/null +++ b/libsrc/interface/writetecplot.cpp @@ -0,0 +1,127 @@ +// +// +// TECPLOT file by Jawor Georgiew +// +#include + +#include +#include +#include +#include + + + +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 sn(np); + ofstream outfile(filename.c_str()); + + outfile << "TITLE=\" " << filename << "\"" << endl; + + // fill hashtable + + INDEX_3_HASHTABLE face2volelement(ne); + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + INDEX_3 i3; + int 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)(0) << " " /* Knoten Koordinaten */ + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << " " + << 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 (k = 1; k <= nse; k++) + { + const Element2d & sel = mesh.SurfaceElement(k); + INDEX_3 i3; + for (j = 1; j <= 3; j++) + i3.I(j) = sel.PNum(j); + i3.Sort(); + + //int elind = face2volelement.Get(i3); + } + } + } +} + + +} diff --git a/libsrc/interface/writetet.cpp b/libsrc/interface/writetet.cpp new file mode 100644 index 00000000..581cc0a3 --- /dev/null +++ b/libsrc/interface/writetet.cpp @@ -0,0 +1,1096 @@ + +#include + +#include +#include +#include +#include +#include + +namespace netgen +{ + +#include "writeuser.hpp" + + + void WriteTETFormat (const Mesh & mesh, + const string & filename)//, const string& problemType ) + { + string problemType = ""; + if(!mesh.PureTetMesh()) + throw NgException("Can only export pure tet mesh in this format"); + + cout << "starting .tet export to file " << filename << endl; + + + ARRAY point_ids,edge_ids,face_ids; + ARRAY elnum(mesh.GetNE()); + elnum = -1; + + + ARRAY userdata_int; + ARRAY userdata_double; + ARRAY ports; + + ARRAY uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D; + + int pos_int = 0; + int pos_double = 0; + + bool haveuserdata = + (mesh.GetUserData("TETmesh:double",userdata_double) && + mesh.GetUserData("TETmesh:int",userdata_int) && + mesh.GetUserData("TETmesh:ports",ports) && + mesh.GetUserData("TETmesh:point_id",point_ids,PointIndex::BASE) && + mesh.GetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D) && + mesh.GetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D) && + mesh.GetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D) && + mesh.GetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D)); + + + int version,subversion; + + if(haveuserdata) + { + version = int(userdata_double[0]); + subversion = int(10*(userdata_double[0] - version)); + pos_double++; + } + else + { + version = 2; + subversion = 0; + } + + + if(version >= 2) + { + // test if ids are disjunct, if not version 2.0 not possible + int maxbc(-1),mindomain(-1); + + for(ElementIndex i=0; i maxbc) + maxbc = mesh.GetFaceDescriptor(i).BCProperty(); + + if(maxbc >= mindomain) + { + cout << "WARNING: writing version " << version << "." << subversion << " tetfile not possible, "; + version = 1; subversion = 1; + cout << "using version " << version << "." << subversion << endl; + } + } + + + + int startsize = point_ids.Size(); + point_ids.SetSize(mesh.GetNP()+1); + for(int i=startsize; i edgenumbers(6*mesh.GetNE()+3*mesh.GetNSE());; + INDEX_3_CLOSED_HASHTABLE facenumbers(4*mesh.GetNE()+mesh.GetNSE()); + + ARRAY edge2node; + ARRAY face2edge; + ARRAY element2face; + + int numelems(0),numfaces(0),numedges(0),numnodes(0); + + for(SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + const Segment & seg = mesh[si]; + INDEX_2 i2(seg.p1,seg.p2); + i2.Sort(); + if(edgenumbers.Used(i2)) + continue; + + numedges++; + edgenumbers.Set(i2,numedges); + edge2node.Append(i2); + + edge_ids.Append(seg.edgenr); + + if(point_ids[seg.p1] == -1) + point_ids[seg.p1] = (version >= 2) ? seg.edgenr : 0; + if(point_ids[seg.p2] == -1) + point_ids[seg.p2] = (version >= 2) ? seg.edgenr : 0; + } + + for(SurfaceElementIndex si = 0; si < mesh.GetNSE(); si++) + { + if(mesh[si].IsDeleted()) + continue; + + const Element2d & elem = mesh[si]; + + numfaces++; + INDEX_3 i3(elem[0], elem[1], elem[2]); + + int min = i3[0]; + int minpos = 0; + for(int j=1; j<3; j++) + if(i3[j] < min) + { + min = i3[j]; minpos = j; + } + if(minpos == 1) + { + int aux = i3[0]; i3[0] = i3[1]; i3[1] = i3[2]; i3[2] = aux; + } + else if(minpos == 2) + { + int aux = i3[0]; i3[0] = i3[2]; i3[2] = i3[1]; i3[1] = aux; + } + facenumbers.Set(i3,numfaces); + + int bc = mesh.GetFaceDescriptor(elem.GetIndex()).BCProperty(); + face_ids.Append(bc); + + for(int j=0; j<3; j++) + if(point_ids[elem[j]] == -1) + point_ids[elem[j]] = (version >= 2) ? bc : 0; + + INDEX_2 i2a,i2b; + INDEX_3 f_to_n; + for(int j=0; j<3; j++) + { + i2a = INDEX_2(i3[j],i3[(j+1)%3]); + i2b[0] = i2a[1]; i2b[1] = i2a[0]; + if(edgenumbers.Used(i2a)) + f_to_n[j] = edgenumbers.Get(i2a); + else if(edgenumbers.Used(i2b)) + f_to_n[j] = -edgenumbers.Get(i2b); + else + { + numedges++; + edgenumbers.Set(i2a,numedges); + edge2node.Append(i2a); + f_to_n[j] = numedges; + if(version >= 2) + edge_ids.Append(bc); + else + edge_ids.Append(0); + } + } + face2edge.Append(f_to_n); + } + + for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + if(el.IsDeleted()) + continue; + + numelems++; + elnum[ei] = numelems; + + static int tetfaces[4][3] = + { { 0, 2, 1 }, + { 0, 1, 3 }, + { 1, 2, 3 }, + { 2, 0, 3 } }; + + for(int j=0; j<4; j++) + if(point_ids[el[j]] == -1) + point_ids[el[j]] = (version >= 2) ? el.GetIndex() : 0; + + INDEX_4 e_to_f; + + for(int i = 0; i < 4; i++) + { + INDEX_3 i3a(el[tetfaces[i][0]],el[tetfaces[i][1]],el[tetfaces[i][2]]); + + int min = i3a[0]; + int minpos = 0; + for(int j=1; j<3; j++) + if(i3a[j] < min) + { + min = i3a[j]; minpos = j; + } + if(minpos == 1) + { + int aux = i3a[0]; i3a[0] = i3a[1]; i3a[1] = i3a[2]; i3a[2] = aux; + } + else if(minpos == 2) + { + int aux = i3a[0]; i3a[0] = i3a[2]; i3a[2] = i3a[1]; i3a[1] = aux; + } + INDEX_3 i3b(i3a[0],i3a[2],i3a[1]); + + + if(facenumbers.Used(i3a)) + e_to_f[i] = facenumbers.Get(i3a); + else if(facenumbers.Used(i3b)) + e_to_f[i] = -facenumbers.Get(i3b); + else + { + numfaces++; + facenumbers.Set(i3a,numfaces); + e_to_f[i] = numfaces; + if(version >= 2) + face_ids.Append(el.GetIndex()); + else + face_ids.Append(0); + + INDEX_2 i2a,i2b; + INDEX_3 f_to_n; + for(int j=0; j<3; j++) + { + i2a = INDEX_2(i3a[j],i3a[(j+1)%3]); + i2b[0] = i2a[1]; i2b[1] = i2a[0]; + if(edgenumbers.Used(i2a)) + f_to_n[j] = edgenumbers.Get(i2a); + else if(edgenumbers.Used(i2b)) + f_to_n[j] = -edgenumbers.Get(i2b); + else + { + numedges++; + edgenumbers.Set(i2a,numedges); + edge2node.Append(i2a); + f_to_n[j] = numedges; + if(version >= 2) + edge_ids.Append(el.GetIndex()); + else + edge_ids.Append(0); + } + } + face2edge.Append(f_to_n); + } + } + element2face.Append(e_to_f); + } + + + + + ofstream outfile(filename.c_str()); + + outfile.precision(16); + + int unitcode; + double tolerance; + double dS1,dS2, alphaDeg; + double x3D,y3D,z3D; + int modelverts(0), modeledges(0), modelfaces(0), modelcells(0); + + int numObj0D,numObj1D,numObj2D,numObj3D; + int numports = ports.Size(); + + ARRAY nodenum(point_ids.Size()+1); + + nodenum = -1; + + + + numnodes = 0; + for(int i=0; i* > idmaps; + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + idmaps.Append(new ARRAY); + mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true); + } + } + + ARRAY id_num,id_type; + ARRAY< ARRAY *> id_groups; + + + // sst 2008-03-12: Write problem class... + { + std::string block; + block = "// CST Tetrahedral "; + block += !problemType.empty() ? problemType : "High Frequency"; + block += " Mesh, Version no.:\n"; + + size_t size = block.size()-3; + block += "// "; + block.append( size, '^' ); + block += "\n"; + + outfile + << block + << version << "." << subversion << "\n\n"; + } + + outfile + << "// User Units Code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << unitcode << "\n\n" \ + << "// Geometric coord \"zero\" tolerance threshold:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << tolerance << "\n\n" \ + << "// Periodic UnitCell dS1 , dS2 , alphaDeg:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << dS1 << " " << dS2 << " " << alphaDeg <<"\n\n" \ + << "// Periodic UnitCell origin in global coords (x3D,y3D,z3D):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << x3D << " " << y3D << " " << z3D << "\n" << endl; + + if(version == 2) + { + outfile << "// Model entity count: Vertices, Edges, Faces, Cells:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << modelverts << " " << modeledges << " " << modelfaces << " " << modelcells << endl << endl; + } + + + outfile << "// Topological mesh-entity counts (#elements,#faces,#edges,#nodes):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + outfile << numelems << " " + << numfaces << " " + << numedges << " " + << numnodes << endl << endl; + + outfile << "// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<< uidpid <<":\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + + + + id_num.SetSize(mesh.GetNP()+1); + id_type.SetSize(mesh.GetNP()+1); + id_num = 0; + id_type = 0; + + int n2,n4,n8; + n2 = n4 = n8 = 0; + + + for(int i=PointIndex::BASE; i group; + group.Append(i); + for(int j=0; j 1) + { + id_groups.Append(new ARRAY(group)); + if(group.Size() == 2) + { + id_type[i] = 1; + id_type[group[1]] = 2; + n2++; + } + else if(group.Size() == 4) + { + id_type[i] = 3; + for(int j=1; jSize() != 2) + continue; + + for(int j=0; jSize(); j++) + outfile << nodenum[(*id_groups[i])[j]] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + outfile << "// Number of Corner Periodic Master Nodes:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << n4 << "\n" \ + << "\n" \ + << "// MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + + + for(int i=0; iSize() != 4) + continue; + + for(int j=0; jSize(); j++) + outfile << nodenum[(*id_groups[i])[j]] << " "; + for(int j=1; jSize(); j++) + { + outfile << id_num[(*id_groups[i])[j]] << " "; + } + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + outfile << "// Number of Cubic Periodic Master Nodes:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << n8 << "\n" \ + << "\n" \ + << "// MasterNodeID, 7-SlaveNodeID's, TranslCodes:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() != 8) + continue; + + for(int j=0; jSize(); j++) + outfile << nodenum[(*id_groups[i])[j]] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + + + outfile << "// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<* > vertex_to_edge(mesh.GetNP()+1); + for(int i=0; i<=mesh.GetNP(); i++) + vertex_to_edge[i] = new ARRAY; + + ARRAY< ARRAY* > idmaps_edge(idmaps.Size()); + for(int i=0; i(numedges); + (*idmaps_edge[i]) = 0; + } + + ARRAY possible; + for(int i=0; i 0) + { + cerr << "ERROR: too many possible edge identifications" << endl; + (*testout) << "ERROR: too many possible edge identifications" << endl + << "*vertex_to_edge["<Append(i+1); + vertex_to_edge[v[1]]->Append(i+1); + } + + + for(int i=0; i group; + group.Append(i); + for(int j=0; j 1) + { + id_num[i] = 1; + id_groups.Append(new ARRAY(group)); + if(group.Size() == 2) + { + id_type[i] = 1; + id_type[group[1]] = 2; + n2++; + } + else if(group.Size() == 4) + { + id_type[i] = 3; + for(int j=1; j group; + group.Append(i); + for(int j=0; j 1) + { + id_num[i] = 1; + id_groups.Append(new ARRAY(group)); + if(group.Size() == 2) + { + id_type[i] = 1; + id_type[group[1]] = 2; + n2++; + } + else if(group.Size() == 4) + { + id_type[i] = 3; + for(int j=1; jSize() != 2) + continue; + + for(int j=0; jSize(); j++) + outfile << (*id_groups[i])[j] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + outfile << "// Number of Corner Periodic Master Edges:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\ + << n4 << "\n" \ + << "\n"\ + << "// MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() != 4) + continue; + + for(int j=0; jSize(); j++) + outfile << (*id_groups[i])[j] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + outfile << "// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), "<* > edge_to_face(numedges+1); + for(int i=0; i; + + + for(int i=0; iSetSize(numfaces); + (*idmaps[i]) = 0; + } + + + for(int i=0; i 0) + cerr << "ERROR: too many possible face identifications" << endl; + } + } + + edge_to_face[abs(face2edge[i][0])]->Append(i+1); + edge_to_face[abs(face2edge[i][1])]->Append(i+1); + edge_to_face[abs(face2edge[i][2])]->Append(i+1); + } + + for(int i=0; i group; + group.Append(i); + for(int j=0; j 1) + { + id_num[i] = -1; + id_groups.Append(new ARRAY(group)); + if(group.Size() == 2) + n2++; + else + cerr << "ERROR: face identification group size = " << group.Size() << endl; + } + + } + + + for(int i=0; iSize() != 2) + continue; + + for(int j=0; jSize(); j++) + outfile << (*id_groups[i])[j] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + } + outfile << endl; + + + + + outfile << "// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, "<= 0) + { + outfile << elnum[i] << " "; + for(int j=0; j<4; j++) + outfile << element2face[elnum[i]-1][j] << " "; + + outfile << mesh[i].GetIndex() << "\n"; + } + } + outfile << endl; + + outfile << "// ElemID, NodeID0, NodeID1, NodeID2, NodeID3:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + + + for(ElementIndex i=0; i= 0) + outfile << elnum[i] << " " + << nodenum[mesh[i][1]] << " " << nodenum[mesh[i][0]] << " " << nodenum[mesh[i][2]] << " " << nodenum[mesh[i][3]] << "\n"; + } + outfile << endl; + + + + + outfile << "// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D):\n" + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + << " "<< numObj3D << " " << numObj2D << " " << numObj1D << " " << numObj0D << "\n" \ + << "\n" \ + << "// Number of Ports (Ports are a subset of Object2D list):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << numports << "\n" \ + << endl; + + + ARRAY< ARRAY * > groups; + + int maxg = -1; + for(int i = 0; i maxg) + maxg = uid_to_group_3D[i]; + for(int i = 0; i maxg) + maxg = uid_to_group_2D[i]; + for(int i = 0; i maxg) + maxg = uid_to_group_1D[i]; + for(int i = 0; i maxg) + maxg = uid_to_group_0D[i]; + + groups.SetSize(maxg+1); + for(int i=0; i; + + for(ElementIndex i=0; i= 0) + groups[uid_to_group_3D[mesh[i].GetIndex()]]->Append(i+1); + + + + + outfile << "// Object3D GroupID, #Elems ElemID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + outfile << (*groups[i])[j] << "\n"; + } + + for(int i=0; iSetSize(0); + + for(int i=0; i= 0) + groups[uid_to_group_2D[face_ids[i]]]->Append(i+1); + + + outfile << "// Object2D GroupID, #Faces FaceID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + { + outfile << (*groups[i])[j]; + if(ports.Contains(face_ids[(*groups[i])[j]-1])) + outfile << " P"; + outfile << "\n"; + } + } + outfile << endl; + + + for(int i=0; iSetSize(0); + + for(int i=0; i= 0) + groups[uid_to_group_1D[edge_ids[i]]]->Append(i+1); + + + + outfile << "// Object1D GroupID, #Edges EdgeID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + outfile << (*groups[i])[j] << "\n"; + } + outfile << endl; + + + for(int i=0; iSetSize(0); + for(PointIndex i=PointIndex::BASE; i= 0) + groups[uid_to_group_0D[point_ids[i]]]->Append(i+1-PointIndex::BASE); + } + else + groups[uid_to_group_0D[0]]->Append(i+1-PointIndex::BASE); + } + + + outfile << "// Object0D GroupID, #Nodes NodeID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + outfile << (*groups[i])[j] << "\n"; + } + outfile << endl; + + for(int i=0; i + +#include +#include +#include +#include + + +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; + + for (i = 1; i <= np; i++) + { + outfile << "node " << " " << i << " "; + outfile << mesh.Point(i)(0) << " "; + outfile << mesh.Point(i)(1) << " "; + outfile << mesh.Point(i)(2) << "\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/libsrc/interface/writeuser.cpp b/libsrc/interface/writeuser.cpp new file mode 100644 index 00000000..92b76520 --- /dev/null +++ b/libsrc/interface/writeuser.cpp @@ -0,0 +1,910 @@ +// +// Write user dependent output file +// + +#include + +#include +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + + +void RegisterUserFormats (ARRAY & names) +{ + const 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", + "JCMwave Format", + "TET 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 if (format == "JCMwave Format") + WriteJCMFormat (mesh, geom, filename); + +#ifdef OLIVER + else if (format == "TET Format") + WriteTETFormat( mesh, filename);//, "High Frequency" ); +#endif + + 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 = 0; j < 3; j++) + { + outfile.width(10); + outfile << mesh.Point(i)(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; + + 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 + + int np = mesh.GetNP(); + int nse = mesh.GetNSE(); + int i, j; + + 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 + + int np = mesh.GetNP(); + int nse = mesh.GetNSE(); + int i, j; + + 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 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 edgeht(mesh.GetNP()); + + // list of edges + ARRAY 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/libsrc/interface/writeuser.hpp b/libsrc/interface/writeuser.hpp new file mode 100644 index 00000000..d9be90ec --- /dev/null +++ b/libsrc/interface/writeuser.hpp @@ -0,0 +1,145 @@ +#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 WriteJCMFormat (const Mesh & mesh, + const CSGeometry & geom, + 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); + + + +#ifdef OLIVER +extern +void WriteTETFormat (const Mesh & mesh, + const string & filename); + +#endif + +extern void ReadTETFormat (Mesh & mesh, + const string & filename); + + +extern void ReadFNFFormat (Mesh & mesh, + const string & filename); + + + +void WriteDolfinFormat (const Mesh & mesh, + const string & filename); + + +extern void RegisterUserFormats (ARRAY & names); + +extern bool WriteUserFormat (const string & format, + const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + + + + +#endif + diff --git a/libsrc/interface/wuchemnitz.cpp b/libsrc/interface/wuchemnitz.cpp new file mode 100644 index 00000000..147d0d4d --- /dev/null +++ b/libsrc/interface/wuchemnitz.cpp @@ -0,0 +1,313 @@ +// Write Chemnitz file format + + +#include + +#include + +#include +#include +#include + +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 points; +static ARRAY volelements; +static ARRAY surfelements; + +static ARRAY faces; +static ARRAY 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 faceindex(volelements.Size()/5 + 1); + INDEX_2_HASHTABLE 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; + default: + i3.I1()=i3.I2()=i3.I3()=0; + } + 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; + default: + i2.I1()=i2.I2()=0; + } + 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/libsrc/linalg/Makefile.am b/libsrc/linalg/Makefile.am new file mode 100644 index 00000000..99c3a271 --- /dev/null +++ b/libsrc/linalg/Makefile.am @@ -0,0 +1,4 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libla.a +libla_a_SOURCES = densemat.cpp polynomial.cpp vector.cpp diff --git a/libsrc/linalg/Makefile.in b/libsrc/linalg/Makefile.in new file mode 100644 index 00000000..a6869359 --- /dev/null +++ b/libsrc/linalg/Makefile.in @@ -0,0 +1,442 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/linalg +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libla_a_AR = $(AR) $(ARFLAGS) +libla_a_LIBADD = +am_libla_a_OBJECTS = densemat.$(OBJEXT) polynomial.$(OBJEXT) \ + vector.$(OBJEXT) +libla_a_OBJECTS = $(am_libla_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libla_a_SOURCES) +DIST_SOURCES = $(libla_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libla.a +libla_a_SOURCES = densemat.cpp polynomial.cpp vector.cpp +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/linalg/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/linalg/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libla.a: $(libla_a_OBJECTS) $(libla_a_DEPENDENCIES) + -rm -f libla.a + $(libla_a_AR) libla.a $(libla_a_OBJECTS) $(libla_a_LIBADD) + $(RANLIB) libla.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/densemat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polynomial.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vector.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/linalg/densemat.cpp b/libsrc/linalg/densemat.cpp new file mode 100644 index 00000000..762792f5 --- /dev/null +++ b/libsrc/linalg/densemat.cpp @@ -0,0 +1,1444 @@ +#include + +#include + + +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; height = width = 0; + 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 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 & 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 & 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/libsrc/linalg/densemat.hpp b/libsrc/linalg/densemat.hpp new file mode 100644 index 00000000..9daec518 --- /dev/null +++ b/libsrc/linalg/densemat.hpp @@ -0,0 +1,286 @@ +#ifndef FILE_DENSEMAT +#define FILE_DENSEMAT + +/**************************************************************************/ +/* File: densemat.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Oct. 94 */ +/**************************************************************************/ + +/** + Data type dense matrix +*/ + + +#include + + + + +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 (int 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(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]; } +}; + + +extern ostream & operator<< (ostream & ost, const DenseMatrix & m); + + + +template +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]; } + + + MatrixFixWidth & operator*= (double v) + { + if (data) + for (int i = 0; i < height*WIDTH; i++) + data[i] *= v; + return *this; + } + + + + 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]; } +}; + + +template +extern ostream & operator<< (ostream & ost, const MatrixFixWidth & 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; +}; + + +extern void CalcAtA (const DenseMatrix & a, DenseMatrix & m2); +extern void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2); + + +#endif diff --git a/libsrc/linalg/linalg.hpp b/libsrc/linalg/linalg.hpp new file mode 100644 index 00000000..7be9b4ad --- /dev/null +++ b/libsrc/linalg/linalg.hpp @@ -0,0 +1,33 @@ +#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 "../include/myadt.hpp" +namespace netgen +{ +#include "vector.hpp" +#include "densemat.hpp" +#include "polynomial.hpp" +} +#endif + + diff --git a/libsrc/linalg/polynomial.cpp b/libsrc/linalg/polynomial.cpp new file mode 100644 index 00000000..f947e0a1 --- /dev/null +++ b/libsrc/linalg/polynomial.cpp @@ -0,0 +1,216 @@ +#include +#include + +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/libsrc/linalg/polynomial.hpp b/libsrc/linalg/polynomial.hpp new file mode 100644 index 00000000..3108d4dd --- /dev/null +++ b/libsrc/linalg/polynomial.hpp @@ -0,0 +1,45 @@ +#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/libsrc/linalg/vector.cpp b/libsrc/linalg/vector.cpp new file mode 100644 index 00000000..b9dabda3 --- /dev/null +++ b/libsrc/linalg/vector.cpp @@ -0,0 +1,786 @@ +#ifdef abc +#include +#include +#include + +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 & pnum, + BaseVector & elvec) const +{ + int i; + for (i = 1; i <= pnum.Size(); i++) + elvec(i) = (*this)(pnum.Get(i)); +} + +void BaseVector :: SetElementVector (const ARRAY & pnum, + const BaseVector & elvec) +{ + int i; + for (i = 1; i <= pnum.Size(); i++) + (*this)(pnum.Get(i)) = elvec(i); +} + + +void BaseVector :: AddElementVector (const ARRAY & 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 vecs; + ARRAY 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() && Length() == hv3.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 & 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 & 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 & 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/libsrc/linalg/vector.hpp b/libsrc/linalg/vector.hpp new file mode 100644 index 00000000..90ee657f --- /dev/null +++ b/libsrc/linalg/vector.hpp @@ -0,0 +1,138 @@ +#ifndef FILE_VECTOR +#define FILE_VECTOR + +/* *************************************************************************/ +/* File: vector.hpp */ +/* 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[i]; + return *this; + } + + FlatVector & Set (double scal, const FlatVector & v2) + { + for (int i = 0; i < s; i++) + data[i] = scal * v2[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[i] + scal2 * v2[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; +} + + + +#endif + + diff --git a/libsrc/meshing/Makefile.am b/libsrc/meshing/Makefile.am new file mode 100644 index 00000000..377f83c0 --- /dev/null +++ b/libsrc/meshing/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libmesh.a +libmesh_a_SOURCES = adfront2.cpp adfront3.cpp bisect.cpp boundarylayer.cpp \ + clusters.cpp curvedelems_new.cpp delaunay.cpp geomsearch.cpp global.cpp \ + hprefinement.cpp improve2.cpp improve2gen.cpp improve3.cpp localh.cpp meshclass.cpp \ + meshfunc.cpp meshfunc2d.cpp meshing2.cpp meshing3.cpp meshtool.cpp meshtype.cpp \ + msghandler.cpp netrule2.cpp netrule3.cpp parser2.cpp parser3.cpp prism2rls.cpp \ + prism2rls_2.cpp pyramid2rls.cpp pyramidrls.cpp quadrls.cpp refine.cpp ruler2.cpp \ + ruler3.cpp secondorder.cpp smoothing2.5.cpp smoothing2.cpp smoothing3.cpp \ + specials.cpp tetrarls.cpp topology.cpp triarls.cpp validate.cpp zrefine.cpp diff --git a/libsrc/meshing/Makefile.in b/libsrc/meshing/Makefile.in new file mode 100644 index 00000000..f931b39e --- /dev/null +++ b/libsrc/meshing/Makefile.in @@ -0,0 +1,505 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/meshing +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libmesh_a_AR = $(AR) $(ARFLAGS) +libmesh_a_LIBADD = +am_libmesh_a_OBJECTS = adfront2.$(OBJEXT) adfront3.$(OBJEXT) \ + bisect.$(OBJEXT) boundarylayer.$(OBJEXT) clusters.$(OBJEXT) \ + curvedelems_new.$(OBJEXT) delaunay.$(OBJEXT) \ + geomsearch.$(OBJEXT) global.$(OBJEXT) hprefinement.$(OBJEXT) \ + improve2.$(OBJEXT) improve2gen.$(OBJEXT) improve3.$(OBJEXT) \ + localh.$(OBJEXT) meshclass.$(OBJEXT) meshfunc.$(OBJEXT) \ + meshfunc2d.$(OBJEXT) meshing2.$(OBJEXT) meshing3.$(OBJEXT) \ + meshtool.$(OBJEXT) meshtype.$(OBJEXT) msghandler.$(OBJEXT) \ + netrule2.$(OBJEXT) netrule3.$(OBJEXT) parser2.$(OBJEXT) \ + parser3.$(OBJEXT) prism2rls.$(OBJEXT) prism2rls_2.$(OBJEXT) \ + pyramid2rls.$(OBJEXT) pyramidrls.$(OBJEXT) quadrls.$(OBJEXT) \ + refine.$(OBJEXT) ruler2.$(OBJEXT) ruler3.$(OBJEXT) \ + secondorder.$(OBJEXT) smoothing2.5.$(OBJEXT) \ + smoothing2.$(OBJEXT) smoothing3.$(OBJEXT) specials.$(OBJEXT) \ + tetrarls.$(OBJEXT) topology.$(OBJEXT) triarls.$(OBJEXT) \ + validate.$(OBJEXT) zrefine.$(OBJEXT) +libmesh_a_OBJECTS = $(am_libmesh_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libmesh_a_SOURCES) +DIST_SOURCES = $(libmesh_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libmesh.a +libmesh_a_SOURCES = adfront2.cpp adfront3.cpp bisect.cpp boundarylayer.cpp \ + clusters.cpp curvedelems_new.cpp delaunay.cpp geomsearch.cpp global.cpp \ + hprefinement.cpp improve2.cpp improve2gen.cpp improve3.cpp localh.cpp meshclass.cpp \ + meshfunc.cpp meshfunc2d.cpp meshing2.cpp meshing3.cpp meshtool.cpp meshtype.cpp \ + msghandler.cpp netrule2.cpp netrule3.cpp parser2.cpp parser3.cpp prism2rls.cpp \ + prism2rls_2.cpp pyramid2rls.cpp pyramidrls.cpp quadrls.cpp refine.cpp ruler2.cpp \ + ruler3.cpp secondorder.cpp smoothing2.5.cpp smoothing2.cpp smoothing3.cpp \ + specials.cpp tetrarls.cpp topology.cpp triarls.cpp validate.cpp zrefine.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/meshing/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/meshing/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libmesh.a: $(libmesh_a_OBJECTS) $(libmesh_a_DEPENDENCIES) + -rm -f libmesh.a + $(libmesh_a_AR) libmesh.a $(libmesh_a_OBJECTS) $(libmesh_a_LIBADD) + $(RANLIB) libmesh.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adfront2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adfront3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bisect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/boundarylayer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clusters.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curvedelems_new.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delaunay.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geomsearch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hprefinement.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improve2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improve2gen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improve3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshclass.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshfunc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshfunc2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshing2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshing3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshtool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshtype.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msghandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrule2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrule3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prism2rls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prism2rls_2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyramid2rls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyramidrls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quadrls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ruler2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ruler3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/secondorder.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smoothing2.5.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smoothing2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smoothing3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specials.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tetrarls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/topology.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triarls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zrefine.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/meshing/adfront2.cpp b/libsrc/meshing/adfront2.cpp new file mode 100644 index 00000000..37a7c385 --- /dev/null +++ b/libsrc/meshing/adfront2.cpp @@ -0,0 +1,466 @@ +/* + Advancing front class for surfaces +*/ + +#include +#include "meshing.hpp" + + +namespace netgen +{ + AdFront2::FrontPoint2 :: FrontPoint2 (const Point<3> & ap, PointIndex agi, + MultiPointGeomInfo * amgi, bool aonsurface) + { + p = ap; + globalindex = agi; + nlinetopoint = 0; + frontnr = INT_MAX-10; + onsurface = aonsurface; + + 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 :: AdFront2 (const Box3d & aboundingbox) + : boundingbox(aboundingbox), + linesearchtree(boundingbox.PMin(), boundingbox.PMax()), + pointsearchtree(boundingbox.PMin(), boundingbox.PMax()), + cpointsearchtree(boundingbox.PMin(), boundingbox.PMax()) + { + nfl = 0; + allflines = 0; + + minval = 0; + starti = lines.Begin(); + } + + AdFront2 :: ~AdFront2 () + { + delete allflines; + } + + + void AdFront2 :: PrintOpenSegments (ostream & ost) const + { + if (nfl > 0) + { + ost << nfl << " open front segments left:" << endl; + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + ost << i << ": " + << GetGlobalIndex (lines[i].L().I1()) << "-" + << GetGlobalIndex (lines[i].L().I2()) << endl; + } + } + + /* + void AdFront2 :: GetPoints (ARRAY > & apoints) const + { + apoints.Append (points); + // for (int i = 0; i < points.Size(); i++) + // apoints.Append (points[i].P()); + } + */ + + + + int AdFront2 :: AddPoint (const Point<3> & p, PointIndex globind, + MultiPointGeomInfo * mgi, + bool pointonsurface) + { + // inserts at empty position or resizes array + int pi; + + if (delpointl.Size() != 0) + { + pi = delpointl.Last(); + delpointl.DeleteLast (); + + points[pi] = FrontPoint2 (p, globind, mgi, pointonsurface); + } + else + { + pi = points.Append (FrontPoint2 (p, globind, mgi, pointonsurface)) - 1; + } + + if (mgi) + cpointsearchtree.Insert (p, pi); + + pointsearchtree.Insert (p, pi); + + return pi; + } + + + int AdFront2 :: AddLine (int pi1, int pi2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2) + { + int minfn; + int li; + + FrontPoint2 & p1 = points[pi1]; + FrontPoint2 & p2 = points[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[li] = FrontLine (INDEX_2(pi1, pi2)); + } + else + { + li = lines.Append(FrontLine (INDEX_2(pi1, pi2))) - 1; + } + + + if (!gi1.trignum || !gi2.trignum) + { + cout << "ERROR: in AdFront::AddLine, illegal geominfo" << endl; + } + + lines[li].SetGeomInfo (gi1, gi2); + + Box3d lbox; + lbox.SetPoint(p1.P()); + lbox.AddPoint(p2.P()); + + linesearchtree.Insert (lbox.PMin(), lbox.PMax(), li); + + 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 (int li) + { + int pi; + + nfl--; + + for (int i = 1; i <= 2; i++) + { + pi = lines[li].L().I(i); + points[pi].RemoveLine(); + + if (!points[pi].Valid()) + { + delpointl.Append (pi); + if (points[pi].mgi) + { + cpointsearchtree.DeleteElement (pi); + delete points[pi].mgi; + points[pi].mgi = NULL; + } + + pointsearchtree.DeleteElement (pi); + } + } + + if (allflines) + { + allflines->Set (INDEX_2 (GetGlobalIndex (lines[li].L().I1()), + GetGlobalIndex (lines[li].L().I2())), 2); + } + + lines[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 (int li) + { + lines[li].IncrementClass(); + } + + + void AdFront2 :: ResetClass (int li) + { + lines[li].ResetClass(); + } + */ + + int AdFront2 :: SelectBaseLine (Point<3> & p1, Point<3> & p2, + const PointGeomInfo *& geominfo1, + const PointGeomInfo *& geominfo2, + int & qualclass) + { + int baselineindex = -1; + + for (int i = starti; i < lines.End(); i++) + { + if (lines[i].Valid()) + { + int hi = lines[i].LineClass() + + points[lines[i].L().I1()].FrontNr() + + points[lines[i].L().I2()].FrontNr(); + + if (hi <= minval) + { + minval = hi; + baselineindex = i; + break; + } + } + } + + if (baselineindex == -1) + { + minval = INT_MAX; + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + { + int hi = lines[i].LineClass() + + points[lines[i].L().I1()].FrontNr() + + points[lines[i].L().I2()].FrontNr(); + + if (hi < minval) + { + minval = hi; + baselineindex = i; + } + } + } + starti = baselineindex+1; + + p1 = points[lines[baselineindex].L().I1()].P(); + p2 = points[lines[baselineindex].L().I2()].P(); + geominfo1 = &lines[baselineindex].GetGeomInfo(1); + geominfo2 = &lines[baselineindex].GetGeomInfo(2); + + qualclass = lines[baselineindex].LineClass(); + + return baselineindex; + } + + + + + int AdFront2 :: GetLocals (int baselineindex, + ARRAY & locpoints, + ARRAY & pgeominfo, + ARRAY & loclines, // local index + ARRAY & pindex, + ARRAY & lindex, + double xh) + { + // baselineindex += 1-lines.Begin(); + + int pstind; + Point<3> midp, p0; + + pstind = lines[baselineindex].L().I1(); + p0 = points[pstind].P(); + + loclines.Append(lines[baselineindex].L()); + lindex.Append(baselineindex); // +1-lines.Begin()); + + static ARRAY nearlines; + nearlines.SetSize(0); + static ARRAY nearpoints; + nearpoints.SetSize(0); + + linesearchtree.GetIntersecting (p0 - Vec3d(xh, xh, xh), + p0 + Vec3d(xh, xh, xh), + nearlines); + + pointsearchtree.GetIntersecting (p0 - Vec3d(xh, xh, xh), + p0 + Vec3d(xh, xh, xh), + nearpoints); + + + for (int ii = 1; ii <= nearlines.Size(); ii++) + { + int i = nearlines.Get(ii); + if (lines[i].Valid() && i != baselineindex) // + 1-lines.Begin()) + { + loclines.Append(lines[i].L()); + lindex.Append(i); + } + } + + static ARRAY invpindex; + invpindex.SetSize (points.Size()); + // invpindex = -1; + for (int i = 0; i < nearpoints.Size(); i++) + invpindex[nearpoints[i]] = -1; + + for (int i = 0; i < loclines.Size(); i++) + { + invpindex[loclines[i].I1()] = 0; + invpindex[loclines[i].I2()] = 0; + } + + + for (int i = 0; i < loclines.Size(); i++) + { + for (int j = 0; j < 2; j++) + { + int pi = loclines[i][j]; + if (invpindex[pi] == 0) + { + pindex.Append (pi); + invpindex[pi] = pindex.Size(); + loclines[i][j] = locpoints.Append (points[pi].P()); + } + else + loclines[i][j] = invpindex[pi]; + } + } + + + // double xh2 = xh*xh; + for (int ii = 0; ii < nearpoints.Size(); ii++) + { + int i = nearpoints[ii]; + if (points[i].Valid() && + points[i].OnSurface() && + // Dist2 (points.Get(i).P(), p0) <= xh2 && + invpindex[i] <= 0) + { + invpindex[i] = locpoints.Append (points[i].P()); + pindex.Append(i); + } + } + /* + double xh2 = xh*xh; + for (i = 1; i <= points.Size(); i++) + { + if (points.Get(i).Valid() && + points.Get(i).OnSurface() && + Dist2 (points.Get(i).P(), p0) <= xh2 && + invpindex.Get(i) <= 0) + { + invpindex.Elem(i) = + locpoints.Append (points.Get(i).P()); + pindex.Append(i); + } + } + */ + + pgeominfo.SetSize (locpoints.Size()); + for (int i = 0; i < pgeominfo.Size(); i++) + pgeominfo[i].Init(); + + + for (int i = 0; i < loclines.Size(); i++) + for (int j = 0; j < 2; j++) + { + int lpi = loclines[i][j]; + + const PointGeomInfo & gi = + lines[lindex[i]].GetGeomInfo (j+1); + 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 (int i = 0; i < locpoints.Size(); i++) + { + int pi = pindex[i]; + + if (points[pi].mgi) + for (int j = 1; j <= points[pi].mgi->GetNPGI(); j++) + pgeominfo[i].AddPointGeomInfo (points[pi].mgi->GetPGI(j)); + } + + 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[baselineindex].LineClass(); + } + + + + void AdFront2 :: SetStartFront () + { + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + for (int j = 1; j <= 2; j++) + points[lines[i].L().I(j)].DecFrontNr(0); + } + + + void AdFront2 :: Print (ostream & ost) const + { + ost << points.Size() << " Points: " << endl; + for (int i = points.Begin(); i < points.End(); i++) + if (points[i].Valid()) + ost << i << " " << points[i].P() << endl; + + ost << nfl << " Lines: " << endl; + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + ost << lines[i].L().I1() << " - " << lines[i].L().I2() << endl; + + ost << flush; + } +} diff --git a/libsrc/meshing/adfront2.hpp b/libsrc/meshing/adfront2.hpp new file mode 100644 index 00000000..4266d333 --- /dev/null +++ b/libsrc/meshing/adfront2.hpp @@ -0,0 +1,264 @@ +#ifndef FILE_ADFRONT2 +#define FILE_ADFRONT2 + +/**************************************************************************/ +/* File: adfront2.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + + +/** + + Advancing front class for surfaces + +*/ +class AdFront2 +{ + + /// + class FrontPoint2 + { + /// coordinates + Point<3> p; + /// global node index + PointIndex globalindex; + /// number of front lines connected to point + int nlinetopoint; + /// distance to original boundary + int frontnr; + + bool onsurface; + + public: + /// + MultiPointGeomInfo * mgi; + + /// + FrontPoint2 () + { + globalindex = -1; + nlinetopoint = 0; + frontnr = INT_MAX-10; // attention: overflow on calculating INT_MAX + 1 + mgi = NULL; + onsurface = true; + } + + /// + FrontPoint2 (const Point<3> & ap, PointIndex agi, + MultiPointGeomInfo * amgi, bool aonsurface = true); + /// + ~FrontPoint2 () { ; } + + /// + const Point<3> & P () const { return p; } + /// + operator const Point<3> & () 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; } + + /// + bool OnSurface() const + { return onsurface; } + + /// + 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 + PointGeomInfo geominfo[2]; + public: + + FrontLine () + { + lineclass = 1; + } + + /// + FrontLine (const INDEX_2 & al) + { + l = al; + lineclass = 1; + } + + + /// + 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 points; /// front points + ARRAY lines; /// front lines + + Box3d boundingbox; + Box3dTree linesearchtree; /// search tree for lines + Point3dTree pointsearchtree; /// search tree for points + Point3dTree cpointsearchtree; /// search tree for cone points (not used ???) + + ARRAY delpointl; /// list of deleted front points + ARRAY dellinel; /// list of deleted front lines + + int nfl; /// number of front lines; + INDEX_2_HASHTABLE * allflines; /// all front lines ever have been + + + int minval; + int starti; + +public: + /// + // AdFront2 (); + AdFront2 (const Box3d & aboundingbox); + /// + ~AdFront2 (); + + /// + // void GetPoints (ARRAY > & apoints) const; + /// + void Print (ostream & ost) const; + + /// + bool Empty () const + { + return nfl == 0; + } + /// + int GetNFL () const { return nfl; } + /// + int SelectBaseLine (Point<3> & p1, Point<3> & p2, + const PointGeomInfo *& geominfo1, + const PointGeomInfo *& geominfo2, + int & qualclass); + + /// + int GetLocals (int baseline, + ARRAY & locpoints, + ARRAY & pgeominfo, + ARRAY & loclines, // local index + ARRAY & pindex, + ARRAY & lindex, + double xh); + + /// + void DeleteLine (int li); + /// + int AddPoint (const Point<3> & p, PointIndex globind, + MultiPointGeomInfo * mgi = NULL, + bool pointonsurface = true); + /// + int AddLine (int pi1, int pi2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2); + /// + int ExistsLine (int gpi1, int gpi2); + + /// + void IncrementClass (int li) + { + lines[li].IncrementClass(); + } + + /// + void ResetClass (int li) + { + lines[li].ResetClass(); + } + + /// + const PointGeomInfo & GetLineGeomInfo (int li, int lend) const + { return lines[li].GetGeomInfo (lend); } + /// + + PointIndex GetGlobalIndex (int pi) const + { + return points[pi].GlobalIndex(); + } + /// + void SetStartFront (); + /// + void PrintOpenSegments (ostream & ost) const; +}; + + + +#endif + + + diff --git a/libsrc/meshing/adfront3.cpp b/libsrc/meshing/adfront3.cpp new file mode 100644 index 00000000..dfe2edc8 --- /dev/null +++ b/libsrc/meshing/adfront3.cpp @@ -0,0 +1,876 @@ +#include +#include "meshing.hpp" + + +/* ********************** FrontPoint ********************** */ + +namespace netgen +{ + +FrontPoint3 :: FrontPoint3 () +{ + globalindex = -1; + nfacetopoint = 0; + frontnr = 1000; + cluster = 0; +} + + +FrontPoint3 :: FrontPoint3 (const Point<3> & 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 MiniElement2d & 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 > & apoints) const +{ + for (PointIndex pi = PointIndex::BASE; + pi < points.Size()+PointIndex::BASE; pi++) + + apoints.Append (points[pi].P()); +} + + +PointIndex AdFront3 :: AddPoint (const Point<3> & 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 MiniElement2d & 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 MiniElement2d & 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 (GetNP()); + + connectedpairs->Add (apair.I1(), apair.I2()); + connectedpairs->Add (apair.I2(), apair.I1()); + + return 0; +} + + +void AdFront3 :: CreateTrees () +{ + int i, j; + PointIndex pi; + Point3d pmin, pmax; + + for (pi = PointIndex::BASE; + pi < GetNP()+PointIndex::BASE; pi++) + { + const Point<3> & 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 MiniElement2d & el = GetFace(i); + pmin = GetPoint (el[0]); + pmax = pmin; + for (j = 1; j < 3; j++) + { + const Point<3> & 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 Point<3> & pmin, const Point<3> & pmax, + ARRAY & 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 () +{ + static int timer_a = NgProfiler::CreateTimer ("Adfront3::RebuildInternal A"); + static int timer_b = NgProfiler::CreateTimer ("Adfront3::RebuildInternal B"); + static int timer_c = NgProfiler::CreateTimer ("Adfront3::RebuildInternal C"); + static int timer_d = NgProfiler::CreateTimer ("Adfront3::RebuildInternal D"); + + + NgProfiler::StartTimer (timer_a); + int hi = 0; + for (int 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 (int i = PointIndex::BASE; + i < np+PointIndex::BASE; i++) + points[i].cluster = i; + + NgProfiler::StopTimer (timer_a); + NgProfiler::StartTimer (timer_b); + + int change; + do + { + change = 0; + for (int i = 1; i <= faces.Size(); i++) + { + const MiniElement2d & el = faces.Get(i).Face(); + + int mini = points[el.PNum(1)].cluster; + int maxi = mini; + + for (int 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 (int j = 1; j <= 3; j++) + points[el.PNum(j)].cluster = mini; + } + } + } + while (change); + + + NgProfiler::StopTimer (timer_b); + NgProfiler::StartTimer (timer_c); + + + + + BitArrayChar usecl(np); + usecl.Clear(); + for (int 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 (int i = PointIndex::BASE; + i < np+PointIndex::BASE; i++) + if (usecl.Test(i)) + cntcl++; + + ARRAY clvol (np); + clvol = 0.0; + + for (int i = 1; i <= faces.Size(); i++) + { + const MiniElement2d & 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; + } + + NgProfiler::StopTimer (timer_c); + NgProfiler::StartTimer (timer_d); + + + + int negvol = 0; + for (int i = PointIndex::BASE; + i < clvol.Size()+PointIndex::BASE; i++) + { + if (clvol[i] < 0) + negvol = 1; + } + + if (negvol) + { + for (int i = 1; i <= faces.Size(); i++) + faces.Elem(i).cluster = 1; + for (int i = PointIndex::BASE; + i < points.Size()+PointIndex::BASE; i++) + points[i].cluster = 1; + } + + if (hashon) + hashtable.Create(); + + NgProfiler::StopTimer (timer_d); +} + + + +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 & locpoints, + ARRAY & locfaces, // local index + ARRAY & pindex, + ARRAY & findex, + INDEX_2_HASHTABLE & getconnectedpairs, + float xh, + float relh, + INDEX& facesplit) +{ + static int timer = NgProfiler::CreateTimer ("AdFront3::GetLocals"); + NgProfiler::RegionTimer reg (timer); + + + 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 invpindex; + + static ARRAY locfaces2; //all local faces in radius xh + static ARRAY locfaces3; // all faces in outer radius relh + static ARRAY 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 MiniElement2d & face = faces.Get(i).Face(); + if (faces.Get(i).cluster == cluster && faces.Get(i).Valid() && i != fstind) + { + Box3d b2; + b2.SetPoint (points[face[0]].P()); + b2.AddPoint (points[face[1]].P()); + b2.AddPoint (points[face[2]].P()); + + 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 MiniElement2d & face = locfaces2.Get(i); + const Point3d & p1 = points[face[0]].P(); + const Point3d & p2 = points[face[1]].P(); + const Point3d & p3 = points[face[2]].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 pind = pindex.Get(i); + if (pind >= 1 && pind <= connectedpairs->Size ()) + { + for (j = 1; j <= connectedpairs->EntrySize(pind); j++) + { + int oi = connectedpairs->Get(pind, 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 (INDEX_2::Sort (i, other), 1); + } + } + } + } + } + + + /* + // add isolated points + 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 & grouppoints, + ARRAY & groupelements, + ARRAY & pindex, + ARRAY & findex) const +{ + static ARRAY pingroup; + int i, j, changed; + + pingroup.SetSize(points.Size()); + + pingroup = 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 MiniElement2d & face = faces.Get(i).Face(); + + int 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 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()) + { + int 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 MiniElement2d & 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; + } + */ +} + + +bool AdFront3 :: Inside (const Point<3> & 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 Point<3> & p1 = points[faces.Get(i).Face().PNum(1)].P(); + const Point<3> & p2 = points[faces.Get(i).Face().PNum(2)].P(); + const Point<3> & 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(0) - p1(0); + b.Elem(2) = p(1) - p1(1); + b.Elem(3) = p(2) - p1(2); + + 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) != 0); +} + + + + + +int AdFront3 :: SameSide (const Point<3> & lp1, const Point<3> & lp2, + const ARRAY * testfaces) const +{ + int i, ii, cnt; + + const Point<3> *line[2]; + line[0] = &lp1; + line[1] = &lp2; + + + cnt = 0; + + Point3d pmin(lp1); + Point3d pmax(lp1); + pmin.SetToMin (lp2); + pmax.SetToMax (lp2); + + static ARRAY 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 Point<3> *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/libsrc/meshing/adfront3.hpp b/libsrc/meshing/adfront3.hpp new file mode 100644 index 00000000..40d6eabb --- /dev/null +++ b/libsrc/meshing/adfront3.hpp @@ -0,0 +1,319 @@ +#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 +Point<3> 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 Point<3> & ap, PointIndex agi); + + /// + const Point<3> & 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; +}; + + + +class MiniElement2d +{ +protected: + int np; + PointIndex pnum[4]; + bool deleted; +public: + MiniElement2d () + { np = 3; deleted = 0; } + MiniElement2d (int anp) + { np = anp; deleted = 0; } + + int GetNP() const { return np; } + PointIndex & operator[] (int i) { return pnum[i]; } + const PointIndex operator[] (int i) const { return pnum[i]; } + + const PointIndex PNum (int i) const { return pnum[i-1]; } + PointIndex & PNum (int i) { return pnum[i-1]; } + const PointIndex PNumMod (int i) const { return pnum[(i-1)%np]; } + + void Delete () { deleted = 1; pnum[0] = pnum[1] = pnum[2] = pnum[3] = PointIndex::BASE-1; } + bool IsDeleted () const { return deleted; } +}; + + +inline ostream & operator<<(ostream & s, const MiniElement2d & el) +{ + s << "np = " << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + s << " " << el[j]; + return s; +} + + + + +/// Face in advancing front +class FrontFace +{ +private: + /// + MiniElement2d f; + /// + int qualclass; + /// + char oldfront; + /// + int hashvalue; + /// + int cluster; + +public: + /// + FrontFace (); + /// + FrontFace (const MiniElement2d & af); + /// + const MiniElement2d & 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 points; + /// +ARRAY faces; + /// +ARRAY delpointl; + + /// which points are connected to pi ? +TABLE * 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 > & apoints) const; + /// + int GetNP() const + { return points.Size(); } + /// + const Point<3> & GetPoint (PointIndex pi) const + { return points[pi].P(); } + /// + int GetNF() const + { return nff; } + /// + const MiniElement2d & 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 Point<3> & pmin, const Point<3> & pmax, + ARRAY & ifaces) const; + + /// + void GetFaceBoundingBox (int i, Box3d & box) const; + + /// + int GetLocals (int baseelement, + ARRAY & locpoints, + ARRAY & locfaces, // local index + ARRAY & pindex, + ARRAY & findex, + INDEX_2_HASHTABLE & connectedpairs, + float xh, + float relh, + INDEX& facesplit); + + /// + void GetGroup (int fi, + ARRAY & grouppoints, + ARRAY & groupelements, + ARRAY & pindex, + ARRAY & findex + ) const; + + /// + void DeleteFace (INDEX fi); + /// + PointIndex AddPoint (const Point<3> & p, PointIndex globind); + /// + INDEX AddFace (const MiniElement2d & e); + /// + INDEX AddConnectedPair (const INDEX_2 & pair); + /// + void IncrementClass (INDEX fi) + { faces.Elem(fi).IncrementQualClass(); } + + /// + void ResetClass (INDEX fi) + { faces.Elem(fi).ResetQualClass(); } + + /// + void SetStartFront (int baseelnp = 0); + + /// is Point p inside Surface ? + bool Inside (const Point<3> & p) const; + /// both points on same side ? + int SameSide (const Point<3> & lp1, const Point<3> & lp2, + const ARRAY * testfaces = NULL) const; + + + /// + PointIndex GetGlobalIndex (PointIndex pi) const + { return points[pi].GlobalIndex(); } + /// + double Volume () const + { return vol; } + + +private: + void RebuildInternalTables(); +}; + + + + +#endif diff --git a/libsrc/meshing/bisect.cpp b/libsrc/meshing/bisect.cpp new file mode 100644 index 00000000..cc8d0d2c --- /dev/null +++ b/libsrc/meshing/bisect.cpp @@ -0,0 +1,4051 @@ +#include +#include "meshing.hpp" + +#define noDEBUG + + +namespace netgen +{ + //#include "../interface/writeuser.hpp" + class MarkedTet; + class MarkedPrism; + class MarkedIdentification; + class MarkedTri; + class MarkedQuad; + + typedef MoveableArray T_MTETS; + typedef MoveableArray T_MPRISMS; + typedef MoveableArray T_MIDS; + typedef MoveableArray T_MTRIS; + typedef MoveableArray 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 + + char faceedges[4]; + // unsigned char faceedges[4]; + bool incorder; + unsigned int order:6; + + MarkedTet() + { + for (int i = 0; i < 4; i++) { faceedges[i] = 255; } + } + }; + + ostream & operator<< (ostream & ost, const MarkedTet & mt) + { + for(int i=0; i<4; i++) + ost << mt.pnums[i] << " "; + + ost << mt.matindex << " " << int(mt.marked) << " " << int(mt.flagged) << " " << int(mt.tetedge1) << " " << int(mt.tetedge2) << " "; + + ost << "faceedges = "; + for(int i=0; i<4; i++) + ost << int(mt.faceedges[i]) << " "; + + ost << " order = "; + ost << mt.incorder << " " << int(mt.order) << "\n"; + return ost; + } + istream & operator>> (istream & ost, MarkedTet & mt) + { + for(int i=0; i<4; i++) + ost >> mt.pnums[i]; + + ost >> mt.matindex; + + int auxint; + ost >> auxint; + mt.marked = auxint; + ost >> auxint; + mt.flagged = auxint; + ost >> auxint; + mt.tetedge1 = auxint; + ost >> auxint; + mt.tetedge2 = auxint; + + char auxchar; + + for(int i=0; i<4; i++) + { + ost >> auxchar; + mt.faceedges[i] = auxchar; + } + + ost >> mt.incorder; + ost >> auxint; + mt.order = auxint; + return ost; + } + + 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; + }; + + + ostream & operator<< (ostream & ost, const MarkedPrism & mp) + { + for(int i=0; i<6; i++) + ost << mp.pnums[i] << " "; + + ost << mp.matindex << " " << mp.marked << " " << mp.markededge << " " << mp.incorder << " " << int(mp.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedPrism & mp) + { + for(int i=0; i<6; i++) + ist >> mp.pnums[i]; + + ist >> mp.matindex >> mp.marked >> mp.markededge >> mp.incorder; + int auxint; + ist >> auxint; + mp.order = auxint; + return ist; + } + + + class MarkedIdentification + { + public: + // number of points of one face (3 or 4) + int np; + /// 6 or 8 point numbers + PointIndex pnums[8]; + /// marked for refinement + int marked; + /// edge starting with node k (0,1,2, or 3) + int markededge; + + bool incorder; + unsigned int order:6; + }; + + + ostream & operator<< (ostream & ost, const MarkedIdentification & mi) + { + ost << mi.np << " "; + for(int i=0; i<2*mi.np; i++) + ost << mi.pnums[i] << " "; + ost << mi.marked << " " << mi.markededge << " " << mi.incorder << " " << int(mi.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedIdentification & mi) + { + ist >> mi.np; + for(int i=0; i<2*mi.np; i++) + ist >> mi.pnums[i]; + ist >> mi.marked >> mi.markededge >> mi.incorder; + int auxint; + ist >> auxint; + mi.order = auxint; + return ist; + } + + + + + + 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; + }; + + ostream & operator<< (ostream & ost, const MarkedTri & mt) + { + for(int i=0; i<3; i++) + ost << mt.pnums[i] << " "; + for(int i=0; i<3; i++) + ost << mt.pgeominfo[i] << " "; + ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedTri & mt) + { + for(int i=0; i<3; i++) + ist >> mt.pnums[i]; + for(int i=0; i<3; i++) + ist >> mt.pgeominfo[i]; + ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder; + int auxint; + ist >> auxint; + mt.order = auxint; + return ist; + } + + + + class MarkedQuad + { + public: + /// point numbers + PointIndex pnums[4]; + /// + PointGeomInfo pgeominfo[4]; + /// marked for refinement + int marked; + /// marked edge: 0/2 = vertical, 1/3 = horizontal + int markededge; + /// surface id + int surfid; + + bool incorder; + unsigned int order:6; + }; + + ostream & operator<< (ostream & ost, const MarkedQuad & mt) + { + for(int i=0; i<4; i++) + ost << mt.pnums[i] << " "; + for(int i=0; i<4; i++) + ost << mt.pgeominfo[i] << " "; + ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedQuad & mt) + { + for(int i=0; i<4; i++) + ist >> mt.pnums[i]; + for(int i=0; i<4; i++) + ist >> mt.pgeominfo[i]; + ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder; + int auxint; + ist >> auxint; + mt.order = auxint; + return ist; + } + + + + + void PrettyPrint(ostream & ost, const MarkedTet & mt) + { + int te1 = mt.tetedge1; + int te2 = mt.tetedge2; + int order = mt.order; + + ost << "MT: " << mt.pnums[0] << " - " << mt.pnums[1] << " - " + << mt.pnums[2] << " - " << mt.pnums[3] << endl + << "marked edge: " << te1 << " - " << te2 + << ", order = " << order << endl; + //for (int k = 0; k < 4; k++) + // ost << int(mt.faceedges[k]) << " "; + for (int k = 0; k < 4; k++) + { + ost << "face"; + for (int j=0; j<4; j++) + if(j != k) + ost << " " << mt.pnums[j]; + for(int i=0; i<3; i++) + for(int j=i+1; j<4; j++) + if(i != k && j != k && int(mt.faceedges[k]) == 6-k-i-j) + ost << " marked edge " << mt.pnums[i] << " " << mt.pnums[j] << endl; + } + ost << endl; + } + + + + + int BTSortEdges (const Mesh & mesh, + const ARRAY< ARRAY* > & idmaps, + INDEX_2_CLOSED_HASHTABLE & edgenumber) + { + PrintMessage(4,"sorting ... "); + + // if (mesh.PureTetMesh()) + if (1) + { + // new, fast version + + ARRAY edges; + ARRAY eclasses; + + int i, j, k; + int cntedges = 0; + int go_on; + int ned(0); + + // 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] = NULL; + + 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(); + //(*testout) << "edge " << i2 << endl; + 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] = NULL; + + 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 + { + go_on = 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] = NULL; + 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); + go_on = 1; + } + else if (eclasses.Get(eclass2) > + eclasses.Get(eclass1)) + { + eclasses.Elem(eclass2) = + eclasses.Get(eclass1); + go_on = 1; + } + } + } + + for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el2d = mesh[sei]; + + for(i = 0; i < el2d.GetNP(); i++) + { + INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]); + e1.Sort(); + INDEX_2 e2; + + for(k = 0; k < idmaps.Size(); k++) + { + e2.I1() = (*idmaps[k])[e1.I1()]; + e2.I2() = (*idmaps[k])[e1.I2()]; + + if(e2.I1() == 0 || e2.I2() == 0 || + e1.I1() == e2.I1() || e1.I2() == e2.I2()) + continue; + + e2.Sort(); + if(!edgenumber.Used(e2)) + continue; + + + int eclass1 = edgenumber.Get (e1); + int eclass2 = edgenumber.Get (e2); + + if (eclasses.Get(eclass1) > + eclasses.Get(eclass2)) + { + eclasses.Elem(eclass1) = + eclasses.Get(eclass2); + + + go_on = 1; + } + else if (eclasses.Get(eclass2) > + eclasses.Get(eclass1)) + { + eclasses.Elem(eclass2) = + eclasses.Get(eclass1); + go_on = 1; + } + } + } + + } + + } + while (go_on); + +// 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 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 eclasstab(cntedges); + for (i = 1; i <= cntedges; i++) + eclasstab.Add1 (eclasses.Get(i), i); + + + // sort edges: + ARRAY 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); + } + } + return cnt; + } + + else + + { + // old version + + int i, j; + 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 go_on = 0; + do + { + go_on = 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); + go_on = 1; + } + if (used2 && !used1) + { + cnt++; + edgenumber.Set (e1, cnt); + go_on = 1; + } + } + } + } + while (go_on); + } + } + while (found); + + return cnt; + } + } + + + + + void BTDefineMarkedTet (const Element & el, + INDEX_2_CLOSED_HASHTABLE & 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; + int hi = 6 - k - i - j; + mt.faceedges[k] = char(hi); + } + } + } + } + + + + + void BTDefineMarkedPrism (const Element & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedPrism & mp) + { + int i, j; + + 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; + } + } + } + + + + bool BTDefineMarkedId(const Element2d & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + const ARRAY & idmap, + MarkedIdentification & mi) + { + + bool identified = true; + mi.np = el.GetNP(); + int min1(0),min2(0); + for(int j = 0; identified && j < mi.np; j++) + { + mi.pnums[j] = el[j]; + mi.pnums[j+mi.np] = idmap[el[j]]; + + if(j == 0 || el[j] < min1) + min1 = el[j]; + if(j == 0 || mi.pnums[j+mi.np] < min2) + min2 = mi.pnums[j+mi.np]; + + identified = (mi.pnums[j+mi.np] != 0 && mi.pnums[j+mi.np] != mi.pnums[j]); + } + + identified = identified && (min1 < min2); + + if(identified) + { + mi.marked = 0; + + mi.incorder = 0; + mi.order = 1; + + int val = 0; + for (int i = 0; i < mi.np; i++) + { + INDEX_2 i2(mi.pnums[i], mi.pnums[(i+1)%mi.np]); + i2.Sort(); + int hval = edgenumber.Get(i2); + if (hval > val) + { + val = hval; + mi.markededge = i; + } + } + } + + return identified; + } + + + void BTDefineMarkedTri (const Element2d & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedTri & mt) + { + int i, j; + 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 PrettyPrint(ostream & ost, const MarkedTri & mt) + { + ost << "MarkedTrig: " << endl; + ost << " pnums = "; for (int i=0; i<3; i++) ost << mt.pnums[i] << " "; ost << endl; + ost << " marked = " << mt.marked << ", markededge=" << mt.markededge << endl; + for(int i=0; i<2; i++) + for(int j=i+1; j<3; j++) + if(mt.markededge == 3-i-j) + ost << " marked edge pnums = " << mt.pnums[i] << " " << mt.pnums[j] << endl; + } + + + void PrettyPrint(ostream & ost, const MarkedQuad & mq) + { + ost << "MarkedQuad: " << endl; + ost << " pnums = "; for (int i=0; i<4; i++) ost << mq.pnums[i] << " "; ost << endl; + ost << " marked = " << mq.marked << ", markededge=" << mq.markededge << endl; + } + + + + + + void BTDefineMarkedQuad (const Element2d & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedQuad & mq) + { + int i; + for (i = 0; i < 4; i++) + mq.pnums[i] = el[i]; + Swap (mq.pnums[2], mq.pnums[3]); + + mq.marked = 0; + mq.markededge = 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 Point<3> & p1 = mesh.Point (mtets.Get(i).pnums[j]); + const Point<3> & 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 Point<3> & p1 = mesh.Point (mprisms.Get(i).pnums[j]); + const Point<3> & 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) + { +#ifdef DEBUG + *testout << "bisect tet " << oldtet << endl; +#endif + + 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; + +#ifdef DEBUG + *testout << "newtet1,before = " << newtet1 << endl; + *testout << "newtet2,before = " << newtet2 << endl; +#endif + + 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) + { + int hi = 6 - oldtet.tetedge1 - j - k; + newtet2.faceedges[oldtet.tetedge2] = char(hi); + } + else + newtet2.faceedges[oldtet.tetedge2] = oldtet.tetedge1; + +#ifdef DEBUG + *testout << "i = " << i << ", j = " << j << " k = " << k + << " oldtet.tetedge1 = " << oldtet.tetedge1 + << " oldtet.tetedge2 = " << oldtet.tetedge2 + << " 6-oldtet.tetedge1-j-k = " << 6 - oldtet.tetedge1 - j - k + << " 6-oldtet.tetedge1-j-k = " << short(6 - oldtet.tetedge1 - j - k) + << endl; + *testout << "vis1 = " << vis1 << ", vis2 = " << vis2 << endl; + for (int j = 0; j < 4; j++) + if (newtet2.faceedges[j] > 3) + { + *testout << "ERROR1" << endl; + } +#endif + } + + 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) + { + int hi = 6 - oldtet.tetedge2 - j - k; + newtet1.faceedges[oldtet.tetedge1] = char(hi); + } + else + newtet1.faceedges[oldtet.tetedge1] = oldtet.tetedge2; + +#ifdef DEBUG + for (int j = 0; j < 4; j++) + if (newtet2.faceedges[j] > 3) + { + *testout << "ERROR2" << endl; + } +#endif + } + } + + newtet1.matindex = oldtet.matindex; + newtet2.matindex = oldtet.matindex; + newtet1.incorder = 0; + newtet1.order = oldtet.order; + newtet2.incorder = 0; + newtet2.order = oldtet.order; + + *testout << "newtet1 = " << newtet1 << endl; + *testout << "newtet2 = " << newtet2 << endl; + } + + + + + void BTBisectPrism (const MarkedPrism & oldprism, int newp1, int newp2, + MarkedPrism & newprism1, MarkedPrism & newprism2) + { + int i; + + 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 BTBisectIdentification (const MarkedIdentification & oldid, + ARRAY & newp, + MarkedIdentification & newid1, + MarkedIdentification & newid2) + { + for(int i=0; i<2*oldid.np; i++) + { + newid1.pnums[i] = oldid.pnums[i]; + newid2.pnums[i] = oldid.pnums[i]; + } + newid1.np = newid2.np = oldid.np; + + if(oldid.np == 3) + { + newid1.pnums[(oldid.markededge+1)%3] = newp[0]; + newid1.pnums[(oldid.markededge+1)%3+3] = newp[1]; + newid1.markededge = (oldid.markededge+2)%3; + + newid2.pnums[oldid.markededge] = newp[0]; + newid2.pnums[oldid.markededge+3] = newp[1]; + newid2.markededge = (oldid.markededge+1)%3; + } + else if(oldid.np == 4) + { + newid1.pnums[(oldid.markededge+1)%4] = newp[0]; + newid1.pnums[(oldid.markededge+2)%4] = newp[2]; + newid1.pnums[(oldid.markededge+1)%4+4] = newp[1]; + newid1.pnums[(oldid.markededge+2)%4+4] = newp[3]; + newid1.markededge = (oldid.markededge+3)%4; + + newid2.pnums[oldid.markededge] = newp[0]; + newid2.pnums[(oldid.markededge+3)%4] = newp[2]; + newid2.pnums[oldid.markededge+4] = newp[1]; + newid2.pnums[(oldid.markededge+3)%4+4] = newp[3]; + newid2.markededge = (oldid.markededge+1)%4; + } + + + int nm = oldid.marked - 1; + if (nm < 0) nm = 0; + newid1.marked = newid2.marked = nm; + + newid1.incorder = newid2.incorder = 0; + newid1.order = newid2.order = oldid.order; + } + + + + void BTBisectTri (const MarkedTri & oldtri, int newp, const PointGeomInfo & newpgi, + MarkedTri & newtri1, MarkedTri & newtri2) + { + int i; + + 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; + + 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]; + } + +/* if (oldquad.marked==1) // he/sz: 2d quads or 3d prism + { + 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; + } + + else if (oldquad.marked==2) // he/sz: 2d quads only + { + newquad1.pnums[0] = newp1; + newquad1.pnums[1] = newp2; + newquad1.pnums[3] = oldquad.pnums[2]; + newquad1.pnums[2] = oldquad.pnums[0]; + newquad1.pgeominfo[0] = npgi1; + newquad1.pgeominfo[1] = npgi2; + newquad1.pgeominfo[3] = oldquad.pgeominfo[2]; + newquad1.pgeominfo[2] = oldquad.pgeominfo[0]; + + newquad2.pnums[0] = newp2; + newquad2.pnums[1] = newp1; + newquad2.pnums[3] = oldquad.pnums[1]; + newquad2.pnums[2] = oldquad.pnums[3]; + newquad2.pgeominfo[0] = npgi2; + newquad2.pgeominfo[1] = npgi1; + newquad2.pgeominfo[3] = oldquad.pgeominfo[1]; + newquad2.pgeominfo[2] = oldquad.pgeominfo[3]; + } + + */ + + if (oldquad.markededge==0 || oldquad.markededge==2) + { + 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; + } + else // 1 || 3 + { + newquad1.pnums[2] = newp1; + newquad1.pgeominfo[2] = npgi1; + newquad1.pnums[3] = newp2; + newquad1.pgeominfo[3] = npgi2; + + newquad2.pnums[0] = newp1; + newquad2.pgeominfo[0] = npgi1; + newquad2.pnums[1] = newp2; + newquad2.pgeominfo[1] = 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; + + if (nm==1) + { + newquad1.markededge=1; + newquad2.markededge=1; + } + else + { + newquad1.markededge=0; + newquad2.markededge=0; + } + + } + + + int MarkHangingIdentifications(T_MIDS & mids, + const INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int i, j; + + int hanging = 0; + for (i = 1; i <= mids.Size(); i++) + { + if (mids.Elem(i).marked) + { + hanging = 1; + continue; + } + + const int np = mids.Get(i).np; + + for(j = 0; j < np; j++) + { + INDEX_2 edge1(mids.Get(i).pnums[j], + mids.Get(i).pnums[(j+1) % np]); + INDEX_2 edge2(mids.Get(i).pnums[j+np], + mids.Get(i).pnums[((j+1) % np) + np]); + + edge1.Sort(); + edge2.Sort(); + if (cutedges.Used (edge1) || + cutedges.Used (edge2)) + { + mids.Elem(i).marked = 1; + hanging = 1; + } + } + } + + return hanging; + } + + + /* + void IdentifyCutEdges(Mesh & mesh, + INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int i,j,k; + + ARRAY< ARRAY* > idmaps; + for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + idmaps.Append(new ARRAY); + mesh.GetIdentifications().GetMap(i,*idmaps.Last()); + } + + + + for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el2d = mesh[sei]; + + for(i = 0; i < el2d.GetNP(); i++) + { + INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]); + e1.Sort(); + + if(!cutedges.Used(e1)) + continue; + + + for(k = 0; k < idmaps.Size(); k++) + { + INDEX_2 e2((*idmaps[k])[e1.I1()], + (*idmaps[k])[e1.I2()]); + + if(e2.I1() == 0 || e2.I2() == 0 || + e1.I1() == e2.I1() || e1.I2() == e2.I2()) + continue; + + e2.Sort(); + + if(cutedges.Used(e2)) + continue; + + Point3d np = Center(mesh.Point(e2.I1()), + mesh.Point(e2.I2())); + int newp = mesh.AddPoint(np); + cutedges.Set(e2,newp); + (*testout) << "DAAA" << endl; + } + } + } + + + for(i=0; i & 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 & 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 & 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 & 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; + mquads.Elem(i).markededge = 0; + hanging = 1; + continue; + } + + // he/sz: second case: split horizontally + INDEX_2 edge3(mquads.Get(i).pnums[1], + mquads.Get(i).pnums[3]); + INDEX_2 edge4(mquads.Get(i).pnums[2], + mquads.Get(i).pnums[0]); + + edge3.Sort(); + edge4.Sort(); + if (cutedges.Used (edge3) || + cutedges.Used (edge4)) + { + mquads.Elem(i).marked = 1; + mquads.Elem(i).markededge = 1; + hanging = 1; + continue; + } + + } + return hanging; + } + + + + void ConnectToNodeRec (int node, int tonode, + const TABLE & conto, ARRAY & 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_MIDS mids; + T_MTRIS mtris; + T_MQUADS mquads; + + + void WriteMarkedElements(ostream & ost) + { + ost << "Marked Elements\n"; + + ost << mtets.Size() << "\n"; + for(int i=0; i> auxstring; + + if(auxstring != "Marked") + return false; + + if(ist) + ist >> auxstring; + + if(auxstring != "Elements") + return false; + + int size; + + ist >> size; + mtets.SetSize(size); + for(int i=0; i> mtets[i]; + if(mtets[i].pnums[0] > mesh.GetNV() || + mtets[i].pnums[1] > mesh.GetNV() || + mtets[i].pnums[2] > mesh.GetNV() || + mtets[i].pnums[3] > mesh.GetNV()) + return false; + } + + ist >> size; + mprisms.SetSize(size); + for(int i=0; i> mprisms[i]; + + ist >> size; + mids.SetSize(size); + for(int i=0; i> mids[i]; + + ist >> size; + mtris.SetSize(size); + for(int i=0; i> mtris[i]; + + ist >> size; + mquads.SetSize(size); + for(int i=0; i> mquads[i]; + + return true; + } + + + + + + void BisectTetsCopyMesh (Mesh & mesh, const class CSGeometry *, + BisectionOptions & opt, + const ARRAY< ARRAY* > & idmaps, + const string & refinfofile) + { + mtets.SetName ("bisection, tets"); + mprisms.SetName ("bisection, prisms"); + mtris.SetName ("bisection, trigs"); + mquads.SetName ("bisection, quads"); + mids.SetName ("bisection, identifications"); + + //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; + */ + + bool readok = false; + + if(refinfofile != "") + { + PrintMessage(3,"Reading marked-element information from \"",refinfofile,"\""); + ifstream ist(refinfofile.c_str()); + + readok = ReadMarkedElements(ist,mesh); + + ist.close(); + } + + if(!readok) + { + PrintMessage(3,"resetting marked-element information"); + mtets.SetSize(0); + mprisms.SetSize(0); + mids.SetSize(0); + mtris.SetSize(0); + mquads.SetSize(0); + + + INDEX_2_HASHTABLE 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 edgenumber(np); + INDEX_2_CLOSED_HASHTABLE edgenumber(9*ne+4*nse); + + BTSortEdges (mesh, idmaps, 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); + } + + MarkedIdentification mi; + for(j=0; j0) + { + ostringstream str1,str2; + str1 << "copied " << mtets.Size() << " tets, " << mprisms.Size() << " prisms"; + str2 << " " << mtris.Size() << " trigs, " << mquads.Size() << " quads"; + + PrintMessage(4,str1.str()); + PrintMessage(4,str2.str()); + } + } + + + /* + void UpdateEdgeMarks2(Mesh & mesh, + const ARRAY< ARRAY* > & idmaps) + { + ARRAY< ARRAY*,PointIndex::BASE > mtets_old(mesh.GetNP()); + ARRAY< ARRAY*,PointIndex::BASE > mprisms_old(mesh.GetNP()); + ARRAY< ARRAY*,PointIndex::BASE > mids_old(mesh.GetNP()); + ARRAY< ARRAY*,PointIndex::BASE > mtris_old(mesh.GetNP()); + ARRAY< ARRAY*,PointIndex::BASE > mquads_old(mesh.GetNP()); + + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + + for(int i=0; iAppend(mtets[i]); + for(int i=0; iAppend(mprisms[i]); + for(int i=0; iAppend(mids[i]); + for(int i=0; iAppend(mtris[i]); + } + for(int i=0; iAppend(mquads[i]); + + + + 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); + mids.SetSize(0); + mtris.SetSize(0); + mquads.SetSize(0); + + + INDEX_2_HASHTABLE 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 edgenumber(np); + INDEX_2_CLOSED_HASHTABLE edgenumber(9*ne+4*nse); + + BTSortEdges (mesh, idmaps, 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; + + int oldind = -1; + for(l = 0; oldind < 0 && lSize(); l++) + if(el[1] == (*mtets_old[el[0]])[l].pnums[1] && + el[2] == (*mtets_old[el[0]])[l].pnums[2] && + el[3] == (*mtets_old[el[0]])[l].pnums[3]) + oldind = l; + + if(oldind >= 0) + mtets.Append((*mtets_old[el[0]])[oldind]); + else + { + 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); + } + + MarkedIdentification mi; + + + + for(j=0; jSize(); l++) + { + bool equal = true; + for(int m = 1; equal && m < mi.np; m++) + equal = (mi.pnums[m] == (*mids_old[el[0]])[l].pnums[m]); + if(equal) + oldind = l; + } + + if(oldind >= 0) + mids.Last() = (*mids_old[mi.pnums[0]])[oldind]; + } + + } + + + + for(int i=PointIndex::BASE; i* > & idmaps) + //const ARRAY < ARRAY* > & elements_before, + //const ARRAY < ARRAY* > & markedelts_num, + // const ARRAY < ARRAY* > & surfelements_before, + // const ARRAY < ARRAY* > & markedsurfelts_num) + { + T_MTETS mtets_old; mtets_old.Copy(mtets); + T_MPRISMS mprisms_old; mprisms_old.Copy(mprisms); + T_MIDS mids_old; mids_old.Copy(mids); + T_MTRIS mtris_old; mtris_old.Copy(mtris); + T_MQUADS mquads_old; mquads_old.Copy(mquads); + + + + + mtets.SetSize(0); + mprisms.SetSize(0); + mids.SetSize(0); + mtris.SetSize(0); + mquads.SetSize(0); + + //int nv = mesh.GetNV(); + + + INDEX_2_CLOSED_HASHTABLE edgenumber(9*mesh.GetNE()+4*mesh.GetNSE()); + + int maxnum = BTSortEdges (mesh, idmaps, edgenumber); + + for(int m = 0; m < mtets_old.Size(); m++) + { + MarkedTet & mt = mtets_old[m]; + + //(*testout) << "old mt " << mt; + + INDEX_2 edge (mt.pnums[mt.tetedge1],mt.pnums[mt.tetedge2]); + edge.Sort(); + if(edgenumber.Used(edge)) + { + int val = edgenumber.Get(edge); + //(*testout) << "set voledge " << edge << " from " << val; + if(val <= maxnum) + { + val += 2*maxnum; + edgenumber.Set(edge,val); + } + else if(val <= 2*maxnum) + { + val += maxnum; + edgenumber.Set(edge,val); + } + //(*testout) << " to " << val << endl; + } + + for(int k=0; k<4; k++) + for(int i=0; i<3; i++) + for(int j=i+1; i != k && j<4; j++) + if(j != k && int(mt.faceedges[k]) == 6-k-i-j) + { + edge[0] = mt.pnums[i]; + edge[1] = mt.pnums[j]; + edge.Sort(); + if(edgenumber.Used(edge)) + { + int val = edgenumber.Get(edge); + //(*testout) << "set faceedge " << edge << " from " << val; + if(val <= maxnum) + { + val += maxnum; + edgenumber.Set(edge,val); + } + //(*testout) << " to " << val << endl; + } + } + } + + + + + for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + //int pos = elements_before[el[0]]->Pos(el); + //int elnum = (pos >= 0) ? (*markedelts_num[el[0]])[pos] : -1; + + switch (el.GetType()) + { + case TET: + case TET10: + { + //if(elnum >= 0) + // { + // mtets.Append(mtets_old[elnum]); + // } + //else + // { + MarkedTet mt; + BTDefineMarkedTet (el, edgenumber, mt); + mt.matindex = el.GetIndex(); + + mtets.Append (mt); + + //(*testout) << "mtet " << mtets.Last() << endl; + break; + } + case PYRAMID: + { + cerr << "Refinement :: UpdateEdgeMarks not yet implemented for pyramids" + << endl; + break; + } + + case PRISM: + case PRISM12: + { + cerr << "Refinement :: UpdateEdgeMarks not yet implemented for prisms" + << endl; + break; + } + } + + } + + + + for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el = mesh[sei]; + + /* + for(int k=0; k<3; k++) + auxind3[k] = el[k]; + + auxind3.Sort(); + + int pos = oldfaces[auxind3[0]]->Pos(auxind3); + if(pos < 0) + cout << "UIUIUI" << endl; + */ + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + MarkedTri mt; + BTDefineMarkedTri (el, edgenumber, mt); + mtris.Append (mt); + break; + } + + case QUAD: + case QUAD6: + { + MarkedQuad mt; + BTDefineMarkedQuad (el, edgenumber, mt); + mquads.Append (mt); + break; + } + } + + + MarkedIdentification mi; + for(int j=0; jPos(el); + int elnum = (pos >= 0) ? (*markedsurfelts_num[el[0]])[pos] : -1; + + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + if(elnum >= 0) + mtris.Append(mtris_old[elnum]); + else + { + MarkedTri mt; + BTDefineMarkedTri (el, edgenumber, mt); + mtris.Append (mt); + (*testout) << "(new) "; + } + (*testout) << "mtri " << mtris.Last(); + break; + } + + case QUAD: + case QUAD6: + { + if(elnum >= 0) + mquads.Append(mquads_old[elnum]); + else + { + MarkedQuad mt; + BTDefineMarkedQuad (el, edgenumber, mt); + mquads.Append (mt); + } + break; + } + } + */ + } + + /* + for(int i=0; i * quality_loss) + { + PrintMessage(1,"Mesh bisection"); + PushStatus("Mesh bisection"); + + static int localizetimer = NgProfiler::CreateTimer("localize edgepoints"); + NgProfiler::RegionTimer * loct = new NgProfiler::RegionTimer(localizetimer); + LocalizeEdgePoints(mesh); + delete loct; + + ARRAY< ARRAY* > idmaps; + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + idmaps.Append(new ARRAY); + mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true); + } + } + + + string refelementinfofileread = ""; + string refelementinfofilewrite = ""; + + if(opt.refinementfilename) + { + ifstream inf(opt.refinementfilename); + string st; + inf >> st; + if(st == "refinementinfo") + { + while(inf) + { + while(inf && st != "markedelementsfile") + inf >> st; + + if(inf) + inf >> st; + + if(st == "read" && inf) + ReadEnclString(inf,refelementinfofileread,'\"'); + else if(st == "write" && inf) + ReadEnclString(inf,refelementinfofilewrite,'\"'); + } + } + inf.close(); + } + + + + if (mesh.mglevels == 1 || idmaps.Size() > 0) + BisectTetsCopyMesh(mesh, NULL, opt, idmaps, refelementinfofileread); + + + 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 ox,oy,oz; + for (ElementIndex ei = 0; ei < ne; ei++) + if (mesh[ei].TestRefinementFlag()) + { + mesh[ei].GetOrder(ox,oy,oz); + mesh[ei].SetOrder (ox+1,oy+1,oz+1); + if (mesh[ei].TestStrongRefinementFlag()) + mesh[ei].SetOrder (ox+2,oy+2,oz+2); + } + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + if (mesh[sei].TestRefinementFlag()) + { + mesh[sei].GetOrder(ox,oy); + mesh[sei].SetOrder(ox+1,oy+1); + if (mesh[sei].TestStrongRefinementFlag()) + mesh[sei].SetOrder(ox+2,oy+2); + } + + /* + #ifndef SABINE //Nachbarelemente mit ordx,ordy,ordz + + ARRAY 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); + + #endif + */ + + PopStatus(); + return; + } + + + + // INDEX_2_HASHTABLE cutedges(10 + 5 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size())); + INDEX_2_CLOSED_HASHTABLE cutedges(10 + 9 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size())); + + bool noprojection = false; + + for (l = 1; l <= 1; l++) + { + int marked = 0; + if (opt.refinementfilename) + { + ifstream inf(opt.refinementfilename); + PrintMessage(3,"load refinementinfo from file ",opt.refinementfilename); + + string st; + inf >> st; + if(st == "refinementinfo") + // new version + { + for(i=1; i<=mtets.Size(); i++) + mtets.Elem(i).marked = 0; + for(i=1; i<=mprisms.Size(); i++) + mprisms.Elem(i).marked = 0; + for(i=1; i<=mtris.Size(); i++) + mtris.Elem(i).marked = 0; + for(i=1; i<=mquads.Size(); i++) + mquads.Elem(i).marked = 0; + for(i=1; i<=mprisms.Size(); i++) + mids.Elem(i).marked = 0; + + inf >> st; + while(inf) + { + if(st[0] == '#') + { + inf.ignore(10000,'\n'); + inf >> st; + } + else if(st == "markedelementsfile") + { + inf >> st; + ReadEnclString(inf,st,'\"'); + inf >> st; + } + else if(st == "noprojection") + { + noprojection = true; + inf >> st; + } + else if(st == "refine") + { + inf >> st; + if(st == "elements") + { + inf >> st; + bool isint = true; + for(string::size_type ii=0; isint && ii> st; + isint = true; + for(string::size_type ii=0; isint && ii> bounds[i]; + + int cnt = 0; + + for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + // + Point<3> center(0,0,0); + for(i=0; i 0) + marked = 1; + + + inf >> st; + } + else + { + throw NgException("something wrong with refinementinfo file"); + } + } + } + } + else + { + inf.close(); + inf.open(opt.refinementfilename); + + char ch; + for (i = 1; i <= mtets.Size(); i++) + { + inf >> ch; + if(!inf) + throw NgException("something wrong with refinementinfo file (old format)"); + mtets.Elem(i).marked = (ch == '1'); + } + marked = 1; + } + inf.close(); + } + + 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; + */ + + if (printmessage_importance>0) + { + ostringstream str; + str << "marked elements: " << cntm; + PrintMessage(4,str.str()); + } + + 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++; + // 2d: marked=2, 3d prisms: marked=1 + mquads.Elem(cntquad).marked = + mesh.SurfaceElement(i).TestRefinementFlag() ? 4-mesh.GetDimension() : 0 ; + // mquads.Elem(cntquad).marked = 0; + if (mquads.Elem(cntquad).marked) + cntm++; + } + } + + if (printmessage_importance>0) + { + ostringstream str; + str << "with surface-elements: " << cntm; + PrintMessage(4,str.str()); + } + + // he/sz: das wird oben schon richtig gemacht. + // hier sind die quads vergessen! + /* + 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; + + + //(*testout) << "mtets " << mtets << endl; + + if (opt.refine_p) + { + PrintMessage(3,"refine p"); + + 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) + { + PrintMessage(3,"refine hp"); + 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); + } + /* + for ( i=1; i<= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for(int j=1; j<=sel.GetNP(); j++) + singv.Set(sel.PNum(j)); + } + */ + } + else + { + // vertices with 2 different bnds + ARRAY bndind(np); + bndind = 0; + for (i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + for (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; + + //cout << "write?" << endl; + //string yn; + //cin >> yn; + + (*testout) << "refine volume elements" << endl; + 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); + //if(yn == "y") + // (*testout) << "bisected tet " << oldtet; + INDEX_2 edge(oldtet.pnums[oldtet.tetedge1], + oldtet.pnums[oldtet.tetedge2]); + edge.Sort(); + if (cutedges.Used (edge)) + { + newp = cutedges.Get(edge); + } + else + { + Point<3> npt = Center (mesh.Point (edge.I1()), + mesh.Point (edge.I2())); + newp = mesh.AddPoint (npt); + cutedges.Set (edge, newp); + } + + BTBisectTet (oldtet, newp, newtet1, newtet2); + + mtets.Elem(i) = newtet1; + mtets.Append (newtet2); + +#ifdef DEBUG + *testout << "tet1 has elnr = " << i << ", tet2 has elnr = " << mtets.Size() << endl; +#endif + //if(yn == "y") + // (*testout) << "and got " << newtet1 << "and " << newtet2 << endl; + + mesh.mlparentelement.Append (i); + } + + 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 + { + Point<3> npt = Center (mesh.Point (edge1.I1()), + mesh.Point (edge1.I2())); + newp1 = mesh.AddPoint (npt); + cutedges.Set (edge1, newp1); + } + if (cutedges.Used (edge2)) + newp2 = cutedges.Get(edge2); + else + { + Point<3> npt = Center (mesh.Point (edge2.I1()), + mesh.Point (edge2.I2())); + newp2 = mesh.AddPoint (npt); + cutedges.Set (edge2, newp2); + } + + + BTBisectPrism (oldprism, newp1, newp2, newprism1, newprism2); + //if(yn == "y") + // (*testout) << "bisected prism " << oldprism << "and got " << newprism1 << "and " << newprism2 << endl; + mprisms.Elem(i) = newprism1; + mprisms.Append (newprism2); + } + + int nid = mids.Size(); + for (i = 1; i <= nid; i++) + if (mids.Elem(i).marked) + { + MarkedIdentification oldid,newid1,newid2; + ARRAY newp; + + oldid = mids.Get(i); + + ARRAY edges; + edges.Append(INDEX_2(oldid.pnums[oldid.markededge], + oldid.pnums[(oldid.markededge+1)%oldid.np])); + edges.Append(INDEX_2(oldid.pnums[oldid.markededge + oldid.np], + oldid.pnums[(oldid.markededge+1)%oldid.np + oldid.np])); + + if(oldid.np == 4) + { + edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np], + oldid.pnums[(oldid.markededge+3)%oldid.np])); + edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np + oldid.np], + oldid.pnums[(oldid.markededge+3)%oldid.np + oldid.np])); + } + for (j = 0; j < edges.Size(); j++) + { + edges[j].Sort(); + + if(cutedges.Used(edges[j])) + newp.Append(cutedges.Get(edges[j])); + else + { + Point<3> npt = Center (mesh.Point (edges[j].I1()), + mesh.Point (edges[j].I2())); + newp.Append(mesh.AddPoint(npt)); + cutedges.Set(edges[j],newp[j]); + } + } + + BTBisectIdentification(oldid,newp,newid1,newid2); + mids.Elem(i) = newid1; + mids.Append(newid2); + } + + + //IdentifyCutEdges(mesh, cutedges); + + + hangingvol = + MarkHangingTets (mtets, cutedges) + + MarkHangingPrisms (mprisms, cutedges) + + MarkHangingIdentifications (mids, cutedges); + + + int nsel = mtris.Size(); + + for (i = 1; i <= nsel; i++) + if (mtris.Elem(i).marked) + { + MarkedTri oldtri; + MarkedTri newtri1, newtri2; + PointIndex 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 + { + Point<3> npt = Center (mesh.Point (edge.I1()), + mesh.Point (edge.I2())); + newp = mesh.AddPoint (npt); + cutedges.Set (edge, newp); + } + // newp = cutedges.Get(edge); + + int si = mesh.GetFaceDescriptor (oldtri.surfid).SurfNr(); + // geom->GetSurface(si)->Project (mesh.Point(newp)); + PointGeomInfo npgi; + +// cerr << "project point " << newp << " old: " << mesh.Point(newp); + if (mesh[newp].Type() != 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); +// cerr << " new: " << mesh.Point(newp) << endl; + + BTBisectTri (oldtri, newp, npgi, newtri1, newtri2); + //if(yn == "y") + // (*testout) << "bisected tri " << oldtri << "and got " << newtri1 << "and " << newtri2 << endl; + + + 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]); + */ + INDEX_2 edge1, edge2; + PointGeomInfo pgi11, pgi12, pgi21, pgi22; + if (oldquad.markededge==0 || oldquad.markededge==2) + { + edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0]; + edge1.I2()=oldquad.pnums[1]; pgi12=oldquad.pgeominfo[1]; + edge2.I1()=oldquad.pnums[2]; pgi21=oldquad.pgeominfo[2]; + edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3]; + } + else // 3 || 1 + { + edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0]; + edge1.I2()=oldquad.pnums[2]; pgi12=oldquad.pgeominfo[2]; + edge2.I1()=oldquad.pnums[1]; pgi21=oldquad.pgeominfo[1]; + edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3]; + } + + edge1.Sort(); + edge2.Sort(); + + if (cutedges.Used (edge1)) + { + newp1 = cutedges.Get(edge1); + } + else + { + Point<3> np1 = Center (mesh.Point (edge1.I1()), + mesh.Point (edge1.I2())); + newp1 = mesh.AddPoint (np1); + cutedges.Set (edge1, newp1); + } + + if (cutedges.Used (edge2)) + { + newp2 = cutedges.Get(edge2); + } + else + { + Point<3> np2 = Center (mesh.Point (edge2.I1()), + mesh.Point (edge2.I2())); + newp2 = mesh.AddPoint (np2); + 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) +// cerr << "project point 1 " << newp1 << " old: " << mesh.Point(newp1); + PointBetween (mesh.Point (edge1.I1()), mesh.Point (edge1.I2()), + 0.5, si, + pgi11, + pgi12, + mesh.Point (newp1), npgi1); +// (*testout) +// cerr << " new: " << mesh.Point(newp1) << endl; + + +// cerr << "project point 2 " << newp2 << " old: " << mesh.Point(newp2); + PointBetween (mesh.Point (edge2.I1()), mesh.Point (edge2.I2()), + 0.5, si, + pgi21, + pgi22, + mesh.Point (newp2), npgi2); +// cerr << " new: " << mesh.Point(newp2) << endl; + + + 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; + + +// +// cerr << "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); +// cerr << " to " << mesh.Point (newpi) << endl; + + + nseg1.epgeominfo[1] = newepgi; + nseg2.epgeominfo[0] = newepgi; + + mesh.LineSegment (i) = nseg1; + mesh.AddSegment (nseg2); + } + } + } + while (hangingvol || hangingsurf || hangingedge); + + if (printmessage_importance>0) + { + ostringstream strstr; + strstr << mtets.Size() << " tets" << endl + << mtris.Size() << " trigs" << endl; + if (mprisms.Size()) + { + strstr << mprisms.Size() << " prisms" << endl + << mquads.Size() << " quads" << endl; + } + strstr << mesh.GetNP() << " points"; + PrintMessage(4,strstr.str()); + + } + } + + + // (*testout) << "mtets = " << mtets << endl; + + if (opt.refine_hp) + { + // + ARRAY 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 (int(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 (int(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 (int(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 (int(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()); + mids.SetAllocSize (mids.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) + { + PrintMessage(4,"RESETTING mlbetweennodes"); + 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; + } + */ + + BitArray isnewpoint(np); + isnewpoint.Clear(); + + for (i = 1; i <= cutedges.Size(); i++) + if (cutedges.UsedPos(i)) + { + INDEX_2 edge; + int newpi; + cutedges.GetData (i, edge, newpi); + isnewpoint.Set(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 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(); + + + + // update identification tables + for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) + { + ARRAY 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); + } + } + } + + + + + // Repair works only for tets! + bool do_repair = mesh.PureTetMesh (); + + //if(mesh.mglevels == 3) + // noprojection = true; + + //noprojection = true; + + if(noprojection) + { + do_repair = false; + for(int ii=1; ii<=mesh.GetNP(); ii++) + { + if(isnewpoint.Test(ii) && mesh.mlbetweennodes[ii][0] > 0) + { + mesh.Point(ii) = Center(mesh.Point(mesh.mlbetweennodes[ii][0]),mesh.Point(mesh.mlbetweennodes[ii][1])); + } + } + } + + + // Check/Repair + + //cout << "Hallo Welt" << endl; + //getchar(); + + static bool repaired_once; + if(mesh.mglevels == 1) + repaired_once = false; + + //mesh.Save("before.vol"); + + static int reptimer = NgProfiler::CreateTimer("check/repair"); + NgProfiler::RegionTimer * regt(NULL); + regt = new NgProfiler::RegionTimer(reptimer); + + ARRAY bad_elts; + ARRAY pure_badness; + + if(do_repair || quality_loss != NULL) + { + pure_badness.SetSize(mesh.GetNP()+2); + GetPureBadness(mesh,pure_badness,isnewpoint); + } + + + if(do_repair) + { + const double max_worsening = 1; + + const bool uselocalworsening = false; + + bool repaired = false; + + Validate(mesh,bad_elts,pure_badness,max_worsening,uselocalworsening); + + if (printmessage_importance>0) + { + ostringstream strstr; + for(int ii=0; ii 0) + { + clock_t t1(clock()); + + + // update id-maps + j=0; + for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + mesh.GetIdentifications().GetMap(i,*idmaps[j],true); + j++; + } + } + + + // do the repair + try + { + RepairBisection(mesh,bad_elts,isnewpoint,*this, + pure_badness, + max_worsening,uselocalworsening, + idmaps); + repaired = true; + repaired_once = true; + } + catch(NgException & ex) + { + PrintMessage(1,string("Problem: ") + ex.What()); + } + + + if (printmessage_importance>0) + { + ostringstream strstr; + strstr << "Time for Repair: " << double(clock() - t1)/double(CLOCKS_PER_SEC) << endl + << "bad elements after repair: " << bad_elts << endl; + PrintMessage(1,strstr.str()); + } + + if(quality_loss != NULL) + Validate(mesh,bad_elts,pure_badness,1e100,uselocalworsening,quality_loss); + + if(idmaps.Size() == 0) + UpdateEdgeMarks(mesh,idmaps); + + /* + if(1==1) + UpdateEdgeMarks(mesh,idmaps); + else + mesh.mglevels = 1; + */ + + //mesh.ImproveMesh(); + + } + } + delete regt; + + + + + + + + for(i=0; i & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) + { + newp = p1+secpoint*(p2-p1); + } + + void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) + { + newp = p1+secpoint*(p2-p1); + } + + + Vec<3> Refinement :: GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const + { + cerr << "Refinement::GetTangent not overloaded" << endl; + return Vec<3> (0,0,0); + } + + Vec<3> Refinement :: GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const + { + cerr << "Refinement::GetNormal not overloaded" << endl; + return Vec<3> (0,0,0); + } + + + void Refinement :: ProjectToSurface (Point<3> & p, int surfi) + { + if (printmessage_importance>0) + cerr << "Refinement :: ProjectToSurface ERROR: no geometry set" << endl; + }; + + void Refinement :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const + { + cerr << "Refinement::ProjectToEdge not overloaded" << endl; + } +} diff --git a/libsrc/meshing/bisect.hpp b/libsrc/meshing/bisect.hpp new file mode 100644 index 00000000..9ae0b1de --- /dev/null +++ b/libsrc/meshing/bisect.hpp @@ -0,0 +1,99 @@ +#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 +{ + MeshOptimize2d * optimizer2d; + +public: + Refinement (); + virtual ~Refinement (); + + void Refine (Mesh & mesh); + void Bisect (Mesh & mesh, class BisectionOptions & opt, ARRAY * quality_loss = NULL); + void MakeSecondOrder (Mesh & mesh); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi); + + virtual Vec<3> GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & egi) const; + + virtual Vec<3> GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const; + + + virtual void ProjectToSurface (Point<3> & p, int surfi); + + virtual void ProjectToSurface (Point<3> & p, int surfi, const PointGeomInfo & /* gi */) + { + ProjectToSurface (p, surfi); + } + + virtual void ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const; + + + void ValidateSecondOrder (Mesh & mesh); + void ValidateRefinedMesh (Mesh & mesh, + ARRAY & parents); + + MeshOptimize2d * Get2dOptimizer(void) + { + return optimizer2d; + } + void Set2dOptimizer(MeshOptimize2d * opti) + { + optimizer2d = opti; + } + + + virtual void LocalizeEdgePoints(Mesh & /* mesh */) const {;} +}; + +#endif diff --git a/libsrc/meshing/boundarylayer.cpp b/libsrc/meshing/boundarylayer.cpp new file mode 100644 index 00000000..1dd34038 --- /dev/null +++ b/libsrc/meshing/boundarylayer.cpp @@ -0,0 +1,92 @@ +#include +#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 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(QUAD); + 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/libsrc/meshing/boundarylayer.hpp b/libsrc/meshing/boundarylayer.hpp new file mode 100644 index 00000000..e5a047b6 --- /dev/null +++ b/libsrc/meshing/boundarylayer.hpp @@ -0,0 +1,9 @@ +#ifndef FILE_BOUNDARYLAYER +#define FILE_BOUNDARYLAYER + + +/// +extern void InsertVirtualBoundaryLayer (Mesh & mesh); + + +#endif diff --git a/libsrc/meshing/classifyhpel.hpp b/libsrc/meshing/classifyhpel.hpp new file mode 100644 index 00000000..96bf1b62 --- /dev/null +++ b/libsrc/meshing/classifyhpel.hpp @@ -0,0 +1,1713 @@ +HPREF_ELEMENT_TYPE ClassifyTet(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint) +{ + int ep1(0), ep2(0), ep3(0), ep4(0), cp1(0), cp2(0), cp3(0), cp4(0), fp1, fp2, fp3, fp4; + int isedge1(0), isedge2(0), isedge3(0), isedge4(0), isedge5(0), isedge6(0); + int isfedge1, isfedge2, isfedge3, isfedge4, isfedge5, isfedge6; + int isface1(0), isface2(0), isface3(0), isface4(0); + + HPREF_ELEMENT_TYPE type = HP_NONE; + + + int debug = 0; + for (int j = 0;j < 4; j++) + { + if (el.pnums[j] == 444) debug++; + if (el.pnums[j] == 115) debug++; + if (el.pnums[j] == 382) debug++; + if (el.pnums[j] == 281) debug++; + } + if (debug < 4) debug = 0; + + + + 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.pnums[j]); + ep2 = edgepoint.Test (el.pnums[k]); + ep3 = edgepoint.Test (el.pnums[pi3]); + ep4 = edgepoint.Test (el.pnums[pi4]); + + cp1 = cornerpoint.Test (el.pnums[j]); + cp2 = cornerpoint.Test (el.pnums[k]); + cp3 = cornerpoint.Test (el.pnums[pi3]); + cp4 = cornerpoint.Test (el.pnums[pi4]); + + isedge1 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[k])); + isedge2 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi3])); + isedge3 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi4])); + isedge4 = edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi3])); + isedge5 = edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi4])); + isedge6 = edges.Used (INDEX_2::Sort (el.pnums[pi3], el.pnums[pi4])); + + if (debug) + { + cout << "debug" << endl; + *testout << "debug" << endl; + *testout << "ep = " << ep1 << ep2 << ep3 << ep4 << endl; + *testout << "cp = " << cp1 << cp2 << cp3 << cp4 << endl; + *testout << "edge = " << isedge1 << isedge2 << isedge3 << isedge4 << isedge5 << isedge6 << endl; + } + + + isface1 = isface2 = isface3 = isface4 = 0; + for (int l = 0; l < 4; l++) + { + INDEX_3 i3(0,0,0); + switch (l) + { + case 0: i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi3]; i3.I1() = el.pnums[pi4]; break; + case 1: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[pi3]; i3.I1() = el.pnums[pi4]; break; + case 2: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi4]; break; + case 3: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[k]; i3.I1() = el.pnums[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.pnums[k], el.pnums[pi3], el.pnums[pi4])); + isface2 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[pi3], el.pnums[pi4])); + isface3 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[k], el.pnums[pi4])); + isface4 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[k], el.pnums[pi3])); + */ + + isfedge1 = isfedge2 = isfedge3 = isfedge4 = isfedge5 = isfedge6 = 0; + for (int l = 0; l < 6; l++) + { + INDEX_2 i2(0,0); + switch (l) + { + case 0: i2.I1() = el.pnums[j]; i2.I2() = el[k]; break; + case 1: i2.I1() = el.pnums[j]; i2.I2() = el.pnums[pi3]; break; + case 2: i2.I1() = el.pnums[j]; i2.I2() = el.pnums[pi4]; break; + case 3: i2.I1() = el.pnums[k]; i2.I2() = el.pnums[pi3]; break; + case 4: i2.I1() = el.pnums[k]; i2.I2() = el.pnums[pi4]; break; + case 5: i2.I1() = el.pnums[pi3]; i2.I2() = el.pnums[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.pnums[j], el.pnums[k])); + isfedge2 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi3])); + isfedge3 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi4])); + isfedge4 = face_edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi3])); + isfedge5 = face_edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi4])); + isfedge6 = face_edges.Used (INDEX_2::Sort (el.pnums[pi3], el.pnums[pi4])); + */ + + fp1 = fp2 = fp3 = fp4 = 0; + for (int l = 0; l < 4; l++) + { + int pti(0); + switch (l) + { + case 0: pti = el.pnums[j]; break; + case 1: pti = el.pnums[k]; break; + case 2: pti = el.pnums[pi3]; break; + case 3: pti = el.pnums[pi4]; break; + } + int domnr = facepoint[pti]; + 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.pnums[j]] != 0; + fp2 = facepoint[el.pnums[k]] != 0; + fp3 = facepoint[el.pnums[pi3]] != 0; + fp4 = facepoint[el.pnums[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; + } + break; + } + 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: // two singular faces + { + 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) + { + int pnums[4]; + pnums[0] = el.pnums[j]; + pnums[1] = el.pnums[k]; + pnums[2] = el.pnums[pi3]; + pnums[3] = el.pnums[pi4]; + for(k=0;k<4;k++) el.pnums[k] = pnums[k]; + break; + } + } + + + if (debug) cout << "type = " << type << endl; + + 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 + << "isface = " << isface1 << isface2 << isface3 << isface4 << endl; + cout << "undefined element !!! " << endl; + + + } + return(type); +} + + + +HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint) +{ + + HPREF_ELEMENT_TYPE type = HP_NONE; + + int p[6]; + for(int m=1;m<=6;m++) + { + int point_sing[6]={0,0,0,0,0,0}; + int face_sing[5]={0,0,0,0,0}; + int edge_sing[9]={0,0,0,0,0,0,0,0,0}; + + if(m<4) + { + p[0]= m; p[1]=m%3+1; p[2]=(m%3+1)%3+1; + for(int l=3;l<6;l++) p[l]=p[l-3]+3; + } + else + { + p[0] = m; p[1]=(m%3+1)%3+4; p[2]=m%3+4; + for(int l=3;l<6;l++) p[l]=p[l-3]-3; + } + + for(int j=0;j<6;j++) + { + if(cornerpoint.Test(el.PNum(p[j]))) { point_sing[p[j]-1]=3;} + else if(edgepoint.Test(el.PNum(p[j]))) point_sing[p[j]-1]=2; + else if (facepoint[el.PNum(p[j])] == -1 || facepoint[el.PNum(p[j])] == el.GetIndex()) + point_sing[p[j]-1] = 1; + } + + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (PRISM); + for(int k=0;k<9;k++) + { + INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); + if (edges.Used(i2)) edge_sing[k] = 2; + else edge_sing[k] = face_edges.Used(i2); + } + + const ELEMENT_FACE * elfaces = MeshTopology::GetFaces (PRISM); + for (int k=0;k<5;k++) + { + INDEX_3 i3; + + if(k<2) + i3 = INDEX_3::Sort(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], + el.pnums[p[elfaces[k][2]-1]-1]); + else + { + INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + } + + if (faces.Used (i3)) + { + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + face_sing[k] = 1; + + } + } + if (face_sing[1] > face_sing[0]) {m=m+2; continue;} + + + //int cp = 0; + + int qfsing = face_sing[2] + face_sing[3] + face_sing[4]; + int tfsing = face_sing[0] + face_sing[1]; + int evsing = edge_sing[6] + edge_sing[7] + edge_sing[8]; + int ehsing = edge_sing[0] + edge_sing[1] + edge_sing[2] + edge_sing[3] + edge_sing[4] + edge_sing[5]; + + if (qfsing + tfsing + evsing + ehsing == 0) + { type = HP_PRISM; break;} + + HPREF_ELEMENT_TYPE types[] = {HP_NONE,HP_NONE,HP_NONE}; + + int fb = (1-face_sing[4])* face_sing[3] * (face_sing[2] + face_sing[3]) + 3*face_sing[4]*face_sing[3]*face_sing[2]; + int sve[3] = {edge_sing[7] , edge_sing[8], edge_sing[6]}; + + + if(fb!=qfsing) continue; + + + switch(fb) + { + case 0: + if (evsing == 0 && ehsing==3*tfsing) + { + types[0] = HP_PRISM; + types[1] = HP_PRISM_1FA_0E_0V; + types[2] = HP_PRISM_2FA_0E_0V; + } + if(evsing > 0 && sve[0] == evsing) // 1 vertical edge 1-4 + { + types[0] = HP_PRISM_SINGEDGE; + types[1] = HP_PRISM_1FA_1E_0V; + types[2] = HP_PRISM_2FA_1E_0V; + } + + if(sve[0] > 0 && sve[1] > 0 && sve[2] == 0) + { + types[0] = HP_PRISM_SINGEDGE_V12; + types[1] = HP_PRISM_1FA_2E_0V; + types[2] = HP_PRISM_2FA_2E_0V; + } + if(sve[0] > 0 && sve[1] > 0 && sve[2] > 0) + { + types[0] = HP_PRISM_3E_0V; + types[1] = HP_PRISM_1FA_3E_0V; + types[2] = HP_PRISM_2FA_3E_0V; + + if ( edge_sing[0] > 1 && edge_sing[2] > 1 && + edge_sing[4] > 1 && edge_sing[5] > 1 && tfsing==0) + types[0] = HP_PRISM_3E_4EH; + } + + break; + case 1: + if(sve[0] <= 1 && sve[1] <= 1) + if(sve[2]==0) + { + types[0] = HP_PRISM_1FB_0E_0V; + types[1] = HP_PRISM_1FA_1FB_0E_0V; + types[2] = HP_PRISM_2FA_1FB_0E_0V; + } + else + { + types[0] = HP_PRISM_1FB_1EC_0V; + types[1] = HP_PRISM_1FA_1FB_1EC_0V; + types[2] = HP_PRISM_2FA_1FB_1EC_0V; + } + + if(sve[0] > 1 && sve[2] >= 1 && sve[1] <= 1) + { + types[0] = HP_PRISM_1FB_2EB_0V; + types[1] = HP_PRISM_1FA_1FB_2EB_0V; + types[2] = HP_PRISM_2FA_1FB_2EB_0V; + } + + if(sve[0] > 1 && sve[1] <= 1 && sve[2] == 0) // ea && !eb + { + types[0] = HP_PRISM_1FB_1EA_0V; + types[1] = HP_PRISM_1FA_1FB_1EA_0V; + types[2] = HP_PRISM_2FA_1FB_1EA_0V; + } + + if(sve[0] <= 1 && sve[1] > 1 && sve[2] == 0) + types[1] = HP_PRISM_1FA_1FB_1EB_0V; + + if(sve[0] > 1 && sve[1]>1) + if(sve[2] == 0) // ea && eb + { + types[0] = HP_PRISM_1FB_2EA_0V; + types[1] = HP_PRISM_1FA_1FB_2EA_0V; + types[2] = HP_PRISM_2FA_1FB_2EA_0V; + } + if(sve[0] <= 1 && sve[1] > 1 && sve[2] >0) + types[1] = HP_PRISM_1FA_1FB_2EC_0V; + + if(sve[0] > 1 && sve[1] > 1 && sve[2] >= 1) //sve[2] can also be a face-edge + { + types[0] = HP_PRISM_1FB_3E_0V; + types[1] = HP_PRISM_1FA_1FB_3E_0V; + types[2] = HP_PRISM_2FA_1FB_3E_0V; + } + + break; + + case 2: + if(sve[0] <= 1) + cout << " **** WARNING: Edge between to different singular faces should be marked singular " << endl; + + if(sve[1] <= 1) + if(sve[2] <=1) + { + types[0] = HP_PRISM_2FB_0E_0V; + types[1] = HP_PRISM_1FA_2FB_0E_0V; + types[2] = HP_PRISM_2FA_2FB_0E_0V; + } + else + { + types[0] = HP_PRISM_2FB_1EC_0V; + types[1] = HP_PRISM_1FA_2FB_1EC_0V; + types[2] = HP_PRISM_2FA_2FB_1EC_0V; + } + else + if(sve[2] <= 1) + types[1] = HP_PRISM_1FA_2FB_1EB_0V; + else + { + types[0] = HP_PRISM_2FB_3E_0V; + types[1] = HP_PRISM_1FA_2FB_3E_0V; + types[2] = HP_PRISM_2FA_2FB_3E_0V; + } + + break; + + case 3: + types[0] = HP_PRISM_3FB_0V; + types[1] = HP_PRISM_1FA_3FB_0V; + types[2] = HP_PRISM_2FA_3FB_0V; + break; + } + type = types[tfsing]; + + + if(type != HP_NONE) + break; + } + + /* + *testout << " Prism with pnums " << endl; + for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; + *testout << endl; + */ + + if(type != HP_NONE) + { + int pnums[6]; + for(int j=0;j<6;j++) pnums[j] = el.PNum (p[j]); + for(int k=0;k<6;k++) el.pnums[k] = pnums[k]; + } + + /* *testout << " Classified Prism with pnums " << endl; + for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; + *testout << endl; + */ + return(type); +} + + +// #ifdef SABINE +HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint, int dim, const FaceDescriptor & fd) + +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + int pnums[3]; + int p[3]; + + INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]); + i3.Sort(); + bool sing_face = faces.Used (i3); + + // *testout << " facepoint " << facepoint << endl; + + + // Try all rotations of the trig + for (int j=0;j<3;j++) + { + int point_sing[3] = {0,0,0}; + int edge_sing[3] = {0,0,0}; + // *testout << " actual rotation of trig points " ; + for(int m=0;m<3;m++) + { + p[m] = (j+m)%3 +1; // local vertex number + pnums[m] = el.PNum(p[m]); // global vertex number + // *testout << pnums[m] << " \t "; + } + // *testout << endl ; + + if(dim == 3) + { + // face point + for(int k=0;k<3;k++) + if(!sing_face) + { + // *testout << " fp [" << k << "] = " << facepoint[pnums[k]] << endl; + // *testout << " fd.DomainIn()" << fd.DomainIn() << endl; + // *testout << " fd.DomainOut()" << fd.DomainOut() << endl; + if( facepoint[pnums[k]] && (facepoint[pnums[k]] ==-1 || + facepoint[pnums[k]] == fd.DomainIn() || facepoint[pnums[k]] == fd.DomainOut())) + point_sing[p[k]-1] = 1; + } + // if point is on face_edge in next step sing = 2 + + /* *testout << " pointsing NACH FACEPOints ... FALLS EDGEPOINT UMSETZEN" ; + for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ; + *testout << endl; */ + } + + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(TRIG); + + if(dim==3) + { + for(int k=0;k<3;k++) + { + int ep1=p[eledges[k][0]-1]; + int ep2=p[eledges[k][1]-1]; + INDEX_2 i2(el.PNum(ep1),el.PNum(ep2)); + + if(edges.Used(i2)) + { + + edge_sing[k]=2; + point_sing[ep1-1] = 2; + point_sing[ep2-1] = 2; + } + else // face_edge? + { + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1) // edge not face_edge acc. to surface in which trig lies + if(face_edges.Get(i2)==-1 ||face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut() ) + { + edge_sing[k]=1; + } + else + { + point_sing[ep1-1] = 0; // set to edge_point + point_sing[ep2-1] = 0; // set to edge_point + } + } + + /* *testout << " pointsing NACH edges UND FACEEDGES UMSETZEN ... " ; + for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ; + *testout << endl; + */ + } + } + /* + *testout << " dim " << dim << endl; + *testout << " edgepoint_dom " << edgepoint_dom << endl; + */ + if(dim==2) + { + for(int k=0;k<3;k++) + { + int ep1=p[eledges[k][0]-1]; + int ep2=p[eledges[k][1]-1]; + + INDEX_2 i2(el.PNum(ep1),el.PNum(ep2)); + + if(edges.Used(i2)) + { + + if(edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep1-1])) || + edgepoint_dom.Used(INDEX_2(-1,pnums[ep1-1])) || + edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep2-1])) || + edgepoint_dom.Used(INDEX_2(-1,pnums[ep2-1]))) + { + edge_sing[k]=2; + point_sing[ep1-1] = 2; + point_sing[ep2-1] = 2; + } + } + + } + } + + + + for(int k=0;k<3;k++) + if(edgepoint.Test(pnums[k])) //edgepoint, but not member of sing_edge on trig -> cp + { + INDEX_2 i2a=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+1)%3])); + INDEX_2 i2b=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+2)%3])); + + if(!edges.Used(i2a) && !edges.Used(i2b)) + point_sing[p[k]-1] = 3; + } + + for(int k=0;k<3;k++) + if(cornerpoint.Test(el.PNum(p[k]))) + point_sing[p[k]-1] = 3; + + + if(edge_sing[0] + edge_sing[1] + edge_sing[2] == 0) + { + int ps = point_sing[0] + point_sing[1] + point_sing[2]; + + if(ps==0) + type = HP_TRIG; + else if(point_sing[p[0]-1] && !point_sing[p[1]-1] && !point_sing[p[2]-1]) + type = HP_TRIG_SINGCORNER; + else if(point_sing[p[0]-1] && point_sing[p[1]-1] && !point_sing[p[2]-1]) + type = HP_TRIG_SINGCORNER12; + else if(point_sing[p[0]-1] && point_sing[p[1]-1] && point_sing[p[2]-1]) + { + if(dim==2) type = HP_TRIG_SINGCORNER123_2D; + else type = HP_TRIG_SINGCORNER123; + } + } + else + if (edge_sing[2] && !edge_sing[0] && !edge_sing[1]) //E[2]=(1,2) + { + int code = 0; + if(point_sing[p[0]-1] > edge_sing[2]) code+=1; + if(point_sing[p[1]-1] > edge_sing[2]) code+=2; + if(point_sing[p[2]-1]) 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]; + + } // E[0] = [0,2], E[1] =[1,2], E[2] = [0,1] + else + if(edge_sing[2] && !edge_sing[1] && edge_sing[0]) + { + if(point_sing[p[2]-1] <= edge_sing[0] ) + { + if(point_sing[p[1]-1]<= edge_sing[2]) type = HP_TRIG_SINGEDGES; + else type = HP_TRIG_SINGEDGES2; + } + else + { + if(point_sing[p[1]-1]<= edge_sing[2]) + type = HP_TRIG_SINGEDGES3; + else type = HP_TRIG_SINGEDGES23; + } + } + else if (edge_sing[2] && edge_sing[1] && edge_sing[0]) + type = HP_TRIG_3SINGEDGES; + + // cout << " run for " << j << " gives type " << type << endl; + //*testout << " run for " << j << " gives type " << type << endl; + if(type!=HP_NONE) break; + } + + for(int k=0;k<3;k++) el[k] = pnums[k]; + /*if(type != HP_NONE) + { + + cout << " TRIG with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << endl; + cout << " type " << type << endl; + } + */ + return(type); +} +#ifdef HPREF_OLD +HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint, int dim, const FaceDescriptor & fd) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + int pnums[3]; + + INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]); + i3.Sort(); + bool sing_face = faces.Used (i3); + + + for (int 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 (dim == 2) + { + // JS, Dec 11 + ep1 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j))) || + edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j))); + ep2 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+1))) || + edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+1))); + ep3 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+2))) || + edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+2))); + /* + ep1 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j))); + ep2 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+1))); + ep3 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+2))); + */ + // 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; + + + // (*testout) << "cp = " << cp1 << cp2 << cp3 << ", ep = " << ep1 << ep2 << ep3 << endl; + + int p[3] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2)}; + if(ep1) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[0], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp1 = 1; + } + if(ep2) + { + INDEX_2 i2a=INDEX_2::Sort(p[1], p[0]); + INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp2 = 1; + } + if(ep3) + { + INDEX_2 i2a=INDEX_2::Sort(p[2], p[0]); + INDEX_2 i2b=INDEX_2::Sort(p[2], p[1]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp3= 1; + } + + + int isedge1=0, isedge2=0, isedge3=0; + if(dim == 3 ) + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + isedge1 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge1=1; + ep1 = 1; ep2=1; + } + + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + isedge2 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge2=1; + ep2 = 1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + isedge3 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge3=1; + ep1 = 1; ep3=1; + } + + // cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl; + + if (!sing_face) + { + /* + if (!isedge1) { cp1 |= ep1; cp2 |= ep2; } + if (!isedge2) { cp2 |= ep2; cp3 |= ep3; } + if (!isedge3) { cp3 |= ep3; cp1 |= ep1; } + */ + ep1 |= facepoint [el.PNumMod(j)] != 0; + ep2 |= facepoint [el.PNumMod(j+1)] != 0; + ep3 |= facepoint [el.PNumMod(j+2)] != 0; + + + isedge1 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1))); + isedge2 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+1), el.PNumMod(j+2))); + isedge3 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+2), el.PNumMod(j+3))); + } + } + + if(dim ==2) + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + i2.Sort(); + isedge1 = edges.Used (i2); + if(isedge1) + { + ep1 = 1; ep2=1; + } + + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + i2.Sort(); + isedge2 = edges.Used (i2); + if(isedge2) + { + ep2 = 1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + i2.Sort(); + isedge3 = edges.Used (i2); + if(isedge3) + { + ep1 = 1; ep3=1; + } + + + } + + + /* + cout << " used " << face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1))) << endl; + + cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl; + cout << " ep " << ep1 << "\t" << ep2 << " \t " << ep3 << endl; + cout << " cp " << cp1 << "\t" << cp2 << " \t " << cp3 << endl; + */ + + + + 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 (dim == 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; + } + } + + for(int k=0;k<3;k++) el[k] = pnums[k]; + /*if(type != HP_NONE) + { + + cout << " TRIG with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << endl; + cout << " type " << type << endl; + } + */ + return(type); +} +#endif +HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint, int dim, const FaceDescriptor & fd) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + int ep1(-1), ep2(-1), ep3(-1), ep4(-1), cp1(-1), cp2(-1), cp3(-1), cp4(-1); + int isedge1, isedge2, isedge3, isedge4; + + for (int 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 (dim == 2) + { + ep1 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j))); + ep2 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+1))); + ep3 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+2))); + ep4 = edgepoint_dom.Used (INDEX_2 (el.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; + + int p[4] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2), el.PNumMod(j+4)}; + //int epp[4] = { ep1, ep2, ep3, ep4}; + int cpp[4] = { cp1, cp2, cp3, cp4}; + for(int k=0;k<0;k++) + { + INDEX_2 i2a=INDEX_2::Sort(p[k], p[(k+1)%4]); + INDEX_2 i2b=INDEX_2::Sort(p[k], p[(k-1)%4]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cpp[k] = 1; + } + cp1= cpp[0]; cp2=cpp[1]; cp3=cpp[2]; cp4=cpp[3]; + + + if(dim ==3) + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + // i2.Sort(); + isedge1 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge1=1; + ep1 = 1; ep2=1; + } + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + // i2.Sort(); + isedge2 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge2=1; + ep2=1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + // i2.Sort(); + isedge3 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge3=1; + ep3=1; ep4=1; + } + i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4)); + // i2.Sort(); + isedge4 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge4=1; + ep4=1; ep1=1; + } + + +//MH*********************************************************************************************************** + if(ep1) + if(edgepoint.Test(p[0])) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[0], p[3]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp1 = 1; + } + if(ep2) + if(edgepoint.Test(p[1])) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp2 = 1; + } + if(ep3) + if(edgepoint.Test(p[2])) + { + INDEX_2 i2a=INDEX_2::Sort(p[2], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[3], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp3 = 1; + } + if(ep4) + if(edgepoint.Test(p[3])) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[3]); + INDEX_2 i2b=INDEX_2::Sort(p[3], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp4 = 1; + } +//MH***************************************************************************************************************************** + } + else + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + i2.Sort(); + isedge1 = edges.Used (i2); + if(isedge1) + { + ep1 = 1; ep2=1; + } + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + i2.Sort(); + isedge2 = edges.Used (i2); + if(isedge2) + { + ep2=1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + i2.Sort(); + isedge3 = edges.Used (i2); + + if(isedge3) + { + ep3=1; ep4=1; + } + i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4)); + i2.Sort(); + isedge4 = edges.Used (i2); + if(isedge4) + { + ep4=1; ep1=1; + } + } + + 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) + { + int pnums[4]; + pnums[0] = el.PNumMod (j); + pnums[1] = el.PNumMod (j+1); + pnums[2] = el.PNumMod (j+2); + pnums[3] = el.PNumMod (j+3); + for (int k=0;k<4;k++) el[k] = pnums[k]; + + /* cout << " QUAD with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << "\t" << pnums[3] + << endl << " of type " << type << endl; */ + + 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; + } + + + return(type); +} + + +HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + // implementation only for HP_HEX_1F_0E_0V + // HP_HEX_1FA_1FB_0E_0V + // HP_HEX + // up to now other cases are refine dummies + + // indices of bot,top-faces combinations + int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; + int p[8]; + const ELEMENT_FACE * elfaces = MeshTopology::GetFaces (HEX); + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (HEX); + + for(int m=0;m<6 && type == HP_NONE;m++) + for(int j=0;j<4 && type == HP_NONE;j++) + { + int point_sing[8]={0,0,0,0,0,0,0,0}; + int face_sing[6] = {0,0,0,0,0,0}; + int edge_sing[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; + int spoint=0, sface=0, sedge=0; + for(int l=0;l<4;l++) + { + p[l] = elfaces[index[m][0]][(4-j-l)%4]; + p[l+4] = elfaces[index[m][1]][(j+l)%4]; + } + + for(int l=0;l<8;l++) + if(cornerpoint.Test(el.PNum(p[l]))) + { + point_sing[p[l]-1]=3; + spoint++; + } + else if(edgepoint.Test(el.PNum(p[l]))) point_sing[p[l]-1]=2; + else if (facepoint[el.PNum(p[l])] == -1 || facepoint[el.PNum(p[l])] == el.GetIndex()) + point_sing[p[l]-1] = 1; + + for(int k=0;k<12;k++) + { + INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); + if (edges.Used(i2)) + { + edge_sing[k] = 2; + sedge++; + } + else edge_sing[k] = face_edges.Used(i2); + } + + for (int k=0;k<6;k++) + { + INDEX_3 i3; + + + INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + + if (faces.Used (i3)) + { + + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + { + face_sing[k] = 1; + sface++; + } + + } + } + + if(!sface && !sedge && !spoint) type = HP_HEX; + if(!sedge && !spoint) + { + if(face_sing[0] && face_sing[2] && sface==2) + type = HP_HEX_1FA_1FB_0E_0V; + if (face_sing[0] && sface==1) + type = HP_HEX_1F_0E_0V; + } + + el.type=type; + + if(type != HP_NONE) + { + int pnums[8]; + for(int l=0;l<8;l++) pnums[l] = el[p[l]-1]; + for(int l=0;l<8;l++) el[l] = pnums[l]; + /* cout << " HEX with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << "\t" << pnums[3] << "\t" << + pnums[4] << "\t" << pnums[5] << endl << " of type " << type << endl; */ + break; + } + } + + return (type); + +} + +HPREF_ELEMENT_TYPE ClassifySegm(HPRefElement & hpel, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint) +{ + + int cp1 = cornerpoint.Test (hpel[0]); + int cp2 = cornerpoint.Test (hpel[1]); + + INDEX_2 i2; + i2 = INDEX_2(hpel[0], hpel[1]); + i2.Sort(); + if (!edges.Used (i2)) + { + cp1 = edgepoint.Test (hpel[0]); + cp2 = edgepoint.Test (hpel[1]); + } + + if(!edges.Used(i2) && !face_edges.Used(i2)) + { + if(facepoint[hpel[0]]!=0) cp1=1; + if(facepoint[hpel[1]]!=0) cp2=1; + } + + if(edges.Used(i2) && !face_edges.Used(i2)) + { + if(facepoint[hpel[0]]) cp1 = 1; + if(facepoint[hpel[1]]) cp2 = 1; + } + + 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; + + // cout << " SEGM found with " << hpel[0] << " \t" << hpel[1] << endl << " of type " << hpel.type << endl; + return(hpel.type) ; +} + + +HPREF_ELEMENT_TYPE ClassifyPyramid(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + // implementation only for HP_PYRAMID + // HP_PYRAMID_0E_1V + // HP_PYRAMID_EDGES + // HP_PYRAMID_1FB_0E_1VA + // up to now other cases are refine dummies + + // indices of bot,top-faces combinations + // int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; + + const ELEMENT_FACE * elfaces = MeshTopology::GetFaces (PYRAMID); + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (PYRAMID); + + int point_sing[5]={0,0,0,0,0}; + int face_sing[5] = {0,0,0,0,0}; + int edge_sing[8] = {0,0,0,0,0,0,0,0}; + + int spoint=0, sedge=0, sface=0; + + for(int m=0;m<4 && type == HP_NONE;m++) + { + int p[5] = {m%4, m%4+1, m%4+2, m%4+3, 4}; + + for(int l=0;l<5;l++) + { + if(cornerpoint.Test(el.pnums[p[l]])) + point_sing[l]=3; + + else if(edgepoint.Test(el.pnums[p[l]])) + point_sing[l]=2; + + else if (facepoint[el.pnums[p[l]]] == -1 || facepoint[el.pnums[p[l]]] == el.GetIndex()) + point_sing[l] = 1; + + spoint += point_sing[l]; + } + + for(int k=0;k<8;k++) + { + INDEX_2 i2 = INDEX_2 :: Sort(el.pnums[p[eledges[k][0]-1]], + el.pnums[p[eledges[k][1]-1]]); + if (edges.Used(i2)) + edge_sing[k] = 2; + else + edge_sing[k] = face_edges.Used(i2); + + sedge += edge_sing[k]; + } + + for (int k=0;k<5;k++) + { + INDEX_3 i3; + INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]], el.pnums[p[elfaces[k][1]-1]], el.pnums[p[elfaces[k][2]-1]], + el.pnums[p[elfaces[k][3]-1]]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + + if (faces.Used (i3)) + { + + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + face_sing[k] = 1; + } + sface +=face_sing[k]; + } + + if(!sface && !spoint && !sedge) return(HP_PYRAMID); + + if(!sface && !sedge && point_sing[p[0]] == spoint) + type = HP_PYRAMID_0E_1V; + + if(!sface && edge_sing[0] + edge_sing[2] == sedge && + spoint == point_sing[0] + point_sing[1] + point_sing[3]) + type = HP_PYRAMID_EDGES; + + if(sface && sface == face_sing[0] && spoint == point_sing[4] + 2) + type = HP_PYRAMID_1FB_0E_1VA; + + + if(type != HP_NONE) + { + int pnums[8]; + for(int l=0;l<5;l++) pnums[l] = el[p[l]]; + for(int l=0;l<5;l++) el[l] = pnums[l]; + el.type=type; + break; + } + } + + return (type); + +} diff --git a/libsrc/meshing/clusters.cpp b/libsrc/meshing/clusters.cpp new file mode 100644 index 00000000..da6c66fe --- /dev/null +++ b/libsrc/meshing/clusters.cpp @@ -0,0 +1,267 @@ +#include + +#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(); + + bool hasedges = top.HasEdges(); + bool hasfaces = top.HasFaces(); + + if (!hasedges || !hasfaces) 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 nnums, ednums, fanums; + int changed; + + 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/libsrc/meshing/clusters.hpp b/libsrc/meshing/clusters.hpp new file mode 100644 index 00000000..b0eea1b5 --- /dev/null +++ b/libsrc/meshing/clusters.hpp @@ -0,0 +1,42 @@ +#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 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/libsrc/meshing/curvedelems.hpp b/libsrc/meshing/curvedelems.hpp new file mode 100644 index 00000000..5e621f6d --- /dev/null +++ b/libsrc/meshing/curvedelems.hpp @@ -0,0 +1,868 @@ +#ifndef CURVEDELEMS +#define CURVEDELEMS + +/**************************************************************************/ +/* File: curvedelems.hpp */ +/* Author: Robert Gaisbauer */ +/* Date: 27. Sep. 02 (second version: 30. Jan. 03) */ +/**************************************************************************/ + +#include "bisect.hpp" +#include + +#define EPSILON 1e-20 + + + +void ComputeGaussRule (int n, ARRAY & xi, ARRAY & wi); + + + + + +// ---------------------------------------------------------------------------- +// CurvedElements +// ---------------------------------------------------------------------------- + +class CurvedElements +{ + const Mesh & mesh; + const MeshTopology & top; + + bool isHighOrder; + int nvisualsubsecs; + int nIntegrationPoints; + + ARRAY edgeorder; + ARRAY faceorder; + + /* + + ARRAY< Vec<3> > edgecoeffs; + ARRAY< Vec<3> > facecoeffs; + + ARRAY edgecoeffsindex; + ARRAY 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 edgecoeffsindex; + ARRAY 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, bool rational=false); + + 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 (const Point<2> & xi, int elnr, + Point<3> & x) + { CalcSurfaceTransformation (xi, elnr, &x, NULL); }; + + void CalcSurfaceTransformation (const Point<2> & xi, int elnr, + Mat<3,2> & dxdxi) + { CalcSurfaceTransformation (xi, elnr, NULL, &dxdxi); }; + + void CalcSurfaceTransformation (const Point<2> & xi, int elnr, + Point<3> & x, Mat<3,2> & dxdxi) + { CalcSurfaceTransformation (xi, elnr, &x, &dxdxi); }; + + + void CalcElementTransformation (const Point<3> & xi, int elnr, + Point<3> & x) + { CalcElementTransformation (xi, elnr, &x, NULL); }; + + void CalcElementTransformation (const Point<3> & xi, int elnr, + Mat<3,3> & dxdxi) + { CalcElementTransformation (xi, elnr, NULL, &dxdxi); }; + + void CalcElementTransformation (const Point<3> & xi, int elnr, + Point<3> & x, Mat<3,3> & dxdxi) + { CalcElementTransformation (xi, elnr, &x, &dxdxi); }; + + + + + void CalcMultiPointSegmentTransformation (ARRAY * xi, int segnr, + ARRAY > * x, + ARRAY > * dxdxi); + + void CalcMultiPointSurfaceTransformation (ARRAY< Point<2> > * xi, int elnr, + ARRAY< Point<3> > * x, + ARRAY< Mat<3,2> > * dxdxi); + + void CalcMultiPointElementTransformation (ARRAY< Point<3> > * xi, int elnr, + ARRAY< Point<3> > * x, + ARRAY< Mat<3,3> > * dxdxi); + +}; + + + +// ---------------------------------------------------------------------------- +// PolynomialBasis +// ---------------------------------------------------------------------------- + +class PolynomialBasis +{ + int order; + int maxorder; + ArrayMem f; + ArrayMem df; + ArrayMem ddf; + + ArrayMem lp; + ArrayMem dlp; + + inline void CalcLegendrePolynomials (double x); + // P_i(x/t) t^i + inline void CalcScaledLegendrePolynomials (double x, double t); + 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); + + // compute F_i(x/t) t^i + inline void CalcFScaled (double x, double t); + static inline void CalcFScaled (int p, double x, double t, double * values); + + 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 +class BaseFiniteElement +{ +protected: + + Point 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 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 eshape; + ArrayMem edshape; + ArrayMem 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 eshape; + ArrayMem< Vec<2>,80> edshape; + ArrayMem fshape; + ArrayMem,400> fdshape; + ArrayMem 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 eshape; + ArrayMem,120> edshape; + ArrayMem fshape; + ArrayMem,300> 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 CalcVertexShapesOnly() + { CalcVertexShapes(); } + + virtual void CalcEdgeShapes() = 0; + virtual void CalcEdgeShapesOnly() + { CalcEdgeShapes(); } + + 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 CalcVertexShapesOnly(); + virtual void CalcEdgeShapes(); + virtual void CalcEdgeShapesOnly(); + 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/libsrc/meshing/curvedelems_new.cpp b/libsrc/meshing/curvedelems_new.cpp new file mode 100644 index 00000000..25eb647f --- /dev/null +++ b/libsrc/meshing/curvedelems_new.cpp @@ -0,0 +1,3169 @@ +#include + +#include "meshing.hpp" +#ifdef CURVEDELEMS_NEW + +#include "../general/autodiff.hpp" + + +namespace netgen +{ + + // bool rational = true; + + + + static void ComputeGaussRule (int n, ARRAY & xi, ARRAY & 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); + } + } + + + + // compute edge bubbles up to order n, x \in (-1, 1) + static void CalcEdgeShape (int n, double x, double * shape) + { + double p1 = x, p2 = -1, p3 = 0; + for (int j=2; j<=n; j++) + { + p3=p2; p2=p1; + p1=( (2*j-3) * x * p2 - (j-3) * p3) / j; + shape[j-2] = p1; + } + } + + static void CalcEdgeDx (int n, double x, double * dshape) + { + double p1 = x, p2 = -1, p3 = 0; + double p1dx = 1, p2dx = 0, p3dx = 0; + + for (int j=2; j<=n; j++) + { + p3=p2; p2=p1; + p3dx = p2dx; p2dx = p1dx; + + p1=( (2*j-3) * x * p2 - (j-3) * p3) / j; + p1dx = ( (2*j-3) * (x * p2dx + p2) - (j-3) * p3dx) / j; + + dshape[j-2] = p1dx; + } + } + + static void CalcEdgeShapeDx (int n, double x, double * shape, double * dshape) + { + double p1 = x, p2 = -1, p3 = 0; + double p1dx = 1, p2dx = 0, p3dx = 0; + + for (int j=2; j<=n; j++) + { + p3=p2; p2=p1; + p3dx = p2dx; p2dx = p1dx; + + p1=( (2*j-3) * x * p2 - (j-3) * p3) / j; + p1dx = ( (2*j-3) * (x * p2dx + p2) - (j-3) * p3dx) / j; + + shape[j-2] = p1; + dshape[j-2] = p1dx; + } + } + + // compute L_i(x/t) * t^i + static void CalcScaledEdgeShape (int n, double x, double t, double * shape) + { + static bool init = false; + static double coefs[100][2]; + if (!init) + { + for (int j = 0; j < 100; j++) + { + coefs[j][0] = double(2*j+1)/(j+2); + coefs[j][1] = -double(j-1)/(j+2); + } + init = true; + } + + double p1 = x, p2 = -1, p3 = 0; + double tt = t*t; + for (int j=0; j<=n-2; j++) + { + p3=p2; p2=p1; + p1= coefs[j][0] * x * p2 + coefs[j][1] * tt*p3; + // p1=( (2*j+1) * x * p2 - t*t*(j-1) * p3) / (j+2); + shape[j] = p1; + } + } + + template + static void CalcScaledEdgeShapeDxDt (int n, double x, double t, double * dshape) + { + double p1 = x, p2 = -1, p3 = 0; + double p1dx = 1, p1dt = 0; + double p2dx = 0, p2dt = 0; + double p3dx = 0, p3dt = 0; + + for (int j=0; j<=n-2; j++) + { + p3=p2; p3dx=p2dx; p3dt = p2dt; + p2=p1; p2dx=p1dx; p2dt = p1dt; + + p1 = ( (2*j+1) * x * p2 - t*t*(j-1) * p3) / (j+2); + p1dx = ( (2*j+1) * (x * p2dx + p2) - t*t*(j-1) * p3dx) / (j+2); + p1dt = ( (2*j+1) * x * p2dt - (j-1)* (t*t*p3dt+2*t*p3)) / (j+2); + + // shape[j] = p1; + dshape[DIST*j ] = p1dx; + dshape[DIST*j+1] = p1dt; + } + } + + + template + static void LegendrePolynomial (int n, Tx x, Tres * values) + { + switch (n) + { + case 0: + values[0] = 1; + break; + case 1: + values[0] = 1; + values[1] = x; + break; + + default: + + if (n < 0) return; + + Tx p1 = 1.0, p2 = 0.0, p3; + + values[0] = 1.0; + for (int j=1; j<=n; j++) + { + p3 = p2; p2 = p1; + p1 = ((2.0*j-1.0)*x*p2 - (j-1.0)*p3) / j; + values[j] = p1; + } + } + } + + template + static void ScaledLegendrePolynomial (int n, Tx x, Tt t, Tres * values) + { + switch (n) + { + case 0: + values[0] = 1.0; + break; + + case 1: + values[0] = 1.0; + values[1] = x; + break; + + default: + + if (n < 0) return; + + Tx p1 = 1.0, p2 = 0.0, p3; + values[0] = 1.0; + for (int j=1; j<=n; j++) + { + p3 = p2; p2 = p1; + p1 = ((2.0*j-1.0)*x*p2 - t*t*(j-1.0)*p3) / j; + values[j] = p1; + } + } + } + + + +template +inline void JacobiPolynomial (int n, S x, double alpha, double beta, T * values) +{ + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) + p2 = values[0] = 1.0; + if (n >= 1) + p1 = values[1] = 0.5 * (2*(alpha+1)+(alpha+beta+2)*(x-1)); + + for (int i = 1; i < n; i++) + { + p3 = p2; p2=p1; + p1 = + 1.0 / ( 2 * (i+1) * (i+alpha+beta+1) * (2*i+alpha+beta) ) * + ( + ( (2*i+alpha+beta+1)*(alpha*alpha-beta*beta) + + (2*i+alpha+beta)*(2*i+alpha+beta+1)*(2*i+alpha+beta+2) * x) + * p2 + - 2*(i+alpha)*(i+beta) * (2*i+alpha+beta+2) * p3 + ); + values[i+1] = p1; + } +} + + + + +template +inline void ScaledJacobiPolynomial (int n, S x, St t, double alpha, double beta, T * values) +{ + /* + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) values[0] = 1.0; + */ + + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) + p2 = values[0] = 1.0; + if (n >= 1) + p1 = values[1] = 0.5 * (2*(alpha+1)*t+(alpha+beta+2)*(x-t)); + + for (int i=1; i < n; i++) + { + p3 = p2; p2=p1; + p1 = + 1.0 / ( 2 * (i+1) * (i+alpha+beta+1) * (2*i+alpha+beta) ) * + ( + ( (2*i+alpha+beta+1)*(alpha*alpha-beta*beta) * t + + (2*i+alpha+beta)*(2*i+alpha+beta+1)*(2*i+alpha+beta+2) * x) + * p2 + - 2*(i+alpha)*(i+beta) * (2*i+alpha+beta+2) * t * t * p3 + ); + values[i+1] = p1; + } +} + + + + + + // compute face bubbles up to order n, 0 < y, y-x < 1, x+y < 1 + template + static void CalcTrigShape (int n, Tx x, Ty y, Ts * shape) + { + if (n < 3) return; + Tx hx[50], hy[50*50]; + // ScaledLegendrePolynomial (n-3, 2*x-1, 1-y, hx); + ScaledJacobiPolynomial (n-3, x, 1-y, 2, 2, hx); + + + // LegendrePolynomial (n-3, 2*y-1, hy); + for (int ix = 0; ix <= n-3; ix++) + // JacobiPolynomial (n-3, 2*y-1, 0, 0, hy+50*ix); + JacobiPolynomial (n-3, 2*y-1, 2*ix+5, 2, hy+50*ix); + + int ii = 0; + Tx bub = (1+x-y)*y*(1-x-y); + for (int iy = 0; iy <= n-3; iy++) + for (int ix = 0; ix <= n-3-iy; ix++) + shape[ii++] = bub * hx[ix]*hy[iy+50*ix]; + } + + + + static void CalcTrigShapeDxDy (int n, double x, double y, double * dshape) + { + if (n < 3) return; + + AutoDiff<2> adx(x, 0); + AutoDiff<2> ady(y, 1); + AutoDiff<2> res[2000]; + CalcTrigShape (n, adx, ady, &res[0]); + int ndof = (n-1)*(n-2)/2; + for (int i = 0; i < ndof; i++) + { + dshape[2*i] = res[i].DValue(0); + dshape[2*i+1] = res[i].DValue(1); + } + + /* + if (n < 3) return; + + int ndof = (n-1)*(n-2)/2; + double h1[1000], h2[1000]; + double eps = 1e-4; + + CalcTrigShape (n, x+eps, y, h1); + CalcTrigShape (n, x-eps, y, h2); + + for (int i = 0; i < ndof; i++) + dshape[2*i] = (h1[i]-h2[i])/(2*eps); + + CalcTrigShape (n, x, y+eps, h1); + CalcTrigShape (n, x, y-eps, h2); + + for (int i = 0; i < ndof; i++) + dshape[2*i+1] = (h1[i]-h2[i])/(2*eps); + */ + } + + + + + + + + + // compute face bubbles up to order n, 0 < y, y-x < 1, x+y < 1 + template + static void CalcScaledTrigShape (int n, Tx x, Ty y, Tt t, Tr * shape) + { + if (n < 3) return; + + Tx hx[50], hy[50*50]; + // ScaledLegendrePolynomial (n-3, (2*x-1), t-y, hx); + ScaledJacobiPolynomial (n-3, x, t-y, 2, 2, hx); + + // ScaledLegendrePolynomial (n-3, (2*y-1), t, hy); + for (int ix = 0; ix <= n-3; ix++) + ScaledJacobiPolynomial (n-3, 2*y-1, t, 2*ix+5, 2, hy+50*ix); + + + int ii = 0; + Tx bub = (t+x-y)*y*(t-x-y); + for (int iy = 0; iy <= n-3; iy++) + for (int ix = 0; ix <= n-3-iy; ix++) + shape[ii++] = bub * hx[ix]*hy[iy+50*ix]; + } + + + // compute face bubbles up to order n, 0 < y, y-x < 1, x+y < 1 + static void CalcScaledTrigShapeDxDyDt (int n, double x, double y, double t, double * dshape) + { + if (n < 3) return; + AutoDiff<3> adx(x, 0); + AutoDiff<3> ady(y, 1); + AutoDiff<3> adt(t, 2); + AutoDiff<3> res[2000]; + CalcScaledTrigShape (n, adx, ady, adt, &res[0]); + double dshape1[6000]; + int ndof = (n-1)*(n-2)/2; + for (int i = 0; i < ndof; i++) + { + dshape[3*i] = res[i].DValue(0); + dshape[3*i+1] = res[i].DValue(1); + dshape[3*i+2] = res[i].DValue(2); + } + + /* + if (n < 3) return; + double hvl[1000], hvr[1000]; + int nd = (n-1)*(n-2)/2; + + double eps = 1e-6; + + CalcScaledTrigShape (n, x-eps, y, t, hvl); + CalcScaledTrigShape (n, x+eps, y, t, hvr); + for (int i = 0; i < nd; i++) + dshape[3*i] = (hvr[i]-hvl[i])/(2*eps); + + CalcScaledTrigShape (n, x, y-eps, t, hvl); + CalcScaledTrigShape (n, x, y+eps, t, hvr); + for (int i = 0; i < nd; i++) + dshape[3*i+1] = (hvr[i]-hvl[i])/(2*eps); + + CalcScaledTrigShape (n, x, y, t-eps, hvl); + CalcScaledTrigShape (n, x, y, t+eps, hvr); + for (int i = 0; i < nd; i++) + dshape[3*i+2] = (hvr[i]-hvl[i])/(2*eps); + */ + + /* + for (int i = 0; i < 3*nd; i++) + if (fabs (dshape[i]-dshape1[i]) > 1e-8 * fabs(dshape[i]) + 1e-6) + { + cerr + cerr << "big difference: " << dshape1[i] << " != " << dshape[i] << endl; + } + */ + } + + + + + + CurvedElements :: CurvedElements (const Mesh & amesh) + : mesh (amesh) + { + order = 1; + rational = 0; + ishighorder = 0; + } + + + CurvedElements :: ~CurvedElements() + { + ; + } + + + void CurvedElements :: BuildCurvedElements(Refinement * ref, int aorder, + bool arational) + { + order = aorder; + ishighorder = 0; + + if (mesh.coarsemesh) + { + mesh.coarsemesh->GetCurvedElements().BuildCurvedElements (ref, aorder, arational); + order = aorder; + rational = arational; + ishighorder = (order > 1); + return; + } + + PrintMessage (1, "Curve elements, order = ", aorder); + if (rational) PrintMessage (1, "curved elements with rational splines"); + + const_cast (mesh).UpdateTopology(); + const MeshTopology & top = mesh.GetTopology(); + + rational = arational; + + ARRAY edgenrs; + + edgeorder.SetSize (top.GetNEdges()); + faceorder.SetSize (top.GetNFaces()); + + edgeorder = 1; + faceorder = 1; + + if (rational) + { + edgeweight.SetSize (top.GetNEdges()); + edgeweight = 1.0; + } + + + if (aorder <= 1) + { + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + if (mesh[ei].GetType() == TET10) + ishighorder = 1; + return; + } + + + if (rational) aorder = 2; + + + if (mesh.GetDimension() == 3) + for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + { + top.GetSurfaceElementEdges (i+1, edgenrs); + for (int j = 0; j < edgenrs.Size(); j++) + edgeorder[edgenrs[j]-1] = aorder; + faceorder[top.GetSurfaceElementFace (i+1)-1] = aorder; + } + for (SegmentIndex i = 0; i < mesh.GetNSeg(); i++) + edgeorder[top.GetSegmentEdge (i+1)-1] = aorder; + + if (rational) + { + edgeorder = 2; + faceorder = 1; + } + + + edgecoeffsindex.SetSize (top.GetNEdges()+1); + int nd = 0; + for (int i = 0; i < top.GetNEdges(); i++) + { + edgecoeffsindex[i] = nd; + nd += max (0, edgeorder[i]-1); + } + edgecoeffsindex[top.GetNEdges()] = nd; + + edgecoeffs.SetSize (nd); + edgecoeffs = Vec<3> (0,0,0); + + + facecoeffsindex.SetSize (top.GetNFaces()+1); + nd = 0; + for (int i = 0; i < top.GetNFaces(); i++) + { + facecoeffsindex[i] = nd; + if (top.GetFaceType(i+1) == TRIG) + nd += max (0, (faceorder[i]-1)*(faceorder[i]-2)/2); + else + nd += max (0, sqr(faceorder[i]-1)); + } + facecoeffsindex[top.GetNFaces()] = nd; + + facecoeffs.SetSize (nd); + facecoeffs = Vec<3> (0,0,0); + + + if (!ref || aorder <= 1) + { + order = aorder; + return; + } + + ARRAY xi, weight; + + ComputeGaussRule (aorder+4, xi, weight); // on (0,1) + + PrintMessage (3, "Curving edges"); + + if (mesh.GetDimension() == 3 || rational) + for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + { + SetThreadPercent(double(i)/mesh.GetNSE()*100.); + const Element2d & el = mesh[i]; + top.GetSurfaceElementEdges (i+1, edgenrs); + for (int j = 0; j < edgenrs.Size(); j++) + edgenrs[j]--; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (el.GetType()); + + for (int i2 = 0; i2 < edgenrs.Size(); i2++) + { + PointIndex pi1 = edges[i2][0]-1; + PointIndex pi2 = edges[i2][1]-1; + + bool swap = el[pi1] > el[pi2]; + + Point<3> p1 = mesh[el[pi1]]; + Point<3> p2 = mesh[el[pi2]]; + + int order1 = edgeorder[edgenrs[i2]]; + int ndof = max (0, order1-1); + + if (rational && order1 >= 2) + { + Point<3> pm = Center (p1, p2); + + int surfnr = mesh.GetFaceDescriptor(el.GetIndex()).SurfNr(); + + Vec<3> n1 = ref -> GetNormal (p1, surfnr, el.GeomInfoPi(edges[i2][0])); + Vec<3> n2 = ref -> GetNormal (p2, surfnr, el.GeomInfoPi(edges[i2][1])); + + // p3 = pm + alpha1 n1 + alpha2 n2 + + Mat<2> mat, inv; + Vec<2> rhs, sol; + + mat(0,0) = n1*n1; + mat(0,1) = mat(1,0) = n1*n2; + mat(1,1) = n2*n2; + + rhs(0) = n1 * (p1-pm); + rhs(1) = n2 * (p2-pm); + + + Point<3> p3; + + if (fabs (Det (mat)) > 1e-10) + { + CalcInverse (mat, inv); + sol = inv * rhs; + + p3 = pm + sol(0) * n1 + sol(1) * n2; + } + else + p3 = pm; + + edgecoeffs[edgecoeffsindex[edgenrs[i2]]] = Vec<3> (p3); + + + double wold = 1, w = 1, dw = 0.1; + double dold = 1e99; + while (fabs (dw) > 1e-12) + { + Vec<3> v05 = 0.25 * Vec<3> (p1) + 0.5*w* Vec<3>(p3) + 0.25 * Vec<3> (p2); + v05 /= 1 + (w-1) * 0.5; + Point<3> p05 (v05), pp05(v05); + ref -> ProjectToSurface (pp05, surfnr, el.GeomInfoPi(edges[i2][0])); + double d = Dist (pp05, p05); + + if (d < dold) + { + dold = d; + wold = w; + w += dw; + } + else + { + dw *= -0.7; + w = wold + dw; + } + } + + edgeweight[edgenrs[i2]] = w; + continue; + } + + Vector shape(ndof); + DenseMatrix mat(ndof, ndof), inv(ndof, ndof), + rhs(ndof, 3), sol(ndof, 3); + + rhs = 0.0; + mat = 0.0; + for (int j = 0; j < xi.Size(); j++) + { + Point<3> p; + Point<3> pp; + PointGeomInfo ppgi; + + if (swap) + { + p = p1 + xi[j] * (p2-p1); + ref -> PointBetween (p1, p2, xi[j], + mesh.GetFaceDescriptor(el.GetIndex()).SurfNr(), + el.GeomInfoPi(edges[i2][0]), + el.GeomInfoPi(edges[i2][1]), + pp, ppgi); + } + else + { + p = p2 + xi[j] * (p1-p2); + ref -> PointBetween (p2, p1, xi[j], + mesh.GetFaceDescriptor(el.GetIndex()).SurfNr(), + el.GeomInfoPi(edges[i2][1]), + el.GeomInfoPi(edges[i2][0]), + pp, ppgi); + } + + Vec<3> dist = pp - p; + + CalcEdgeShape (order1, 2*xi[j]-1, &shape(0)); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < ndof; l++) + mat(k,l) += weight[j] * shape(k) * shape(l); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < 3; l++) + rhs(k,l) += weight[j] * shape(k) * dist(l); + } + + CalcInverse (mat, inv); + Mult (inv, rhs, sol); + + + + int first = edgecoeffsindex[edgenrs[i2]]; + for (int j = 0; j < ndof; j++) + for (int k = 0; k < 3; k++) + edgecoeffs[first+j](k) = sol(j,k); + } + } + + + + for (SegmentIndex i = 0; i < mesh.GetNSeg(); i++) + { + SetThreadPercent(double(i)/mesh.GetNSeg()*100.); + const Segment & seg = mesh[i]; + PointIndex pi1 = mesh[i].p1; + PointIndex pi2 = mesh[i].p2; + + bool swap = (pi1 > pi2); + + Point<3> p1 = mesh[pi1]; + Point<3> p2 = mesh[pi2]; + + int segnr = top.GetSegmentEdge (i+1)-1; + + int order1 = edgeorder[segnr]; + int ndof = max (0, order1-1); + + + if (rational) + { + Vec<3> tau1 = ref -> GetTangent (p1, seg.surfnr2, seg.surfnr1, seg.epgeominfo[0]); + Vec<3> tau2 = ref -> GetTangent (p2, seg.surfnr2, seg.surfnr1, seg.epgeominfo[1]); + // p1 + alpha1 tau1 = p2 + alpha2 tau2; + + Mat<3,2> mat; + Mat<2,3> inv; + Vec<3> rhs; + Vec<2> sol; + for (int j = 0; j < 3; j++) + { + mat(j,0) = tau1(j); + mat(j,1) = -tau2(j); + rhs(j) = p2(j)-p1(j); + } + CalcInverse (mat, inv); + sol = inv * rhs; + + Point<3> p3 = p1+sol(0) * tau1; + edgecoeffs[edgecoeffsindex[segnr]] = Vec<3> (p3); + + +// double dopt = 1e99; +// double wopt = 0; +// for (double w = 0; w <= 2; w += 0.0001) +// { +// Vec<3> v05 = 0.25 * Vec<3> (p1) + 0.5*w* Vec<3>(p3) + 0.25 * Vec<3> (p2); +// v05 /= 1 + (w-1) * 0.5; +// Point<3> p05 (v05), pp05(v05); +// ref -> ProjectToEdge (pp05, seg.surfnr1, seg.surfnr2, seg.epgeominfo[0]); +// double d = Dist (pp05, p05); +// if (d < dopt) +// { +// wopt = w; +// dopt = d; +// } +// } + + double wold = 1, w = 1, dw = 0.1; + double dold = 1e99; + while (fabs (dw) > 1e-12) + { + Vec<3> v05 = 0.25 * Vec<3> (p1) + 0.5*w* Vec<3>(p3) + 0.25 * Vec<3> (p2); + v05 /= 1 + (w-1) * 0.5; + Point<3> p05 (v05), pp05(v05); + ref -> ProjectToEdge (pp05, seg.surfnr1, seg.surfnr2, seg.epgeominfo[0]); + double d = Dist (pp05, p05); + + if (d < dold) + { + dold = d; + wold = w; + w += dw; + } + else + { + dw *= -0.7; + w = wold + dw; + } + // *testout << "w = " << w << ", dw = " << dw << endl; + } + + // cout << "wopt = " << w << ", dopt = " << dold << endl; + edgeweight[segnr] = w; + +// cout << "p1 = " << p1 << ", tau1 = " << tau1 << ", alpha1 = " << sol(0) << endl; +// cout << "p2 = " << p2 << ", tau2 = " << tau2 << ", alpha2 = " << -sol(1) << endl; +// cout << "p+alpha tau = " << p1 + sol(0) * tau1 +// << " =?= " << p2 +sol(1) * tau2 << endl; + + } + + else + + { + + Vector shape(ndof); + DenseMatrix mat(ndof, ndof), inv(ndof, ndof), + rhs(ndof, 3), sol(ndof, 3); + + rhs = 0.0; + mat = 0.0; + for (int j = 0; j < xi.Size(); j++) + { + Point<3> p; + + Point<3> pp; + EdgePointGeomInfo ppgi; + + if (swap) + { + p = p1 + xi[j] * (p2-p1); + ref -> PointBetween (p1, p2, xi[j], + seg.surfnr2, seg.surfnr1, + seg.epgeominfo[0], seg.epgeominfo[1], + pp, ppgi); + } + else + { + p = p2 + xi[j] * (p1-p2); + ref -> PointBetween (p2, p1, xi[j], + seg.surfnr2, seg.surfnr1, + seg.epgeominfo[1], seg.epgeominfo[0], + pp, ppgi); + } + + Vec<3> dist = pp - p; + + CalcEdgeShape (order1, 2*xi[j]-1, &shape(0)); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < ndof; l++) + mat(k,l) += weight[j] * shape(k) * shape(l); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < 3; l++) + rhs(k,l) += weight[j] * shape(k) * dist(l); + } + + + CalcInverse (mat, inv); + Mult (inv, rhs, sol); + + int first = edgecoeffsindex[segnr]; + for (int j = 0; j < ndof; j++) + for (int k = 0; k < 3; k++) + edgecoeffs[first+j](k) = sol(j,k); + } + } + + + + + PrintMessage (3, "Curving faces"); + + if (mesh.GetDimension() == 3) + for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + { + SetThreadPercent(double(i)/mesh.GetNSE()*100.); + const Element2d & el = mesh[i]; + int facenr = top.GetSurfaceElementFace (i+1)-1; + + if (el.GetType() == TRIG && order >= 3) + { + int fnums[] = { 0, 1, 2 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + int order1 = faceorder[facenr]; + int ndof = max (0, (order1-1)*(order1-2)/2); + + Vector shape(ndof); + DenseMatrix mat(ndof, ndof), inv(ndof, ndof), + rhs(ndof, 3), sol(ndof, 3); + + rhs = 0.0; + mat = 0.0; + + for (int jx = 0; jx < xi.Size(); jx++) + for (int jy = 0; jy < xi.Size(); jy++) + { + double y = xi[jy]; + double x = (1-y) * xi[jx]; + double lami[] = { x, y, 1-x-y }; + double wi = weight[jx]*weight[jy]*(1-y); + + Point<2> xii (x, y); + Point<3> p1, p2; + CalcSurfaceTransformation (xii, i, p1); + p2 = p1; + ref -> ProjectToSurface (p2, mesh.GetFaceDescriptor(el.GetIndex()).SurfNr()); + + Vec<3> dist = p2-p1; + + CalcTrigShape (order1, lami[fnums[1]]-lami[fnums[0]], + 1-lami[fnums[1]]-lami[fnums[0]], &shape(0)); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < ndof; l++) + mat(k,l) += wi * shape(k) * shape(l); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < 3; l++) + rhs(k,l) += wi * shape(k) * dist(l); + } + + // *testout << "mat = " << endl << mat << endl; + // CalcInverse (mat, inv); + // Mult (inv, rhs, sol); + + for (int i = 0; i < ndof; i++) + for (int j = 0; j < 3; j++) + sol(i,j) = rhs(i,j) / mat(i,i); // Orthogonal basis ! + + int first = facecoeffsindex[facenr]; + for (int j = 0; j < ndof; j++) + for (int k = 0; k < 3; k++) + facecoeffs[first+j](k) = sol(j,k); + } + } + + PrintMessage (3, "Complete"); + + + // compress edge and face tables + int newbase = 0; + for (int i = 0; i < edgeorder.Size(); i++) + { + bool curved = 0; + int oldbase = edgecoeffsindex[i]; + nd = edgecoeffsindex[i+1] - edgecoeffsindex[i]; + + for (int j = 0; j < nd; j++) + if (edgecoeffs[oldbase+j].Length() > 1e-12) + curved = 1; + if (rational) curved = 1; + + if (curved && newbase != oldbase) + for (int j = 0; j < nd; j++) + edgecoeffs[newbase+j] = edgecoeffs[oldbase+j]; + + edgecoeffsindex[i] = newbase; + if (!curved) edgeorder[i] = 1; + if (curved) newbase += nd; + } + edgecoeffsindex.Last() = newbase; + + + newbase = 0; + for (int i = 0; i < faceorder.Size(); i++) + { + bool curved = 0; + int oldbase = facecoeffsindex[i]; + nd = facecoeffsindex[i+1] - facecoeffsindex[i]; + + for (int j = 0; j < nd; j++) + if (facecoeffs[oldbase+j].Length() > 1e-12) + curved = 1; + + if (curved && newbase != oldbase) + for (int j = 0; j < nd; j++) + facecoeffs[newbase+j] = facecoeffs[oldbase+j]; + + facecoeffsindex[i] = newbase; + if (!curved) faceorder[i] = 1; + if (curved) newbase += nd; + } + facecoeffsindex.Last() = newbase; + + ishighorder = (order > 1); + // (*testout) << "edgecoeffs = " << endl << edgecoeffs << endl; + // (*testout) << "facecoeffs = " << endl << facecoeffs << endl; + } + + + + + + + + + + + // *********************** Transform edges ***************************** + + + bool CurvedElements :: IsSegmentCurved (SegmentIndex elnr) const + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsSegmentCurved (hpref_el.coarse_elnr); + } + + SegmentInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = 2; + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + info.edgenr = top.GetSegmentEdge (elnr+1)-1; + info.ndof += edgeorder[info.edgenr]-1; + } + + return (info.ndof > info.nv); + } + + + + + + void CurvedElements :: + CalcSegmentTransformation (double xi, SegmentIndex elnr, + Point<3> * x, Vec<3> * dxdxi, bool * curved) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[2] = { xi, 1-xi }; + double dlami[2] = { 1, -1 }; + + double coarse_xi = 0; + double trans = 0; + for (int i = 0; i < 2; i++) + { + coarse_xi += hpref_el.param[i][0] * lami[i]; + trans += hpref_el.param[i][0] * dlami[i]; + } + + mesh.coarsemesh->GetCurvedElements().CalcSegmentTransformation (coarse_xi, hpref_el.coarse_elnr, x, dxdxi, curved); + if (dxdxi) *dxdxi *= trans; + + return; + } + + + Vector shapes, dshapes; + ARRAY > coefs; + + SegmentInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = 2; + + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + info.edgenr = top.GetSegmentEdge (elnr+1)-1; + info.ndof += edgeorder[info.edgenr]-1; + } + + CalcElementShapes (info, xi, shapes); + GetCoefficients (info, coefs); + + *x = 0; + for (int i = 0; i < shapes.Size(); i++) + *x += shapes(i) * coefs[i]; + + + if (dxdxi) + { + CalcElementDShapes (info, xi, dshapes); + + *dxdxi = 0; + for (int i = 0; i < shapes.Size(); i++) + for (int j = 0; j < 3; j++) + (*dxdxi)(j) += dshapes(i) * coefs[i](j); + } + + if (curved) + *curved = (info.order > 1); + + // cout << "Segment, |x| = " << Abs2(Vec<3> (*x) ) << endl; + } + + + + + void CurvedElements :: + CalcElementShapes (SegmentInfo & info, double xi, Vector & shapes) const + { + if (rational && info.order == 2) + { + shapes.SetSize(3); + double w = edgeweight[info.edgenr]; + shapes(0) = xi*xi; + shapes(1) = (1-xi)*(1-xi); + shapes(2) = 2*w*xi*(1-xi); + shapes *= 1.0 / (1 + (w-1) *2*xi*(1-xi)); + return; + } + + + shapes.SetSize(info.ndof); + shapes(0) = xi; + shapes(1) = 1-xi; + + if (info.order >= 2) + { + if (mesh[info.elnr].p1 > mesh[info.elnr].p2) + xi = 1-xi; + CalcEdgeShape (edgeorder[info.edgenr], 2*xi-1, &shapes(2)); + } + } + + void CurvedElements :: + CalcElementDShapes (SegmentInfo & info, double xi, Vector & dshapes) const + { + if (rational && info.order == 2) + { + dshapes.SetSize(3); + double wi = edgeweight[info.edgenr]; + double shapes[3]; + shapes[0] = xi*xi; + shapes[1] = (1-xi)*(1-xi); + shapes[2] = 2*wi*xi*(1-xi); + double w = 1 + (wi-1) *2*xi*(1-xi); + double dw = (wi-1) * (2 - 4*xi); + + dshapes(0) = 2*xi; + dshapes(1) = 2*(xi-1); + dshapes(2) = 2*wi*(1-2*xi); + + for (int j = 0;j < 3; j++) + dshapes(j) = dshapes(j) / w - shapes[j] * dw / (w*w); + return; + } + + + + + + + dshapes.SetSize(info.ndof); + dshapes = 0; + dshapes(0) = 1; + dshapes(1) = -1; + + // int order = edgeorder[info.edgenr]; + + if (info.order >= 2) + { + double fac = 2; + if (mesh[info.elnr].p1 > mesh[info.elnr].p2) + { + xi = 1-xi; + fac *= -1; + } + CalcEdgeDx (edgeorder[info.edgenr], 2*xi-1, &dshapes(2)); + for (int i = 2; i < dshapes.Size(); i++) + dshapes(i) *= fac; + } + + // ??? not implemented ???? + } + + void CurvedElements :: + GetCoefficients (SegmentInfo & info, ARRAY > & coefs) const + { + const Segment & el = mesh[info.elnr]; + + coefs.SetSize(info.ndof); + + coefs[0] = Vec<3> (mesh[el.p1]); + coefs[1] = Vec<3> (mesh[el.p2]); + + if (info.order >= 2) + { + int first = edgecoeffsindex[info.edgenr]; + int next = edgecoeffsindex[info.edgenr+1]; + for (int i = 0; i < next-first; i++) + coefs[i+2] = edgecoeffs[first+i]; + } + } + + + + + + + + + + + + + + // ********************** Transform surface elements ******************* + + + bool CurvedElements :: IsSurfaceElementCurved (SurfaceElementIndex elnr) const + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsSurfaceElementCurved (hpref_el.coarse_elnr); + } + + const Element2d & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + SurfaceElementInfo info; + info.elnr = elnr; + info.order = order; + + switch (type) + { + case TRIG : info.nv = 3; break; + case QUAD : info.nv = 4; break; + case TRIG6: return true; + default: + cerr << "undef element in CalcSurfaceTrafo" << endl; + } + info.ndof = info.nv; + + // info.ndof = info.nv = ( (type == TRIG) || (type == TRIG6) ) ? 3 : 4; + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + for (int i = 0; i < info.edgenrs.Size(); i++) + info.edgenrs[i]--; + info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + for (int i = 0; i < info.edgenrs.Size(); i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + return (info.ndof > info.nv); + } + + void CurvedElements :: + CalcSurfaceTransformation (Point<2> xi, SurfaceElementIndex elnr, + Point<3> * x, Mat<3,2> * dxdxi, bool * curved) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[4]; + FlatVector vlami(4, lami); + vlami = 0; + mesh[elnr].GetShapeNew (xi, vlami); + + Mat<2,2> trans; + Mat<3,2> dxdxic; + if (dxdxi) + { + MatrixFixWidth<2> dlami(4); + dlami = 0; + mesh[elnr].GetDShapeNew (xi, dlami); + + trans = 0; + for (int k = 0; k < 2; k++) + for (int l = 0; l < 2; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + } + + Point<2> coarse_xi(0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 2; j++) + coarse_xi(j) += hpref_el.param[i][j] * lami[i]; + + mesh.coarsemesh->GetCurvedElements().CalcSurfaceTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic, curved); + + if (dxdxi) + *dxdxi = dxdxic * trans; + + return; + } + + + + Vector shapes; + DenseMatrix dshapes; + ARRAY > coefs; + + const Element2d & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + SurfaceElementInfo info; + info.elnr = elnr; + info.order = order; + + switch (type) + { + case TRIG : info.nv = 3; break; + case QUAD : info.nv = 4; break; + case TRIG6: info.nv = 6; break; + default: + cerr << "undef element in CalcSurfaceTrafo" << endl; + } + info.ndof = info.nv; + + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + for (int i = 0; i < info.edgenrs.Size(); i++) + info.edgenrs[i]--; + info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + + bool firsttry = true; + bool problem = false; + + while(firsttry || problem) + { + problem = false; + + for (int i = 0; !problem && i < info.edgenrs.Size(); i++) + { + if(info.edgenrs[i]+1 >= edgecoeffsindex.Size()) + problem = true; + else + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + } + if(info.facenr+1 >= facecoeffsindex.Size()) + problem = true; + else + info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + + if(problem && !firsttry) + throw NgException("something wrong with curved elements"); + + if(problem) + BuildCurvedElements(NULL,order,rational); + + firsttry = false; + } + } + + CalcElementShapes (info, xi, shapes); + GetCoefficients (info, coefs); + + *x = 0; + for (int i = 0; i < coefs.Size(); i++) + *x += shapes(i) * coefs[i]; + + if (dxdxi) + { + CalcElementDShapes (info, xi, dshapes); + + *dxdxi = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + (*dxdxi)(j,k) += dshapes(i,k) * coefs[i](j); + } + + if (curved) + *curved = (info.ndof > info.nv); + } + + + + + void CurvedElements :: + CalcElementShapes (SurfaceElementInfo & info, const Point<2> & xi, Vector & shapes) const + { + const Element2d & el = mesh[info.elnr]; + + shapes.SetSize(info.ndof); + shapes = 0; + + if (rational && info.order >= 2) + { + shapes.SetSize(6); + double w = 1; + double lami[3] = { xi(0), xi(1), 1-xi(0)-xi(1) }; + for (int j = 0; j < 3; j++) + shapes(j) = lami[j] * lami[j]; + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TRIG); + for (int j = 0; j < 3; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + shapes(j+3) = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + } + + shapes *= 1.0 / w; + return; + } + + switch (el.GetType()) + { + case TRIG: + { + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = 1-xi(0)-xi(1); + + if (info.order == 1) return; + + int ii = 3; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TRIG); + + for (int i = 0; i < 3; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, shapes(vi1)-shapes(vi2), shapes(vi1)+shapes(vi2), &shapes(ii)); + ii += eorder-1; + } + } + + int forder = faceorder[info.facenr]; + if (forder >= 3) + { + int fnums[] = { 0, 1, 2 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcTrigShape (forder, + shapes(fnums[1])-shapes(fnums[0]), + 1-shapes(fnums[1])-shapes(fnums[0]), &shapes(ii)); + } + break; + } + + case TRIG6: + { + if (shapes.Size() == 3) + { + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = 1-xi(0)-xi(1); + } + else + { + double x = xi(0); + double y = xi(1); + double lam3 = 1-x-y; + + shapes(0) = x * (2*x-1); + shapes(1) = y * (2*y-1); + shapes(2) = lam3 * (2*lam3-1); + shapes(3) = 4 * y * lam3; + shapes(4) = 4 * x * lam3; + shapes(5) = 4 * x * y; + } + break; + } + + case QUAD: + { + shapes(0) = (1-xi(0))*(1-xi(1)); + shapes(1) = xi(0) *(1-xi(1)); + shapes(2) = xi(0) * xi(1) ; + shapes(3) = (1-xi(0))* xi(1) ; + + if (info.order == 1) return; + + double mu[4] = { + 1 - xi(0) + 1 - xi(1), + xi(0) + 1 - xi(1), + xi(0) + xi(1), + 1 - xi(0) + xi(1), + }; + + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (QUAD); + + for (int i = 0; i < 4; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcEdgeShape (eorder, mu[vi1]-mu[vi2], &shapes(ii)); + double lame = shapes(vi1)+shapes(vi2); + for (int j = 0; j < order-1; j++) + shapes(ii+j) *= lame; + ii += eorder-1; + } + } + + for (int i = ii; i < info.ndof; i++) + shapes(i) = 0; + + break; + } + }; + } + + + void CurvedElements :: + CalcElementDShapes (SurfaceElementInfo & info, const Point<2> & xi, DenseMatrix & dshapes) const + { + const Element2d & el = mesh[info.elnr]; + ELEMENT_TYPE type = el.GetType(); + + double lami[4]; + + dshapes.SetSize(info.ndof,2); + dshapes = 0; + + // *testout << "calcelementdshapes, info.ndof = " << info.ndof << endl; + + if (rational && info.order >= 2) + { + double w = 1; + double dw[2] = { 0, 0 }; + + + lami[0] = xi(0); lami[1] = xi(1); lami[2] = 1-xi(0)-xi(1); + double dlami[3][2] = { { 1, 0 }, { 0, 1 }, { -1, -1 }}; + double shapes[6]; + + for (int j = 0; j < 3; j++) + { + shapes[j] = lami[j] * lami[j]; + dshapes(j,0) = 2 * lami[j] * dlami[j][0]; + dshapes(j,1) = 2 * lami[j] * dlami[j][1]; + } + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TRIG); + for (int j = 0; j < 3; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + + shapes[j+3] = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 2; k++) + dshapes(j+3,k) = 2*wi* (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 2; k++) + dw[k] += 2*(wi-1) * (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + } + // shapes *= 1.0 / w; + dshapes *= 1.0 / w; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 2; j++) + dshapes(i,j) -= shapes[i] * dw[j] / (w*w); + return; + } + + + + + + switch (type) + { + case TRIG: + { + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,0) = -1; + dshapes(2,1) = -1; + + if (info.order == 1) return; + + // *testout << "info.order = " << info.order << endl; + + + lami[0] = xi(0); + lami[1] = xi(1); + lami[2] = 1-xi(0)-xi(1); + + int ii = 3; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TRIG); + + for (int i = 0; i < 3; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShapeDxDt<2> (eorder, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &dshapes(ii,0)); + + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dshapes(vi1,j)-dshapes(vi2,j); + trans(1,j) = dshapes(vi1,j)+dshapes(vi2,j); + } + + for (int j = 0; j < eorder-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + + ii += eorder-1; + } + } + + int forder = faceorder[info.facenr]; + // *testout << "forder = " << forder << endl; + if (forder >= 3) + { + int fnums[] = { 0, 1, 2 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcTrigShapeDxDy (forder, + lami[fnums[1]]-lami[fnums[0]], + 1-lami[fnums[1]]-lami[fnums[0]], &dshapes(ii,0)); + + int nd = (forder-1)*(forder-2)/2; + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dshapes(fnums[1],j)-dshapes(fnums[0],j); + trans(1,j) = -dshapes(fnums[1],j)-dshapes(fnums[0],j); + } + + for (int j = 0; j < nd; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + } + + break; + } + + case TRIG6: + { + if (dshapes.Height() == 3) + { + dshapes = 0.0; + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,0) = -1; + dshapes(2,1) = -1; + } + else + { + AutoDiff<2> x(xi(0), 0); + AutoDiff<2> y(xi(1), 1); + AutoDiff<2> lam3 = 1-x-y; + AutoDiff<2> shapes[6]; + shapes[0] = x * (2*x-1); + shapes[1] = y * (2*y-1); + shapes[2] = lam3 * (2*lam3-1); + shapes[3] = 4 * y * lam3; + shapes[4] = 4 * x * lam3; + shapes[5] = 4 * x * y; + + for (int i = 0; i < 6; i++) + { + dshapes(i,0) = shapes[i].DValue(0); + dshapes(i,1) = shapes[i].DValue(1); + } + + } + break; + } + + case QUAD: + { + dshapes(0,0) = -(1-xi(1)); + dshapes(0,1) = -(1-xi(0)); + dshapes(1,0) = (1-xi(1)); + dshapes(1,1) = -xi(0); + dshapes(2,0) = xi(1); + dshapes(2,1) = xi(0); + dshapes(3,0) = -xi(1); + dshapes(3,1) = (1-xi(0)); + + if (info.order == 1) return; + + double shapes[4] = { + (1-xi(0))*(1-xi(1)), + xi(0) *(1-xi(1)), + xi(0) * xi(1) , + (1-xi(0))* xi(1) + }; + + double mu[4] = { + 1 - xi(0) + 1 - xi(1), + xi(0) + 1 - xi(1), + xi(0) + xi(1), + 1 - xi(0) + xi(1), + }; + + double dmu[4][2] = { + { -1, -1 }, + { 1, -1 }, + { 1, 1 }, + { -1, 1 } }; + + // double hshapes[20], hdshapes[20]; + ArrayMem hshapes(order+1), hdshapes(order+1); + + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (QUAD); + + for (int i = 0; i < 4; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcEdgeShapeDx (eorder, mu[vi1]-mu[vi2], &hshapes[0], &hdshapes[0]); + + double lame = shapes[vi1]+shapes[vi2]; + double dlame[2] = { + dshapes(vi1, 0) + dshapes(vi2, 0), + dshapes(vi1, 1) + dshapes(vi2, 1) }; + + for (int j = 0; j < eorder-1; j++) + for (int k = 0; k < 2; k++) + dshapes(ii+j, k) = + lame * hdshapes[j] * (dmu[vi1][k]-dmu[vi2][k]) + + dlame[k] * hshapes[j]; + + ii += eorder-1; + } + } + + /* + *testout << "quad, dshape = " << endl << dshapes << endl; + for (int i = 0; i < 2; i++) + { + Point<2> xil = xi, xir = xi; + Vector shapesl(dshapes.Height()), shapesr(dshapes.Height()); + xil(i) -= 1e-6; + xir(i) += 1e-6; + CalcElementShapes (info, xil, shapesl); + CalcElementShapes (info, xir, shapesr); + + for (int j = 0; j < dshapes.Height(); j++) + dshapes(j,i) = 1.0 / 2e-6 * (shapesr(j)-shapesl(j)); + } + + *testout << "quad, num dshape = " << endl << dshapes << endl; + */ + break; + } + }; + } + + + + void CurvedElements :: + GetCoefficients (SurfaceElementInfo & info, ARRAY > & coefs) const + { + const Element2d & el = mesh[info.elnr]; + coefs.SetSize (info.ndof); + // coefs = Vec<3> (0,0,0); + + for (int i = 0; i < info.nv; i++) + coefs[i] = Vec<3> (mesh[el[i]]); + + if (info.order == 1) return; + + int ii = info.nv; + + for (int i = 0; i < info.edgenrs.Size(); i++) + { + int first = edgecoeffsindex[info.edgenrs[i]]; + int next = edgecoeffsindex[info.edgenrs[i]+1]; + for (int j = first; j < next; j++, ii++) + coefs[ii] = edgecoeffs[j]; + } + + int first = facecoeffsindex[info.facenr]; + int next = facecoeffsindex[info.facenr+1]; + for (int j = first; j < next; j++, ii++) + coefs[ii] = facecoeffs[j]; + } + + + + + + + + // ********************** Transform volume elements ******************* + + + bool CurvedElements :: IsElementCurved (ElementIndex elnr) const + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsElementCurved (hpref_el.coarse_elnr); + } + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + } + + return (info.ndof > info.nv); + } + + + + + + + void CurvedElements :: + CalcElementTransformation (Point<3> xi, ElementIndex elnr, + Point<3> * x, Mat<3,3> * dxdxi, // bool * curved, + void * buffer, bool valid) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[8]; + FlatVector vlami(8, lami); + vlami = 0; + mesh[elnr].GetShapeNew (xi, vlami); + + Mat<3,3> trans, dxdxic; + if (dxdxi) + { + MatrixFixWidth<3> dlami(8); + dlami = 0; + mesh[elnr].GetDShapeNew (xi, dlami); + + trans = 0; + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + } + + Point<3> coarse_xi(0,0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 3; j++) + coarse_xi(j) += hpref_el.param[i][j] * lami[i]; + + mesh.coarsemesh->GetCurvedElements().CalcElementTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic /* , curved */); + + if (dxdxi) + *dxdxi = dxdxic * trans; + + return; + } + + + Vector shapes; + MatrixFixWidth<3> dshapes; + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo hinfo; + ElementInfo & info = (buffer) ? *static_cast (buffer) : hinfo; + + + if (!valid) + { + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + } + } + + CalcElementShapes (info, xi, shapes); + + Vec<3> * coefs = (info.ndof <= 10) ? + &info.hcoefs[0] : new Vec<3> [info.ndof]; + + if (info.ndof > 10 || !valid) + GetCoefficients (info, coefs); + + if (x) + { + *x = 0; + for (int i = 0; i < shapes.Size(); i++) + *x += shapes(i) * coefs[i]; + } + + if (dxdxi) + { + if (valid && info.order == 1 && info.nv == 4) // a linear tet + { + *dxdxi = info.hdxdxi; + } + else + { + CalcElementDShapes (info, xi, dshapes); + + *dxdxi = 0; + for (int i = 0; i < shapes.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + (*dxdxi)(j,k) += dshapes(i,k) * coefs[i](j); + + info.hdxdxi = *dxdxi; + } + } + + // *testout << "curved_elements, dshapes = " << endl << dshapes << endl; + + // if (curved) *curved = (info.ndof > info.nv); + + if (info.ndof > 10) delete [] coefs; + } + + + + + void CurvedElements :: CalcElementShapes (ElementInfo & info, const Point<3> & xi, Vector & shapes) const + { + const Element & el = mesh[info.elnr]; + + if (rational && info.order >= 2) + { + shapes.SetSize(10); + double w = 1; + double lami[4] = { xi(0), xi(1), xi(2), 1-xi(0)-xi(1)-xi(2) }; + for (int j = 0; j < 4; j++) + shapes(j) = lami[j] * lami[j]; + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TET); + for (int j = 0; j < 6; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + shapes(j+4) = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + } + + shapes *= 1.0 / w; + return; + } + + shapes.SetSize(info.ndof); + + switch (el.GetType()) + { + case TET: + { + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = xi(2); + shapes(3) = 1-xi(0)-xi(1)-xi(2); + + if (info.order == 1) return; + + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TET); + for (int i = 0; i < 6; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, shapes(vi1)-shapes(vi2), shapes(vi1)+shapes(vi2), &shapes(ii)); + ii += eorder-1; + } + } + const ELEMENT_FACE * faces = MeshTopology::GetFaces (TET); + for (int i = 0; i < 4; i++) + { + int forder = faceorder[info.facenrs[i]]; + if (forder >= 3) + { + int fnums[] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcScaledTrigShape (forder, + shapes(fnums[1])-shapes(fnums[0]), shapes(fnums[2]), + shapes(fnums[0])+shapes(fnums[1])+shapes(fnums[2]), &shapes(ii)); + ii += (forder-1)*(forder-2)/2; + // CalcScaledEdgeShape (forder, shapes(vi1)-shapes(vi2), shapes(vi1)+shapes(vi2), &shapes(ii)); + // ii += forder-1; + } + } + + + break; + } + + case TET10: + { + double x = xi(0); + double y = xi(1); + double z = xi(2); + double lam4 = 1 - x - y - z; + /* + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = xi(2); + shapes(3) = 1-xi(0)-xi(1)-xi(2); + */ + + shapes(0) = 2 * x * x - x; + shapes(1) = 2 * y * y - y; + shapes(2) = 2 * z * z - z; + shapes(3) = 2 * lam4 * lam4 - lam4; + + shapes(4) = 4 * x * y; + shapes(5) = 4 * x * z; + shapes(6) = 4 * x * lam4; + shapes(7) = 4 * y * z; + shapes(8) = 4 * y * lam4; + shapes(9) = 4 * z * lam4; + + break; + } + + case PRISM: + { + double lami[6] = { xi(0), xi(1), 1-xi(0)-xi(1), xi(0), xi(1), 1-xi(0)-xi(1) }; + double lamiz[6] = { 1-xi(2), 1-xi(2), 1-xi(2), xi(2), xi(2), xi(2) }; + for (int i = 0; i < 6; i++) + shapes(i) = lami[i%3] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + for (int i = 6; i < info.ndof; i++) + shapes(i) = 0; + + if (info.order == 1) return; + + + int ii = 6; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (PRISM); + for (int i = 0; i < 6; i++) // horizontal edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = (edges[i][0]-1) % 3, vi2 = (edges[i][1]-1) % 3; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &shapes(ii)); + double facz = (i < 3) ? (1-xi(2)) : xi(2); + for (int j = 0; j < eorder-1; j++) + shapes(ii+j) *= facz; + + ii += eorder-1; + } + } + + for (int i = 6; i < 9; i++) // vertical edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = (edges[i][0]-1), vi2 = (edges[i][1]-1); + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + double bubz = lamiz[vi1]*lamiz[vi2]; + double polyz = lamiz[vi1] - lamiz[vi2]; + double bubxy = lami[(vi1)%3]; + + for (int j = 0; j < eorder-1; j++) + { + shapes(ii+j) = bubxy * bubz; + bubz *= polyz; + } + ii += eorder-1; + } + } + + // FACE SHAPES + const ELEMENT_FACE * faces = MeshTopology::GetFaces (PRISM); + for (int i = 0; i < 2; i++) + { + int forder = faceorder[info.facenrs[i]]; + if ( forder < 3 ) continue; + int fav[3] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + if(el[fav[1]] > el[fav[2]]) swap(fav[1],fav[2]); + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + + CalcTrigShape (forder, + lami[fav[2]]-lami[fav[1]], lami[fav[0]], + &shapes(ii)); + + int ndf = (forder+1)*(forder+2)/2 - 3 - 3*(forder-1); + for ( int j = 0; j < ndf; j++ ) + shapes(ii+j) *= lamiz[fav[1]]; + ii += ndf; + } + break; + } + + case PYRAMID: + { + shapes = 0.0; + double x = xi(0); + double y = xi(1); + double z = xi(2); + + if (z == 1.) z = 1-1e-10; + shapes[0] = (1-z-x)*(1-z-y) / (1-z); + shapes[1] = x*(1-z-y) / (1-z); + shapes[2] = x*y / (1-z); + shapes[3] = (1-z-x)*y / (1-z); + shapes[4] = z; + + if (info.order == 1) return; + + int ii = 5; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (PYRAMID); + for (int i = 0; i < 4; i++) // horizontal edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = (edges[i][0]-1), vi2 = (edges[i][1]-1); + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, shapes[vi1]-shapes[vi2], shapes[vi1]+shapes[vi2], &shapes(ii)); + double fac = (shapes[vi1]+shapes[vi2]) / (1-z); + for (int j = 0; j < eorder-1; j++) + shapes(ii+j) *= fac; + + ii += eorder-1; + } + } + + + + break; + } + + case HEX: + { + shapes = 0.0; + double x = xi(0); + double y = xi(1); + double z = xi(2); + + shapes[0] = (1-x)*(1-y)*(1-z); + shapes[1] = x *(1-y)*(1-z); + shapes[2] = x * y *(1-z); + shapes[3] = (1-x)* y *(1-z); + shapes[4] = (1-x)*(1-y)*(z); + shapes[5] = x *(1-y)*(z); + shapes[6] = x * y *(z); + shapes[7] = (1-x)* y *(z); + break; + } + }; + } + + + void CurvedElements :: + CalcElementDShapes (ElementInfo & info, const Point<3> & xi, MatrixFixWidth<3> & dshapes) const + { + const Element & el = mesh[info.elnr]; + + dshapes.SetSize(info.ndof); + dshapes = 0.0; + + + + if (rational && info.order >= 2) + { + double w = 1; + double dw[3] = { 0, 0, 0 }; + + double lami[4] = { xi(0), xi(1), xi(2), 1-xi(0)-xi(1)-xi(2) }; + double dlami[4][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { -1, -1, -1 }}; + double shapes[10]; + + for (int j = 0; j < 4; j++) + { + shapes[j] = lami[j] * lami[j]; + dshapes(j,0) = 2 * lami[j] * dlami[j][0]; + dshapes(j,1) = 2 * lami[j] * dlami[j][1]; + dshapes(j,2) = 2 * lami[j] * dlami[j][2]; + } + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TET); + for (int j = 0; j < 6; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + + shapes[j+4] = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 3; k++) + dshapes(j+4,k) = 2*wi* (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 3; k++) + dw[k] += 2*(wi-1) * (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + } + // shapes *= 1.0 / w; + dshapes *= 1.0 / w; + for (int i = 0; i < 10; i++) + for (int j = 0; j < 3; j++) + dshapes(i,j) -= shapes[i] * dw[j] / (w*w); + return; + } + + switch (el.GetType()) + { + case TET: + { + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,2) = 1; + dshapes(3,0) = -1; + dshapes(3,1) = -1; + dshapes(3,2) = -1; + + if (info.order == 1) return; + + double lami[] = { xi(0), xi(1), xi(2), 1-xi(0)-xi(1)-xi(2) }; + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (TET); + for (int i = 0; i < 6; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShapeDxDt<3> (eorder, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &dshapes(ii,0)); + + Mat<2,3> trans; + for (int j = 0; j < 3; j++) + { + trans(0,j) = dshapes(vi1,j)-dshapes(vi2,j); + trans(1,j) = dshapes(vi1,j)+dshapes(vi2,j); + } + + for (int j = 0; j < order-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + dshapes(ii+j,2) = ddx * trans(0,2) + ddt * trans(1,2); + } + + ii += eorder-1; + } + } + + const ELEMENT_FACE * faces = MeshTopology::GetFaces (TET); + for (int i = 0; i < 4; i++) + { + int forder = faceorder[info.facenrs[i]]; + if (forder >= 3) + { + int fnums[] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcScaledTrigShapeDxDyDt (forder, + lami[fnums[1]]-lami[fnums[0]], + lami[fnums[2]], lami[fnums[0]]+lami[fnums[1]]+lami[fnums[2]], + &dshapes(ii,0)); + + Mat<3,3> trans; + for (int j = 0; j < 3; j++) + { + trans(0,j) = dshapes(fnums[1],j)-dshapes(fnums[0],j); + trans(1,j) = dshapes(fnums[2],j); + trans(2,j) = dshapes(fnums[0],j)+dshapes(fnums[1],j)+dshapes(fnums[2],j); + } + + int nfd = (forder-1)*(forder-2)/2; + for (int j = 0; j < nfd; j++) + { + double ddx = dshapes(ii+j,0); + double ddy = dshapes(ii+j,1); + double ddt = dshapes(ii+j,2); + dshapes(ii+j,0) = ddx * trans(0,0) + ddy * trans(1,0) + ddt * trans(2,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddy * trans(1,1) + ddt * trans(2,1); + dshapes(ii+j,2) = ddx * trans(0,2) + ddy * trans(1,2) + ddt * trans(2,2); + } + + ii += nfd; + } + } + + break; + } + + case TET10: + { + if (dshapes.Height() == 4) + { + dshapes = 0.0; + + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,2) = 1; + dshapes(3,0) = -1; + dshapes(3,1) = -1; + dshapes(3,2) = -1; + } + else + { + AutoDiff<3> x(xi(0), 0); + AutoDiff<3> y(xi(1), 1); + AutoDiff<3> z(xi(2), 2); + AutoDiff<3> lam4 = 1-x-y-z; + AutoDiff<3> shapes[10]; + + shapes[0] = 2 * x * x - x; + shapes[1] = 2 * y * y - y; + shapes[2] = 2 * z * z - z; + shapes[3] = 2 * lam4 * lam4 - lam4; + + shapes[4] = 4 * x * y; + shapes[5] = 4 * x * z; + shapes[6] = 4 * x * lam4; + shapes[7] = 4 * y * z; + shapes[8] = 4 * y * lam4; + shapes[9] = 4 * z * lam4; + + for (int i = 0; i < 10; i++) + { + dshapes(i,0) = shapes[i].DValue(0); + dshapes(i,1) = shapes[i].DValue(1); + dshapes(i,2) = shapes[i].DValue(2); + } + + } + break; + + break; + } + + + case PRISM: + { + double lami[6] = { xi(0), xi(1), 1-xi(0)-xi(1), xi(0), xi(1), 1-xi(0)-xi(1) }; + double lamiz[6] = { 1-xi(2), 1-xi(2), 1-xi(2), xi(2), xi(2), xi(2) }; + double dlamiz[6] = { -1, -1, -1, 1, 1, 1 }; + double dlami[6][2] = + { { 1, 0, }, + { 0, 1, }, + { -1, -1 }, + { 1, 0, }, + { 0, 1, }, + { -1, -1 } }; + for (int i = 0; i < 6; i++) + { + // shapes(i) = lami[i%3] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + dshapes(i,0) = dlami[i%3][0] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + dshapes(i,1) = dlami[i%3][1] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + dshapes(i,2) = lami[i%3] * ( (i < 3) ? -1 : 1 ); + } + + int ii = 6; + + if (info.order == 1) return; + + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges (PRISM); + for (int i = 0; i < 6; i++) // horizontal edges + { + int order = edgeorder[info.edgenrs[i]]; + if (order >= 2) + { + int vi1 = (edges[i][0]-1) % 3, vi2 = (edges[i][1]-1) % 3; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + Vector shapei(order+1); + CalcScaledEdgeShapeDxDt<3> (order, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &dshapes(ii,0) ); + CalcScaledEdgeShape(order, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &shapei(0) ); + + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dlami[vi1][j]-dlami[vi2][j]; + trans(1,j) = dlami[vi1][j]+dlami[vi2][j]; + } + + for (int j = 0; j < order-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + + + + double facz = (i < 3) ? (1-xi(2)) : xi(2); + double dfacz = (i < 3) ? (-1) : 1; + for (int j = 0; j < order-1; j++) + { + dshapes(ii+j,0) *= facz; + dshapes(ii+j,1) *= facz; + dshapes(ii+j,2) = shapei(j) * dfacz; + } + + ii += order-1; + } + } + for (int i = 6; i < 9; i++) // vertical edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = (edges[i][0]-1), vi2 = (edges[i][1]-1); + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + double bubz = lamiz[vi1] * lamiz[vi2]; + double dbubz = dlamiz[vi1]*lamiz[vi2] + lamiz[vi1]*dlamiz[vi2]; + double polyz = lamiz[vi1] - lamiz[vi2]; + double dpolyz = dlamiz[vi1] - dlamiz[vi2]; + double bubxy = lami[(vi1)%3]; + double dbubxydx = dlami[(vi1)%3][0]; + double dbubxydy = dlami[(vi1)%3][1]; + + for (int j = 0; j < eorder-1; j++) + { + dshapes(ii+j,0) = dbubxydx * bubz; + dshapes(ii+j,1) = dbubxydy * bubz; + dshapes(ii+j,2) = bubxy * dbubz; + + dbubz = bubz * dpolyz + dbubz * polyz; + bubz *= polyz; + } + ii += eorder-1; + } + } + + + if (info.order == 2) return; + // FACE SHAPES + const ELEMENT_FACE * faces = MeshTopology::GetFaces (PRISM); + for (int i = 0; i < 2; i++) + { + int forder = faceorder[info.facenrs[i]]; + if ( forder < 3 ) continue; + int ndf = (forder+1)*(forder+2)/2 - 3 - 3*(forder-1); + + int fav[3] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + if(el[fav[1]] > el[fav[2]]) swap(fav[1],fav[2]); + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + + MatrixFixWidth<2> dshapei(ndf); + Vector shapei(ndf); + + CalcTrigShapeDxDy (forder, + lami[fav[2]]-lami[fav[1]], lami[fav[0]], + &dshapei(0,0)); + CalcTrigShape (forder, lami[fav[2]]-lami[fav[1]], lami[fav[0]], + &shapei(0)); + + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dlami[fav[2]][j]-dlami[fav[1]][j]; + trans(1,j) = dlami[fav[0]][j]; + } + + for (int j = 0; j < order-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + + for ( int j = 0; j < ndf; j++ ) + { + dshapes(ii+j,0) *= lamiz[fav[1]]; + dshapes(ii+j,1) *= lamiz[fav[1]]; + dshapes(ii+j,2) = shapei(j) * dlamiz[fav[1]]; + } + ii += ndf; + } + + break; + + } + + case PYRAMID: + { + dshapes = 0.0; + double x = xi(0); + double y = xi(1); + double z = xi(2); + + if (z == 1.) z = 1-1e-10; + double z1 = 1-z; + double z2 = z1*z1; + + dshapes(0,0) = -(z1-y)/z1; + dshapes(0,1) = -(z1-x)/z1; + dshapes(0,2) = ((x+y+2*z-2)*z1+(z1-y)*(z1-x))/z2; + + dshapes(1,0) = (z1-y)/z1; + dshapes(1,1) = -x/z1; + dshapes(1,2) = (-x*z1+x*(z1-y))/z2; + + dshapes(2,0) = y/z1; + dshapes(2,1) = x/z1; + dshapes(2,2) = x*y/z2; + + dshapes(3,0) = -y/z1; + dshapes(3,1) = (z1-x)/z1; + dshapes(3,2) = (-y*z1+y*(z1-x))/z2; + + dshapes(4,0) = 0; + dshapes(4,1) = 0; + dshapes(4,2) = 1; + /* old: + 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 ); + */ + break; + } + + case HEX: + { + dshapes = 0.0; + + double x = xi(0); + double y = xi(1); + double z = xi(2); + + // shapes[0] = (1-x)*(1-y)*(1-z); + dshapes(0,0) = - (1-y)*(1-z); + dshapes(0,1) = (1-x) * (-1) * (1-z); + dshapes(0,2) = (1-x) * (1-y) * (-1); + + // shapes[1] = x *(1-y)*(1-z); + dshapes(1,0) = (1-y)*(1-z); + dshapes(1,1) = -x * (1-z); + dshapes(1,2) = -x * (1-y); + + // shapes[2] = x * y *(1-z); + dshapes(2,0) = y * (1-z); + dshapes(2,1) = x * (1-z); + dshapes(2,2) = -x * y; + + // shapes[3] = (1-x)* y *(1-z); + dshapes(3,0) = -y * (1-z); + dshapes(3,1) = (1-x) * (1-z); + dshapes(3,2) = -(1-x) * y; + + // shapes[4] = (1-x)*(1-y)*z; + dshapes(4,0) = - (1-y)*z; + dshapes(4,1) = (1-x) * (-1) * z; + dshapes(4,2) = (1-x) * (1-y) * 1; + + // shapes[5] = x *(1-y)*z; + dshapes(5,0) = (1-y)*z; + dshapes(5,1) = -x * z; + dshapes(5,2) = x * (1-y); + + // shapes[6] = x * y *z; + dshapes(6,0) = y * z; + dshapes(6,1) = x * z; + dshapes(6,2) = x * y; + + // shapes[7] = (1-x)* y *z; + dshapes(7,0) = -y * z; + dshapes(7,1) = (1-x) * z; + dshapes(7,2) = (1-x) * y; + + break; + } + } + + /* + DenseMatrix dshapes2 (info.ndof, 3); + Vector shapesl(info.ndof); + Vector shapesr(info.ndof); + + double eps = 1e-6; + for (int i = 0; i < 3; i++) + { + Point<3> xl = xi; + Point<3> xr = xi; + + xl(i) -= eps; + xr(i) += eps; + CalcElementShapes (info, xl, shapesl); + CalcElementShapes (info, xr, shapesr); + + for (int j = 0; j < info.ndof; j++) + dshapes2(j,i) = (shapesr(j)-shapesl(j)) / (2*eps); + } + (*testout) << "dshapes = " << endl << dshapes << endl; + (*testout) << "dshapes2 = " << endl << dshapes2 << endl; + dshapes2 -= dshapes; + (*testout) << "diff = " << endl << dshapes2 << endl; + */ + } + + + + void CurvedElements :: + GetCoefficients (ElementInfo & info, Vec<3> * coefs) const + { + // cout << "getcoeffs, info.elnr = " << info.elnr << endl; + // cout << "getcoeffs, info.nv = " << info.nv << endl; + + const Element & el = mesh[info.elnr]; + + /* + coefs.SetSize (info.ndof); + coefs = Vec<3> (0,0,0); + */ + /* + for (int i = 0; i < info.ndof; i++) + coefs[i] = Vec<3> (0,0,0); + */ + for (int i = 0; i < info.nv; i++) + coefs[i] = Vec<3> (mesh[el[i]]); + + if (info.order == 1) return; + + int ii = info.nv; + + for (int i = 0; i < info.nedges; i++) + { + int first = edgecoeffsindex[info.edgenrs[i]]; + int next = edgecoeffsindex[info.edgenrs[i]+1]; + for (int j = first; j < next; j++, ii++) + coefs[ii] = edgecoeffs[j]; + } + for (int i = 0; i < info.nfaces; i++) + { + int first = facecoeffsindex[info.facenrs[i]]; + int next = facecoeffsindex[info.facenrs[i]+1]; + for (int j = first; j < next; j++, ii++) + coefs[ii] = facecoeffs[j]; + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + void CurvedElements :: + CalcMultiPointSegmentTransformation (ARRAY * xi, SegmentIndex segnr, + ARRAY > * x, + ARRAY > * dxdxi) + { + ; + } + + void CurvedElements :: + CalcMultiPointSurfaceTransformation (ARRAY< Point<2> > * xi, SurfaceElementIndex elnr, + ARRAY< Point<3> > * x, + ARRAY< Mat<3,2> > * dxdxi) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[4]; + FlatVector vlami(4, lami); + + ArrayMem, 50> coarse_xi (xi->Size()); + + for (int pi = 0; pi < xi->Size(); pi++) + { + vlami = 0; + mesh[elnr].GetShapeNew ( (*xi)[pi], vlami); + + Point<2> cxi(0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 2; j++) + cxi(j) += hpref_el.param[i][j] * lami[i]; + + coarse_xi[pi] = cxi; + } + + mesh.coarsemesh->GetCurvedElements(). + CalcMultiPointSurfaceTransformation (&coarse_xi, hpref_el.coarse_elnr, x, dxdxi); + + + Mat<2,2> trans; + Mat<3,2> dxdxic; + if (dxdxi) + { + MatrixFixWidth<2> dlami(4); + dlami = 0; + + for (int pi = 0; pi < xi->Size(); pi++) + { + mesh[elnr].GetDShapeNew ( (*xi)[pi], dlami); + + trans = 0; + for (int k = 0; k < 2; k++) + for (int l = 0; l < 2; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + + dxdxic = (*dxdxi)[pi]; + (*dxdxi)[pi] = dxdxic * trans; + } + } + + return; + } + + + + + + Vector shapes; + DenseMatrix dshapes; + ARRAY > coefs; + + + const Element2d & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + SurfaceElementInfo info; + info.elnr = elnr; + info.order = order; + switch (type) + { + case TRIG : info.nv = 3; break; + case QUAD : info.nv = 4; break; + case TRIG6: info.nv = 6; break; + default: + cerr << "undef element in CalcMultPointSurfaceTrao" << endl; + } + info.ndof = info.nv; + + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + for (int i = 0; i < info.edgenrs.Size(); i++) + info.edgenrs[i]--; + info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + for (int i = 0; i < info.edgenrs.Size(); i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + GetCoefficients (info, coefs); + if (x) + { + for (int j = 0; j < xi->Size(); j++) + { + CalcElementShapes (info, (*xi)[j], shapes); + Point<3> val(0,0,0); + for (int i = 0; i < coefs.Size(); i++) + val += shapes(i) * coefs[i]; + (*x)[j] = val; + } + } + + if (dxdxi) + { + for (int ip = 0; ip < xi->Size(); ip++) + { + CalcElementDShapes (info, (*xi)[ip], dshapes); + + /* + (*dxdxi)[ip] = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + (*dxdxi)[ip](j,k) += dshapes(i,k) * coefs[i](j); + */ + + Mat<3,2> ds; + ds = 0.0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + ds(j,k) += dshapes(i,k) * coefs[i](j); + (*dxdxi)[ip] = ds; + } + } + } + + void CurvedElements :: + CalcMultiPointElementTransformation (ARRAY< Point<3> > * xi, ElementIndex elnr, + ARRAY< Point<3> > * x, + ARRAY< Mat<3,3> > * dxdxi) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[8]; + FlatVector vlami(8, lami); + + + ArrayMem, 50> coarse_xi (xi->Size()); + + for (int pi = 0; pi < xi->Size(); pi++) + { + vlami = 0; + mesh[elnr].GetShapeNew ( (*xi)[pi], vlami); + + Point<3> cxi(0,0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 3; j++) + cxi(j) += hpref_el.param[i][j] * lami[i]; + + coarse_xi[pi] = cxi; + } + + mesh.coarsemesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&coarse_xi, hpref_el.coarse_elnr, x, dxdxi); + + + Mat<3,3> trans, dxdxic; + if (dxdxi) + { + MatrixFixWidth<3> dlami(8); + dlami = 0; + + for (int pi = 0; pi < xi->Size(); pi++) + { + mesh[elnr].GetDShapeNew ( (*xi)[pi], dlami); + + trans = 0; + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + + dxdxic = (*dxdxi)[pi]; + (*dxdxi)[pi] = dxdxic * trans; + } + } + + return; + } + + + + + + + + + Vector shapes; + MatrixFixWidth<3> dshapes; + + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + // info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + ARRAY > coefs(info.ndof); + GetCoefficients (info, &coefs[0]); + if (x) + { + for (int j = 0; j < xi->Size(); j++) + { + CalcElementShapes (info, (*xi)[j], shapes); + (*x)[j] = 0; + for (int i = 0; i < coefs.Size(); i++) + (*x)[j] += shapes(i) * coefs[i]; + } + } + if (dxdxi) + { + for (int ip = 0; ip < xi->Size(); ip++) + { + CalcElementDShapes (info, (*xi)[ip], dshapes); + + /* + (*dxdxi)[ip] = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + (*dxdxi)[ip](j,k) += dshapes(i,k) * coefs[i](j); + */ + + Mat<3,3> ds; + ds = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + ds(j,k) += dshapes(i,k) * coefs[i](j); + (*dxdxi)[ip] = ds; + } + } + } + + + + + void CurvedElements :: + CalcMultiPointElementTransformation (ElementIndex elnr, int n, + const double * xi, int sxi, + double * x, int sx, + double * dxdxi, int sdxdxi) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[8]; + FlatVector vlami(8, lami); + + + ArrayMem coarse_xi (3*n); + + for (int pi = 0; pi < n; pi++) + { + vlami = 0; + Point<3> pxi; + for (int j = 0; j < 3; j++) + pxi(j) = xi[pi*sxi+j]; + + mesh[elnr].GetShapeNew ( pxi, vlami); + + Point<3> cxi(0,0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 3; j++) + cxi(j) += hpref_el.param[i][j] * lami[i]; + + for (int j = 0; j < 3; j++) + coarse_xi[3*pi+j] = cxi(j); + } + + mesh.coarsemesh->GetCurvedElements(). + CalcMultiPointElementTransformation (hpref_el.coarse_elnr, n, + &coarse_xi[0], 3, + x, sx, + dxdxi, sdxdxi); + + Mat<3,3> trans, dxdxic; + if (dxdxi) + { + MatrixFixWidth<3> dlami(8); + dlami = 0; + + for (int pi = 0; pi < n; pi++) + { + Point<3> pxi; + for (int j = 0; j < 3; j++) + pxi(j) = xi[pi*sxi+j]; + + mesh[elnr].GetDShapeNew (pxi, dlami); + + trans = 0; + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + + Mat<3> mat_dxdxic, mat_dxdxi; + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + mat_dxdxic(j,k) = dxdxi[pi*sdxdxi+3*j+k]; + + mat_dxdxi = mat_dxdxic * trans; + + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxi[pi*sdxdxi+3*j+k] = mat_dxdxi(j,k); + + // dxdxic = (*dxdxi)[pi]; + // (*dxdxi)[pi] = dxdxic * trans; + } + } + return; + } + + + + + + + + + Vector shapes; + MatrixFixWidth<3> dshapes; + + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + // info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + ARRAY > coefs(info.ndof); + GetCoefficients (info, &coefs[0]); + if (x) + { + for (int j = 0; j < n; j++) + { + Point<3> xij, xj; + for (int k = 0; k < 3; k++) + xij(k) = xi[j*sxi+k]; + + CalcElementShapes (info, xij, shapes); + xj = 0; + for (int i = 0; i < coefs.Size(); i++) + xj += shapes(i) * coefs[i]; + + for (int k = 0; k < 3; k++) + x[j*sx+k] = xj(k); + } + } + if (dxdxi) + { + for (int ip = 0; ip < n; ip++) + { + Point<3> xij; + for (int k = 0; k < 3; k++) + xij(k) = xi[ip*sxi+k]; + + CalcElementDShapes (info, xij, dshapes); + + Mat<3> dxdxij; + dxdxij = 0.0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxij(j,k) += dshapes(i,k) * coefs[i](j); + + + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxi[ip*sdxdxi+3*j+k] = dxdxij(j,k); + } + } + } + + + + + + + + + +}; + + +#endif diff --git a/libsrc/meshing/curvedelems_new.hpp b/libsrc/meshing/curvedelems_new.hpp new file mode 100644 index 00000000..ae049ae5 --- /dev/null +++ b/libsrc/meshing/curvedelems_new.hpp @@ -0,0 +1,209 @@ +#ifndef CURVEDELEMS_NEWH +#define CURVEDELEMS_NEWH + +/**************************************************************************/ +/* File: curvedelems.hpp */ +/* Author: Robert Gaisbauer (first version) */ +/* redesign by Joachim Schoeberl */ +/* Date: 27. Sep. 02, Feb 2006 */ +/**************************************************************************/ + + + + +class Refinement; + + +class CurvedElements +{ + const Mesh & mesh; + + ARRAY edgeorder; + ARRAY faceorder; + + ARRAY edgecoeffsindex; + ARRAY facecoeffsindex; + + ARRAY< Vec<3> > edgecoeffs; + ARRAY< Vec<3> > facecoeffs; + + ARRAY< double > edgeweight; // for rational 2nd order splines + + int order; + bool rational; + + bool ishighorder; + +public: + CurvedElements (const Mesh & amesh); + ~CurvedElements(); + + // bool IsHighOrder() const { return order > 1; } + bool IsHighOrder() const { return ishighorder; } + + // void SetHighOrder (int aorder) { order=aorder; } + void SetIsHighOrder (bool ho) { ishighorder = ho; } + + void BuildCurvedElements(Refinement * ref, int aorder, bool arational = false); + + int GetOrder () { return order; } + + + bool IsSegmentCurved (SegmentIndex segnr) const; + bool IsSurfaceElementCurved (SurfaceElementIndex sei) const; + bool IsElementCurved (ElementIndex ei) const; + + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> & x) + { CalcSegmentTransformation (xi, segnr, &x, NULL); }; + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Vec<3> & dxdxi) + { CalcSegmentTransformation (xi, segnr, NULL, &dxdxi); }; + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> & x, Vec<3> & dxdxi) + { CalcSegmentTransformation (xi, segnr, &x, &dxdxi, NULL); }; + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> & x, Vec<3> & dxdxi, bool & curved) + { CalcSegmentTransformation (xi, segnr, &x, &dxdxi, &curved); }; + + + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Point<3> & x) + { CalcSurfaceTransformation (xi, elnr, &x, NULL); }; + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Mat<3,2> & dxdxi) + { CalcSurfaceTransformation (xi, elnr, NULL, &dxdxi); }; + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Point<3> & x, Mat<3,2> & dxdxi) + { CalcSurfaceTransformation (xi, elnr, &x, &dxdxi, NULL); }; + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Point<3> & x, Mat<3,2> & dxdxi, bool & curved) + { CalcSurfaceTransformation (xi, elnr, &x, &dxdxi, &curved); }; + + + + + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Point<3> & x) + { CalcElementTransformation (xi, elnr, &x, NULL); }; + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Mat<3,3> & dxdxi) + { CalcElementTransformation (xi, elnr, NULL, &dxdxi); }; + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Point<3> & x, Mat<3,3> & dxdxi) + { CalcElementTransformation (xi, elnr, &x, &dxdxi /* , NULL */ ); }; + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Point<3> & x, Mat<3,3> & dxdxi, + void * buffer, bool valid) + { CalcElementTransformation (xi, elnr, &x, &dxdxi, /* NULL, */ buffer, valid ); }; + + // void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + // Point<3> & x, Mat<3,3> & dxdxi) // , bool & curved) + // { CalcElementTransformation (xi, elnr, &x, &dxdxi /* , &curved * ); } + + + + void CalcMultiPointSegmentTransformation (ARRAY * xi, SegmentIndex segnr, + ARRAY > * x, + ARRAY > * dxdxi); + + void CalcMultiPointSurfaceTransformation (ARRAY< Point<2> > * xi, SurfaceElementIndex elnr, + ARRAY< Point<3> > * x, + ARRAY< Mat<3,2> > * dxdxi); + + void CalcMultiPointElementTransformation (ARRAY< Point<3> > * xi, ElementIndex elnr, + ARRAY< Point<3> > * x, + ARRAY< Mat<3,3> > * dxdxi); + + void CalcMultiPointElementTransformation (ElementIndex elnr, int n, + const double * xi, int sxi, + double * x, int sx, + double * dxdxi, int sdxdxi); + + + + +private: + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> * x = NULL, Vec<3> * dxdxi = NULL, bool * curved = NULL); + + void CalcSurfaceTransformation (Point<2> xi, SurfaceElementIndex elnr, + Point<3> * x = NULL, Mat<3,2> * dxdxi = NULL, bool * curved = NULL); + + void CalcElementTransformation (Point<3> xi, ElementIndex elnr, + Point<3> * x = NULL, Mat<3,3> * dxdxi = NULL, // bool * curved = NULL, + void * buffer = NULL, bool valid = 0); + + + + + + + class SegmentInfo + { + public: + SegmentIndex elnr; + int order; + int nv; + int ndof; + int edgenr; + }; + + void CalcElementShapes (SegmentInfo & elnr, double xi, Vector & shapes) const; + void GetCoefficients (SegmentInfo & elnr, ARRAY > & coefs) const; + void CalcElementDShapes (SegmentInfo & elnr, double xi, Vector & dshapes) const; + + + class ElementInfo + { + public: + ElementIndex elnr; + int order; + int nv; + int ndof; + int nedges; + int nfaces; + int edgenrs[12]; + int facenrs[6]; + Mat<3> hdxdxi; + Vec<3> hcoefs[10]; // enough for second order tets + }; + + + void CalcElementShapes (ElementInfo & info, const Point<3> & xi, Vector & shapes) const; + void GetCoefficients (ElementInfo & info, Vec<3> * coefs) const; + void CalcElementDShapes (ElementInfo & info, const Point<3> & xi, MatrixFixWidth<3> & dshapes) const; + + + class SurfaceElementInfo + { + public: + SurfaceElementIndex elnr; + int order; + int nv; + int ndof; + ArrayMem edgenrs; + int facenr; + }; + + void CalcElementShapes (SurfaceElementInfo & elinfo, const Point<2> & xi, Vector & shapes) const; + void GetCoefficients (SurfaceElementInfo & elinfo, ARRAY > & coefs) const; + void CalcElementDShapes (SurfaceElementInfo & elinfo, const Point<2> & xi, DenseMatrix & dshapes) const; +}; + + + +#endif diff --git a/libsrc/meshing/delaunay.cpp b/libsrc/meshing/delaunay.cpp new file mode 100644 index 00000000..e74afec3 --- /dev/null +++ b/libsrc/meshing/delaunay.cpp @@ -0,0 +1,1676 @@ +#include +#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 faces; + + // + ARRAY & tets; + + public: + + // estimated number of points + MeshNB (ARRAY & 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 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 & linked) const; + }; + + + void SphereList :: GetList (int eli, ARRAY & 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 & tempels, + Mesh & mesh, + Box3dTree & tettree, + MeshNB & meshnb, + ARRAY > & centers, ARRAY & radi2, + ARRAY & connected, ARRAY & treesearch, + ARRAY & freelist, SphereList & list, + IndexSet & insphere, IndexSet & closesphere) + { + /* + find any sphere, such that newp is contained in + */ + + DelaunayTet el; + int cfelind = -1; + + const Point<3> * pp[4]; + Point<3> pc; + double r2; + Point3d tpmin, tpmax; + + tettree.GetIntersecting (newp, newp, treesearch); + + double quot,minquot(1e20); + + for (int j = 0; j < treesearch.Size(); j++) + { + int jjj = treesearch[j]; + quot = Dist2 (centers.Get(jjj), newp) / radi2.Get(jjj); + + if((cfelind == -1 || quot < 0.99*minquot) && quot < 1) + { + minquot = quot; + el = tempels.Get(jjj); + cfelind = jjj; + if(minquot < 0.917632) + break; + } + } + + + /* + int i, j, k, l; + 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 (int 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 (int j = starti; j < nstarti; j++) + { + list.GetList (insphere.Array().Get(j), connected); + for (int k = 0; k < connected.Size(); k++) + { + int celind = connected[k]; + + if (tempels.Get(celind)[0] != -1 && + !insphere.IsIn (celind)) + { + changed = 1; + insphere.Add (celind); + } + } + } + + // check neighbour-tets + for (int j = starti; j < nstarti; j++) + for (int k = 1; k <= 4; k++) + { + int helind = insphere.Array().Get(j); + int nbind = meshnb.GetNB (helind, k); + + if (nbind && !insphere.IsIn (nbind) ) + { + //changed + //int prec = testout->precision(); + //testout->precision(12); + //(*testout) << "val1 " << Dist2 (centers.Get(nbind), newp) + // << " val2 " << radi2.Get(nbind) * (1+1e-8) + // << " val3 " << radi2.Get(nbind) + // << " val1 / val3 " << Dist2 (centers.Get(nbind), newp)/radi2.Get(nbind) << endl; + //testout->precision(prec); + 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 newels; + + Element2d face(TRIG); + + for (int j = 1; j <= insphere.Array().Size(); j++) + for (int 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 (int l = 0; l < 3; l++) + newel[l] = face[l]; + newel[3] = newpi; + + newels.Append (newel); + + Vec<3> v1 = mesh[face[1]] - mesh[face[0]]; + Vec<3> v2 = mesh[face[2]] - mesh[face[0]]; + Vec<3> n = Cross (v1, v2); + + n.Normalize(); + if (n * Vec3d(mesh.Point (face[0]), + mesh.Point (tempels.Get(insphere.Array().Get(j))[k-1])) + > 0) + n *= -1; + + double hval = n * ( newp - mesh[face[0]]); + + 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 (int j = 1; j <= insphere.Array().Size(); j++) + { + // int elind = + int celind = insphere.Array().Get(j); + + meshnb.Delete (celind); + list.DeleteElement (celind); + + for (int k = 0; k < 4; k++) + tempels.Elem(celind)[k] = -1; + + ((ADTree6&)tettree.Tree()).DeleteElement (celind); + freelist.Append (celind); + } + + + int hasclose = 0; + for (int 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 (int 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 (int k = 0; k < 4; k++) + pp[k] = &mesh.Point (newels.Get(j)[k]); + + if (CalcSphereCenter (&pp[0], pc) ) + { + PrintSysError ("Delaunay: New tet is flat"); + + (*testout) << "new tet is flat" << endl; + for (int k = 1; k <= 4; k++) + (*testout) << newels.Get(j).PNum(k) << " "; + (*testout) << endl; + for (int k = 1; k <= 4; k++) + (*testout) << *pp[k-1] << " "; + (*testout) << endl; + } + + r2 = Dist2 (*pp[0], pc); + if (hasclose) + for (int 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 (int 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 & tempels, + int oldnp, DelaunayTet & startel, Point3d & pmin, Point3d & pmax) + { + int i, j, k; + const Point<3> * pp[4]; + + ARRAY > centers; + ARRAY 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 MiniElement2d & 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 usep(np); + usep.Clear(); + for (i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & 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 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 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); + + + Point<3> 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()); + + + + // "random" reordering of points (speeds a factor 3 - 5 !!!) + + ARRAY 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 % 1000 == 0) + { + if (i % 10000 == 0) + PrintDot ('+'); + else + 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); + } + + 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, int domainnr, const MeshingParameters & mp) + { + int np, ne; + + PrintMessage (1, "Delaunay meshing"); + PrintMessage (3, "number of points: ", mesh.GetNP()); + PushStatus ("Delaunay meshing"); + + + ARRAY tempels; + Point3d pmin, pmax; + + 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 (PointIndex pi = PointIndex::BASE; pi < mesh.GetNP()+PointIndex::BASE; pi++) + tempmesh.AddPoint (mesh[pi]); + + for (int i = 1; i <= tempels.Size(); i++) + { + Element el(4); + for (int 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); + + tempmesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); + tempmesh.AddFaceDescriptor (FaceDescriptor (2, 1, 0, 0)); + + + + for (int 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 (int i = 1; i <= 4; i++) + { + Element2d self(TRIG); + self.SetIndex (1); + startel.GetFace1 (i, self); + tempmesh.AddSurfaceElement (self); + } + + + // for (i = mesh.GetNP() - 3; i <= mesh.GetNP(); i++) + // tempmesh.AddLockedPoint (i); + for (PointIndex pi = PointIndex::BASE; + pi < tempmesh.GetNP() + PointIndex::BASE; pi++) + tempmesh.AddLockedPoint (pi); + + // tempmesh.PrintMemInfo(cout); + // tempmesh.Save ("tempmesh.vol"); + + for (int i = 1; i <= 2; i++) + { + tempmesh.FindOpenElements (); + + PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); + tempmesh.CalcSurfacesOfNode (); + + tempmesh.FreeOpenElementsEnvironment (1); + + MeshOptimize3d meshopt; + // tempmesh.CalcSurfacesOfNode(); + meshopt.SwapImprove(tempmesh, OPT_CONFORM); + } + + MeshQuality3d (tempmesh); + + tempels.SetSize(0); + for (int i = 1; i <= tempmesh.GetNE(); i++) + tempels.Append (tempmesh.VolumeElement(i)); + } + + + + // remove degenerated + + BitArray badnode(mesh.GetNP()); + badnode.Clear(); + int ndeg = 0; + for (int i = 1; i <= tempels.Size(); i++) + { + Element el(4); + for (int 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 (int 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 openeltab(mesh.GetNOpenElements()+3); + ARRAY openels; + for (int 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 (int i = 1; i <= tempels.Size(); i++) + { + for (int 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 (int i = 1; i <= openeltab.GetNBags(); i++) + for (int 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 twotrias(mesh.GetNOpenElements()+5); + // for (i = 1; i <= mesh.GetNOpenElements(); i++) + for (int ii = 1; ii <= openels.Size(); ii++) + { + int i = openels.Get(ii); + const Element2d & el = mesh.OpenElement(i); + for (int 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 tetedges(tempels.Size() + 5); + for (int i = 1; i <= tempels.Size(); i++) + { + const DelaunayTet & el = tempels.Get(i); + INDEX_2 i2; + for (int j = 1; j <= 6; j++) + { + switch (j) + { + case 1: i2.I1()=el[0]; i2.I2()=el[1]; break; + case 2: i2.I1()=el[0]; i2.I2()=el[2]; break; + case 3: i2.I1()=el[0]; i2.I2()=el[3]; break; + case 4: i2.I1()=el[1]; i2.I2()=el[2]; break; + case 5: i2.I1()=el[1]; i2.I2()=el[3]; break; + case 6: i2.I1()=el[2]; i2.I2()=el[3]; break; + default: i2.I1()=i2.I2()=0; break; + } + i2.Sort(); + tetedges.Set (i2, 1); + } + } + // cout << "tetedges:"; + // tetedges.PrintMemInfo (cout); + + + for (INDEX_2_HASHTABLE::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 (int 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 (int 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 (ltpmin); + + for (int 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 neartrias; + for (int i = 1; i <= tempels.Size(); i++) + { + const Point<3> *pp[4]; + int tetpi[4]; + DelaunayTet & el = tempels.Elem(i); + + int intersect = 0; + + for (int j = 0; j < 4; j++) + { + pp[j] = &mesh.Point(el[j]); + tetpi[j] = el[j]; + } + + Point3d tetpmin(*pp[0]); + Point3d tetpmax(tetpmin); + for (int 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++) + { + int j = neartrias.Get(jj); + + const Element2d & tri = mesh.OpenElement(j); + const Point<3> *tripp[3]; + int tripi[3]; + + for (int 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--; + } + } + } + + + + + PrintMessage (3, "Remove outer"); + + // find connected tets (with no face between, and no hole due + // to removed intersecting tets. + // INDEX_3_HASHTABLE innerfaces(np); + + + INDEX_3_HASHTABLE boundaryfaces(mesh.GetNOpenElements()/3+1); + for (int 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 (int 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 (int i = 0; i < tempels.Size(); i++) + for (int j = 0; j < 4; j++) + tempels[i].NB(j) = 0; + + TABLE elsonpoint(mesh.GetNP()); + for (int 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 (int 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 faceht(100); + + Element2d hel(TRIG); + for (PointIndex pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + { + faceht.SetSize (4 * elsonpoint[pi].Size()); + for (int ii = 0; ii < elsonpoint[pi].Size(); ii++) + { + int i = elsonpoint[pi][ii]; + const DelaunayTet & el = tempels.Get(i); + + for (int 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 i3i(hel[0], hel[1], hel[2]); + INDEX_2 i2(i, j); + faceht.Set (i3i, 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 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; + + int i; + 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 (int 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 (int 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 (int 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 (int i = ne; i >= 1; i--) + { + if (outer.Test(i)) + tempels.DeleteElement(i); + } + + + // mesh.points.SetSize(mesh.points.Size()-4); + + for (int i = 0; i < tempels.Size(); i++) + { + Element el(4); + for (int j = 0; j < 4; j++) + el[j] = tempels[i][j]; + mesh.AddVolumeElement (el); + } + + PrintMessage (5, "outer removed"); + + mesh.FindOpenElements(domainnr); + + mesh.Compress(); + + PopStatus (); + } +} diff --git a/libsrc/meshing/findip.hpp b/libsrc/meshing/findip.hpp new file mode 100644 index 00000000..2d9058fc --- /dev/null +++ b/libsrc/meshing/findip.hpp @@ -0,0 +1,192 @@ +// find inner point + + + +inline void Minimize (const ARRAY & a, + const ARRAY & c, + int * act, + Vec<3> & x, double & f, + int * sol) +{ + int act1[4]; + Mat<3> m, inv; + Vec<3> rs, xmax, center; + + f = 1e99; + + for (int j = 0; j < 5; j++) + { + for (int hk = 0, k = 0; hk < 4; hk++) + { + if (hk == j) k++; + act1[hk] = act[k]; + k++; + } + + for (int k = 0; k < 3; k++) + { + m(k, 0) = a[act1[0]].X() - a[act1[k+1]].X(); + m(k, 1) = a[act1[0]].Y() - a[act1[k+1]].Y(); + m(k, 2) = a[act1[0]].Z() - a[act1[k+1]].Z(); + rs(k) = c[act1[k+1]] - c[act1[0]]; + } + + /* + (*testout) << "act1 = " + << act1[0] << " " + << act1[1] << " " + << act1[2] << " " + << act1[3] << endl; + (*testout) << "Det = " << Det(m) << endl; + */ + + if (fabs (Det (m)) > 1e-10) + { + CalcInverse (m, inv); + xmax = inv * rs; + + double fmax = -1e10; + for (int k = 0; k < 5; k++) + { + double hd = + xmax(0) * a[act[k]].X() + xmax(1) * a[act[k]].Y() + xmax(2) * a[act[k]].Z() + c[act[k]]; + if (hd > fmax) fmax = hd; + } + + if (fmax < f) + { + f = fmax; + x = xmax; + for (int k = 0; k < 4; k++) + sol[k] = act1[k]; + } + } + } +} + + + + +template +inline int FindInnerPoint (POINTARRAY & points, + FACEARRAY & faces, + Point3d & p) +{ + static int timer = NgProfiler::CreateTimer ("FindInnerPoint"); + NgProfiler::RegionTimer reg (timer); + + ARRAY a; + ARRAY c; + Mat<3> m, inv; + Vec<3> rs, x, center; + double f; + + int nf = faces.Size(); + + // minimize_x max_i a_i x + c_i + + a.SetSize (nf+4); + c.SetSize (nf+4); + + for (int i = 0; i < nf; i++) + { + Point3d p1 = points.Get(faces[i][0]); + a[i] = Cross (points.Get(faces[i][1]) - p1, + points.Get(faces[i][2]) - p1); + a[i] /= a[i].Length(); + c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z()); + } + + /* + center = 0; + for (int i = 0; i < points.Size(); i++) + center += Vec<3> (points[i]); + center /= points.Size(); + */ + + center = 0; + for (int i = 0; i < faces.Size(); i++) + for (int j = 0; j < 3; j++) + center += Vec<3> (points.Get(faces[i][j])); + center /= (3*faces.Size()); + + + // (*testout) << "center = " << center << endl; + + double hmax = 0; + for (int i = 0; i < nf; i++) + { + // const Element2d & el = faces[i]; + // (*testout) << "el[" << i << "] = " << el << endl; + for (int j = 1; j <= 3; j++) + { + double hi = Dist (points.Get(faces[i].PNumMod(j)), + points.Get(faces[i].PNumMod(j+1))); + if (hi > hmax) hmax = hi; + } + } + + // (*testout) << "hmax = " << hmax << endl; + + a[nf] = Vec<3> (1, 0, 0); + c[nf] = -center(0) - hmax; + a[nf+1] = Vec<3> (0, 1, 0); + c[nf+1] = -center(1) - hmax; + a[nf+2] = Vec<3> (0, 0, 1); + c[nf+2] = -center(2) - hmax; + a[nf+3] = Vec<3> (-1, -1, -1); + c[nf+3] = center(0)+center(1)+center(2)-3*hmax; + + /* + (*testout) << "findip, a now = " << endl << a << endl; + (*testout) << "findip, c now = " << endl << c << endl; + */ + + int act[5] = { 0, nf, nf+1, nf+2, nf+3 }; + int sol[4]; + + while (1) + { + /* + (*testout) << "try "; + for (int j = 0; j < 5; j++) + (*testout) << act[j] << " "; + */ + + Minimize (a, c, act, x, f, sol); + + /* + (*testout) << endl << "sol = "; + for (int j = 0; j < 4; j++) + (*testout) << sol[j] << " "; + + (*testout) << " fmin = " << f << endl; + */ + for (int j = 0; j < 4; j++) act[j] = sol[j]; + + bool found = 0; + double maxval = f; + for (int j = 0; j < nf; j++) + { + double val = x(0) * a[j].X() + x(1) * a[j].Y() + x(2) * a[j].Z() + c[j]; + if (val > maxval + hmax * 1e-6) + { + found = 1; + maxval = val; + act[4] = j; + } + } + + // (*testout) << "maxval = " << maxval << endl; + if (!found) break; + } + + // cout << "converged, f = " << f << endl; + + p = Point3d (x(0), x(1), x(2)); + // (*testout) << "findip, f = " << f << ", hmax = " << hmax << endl; + return (f < -1e-5 * hmax); +} + + + diff --git a/libsrc/meshing/findip2.hpp b/libsrc/meshing/findip2.hpp new file mode 100644 index 00000000..fa9215d9 --- /dev/null +++ b/libsrc/meshing/findip2.hpp @@ -0,0 +1,95 @@ +// find inner point + +template +inline int FindInnerPoint2 (POINTARRAY & points, + FACEARRAY & faces, + Point3d & p) +{ + static int timer = NgProfiler::CreateTimer ("FindInnerPoint2"); + NgProfiler::RegionTimer reg (timer); + + ARRAY a; + ARRAY c; + Mat<3> m, inv; + Vec<3> rs, x, pmin; + + int nf = faces.Size(); + + a.SetSize (nf); + c.SetSize (nf); + + for (int i = 0; i < nf; i++) + { + Point3d p1 = points.Get(faces[i][0]); + a[i] = Cross (points.Get(faces[i][1]) - p1, + points.Get(faces[i][2]) - p1); + a[i] /= a[i].Length(); + c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z()); + } + + + x = 0; + + + double hmax = 0; + for (int i = 0; i < nf; i++) + { + const Element2d & el = faces[i]; + for (int j = 1; j <= 3; j++) + { + double hi = Dist (points.Get(el.PNumMod(j)), + points.Get(el.PNumMod(j+1))); + if (hi > hmax) hmax = hi; + } + } + + double fmin = 0; + + for (int i1 = 1; i1 <= nf; i1++) + for (int i2 = i1+1; i2 <= nf; i2++) + for (int i3 = i2+1; i3 <= nf; i3++) + for (int i4 = i3+1; i4 <= nf; i4++) + { + m(0, 0) = a.Get(i1).X() - a.Get(i2).X(); + m(0, 1) = a.Get(i1).Y() - a.Get(i2).Y(); + m(0, 2) = a.Get(i1).Z() - a.Get(i2).Z(); + rs(0) = c.Get(i2) - c.Get(i1); + + m(1, 0) = a.Get(i1).X() - a.Get(i3).X(); + m(1, 1) = a.Get(i1).Y() - a.Get(i3).Y(); + m(1, 2) = a.Get(i1).Z() - a.Get(i3).Z(); + rs(1) = c.Get(i3) - c.Get(i1); + + m(2, 0) = a.Get(i1).X() - a.Get(i4).X(); + m(2, 1) = a.Get(i1).Y() - a.Get(i4).Y(); + m(2, 2) = a.Get(i1).Z() - a.Get(i4).Z(); + rs(2) = c.Get(i4) - c.Get(i1); + + + if (fabs (Det (m)) > 1e-10) + { + CalcInverse (m, inv); + x = inv * rs; + + double f = -1e10; + for (int i = 0; i < nf; i++) + { + double hd = + x(0) * a[i].X() + x(1) * a[i].Y() + x(2) * a[i].Z() + c[i]; + if (hd > f) f = hd; + if (hd > fmin) break; + } + + if (f < fmin) + { + fmin = f; + pmin = x; + } + } + } + + p = Point3d (pmin(0), pmin(1), pmin(2)); + (*testout) << "fmin = " << fmin << endl; + return (fmin < -1e-3 * hmax); +} + diff --git a/libsrc/meshing/geomsearch.cpp b/libsrc/meshing/geomsearch.cpp new file mode 100644 index 00000000..1bedd23c --- /dev/null +++ b/libsrc/meshing/geomsearch.cpp @@ -0,0 +1,263 @@ +#include +#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 *pointsi, ARRAY *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 MiniElement2d& elem) + { + maxp.X()=(*points)[elem.PNum(1)].P()(0); + maxp.Y()=(*points)[elem.PNum(1)].P()(1); + maxp.Z()=(*points)[elem.PNum(1)].P()(2); + minp.X()=(*points)[elem.PNum(1)].P()(0); + minp.Y()=(*points)[elem.PNum(1)].P()(1); + minp.Z()=(*points)[elem.PNum(1)].P()(2); + + for (int i=2; i <= 3; i++) + { + maxp.X()=max2((*points)[elem.PNum(i)].P()(0),maxp.X()); + maxp.Y()=max2((*points)[elem.PNum(i)].P()(1),maxp.Y()); + maxp.Z()=max2((*points)[elem.PNum(i)].P()(2),maxp.Z()); + minp.X()=min2((*points)[elem.PNum(i)].P()(0),minp.X()); + minp.Y()=min2((*points)[elem.PNum(i)].P()(1),minp.Y()); + minp.Z()=min2((*points)[elem.PNum(i)].P()(2),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 (); + } + } + } + } + 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 MiniElement2d& 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.); + + for (int ix = sx; ix <= ex; ix++) + for (int iy = sy; iy <= ey; iy++) + for (int 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; + throw NgException ("Illegal position in Geomsearch"); + } + hashtable.Elem(ind)->Append(elemnum); + } + } + + void GeomSearch3d :: GetLocals(ARRAY & locfaces, ARRAY & 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 & 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 MiniElement2d & 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) + if((Dist2 (p1, p0) <= xh*xh) || + (Dist2 (p2, p0) <= xh*xh) || + (Dist2 (p3, p0) <= xh*xh) || + (Dist2 (midp, p0) <= xh*xh) ) // by Jochen Wild + { + 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/libsrc/meshing/geomsearch.hpp b/libsrc/meshing/geomsearch.hpp new file mode 100644 index 00000000..236c98b1 --- /dev/null +++ b/libsrc/meshing/geomsearch.hpp @@ -0,0 +1,117 @@ +#ifndef FILE_GEOMSEARCH +#define FILE_GEOMSEARCH + +/**************************************************************************/ +/* File: geomsearch.hh */ +/* Author: Johannes Gerstmayr */ +/* Date: 19. Nov. 97 */ +/**************************************************************************/ + +class FrontPoint3; +class FrontFace; +class MiniElement2d; + + /// class for quick access of 3D-elements; class cannot delete elements, but only append +class GeomSearch3d +{ + +public: + /// + GeomSearch3d(); + /// + virtual ~GeomSearch3d(); + + /// + void Init (ARRAY *pointsi, ARRAY *facesi); + + ///get elements max extension + void ElemMaxExt(Point3d& minp, Point3d& maxp, const MiniElement2d& 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 MiniElement2d& elem, INDEX elemnum); + + ///GetLocal faces in sphere with radius xh and middlepoint p + void GetLocals(ARRAY & locfaces, ARRAY & findex, + INDEX fstind, const Point3d& p0, double xh); + +private: + + ARRAY *faces; // Pointers to Arrays in Adfront + ARRAY *points; + + ARRAY *> 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/libsrc/meshing/global.cpp b/libsrc/meshing/global.cpp new file mode 100644 index 00000000..60a1fbe5 --- /dev/null +++ b/libsrc/meshing/global.cpp @@ -0,0 +1,53 @@ +#include +#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 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/libsrc/meshing/global.hpp b/libsrc/meshing/global.hpp new file mode 100644 index 00000000..10196245 --- /dev/null +++ b/libsrc/meshing/global.hpp @@ -0,0 +1,54 @@ +#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 testout; + +/// calling parameters +extern Flags parameters; + +extern MeshingParameters mparam; + +extern ARRAY tets_in_qualclass; + + +class multithreadt +{ +public: + int pause; + int testmode; + int redraw; + int drawing; + int terminate; + int running; + double percent; + const char * task; + bool demorunning; + multithreadt(); +}; + +extern volatile multithreadt multithread; + +extern string ngdir; +extern DebugParameters debugparam; +extern bool verbose; + +#endif diff --git a/libsrc/meshing/hpref_hex.hpp b/libsrc/meshing/hpref_hex.hpp new file mode 100644 index 00000000..11e3f86e --- /dev/null +++ b/libsrc/meshing/hpref_hex.hpp @@ -0,0 +1,236 @@ +// SZ + +// HP_HEX ... no refinement +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_1F ... face (1 - 4 - 3 -2) singular +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, + HP_HEX_1F_0E_0V, + HP_NONE, + }; +int refhex_1f_0e_0v_newels[][8] = + { + { 9, 10, 11, 12, 5, 6, 7, 8 }, + { 1, 2, 3, 4, 9, 10, 11, 12} + }; +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 + }; + + + +// HP_HEX_1FA_1FB ... face (1 - 4 - 3 -2) and face (1-2-6-5) singular +int refhex_1fa_1fb_0e_0v_splitedges[][3] = + { + { 1, 5, 9 }, + { 2, 6, 10 }, + { 3, 7, 11 }, + { 4, 8, 12 }, + { 1, 4, 13 }, + { 2, 3, 14 }, + { 6, 7, 15 }, + { 5, 8, 16 }, + { 0, 0, 0 } + }; + +int refhex_1fa_1fb_0e_0v_splitfaces[][4] = + { + { 2, 3, 6, 17 }, + { 1, 4, 5, 18 }, + { 0, 0, 0, 0 }, + }; +HPREF_ELEMENT_TYPE refhex_1fa_1fb_0e_0v_newelstypes[] = + { + HP_HEX, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; +int refhex_1fa_1fb_0e_0v_newels[][8] = + { + {18, 17, 11, 12, 16, 15, 7, 8}, + {13, 14, 3, 4, 18, 17, 11, 12}, + { 5, 6, 10, 9, 16, 15, 17, 18}, + { 1, 2, 14, 13, 9, 10, 17, 18} + }; +HPRef_Struct refhex_1fa_1fb_0e_0v = + { + HP_HEX, + refhex_1fa_1fb_0e_0v_splitedges, + refhex_1fa_1fb_0e_0v_splitfaces, 0, + refhex_1fa_1fb_0e_0v_newelstypes, + refhex_1fa_1fb_0e_0v_newels + }; + + + +// Refine Dummies + // 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 + }; + + + +// Refine Dummies + // 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 + }; + + +// Refine Dummies + // 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 + }; + + + +// Refine Dummies + // 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_SINGEDGE_H1, + 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 + }; + + diff --git a/libsrc/meshing/hpref_prism.hpp b/libsrc/meshing/hpref_prism.hpp new file mode 100644 index 00000000..3cceb44a --- /dev/null +++ b/libsrc/meshing/hpref_prism.hpp @@ -0,0 +1,3405 @@ + + // 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_SINGEDGE, + HP_PRISM_SINGEDGE, + 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, 16 }, + { 2, 5, 17 }, + { 3, 6, 18 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fa_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_NONE, + }; + int refprism_1fa_0e_0v_newels[][8] = + { + { 16, 17, 18, 4, 5, 6 }, + { 1, 2, 3, 16, 17, 18 } + }; + 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_1FA_1E_0V + int refprism_1fa_1e_0v_splitedges[][3] = + { + { 1, 4, 16 }, + { 2, 5, 17 }, + { 3, 6, 18 }, + { 1, 2, 7}, + { 1, 3, 12}, + { 4, 6, 45}, + { 4, 5, 40}, + { 0, 0, 0 } + }; + int refprism_1fa_1e_0v_splitfaces[][4] = + { + {1,2,4,19}, + {1,3,4,24}, + {0,0,0,0} + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_1fa_1e_0v_newels[][8] = + { + { 16, 19, 24, 4, 40, 45 }, + { 24, 19, 17, 18, 45 , 40, 5, 6 }, + { 1, 7 , 12 , 16, 19, 24 }, + { 7, 2, 3, 12, 19, 17, 18, 24 } + }; + HPRef_Struct refprism_1fa_1e_0v = + { + HP_PRISM, + refprism_1fa_1e_0v_splitedges, + refprism_1fa_1e_0v_splitfaces, + 0, + refprism_1fa_1e_0v_newelstypes, + refprism_1fa_1e_0v_newels + }; + +// HP_PRISM_2FA_1E_0V + int refprism_2fa_1e_0v_splitedges[][3] = + { + { 1, 4, 16 }, + { 2, 5, 17 }, + { 3, 6, 18 }, + { 1, 2, 7}, + { 1, 3, 12}, + { 4, 6, 45}, + { 4, 5, 40}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 0, 0, 0 } + }; + int refprism_2fa_1e_0v_splitfaces[][4] = + { + {1,2,4,19}, + {1,3,4,24}, + {4,1,5,31}, + {4,1,6,36}, + {0,0,0,0} + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_2fa_1e_0v_newels[][8] = + { + { 16, 19, 24, 28, 31, 36 }, + { 24, 19, 17, 18, 36, 31, 29, 30 }, + { 1, 7 , 12 , 16, 19, 24 }, + { 12, 7, 2, 3, 24, 19, 17, 18 }, + { 4, 45, 40, 28, 36, 31 }, + { 40, 45, 6, 5, 31, 36, 30, 29,} + }; + HPRef_Struct refprism_2fa_1e_0v = + { + HP_PRISM, + refprism_2fa_1e_0v_splitedges, + refprism_2fa_1e_0v_splitfaces, + 0, + refprism_2fa_1e_0v_newelstypes, + refprism_2fa_1e_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 + }; + +// HP_PRISM_1FB_1EC_0V ... quad face 1-2-4-5 with singular edge 3-6 + int refprism_1fb_1ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_1fb_1ec_0v_newels[][8] = + { + { 3, 11, 10, 6, 44, 43}, + { 12, 9, 10, 11, 45, 42, 43, 44}, + { 4, 5, 2, 1, 45, 42, 9, 12 } + }; + HPRef_Struct refprism_1fb_1ec_0v = + { + HP_PRISM, + refprism_1fb_1ec_0v_splitedges, + 0, 0, + refprism_1fb_1ec_0v_newelstypes, + refprism_1fb_1ec_0v_newels + }; + +// HP_PRISM_1FA_1FB_1EC_0V ... bot-trig face, quad face 1-2-4-5 with singular edge 3-6 + int refprism_1fa_1fb_1ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 0, 0, 0 } + }; + + int refprism_1fa_1fb_1ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_1fa_1fb_1ec_0v_newels[][8] = + { + { 18, 23, 22, 6, 44, 43}, + { 24, 21, 22, 23, 45, 42, 43, 44}, + { 4, 5, 17, 16, 45, 42, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 1, 2, 9, 12, 16, 17, 21, 24} + }; + HPRef_Struct refprism_1fa_1fb_1ec_0v = + { + HP_PRISM, + refprism_1fa_1fb_1ec_0v_splitedges, + refprism_1fa_1fb_1ec_0v_splitfaces, 0, + refprism_1fa_1fb_1ec_0v_newelstypes, + refprism_1fa_1fb_1ec_0v_newels + }; + + +// HP_PRISM_1FA_1FB_2EB_0V + int refprism_1fa_1fb_2eb_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 4, 5, 40}, + { 4, 6, 45}, + { 1, 2, 7}, + { 0, 0, 0 } + }; + + int refprism_1fa_1fb_2eb_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {1,2,4,19}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_1fa_1fb_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fa_1fb_2eb_0v_newels[][8] = + { + { 18, 23, 22, 6, 44, 43}, + { 24, 21, 22, 23, 45, 42, 43, 44}, + { 40, 5, 17, 19, 45, 42, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 7, 2, 9, 12, 19, 17, 21, 24}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_1fb_2eb_0v = + { + HP_PRISM, + refprism_1fa_1fb_2eb_0v_splitedges, + refprism_1fa_1fb_2eb_0v_splitfaces, 0, + refprism_1fa_1fb_2eb_0v_newelstypes, + refprism_1fa_1fb_2eb_0v_newels + }; + + // HP_PRISM_1FA_1FB_2EC_0V + int refprism_1fa_1fb_2ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,4,41}, + {2,1,8}, + { 0, 0, 0 } + }; + + int refprism_1fa_1fb_2ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {2,1,5,20}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_1fa_1fb_2ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fa_1fb_2ec_0v_newels[][8] = + { + { 18, 23, 22, 6, 44, 43}, + { 24, 21, 22, 23, 45, 42, 43, 44}, + { 4, 41, 20, 16, 45, 42, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 1, 8, 9, 12, 16, 20, 21, 24}, + {8,2,9,20,17,21}, + {5,41,42,17,20,21} + }; + HPRef_Struct refprism_1fa_1fb_2ec_0v = + { + HP_PRISM, + refprism_1fa_1fb_2ec_0v_splitedges, + refprism_1fa_1fb_2ec_0v_splitfaces, + 0, + refprism_1fa_1fb_2ec_0v_newelstypes, + refprism_1fa_1fb_2ec_0v_newels + }; + + + + + + + +// HP_PRISM_2FA_1FB_1EC_0V ... trig faces, quad face 1-2-4-5 with singular edge 3-6 + int refprism_2fa_1fb_1ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 0, 0, 0 } + }; + + int refprism_2fa_1fb_1ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {5,2,6,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_2fa_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_2fa_1fb_1ec_0v_newels[][8] = + { + { 18, 23, 22, 30, 35, 34}, + { 24, 21, 22, 23, 36, 33, 34, 35}, + { 28, 29, 17, 16, 36, 33, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 1, 2, 9, 12, 16, 17, 21, 24}, + { 6, 43, 44, 30, 34, 35}, + { 44, 43, 42, 45, 35, 34, 33, 36}, + { 5, 4, 45, 42, 29, 28, 36, 33 }, + }; + HPRef_Struct refprism_2fa_1fb_1ec_0v = + { + HP_PRISM, + refprism_2fa_1fb_1ec_0v_splitedges, + refprism_2fa_1fb_1ec_0v_splitfaces, + 0, + refprism_2fa_1fb_1ec_0v_newelstypes, + refprism_2fa_1fb_1ec_0v_newels + }; + +// HP_PRISM_2FA_1FB_2EB_0V + int refprism_2fa_1fb_2eb_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + {4,5,40}, + {1,2,7}, + { 0, 0, 0 } + }; + + int refprism_2fa_1fb_2eb_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,1,5,31}, + {1,2,4,19}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_2fa_1fb_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_NONE, + }; + int refprism_2fa_1fb_2eb_0v_newels[][8] = + { + { 18, 23, 22, 30, 35, 34}, + { 24, 21, 22, 23, 36, 33, 34, 35}, + { 31, 29, 17, 19, 36, 33, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 7, 2, 9, 12, 19, 17, 21, 24}, + { 6, 43, 44, 30, 34, 35}, + { 44, 43, 42, 45, 35, 34, 33, 36}, + { 5, 40, 45, 42, 29, 31, 36, 33 }, + { 1, 7, 12, 16, 19, 24 }, + { 16, 19, 24, 28, 31, 36 }, + { 40, 4, 45, 31, 28, 36 }, + }; + HPRef_Struct refprism_2fa_1fb_2eb_0v = + { + HP_PRISM, + refprism_2fa_1fb_2eb_0v_splitedges, + refprism_2fa_1fb_2eb_0v_splitfaces, 0, + refprism_2fa_1fb_2eb_0v_newelstypes, + refprism_2fa_1fb_2eb_0v_newels + }; + +// HP_PRISM_1FB_2EA_0V ... quad face 1-2-4-5 with singular edges 1-4, 2-5 + int refprism_1fb_2ea_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 2, 1, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 5, 4, 14 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_2ea_0v_newelstypes[] = + { + HP_PRISM, + HP_PRISM_1FB_1EA_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fb_2ea_0v_newels[][8] = + { + { 7, 8, 3, 11, 12, 6 }, + { 1, 9, 7, 4, 13, 11 }, + { 13, 14, 10, 9, 11, 12, 8, 7 }, + { 5, 14, 12, 2, 10, 8 }, + }; + HPRef_Struct refprism_1fb_2ea_0v = + { + HP_PRISM, + refprism_1fb_2ea_0v_splitedges, + 0, 0, + refprism_1fb_2ea_0v_newelstypes, + refprism_1fb_2ea_0v_newels + }; + +// HP_PRISM_1FB_2EB_0V ... quad face 1-2-4-5 with singular edges 1-4, 3-6 + int refprism_1fb_2eb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE refprism_1fb_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FB_1EA_0V, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_1fb_2eb_0v_newels[][8] = + { + { 3, 11, 10, 6, 44, 43 }, + { 12, 9, 10, 11, 45, 42, 43, 44}, + { 1, 7, 12, 4, 40, 45}, + { 40, 5, 2, 7, 45, 42, 9, 12} + }; + HPRef_Struct refprism_1fb_2eb_0v = + { + HP_PRISM, + refprism_1fb_2eb_0v_splitedges, + 0, 0, + refprism_1fb_2eb_0v_newelstypes, + refprism_1fb_2eb_0v_newels + }; + +// HP_PRISM_1FB_3E_0V ... quad face 1-2-4-5 with singular edges 1-4, 3-6 + int refprism_1fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_3e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FB_1EA_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fb_3e_0v_newels[][8] = + { + { 3, 11, 10, 6, 44, 43 }, + { 12, 9, 10, 11, 45, 42, 43, 44}, + { 1, 7, 12, 4, 40, 45 }, + { 40, 41, 8, 7, 45, 42, 9, 12}, + { 5, 41, 42, 2, 8, 9}, + }; + HPRef_Struct refprism_1fb_3e_0v = + { + HP_PRISM, + refprism_1fb_3e_0v_splitedges, + 0, 0, + refprism_1fb_3e_0v_newelstypes, + refprism_1fb_3e_0v_newels + }; + + + +// HP_PRISM_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 + int refprism_2fb_0e_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 3, 2, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 6, 5, 14 }, + { 0, 0, 0 } + }; + int refprism_2fb_0e_0v_splitfaces[][4] = + { + { 1, 2, 3, 15 }, + { 4, 5, 6, 16 }, + { 0, 0, 0, 0 }, + }; + HPREF_ELEMENT_TYPE refprism_2fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_2fb_0e_0v_newels[][8] = + { + { 15, 8, 10, 16, 12, 14 }, + { 13, 5, 2, 9, 16, 12, 8, 15}, + { 11, 7, 3, 6, 16, 15, 10, 14 }, + { 1, 9, 15, 4, 13, 16 }, + { 4, 11, 16, 1,7, 15 } + }; + HPRef_Struct refprism_2fb_0e_0v = + { + HP_PRISM, + refprism_2fb_0e_0v_splitedges, + refprism_2fb_0e_0v_splitfaces, + 0, + refprism_2fb_0e_0v_newelstypes, + refprism_2fb_0e_0v_newels + }; + +// HP_PRISM_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 and sing edge 3-6 + int refprism_2fb_1ec_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 3, 2, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 6, 5, 14 }, + { 3, 1, 17}, + { 6, 4, 18}, + { 0, 0, 0 } + }; + int refprism_2fb_1ec_0v_splitfaces[][4] = + { + { 1, 2, 3, 15 }, + { 4, 5, 6, 16 }, + { 0, 0, 0, 0 }, + }; + HPREF_ELEMENT_TYPE refprism_2fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_2fb_1ec_0v_newels[][8] = + { + { 15, 8, 10, 16, 12, 14 }, + { 13, 5, 2, 9, 16, 12, 8, 15}, + { 11, 7, 17, 18, 16, 15, 10, 14 }, + { 1, 9, 15, 4, 13, 16 }, + { 4, 11, 16, 1,7, 15 }, + { 3, 17, 10, 6, 18, 14 } + }; + HPRef_Struct refprism_2fb_1ec_0v = + { + HP_PRISM, + refprism_2fb_1ec_0v_splitedges, + refprism_2fb_1ec_0v_splitfaces, + 0, + refprism_2fb_1ec_0v_newelstypes, + refprism_2fb_1ec_0v_newels + }; + + + +// HP_PRISM_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 and 3 sing edges + int refprism_2fb_3e_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 3, 2, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 6, 5, 14 }, + { 3, 1, 17}, + { 6, 4, 18}, + { 2, 1, 19}, + { 5, 4, 20}, + { 0, 0, 0 } + }; + int refprism_2fb_3e_0v_splitfaces[][4] = + { + { 1, 2, 3, 15 }, + { 4, 5, 6, 16 }, + { 0, 0, 0, 0 }, + }; + HPREF_ELEMENT_TYPE refprism_2fb_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_2fb_3e_0v_newels[][8] = + { + { 15, 8, 10, 16, 12, 14 }, + { 13, 20, 19, 9, 16, 12, 8, 15}, + { 11, 7, 17, 18, 16, 15, 10, 14 }, + { 1, 9, 15, 4, 13, 16 }, + { 4, 11, 16, 1,7, 15 }, + { 3, 17, 10, 6, 18, 14 }, + { 5, 20, 12, 2, 19, 8 } + }; + HPRef_Struct refprism_2fb_3e_0v = + { + HP_PRISM, + refprism_2fb_3e_0v_splitedges, + refprism_2fb_3e_0v_splitfaces, 0, + refprism_2fb_3e_0v_newelstypes, + refprism_2fb_3e_0v_newels + }; + + + +// HP_PRISM_1FA_1FB_0E_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_0e_0v_splitedges[][3] = + { + {1,4,16}, + {2,5,17}, + {3,6,18}, + {2,3,9}, + {1,3,12}, + {5,6,42}, + {4,6,45}, + {0,0,0} + }; + int refprism_1fa_1fb_0e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + { 0, 0, 0, 0 } + }; + +HPREF_ELEMENT_TYPE refprism_1fa_1fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_1fa_1fb_0e_0v_newels[][8] = + { + { 24, 21, 18, 45, 42, 6 }, + { 4, 5, 17, 16, 45, 42, 21, 24 }, + { 12, 9, 3, 24, 21, 18 }, + { 1, 2, 9, 12, 16, 17, 21, 24 } + }; + HPRef_Struct refprism_1fa_1fb_0e_0v = + { + HP_PRISM, + refprism_1fa_1fb_0e_0v_splitedges, + + refprism_1fa_1fb_0e_0v_splitfaces, 0, + refprism_1fa_1fb_0e_0v_newelstypes, + refprism_1fa_1fb_0e_0v_newels + }; + +/* +// HP_PRISM_1FA_1FB_1EC_0V ... quad face 1-2-4-5 and trig face 1-2-3 +int refprism_1fa_1fb_1ec_0v_splitedges[][3] = + { + {1,4,16}, + {2,5,17}, + {3,6,18}, + {2,3,9}, + {1,3,12}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {3,2,10}, + {3,1,11}, + {0,0,0} + }; + int refprism_1fa_1fb_1ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + { 0, 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_SINGEDGE, + HP_PRISM_1FA_1E_0V, + HP_PRISM_ + HP_NONE, + }; + int refprism_1fa_1fb_0e_0v_newels[][8] = + { + { 24, 21, 18, 45, 42, 6 }, + { 4, 5, 17, 16, 45, 42, 21, 24 }, + { 12, 9, 3, 24, 21, 18 }, + { 1, 2, 9, 12, 16, 17, 21, 24 } + }; + HPRef_Struct refprism_1fa_1fb_0e_0v = + { + HP_PRISM, + refprism_1fa_1fb_1ec_0v_splitedges, + + refprism_1fa_1fb_1ec_0v_splitfaces, 0, + refprism_1fa_1fb_1ec_0v_newelstypes, + refprism_1fa_1fb_1ec_0v_newels + }; + + +*/ + + + + +// HP_PRISM_2FA_1FB_0E_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_2fa_1fb_0e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {0,0,0} + + }; + int refprism_2fa_1fb_0e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {5,6,2,33}, + {4,1,6,36}, + {0,0,0,0} + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_0e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_2fa_1fb_0e_0v_newels[][8] = + { + {28,29,17,16,36,33,21,24}, + {24,21,18, 36, 33, 30}, + {12,9,3,24,21,18}, + {1,2,9,12,16,17,21,24}, + {6,42,45,30,33,36}, + {4,5,29,28,45,42,33,36} + }; + HPRef_Struct refprism_2fa_1fb_0e_0v = + { + HP_PRISM, + refprism_2fa_1fb_0e_0v_splitedges, + + refprism_2fa_1fb_0e_0v_splitfaces, 0, + refprism_2fa_1fb_0e_0v_newelstypes, + refprism_2fa_1fb_0e_0v_newels + }; + + +// HP_PRISM_1FA_1FB_1EA_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_1ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + }; + int refprism_1fa_1fb_1ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1ea_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_1fa_1fb_1ea_0v_newels[][8] = + { + {40,5,17,19,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {7,2,9,12,19,17,21,24}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + + }; + HPRef_Struct refprism_1fa_1fb_1ea_0v = + { + HP_PRISM, + refprism_1fa_1fb_1ea_0v_splitedges, + refprism_1fa_1fb_1ea_0v_splitfaces, 0, + refprism_1fa_1fb_1ea_0v_newelstypes, + refprism_1fa_1fb_1ea_0v_newels + }; + +// HP_PRISM_2FA_1FB_1EA_0V + int refprism_2fa_1fb_1ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + }; + int refprism_2fa_1fb_1ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {4,1,6,36}, + {4,1,5,31}, + {5,6,2,33}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_1ea_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_NONE + }; + int refprism_2fa_1fb_1ea_0v_newels[][8] = + { + { 18, 24, 21, 30, 36, 33}, + { 31, 29, 17, 19, 36, 33, 21, 24}, + { 16,19, 24, 28, 31, 36 }, + { 3, 12, 9, 18, 24, 21 }, + { 7, 2, 9, 12, 19, 17, 21, 24}, + { 1, 7, 12, 16, 19, 24 }, + { 6, 42, 45, 30, 33, 36 }, + { 40, 5, 29, 31, 45, 42, 33, 36 }, + { 40, 4, 45, 31, 28, 36} + }; + HPRef_Struct refprism_2fa_1fb_1ea_0v = + { + HP_PRISM, + refprism_2fa_1fb_1ea_0v_splitedges, + refprism_2fa_1fb_1ea_0v_splitfaces, 0, + refprism_2fa_1fb_1ea_0v_newelstypes, + refprism_2fa_1fb_1ea_0v_newels + }; + + +// HP_PRISM_2FA_1FB_2EA_0V + int refprism_2fa_1fb_2ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {4,5,40}, + {1,2,7}, + { 5, 4, 41}, + { 2, 1, 8}, + {0,0,0}, + }; + int refprism_2fa_1fb_2ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {4,1,6,36}, + {4,1,5,31}, + {5,6,2,33}, + {5,4,2,32}, + {2,1,5,20}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_2ea_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_2fa_1fb_2ea_0v_newels[][8] = + { + { 18, 24, 21, 30, 36, 33}, + { 31, 32, 20, 19, 36, 33, 21, 24}, + { 16,19, 24, 28, 31, 36 }, + { 3, 12, 9, 18, 24, 21 }, + {7,8,9,12,19,20,21,24}, + { 1, 7, 12, 16, 19, 24 }, + { 6, 42, 45, 30, 33, 36 }, + { 40, 41, 32, 31, 45, 42, 33, 36}, + { 40, 4, 45, 31, 28, 36}, + { 8, 2, 9, 20, 17, 21 }, + { 29, 32, 33, 17, 20, 21 }, + { 5, 41, 42, 29, 32, 33 }, + }; + HPRef_Struct refprism_2fa_1fb_2ea_0v = + { + HP_PRISM, + refprism_2fa_1fb_2ea_0v_splitedges, + refprism_2fa_1fb_2ea_0v_splitfaces, 0, + refprism_2fa_1fb_2ea_0v_newelstypes, + refprism_2fa_1fb_2ea_0v_newels + }; + +// HP_PRISM_2FA_1FB_3E_0V + int refprism_2fa_1fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + {0,0,0}, + }; + int refprism_2fa_1fb_3e_0v_splitfaces[][4] = + { + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_3e_0v_newelstypes[] = + { + HP_HEX, + HP_PRISM_SINGEDGE, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_HEX_1FA_1FB_0E_0V, + + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_HEX_1FA_1FB_0E_0V, + + HP_NONE + }; + int refprism_2fa_1fb_3e_0v_newels[][8] = + { + {24, 21, 22, 23, 36, 33, 34, 35}, + {18, 23, 22, 30, 35, 34}, + { 31, 32, 20, 19, 36, 33, 21, 24}, + { 16,19, 24, 28, 31, 36 }, + { 29, 32, 33, 17, 20, 21}, + + + { 12, 9,10,11, 24, 21, 22, 23 }, + { 3, 11, 10, 18,23,22}, + { 1, 7, 12 , 16, 19, 24}, + { 8,2,9, 20, 17,21}, + { 7,8,9,12,19, 20, 21, 24}, + + { 44, 43, 42, 45, 35, 34, 33, 36}, + { 6, 43, 44, 30, 34, 35}, + { 40, 4, 45, 31,28, 36}, + { 5, 41,42, 29, 32, 33}, + { 40, 41, 32, 31, 45, 42, 33, 36}, + }; + HPRef_Struct refprism_2fa_1fb_3e_0v = + { + HP_PRISM, + refprism_2fa_1fb_3e_0v_splitedges, + + refprism_2fa_1fb_3e_0v_splitfaces, 0, + refprism_2fa_1fb_3e_0v_newelstypes, + refprism_2fa_1fb_3e_0v_newels + }; + + + + +// HP_PRISM_1FA_1FB_1EB_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_1eb_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {0,0,0}, + }; + int refprism_1fa_1fb_1eb_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1eb_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V , + HP_NONE + }; + int refprism_1fa_1fb_1eb_0v_newels[][8] = + { + {4,41,20,16,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {1,8,9,12,16,20,21,24}, + {5,41,42,17,20,21}, + {8,2,9,20,17,21} + }; + HPRef_Struct refprism_1fa_1fb_1eb_0v = + { + HP_PRISM, + refprism_1fa_1fb_1eb_0v_splitedges, + + refprism_1fa_1fb_1eb_0v_splitfaces, 0, + refprism_1fa_1fb_1eb_0v_newelstypes, + refprism_1fa_1fb_1eb_0v_newels + }; + + +// HP_PRISM_1FA_1FB_2EA_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_2ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + + }; + int refprism_1fa_1fb_2ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {1,2,4,19}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_2ea_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V , + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_1fa_1fb_2ea_0v_newels[][8] = + { + {40,41,20,19,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {7,8,9,12,19,20,21,24}, + {5,41,42,17,20,21}, + {8,2,9,20,17,21}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_1fb_2ea_0v = + { + HP_PRISM, + refprism_1fa_1fb_2ea_0v_splitedges, + + refprism_1fa_1fb_2ea_0v_splitfaces, 0, + refprism_1fa_1fb_2ea_0v_newelstypes, + refprism_1fa_1fb_2ea_0v_newels + }; + + +// HP_PRISM_1FA_1FB_3E_0V + int refprism_1fa_1fb_3e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {4,5,40}, + {1,2,7}, + { 3, 2, 10}, + { 3, 1, 11}, + { 6, 5, 43}, + { 6, 4, 44}, + {0,0,0}, + + }; + int refprism_1fa_1fb_3e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {1,2,4,19}, + {3,2,6,22}, + {3,1,6,23}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_3e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_HEX, + HP_PRISM_SINGEDGE, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V , + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_1fa_1fb_3e_0v_newels[][8] = + { + {40,41,20,19,45,42,21,24}, + {24, 21, 22, 23, 45, 42, 43, 44}, + {18, 23, 22, 6, 44, 43}, + {12, 9, 10, 11, 24, 21, 22, 23}, + {3, 11, 10, 18, 23, 22}, + {7,8,9,12,19,20,21,24}, + {5,41,42,17,20,21}, + {8,2,9,20,17,21}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_1fb_3e_0v = + { + HP_PRISM, + refprism_1fa_1fb_3e_0v_splitedges, + + refprism_1fa_1fb_3e_0v_splitfaces, 0, + refprism_1fa_1fb_3e_0v_newelstypes, + refprism_1fa_1fb_3e_0v_newels + }; + + + + + + + + +// HP_PRISM_2FA_0E_0V singular trig faces + int refprism_2fa_0e_0v_splitedges[][3] = + { + {1,4,16}, + {2,5,17}, + {3,6,18}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_NONE + }; + int refprism_2fa_0e_0v_newels[][8] = + { + {16,17,18,28,29,30}, + {1,2,3,16,17,18}, + {4,6,5,28,30,29}, + }; + +HPRef_Struct refprism_2fa_0e_0v = + + { + HP_PRISM, + refprism_2fa_0e_0v_splitedges, + 0, 0, + refprism_2fa_0e_0v_newelstypes, + refprism_2fa_0e_0v_newels + }; + + + + + +// HP_PRISM_1FA_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_0e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_0e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_0e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_NONE, + }; + int refprism_1fa_2fb_0e_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 5, 17, 19, 46, 42, 21, 25 }, + { 24, 18, 6, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 3, 12, 13, 10, 18, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 } + + }; + HPRef_Struct refprism_1fa_2fb_0e_0v = + { + HP_PRISM, + refprism_1fa_2fb_0e_0v_splitedges, + refprism_1fa_2fb_0e_0v_splitfaces, + refprism_1fa_2fb_0e_0v_splitelement, + refprism_1fa_2fb_0e_0v_newelstypes, + refprism_1fa_2fb_0e_0v_newels + }; + +// HP_PRISM_1FA_2FB_1EC ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_1ec_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_1ec_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_1ec_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_NONE, + }; + int refprism_1fa_2fb_1ec_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 5, 17, 19, 46, 42, 21, 25 }, + { 24, 23, 44, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 18, 23, 22, 6, 44, 43}, + + + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22}, + + }; + HPRef_Struct refprism_1fa_2fb_1ec_0v = + { + HP_PRISM, + refprism_1fa_2fb_1ec_0v_splitedges, + refprism_1fa_2fb_1ec_0v_splitfaces, + refprism_1fa_2fb_1ec_0v_splitelement, + refprism_1fa_2fb_1ec_0v_newelstypes, + refprism_1fa_2fb_1ec_0v_newels + }; + + +// HP_PRISM_1FA_2FB_3E ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_3e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE, + }; + int refprism_1fa_2fb_3e_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 41, 20, 19, 46, 42, 21, 25 }, + { 24, 23, 44, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 18, 23, 22, 6, 44, 43}, + { 5, 41, 42, 17, 20, 21}, + + + { 13, 9, 10, 25, 21, 22 }, + { 7, 8, 9, 13, 19, 20, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22}, + { 8, 2, 9, 20, 17, 21}, + + }; + HPRef_Struct refprism_1fa_2fb_3e_0v = + { + HP_PRISM, + refprism_1fa_2fb_3e_0v_splitedges, + refprism_1fa_2fb_3e_0v_splitfaces, + refprism_1fa_2fb_3e_0v_splitelement, + refprism_1fa_2fb_3e_0v_newelstypes, + refprism_1fa_2fb_3e_0v_newels + }; + + + + + + + + + +// HP_PRISM_1FA_2FB_1eb ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_1eb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_1eb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_1eb_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_1eb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE, + }; + + int refprism_1fa_2fb_1eb_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 41, 20, 19, 46, 42, 21, 25 }, + { 24, 18, 6, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 5, 41, 42, 17, 20, 21 }, + + + { 13, 9, 10, 25, 21, 22 }, + { 7, 8, 9, 13, 19, 20, 21, 25 }, + { 3, 12, 13, 10, 18, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 8, 2, 9, 20, 17, 21}, + + }; + HPRef_Struct refprism_1fa_2fb_1eb_0v = + { + HP_PRISM, + refprism_1fa_2fb_1eb_0v_splitedges, + refprism_1fa_2fb_1eb_0v_splitfaces, + refprism_1fa_2fb_1eb_0v_splitelement, + refprism_1fa_2fb_1eb_0v_newelstypes, + refprism_1fa_2fb_1eb_0v_newels + }; + + + + + + +// HP_PRISM_2FA_2FB +int refprism_2fa_2fb_0e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 4, 6, 45}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 0, 0, 0 } + }; +int refprism_2fa_2fb_0e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {1,3,4,24}, + {4,5,6,46}, + {4,1,5,31}, + {5,6,2,33}, + {6,5,3,34}, + {4,1,6,36}, + { 0, 0, 0, 0 } + }; +int refprism_2fa_2fb_0e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {4,1,6,5,37}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_2fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_NONE, + }; + int refprism_2fa_2fb_0e_0v_newels[][8] = + { + { 25, 21, 22, 37, 33, 34}, + { 31, 29, 17, 19, 37, 33, 21, 25}, + { 36, 24, 18, 30, 37, 25, 22, 34}, + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25}, + + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 3, 12, 13, 10, 18, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + + { 46, 43, 42 ,37, 34, 33}, + { 40, 5, 29, 31, 46, 42, 33, 37 }, + { 6, 45, 36, 30, 43, 46, 37, 34 }, + { 40, 4, 46, 31, 28, 37 }, + { 4, 45, 46, 28, 36, 37}, + + }; + HPRef_Struct refprism_2fa_2fb_0e_0v = + { + HP_PRISM, + refprism_2fa_2fb_0e_0v_splitedges, + refprism_2fa_2fb_0e_0v_splitfaces, + refprism_2fa_2fb_0e_0v_splitelement, + refprism_2fa_2fb_0e_0v_newelstypes, + refprism_2fa_2fb_0e_0v_newels + }; + + +// HP_PRISM_2FA_2FB_1EC +int refprism_2fa_2fb_1ec_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_2fa_2fb_1ec_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {4,1,5,31}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + { 0, 0, 0, 0 } + }; +int refprism_2fa_2fb_1ec_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {4,1,6,5,37}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_2fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE, + }; + int refprism_2fa_2fb_1ec_0v_newels[][8] = + { + { 25, 21, 22, 37, 33, 34}, + { 31, 29, 17, 19, 37, 33, 21, 25}, + { 36, 24, 23, 35, 37, 25, 22, 34}, + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25}, + { 18, 23, 22, 30, 35, 34}, + + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22 }, + + { 46, 43, 42 ,37, 34, 33}, + { 40, 5, 29, 31, 46, 42, 33, 37 }, + { 44, 45, 36, 35, 43, 46, 37, 34 }, + { 40, 4, 46, 31, 28, 37 }, + { 4, 45, 46, 28, 36, 37}, + { 44, 6, 43, 35, 30, 34}, + + }; + HPRef_Struct refprism_2fa_2fb_1ec_0v = + { + HP_PRISM, + refprism_2fa_2fb_1ec_0v_splitedges, + refprism_2fa_2fb_1ec_0v_splitfaces, + refprism_2fa_2fb_1ec_0v_splitelement, + refprism_2fa_2fb_1ec_0v_newelstypes, + refprism_2fa_2fb_1ec_0v_newels + }; + + + +// HP_PRISM_2FA_2FB_3E +int refprism_2fa_2fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_2fa_2fb_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + { 0, 0, 0, 0 } + }; +int refprism_2fa_2fb_3e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {4,1,6,5,37}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_2fb_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_NONE, + }; + int refprism_2fa_2fb_3e_0v_newels[][8] = + { + { 25, 21, 22, 37, 33, 34}, + { 31, 32, 20, 19, 37, 33, 21, 25}, + { 36, 24, 23, 35, 37, 25, 22, 34}, + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25}, + { 18, 23, 22, 30, 35, 34}, + { 29, 32, 33, 17, 20, 21}, + + { 13, 9, 10, 25, 21, 22 }, + { 7, 8, 9, 13, 19, 20, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22 }, + { 8, 2, 9, 20, 17, 21 }, + + { 46, 43, 42 ,37, 34, 33}, + { 40, 41, 32, 31, 46, 42, 33, 37 }, + { 44, 45, 36, 35, 43, 46, 37, 34 }, + { 40, 4, 46, 31, 28, 37 }, + { 4, 45, 46, 28, 36, 37}, + { 44, 6, 43, 35, 30, 34}, + { 5, 41, 42, 29, 32, 33}, + + }; + HPRef_Struct refprism_2fa_2fb_3e_0v = + { + HP_PRISM, + refprism_2fa_2fb_3e_0v_splitedges, + refprism_2fa_2fb_3e_0v_splitfaces, + refprism_2fa_2fb_3e_0v_splitelement, + refprism_2fa_2fb_3e_0v_newelstypes, + refprism_2fa_2fb_3e_0v_newels + }; + + + + +// HP_PRISM_1FA_2E_0V + int refprism_1fa_2e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + + }; + int refprism_1fa_2e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {1,2,4,19}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_2e_0v_newelstypes[] = + { + HP_HEX, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_SINGEDGE, + HP_PRISM_1FA_1E_0V, + HP_PRISM_SINGEDGE, + HP_PRISM_1FA_1E_0V, + HP_NONE + }; + int refprism_1fa_2e_0v_newels[][8] = + { + {40,41,20,19,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {9, 12, 7, 8, 21, 24, 19, 20}, + { 17, 21, 20, 5, 42, 41}, + {2, 9, 8, 17, 21, 20}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_2e_0v = + { + HP_PRISM, + refprism_1fa_2e_0v_splitedges, + + refprism_1fa_2e_0v_splitfaces, 0, + refprism_1fa_2e_0v_newelstypes, + refprism_1fa_2e_0v_newels + }; + +// HP_PRISM_2FA_2E_0V + int refprism_2fa_2e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {4,5,40}, + {1,2,7}, + { 5, 4, 41}, + { 2, 1, 8}, + {0,0,0}, + }; + int refprism_2fa_2e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {4,1,6,36}, + {4,1,5,31}, + {5,6,2,33}, + {5,4,2,32}, + {2,1,5,20}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_2e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_NONE, + + }; + int refprism_2fa_2e_0v_newels[][8] = + { + { 24, 21, 18, 36, 33, 30}, + { 19, 20, 21, 24, 31, 32, 33, 36}, + { 16, 19, 24, 28, 31, 36}, + { 17, 21, 20, 29, 33, 32}, + + { 12, 9, 3, 24, 21, 18}, + { 7, 8, 9, 12, 19, 20, 21, 24}, + { 1, 7, 12, 16, 19, 24}, + { 2, 9, 8, 17, 21, 20}, + + { 45, 6, 42, 36, 30, 33}, + { 40, 45, 42, 41, 31, 36, 33, 32}, + { 4, 45, 40, 28, 36, 31 }, + { 5, 41, 42, 29, 32, 33 }, + }; + HPRef_Struct refprism_2fa_2e_0v = + { + HP_PRISM, + refprism_2fa_2e_0v_splitedges, + refprism_2fa_2e_0v_splitfaces, 0, + refprism_2fa_2e_0v_newelstypes, + refprism_2fa_2e_0v_newels + }; + + + +// HP_PRISM_3E_0V + int refprism_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; + int refprism_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_NONE + }; + int refprism_3e_0v_newels[][8] = + { + { 13, 14, 15, 46, 47, 48}, + { 7, 8, 14, 13, 40, 41, 47, 46}, + { 15, 14, 9, 10, 48, 47, 42, 43}, + { 12, 13, 15, 11, 45, 46, 48, 44}, + { 14, 8, 9, 47, 41, 42 }, + { 11, 15, 10, 44, 48, 43 }, + { 7, 13, 12, 40, 46, 45}, + { 1, 7, 12, 4, 40, 45}, + { 2, 9, 8, 5, 42, 41 }, + { 3, 11, 10, 6, 44, 43 } + }; + HPRef_Struct refprism_3e_0v = + { + HP_PRISM, + refprism_3e_0v_splitedges, + refprism_3e_0v_splitfaces, 0, + refprism_3e_0v_newelstypes, + refprism_3e_0v_newels + }; + + +// HP_PRISM_3E_0V +int refprism_1fa_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + + { 0, 0, 0}, + }; +int refprism_1fa_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_1fa_3e_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_NONE + }; +int refprism_1fa_3e_0v_newels[][8] = + { + { 25, 26, 27, 46, 47, 48}, + { 19, 20, 26, 25, 40, 41, 47, 46}, + { 27, 26, 21, 22, 48, 47, 42, 43}, + { 23, 24, 25, 27, 44, 45, 46, 48}, + { 19, 25, 24, 40, 46, 45}, + { 26, 20, 21, 47, 41, 42}, + { 23, 27, 22, 44, 48, 43}, + { 16, 19, 24, 4, 40, 45}, + { 17, 21, 20, 5, 42, 41}, + { 18, 23, 22, 6, 44, 43}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 15, 14, 9, 10, 27, 26, 21, 22}, + { 12, 13, 15, 11, 24, 25, 27, 23}, + { 14, 8, 9, 26, 20, 21}, + { 11, 15, 10, 23, 27, 22}, + { 7, 13 , 12, 19, 25, 24}, + { 2, 9, 8, 17, 21, 20}, + { 3, 11, 10, 18, 23, 22}, + { 1, 7, 12, 16, 19, 24}, + }; + HPRef_Struct refprism_1fa_3e_0v = + { + HP_PRISM, + refprism_1fa_3e_0v_splitedges, + refprism_1fa_3e_0v_splitfaces, + refprism_1fa_3e_0v_splitelements, + refprism_1fa_3e_0v_newelstypes, + refprism_1fa_3e_0v_newels + }; + + + +// HP_PRISM_2FA_3E_0V +int refprism_2fa_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_2fa_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_2fa_3e_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {4,1,6,5,37}, + {5,2,4,6,38}, + {6,4,5,3,39}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_NONE + }; + + int refprism_2fa_3e_0v_newels[][8] = + { + { 25, 26, 27, 37, 38, 39}, + { 19, 20, 26, 25, 31, 32, 38, 37}, + { 27, 26, 21, 22, 39, 38, 33, 34}, + { 23, 24, 25, 27, 35, 36, 37, 39}, + { 19, 25, 24, 31, 37, 36}, + { 26, 20, 21, 38, 32, 33}, + { 23, 27, 22, 35, 39, 34}, + { 16, 19, 24, 28, 31, 36}, + { 17, 21, 20, 29, 33, 32}, + { 18, 23, 22, 30, 35, 34}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 15, 14, 9, 10, 27, 26, 21, 22}, + { 12, 13, 15, 11, 24, 25, 27, 23}, + { 14, 8, 9, 26, 20, 21}, + { 11, 15, 10, 23, 27, 22}, + { 7, 13 , 12, 19, 25, 24}, + { 2, 9, 8, 17, 21, 20}, + { 3, 11, 10, 18, 23, 22}, + { 1, 7, 12, 16, 19, 24}, + + { 48, 47, 46, 39, 38, 37 }, + { 48, 43, 42, 47, 39, 34, 33, 38}, + { 45, 44, 48, 46, 36, 35, 39, 37}, + { 46, 47, 41, 40, 37, 38, 32, 31}, + { 47, 42, 41, 38, 33, 32}, + { 45, 46, 40, 36, 37, 31}, + { 44, 43, 48, 35, 34, 39}, + { 6, 43, 44, 30, 34, 35}, + { 5, 41, 42, 29, 32, 33}, + { 4, 45, 40, 28, 36, 31}, + }; + +HPRef_Struct refprism_2fa_3e_0v = + { + HP_PRISM, + refprism_2fa_3e_0v_splitedges, + refprism_2fa_3e_0v_splitfaces, + refprism_2fa_3e_0v_splitelements, + refprism_2fa_3e_0v_newelstypes, + refprism_2fa_3e_0v_newels + }; + + + +// HP_PRISM_3FB_0V + int refprism_3fb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; + int refprism_3fb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_3fb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE + }; + int refprism_3fb_0v_newels[][8] = + { + { 13, 14, 15, 46, 47, 48}, + { 8, 7, 40, 41, 14,13, 46, 47 }, + { 10, 9, 42, 43, 15, 14, 47, 48 }, + { 44, 45, 12, 11, 48, 46, 13, 15}, + { 1, 7, 13, 4, 40, 46 }, + { 4, 45, 46, 1, 12, 13}, + { 2, 9, 14, 5, 42, 47 }, + { 5, 41, 47, 2, 8, 14 }, + { 3, 11, 15, 6, 44, 48}, + { 6, 43, 48, 3, 10, 15}, + + }; + HPRef_Struct refprism_3fb_0v = + { + HP_PRISM, + refprism_3fb_0v_splitedges, + refprism_3fb_0v_splitfaces, 0, + refprism_3fb_0v_newelstypes, + refprism_3fb_0v_newels + }; + + +// HP_PRISM_3FB_0V +int refprism_1fa_3fb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_1fa_3fb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_1fa_3fb_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_3fb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE + }; + int refprism_1fa_3fb_0v_newels[][8] = + { + { 25, 26, 27, 46, 47, 48}, + { 19, 40, 41, 20, 25, 46, 47, 26}, + { 22, 21, 42, 43, 27, 26, 47, 48}, + { 24, 23, 44, 45, 25, 27, 48, 46}, + + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 17, 21, 26, 5, 42, 47 }, + { 5, 41, 47, 17, 20, 26}, + { 18, 23, 27, 6, 44, 48}, + { 6, 43, 48, 18, 22, 27}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 9, 10, 15, 14, 21, 22, 27, 26}, + { 11, 12, 13, 15, 23, 24, 25, 27}, + + { 2, 9, 14, 17, 21, 26}, + { 8, 2, 14, 20, 17, 26}, + { 1, 7, 13, 16, 19, 25}, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 15, 18, 23, 27 }, + { 10, 3, 15, 22, 18, 27}, + + }; + HPRef_Struct refprism_1fa_3fb_0v = + { + HP_PRISM, + refprism_1fa_3fb_0v_splitedges, + refprism_1fa_3fb_0v_splitfaces, + refprism_1fa_3fb_0v_splitelements, + refprism_1fa_3fb_0v_newelstypes, + refprism_1fa_3fb_0v_newels + }; + + + +// HP_PRISM_2FA_3E_0V +int refprism_2fa_3fb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_2fa_3fb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_2fa_3fb_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {4,1,6,5,37}, + {5,2,4,6,38}, + {6,4,5,3,39}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_3fb_0v_newelstypes[] = + { + + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE + }; + int refprism_2fa_3fb_0v_newels[][8] = + { + { 25, 26, 27, 37, 38, 39}, + { 19, 31, 32, 20, 25, 37, 38, 26}, + { 33, 34, 22, 21, 38, 39, 27, 26}, + { 35, 36, 24, 23, 39, 37, 25, 27}, + + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25 }, + { 17, 21, 26, 29, 33, 38 }, + { 29, 32, 38, 17, 20, 26}, + { 18, 23, 27, 30, 35, 39}, + { 30, 34, 39, 18, 22, 27}, + + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 9, 10, 15, 14, 21, 22, 27, 26}, + { 11, 12, 13, 15, 23, 24, 25, 27}, + + { 2, 9, 14, 17, 21, 26}, + { 8, 2, 14, 20, 17, 26}, + { 1, 7, 13, 16, 19, 25}, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 15, 18, 23, 27 }, + { 10, 3, 15, 22, 18, 27}, + + + { 48, 47, 46, 39, 38, 37 }, + { 44, 45, 36, 35, 48, 46, 37, 39}, + { 40, 41, 32, 31, 46, 47, 38, 37}, + { 42, 43, 34, 33, 47, 48, 39, 38}, + + { 6, 43, 48, 30, 34, 39}, + { 44, 6, 48, 35, 30, 39}, + { 4, 45, 46, 28, 36, 37}, + { 40, 4, 46, 31, 28, 37}, + { 5, 41, 47, 29, 32, 38}, + { 42, 5, 47, 33, 29, 38}, + }; + +HPRef_Struct refprism_2fa_3fb_0v = + { + HP_PRISM, + refprism_2fa_3fb_0v_splitedges, + refprism_2fa_3fb_0v_splitfaces, + refprism_2fa_3fb_0v_splitelements, + refprism_2fa_3fb_0v_newelstypes, + refprism_2fa_3fb_0v_newels + }; + + +/* + + +// HP_PRISM_3E_4EH +int refprism_3e_4eh_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + + }; +int refprism_3e_4eh_splitfaces[][4] = + { + {3,1,2,15}, + {6,4,5,48}, + {0,0,0,0}, + }; + +HPREF_ELEMENT_TYPE refprism_2fa_3fb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_2EH_0V, + HP_HEX_2EH_0V, + HP_TET_2E, + HP_TET_2E, + HP_PRISM_1E_2EH_0V, + HP_PRISM_1E_2EH_0V, + HP_NONE + }; + int refprism_2fa_3fb_0v_newels[][8] = + { + {15, 7, 8, 48, 40, 41 }, + + }; + +HPRef_Struct refprism_2fa_3fb_0v = + { + HP_PRISM, + refprism_2fa_3fb_0v_splitedges, + refprism_2fa_3fb_0v_splitfaces, + refprism_2fa_3fb_0v_splitelements, + refprism_2fa_3fb_0v_newelstypes, + refprism_2fa_3fb_0v_newels + }; +*/ + +/* +// HP_PRISM_2FA_3E_0V +int refprism_3e_4_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_2fa_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_2fa_3e_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {4,1,6,5,37}, + {5,2,4,6,38}, + {6,4,5,3,39}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_NONE + }; + + int refprism_2fa_3e_0v_newels[][8] = + { + { 25, 26, 27, 37, 38, 39}, + { 19, 20, 26, 25, 31, 32, 38, 37}, + { 27, 26, 21, 22, 39, 38, 33, 34}, + { 23, 24, 25, 27, 35, 36, 37, 39}, + { 19, 25, 24, 31, 37, 36}, + { 26, 20, 21, 38, 32, 33}, + { 23, 27, 22, 35, 39, 34}, + { 16, 19, 24, 28, 31, 36}, + { 17, 21, 20, 29, 33, 32}, + { 18, 23, 22, 30, 35, 34}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 15, 14, 9, 10, 27, 26, 21, 22}, + { 12, 13, 15, 11, 24, 25, 27, 23}, + { 14, 8, 9, 26, 20, 21}, + { 11, 15, 10, 23, 27, 22}, + { 7, 13 , 12, 19, 25, 24}, + { 2, 9, 8, 17, 21, 20}, + { 3, 11, 10, 18, 23, 22}, + { 1, 7, 12, 16, 19, 24}, + + { 48, 47, 46, 39, 38, 37 }, + { 48, 43, 42, 47, 39, 34, 33, 38}, + { 45, 44, 48, 46, 36, 35, 39, 37}, + { 46, 47, 41, 40, 37, 38, 32, 31}, + { 47, 42, 41, 38, 33, 32}, + { 45, 46, 40, 36, 37, 31}, + { 44, 43, 48, 35, 34, 39}, + { 6, 43, 44, 30, 34, 35}, + { 5, 41, 42, 29, 32, 33}, + { 4, 45, 40, 28, 36, 31}, + }; + +HPRef_Struct refprism_2fa_3e_0v = + { + HP_PRISM, + refprism_2fa_3e_0v_splitedges, + refprism_2fa_3e_0v_splitfaces, + refprism_2fa_3e_0v_splitelements, + refprism_2fa_3e_0v_newelstypes, + refprism_2fa_3e_0v_newels + }; + +*/ +/* + +// HP_PRISM_1FB_1EB_0V ... quad face 1-2-4-5 + int refprism_1fb_1eb_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 4, 6, 9 }, + { 5, 6, 10 }, + { 2, 1, 11 }, + { 5, 4, 12 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_1eb_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EB_0V, + HP_PRISM, + HP_NONE, + }; + int refprism_1fb_1eb_0v_newels[][8] = + { + { 1, 4, 12, 11, 7, 9, 10, 8 }, + { 11, 2, 8, 12, 5, 10 }, + { 7, 8, 3, 9, 10, 6 } + }; + HPRef_Struct refprism_1fb_1eb_0v = + { + HP_PRISM, + refprism_1fb_1eb_0v_splitedges, + 0, 0, + refprism_1fb_1eb_0v_newelstypes, + refprism_1fb_1eb_0v_newels + }; + + + + + + + + + + + // HP_PRISM_2F_0E_0V + int refprism_2f_0e_0v_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_2f_0e_0v_splitfaces[][4] = + { + { 2, 1, 3, 11 }, + { 5, 4, 6, 16 }, + { 0, 0, 0, 0 }, + }; + + HPREF_ELEMENT_TYPE refprism_2f_0e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM, + HP_NONE, + }; + int refprism_2f_0e_0v_newels[][8] = + { + //{ 1, 8, 11, 7, 4, 13, 16, 12 }, + // { 9, 3, 10, 11, 14, 6, 15, 16 }, + { 1, 4, 13, 8, 7, 12, 16, 11 }, + { 9, 14, 6, 3, 11, 16, 15, 10 }, + { 2, 9, 11, 5, 14, 16 }, + // { 8, 2, 11, 13, 5, 16 }, + { 5, 13, 16, 2, 8, 11 }, + { 7, 11, 10, 12, 16, 15 } + }; + HPRef_Struct refprism_2f_0e_0v = + { + HP_PRISM, + refprism_2f_0e_0v_splitedges, + refprism_2f_0e_0v_splitfaces, + 0, + refprism_2f_0e_0v_newelstypes, + refprism_2f_0e_0v_newels + }; + +*/ diff --git a/libsrc/meshing/hpref_pyramid.hpp b/libsrc/meshing/hpref_pyramid.hpp new file mode 100644 index 00000000..521daf50 --- /dev/null +++ b/libsrc/meshing/hpref_pyramid.hpp @@ -0,0 +1,118 @@ + + // 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 } + }; + HPRef_Struct refpyramid = + { + HP_PYRAMID, + refpyramid_splitedges, + 0, 0, + refpyramid_newelstypes, + refpyramid_newels + }; + + +// singular point 1 + // 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 + }; + + +// singular edges 1-2 1-4 singular point 1 + // 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 + }; + + + +// singular face 1-2-5 singular point 5 + // 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 + }; + + + + diff --git a/libsrc/meshing/hpref_quad.hpp b/libsrc/meshing/hpref_quad.hpp new file mode 100644 index 00000000..2a23156d --- /dev/null +++ b/libsrc/meshing/hpref_quad.hpp @@ -0,0 +1,2082 @@ +// 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 }, +}; +*/ + +// SZ refine to 4 quads +HPREF_ELEMENT_TYPE refquad_2e_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2e_newels[][8] = +{ + { 1, 5, 9, 6 }, + { 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 }, +}; +*/ +// SZ Quad_2e refinement +HPREF_ELEMENT_TYPE refquad_2e_1va_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_2e_1va_newels[][8] = +{ + { 1, 5, 9, 6 }, + { 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, + // SZ QUAD_2E + HP_QUAD_2E, + 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 }, + { 1, 5, 9, 6 }, + { 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_QUAD_2E, + 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 }, + { 1, 5, 10, 6}, + { 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_2VA +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_2E, + 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 }, + { 1, 5, 9, 6 }, + { 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_QUAD_2E, + 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 }, + { 1, 5, 11, 6 }, + { 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_2VC +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_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGEDGECORNER1, //SZ (vorher: 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_3V +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_2E, + 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 }, + { 1, 5, 9, 6 }, + { 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/libsrc/meshing/hpref_segm.hpp b/libsrc/meshing/hpref_segm.hpp new file mode 100644 index 00000000..25445823 --- /dev/null +++ b/libsrc/meshing/hpref_segm.hpp @@ -0,0 +1,122 @@ + // 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 + }; + + + + diff --git a/libsrc/meshing/hpref_tet.hpp b/libsrc/meshing/hpref_tet.hpp new file mode 100644 index 00000000..df0e2af8 --- /dev/null +++ b/libsrc/meshing/hpref_tet.hpp @@ -0,0 +1,3128 @@ + + + +// 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_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 }, + { 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 }, + { 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_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, 3, 4, 17 }, + { 2, 3, 4, 18 }, + + { 3, 1, 4, 19 }, + { 3, 2, 4, 20 }, + + { 4, 1, 3, 21 }, + { 4, 2, 3, 22 }, + { 0, 0, 0, 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_1e_4v_newelstypes[] = +{ + HP_TET_1E_1VA, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + + HP_PYRAMID, + HP_TET_0E_1V, + + HP_PYRAMID, + HP_TET_0E_1V, + + HP_NONE, +}; + +int reftet_1e_4v_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + + { 5, 6, 7, 8, 9, 10 }, + { 7, 6, 17, 10, 9, 18 }, + + { 7, 10, 18, 17, 14, 15, 22, 21 }, + { 9, 6, 17, 18, 12, 11, 19, 20 }, + + { 17, 19, 21, 18, 20, 22 }, + { 16, 22, 21, 13, 20, 19 }, + + { 14, 15, 22, 21, 16 }, + { 4, 14, 16, 15 }, + { 12, 11, 19, 20, 13 }, + { 3, 11, 12, 13 }, + + + + { 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 }, + { 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, + 0, + 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_1V, // V1 + + +// HP_TET_2EB_1V, // 2 opposite edges, V1 +int reftet_2eb_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 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_1v_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_1v_newels[][8] = +{ + { 5, 6, 7, 2, 9, 10 }, + { 4, 15, 14, 3, 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_1v = +{ + HP_TET, + reftet_2eb_1v_splitedges, + 0, 0, + reftet_2eb_1v_newelstypes, + reftet_2eb_1v_newels +}; + + + +// HP_TET_2EB_2VA, // 2 opposite edges, V1,2 +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, 8, 9, 10 }, + { 4, 15, 14, 3, 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_2VB, // V1,3 +int reftet_2eb_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 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_2vb_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_2vb_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_2vb = +{ + HP_TET, + reftet_2eb_2vb_splitedges, + 0, 0, + reftet_2eb_2vb_newelstypes, + reftet_2eb_2vb_newels +}; + + + + +// HP_TET_2EB_2VC, // V1,4 +int reftet_2eb_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 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_2vc_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_2vc_newels[][8] = +{ + { 5, 6, 7, 2, 9, 10 }, + { 16, 15, 14, 3, 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_2vc = +{ + HP_TET, + reftet_2eb_2vc_splitedges, + 0, 0, + reftet_2eb_2vc_newelstypes, + reftet_2eb_2vc_newels +}; + + + + + + +// HP_TET_2EB_3V, // V1,2,3 +int reftet_2eb_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 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_3v_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_3v_newels[][8] = +{ + { 5, 6, 7, 8, 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_3v = +{ + HP_TET, + reftet_2eb_3v_splitedges, + 0, 0, + reftet_2eb_3v_newelstypes, + reftet_2eb_3v_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/libsrc/meshing/hpref_trig.hpp b/libsrc/meshing/hpref_trig.hpp new file mode 100644 index 00000000..3676ad0f --- /dev/null +++ b/libsrc/meshing/hpref_trig.hpp @@ -0,0 +1,776 @@ + + +// 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 +}; + + +// HP_TRIG_3SINGEDGES +int reftrig_3singedges_splitedges[][3] = +{ + { 1, 2, 4 }, + { 2, 1, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 3, 1, 8 }, + { 1, 3, 9 }, + { 0, 0, 0 } +}; +int reftrig_3singedges_splitfaces[][4] = +{ + { 1, 2, 3, 10 }, + { 2, 3, 1, 11 }, + { 3, 1, 2, 12 }, + { 0, 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftrig_3singedges_newelstypes[] = +{ + HP_TRIG, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int reftrig_3singedges_newels[][8] = +{ + { 10, 11, 12 }, + { 4, 5, 11, 10 }, + { 6, 7, 12, 11 }, + { 8, 9, 10, 12 }, + { 1, 4, 10 }, + { 9, 1, 10 }, + { 2, 6, 11 }, + { 5, 2, 11 }, + { 3, 8, 12 }, + { 7, 3, 12 }, +}; +HPRef_Struct reftrig_3singedges = +{ + HP_TRIG, + reftrig_3singedges_splitedges, + reftrig_3singedges_splitfaces, + 0, + reftrig_3singedges_newelstypes, + reftrig_3singedges_newels +}; diff --git a/libsrc/meshing/hprefinement.cpp b/libsrc/meshing/hprefinement.cpp new file mode 100644 index 00000000..0ba4238b --- /dev/null +++ b/libsrc/meshing/hprefinement.cpp @@ -0,0 +1,1955 @@ +#include +#include "meshing.hpp" +#include "hprefinement.hpp" + +namespace netgen +{ + +#include "hpref_segm.hpp" +#include "hpref_trig.hpp" +#include "hpref_quad.hpp" +#include "hpref_tet.hpp" +#include "hpref_prism.hpp" +#include "hpref_hex.hpp" +#include "hpref_pyramid.hpp" +#include "classifyhpel.hpp" + + + void HPRefElement :: Reset(void) + { + np = 8; + for (int i = 0; i < 8; i++) + { + pnums[i] = -1; + param[i][0] = param[i][1] = param[i][2] = 0; + domin=-1; domout=-1; // he: + } + } + + HPRefElement :: HPRefElement () + { + Reset(); + } + + HPRefElement :: HPRefElement(Element & el) + { + //Reset(); + np = el.GetNV(); + for (int i=0; igeom == HP_TET) + hps = &reftet; + if (hps->geom == HP_TRIG) + hps = &reftrig; + } + */ + + if (!hps) + { + cout << "Attention hps : hp-refinement not implemented for case " << type << endl; + PrintSysError ("hp-refinement not implemented for case ", type); + } + + return hps; + } + + bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoiclt_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint, int & levels, int & act_ref); + + bool ClassifyHPElements (Mesh & mesh, ARRAY & elements, int & act_ref, int & levels); + + + void InitHPElements(Mesh & mesh, ARRAY & elements) + { + for(ElementIndex i=0;i= 10000) + { + throw NgException("assumption that seg.edgenr < 10000 is wrong"); + } + elements.Append(hpel); + + } + } + + + + /* ******************************* DoRefinement *************************************** */ + void DoRefinement (Mesh & mesh, ARRAY & elements, + Refinement * ref, double fac1) + { + elements.SetAllocSize (5 * elements.Size()); + INDEX_2_HASHTABLE newpts(elements.Size()+1); + INDEX_3_HASHTABLE newfacepts(elements.Size()+1); + + // prepare new points + + fac1 = max(0.001,min(0.33,fac1)); + cout << " in HP-REFINEMENT with fac1 " << fac1 << endl; + *testout << " in HP-REFINEMENT with fac1 " << fac1 << endl; + + + 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)) + { + Point<3> np; + for( int l=0;l<3;l++) + np(l) = (1-fac1)*mesh.Point(i2.I1())(l) + + fac1 * mesh.Point(i2.I2())(l); + + 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)) + { + Point<3> np; + for( int l=0;l<3;l++) + np(l) = (1-2*fac1)*mesh.Point(i3.I1())(l) + + fac1*mesh.Point(i3.I2())(l) + fac1*mesh.Point(i3.I3())(l); + 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.levelx + 1; + + int oldnp(0); + switch (hprs->geom) + { + case HP_SEGM: oldnp = 2; break; + case HP_TRIG: oldnp = 3; break; + case HP_QUAD: oldnp = 4; break; + case HP_TET: oldnp = 4; break; + case HP_PYRAMID: oldnp = 5; break; + case HP_PRISM: oldnp = 6; break; + case HP_HEX: oldnp = 8; break; + } + + + 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 || + el.type == HP_PYRAMID) + newlevel = el.levelx; + + if (!hprs) continue; + + int newpnums[64]; + double newparam[64][3]; + + int j; + for (j = 0; j < oldnp; 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; + + for (int l = 0; l < 3; l++) + newparam[hprs->splitedges[j][2]-1][l] = + (1-fac1) * el.param[hprs->splitedges[j][0]-1][l] + + fac1 * 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; + + + for (int l = 0; l < 3; l++) + newparam[hprs->splitfaces[j][3]-1][l] = + (1-2*fac1) * el.param[hprs->splitfaces[j][0]-1][l] + + fac1 * el.param[hprs->splitfaces[j][1]-1][l] + + fac1 * 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]; + Point<3> np; + for( int l=0;l<3;l++) + np(l) = (1-3*fac1)* mesh.Point(el.pnums[hprs->splitelements[j][0]-1])(l) + + fac1* mesh.Point(el.pnums[hprs->splitelements[j][1]-1])(l) + + fac1* mesh.Point(el.pnums[hprs->splitelements[j][2]-1])(l) + + fac1* mesh.Point(el.pnums[hprs->splitelements[j][3]-1])(l); + + int npi = mesh.AddPoint (np); + + newpnums[hprs->splitelements[j][4]-1] = npi; + + + for (int l = 0; l < 3; l++) + newparam[hprs->splitelements[j][4]-1][l] = + (1-3*fac1) * el.param[hprs->splitelements[j][0]-1][l] + + fac1 * el.param[hprs->splitelements[j][1]-1][l] + + fac1 * el.param[hprs->splitelements[j][2]-1][l] + + fac1 * el.param[hprs->splitelements[j][3]-1][l]; + + j++; + } + + j = 0; + + /* + *testout << " newpnums = "; + for (int hi = 0; hi < 64; hi++) + *testout << newpnums[hi] << " "; + *testout << endl; + */ + + while (hprs->neweltypes[j]) + { + HPRef_Struct * hprsnew = Get_HPRef_Struct (hprs->neweltypes[j]); + HPRefElement newel(el); + + newel.type = hprs->neweltypes[j]; + + // newel.index = elements[i].index; + // newel.coarse_elnr = elements[i].coarse_elnr; + newel.levelx = newel.levely = newel.levelz = newlevel; + switch(hprsnew->geom) + { + case HP_SEGM: newel.np=2; break; + case HP_QUAD: newel.np=4; break; + case HP_TRIG: newel.np=3; break; + case HP_HEX: newel.np=8; break; + case HP_PRISM: newel.np=6; break; + case HP_TET: newel.np=4; break; + case HP_PYRAMID: newel.np=5; break; + } + + for (int k = 0; k < newel.np; k++) + newel.pnums[k] = newpnums[hprs->newels[j][k]-1]; + + /* + *testout << " newel pnums " ; + for (int k = 0; k < newel.np; k++) + *testout << newel.pnums[k] << "\t"; + *testout << endl; + */ + + for (int k = 0; k < newel.np; k++) + { + for (int l = 0; l < 3; l++) + { + newel.param[k][l] = newparam[hprs->newels[j][k]-1][l]; + // *testout << newel.param[k][l] << " \t "; + } + // *testout << endl; + } + + if (j == 0) + elements[i] = newel; // overwrite old element + else + elements.Append (newel); + j++; + } + } + } + + + + + + + /* ************************** DoRefineDummies ******************************** */ + + void DoRefineDummies (Mesh & mesh, ARRAY & 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.levelx; + + 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]) + { + HPRef_Struct * hprsnew = Get_HPRef_Struct (hprs->neweltypes[j]); + HPRefElement newel(el); + switch(hprsnew->geom) + { + case HP_SEGM: newel.np=2; break; + case HP_QUAD: newel.np=4; break; + case HP_TRIG: newel.np=3; break; + case HP_HEX: newel.np=8; break; + case HP_PRISM: newel.np=6; break; + case HP_TET: newel.np=4; break; + case HP_PYRAMID: newel.np=5; break; + } + 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.levelx = newel.levely = newel.levelz = 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 & elements, double fac1) + { + 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) + { + + + cout << " Degenerate Hex found " << endl; + *testout << " Degenerate Hex found " << endl; + HPRefElement el = elements[i]; + HPRefElement newel = el; + + 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]]); + // 0.125 originates form 8 points not from fac1; + + 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 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); + + } + + + if (pts.Size() == 3) // TrigFace -> TET + { + + 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; + newel.np = 4; + } + 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; + newel.np = 5; + } + + if (j == 0) + elements[i] = newel; + else + elements.Append (newel); + + + } + + /* const ELEMENT_EDGE * edges = MeshTopology::GetEdges (HEX); + + for(int k=0;k<12;k++) + { + int e[2]; + for(int l=0;l<2;l++) e[l] = edges[k][l]-1; + if(el.PNum(e[0]+1)!=el.PNum(e[1]+1)) + { + newel.SetType(HP_SEGM); + for(int l=0;l<2;l++) + { + newel.pnums[0] = el.PNum(e[l]+1); + newel.pnums[1] = npi; + for(int j=0;j<3;j++) + { + // newel.param[0][j] = el.param[e[l]][j]; + // newel.param[1][j] = newparam[j]; + } + + elements.Append(newel); + } + newel.SetType(HP_TRIG); + newel.pnums[0] = el.PNum(e[0]+1); + newel.pnums[1] = el.PNum(e[1]+1); + newel.pnums[2] = npi; + + *testout << "DEGHEX TRIG :: newpnums " << newel.pnums[0] << "\t" << newel.pnums[1] << "\t" << newel.pnums[2] << endl; + cout << "DEGHEX TRIG :: newpnums " << newel.pnums[0] << "\t" << newel.pnums[1] << "\t" << newel.pnums[2] << endl; + for(int j=0;j<3;j++) + { + // newel.param[0][j] = el.param[e[0]][j]; + // newel.param[1][j] = el.param[e[1]][j]; + // newel.param[2][j] = newparam[j]; + } + + elements.Append(newel); + } + + }*/ + } + } + } + + + void CalcStatistics (ARRAY & elements) + { + return; +#ifdef ABC + 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(p), 6.0); + cpucost = (ntet + nprism + nhex) * pow (static_cast(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(p1), 6.0) + << " (p1-3)^6 = " << pow ( static_cast(max2(p1-3, 0)), 6.0) + << " p1^3 = " << pow ( static_cast(p1), 3.0) + << " (p1-3)^3 = " << pow ( static_cast(p1-3), 3.0) + << " [p1^3-(p1-3)^3]^2 = " << sqr (pow (static_cast(p1),3.0) - pow ( static_cast(p1-3), 3.0)) + << endl; + + p1 /= 2 +1; + memcosttet += pow (static_cast(p1), 6.0); + memcostsctet += pow (static_cast(p1), 6.0) - pow ( static_cast(max2(p1-3, 1)), 6.0); + cpucosttet += pow (static_cast(p1), 9.0); + break; + } + case HP_PRISM: + case HP_PRISM_SINGEDGE: + { + int p1 = maxlevel - el.level + 1; + p1 /= 2 +1; + memcostprism += pow (static_cast(p1), 6.0); + memcostscprism += pow (static_cast(p1), 6.0) - pow ( static_cast(max2(p1-3, 1)), 6.0); + cpucostprism += pow (static_cast(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(p1), 4.0) * pow (static_cast(p2), 2.0); + memcostschex += pow (static_cast(p1), 6.0) - pow ( static_cast(max2(p1-2, 0)), 6.0); + cpucosthex += pow (static_cast(p1), 6.0) * pow (static_cast(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; +#endif + } + + + + void ReorderPoints (Mesh & mesh, ARRAY & hpelements) + { + ARRAY map (mesh.GetNP()); + + for (int i = 1; i <= mesh.GetNP(); i++) + map[i] = i; + + int nwrong(0), nright(0); + for (int k = 0; k < 5; k++) + { + nwrong = nright = 0; + for (int i = 0; i < hpelements.Size(); i++) + { + const HPRefElement & hpel = hpelements[i]; + + if (Get_HPRef_Struct (hpel.type) -> geom == HP_PRISM) + { + int minbot = 0, mintop = 0; + for (int j = 0; j < 3; j++) + { + if (map[hpel.pnums[j]] < map[hpel.pnums[minbot]]) minbot = j; + if (map[hpel.pnums[j+3]] < map[hpel.pnums[mintop+3]]) mintop = j; + } + if (minbot != mintop) + nwrong++; + else + nright++; + + if (minbot != mintop) + { + if (map[hpel.pnums[minbot]] < map[hpel.pnums[mintop+3]]) + swap (map[hpel.pnums[3+minbot]], map[hpel.pnums[3+mintop]]); + else + swap (map[hpel.pnums[minbot]], map[hpel.pnums[mintop]]); + } + } + } + // cout << nwrong << " wrong prisms, " << nright << " right prisms" << endl; + } + + cout << nwrong << " wrong prisms, " << nright << " right prisms" << endl; + + + ARRAY hpts(mesh.GetNP()); + + for (int i = 1; i <= mesh.GetNP(); i++) + hpts[map[i]] = mesh.Point(i); + + for (int i = 1; i <= mesh.GetNP(); i++) + mesh.Point(i) = hpts[i]; + + for (int i = 0; i < hpelements.Size(); i++) + { + HPRefElement & hpel = hpelements[i]; + for (int j = 0; j < hpel.np; j++) + hpel.pnums[j] = map[hpel.pnums[j]]; + } + } + + + + /* ***************************** HPRefinement ********************************** */ + + void HPRefinement (Mesh & mesh, Refinement * ref, int levels, double fac1, bool setorders, bool reflevels) + { + PrintMessage (1, "HP Refinement called, levels = ", levels); + + + NgLock mem_lock (mem_mutex,1); + + mesh.coarsemesh = new Mesh; + *mesh.coarsemesh = mesh; + +#ifdef CURVEDELEMS_NEW + const_cast (mesh.coarsemesh->GetCurvedElements() ). + BuildCurvedElements (ref, mesh.GetCurvedElements().GetOrder()); +#endif + + + delete mesh.hpelements; + mesh.hpelements = new ARRAY; + + ARRAY & hpelements = *mesh.hpelements; + + InitHPElements(mesh,hpelements); + + ARRAY nplevel; + nplevel.Append (mesh.GetNP()); + + int act_ref=1; + bool sing = ClassifyHPElements(mesh,hpelements, act_ref, levels); + + sing = true; // iterate at least once + while(sing) + { + cout << " Start new hp-refinement: step " << act_ref << endl; + + DoRefinement (mesh, hpelements, ref, fac1); + DoRefineDummies (mesh, hpelements, ref); + + nplevel.Append (mesh.GetNP()); + CalcStatistics (hpelements); + + SubdivideDegeneratedHexes (mesh, hpelements,fac1); + + ReorderPoints (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]; // he: war hpel.param[0][0] + seg.epgeominfo[1].dist = hpel.param[1][0]; // he: war hpel.param[1][0] + */ + + const Segment & coarseseg = mesh.coarsemesh->LineSegment(hpel.coarse_elnr+1); + double d1 = coarseseg.epgeominfo[0].dist; + double d2 = coarseseg.epgeominfo[1].dist; + + // seg.epgeominfo[0].dist = hpel.param[0][0]; // he: war hpel.param[0][0] + // seg.epgeominfo[1].dist = hpel.param[1][0]; // he: war hpel.param[1][0] + + seg.epgeominfo[0].dist = d1 + hpel.param[0][0] * (d2-d1); // JS, June 08 + seg.epgeominfo[1].dist = d1 + hpel.param[1][0] * (d2-d1); + + + seg.epgeominfo[0].edgenr = seg.edgenr; + seg.epgeominfo[1].edgenr = seg.edgenr; + seg.domin = hpel.domin; seg.domout=hpel.domout; // he: needed for segments! + seg.hp_elnr = i; + seg.singedge_left = hpel.singedge_left; + seg.singedge_right = hpel.singedge_right; + mesh.AddSegment (seg); + break; + } + + case HP_TRIG: + case HP_QUAD: + { + Element2d el(hpel.np); + for(int j=0;j geom)); + } + } + cout << " Start with Update Topology " << endl; + mesh.UpdateTopology(); + cout << " Mesh Update Topology done " << endl; + + act_ref++; + + sing = ClassifyHPElements(mesh,hpelements, act_ref, levels); + } + + cout << " HP-Refinement done with " << --act_ref << " refinement steps." << endl; + + if(act_ref>=1) + { + for(ElementIndex i=0;i v(hpel.param[edges[j][0]-1][0]-hpel.param[edges[j][1]-1][0], + hpel.param[edges[j][0]-1][1]-hpel.param[edges[j][1]-1][1], + hpel.param[edges[j][0]-1][2]-hpel.param[edges[j][1]-1][2]); + dist[edge_dir[j]] = max(v.Length(),dist[edge_dir[j]]); + } + + int refi[3]; + for(int j=0;j<3;j++) + refi[j] = int(max(double(floor(log(dist[ord_dir[j]]/sqrt(2.))/log(fac1))),0.)); + + // cout << " ref " << refi[0] << "\t" << refi[1] << "\t" << refi[2] << endl; + // cout << " order " << act_ref +1 - refi[0] << "\t" << act_ref +1 - refi[1] << "\t" << act_ref +1 - refi[2] << endl; + + if(setorders) + mesh[i].SetOrder(act_ref+1-refi[0],act_ref+1-refi[1],act_ref+1-refi[2]); + } + for(SurfaceElementIndex i=0;i v(hpel.param[edges[j][0]-1][0]-hpel.param[edges[j][1]-1][0], + hpel.param[edges[j][0]-1][1]-hpel.param[edges[j][1]-1][1], + hpel.param[edges[j][0]-1][2]-hpel.param[edges[j][1]-1][2]); + dist[edge_dir[j]] = max(v.Length(),dist[edge_dir[j]]); + } + + int refi[3]; + for(int j=0;j<3;j++) + refi[j] = int(max(double(floor(log(dist[ord_dir[j]]/sqrt(2.))/log(fac1))),0.)); + + if(setorders) + mesh[i].SetOrder(act_ref+1-refi[0],act_ref+1-refi[1],act_ref+1-refi[2]); + + // cout << " ref " << refi[0] << "\t" << refi[1] << endl; + // cout << " order " << act_ref +1 - refi[0] << "\t" << act_ref +1 - refi[1] << endl; + } + } + } + +bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, ARRAY & facepoint, int & levels, int & act_ref) +{ + bool sing=0; + if (mesh.GetDimension() == 3) + { + /* + // check, if point has as least 3 different surfs: + + ARRAY 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).Singularity() * levels >= act_ref) + { + cornerpoint.Set(i); + sing = 1; + } + } + cout << endl; + + for (int i = 1; i <= mesh.GetNSeg(); i++) + if (mesh.LineSegment(i).singedge_left * levels >= act_ref) + { + INDEX_2 i2 (mesh.LineSegment(i).p1, + mesh.LineSegment(i).p2); + + /* + // before + edges.Set (i2, 1); + i2.Sort(); + INDEX_2 i2s(i2.I2(), i2.I1()); + edges.Set (i2s, 1); + */ + + edges.Set (i2, 1); + INDEX_2 i2s(i2.I2(), i2.I1()); + edges.Set (i2s, 1); + + + edgepoint.Set (i2.I1()); + edgepoint.Set (i2.I2()); + sing = 1; + } + + // 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()); + + int domnr = 0; + if (fd.domin_singular * levels < act_ref && fd.domout_singular * levels < act_ref) + { domnr=0; continue;} + + if (fd.domin_singular * levels >= act_ref) + { + domnr = fd.DomainIn(); + sing = 1; + } + if (fd.domout_singular * levels >= act_ref) + { + domnr = fd.DomainOut(); + sing = 1; + } + if (fd.domin_singular * levels >= act_ref + && fd.domout_singular * levels >= act_ref) + { + domnr = -1; + sing = 1; + } + + INDEX_3 i3; + if (el.GetNP() == 3) + i3 = INDEX_3::Sort (el[0], el[1], el[2]); + else + { + INDEX_4 i4 (el[0], el[1], el[2], el[3]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + } + faces.Set (i3, domnr); + + for (int j = 0; j < el.GetNP(); j++) + { + face_edges.Set (INDEX_2::Sort (el[j], el[(j+1)%el.GetNP()]), domnr); + + surf_edges.Set (INDEX_2::Sort (el[j], el[(j+1)%el.GetNP()]), fd.SurfNr()+1); + + facepoint[el[j]] = domnr; + } + + } + (*testout) << "singular faces = " << faces << endl; + (*testout) << "singular faces_edges = " << face_edges << endl; + } + else + { + // 2D case + + // check, if point has as least 3 different surfs: + ARRAY 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 * levels >= act_ref) + { + INDEX_2 i2 (mesh.LineSegment(i).p1, + mesh.LineSegment(i).p2); + edges.Set(i2,1); + edgepoint.Set(i2.I1()); + edgepoint.Set(i2.I2()); + *testout << " singleft " << endl; + *testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl; + *testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl; + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I1()), 1); + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I2()), 1); + sing = 1; + + } + + if (seg.singedge_right * levels >= act_ref) + { + INDEX_2 i2 (mesh.LineSegment(i).p2, + mesh.LineSegment(i).p1); + edges.Set (i2, 1); + edgepoint.Set(i2.I1()); + edgepoint.Set(i2.I2()); + + *testout << " singright " << endl; + *testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl; + *testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl; + + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I1()), 1); + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I2()), 1); + sing = 1; + } + + // (*testout) << "seg = " << ind << ", " << seg.p1 << "-" << seg.p2 << endl; + + + if (seg.singedge_left * levels >= act_ref + || seg.singedge_right* levels >= act_ref) + { + 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).Singularity()*levels >= act_ref) + { + cornerpoint.Set(i); + edgepoint.Set(i); + sing = 1; + } + } + + edgepoint.Or (cornerpoint); + + (*testout) << "2d sing edges: " << endl << edges << endl; + (*testout) << "2d cornerpoints: " << endl << cornerpoint << endl + << "2d edgepoints: " << endl << edgepoint << endl; + + facepoint = 0; + } + + if (!sing) + { + cout << "PrepareElements no more to do for actual refinement " << act_ref << endl; + return(sing); + } + return(sing); +} + + + + bool ClassifyHPElements (Mesh & mesh, ARRAY & elements, int & act_ref, int & levels) + { + + INDEX_2_HASHTABLE edges(mesh.GetNSeg()+1); + BitArray edgepoint(mesh.GetNP()); + INDEX_2_HASHTABLE 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 faces(mesh.GetNSE()+1); + INDEX_2_HASHTABLE face_edges(mesh.GetNSE()+1); + INDEX_2_HASHTABLE surf_edges(mesh.GetNSE()+1); + ARRAY facepoint(mesh.GetNP()); + + bool sing = CheckSingularities(mesh, edges, edgepoint_dom, + cornerpoint, edgepoint, faces, face_edges, + surf_edges, facepoint, levels, act_ref); + + if(sing==0) return(sing); + + int cnt_undef = 0, cnt_nonimplement = 0; + ARRAY misses(10000); + misses = 0; + + (*testout) << "edgepoint_dom = " << endl << edgepoint_dom << endl; + + for( int i = 0; igeom) + { + case HP_TET: + { + hpel.type = ClassifyTet(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces,face_edges, surf_edges, facepoint); + break; + } + case HP_PRISM: + { + hpel.type = ClassifyPrism(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces, + face_edges, surf_edges, facepoint); + + + break; + } + case HP_HEX: + { + hpel.type = hpel.type = ClassifyHex(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces, + face_edges, surf_edges, facepoint); + break; + } + case HP_TRIG: + { + int dim = mesh.GetDimension(); + const FaceDescriptor & fd = mesh.GetFaceDescriptor (hpel.GetIndex()); + + hpel.type = ClassifyTrig(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, + faces, face_edges, surf_edges, facepoint, dim, fd); + + dd = 2; + break; + } + case HP_QUAD: + { + int dim = mesh.GetDimension(); + const FaceDescriptor & fd = mesh.GetFaceDescriptor (hpel.GetIndex()); + hpel.type = ClassifyQuad(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, + faces, face_edges, surf_edges, facepoint, dim, fd); + + dd = 2; + break; + } + case HP_SEGM: + { + hpel.type = ClassifySegm(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, + faces, face_edges, surf_edges, facepoint); + dd = 1; + break; + } + case HP_PYRAMID: + { + hpel.type = ClassifyPyramid(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces, + face_edges, surf_edges, facepoint); + + cout << " ** Pyramid classified " << hpel.type << endl; + break; + } + default: + { + cout << "illegal element type for hp-prepare elements " << hpel.type << endl; + throw NgException ("hprefinement.cpp: don't know how to set parameters"); + } + } + + if(hpel.type == HP_NONE) + cnt_undef++; + + //else + //cout << "elem " << i << " classified type " << hpel.type << endl; + + + + if (!Get_HPRef_Struct (hpel.type)) + { + (*testout) << "hp-element-type " << hpel.type << " not implemented " << endl; + (*testout) << " elType " << hprs->geom << endl; + (cout) << " elType " << hprs->geom << endl; + cnt_nonimplement++; + misses[hpel.type]++; + } + + + for(int j=0; jgeom) + { + case HP_SEGM: np=2; sing_edge_left=0; sing_edge_right=0; break; + case HP_QUAD: np=4; break; + case HP_TRIG: np=3; break; + case HP_HEX: np=8; break; + case HP_PRISM: np=6; break; + case HP_TET: np=4; break; + case HP_PYRAMID: np=5; break; + } + index = el.index; + levelx = el.levelx; + levely = el.levely; + levelz = el.levelz; + type = el.type; + coarse_elnr = el.coarse_elnr; + singedge_left = el.singedge_left; + singedge_right = el.singedge_left; + } */ + + HPREF_ELEMENT_TYPE type; + PointIndex pnums[8]; + double param[8][3]; + int index; + int levelx; + int levely; + int levelz; + int np; + int coarse_elnr; + int domin, domout; // he: needed for segment!! in 3d there should be surf1, surf2!! + // int coarse_hpelnr; + PointIndex & operator[](int i) { return(pnums[i]);} + PointIndex & PNumMod(int i) { return pnums[(i-1) % np]; }; + PointIndex & PNum(int i) {return pnums[(i-1)]; }; + int GetIndex () const { return index; }; + double singedge_left, singedge_right; + + + // EdgePointGeomInfo epgeominfo[2]; + +}; + + + +extern void HPRefinement (Mesh & mesh, Refinement * ref, int levels, + double fac1=0.125, bool setorders=true, bool ref_level = false); + + +#endif + diff --git a/libsrc/meshing/improve2.cpp b/libsrc/meshing/improve2.cpp new file mode 100644 index 00000000..4824d4eb --- /dev/null +++ b/libsrc/meshing/improve2.cpp @@ -0,0 +1,831 @@ +#include + +#include "meshing.hpp" +#include + +#ifndef SMALLLIB +//#ifndef NOTCL +//#include +//#endif +#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; + } + + + static int timer = NgProfiler::CreateTimer ("EdgeSwapping 2D"); + NgProfiler::RegionTimer reg1 (timer); + + + int i, i2, j, j2; + bool should; + PointIndex pi; + + ARRAY 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 neighbors(mesh.GetNSE()); + INDEX_2_HASHTABLE other(seia.Size() + 2); + + + ARRAY swapped(mesh.GetNSE()); + ARRAY pdef(mesh.GetNP()); + ARRAY 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(-1); + 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[sel[j]].Type(); + 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[pi].Type() == INNERPOINT || mesh[pi].Type() == 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 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); + + bool allowswap = true; + + Vec3d auxvec1,auxvec2; + + auxvec1 = mesh.Point(pi3)-mesh.Point(pi4); + auxvec2 = mesh.Point(pi1)-mesh.Point(pi4); + allowswap = allowswap && fabs(1.-(auxvec1*auxvec2)/(auxvec1.Length()*auxvec2.Length())) > 1e-4; + + if(!allowswap) + continue; + + // normal of new + nv1 = Cross (auxvec1, + auxvec2); + + auxvec1 = mesh.Point(pi4)-mesh.Point(pi3); + auxvec2 = mesh.Point(pi2)-mesh.Point(pi3); + allowswap = allowswap && fabs(1.-(auxvec1*auxvec2)/(auxvec1.Length()*auxvec2.Length())) > 1e-4; + + + if(!allowswap) + continue; + + nv2 = Cross (auxvec1, + auxvec2); + + + // normals of original + 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(); + + Vec<3> 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 + allowswap = 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; + } + + + static int timer = NgProfiler::CreateTimer ("Combineimprove 2D"); + NgProfiler::RegionTimer reg (timer); + + + + int i, j, k, l; + PointIndex pi; + SurfaceElementIndex sei; + + + ARRAY 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(); + + + PointIndex pi1, pi2; + MeshPoint p1, p2, pnew; + double bad1, bad2; + Vec<3> nv; + + int np = mesh.GetNP(); + //int nse = mesh.GetNSE(); + + TABLE elementsonnode(np); + ARRAY 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 fixed(np); + fixed = false; + + SegmentIndex si; + for (si = 0; si < mesh.GetNSeg(); si++) + { + INDEX_2 i2(mesh[si].p1, mesh[si].p2); + fixed[i2.I1()] = true; + fixed[i2.I2()] = true; + } + + for(i = 0; i,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; + + Vec<3> 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(NULL); + l=0; + while(mesh[elementsonnode[pi1][l]].IsDeleted() && lGetNP(); 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]] = true; + } + } + + /* + 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 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/libsrc/meshing/improve2.hpp b/libsrc/meshing/improve2.hpp new file mode 100644 index 00000000..4f25863d --- /dev/null +++ b/libsrc/meshing/improve2.hpp @@ -0,0 +1,102 @@ +#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 ImproveVolumeMesh (Mesh & mesh); + void ProjectBoundaryPoints(ARRAY & surfaceindex, + const ARRAY* > & from, ARRAY* > & dest); + + 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 Point<3> & p, + const PointGeomInfo & gi); + /// + virtual void ProjectPoint (INDEX /* surfind */, Point<3> & /* p */) const { }; + + /// project point, use gi as initial value, and compute new gi + virtual int ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const + { ProjectPoint (surfind, p); return CalcPointGeomInfo (surfind, gi, p); } + + /// + virtual void ProjectPoint2 (INDEX /* surfind */, INDEX /* surfind2 */, Point<3> & /* 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 Point<3> & /*p3*/) const + { gi.trignum = 1; return 1;}; + + virtual int CalcPointGeomInfo(int /* surfind */, PointGeomInfo& gi, const Point<3> & p3) const + { return CalcPointGeomInfo (gi, p3); } + + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & gi, Vec<3> & n) const; + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & 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/libsrc/meshing/improve2gen.cpp b/libsrc/meshing/improve2gen.cpp new file mode 100644 index 00000000..75ffc801 --- /dev/null +++ b/libsrc/meshing/improve2gen.cpp @@ -0,0 +1,455 @@ +#include + +#include "meshing.hpp" +#include + +namespace netgen +{ + + class ImprovementRule + { + public: + ARRAY oldels; + ARRAY newels; + ARRAY deledges; + ARRAY incelsonnode; + ARRAY 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; + + +// for (SurfaceElementIndex sei = 0; sei < ne; sei++) +// { +// const Element2d & el = mesh[sei]; +// (*testout) << "element " << sei << ": " < rules; + ARRAY elmap; + ARRAY elrot; + ARRAY pmap; + ARRAY 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 mapped(rules.Size()); + ARRAY 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 elonnode(np); + ARRAY nelonnode(np); + TABLE 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); + } + if(!el.IsDeleted()) + { + 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]; + bool inuse = false; + for (int l = 0; l < nbels[sei].Size(); l++) + if (nbels[sei][l] == nbel) + inuse = true; + if (!inuse) + 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 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 olddef) + continue; + + // calc metric badness + double bad1 = 0, bad2 = 0; + Vec<3> 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/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp new file mode 100644 index 00000000..c2db1e8b --- /dev/null +++ b/libsrc/meshing/improve3.cpp @@ -0,0 +1,2820 @@ +#include + +#include "meshing.hpp" + +#ifdef SOLIDGEOM +#include +#endif +#include + +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 elementsonnode(np); + ARRAY hasonepi, hasbothpi; + + ARRAY oneperr; + ARRAY elerrs (ne); + + PrintMessage (3, "CombineImprove"); + (*testout) << "Start CombineImprove" << "\n"; + + // mesh.CalcSurfacesOfNode (); + const 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 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 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 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 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; + 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 elementsonnode(np); + ARRAY hasbothpoints; + + BitArray origpoint(np), boundp(np); + origpoint.Set(); + + ARRAY elerrs(ne); + BitArray illegaltet(ne); + illegaltet.Clear(); + + const char * savetask = multithread.task; + multithread.task = "Split Improve"; + + + PrintMessage (3, "SplitImprove"); + (*testout) << "start SplitImprove" << "\n"; + + ARRAY locfaces; + + INDEX_2_HASHTABLE 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 (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, + const BitArray * working_elements) +{ + int j, k, l; + + ElementIndex ei; + SurfaceElementIndex sei; + + PointIndex pi1(0), pi2(0), pi3(0), pi4(0), pi5(0), pi6(0); + 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 elementsonnode(np); + + ARRAY hasbothpoints; + + PrintMessage (3, "SwapImprove "); + (*testout) << "\n" << "Start SwapImprove" << endl; + + const 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 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 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(working_elements && + ei < working_elements->Size() && + !working_elements->Test(ei)) + 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 & elemk = mesh[hasbothpoints[k]]; + bool has1 = 0; + for (l = 0; l < 4; l++) + if (elemk[l] == pi4) + has1 = 1; + if (has1) + { + for (l = 0; l < 4; l++) + if (elemk[l] != pi1 && elemk[l] != pi2 && elemk[l] != pi4) + pi5 = elemk[l]; + } + } + + if(pi5 == 0) + throw NgException("Illegal state observed in SwapImprove"); + + + + 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 suroundpts(nsuround); + ArrayMem 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; + } + } + } + + + bad1 = 0; + 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; +} + + + + + + +void MeshOptimize3d :: SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal, + const BitArray * working_elements, + const ARRAY< ARRAY* > * idmaps) +{ + ARRAY< ARRAY* > locidmaps; + const ARRAY< ARRAY* > * used_idmaps; + + if(idmaps) + used_idmaps = idmaps; + else + { + used_idmaps = &locidmaps; + + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + locidmaps.Append(new ARRAY); + mesh.GetIdentifications().GetMap(i,*locidmaps.Last(),true); + } + } + } + + ElementIndex ei; + SurfaceElementIndex sei; + + PointIndex pi1, pi2, pi3, pi4, pi5, pi6; + PointIndex pi1other, pi2other; + int cnt = 0; + + //double bad1, bad2, bad3, sbad; + double bad1, sbad; + double h; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + + int mattype, othermattype; + + + // contains at least all elements at node + TABLE elementsonnode(np); + TABLE surfaceelementsonnode(np); + TABLE surfaceindicesonnode(np); + + ARRAY hasbothpoints; + ARRAY hasbothpointsother; + + PrintMessage (3, "SwapImproveSurface "); + (*testout) << "\n" << "Start SwapImproveSurface" << endl; + + const char * savetask = multithread.task; + multithread.task = "Swap Improve Surface"; + + + + // find elements on node + for (ei = 0; ei < ne; ei++) + for (int j = 0; j < mesh[ei].GetNP(); j++) + elementsonnode.Add (mesh[ei][j], ei); + + for (sei = 0; sei < nse; sei++) + for(int j=0; j 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(working_elements && + ei < working_elements->Size() && + !working_elements->Test(ei)) + continue; + + if (mesh[ei].IsDeleted()) + continue; + + if ((goal == OPT_LEGAL) && + mesh.LegalTet (mesh[ei]) && + CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) + continue; + + const Element & elemi = mesh[ei]; + //Element elemi = mesh[ei]; + if (elemi.IsDeleted()) continue; + + + mattype = elemi.GetIndex(); + + bool swapped = false; + + for (int j = 0; !swapped && j < 6; j++) + { + // loop over edges + + + 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); + + + bool found = false; + for(int k=0; !found && kSize(); k++) + { + if(pi2 < (*used_idmaps)[k]->Size() + PointIndex::BASE) + { + pi1other = (*(*used_idmaps)[k])[pi1]; + pi2other = (*(*used_idmaps)[k])[pi2]; + found = (pi1other != 0 && pi2other != 0 && pi1other != pi1 && pi2other != pi2); + if(found) + idnum = k; + } + } + if(found) + periodic = true; + else + { + periodic = false; + pi1other = pi1; pi2other = pi2; + } + + + + if (!mesh.BoundaryEdge (pi1, pi2) || + mesh.IsSegment(pi1, pi2)) continue; + + othermattype = -1; + + + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + if (edgeused.Used(i2)) continue; + edgeused.Set (i2, 1); + if(periodic) + { + i2.I1() = pi1other; + i2.I2() = pi2other; + i2.Sort(); + edgeused.Set(i2,1); + } + + + hasbothpoints.SetSize (0); + hasbothpointsother.SetSize (0); + for (int k = 0; k < elementsonnode[pi1].Size(); k++) + { + bool has1 = false, has2 = false; + ElementIndex elnr = elementsonnode[pi1][k]; + const Element & elem = mesh[elnr]; + + if (elem.IsDeleted()) continue; + + for (int l = 0; l < elem.GetNP(); l++) + { + if (elem[l] == pi1) has1 = true; + if (elem[l] == pi2) has2 = true; + } + + if (has1 && has2) + { + if(othermattype == -1 && elem.GetIndex() != mattype) + othermattype = elem.GetIndex(); + + if(elem.GetIndex() == mattype) + { + // only once + for (int l = 0; l < hasbothpoints.Size(); l++) + if (hasbothpoints[l] == elnr) + has1 = 0; + + if (has1) + hasbothpoints.Append (elnr); + } + else if(elem.GetIndex() == othermattype) + { + // only once + for (int l = 0; l < hasbothpointsother.Size(); l++) + if (hasbothpointsother[l] == elnr) + has1 = 0; + + if (has1) + hasbothpointsother.Append (elnr); + } + else + { + cout << "problem with domain indices" << endl; + (*testout) << "problem: mattype = " << mattype << ", othermattype = " << othermattype + << " elem " << elem << " mt " << elem.GetIndex() << endl + << " pi1 " << pi1 << " pi2 " << pi2 << endl; + (*testout) << "hasbothpoints:" << endl; + for(int ii=0; ii < hasbothpoints.Size(); ii++) + (*testout) << mesh[hasbothpoints[ii]] << endl; + (*testout) << "hasbothpointsother:" << endl; + for(int ii=0; ii < hasbothpointsother.Size(); ii++) + (*testout) << mesh[hasbothpointsother[ii]] << endl; + } + } + } + + if(hasbothpointsother.Size() > 0 && periodic) + throw NgException("SwapImproveSurface: Assumption about interface/periodicity wrong!"); + + if(periodic) + { + for (int k = 0; k < elementsonnode[pi1other].Size(); k++) + { + bool has1 = false, has2 = false; + ElementIndex elnr = elementsonnode[pi1other][k]; + const Element & elem = mesh[elnr]; + + if (elem.IsDeleted()) continue; + + for (int l = 0; l < elem.GetNP(); l++) + { + if (elem[l] == pi1other) has1 = true; + if (elem[l] == pi2other) has2 = true; + } + + if (has1 && has2) + { + if(othermattype == -1) + othermattype = elem.GetIndex(); + + // only once + for (int l = 0; l < hasbothpointsother.Size(); l++) + if (hasbothpointsother[l] == elnr) + has1 = 0; + + if (has1) + hasbothpointsother.Append (elnr); + } + } + } + + + //for(k=0; k v1 = mesh[sp1]-mesh[pi1], + v2 = mesh[sp2]-mesh[pi1], + v3 = mesh[sp1]-mesh[pi2], + v4 = mesh[sp2]-mesh[pi2]; + double vol = 0.5*(Cross(v1,v2).Length() + Cross(v3,v4).Length()); + h = sqrt(vol); + h = 0; + + sbad = CalcTriangleBadness (mesh[pi1],mesh[pi2],mesh[sp1],0,0) + + CalcTriangleBadness (mesh[pi2],mesh[pi1],mesh[sp2],0,0); + + + + bool puretet = true; + for (int k = 0; puretet && k < hasbothpoints.Size(); k++) + if (mesh[hasbothpoints[k]].GetType () != TET) + puretet = false; + for (int k = 0; puretet && k < hasbothpointsother.Size(); k++) + if (mesh[hasbothpointsother[k]].GetType () != TET) + puretet = false; + if (!puretet) + continue; + + int nsuround = hasbothpoints.Size(); + int nsuroundother = hasbothpointsother.Size(); + + ARRAY < int > outerpoints(nsuround+1); + outerpoints[0] = sp1; + + for(int i=0; i 0) + (*testout) << mesh[hasbothpoints[ii]][jj] << " between " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][0] << " and " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][1] << endl; + } + (*testout) << "outerpoints: " << outerpoints << endl; + (*testout) << "sel1 " << mesh[sel1] << endl + << "sel2 " << mesh[sel2] << endl; + for(int ii=0; ii<3; ii++) + { + if(mesh.mlbetweennodes[mesh[sel1][ii]][0] > 0) + (*testout) << mesh[sel1][ii] << " between " + << mesh.mlbetweennodes[mesh[sel1][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel1][ii]][1] << endl; + if(mesh.mlbetweennodes[mesh[sel2][ii]][0] > 0) + (*testout) << mesh[sel2][ii] << " between " + << mesh.mlbetweennodes[mesh[sel2][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel2][ii]][1] << endl; + } + } + + + ARRAY < int > outerpointsother; + + if(nsuroundother > 0) + { + outerpointsother.SetSize(nsuroundother+1); + outerpointsother[0] = sp2other; + } + + for(int i=0; i 0 && outerpointsother[nsuroundother] != sp1other) + { + cerr << "OJE OJE OJE (other)" << endl; + (*testout) << "OJE OJE OJE (other)" << endl; + (*testout) << "pi1 " << pi1 << " pi2 " << pi2 << " sp1 " << sp1 << " sp2 " << sp2 << endl; + (*testout) << "hasbothpoints: " << endl; + for(int ii=0; ii < hasbothpoints.Size(); ii++) + { + (*testout) << mesh[hasbothpoints[ii]] << endl; + for(int jj=0; jj 0) + (*testout) << mesh[hasbothpoints[ii]][jj] << " between " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][0] << " and " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][1] << endl; + } + (*testout) << "outerpoints: " << outerpoints << endl; + (*testout) << "sel1 " << mesh[sel1] << endl + << "sel2 " << mesh[sel2] << endl; + for(int ii=0; ii<3; ii++) + { + if(mesh.mlbetweennodes[mesh[sel1][ii]][0] > 0) + (*testout) << mesh[sel1][ii] << " between " + << mesh.mlbetweennodes[mesh[sel1][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel1][ii]][1] << endl; + if(mesh.mlbetweennodes[mesh[sel2][ii]][0] > 0) + (*testout) << mesh[sel2][ii] << " between " + << mesh.mlbetweennodes[mesh[sel2][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel2][ii]][1] << endl; + } + + (*testout) << "pi1other " << pi1other << " pi2other " << pi2other << " sp1other " << sp1other << " sp2other " << sp2other << endl; + (*testout) << "hasbothpointsother: " << endl; + for(int ii=0; ii < hasbothpointsother.Size(); ii++) + { + (*testout) << mesh[hasbothpointsother[ii]] << endl; + for(int jj=0; jj 0) + (*testout) << mesh[hasbothpointsother[ii]][jj] << " between " + << mesh.mlbetweennodes[mesh[hasbothpointsother[ii]][jj]][0] << " and " + << mesh.mlbetweennodes[mesh[hasbothpointsother[ii]][jj]][1] << endl; + } + (*testout) << "outerpoints: " << outerpointsother << endl; + (*testout) << "sel1other " << mesh[sel1other] << endl + << "sel2other " << mesh[sel2other] << endl; + for(int ii=0; ii<3; ii++) + { + if(mesh.mlbetweennodes[mesh[sel1other][ii]][0] > 0) + (*testout) << mesh[sel1other][ii] << " between " + << mesh.mlbetweennodes[mesh[sel1other][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel1other][ii]][1] << endl; + if(mesh.mlbetweennodes[mesh[sel2other][ii]][0] > 0) + (*testout) << mesh[sel2other][ii] << " between " + << mesh.mlbetweennodes[mesh[sel2other][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel2other][ii]][1] << endl; + } + } + + bad1=0; + for(int i=0; i * > newelts(startpoints); + ARRAY < ARRAY < Element* > * > neweltsother(startpointsother); + + double minbad = 1e50, minbadother = 1e50, currbad; + int minpos = -1, minposother = -1; + + //(*testout) << "pi1 " << pi1 << " pi2 " << pi2 << " outerpoints " << outerpoints << endl; + + for(int i=0; i(2*(nsuround-1)); + + for(int jj=0; jjSize(); jj++) + wrongorientation = wrongorientation && WrongOrientation(mesh.Points(), *(*newelts[i])[jj]); + + currbad = 0; + + for(int jj=0; jjSize(); jj++) + { + if(wrongorientation) + Swap((*(*newelts[i])[jj])[2],(*(*newelts[i])[jj])[3]); + + + // not two new faces on same surface + ARRAY face_index; + for(int k = 0; kSize()); + + + + if(currbad < minbad) + { + minbad = currbad; + minpos = i; + } + + } + + if(startpointsother == 0) + minbadother = 0; + + for(int i=0; i(2*(nsuroundother)); + + for(int jj=0; jjSize(); jj++) + wrongorientation = wrongorientation && WrongOrientation(mesh.Points(), *(*neweltsother[i])[jj]); + + currbad = 0; + + for(int jj=0; jjSize(); jj++) + { + if(wrongorientation) + Swap((*(*neweltsother[i])[jj])[2],(*(*neweltsother[i])[jj])[3]); + + currbad += CalcBad(mesh.Points(),*(*neweltsother[i])[jj],h); + } + + //currbad /= double(neweltsother[i]->Size()); + + + + if(currbad < minbadother) + { + minbadother = currbad; + minposother = i; + } + + } + + //(*testout) << "minbad " << minbad << " bad1 " << bad1 << endl; + + + double sbadnew = CalcTriangleBadness (mesh[pi1],mesh[sp2],mesh[sp1],0,0) + + CalcTriangleBadness (mesh[pi2],mesh[sp1],mesh[sp2],0,0); + + + int denom = newelts[minpos]->Size(); + if(minposother >= 0) + denom += neweltsother[minposother]->Size(); + + + if((minbad+minbadother)/double(denom) < bad1 && + sbadnew < sbad) + { + cnt++; + + swapped = true; + + + int start1 = -1; + for(int l=0; l<3; l++) + if(mesh[sel1][l] == pi1) + start1 = l; + if(mesh[sel1][(start1+1)%3] == pi2) + { + mesh[sel1][0] = pi1; + mesh[sel1][1] = sp2; + mesh[sel1][2] = sp1; + mesh[sel2][0] = pi2; + mesh[sel2][1] = sp1; + mesh[sel2][2] = sp2; + } + else + { + mesh[sel1][0] = pi2; + mesh[sel1][1] = sp2; + mesh[sel1][2] = sp1; + mesh[sel2][0] = pi1; + mesh[sel2][1] = sp1; + mesh[sel2][2] = sp2; + } + //(*testout) << "changed surface element " << sel1 << " to " << mesh[sel1] << ", " << sel2 << " to " << mesh[sel2] << endl; + + for(int l=0; l<3; l++) + { + surfaceelementsonnode.Add(mesh[sel1][l],sel1); + surfaceelementsonnode.Add(mesh[sel2][l],sel2); + } + + + + if(periodic) + { + start1 = -1; + for(int l=0; l<3; l++) + if(mesh[sel1other][l] == pi1other) + start1 = l; + + + + //(*testout) << "changed surface elements " << mesh[sel1other] << " and " << mesh[sel2other] << endl; + if(mesh[sel1other][(start1+1)%3] == pi2other) + { + mesh[sel1other][0] = pi1other; + mesh[sel1other][1] = sp2other; + mesh[sel1other][2] = sp1other; + mesh[sel2other][0] = pi2other; + mesh[sel2other][1] = sp1other; + mesh[sel2other][2] = sp2other; + //(*testout) << " with rule 1" << endl; + } + else + { + mesh[sel1other][0] = pi2other; + mesh[sel1other][1] = sp2other; + mesh[sel1other][2] = sp1other; + mesh[sel2other][0] = pi1other; + mesh[sel2other][1] = sp1other; + mesh[sel2other][2] = sp2other; + //(*testout) << " with rule 2" << endl; + } + //(*testout) << " to " << mesh[sel1other] << " and " << mesh[sel2other] << endl; + + //(*testout) << " and surface element " << sel1other << " to " << mesh[sel1other] << ", " << sel2other << " to " << mesh[sel2other] << endl; + + for(int l=0; l<3; l++) + { + surfaceelementsonnode.Add(mesh[sel1other][l],sel1other); + surfaceelementsonnode.Add(mesh[sel2other][l],sel2other); + } + } + + + + + for(int i=0; i 0) + { + for(int i=0; iSize(); jj++) + delete (*newelts[i])[jj]; + delete newelts[i]; + } + + for(int i=0; iSize(); jj++) + delete (*neweltsother[i])[jj]; + delete neweltsother[i]; + } + + } + } + + PrintMessage (5, cnt, " swaps performed"); + + + for(int i=0; i 3 conversion +*/ + + + +void MeshOptimize3d :: SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal) +{ + int j, k, l; + ElementIndex ei, eli1, eli2, elnr; + SurfaceElementIndex sei; + PointIndex pi1(0), pi2(0), pi3(0), pi4(0), pi5(0); + + 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 elementsonnode(np); + TABLE 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 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 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/libsrc/meshing/improve3.hpp b/libsrc/meshing/improve3.hpp new file mode 100644 index 00000000..e82f37b0 --- /dev/null +++ b/libsrc/meshing/improve3.hpp @@ -0,0 +1,99 @@ +#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, + const BitArray * working_elements = NULL); + void SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, + const BitArray * working_elements = NULL, + const ARRAY< ARRAY* > * idmaps = NULL); + 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 MinFunctionSum : public MinFunction +{ +protected: + ARRAY functions; + +public: + + virtual double Func (const Vector & x) const; + virtual void Grad (const Vector & x, Vector & g) 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; + + void AddFunction(MinFunction & fun); + + const MinFunction & Function(int i) const; + MinFunction & Function(int i); +}; + + + +class PointFunction1 : public MinFunction +{ + Mesh::T_POINTS & points; + const ARRAY & faces; + double h; +public: + PointFunction1 (Mesh::T_POINTS & apoints, + const ARRAY & 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; +}; + + +class JacobianPointFunction : public MinFunction +{ +public: + Mesh::T_POINTS & points; + const Mesh::T_VOLELEMENTS & elements; + TABLE elementsonpoint; + PointIndex actpind; + + bool onplane; + Vec<3> nv; + +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; + + inline void SetNV(const Vec<3> & anv) {nv = anv; onplane = true;} + inline void UnSetNV(void) {onplane = false;} +}; + + + +#endif diff --git a/libsrc/meshing/localh.cpp b/libsrc/meshing/localh.cpp new file mode 100644 index 00000000..1a9f3d34 --- /dev/null +++ b/libsrc/meshing/localh.cpp @@ -0,0 +1,680 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + +GradingBox :: GradingBox (const double * ax1, const double * ax2) +{ + h2 = 0.5 * (ax2[0] - ax1[0]); + for (int 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 (int 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; + + 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 faceinds(nf); + ARRAY 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 & faceboxes, + ARRAY & 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 faceused; + static ARRAY faceused2; + static ARRAY 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 & 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 & 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/libsrc/meshing/localh.hpp b/libsrc/meshing/localh.hpp new file mode 100644 index 00000000..7531bc7f --- /dev/null +++ b/libsrc/meshing/localh.hpp @@ -0,0 +1,145 @@ +#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 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 & points); + + /// get points in outer closure + void GetOuterPoints (ARRAY & 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 & faceboxes, + ARRAY & finds, int nfinbox); + + + /// + void SetInnerBoxesRec (GradingBox * box); + + /// + void ClearFlagsRec (GradingBox * box); + + /// + void ConvexifyRec (GradingBox * box); +}; + + +#endif diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp new file mode 100644 index 00000000..13926237 --- /dev/null +++ b/libsrc/meshing/meshclass.cpp @@ -0,0 +1,5506 @@ +#include +#include "meshing.hpp" + +#ifdef PARALLEL +#include +#endif + +namespace netgen +{ + + Mesh :: Mesh () + { + volelements.SetName ("vol elements"); + surfelements.SetName ("surf elements"); + points.SetName ("meshpoints"); + + boundaryedges = NULL; + surfelementht = NULL; + segmentht = NULL; + + lochfunc = NULL; + mglevels = 1; + elementsearchtree = NULL; + elementsearchtreets = NextTimeStamp(); + majortimestamp = timestamp = NextTimeStamp(); + hglob = 1e10; + hmin = 0; + numvertices = -1; + dimension = 3; + + topology = new MeshTopology (*this); + curvedelems = new CurvedElements (*this); + clusters = new AnisotropicClusters (*this); + ident = new Identifications (*this); + + hpelements = NULL; + coarsemesh = NULL; + + ps_startelement = 0; + + geomtype = NO_GEOM; + + bcnames.SetSize(0); +#ifdef PARALLEL + paralleltop = new ParallelMeshTopology (*this); +#endif + } + + + Mesh :: ~Mesh() + { + delete lochfunc; + delete boundaryedges; + delete surfelementht; + delete segmentht; + delete curvedelems; + delete clusters; + delete topology; + delete ident; + delete elementsearchtree; + + delete coarsemesh; + delete hpelements; + + for (int i = 0; i < materials.Size(); i++) + delete [] materials[i]; + + for(int i = 0; i < userdata_int.Size(); i++) + delete userdata_int[i]; + for(int i = 0; i < userdata_double.Size(); i++) + delete userdata_double[i]; + + for (int i = 0; i < bcnames.Size(); i++ ) + if ( bcnames[i] ) delete bcnames[i]; + +#ifdef PARALLEL + delete paralleltop; +#endif + } + + + 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; + + bcnames.SetSize( mesh2.bcnames.Size() ); + for ( int i = 0; i < mesh2.bcnames.Size(); i++ ) + if ( mesh2.bcnames[i] ) bcnames[i] = new string ( *mesh2.bcnames[i] ); + else bcnames[i] = 0; + + return *this; + } + + + void Mesh :: DeleteMesh() + { + points.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); + + delete ident; + ident = new Identifications (*this); + delete topology; + topology = new MeshTopology (*this); + delete curvedelems; + curvedelems = new CurvedElements (*this); + delete clusters; + clusters = new AnisotropicClusters (*this); + + for ( int i = 0; i < bcnames.Size(); i++ ) + if ( bcnames[i] ) delete bcnames[i]; + +#ifdef PARALLEL + delete paralleltop; + paralleltop = new ParallelMeshTopology (*this); +#endif + + + 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) ); + +#ifdef PARALLEL + points.Last().SetGhost(0); +#endif + + lock.UnLock(); + + return pi; + } + + PointIndex Mesh :: AddPoint (const Point3d & p, int layer, POINTTYPE type) + { + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.Size() + PointIndex::BASE; + points.Append ( MeshPoint (p, layer, type) ); + +#ifdef PARALLEL + points.Last().SetGhost(0); +#endif + + lock.UnLock(); + + return pi; + } + + +#ifdef PARALLEL + PointIndex Mesh :: AddPoint (const Point3d & p, bool isghost, int layer) + { + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.Size() + PointIndex::BASE; + points.Append ( MeshPoint (p, layer, INNERPOINT) ); + + points.Last().SetGhost(isghost); + + lock.UnLock(); + + return pi; + } + + PointIndex Mesh :: AddPoint (const Point3d & p, bool isghost, int layer, POINTTYPE type) + { + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.Size() + PointIndex::BASE; + points.Append ( MeshPoint (p, layer, type) ); + + points.Last().SetGhost(isghost); + + lock.UnLock(); + + return pi; + } + +#endif + + + + 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); + + if (el.index > facedecoding.Size()) + cerr << "has no facedecoding: fd.size = " << facedecoding.Size() << ", ind = " << el.index << endl; + + surfelements.Last().next = facedecoding[el.index-1].firstelement; + facedecoding[el.index-1].firstelement = si; + +#ifdef PARALLEL + surfelements.Last().SetGhost ( el.IsGhost() ); +#endif + + 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; + +#ifdef PARALLEL + volelements.Last().SetGhost ( el.IsGhost() ); +#endif + + // while (volelements.Size() > eltyps.Size()) + // eltyps.Append (FREEELEMENT); + + timestamp = NextTimeStamp(); + + lock.UnLock(); + return ve; + } + + + + + + + void Mesh :: Save (const string & filename) const + { + + ofstream outfile(filename.c_str()); + + Save(outfile); + } + + + + void Mesh :: Save (ostream & outfile) const + { + int i, j; + + double scale = 1; // globflags.GetNumFlag ("scale", 1); + int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); + int invertsurf = 0; // globflags.GetDefineFlag ("invertsurfacemesh"); + + + + outfile << "mesh3d" << "\n"; + + outfile << "dimension\n" << GetDimension() << "\n"; + + outfile << "geomtype\n" << int(geomtype) << "\n"; + + + outfile << "\n"; + outfile << "# surfnr bcnr domin domout np p1 p2 p3" + << "\n"; + + + switch (geomtype) + { + case GEOM_STL: + outfile << "surfaceelementsgi" << "\n"; + break; + case GEOM_OCC: case GEOM_ACIS: + outfile << "surfaceelementsuv" << "\n"; + break; + default: + 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]; + } + + + switch (geomtype) + { + case GEOM_STL: + for (j = 1; j <= sel.GetNP(); j++) + { + outfile.width(7); + outfile << " " << sel.GeomInfoPi(j).trignum; + } + break; + case GEOM_OCC: case GEOM_ACIS: + for (j = 1; j <= sel.GetNP(); j++) + { + outfile.width(7); + outfile << " " << sel.GeomInfoPi(j).u; + outfile << " " << sel.GeomInfoPi(j).v; + } + break; + default: + outfile << "\n"; + } + + + 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++) + for (int k = 0; k < el.GetNP()-1; k++) + if (el[k] > el[k+1]) swap (el[k], el[k+1]); + */ + + 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 << "# surfid 0 p1 p2 trignum1 trignum2 domin/surfnr1 domout/surfnr2 ednr1 dist1 ednr2 dist2 \n"; + outfile << "edgesegmentsgi2" << "\n"; + outfile << GetNSeg() << "\n"; + + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + outfile.width(8); + outfile << seg.si; // 2D: bc number, 3D: wievielte Kante + 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; // stl dreiecke + outfile << " "; + outfile.width(8); + outfile << seg.geominfo[1].trignum; // << endl; // stl dreieck + + if (dimension == 3) + { + outfile << " "; + outfile.width(8); + outfile << seg.surfnr1+1; + outfile << " "; + outfile.width(8); + outfile << seg.surfnr2+1; + } + else + { + outfile << " "; + outfile.width(8); + outfile << seg.domin; + outfile << " "; + outfile.width(8); + outfile << seg.domout; + } + + outfile << " "; + outfile.width(8); + outfile << seg.edgenr; + outfile << " "; + outfile.width(12); + outfile.precision(16); + outfile << seg.epgeominfo[0].dist; // splineparameter (2D) + outfile << " "; + outfile.width(8); + outfile.precision(16); + outfile << seg.epgeominfo[1].edgenr; // geometry dependent + 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](0)/scale << " "; + outfile.width(22); + outfile << (*this)[pi](1)/scale << " "; + outfile.width(22); + outfile << (*this)[pi](2)/scale << "\n"; + } + + if (ident -> GetMaxNr() > 0) + { + outfile << "identifications\n"; + ARRAY 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"; + } + } + + outfile << "identificationtypes\n"; + outfile << ident -> GetMaxNr() << "\n"; + for (i = 1; i <= ident -> GetMaxNr(); i++) + { + int type = ident -> GetType(i); + outfile << " " << type; + } + outfile << "\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 cntbcnames = 0; + for ( int ii = 0; ii < bcnames.Size(); ii++ ) + if ( bcnames[ii] ) cntbcnames++; + + if ( cntbcnames ) + { + outfile << "\n\nbcnames" << endl << bcnames.Size() << endl; + for ( i = 0; i < bcnames.Size(); i++ ) + outfile << i+1 << "\t" << GetBCName(i) << endl; + outfile << endl << endl; + } + + /* + if ( GetDimension() == 2 ) + { + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + if ( ! bcprops.Contains(seg.si) && seg.GetBCName() != "" ) + { + bcprops.Append(seg.si); + cntbcnames++; + } + } + } + else + { + for (sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + int bcp = GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + string name = GetFaceDescriptor((*this)[sei].GetIndex ()).BCName(); + if ( !bcprops.Contains(bcp) && + name != "" ) + { + bcprops.Append(bcp); + cntbcnames++; + } + } + } + } + + bcprops.SetSize(0); + if ( cntbcnames ) + { + outfile << "\nbcnames" << endl << cntbcnames << endl; + if ( GetDimension() == 2 ) + { + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + if ( ! bcprops.Contains(seg.si) && seg.GetBCName() != "" ) + { + bcprops.Append(seg.si); + outfile << seg.si << "\t" << seg.GetBCName() << endl; + } + } + } + else + { + for (sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + int bcp = GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + string name = GetFaceDescriptor((*this)[sei].GetIndex ()).BCName(); + if ( !bcprops.Contains(bcp) && + name != "" ) + { + bcprops.Append(bcp); + outfile << bcp << "\t" << name << endl; + } + } + } + } + outfile << endl << endl; + } + */ + + int cnt_sing = 0; + for (PointIndex pi = PointIndex::BASE; pi < GetNP()+PointIndex::BASE; pi++) + if ((*this)[pi].Singularity()>=1.) 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].Singularity()>=1.) + outfile << int(pi) << "\t" << (*this)[pi].Singularity() << 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) << "\t" << segments[si].singedge_left << 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) << "\t" << segments[si].singedge_right << 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) << "\t" << + GetFaceDescriptor ((*this)[sei].GetIndex()).domin_singular << 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) << "\t" + << GetFaceDescriptor ((*this)[sei].GetIndex()).domout_singular << endl; + } + + + } + + + + void Mesh :: Load (const string & filename) + { + + ifstream infile(filename.c_str()); + if (!infile.good()) + throw NgException ("mesh file not found"); + + Load(infile); + } + + + + + void Mesh :: Load (istream & infile) + { + + 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"); + + + facedecoding.SetSize(0); + + bool endmesh = false; + + while (infile.good() && !endmesh) + { + infile >> str; + + if (strcmp (str, "dimension") == 0) + { + infile >> dimension; + } + + if (strcmp (str, "geomtype") == 0) + { + int hi; + infile >> hi; + geomtype = GEOM_TYPE(hi); + } + + + if (strcmp (str, "surfaceelements") == 0 || strcmp (str, "surfaceelementsgi")==0 || strcmp (str, "surfaceelementsuv") == 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 (strcmp (str, "surfaceelementsgi") == 0) + for (j = 1; j <= nep; j++) + infile >> tri.GeomInfoPi(j).trignum; + + if (strcmp (str, "surfaceelementsuv") == 0) + for (j = 1; j <= nep; j++) + infile >> tri.GeomInfoPi(j).u >> tri.GeomInfoPi(j).v; + + 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) + { + int a; + infile >> a; + n=a; + + 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].dist + >> seg.epgeominfo[1].edgenr + >> seg.epgeominfo[1].dist; + + seg.epgeominfo[0].edgenr = seg.epgeominfo[1].edgenr; + + seg.domin = seg.surfnr1; + seg.domout = seg.surfnr2; + + 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, "identificationtypes") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + int type; + infile >> type; + ident -> SetType(i,Identifications::ID_TYPE(type)); + } + } + + 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, "bcnames" ) == 0 ) + { + infile >> n; + ARRAY bcnrs(n); + + SetNBCNames(n); + for ( i = 1; i <= n; i++ ) + { + string nextbcname; + infile >> bcnrs[i-1] >> nextbcname; + bcnames[bcnrs[i-1]-1] = new string(nextbcname); + } + + if ( GetDimension() == 2 ) + { + for (i = 1; i <= GetNSeg(); i++) + { + Segment & seg = LineSegment (i); + if ( seg.si <= n ) + seg.SetBCName (bcnames[seg.si-1]); + else + seg.SetBCName(0); + } + } + else + { + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + int bcp = GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + if ( bcp <= n ) + GetFaceDescriptor((*this)[sei].GetIndex ()).SetBCName(bcnames[bcp-1]); + else + GetFaceDescriptor((*this)[sei].GetIndex ()).SetBCName(0); + + } + } + + } + + + } + + if (strcmp (str, "singular_points") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + PointIndex pi; + double s; + infile >> pi; + infile >> s; + (*this)[pi].Singularity (s); + } + } + + if (strcmp (str, "singular_edge_left") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SegmentIndex si; + double s; + infile >> si; + infile >> s; + (*this)[si].singedge_left = s; + } + } + if (strcmp (str, "singular_edge_right") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SegmentIndex si; + double s; + infile >> si; + infile >> s; + (*this)[si].singedge_right = s; + } + } + + if (strcmp (str, "singular_face_inside") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SurfaceElementIndex sei; + double s; + infile >> sei; + infile >> s; + GetFaceDescriptor((*this)[sei].GetIndex()).domin_singular = s; + } + } + + if (strcmp (str, "singular_face_outside") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SurfaceElementIndex sei; + double s; + infile >> sei; + infile >> s; + GetFaceDescriptor((*this)[sei].GetIndex()).domout_singular = s; + } + } + + if (strcmp (str, "endmesh") == 0) + endmesh = true; + + + + strcpy (str, ""); + } + + CalcSurfacesOfNode (); + // BuildConnectedNodes (); + topology -> Update(); + clusters -> Update(); + + SetNextMajorTimeStamp(); + // PrintMemInfo (cout); + + +#ifdef PARALLEL + if ( ntasks > 1 ) + { + // for parallel processing + Distribute (); + return; + } +#endif + + } + + + + + + void Mesh :: Merge (const string & filename, const int surfindex_offset) + { + ifstream infile(filename.c_str()); + if (!infile.good()) + throw NgException ("mesh file not found"); + + Merge(infile,surfindex_offset); + + } + + + + void Mesh :: Merge (istream & infile, const int surfindex_offset) + { + char str[100]; + int i, n; + + + int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); + + int oldnp = GetNP(); + int oldne = GetNSeg(); + int oldnd = GetNDomains(); + + for(SurfaceElementIndex si = 0; si < GetNSE(); si++) + for(int j=1; j<=(*this)[si].GetNP(); j++) (*this)[si].GeomInfoPi(j).trignum = -1; + + int max_surfnr = 0; + for (i = 1; i <= GetNFD(); i++) + max_surfnr = max2 (max_surfnr, GetFaceDescriptor(i).SurfNr()); + max_surfnr++; + + if(max_surfnr < surfindex_offset) max_surfnr = surfindex_offset; + + + bool endmesh = false; + + while (infile.good() && !endmesh) + { + infile >> str; + + if (strcmp (str, "surfaceelementsgi") == 0 || 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--; + + if(domin > 0) domin += oldnd; + if(domout > 0) domout += oldnd; + surfnr += max_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)); + if(GetDimension() == 2) bcp++; + 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; + } + + + if (strcmp (str, "surfaceelementsgi") == 0) + for (j = 1; j <= nep; j++) + { + infile >> tri.GeomInfoPi(j).trignum; + tri.GeomInfoPi(j).trignum = -1; + } + + AddSurfaceElement (tri); + } + } + + + 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; + seg.p1 = seg.p1 + oldnp; + seg.p2 = seg.p2 + oldnp; + 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; + seg.p1 = seg.p1 + oldnp; + seg.p2 = seg.p2 + oldnp; + 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].dist + >> seg.epgeominfo[1].edgenr + >> seg.epgeominfo[1].dist; + seg.epgeominfo[0].edgenr = seg.epgeominfo[1].edgenr; + + seg.surfnr1--; + seg.surfnr2--; + + if(seg.surfnr1 >= 0) seg.surfnr1 = seg.surfnr1 + max_surfnr; + if(seg.surfnr2 >= 0) seg.surfnr2 = seg.surfnr2 + max_surfnr; + seg.p1 = seg.p1 +oldnp; + seg.p2 = seg.p2 +oldnp; + seg.edgenr = seg.edgenr + oldne; + seg.epgeominfo[1].edgenr = seg.epgeominfo[1].edgenr + oldne; + + AddSegment (seg); + } + } + + 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+oldnd); + infile >> nep; + el.SetNP(nep); + + for (int j = 0; j < nep; j++) + { + infile >> (int&)(el[j]); + el[j] = el[j]+oldnp; + } + + if (inverttets) + el.Invert(); + + AddVolumeElement (el); + } + } + + + 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); + } + } + + + if (strcmp (str, "endmesh") == 0) + { + endmesh = true; + } + + + if (strcmp (str, "materials") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + int nr; + string mat; + infile >> nr >> mat; + SetMaterial (nr+oldnd, mat.c_str()); + } + } + + + 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 :: SetAllocSize(int nnodes, int nsegs, int nsel, int nel) + { + points.SetAllocSize(nnodes); + segments.SetAllocSize(nsegs); + surfelements.SetAllocSize(nsel); + volelements.SetAllocSize(nel); + } + + + void Mesh :: BuildBoundaryEdges(void) + { + delete boundaryedges; + + boundaryedges = new INDEX_2_CLOSED_HASHTABLE + (3 * (GetNSE() + GetNOpenElements()) + GetNSeg() + 1); + + + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + + int si = sel.GetIndex(); + + for (int j = 0; j < sel.GetNP(); j++) + { + 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 (int i = 0; i < openelements.Size(); i++) + { + const Element2d & sel = openelements[i]; + for (int 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); + } + } + + for (int 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 :: CalcSurfacesOfNode () + { + int i, j, k; + SurfaceElementIndex sei; + + surfacesonnode.SetSize (GetNP()); + + delete boundaryedges; + boundaryedges = NULL; + + delete surfelementht; + delete segmentht; + + /* + surfelementht = new INDEX_3_HASHTABLE (GetNSE()/4 + 1); + segmentht = new INDEX_2_HASHTABLE (GetNSeg() + 1); + */ + + surfelementht = new INDEX_3_CLOSED_HASHTABLE (3*GetNSE() + 1); + segmentht = new INDEX_2_CLOSED_HASHTABLE (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); + + } + } + /* + 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, sei); // war das wichtig ??? sel.GetIndex()); + } + + int np = GetNP(); + + if (dimension == 3) + { + for (PointIndex pi = PointIndex::BASE; + pi < np+PointIndex::BASE; pi++) + points[pi].SetType (INNERPOINT); + + if (GetNFD() == 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) + { + static int timer = NgProfiler::CreateTimer ("Mesh::FindOpenElements"); + static int timera = NgProfiler::CreateTimer ("Mesh::FindOpenElements A"); + static int timerb = NgProfiler::CreateTimer ("Mesh::FindOpenElements B"); + static int timerc = NgProfiler::CreateTimer ("Mesh::FindOpenElements C"); + static int timerd = NgProfiler::CreateTimer ("Mesh::FindOpenElements D"); + static int timere = NgProfiler::CreateTimer ("Mesh::FindOpenElements E"); + + NgProfiler::RegionTimer reg (timer); + + int np = GetNP(); + int ne = GetNE(); + int nse = GetNSE(); + + ARRAY numonpoint(np); + + numonpoint = 0; + + NgProfiler::StartTimer (timera); + for (ElementIndex 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 (int j = 0; j < el.GetNP(); j++) + numonpoint[el[j]]++; + } + } + + TABLE elsonpoint(numonpoint); + for (ElementIndex 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 (int j = 0; j < el.GetNP(); j++) + elsonpoint.Add (el[j], ei); + } + } + NgProfiler::StopTimer (timera); + + + + + NgProfiler::StartTimer (timerb); + + + + ARRAY hasface(GetNFD()); + + int i; + for (i = 1; i <= GetNFD(); i++) + { + int domin = GetFaceDescriptor(i).DomainIn(); + int domout = GetFaceDescriptor(i).DomainOut(); + hasface[i] = + dom == 0 && (domin != 0 || domout != 0) || + dom != 0 && (domin == dom || domout == dom); + } + + numonpoint = 0; + for (SurfaceElementIndex sii = 0; sii < nse; sii++) + { + int ind = surfelements[sii].GetIndex(); + /* + if ( + GetFaceDescriptor(ind).DomainIn() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) + || + GetFaceDescriptor(ind).DomainOut() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) + ) + */ + if (hasface[ind]) + { + /* + Element2d hel = surfelements[i]; + hel.NormalizeNumbering(); + numonpoint[hel[0]]++; + */ + const Element2d & hel = surfelements[sii]; + int mini = 0; + for (int j = 1; j < hel.GetNP(); j++) + if (hel[j] < hel[mini]) + mini = j; + numonpoint[hel[mini]]++; + } + } + + TABLE selsonpoint(numonpoint); + for (SurfaceElementIndex sii = 0; sii < nse; sii++) + { + int ind = surfelements[sii].GetIndex(); + + /* + if ( + GetFaceDescriptor(ind).DomainIn() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) + || + GetFaceDescriptor(ind).DomainOut() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) + ) + */ + if (hasface[ind]) + { + /* + Element2d hel = surfelements[i]; + hel.NormalizeNumbering(); + selsonpoint.Add (hel[0], i); + */ + const Element2d & hel = surfelements[sii]; + int mini = 0; + for (int j = 1; j < hel.GetNP(); j++) + if (hel[j] < hel[mini]) + mini = j; + selsonpoint.Add (hel[mini], sii); + } + } + + + NgProfiler::StopTimer (timerb); + + int ii, j, k, l; + PointIndex pi; + SurfaceElementIndex sei; + Element2d hel; + + NgProfiler::RegionTimer regc (timerc); + + + INDEX_3_CLOSED_HASHTABLE 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 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 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 = 0; 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); + } + } + } + + int cnt3 = 0; + for (i = 0; i < openelements.Size(); i++) + if (openelements[i].GetNP() == 3) + cnt3++; + + int cnt4 = openelements.Size() - cnt3; + + + MyStr treequad; + if (cnt4) + treequad = MyStr(" (") + MyStr(cnt3) + MyStr (" + ") + + MyStr(cnt4) + MyStr(")"); + + PrintMessage (5, openelements.Size(), treequad, " open elements"); + + BuildBoundaryEdges(); + + + NgProfiler::RegionTimer regd (timerd); + + 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); + } + } + + + NgProfiler::RegionTimer rege (timere); + + /* + 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); + } + */ + } + + bool Mesh :: HasOpenQuads () const + { + int no = GetNOpenElements(); + for (int i = 0; i < no; i++) + if (openelements[i].GetNP() == 4) + return true; + return false; + } + + + + + + 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 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(); + } + } + + for (int i = 0; i < facedecoding.Size(); i++) + facedecoding[i].firstelement = -1; + for (int i = surfelements.Size()-1; i >= 0; i--) + { + int ind = surfelements[i].GetIndex(); + surfelements[i].next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = i; + } + + + timestamp = NextTimeStamp(); + // Compress(); + } + + + + + + void Mesh :: FreeOpenElementsEnvironment (int layers) + { + int i, j, k; + PointIndex pi; + const int large = 9999; + ARRAY dist(GetNP()); + + dist = large; + + for (int i = 1; i <= GetNOpenElements(); i++) + { + const Element2d & face = OpenElement(i); + for (j = 0; j < face.GetNP(); j++) + dist[face[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++) + { + 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]]; + + el.flags.fixed = elmin > layers; + // 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) + { + if(hloc < hmin) + hloc = hmin; + + //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) + { + if(hloc < hmin) + hloc = hmin; + + // 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 :: SetMinimalH (double h) + { + hmin = h; + } + + + 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 & 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 edges(3 * GetNP() + 2); + INDEX_2_HASHTABLE 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 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 op2np(GetNP()); + ARRAY hpoints; + BitArrayChar 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 doesnt 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]]; + + for (int i = 0; i < facedecoding.Size(); i++) + facedecoding[i].firstelement = -1; + for (int i = surfelements.Size()-1; i >= 0; i--) + { + int ind = surfelements[i].GetIndex(); + surfelements[i].next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = 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 edges(nf+2); + INDEX_2 i2, i2s, edge; + int err = 0; + + for (int i = 1; i <= nf; i++) + { + const Element2d & sel = OpenElement(i); + + for (int 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); + } + } + + for (int i = 1; i <= edges.GetNBags(); i++) + for (int 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"); + + (*testout) << "Edge " << i2 << " multiple times in surface mesh" << endl; + i2s = i2; + i2s.Sort(); + for (int k = 1; k <= nf; k++) + { + const Element2d & sel = OpenElement(k); + for (int l = 1; l <= sel.GetNP(); l++) + { + edge.I1() = sel.PNumMod(l); + edge.I2() = sel.PNumMod(l+1); + edge.Sort(); + + if (edge == i2s) + (*testout) << "edge of element " << sel << endl; + } + } + + + err = 2; + } + } + + return err; + } + + + + int Mesh :: CheckOverlappingBoundary () + { + int i, j, k; + + Point3d pmin, pmax; + GetBox (pmin, pmax); + Box3dTree setree(pmin, pmax); + ARRAY 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 netgen::Point<3> *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; + + (*testout) << "Face1 = " << GetFaceDescriptor(tri.GetIndex()) << endl; + (*testout) << "Face1 = " << GetFaceDescriptor(tri2.GetIndex()) << 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 + { + // static int timer1 = NgProfiler::CreateTimer ("Legaltet2"); + + + // Test, whether 4 points have a common surface plus + // at least 4 edges at the boundary + + if(!boundaryedges) + const_cast(this)->BuildBoundaryEdges(); + + + // non-tets are always legal + if (el.GetType() != TET) + { + el.SetLegal (1); + return 1; + } + + POINTTYPE pointtype[4]; + for(int i = 0; i < 4; i++) + pointtype[i] = (*this)[el[i]].Type(); + + + + // element has at least 2 inner points ---> legal + int cnti = 0; + for (int j = 0; j < 4; j++) + if ( pointtype[j] == INNERPOINT) + { + cnti++; + if (cnti >= 2) + { + el.SetLegal (1); + return 1; + } + } + + + + // which faces are boundary faces ? + int bface[4]; + for (int i = 0; i < 4; i++) + { + bface[i] = surfelementht->Used (INDEX_3::Sort(el[gftetfacesa[i][0]], + el[gftetfacesa[i][1]], + el[gftetfacesa[i][2]])); + } + + int bedge[4][4]; + int segedge[4][4]; + static const int pi3map[4][4] = { { -1, 2, 1, 1 }, + { 2, -1, 0, 0 }, + { 1, 0, -1, 0 }, + { 1, 0, 0, -1 } }; + + static const int pi4map[4][4] = { { -1, 3, 3, 2 }, + { 3, -1, 3, 2 }, + { 3, 3, -1, 1 }, + { 2, 2, 1, -1 } }; + + + for (int i = 0; i < 4; i++) + for (int j = 0; j < i; j++) + { + bool sege = false, be = false; + + int pos = boundaryedges -> Position(INDEX_2::Sort(el[i], el[j])); + if (pos) + { + be = true; + if (boundaryedges -> GetData(pos) == 2) + sege = true; + } + + segedge[j][i] = segedge[i][j] = sege; + bedge[j][i] = bedge[i][j] = be; + } + + // two boundary faces and no edge is illegal + for (int i = 0; i < 3; i++) + for (int j = i+1; j < 4; j++) + { + if (bface[i] && bface[j]) + if (!segedge[pi3map[i][j]][pi4map[i][j]]) + { + // 2 boundary faces withoud edge in between + el.SetLegal (0); + return 0; + } + } + + // three boundary edges meeting in a Surface point + for (int i = 0; i < 4; i++) + { + bool alledges = 1; + if ( pointtype[i] == SURFACEPOINT) + { + bool alledges = 1; + for (int j = 0; j < 4; j++) + if (j != i && !bedge[i][j]) + { + alledges = 0; + break; + } + if (alledges) + { + // cout << "tet illegal due to unmarked node" << endl; + el.SetLegal (0); + return 0; + } + } + } + + + + for (int fnr = 0; fnr < 4; fnr++) + if (!bface[fnr]) + for (int i = 0; i < 4; i++) + if (i != fnr) + { + int pi1 = pi3map[i][fnr]; + int pi2 = pi4map[i][fnr]; + + if ( pointtype[i] == SURFACEPOINT) + { + // two connected edges on surface, but no face + if (bedge[i][pi1] && bedge[i][pi2]) + { + el.SetLegal (0); + return 0; + } + } + + if ( pointtype[i] == EDGEPOINT) + { + // connected surface edge and edge edge, but no face + if (bedge[i][pi1] && segedge[i][pi2] || + bedge[i][pi2] && segedge[i][pi1]) + { + el.SetLegal (0); + return 0; + } + } + + } + + + el.SetLegal (1); + 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 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() + { + PrintMessage (1, "Split To Tets"); + 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(TET); + 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) cout << "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, 6, 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 + + // cout << "pyramid: " << el << endl; + + 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[0], el[2]) < min2 (el[1], el[3])) + min2pi = &ntets[0][0]; + else + min2pi = &ntets[1][0]; + + bool firsttet = 1; + for (int j = 0; j < 2; j++) + { + Element nel(TET); + for (int k = 0; k < 4; k++) + nel[k] = el[min2pi[4*j + k]-1]; + nel.SetIndex (el.GetIndex()); + + // cout << "pyramid-tet: " << nel << endl; + + bool legal = 1; + for (int k = 0; k < 3; k++) + for (int l = k+1; l < 4; l++) + if (nel[k] == nel[l]) + legal = 0; + + if (legal) + { + (*testout) << nel << " "; + if (firsttet) + VolumeElement(i) = nel; + else + AddVolumeElement(nel); + + firsttet = 0; + } + } + if (firsttet) cout << "no legal"; + (*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)); + } + + + + UpdateTopology(); + 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(); + } + + + + bool Mesh :: PointContainedIn2DElement(const Point3d & p, + double lami[3], + const int element, + bool consider3D) const + { + static Vec3d col1, col2, col3; + static Vec3d rhs, sol; + const double eps = 1e-6; + + static ARRAY loctrigs; + + + //SZ + if(SurfaceElement(element).GetType()==QUAD) + { + const Element2d & el = SurfaceElement(element); + + 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())-c.X()*(p.Y()-a.Y()))/ + (b.X()*c.Y() -b.Y()*c.X()); + lami[1]=(-b.Y()*(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.) return false; + 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 true; + } + + 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) + { + if(consider3D) + { + Vec3d n = Cross(b,c); + lami[2] = 0; + for(int i=1; i<=3; i++) + lami[2] +=(p.X(i)-a.X(i)-lami[0]*b.X(i)-lami[1]*c.X(i)) * n.X(i); + if(lami[2] >= -eps && lami[2] <= eps) + return true; + } + else + return true; + } + + return false; + + } + else + { + // SurfaceElement(element).GetTets (loctets); + loctrigs.SetSize(1); + loctrigs.Elem(1) = SurfaceElement(element); + + + + for (int 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 = Cross(col1,col2); + //col3 = Vec3d(0, 0, 1); + rhs = p - p1; + + int retval = SolveLinearSystem (col1, col2, col3, rhs, sol); + + //(*testout) << "retval " << retval << endl; + + //(*testout) << "col1 " << col1 << " col2 " << col2 << " col3 " << col3 << " rhs " << rhs << endl; + //(*testout) << "sol " << sol << endl; + + if (sol.X() >= -eps && sol.Y() >= -eps && + sol.X() + sol.Y() <= 1+eps) + { + if(!consider3D || (sol.Z() >= -eps && sol.Z() <= eps)) + { + lami[0] = sol.X(); + lami[1] = sol.Y(); + lami[2] = sol.Z(); + + return true; + } + } + } + } + + return false; + + } + + + + + bool Mesh :: PointContainedIn3DElement(const Point3d & p, + double lami[3], + const int element) const + { + //bool oldresult = PointContainedIn3DElementOld(p,lami,element); + //(*testout) << "old result: " << oldresult + // << " lam " << lami[0] << " " << lami[1] << " " << lami[2] << endl; + + //if(!curvedelems->IsElementCurved(element-1)) + // return PointContainedIn3DElementOld(p,lami,element); + + + const double eps = 1.e-4; + const Element & el = VolumeElement(element); + + netgen::Point<3> lam; + + if (el.GetType() == TET) + { + lam = 0.25; + } + else if (el.GetType() == PRISM) + { + lam(0) = 0.33; lam(1) = 0.33; lam(2) = 0.5; + } + else if (el.GetType() == PYRAMID) + { + lam(0) = 0.4; lam(1) = 0.4; lam(2) = 0.2; + } + else if (el.GetType() == HEX) + { + lam = 0.5; + } + + + Vec<3> deltalam,rhs; + netgen::Point<3> x; + Mat<3,3> Jac,Jact; + + double delta=1; + + bool retval; + + int i = 0; + + const int maxits = 30; + + while(delta > 1e-16 && iCalcElementTransformation(lam,element-1,x,Jac); + + rhs = p-x; + Jac.Solve(rhs,deltalam); + + lam += deltalam; + + delta = deltalam.Length2(); + + i++; + //(*testout) << "pcie i " << i << " delta " << delta << " p " << p << " x " << x << " lam " << lam << endl; + //<< "Jac " << Jac << endl; + } + + if(i==maxits) + return false; + + + for(i=0; i<3; i++) + lami[i] = lam(i); + + + + if (el.GetType() == TET) + { + retval = (lam(0) > -eps && + lam(1) > -eps && + lam(2) > -eps && + lam(0) + lam(1) + lam(2) < 1+eps); + } + else if (el.GetType() == PRISM) + { + retval = (lam(0) > -eps && + lam(1) > -eps && + lam(2) > -eps && + lam(2) < 1+eps && + lam(0) + lam(1) < 1+eps); + } + else if (el.GetType() == PYRAMID) + { + retval = (lam(0) > -eps && + lam(1) > -eps && + lam(2) > -eps && + lam(0) + lam(2) < 1+eps && + lam(1) + lam(2) < 1+eps); + } + else if (el.GetType() == HEX) + { + retval = (lam(0) > -eps && lam(0) < 1+eps && + lam(1) > -eps && lam(1) < 1+eps && + lam(2) > -eps && lam(2) < 1+eps); + } + else + throw NgException("Da haun i wos vagessn"); + + return retval; + } + + + + bool Mesh :: PointContainedIn3DElementOld(const Point3d & p, + double lami[3], + const int element) const + { + + static Vec3d col1, col2, col3; + static Vec3d rhs, sol; + const double eps = 1.e-4; + + static ARRAY loctets; + + VolumeElement(element).GetTets (loctets); + + for (int 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 loctetsloc; + ARRAY > pointsloc; + + VolumeElement(element).GetTetsLocal (loctetsloc); + VolumeElement(element).GetNodesLocalNew (pointsloc); + + const Element & le = loctetsloc.Get(j); + + + Point3d pp = + 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] = pp.X(); + lami[1] = pp.Y(); + lami[2] = pp.Z(); + return true; + } + } + return false; + } + + + int Mesh :: GetElementOfPoint (const Point3d & p, + double lami[3], + bool build_searchtree, + const int index, + const bool allowindex) const + { + if(index != -1) + { + ARRAY dummy(1); + dummy[0] = index; + return GetElementOfPoint(p,lami,&dummy,build_searchtree,allowindex); + } + else + return GetElementOfPoint(p,lami,NULL,build_searchtree,allowindex); + } + + + + + int Mesh :: GetElementOfPoint (const Point3d & p, + double lami[3], + const ARRAY * const indices, + bool build_searchtree, + const bool allowindex) const + { + if (dimension == 2) + { + int i, j; + int ne; + + + if(ps_startelement != 0 && ps_startelement <= GetNSE() && PointContainedIn2DElement(p,lami,ps_startelement)) + return ps_startelement; + + ARRAY locels; + if (0) + { + elementsearchtree->GetIntersecting (p, p, locels); + ne = locels.Size(); + } + else + ne = GetNSE(); + + for (i = 1; i <= ne; i++) + { + int ii; + + if (0) + ii = locels.Get(i); + else + ii = i; + + if(ii == ps_startelement) continue; + + if(indices != NULL && indices->Size() > 0) + { + bool contained = indices->Contains(SurfaceElement(ii).GetIndex()); + if((allowindex && !contained) || (!allowindex && contained)) continue; + } + + if(PointContainedIn2DElement(p,lami,ii)) return ii; + + } + return 0; + } + else + + { + int i, j; + int ne; + + if(ps_startelement != 0 && PointContainedIn3DElement(p,lami,ps_startelement)) + return ps_startelement; + + ARRAY locels; + if (elementsearchtree || build_searchtree) + { + // update if necessary: + const_cast(*this).BuildElementSearchTree (); + elementsearchtree->GetIntersecting (p, p, locels); + ne = locels.Size(); + } + else + ne = GetNE(); + + for (i = 1; i <= ne; i++) + { + int ii; + + if (elementsearchtree) + ii = locels.Get(i); + else + ii = i; + + if(ii == ps_startelement) continue; + + if(indices != NULL && indices->Size() > 0) + { + bool contained = indices->Contains(VolumeElement(ii).GetIndex()); + if((allowindex && !contained) || (!allowindex && contained)) continue; + } + + + if(PointContainedIn3DElement(p,lami,ii)) + { + ps_startelement = ii; + return ii; + } + } + + // Not found, try uncurved variant: + for (i = 1; i <= ne; i++) + { + int ii; + + if (elementsearchtree) + ii = locels.Get(i); + else + ii = i; + + if(indices != NULL && indices->Size() > 0) + { + bool contained = indices->Contains(VolumeElement(ii).GetIndex()); + if((allowindex && !contained) || (!allowindex && contained)) continue; + } + + + if(PointContainedIn3DElementOld(p,lami,ii)) + { + ps_startelement = ii; + (*testout) << "WARNING: found element of point " << p <<" only for uncurved mesh" << endl; + return ii; + } + } + + + return 0; + } + } + + + + int Mesh :: GetSurfaceElementOfPoint (const Point3d & p, + double lami[3], + bool build_searchtree, + const int index, + const bool allowindex) const + { + if(index != -1) + { + ARRAY dummy(1); + dummy[0] = index; + return GetSurfaceElementOfPoint(p,lami,&dummy,build_searchtree,allowindex); + } + else + return GetSurfaceElementOfPoint(p,lami,NULL,build_searchtree,allowindex); + } + + + + + int Mesh :: GetSurfaceElementOfPoint (const Point3d & p, + double lami[3], + const ARRAY * const indices, + bool build_searchtree, + const bool allowindex) const + { + if (dimension == 2) + { + throw NgException("GetSurfaceElementOfPoint not yet implemented for 2D meshes"); + } + else + { + double vlam[3]; + int velement = GetElementOfPoint(p,vlam,NULL,build_searchtree,allowindex); + + //(*testout) << "p " << p << endl; + //(*testout) << "velement " << velement << endl; + + ARRAY faces; + topology->GetElementFaces(velement,faces); + + //(*testout) << "faces " << faces << endl; + + for(int i=0; iGetFace2SurfaceElement(faces[i]); + + //(*testout) << "surfel " << faces << endl; + + for(int i=0; iSize() != 0) + { + if(indices->Contains(SurfaceElement(faces[i]).GetIndex()) && + PointContainedIn2DElement(p,lami,faces[i],true)) + return faces[i]; + } + else + { + if(PointContainedIn2DElement(p,lami,faces[i],true)) + { + //(*testout) << "found point " << p << " in sel " << faces[i] + // << ", lam " << lami[0] << ", " << lami[1] << ", " << lami[2] << endl; + return faces[i]; + } + } + } + + } + + return 0; + } + + + void Mesh::GetIntersectingVolEls(const Point3d& p1, const Point3d& p2, + ARRAY & 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 () + { + PrintMessage (3, "SplitSeparateFaces"); + int fdi; + int np = GetNP(); + + BitArray usedp(np); + ARRAY els_of_face; + + fdi = 1; + while (fdi <= GetNFD()) + { + GetSurfaceElementsOfFace (fdi, els_of_face); + + if (els_of_face.Size() == 0) continue; + + SurfaceElementIndex firstel = els_of_face[0]; + + usedp.Clear(); + for (int j = 1; j <= SurfaceElement(firstel).GetNP(); j++) + usedp.Set (SurfaceElement(firstel).PNum(j)); + + bool changed; + do + { + changed = false; + + for (int i = 0; i < els_of_face.Size(); i++) + { + const Element2d & el = SurfaceElement(els_of_face[i]); + + bool has = 0; + bool hasno = 0; + for (int j = 0; j < el.GetNP(); j++) + { + if (usedp.Test(el[j])) + has = true; + else + hasno = true; + } + + if (has && hasno) + changed = true; + + if (has) + for (int j = 0; j < el.GetNP(); j++) + usedp.Set (el[j]); + } + } + while (changed); + + int nface = 0; + for (int i = 0; i < els_of_face.Size(); i++) + { + Element2d & el = SurfaceElement(els_of_face[i]); + + int hasno = 0; + for (int 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); + } + } + + // reconnect list + if (nface) + { + facedecoding[nface-1].firstelement = -1; + facedecoding[fdi-1].firstelement = -1; + + for (int i = 0; i < els_of_face.Size(); i++) + { + int ind = SurfaceElement(els_of_face[i]).GetIndex(); + SurfaceElement(els_of_face[i]).next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = els_of_face[i]; + } + } + + fdi++; + } + + + /* + fdi = 1; + while (fdi <= GetNFD()) + { + int firstel = 0; + for (int i = 1; i <= GetNSE(); i++) + if (SurfaceElement(i).GetIndex() == fdi) + { + firstel = i; + break; + } + if (!firstel) continue; + + usedp.Clear(); + for (int j = 1; j <= SurfaceElement(firstel).GetNP(); j++) + usedp.Set (SurfaceElement(firstel).PNum(j)); + + int changed; + do + { + changed = 0; + for (int i = 1; i <= GetNSE(); i++) + { + const Element2d & el = SurfaceElement(i); + if (el.GetIndex() != fdi) + continue; + + int has = 0; + int hasno = 0; + for (int 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 (int j = 1; j <= el.GetNP(); j++) + usedp.Set (el.PNum(j)); + } + } + while (changed); + + int nface = 0; + for (int i = 1; i <= GetNSE(); i++) + { + Element2d & el = SurfaceElement(i); + if (el.GetIndex() != fdi) + continue; + + int hasno = 0; + for (int 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 & sei) const + { + static int timer = NgProfiler::CreateTimer ("GetSurfaceElementsOfFace"); + NgProfiler::RegionTimer reg (timer); + + /* + 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); + + int size1 = sei.Size(); + */ + + sei.SetSize(0); + + SurfaceElementIndex si = facedecoding[facenr-1].firstelement; + while (si != -1) + { + if ( (*this)[si].GetIndex () == facenr && (*this)[si][0] >= PointIndex::BASE && + !(*this)[si].IsDeleted() ) + { + sei.Append (si); + } + + si = (*this)[si].next; + } + + /* + // *testout << "with list = " << endl << sei << endl; + + if (size1 != sei.Size()) + { + cout << "size mismatch" << endl; + exit(1); + } + */ + } + + + + + 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 & 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 & 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 :: InitPointCurve(double red, double green, double blue) const + { + pointcurves_startpoint.Append(pointcurves.Size()); + pointcurves_red.Append(red); + pointcurves_green.Append(green); + pointcurves_blue.Append(blue); + } + void Mesh :: AddPointCurvePoint(const Point3d & pt) const + { + pointcurves.Append(pt); + } + int Mesh :: GetNumPointCurves(void) const + { + return pointcurves_startpoint.Size(); + } + int Mesh :: GetNumPointsOfPointCurve(int curve) const + { + if(curve == pointcurves_startpoint.Size()-1) + return (pointcurves.Size() - pointcurves_startpoint.Last()); + else + return (pointcurves_startpoint[curve+1]-pointcurves_startpoint[curve]); + } + + Point3d & Mesh :: GetPointCurvePoint(int curve, int n) const + { + return pointcurves[pointcurves_startpoint[curve]+n]; + } + + void Mesh :: GetPointCurveColor(int curve, double & red, double & green, double & blue) const + { + red = pointcurves_red[curve]; + green = pointcurves_green[curve]; + blue = pointcurves_blue[curve]; + } + + + 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 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 & 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 ::SetNBCNames ( int nbcn ) + { + if ( bcnames.Size() ) + for ( int i = 0; i < bcnames.Size(); i++) + if ( bcnames[i] ) delete bcnames[i]; + bcnames.SetSize(nbcn); + bcnames = 0; + } + + void Mesh ::SetBCName ( int bcnr, const string & abcname ) + { + if ( bcnames[bcnr] ) delete bcnames[bcnr]; + if ( abcname != "default" ) + bcnames[bcnr] = new string ( abcname ); + else + bcnames[bcnr] = 0; + } + + string Mesh ::GetBCName ( int bcnr ) const + { + if ( !bcnames.Size() ) + return "default"; + if ( bcnames[bcnr] ) + return *bcnames[bcnr]; + else + return "default"; + } + + void Mesh :: SetUserData(const char * id, ARRAY & data) + { + if(userdata_int.Used(id)) + delete userdata_int.Get(id); + + ARRAY * newdata = new ARRAY(data); + + userdata_int.Set(id,newdata); + } + bool Mesh :: GetUserData(const char * id, ARRAY & data, int shift) const + { + if(userdata_int.Used(id)) + { + if(data.Size() < (*userdata_int.Get(id)).Size()+shift) + data.SetSize((*userdata_int.Get(id)).Size()+shift); + for(int i=0; i<(*userdata_int.Get(id)).Size(); i++) + data[i+shift] = (*userdata_int.Get(id))[i]; + return true; + } + else + { + data.SetSize(0); + return false; + } + } + void Mesh :: SetUserData(const char * id, ARRAY & data) + { + if(userdata_double.Used(id)) + delete userdata_double.Get(id); + + ARRAY * newdata = new ARRAY(data); + + userdata_double.Set(id,newdata); + } + bool Mesh :: GetUserData(const char * id, ARRAY & data, int shift) const + { + if(userdata_double.Used(id)) + { + if(data.Size() < (*userdata_double.Get(id)).Size()+shift) + data.SetSize((*userdata_double.Get(id)).Size()+shift); + for(int i=0; i<(*userdata_double.Get(id)).Size(); i++) + data[i+shift] = (*userdata_double.Get(id))[i]; + return true; + } + else + { + data.SetSize(0); + return false; + } + } + + + + 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/libsrc/meshing/meshclass.hpp b/libsrc/meshing/meshclass.hpp new file mode 100644 index 00000000..4dab869d --- /dev/null +++ b/libsrc/meshing/meshclass.hpp @@ -0,0 +1,777 @@ +#ifndef MESHCLASS +#define MESHCLASS + +/**************************************************************************/ +/* File: meshclass.hpp */ +/* 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 T_POINTS; + typedef MoveableArray T_VOLELEMENTS; + typedef MoveableArray T_SURFELEMENTS; + + // typedef ARRAY T_POINTS; + // typedef ARRAY T_VOLELEMENTS; + // typedef ARRAY T_SURFELEMENTS; + + +private: + /// point coordinates + T_POINTS points; + + /// type of element, set in calcsurfacesofnode + // ARRAY eltyps; + + /// line-segments at edges + ARRAY segments; + /// surface elements, 2d-inner elements + T_SURFELEMENTS surfelements; + /// volume elements + T_VOLELEMENTS volelements; + /// points will be fixed forever + ARRAY lockedpoints; + + + /// surface indices at boundary nodes + TABLE surfacesonnode; + /// boundary edges (1..normal bedge, 2..segment) + INDEX_2_CLOSED_HASHTABLE * boundaryedges; + /// + INDEX_2_CLOSED_HASHTABLE * segmentht; + /// + INDEX_3_CLOSED_HASHTABLE * surfelementht; + + /// faces of rest-solid + ARRAY openelements; + /// open segmenets for surface meshing + ARRAY opensegments; + + + + /** + Representation of local mesh-size h + */ + LocalH * lochfunc; + /// + double hglob; + /// + double hmin; + /// + ARRAY maxhdomain; + + /** + the face-index of the surface element maps into + this table. + */ + ARRAY facedecoding; + + /// sub-domain materials + ARRAY materials; + + ARRAY bcnames; + + /// 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 semaphors. + NgMutex mutex; + /// mesh access semaphors. + NgMutex majormutex; + + SYMBOLTABLE< ARRAY* > userdata_int; + SYMBOLTABLE< ARRAY* > userdata_double; + + + mutable ARRAY< Point3d > pointcurves; + mutable ARRAY pointcurves_startpoint; + mutable ARRAY pointcurves_red,pointcurves_green,pointcurves_blue; + + + /// start element for point search (GetElementOfPoint) + mutable int ps_startelement; + + +#ifdef PARALLEL + /// connection to parallel meshes + class ParallelMeshTopology * paralleltop; + +#endif + + +private: + void BuildBoundaryEdges(void); + +public: + bool PointContainedIn2DElement(const Point3d & p, + double lami[3], + const int element, + bool consider3D = false) const; + bool PointContainedIn3DElement(const Point3d & p, + double lami[3], + const int element) const; + bool PointContainedIn3DElementOld(const Point3d & p, + double lami[3], + const int element) const; + +public: + + // store coarse mesh before hp-refinement + ARRAY * hpelements; + Mesh * coarsemesh; + + + /// number of refinement levels + int mglevels; + /// refinement hierarchy + ARRAY mlbetweennodes; + /// parent element of volume element + ARRAY mlparentelement; + /// parent element of surface element + ARRAY 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; + + void SetAllocSize(int nnodes, int nsegs, int nsel, int nel); + + + PointIndex AddPoint (const Point3d & p, int layer = 1); + PointIndex AddPoint (const Point3d & p, int layer, POINTTYPE type); +#ifdef PARALLEL + PointIndex AddPoint (const Point3d & p, bool aisghost, int layer = 1); + PointIndex AddPoint (const Point3d & p, bool aisghost, int layer, POINTTYPE type); +#endif + 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]; } + + const T_POINTS & Points() const { return points; } + T_POINTS & Points() { return points; } + + + SegmentIndex AddSegment (const Segment & s); + void DeleteSegment (int segnr) + { + segments.Elem(segnr).p1 = PointIndex::BASE-1; + segments.Elem(segnr).p2 = PointIndex::BASE-1; + } + void FullDeleteSegment (int segnr) + { + segments.Delete(segnr-PointIndex::BASE); + } + + 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 & 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 (int i) const + // { return (volelements.Get(i).fixed) ? FIXEDELEMENT : FREEELEMENT; } + + ELEMENTTYPE ElementType (ElementIndex i) const + { return (volelements[i].flags.fixed) ? FIXEDELEMENT : FREEELEMENT; } + + /* + 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 & 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); + /// + void SetMinimalH (double h); + /// + double MaxHDomain (int dom) const; + /// + void SetMaxHDomain (const ARRAY & mhd); + /// + double GetH (const Point3d & p) const; + /// + double GetMinH (const Point3d & pmin, const Point3d & pmax); + /// + LocalH & LocalHFunction () { return * lochfunc; } + /// + bool LocalHFunctionGenerated(void) const { return (lochfunc != NULL); } + + /// 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 + bool 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 + { + if(!boundaryedges) + const_cast(this)->BuildBoundaryEdges(); + + 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 (ostream & outfile) const; + /// + void Load (istream & infile); + /// + void Merge (istream & infile, const int surfindex_offset = 0); + /// + void Save (const string & filename) const; + /// + void Load (const string & filename); + /// + void Merge (const string & filename, const int surfindex_offset = 0); + + + /// + void ImproveMesh (OPTIMIZEGOAL goal = OPT_QUALITY); + + /// + void ImproveMeshJacobian (OPTIMIZEGOAL goal = OPT_QUALITY, const BitArray * usepoint = NULL); + /// + void ImproveMeshJacobianOnSurface (const BitArray & usepoint, + const ARRAY< Vec<3>* > & nv, + OPTIMIZEGOAL goal = OPT_QUALITY, + const ARRAY< ARRAY* > * idmaps = NULL); + /* +#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 (); + + void SetPointSearchStartElement(const int el) const {ps_startelement = el;} + + /// gives element of point, barycentric coordinates + int GetElementOfPoint (const Point3d & p, + double * lami, + bool build_searchtree = 0, + const int index = -1, + const bool allowindex = true) const; + int GetElementOfPoint (const Point3d & p, + double * lami, + const ARRAY * const indices, + bool build_searchtree = 0, + const bool allowindex = true) const; + int GetSurfaceElementOfPoint (const Point3d & p, + double * lami, + bool build_searchtree = 0, + const int index = -1, + const bool allowindex = true) const; + int GetSurfaceElementOfPoint (const Point3d & p, + double * lami, + const ARRAY * const indices, + bool build_searchtree = 0, + const bool allowindex = true) const; + + /// give list of vol elements which are int the box(p1,p2) + void GetIntersectingVolEls(const Point3d& p1, const Point3d& p2, + ARRAY & 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 SetNBCNames ( int nbcn ); + + void SetBCName ( int bcnr, const string & abcname ); + + string GetBCName ( int bcnr ) const; + + string * GetBCNamePtr ( int bcnr ) + { return bcnames[bcnr]; } + + /// + 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 & GetIdentifiedPoints () +// { +// return *identifiedpoints; +// } + +// /// +// void GetIdentificationMap (int identnr, ARRAY & identmap) const; +// /// +// void GetIdentificationPairs (int identnr, ARRAY & 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; } + + + void InitPointCurve(double red = 1, double green = 0, double blue = 0) const; + void AddPointCurvePoint(const Point3d & pt) const; + int GetNumPointCurves(void) const; + int GetNumPointsOfPointCurve(int curve) const; + Point3d & GetPointCurvePoint(int curve, int n) const; + void GetPointCurveColor(int curve, double & red, double & green, double & blue) const; + + + + + /// 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 & 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; } + NgMutex & MajorMutex () { return majormutex; } + + + /// + void SetUserData(const char * id, ARRAY & data); + /// + bool GetUserData(const char * id, ARRAY & data, int shift = 0) const; + /// + void SetUserData(const char * id, ARRAY & data); + /// + bool GetUserData(const char * id, ARRAY & data, int shift = 0) const; + + /// + friend void OptimizeRestart (Mesh & mesh3d); + /// + void PrintMemInfo (ostream & ost) const; + /// + friend class Meshing3; + + + enum GEOM_TYPE { NO_GEOM = 0, GEOM_2D = 1, GEOM_CSG = 10, GEOM_STL = 11, GEOM_OCC = 12, GEOM_ACIS = 13 }; + GEOM_TYPE geomtype; + + + +#ifdef PARALLEL + /// returns parallel topology + class ParallelMeshTopology & GetParallelTopology () const + { return *paralleltop; } + + + /// distributes the master-mesh to local meshes + void Distribute (); + + /// loads a mesh sent from master processor + void ReceiveParallelMesh (); + + /// find connection to parallel meshes +// void FindExchangePoints () ; + +// void FindExchangeEdges (); +// void FindExchangeFaces (); + + /// use metis to decompose master mesh + void ParallelMetis (); // ARRAY & neloc ); + void PartHybridMesh (); // ARRAY & neloc ); + void PartDualHybridMesh (); // ARRAY & neloc ); + void PartDualHybridMesh2D (); // ( ARRAY & neloc ); + + /// send mesh to parallel machine, keep global mesh at master + void SendMesh ( ) const; // Mesh * mastermesh, ARRAY & neloc) const; + + void UpdateOverlap (); + +#endif + + +}; + +inline ostream& operator<<(ostream& ost, const Mesh& mesh) +{ + ost << "mesh: " << endl; + mesh.Save(ost); + return ost; +} + + +#endif + + diff --git a/libsrc/meshing/meshfunc.cpp b/libsrc/meshing/meshfunc.cpp new file mode 100644 index 00000000..06fb451d --- /dev/null +++ b/libsrc/meshing/meshfunc.cpp @@ -0,0 +1,725 @@ +#include +#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 connectednodes; + + mesh3d.Compress(); + + // mesh3d.PrintMemInfo (cout); + + if (mp.checkoverlappingboundary) + 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() != 0); + 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()); + (*testout) << "Meshing subdomain " << k << endl; + + mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k)); + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(k); + + if (!mesh3d.GetNOpenElements()) + continue; + + + + Box<3> domain_bbox( Box<3>::EMPTY_BOX ); + /* + Point<3> (1e10, 1e10, 1e10), + Point<3> (-1e10, -1e10, -1e10)); + */ + + for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++) + { + const Element2d & el = mesh3d[sei]; + if (el.IsDeleted() ) continue; + + if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k || + mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k) + + for (int j = 0; j < el.GetNP(); j++) + domain_bbox.Add (mesh3d[el[j]]); + } + domain_bbox.Increase (0.01 * domain_bbox.Diam()); + + + for (int 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 = 1000; + mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo) + + + 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/pyramid 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, k, mp); + + for (i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + + PrintMessage (3, mesh3d.GetNP(), " points, ", + mesh3d.GetNE(), " elements"); + } + + + cntsteps = 0; + if (mesh3d.GetNOpenElements()) + 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); + + ARRAY glob2loc(mesh3d.GetNP()); + glob2loc = -1; + + for (pi = PointIndex::BASE; + pi < mesh3d.GetNP()+PointIndex::BASE; pi++) + + if (domain_bbox.IsIn (mesh3d[pi])) + glob2loc[pi] = + meshing.AddPoint (mesh3d[pi], pi); + + for (i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + Element2d hel = mesh3d.OpenElement(i); + for (int j = 0; j < hel.GetNP(); j++) + hel[j] = glob2loc[hel[j]]; + meshing.AddBoundaryElement (hel); + // meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + } + + oldne = mesh3d.GetNE(); + + mp.giveuptol = 15 + 10 * cntsteps; + 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"; + size_t j; + for (j = 1; j <= strlen(optstr); j++) + { + mesh3d.CalcSurfacesOfNode(); + mesh3d.FreeOpenElementsEnvironment(2); + mesh3d.CalcSurfacesOfNode(); + + 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, k); + 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; + + 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 (size_t 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 'u': optmesh.SwapImproveSurface(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; + } + } + mesh3d.mglevels = 1; + MeshQuality3d (mesh3d); + } + + return MESHING3_OK; + } + + + + + void RemoveIllegalElements (Mesh & mesh3d) + { + int it = 10; + int nillegal, oldn; + + 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/libsrc/meshing/meshfunc.hpp b/libsrc/meshing/meshfunc.hpp new file mode 100644 index 00000000..ab2d6610 --- /dev/null +++ b/libsrc/meshing/meshfunc.hpp @@ -0,0 +1,41 @@ +#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/libsrc/meshing/meshfunc2d.cpp b/libsrc/meshing/meshfunc2d.cpp new file mode 100644 index 00000000..ac4fbe8e --- /dev/null +++ b/libsrc/meshing/meshfunc2d.cpp @@ -0,0 +1,61 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + void Optimize2d (Mesh & mesh, MeshingParameters & mp) + { + int i; + + //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 (size_t 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/libsrc/meshing/meshing.hpp b/libsrc/meshing/meshing.hpp new file mode 100644 index 00000000..10b77f9e --- /dev/null +++ b/libsrc/meshing/meshing.hpp @@ -0,0 +1,86 @@ +#ifndef FILE_MESHING +#define FILE_MESHING + + + +#define CURVEDELEMS_NEW + + +#include "../include/myadt.hpp" +#include "../include/gprim.hpp" +#include "../include/linalg.hpp" +#include "../include/opti.hpp" + + + + +namespace netgen +{ + + extern int printmessage_importance; + + 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 "findip2.hpp" + +#include "topology.hpp" + +#ifdef CURVEDELEMS_NEW +#include "curvedelems_new.hpp" +#else +#include "curvedelems.hpp" +#endif +#include "clusters.hpp" + +#ifdef _INCLUDE_MORE +#include "meshfunc.hpp" +#endif +#include "bisect.hpp" +#include "hprefinement.hpp" +#include "boundarylayer.hpp" +#include "specials.hpp" + +#include "validate.hpp" + +#ifdef PARALLEL +#include "../parallel/paralleltop.hpp" +// #include "../parallel/parallelmesh.hpp" +#endif + + + +} + +#endif diff --git a/libsrc/meshing/meshing2.cpp b/libsrc/meshing/meshing2.cpp new file mode 100644 index 00000000..7793ecbb --- /dev/null +++ b/libsrc/meshing/meshing2.cpp @@ -0,0 +1,1890 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + static void glrender (int wait); + + + // global variable for visualization + + static ARRAY locpoints; + static ARRAY legalpoints; + static ARRAY plainpoints; + static ARRAY plainzones; + static ARRAY loclines; + static int geomtrig; + //static const char * rname; + static int cntelem, trials, nfaces; + static int oldnl; + static int qualclass; + + + Meshing2 :: Meshing2 (const Box<3> & aboundingbox) + { + boundingbox = aboundingbox; + + LoadRules (NULL); + // LoadRules ("rules/quad.rls"); + // LoadRules ("rules/triangle.rls"); + + adfront = new AdFront2(boundingbox); + starttime = GetTime(); + + maxarea = -1; + } + + + 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, + bool pointonsurface) + { + //(*testout) << "add point " << globind << endl; + adfront ->AddPoint (p, globind, mgi, pointonsurface); + } + + 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-1, i2-1, 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; + } + + + void Meshing2 :: SetMaxArea (double amaxarea) + { + maxarea = amaxarea; + } + + + 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 (const Point3d & p1, const 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 & points, + ARRAY & points3d, + ARRAY & 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 pindex, lindex; + ARRAY delpoints, dellines; + + ARRAY upgeominfo; // unique info + ARRAY mpgeominfo; // multiple info + + ARRAY locelements; + + int z1, z2, oldnp(-1); + SurfaceElementIndex sei; + bool found; + int rulenr(-1); + int globind; + Point<3> 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 intersecttrias; + ARRAY critpoints; + + // test for doubled edges + //INDEX_2_HASHTABLE doubleedge(300000); + + + testmode = 0; + + StartMesh(); + + ARRAY chartboundpoints; + ARRAY chartboundpoints3d; + ARRAY chartboundlines; + + // illegal points: points with more then 50 elements per node + int maxlegalpoint(-1), maxlegalline(-1); + ARRAY trigsonnode; + ARRAY 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) + { + Box<3> box; + box.Set ( mesh[sel[0]] ); + box.Add ( mesh[sel[1]] ); + box.Add ( mesh[sel[2]] ); + surfeltree.Insert (box, sei); + } + + double trigarea = Cross ( mesh[sel[1]]-mesh[sel[0]], + mesh[sel[2]]-mesh[sel[0]] ).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; + } + + + const char * savetask = multithread.task; + multithread.task = "Surface meshing"; + + adfront ->SetStartFront (); + + + int plotnexttrial = 999; + + double meshedarea_before = meshedarea; + + 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 (int 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"; + } + + + int baselineindex = adfront -> SelectBaseLine (p1, p2, blgeominfo1, blgeominfo2, qualclass); + + + 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); + //(*testout) << "h for locals: " << 2*hinner << endl; + + + //(*testout) << "locpoints " << locpoints << endl; + + if (qualclass > mparam.giveuptol2d) + { + 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 (int 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) << "transform " << locpoints.Get(i) << " to " << 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 (int 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 (-1); + 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 (int i = 1; i <= legalpoints.Size(); i++) + legalpoints.Elem(i) = 1; + + double avy = 0; + for (int i = 1; i <= plainpoints.Size(); i++) + avy += plainpoints.Elem(i).Y(); + avy *= 1./plainpoints.Size(); + + + for (int 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) == -1) + { + legalpoints.Elem(i) = 0; + } + + + if (plainpoints.Elem(i).Y() < -1e-10*avy) // changed + { + 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 (int i = 1; i <= chartboundpoints.Size(); i++) + { + plainpoints.Append (chartboundpoints.Get(i)); + locpoints.Append (chartboundpoints3d.Get(i)); + legalpoints.Append (0); + } + + + for (int 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 (int i = 1; i <= locelements.Size() && found; i++) + { + const Element2d & el = locelements.Get(i); + + for (int j = 1; j <= el.GetNP(); j++) + if (el.PNum(j) <= oldnp && pindex.Get(el.PNum(j)) == -1) + { + found = 0; + PrintSysError ("meshing2, index missing"); + } + } + + + if (found) + { + locpoints.SetSize (plainpoints.Size()); + upgeominfo.SetSize(locpoints.Size()); + + for (int 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 (int i = oldnl+1; i <= loclines.Size(); i++) + { + double eh = Dist (locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2())); + + // Markus (brute force method to avoid bad elements on geometries like \_/ ) + //if(eh > 4.*mesh.GetH(locpoints.Get(loclines.Get(i).I1()))) found = 0; + //if(eh > 4.*mesh.GetH(locpoints.Get(loclines.Get(i).I2()))) found = 0; + // Markus end + + if (eh > newedgemaxh) + newedgemaxh = eh; + } + + for (int i = 1; i <= locelements.Size(); i++) + { + Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); + Point3d pmax = pmin; + for (int 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 (int i = 1; i <= locelements.Size(); i++) + for (int 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 (int i = 1; i <= locelements.Size(); i++) + for (int 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 (int i = 1; i <= locelements.Size(); i++) + for (int 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 (int i = oldnp+1; i <= locpoints.Size(); i++) + critpoints.Append (locpoints.Get(i)); + + for (int 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 (int 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++) + { + int 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 (int 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 (int 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 (int i = oldnp+1; i <= locpoints.Size(); i++) + { + globind = mesh.AddPoint (locpoints.Get(i)); + pindex.Elem(i) = adfront -> AddPoint (locpoints.Get(i), globind); + } + + for (int 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()) == -1 || + pindex.Get(loclines.Get(i).I2()) == -1) + { + (*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 (int 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 (int 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 (int 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; + + + + Box<3> box; + box.Set (mesh[mtri[0]]); + box.Add (mesh[mtri[1]]); + box.Add (mesh[mtri[2]]); + surfeltree.Insert (box, mesh.GetNSE()); + + const Point3d & sep1 = mesh.Point (mtri.PNum(1)); + const Point3d & sep2 = mesh.Point (mtri.PNum(2)); + const Point3d & sep3 = mesh.Point (mtri.PNum(3)); + + 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; + + if(maxarea > 0 && meshedarea-meshedarea_before > maxarea) + { + cerr << "meshed area = " << meshedarea-meshedarea_before << endl + << "maximal area = " << maxarea << endl + << "GIVING UP" << endl; + return MESHING2_GIVEUP; + } + + + + for (int 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 (int 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 (int 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 ) + { + // adfront -> PrintOpenSegments (*testout); + 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) << "locpoints " << endl; + for (int i = 1; i <= pindex.Size(); i++) + (*testout) << adfront->GetGlobalIndex (pindex.Get(i)) << endl; + + (*testout) << "old number of lines = " << oldnl << endl; + for (int i = 1; i <= loclines.Size(); i++) + { + (*testout) << "line "; + for (int 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 (int i = 1; i <= loclines.Size(); i++) + { + (*testout) << "line "; + for (int 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 +#include + +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); + glEnable (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/libsrc/meshing/meshing2.hpp b/libsrc/meshing/meshing2.hpp new file mode 100644 index 00000000..0912fa34 --- /dev/null +++ b/libsrc/meshing/meshing2.hpp @@ -0,0 +1,156 @@ +#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 rules; + /// statistics + ARRAY ruleused, canuse, foundmap; + /// + Box<3> boundingbox; + /// + double starttime; + /// + double maxarea; + +public: + /// + Meshing2 (const Box<3> & 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, + bool pointonsurface = true); + + /// + void AddBoundaryElement (INDEX i1, INDEX i2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2); + + /// + void SetStartTime (double astarttime); + + /// + void SetMaxArea (double amaxarea); + +protected: + /// + virtual void StartMesh (); + /// + virtual void EndMesh (); + /// + virtual double CalcLocalH (const Point3d & p, double gh) const; + + /// + virtual void DefineTransformation (const Point3d & p1, const 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 & points, + ARRAY & points3d, + ARRAY & lines, double p) const; + + virtual double Area () const; + + +/** Applies 2D rules. + Tests all 2D rules */ + int ApplyRules (ARRAY & lpoints, + ARRAY & legalpoints, + int maxlegalpoint, + ARRAY & llines, + int maxlegelline, + ARRAY & elements, ARRAY & dellines, + int tolerance); + + +}; + + + + + + + + +#endif + + + + + + + diff --git a/libsrc/meshing/meshing3.cpp b/libsrc/meshing/meshing3.cpp new file mode 100644 index 00000000..075fd6b3 --- /dev/null +++ b/libsrc/meshing/meshing3.cpp @@ -0,0 +1,1292 @@ +#include +#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 & locpoints, + const ARRAY & 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) +{ + MiniElement2d mini(elem.GetNP()); + for (int j = 0; j < elem.GetNP(); j++) + mini[j] = elem[j]; + adfront -> AddFace(mini); +} + + +void Meshing3 :: AddBoundaryElement (const MiniElement2d & elem) +{ + adfront -> AddFace(elem); +} + +int Meshing3 :: AddConnectedPair (const INDEX_2 & apair) +{ + return adfront -> AddConnectedPair (apair); +} + +MESHING3_RESULT Meshing3 :: +GenerateMesh (Mesh & mesh, const MeshingParameters & mp) +{ + static int meshing3_timer = NgProfiler::CreateTimer ("Meshing3::GenerateMesh"); + static int meshing3_timer_a = NgProfiler::CreateTimer ("Meshing3::GenerateMesh a"); + static int meshing3_timer_b = NgProfiler::CreateTimer ("Meshing3::GenerateMesh b"); + static int meshing3_timer_c = NgProfiler::CreateTimer ("Meshing3::GenerateMesh c"); + static int meshing3_timer_d = NgProfiler::CreateTimer ("Meshing3::GenerateMesh d"); + NgProfiler::RegionTimer reg (meshing3_timer); + + + ARRAY locpoints; // local points + ARRAY locfaces; // local faces + ARRAY pindex; // mapping from local to front point numbering + ARRAY allowpoint; // point is allowd ? + ARRAY findex; // mapping from local to front face numbering + //INDEX_2_HASHTABLE connectedpairs(100); // connecgted pairs for prism meshing + + ARRAY plainpoints; // points in reference coordinates + ARRAY delpoints, delfaces; // points and lines to be deleted + ARRAY 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 + + bool loktestmode = false; + + int uselocalh = mp.uselocalh; + + // int giveuptol = mp.giveuptol; // + MeshingStat3d stat; // statistics + int plotstat_oldne = -1; + + + // for star-shaped domain meshing + ARRAY grouppoints; + ARRAY groupfaces; + ARRAY grouppindex; + ARRAY groupfindex; + + + float minerr; + int hasfound; + double tetvol; + // int giveup = 0; + + + ARRAY tempnewpoints; + ARRAY tempnewfaces; + ARRAY tempdelfaces; + ARRAY 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"); + + // 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 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 MiniElement2d & 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); + + NgProfiler::StartTimer (meshing3_timer_a); + stat.qualclass = + adfront -> GetLocals (baseelem, locpoints, locfaces, + pindex, findex, connectedpairs, + houter, hinner, + locfacesplit); + NgProfiler::StopTimer (meshing3_timer_a); + + // (*testout) << "locfaces = " << endl << locfaces << endl; + + int pi1 = pindex.Get(locfaces[0].PNum(1)); + int pi2 = pindex.Get(locfaces[0].PNum(2)); + int pi3 = pindex.Get(locfaces[0].PNum(3)); + + //loktestmode = 1; + testmode = loktestmode; //changed + // loktestmode = testmode = (adfront->GetFace (baseelem).GetNP() == 4) && (rules.Size() == 5); + + loktestmode = stat.qualclass > 5; + + + if (loktestmode) + { + (*testout) << "baseel = " << baseelem << ", ind = " << findex.Get(1) << endl; + (*testout) << "pi = " << pi1 << ", " << pi2 << ", " << pi3 << endl; + } + + + + + + 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) ? 2 : 1; + } + else + allowpoint = 2; + + + + if (stat.qualclass >= mp.starshapeclass && + mp.baseelnp != 4) + { + NgProfiler::RegionTimer reg1 (meshing3_timer_b); + // star-shaped domain removing + + grouppoints.SetSize (0); + groupfaces.SetSize (0); + grouppindex.SetSize (0); + groupfindex.SetSize (0); + + adfront -> GetGroup (findex[0], grouppoints, groupfaces, + grouppindex, groupfindex); + + bool onlytri = 1; + for (i = 0; i < groupfaces.Size(); i++) + if (groupfaces[i].GetNP() != 3) + onlytri = 0; + + if (onlytri && groupfaces.Size() <= 20 + 2*stat.qualclass && + 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; + + bool impossible = 1; + + for (rotind = 1; rotind <= locfaces[0].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) + { + //if(loktestmode) + // (*testout) << "plainpoints.Get(i).Z() = " << plainpoints.Get(i).Z() << " > 0" << endl; + allowpoint.Elem(i) = 0; + } + } + + 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; + } + + NgProfiler::StartTimer (meshing3_timer_c); + + found = ApplyRules (plainpoints, allowpoint, + locfaces, locfacesplit, connectedpairs, + locelements, delfaces, + stat.qualclass, mp.sloppy, rotind, err); + + if (found >= 0) impossible = 0; + if (found < 0) found = 0; + + + NgProfiler::StopTimer (meshing3_timer_c); + + if (!found) loktestmode = 0; + + NgProfiler::RegionTimer reg2 (meshing3_timer_d); + + if (loktestmode) + { + (*testout) << "plainpoints = " << endl << plainpoints << endl; + (*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)++; + + + // 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) << "found is active, 3" << 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 (loktestmode) + { + (*testout) << "apply rule" << 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)); + if (impossible && mp.check_impossible) + { + (*testout) << "skip face since it is impossible" << endl; + for (j = 0; j < 100; j++) + adfront->IncrementClass (findex.Get(1)); + } + } + + locelements.SetSize (0); + delpoints.SetSize(0); + delfaces.SetSize(0); + + if (stat.qualclass >= mp.giveuptol) + break; + } + + PrintMessage (5, ""); // line feed after statistics + + 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(0), i1, i2, i3, j1, j2, j3; + int n1, n2, n3, n, min1, min2, min3, max1, max2, max3; + int changed, filled; + double xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0); + 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 inner(n); + ARRAY 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 MiniElement2d & 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(0), pi2(0), pi3(0), pi4(0); + + 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) + { + MiniElement2d 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 npoints; + + adfront -> CreateTrees(); + + Point3d mpmin, mpmax; + // mesh.GetBox (mpmin, mpmax); + bool firstp = 1; + + double maxh = 0; + for (i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & 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; + //(*testout) << "reducing maxh to " << maxh << " because of " << p1 << " and " << p2 << endl; + } + + 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; + //(*testout) << "reducing maxh to " << maxh << " because of mp.maxh" << endl; + } + + int changed; + do + { + mesh.LocalHFunction().ClearFlags(); + + for (i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & 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 MiniElement2d & 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 MiniElement2d & 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/libsrc/meshing/meshing3.hpp b/libsrc/meshing/meshing3.hpp new file mode 100644 index 00000000..3a4732d1 --- /dev/null +++ b/libsrc/meshing/meshing3.hpp @@ -0,0 +1,130 @@ +#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 rules; + /// counts how often a rule is used + ARRAY ruleused, canuse, foundmap; + /// describes, why a rule is not applied + ARRAY 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 & lpoints, ARRAY & allowpoint, + ARRAY & lfaces, INDEX lfacesplit, + INDEX_2_HASHTABLE & connectedpairs, + ARRAY & elements, + ARRAY & delfaces, int tolerance, + double sloppy, int rotind1, + float & retminerr); + + /// + PointIndex AddPoint (const Point3d & p, PointIndex globind); + /// + void AddBoundaryElement (const Element2d & elem); + /// + void AddBoundaryElement (const MiniElement2d & 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, int domainnr, 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 +extern int FindInnerPoint (POINTARRAY & grouppoints, + FACEARRAY & groupfaces, + Point3d & p); + +*/ + + + + + +#endif + + + + + + + + + + diff --git a/libsrc/meshing/meshtool.cpp b/libsrc/meshing/meshtool.cpp new file mode 100644 index 00000000..c6ac5d65 --- /dev/null +++ b/libsrc/meshing/meshtool.cpp @@ -0,0 +1,1002 @@ +#include + +#include "meshing.hpp" +#include +#include + +namespace netgen +{ + + int CheckSurfaceMesh (const Mesh & mesh) + { + PrintMessage (3, "Check Surface mesh"); + + int nf = mesh.GetNSE(); + INDEX_2_HASHTABLE 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 Point<3> *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 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; + + if (teterrpow == 2) + return err*err; + return pow (err, teterrpow); + } + + + double CalcTetBadnessGrad (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, double h, + int pi, Vec<3> & 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; + + /* + Vec3d gradll; + gradll = v1+v2+v3; + gradll *= -2; + */ + + 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) + { + /* + Vec3d gradll1 (*pp2, *pp1); + Vec3d gradll2 (*pp3, *pp1); + Vec3d gradll3 (*pp4, *pp1); + gradll1 *= 2; + gradll2 *= 2; + gradll3 *= 2; + */ + 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; + if (teterrpow == 2) + { + errpow = err*err; + grad = (2 * err) * graderr; + } + else + { + 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 & 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 & points, + const ARRAY & 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 * inclass) + { + int ncl = 20; + signed int cl; + ARRAY 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)(0) << " " + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << "\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)(0) << " " + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << 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 * 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)(0) << " " + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << 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 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 (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 domainnr) + { + int i, j, k; + + mesh.FindOpenElements(domainnr); + int np = mesh.GetNP(); + + BitArrayChar ppoints(np); + + // int ndom = mesh.GetNDomains(); + + PrintMessage (3, "Elements before Remove: ", mesh.GetNE()); + // for (k = 1; k <= ndom; k++) + k = domainnr; + { + 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/libsrc/meshing/meshtool.hpp b/libsrc/meshing/meshtool.hpp new file mode 100644 index 00000000..9ffaad11 --- /dev/null +++ b/libsrc/meshing/meshtool.hpp @@ -0,0 +1,83 @@ +#ifndef FILE_MESHTOOL +#define FILE_MESHTOOL + + +/// +extern void MeshQuality2d (const Mesh & mesh); + +/// +extern void MeshQuality3d (const Mesh & mesh, + ARRAY * 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 * splines, + ostream & outfile); +*/ + +class Surface; +/// +extern void SaveVolumeMesh ( + const ARRAY & points, + const ARRAY & elements, + const ARRAY & volelements, + const ARRAY & 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, + Vec<3> & grad); + + +/** Calculates volume of an element. + The volume of the tetrahedron el is computed + */ +// extern double CalcVolume (const ARRAY & 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 & points, + const ARRAY & elements); + +/// +extern int CheckSurfaceMesh (const Mesh & mesh); + +/// +extern int CheckSurfaceMesh2 (const Mesh & mesh); +/// +extern int CheckMesh3D (const Mesh & mesh); +/// +extern void RemoveProblem (Mesh & mesh, int domainnr); +#endif diff --git a/libsrc/meshing/meshtype.cpp b/libsrc/meshing/meshtype.cpp new file mode 100644 index 00000000..4ef1bdd2 --- /dev/null +++ b/libsrc/meshing/meshtype.cpp @@ -0,0 +1,2669 @@ +#include + +#include "meshing.hpp" + +namespace netgen +{ + + + ostream & operator<<(ostream & s, const MeshPoint & pt) + { + s << Point<3> (pt); + return s; + } + + /* + 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; + */ + + bcname = 0; + } + + Segment::Segment (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(), + surfnr1(other.surfnr1), + surfnr2(other.surfnr2), + epgeominfo(), + pmid(other.pmid), + meshdocval(other.meshdocval), + hp_elnr(other.hp_elnr) + { + geominfo[0] = other.geominfo[0]; + geominfo[1] = other.geominfo[1]; + epgeominfo[0] = other.epgeominfo[0]; + epgeominfo[1] = other.epgeominfo[1]; + bcname = other.bcname; + } + + Segment& Segment::operator=(const Segment & other) + { + if (&other != this) + { + 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; + hp_elnr = other.hp_elnr; + bcname = other.bcname; + } + + return *this; + } + + + ostream & operator<<(ostream & s, const Segment & seg) + { + s << seg.p1 << "(gi=" << seg.geominfo[0].trignum << ") - " + << seg.p2 << "(gi=" << seg.geominfo[1].trignum << ")" + << " domin = " << seg.domin << ", domout = " << seg.domout + << " si = " << seg.si << ", edgenr = " << seg.edgenr; + return s; + } + + + Element2d :: Element2d () + { + for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) + { + pnum[i] = 0; + geominfo[i].trignum = 0; + } + np = 3; + index = 0; + badel = 0; + deleted = 0; + typ = TRIG; + orderx = ordery = 1; + refflag = 1; + strongrefflag = false; +#ifdef PARALLEL + isghost = 0; +#endif + } + + + 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; + } + orderx = ordery = 1; + refflag = 1; + strongrefflag = false; +#ifdef PARALLEL + isghost = 0; +#endif + } + + 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; + orderx = ordery = 1; + refflag = 1; + strongrefflag = false; +#ifdef PARALLEL + isghost = 0; +#endif + + } + + + + 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; + strongrefflag = false; + deleted = 0; + orderx = ordery = 1; + +#ifdef PARALLEL + isghost = 0; +#endif + +} + +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; + strongrefflag = false; + deleted = 0; + orderx = ordery = 1; + +#ifdef PARALLEL + isghost = 0; +#endif +} + + +/* +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])); +} + +bool Element2d :: operator==(const Element2d & el2) const +{ + bool retval = (el2.GetNP() == np); + for(int i= 0; retval && i ipdtrig; +ARRAY 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 & 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 :: GetShapeNew (const Point<2> & p, FlatVector & shape) const +{ + switch (typ) + { + case TRIG: + { + shape(0) = p(0); + shape(1) = p(1); + shape(2) = 1-p(0)-p(1); + break; + } + + case QUAD: + { + shape(0) = (1-p(0))*(1-p(1)); + shape(1) = p(0) *(1-p(1)); + shape(2) = p(0) * p(1) ; + shape(3) = (1-p(0))* p(1) ; + break; + } + } +} + + + + + + + + + +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 :: +GetDShapeNew (const Point<2> & p, MatrixFixWidth<2> & dshape) const +{ + switch (typ) + { + case TRIG: + { + dshape = 0; + dshape(0,0) = 1; + dshape(1,1) = 1; + dshape(2,0) = -1; + dshape(2,1) = -1; + break; + } + case QUAD: + { + dshape(0,0) = -(1-p(1)); + dshape(0,1) = -(1-p(0)); + + dshape(1,0) = (1-p(1)); + dshape(1,1) = -p(0); + + dshape(2,0) = p(1); + dshape(2,1) = p(0); + + dshape(3,0) = -p(1); + dshape(3,1) = (1-p(0)); + break; + } + } +} + + + + + +void Element2d :: +GetPointMatrix (const ARRAY & 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 & 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 & 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 Vec<3> & n) const +{ + int i, j; + int nip = GetNIP(); + static DenseMatrix trans(2,2); + static DenseMatrix pmat; + + pmat.SetSize (2, GetNP()); + + Vec<3> t1, t2; + t1 = n.GetNormal(); + t2 = Cross (n, t1); + + for (i = 1; i <= GetNP(); i++) + { + Point3d p = points.Get(PNum(i)); + pmat.Elem(1, i) = p.X() * t1(0) + p.Y() * t1(1) + p.Z() * t1(2); + pmat.Elem(2, i) = p.X() * t2(0) + p.Y() * t2(1) + p.Z() * t2(2); + } + + 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(0) = hp.X(); + ipd->p(1) = hp.Y(); + ipd->p(2) = 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.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + orderx = ordery = orderz = 1; + +#ifdef PARALLEL + partitionNumber = -1; + isghost = 0; +#endif + +} + + +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.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 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; + } + orderx = ordery = orderz = 1; + +#ifdef PARALLEL + isghost = 0; +#endif +} + +void Element :: SetOrder (const int aorder) + { + orderx = aorder; + ordery = aorder; + orderz = aorder; + } + + +void Element :: SetOrder (const int ox, const int oy, const int oz) +{ + orderx = ox; + ordery = oy; + orderz = oz; +} + + +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.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + orderx = ordery = orderz = 1; + +#ifdef PARALLEL + isghost = 0; +#endif +} + + + + + +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; + orderx = el2.orderx; + ordery = el2.ordery; + orderz = el2.orderz; + hp_elnr = el2.hp_elnr; + flags = el2.flags; + 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 +{ + Vec<3> v1 = points.Get(PNum(2)) - points.Get(PNum(1)); + Vec<3> v2 = points.Get(PNum(3)) - points.Get(PNum(1)); + Vec<3> 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 tet10faces[][7] = + { { 3, 2, 3, 4, 10, 9, 8 }, + { 3, 3, 1, 4, 7, 10, 6 }, + { 3, 1, 2, 4, 9, 7, 5 }, + { 3, 2, 1, 3, 6, 8, 5 } }; + + 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 + { + face.SetType(TRIG); + for (int j = 1; j <= 3; j++) + face.PNum(j) = PNum(tetfaces[i-1][j]); + break; + } + + case 10: // tet10 + { + face.SetType(TRIG6); + for (int j = 1; j <= 6; j++) + face.PNum(j) = PNum(tet10faces[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 & 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 & 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; + } + } +} + +bool Element :: operator==(const Element & el2) const +{ + bool retval = (el2.GetNP() == np); + for(int i= 0; retval && i & 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 }, + { 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])); +} +#endif + + + + + + +void Element :: GetNodesLocalNew (ARRAY > & 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 (Point<3> (pp[i][0], pp[i][1], pp[i][2])); +} + + + + + + + + + + + + + + + + + +void Element :: GetSurfaceTriangles (ARRAY & surftrigs) const +{ + static int tet4trigs[][3] = + { { 2, 3, 4 }, + { 3, 1, 4 }, + { 1, 2, 4 }, + { 2, 1, 3 } }; + + static int tet10trigs[][3] = + { { 2, 8, 9 }, { 3, 10, 8}, { 4, 9, 10 }, { 9, 8, 10 }, + { 3, 6, 10 }, { 1, 7, 6 }, { 4, 10, 7 }, { 6, 7, 10 }, + { 1, 5, 7 }, { 2, 9, 5 }, { 4, 7, 9 }, { 5, 9, 7 }, + { 1, 6, 5 }, { 2, 5, 8 }, { 3, 8, 6 }, { 5, 6, 8 } + }; + + 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 = 16; + 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(TRIG); + 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< AutoPtr < IntegrationPointData > > ipdtet; +ARRAY< AutoPtr < 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, Point<3> & 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(0) = pp[0]; + p(1) = pp[1]; + p(2) = 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); + + Point<3> 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 Point<3> & hp, Vector & shape) const +{ + Point3d p = hp; + + 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 TET10: + { + double lam1 = p(0); + double lam2 = p(1); + double lam3 = p(2); + double lam4 = 1-p(0)-p(1)-p(2); + + shape(0) = 2 * lam1 * (lam1-0.5); + shape(1) = 2 * lam2 * (lam2-0.5); + shape(2) = 2 * lam3 * (lam3-0.5); + shape(3) = 2 * lam4 * (lam4-0.5); + + shape(4) = 4 * lam1 * lam2; + shape(5) = 4 * lam1 * lam3; + shape(6) = 4 * lam1 * lam4; + shape(7) = 4 * lam2 * lam3; + shape(8) = 4 * lam2 * lam4; + shape(9) = 4 * lam3 * lam4; + + 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 Point<3> & hp, DenseMatrix & dshape) const +{ + Point3d p = hp; + + 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, Vec<3> & 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(j-1); + + + + 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; +} + +double Element :: +CalcJacobianBadnessGradient (const T_POINTS & points, + int pi, Vec<3> & grad) 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) = 1.; + + + double err = 0; + + double dfrob[3]; + + grad = 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); + + for(k = 0; k<3; k++) + { + dfrob[k] = 0; + for (j = 1; j <= 3; j++) + dfrob[k] += trans.Get(k+1,j) * dtrans.Get(k+1,j); + dfrob[k] = dfrob[k] / (3.*frob); + } + + frob /= 3; + + double det = trans.Det(); + double ddet[3]; // = 0; + + for(k=1; k<=3; k++) + { + int km1 = (k > 1) ? (k-1) : 3; + int kp1 = (k < 3) ? (k+1) : 1; + ddet[k-1] = 0; + for(j=1; j<=3; j++) + { + int jm1 = (j > 1) ? (j-1) : 3; + int jp1 = (j < 3) ? (j+1) : 1; + + ddet[k-1] += (-1.)* dtrans.Get(k,j) * ( trans.Get(km1,jm1)*trans.Get(kp1,jp1) - + trans.Get(km1,jp1)*trans.Get(kp1,jm1) ); + } + } + + + det *= -1; + + if (det <= 0) + err += 1e12; + else + { + err += frob * frob * frob / det; + double fac = (frob * frob)/(det * det); + for(j=0; j<3; j++) + grad(j) += fac * (3 * dfrob[j] * det - frob * ddet[j]); + } + } + + err /= nip; + grad *= 1./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)); + } + + switch (GetType()) + { + case TET: ipdtet.SetSize(GetNIP()); break; + case TET10: ipdtet10.SetSize(GetNIP()); break; + } + + + for (int 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.Elem(i).Reset(ipd); break; + case TET10: ipdtet10.Elem(i).Reset(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; + bcname = 0; + firstelement = -1; +} + +FaceDescriptor :: FaceDescriptor(const FaceDescriptor& other) + : surfnr(other.surfnr), domin(other.domin), domout(other.domout), + tlosurf(other.tlosurf), bcprop(other.bcprop), bcname(other.bcname), + domin_singular(other.domin_singular), domout_singular(other.domout_singular) +{ + firstelement = -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.; + bcname = 0; + firstelement = -1; +} + +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.; + bcname = 0; + firstelement = -1; +} + +int FaceDescriptor :: SegmentFits (const Segment & seg) +{ + return + surfnr == seg.si && + domin == seg.domin+1 && + domout == seg.domout+1 && + tlosurf == seg.tlosurf+1; +} + + +string FaceDescriptor :: GetBCName () const +{ + if ( bcname ) + return *bcname; + else + return "default"; + +} + +/* +void FaceDescriptor :: SetBCName (string * bcn) +{ + bcname = bcn; +} +*/ + + +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(100); + identifiedpoints_nr = new INDEX_3_HASHTABLE(100); + maxidentnr = 0; +} + +Identifications :: ~Identifications () +{ + delete identifiedpoints; + delete identifiedpoints_nr; +} + +void Identifications :: Delete () +{ + delete identifiedpoints; + identifiedpoints = new INDEX_2_HASHTABLE(100); + delete identifiedpoints_nr; + identifiedpoints_nr = new INDEX_3_HASHTABLE(100); + maxidentnr = 0; +} + +void Identifications :: Add (PointIndex pi1, PointIndex pi2, int identnr) +{ + // (*testout) << "Identification::Add, pi1 = " << pi1 << ", pi2 = " << pi2 << ", identnr = " << identnr << endl; + INDEX_2 pair (pi1, pi2); + identifiedpoints->Set (pair, identnr); + + INDEX_3 tripl (pi1, pi2, identnr); + identifiedpoints_nr->Set (tripl, 1); + + if (identnr > maxidentnr) maxidentnr = identnr; + + if (identnr+1 > idpoints_table.Size()) + idpoints_table.ChangeSize (identnr+1); + idpoints_table.Add (identnr, pair); + + // 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; +} + +bool Identifications :: Get (PointIndex pi1, PointIndex pi2, int nr) const +{ + INDEX_3 tripl(pi1, pi2, nr); + if (identifiedpoints_nr->Used (tripl)) + return 1; + 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 & identmap, bool symmetric) const +{ + identmap.SetSize (mesh.GetNP()); + identmap = 0; + + if (identnr) + for (int i = 0; i < idpoints_table[identnr].Size(); i++) + { + INDEX_2 pair = idpoints_table[identnr][i]; + identmap[pair.I1()] = pair.I2(); + if(symmetric) + identmap[pair.I2()] = pair.I1(); + } + + else + { + cout << "getmap, identnr = " << identnr << endl; + + for (int i = 1; i <= identifiedpoints_nr->GetNBags(); i++) + for (int j = 1; j <= identifiedpoints_nr->GetBagSize(i); j++) + { + INDEX_3 i3; + int dummy; + identifiedpoints_nr->GetData (i, j, i3, dummy); + + if (i3.I3() == identnr || !identnr) + { + identmap.Elem(i3.I1()) = i3.I2(); + if(symmetric) + identmap.Elem(i3.I2()) = i3.I1(); + } + } + } + +} + + +void Identifications :: GetPairs (int identnr, + ARRAY & identpairs) const +{ + identpairs.SetSize(0); + + if (identnr == 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); + identpairs.Append (i2); + } + else + for (int i = 1; i <= identifiedpoints_nr->GetNBags(); i++) + for (int j = 1; j <= identifiedpoints_nr->GetBagSize(i); j++) + { + INDEX_3 i3; + int dummy; + identifiedpoints_nr->GetData (i, j, i3 , dummy); + + if (i3.I3() == identnr) + identpairs.Append (INDEX_2(i3.I1(), i3.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); + } + } +} + + +void Identifications :: Print (ostream & ost) const +{ + ost << "Identifications:" << endl; + ost << "pairs: " << endl << *identifiedpoints << endl; + ost << "pairs and nr: " << endl << *identifiedpoints_nr << endl; + ost << "table: " << endl << idpoints_table << endl; +} + + +MeshingParameters :: MeshingParameters () +{ + optimize3d = "cmdmustm"; + //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; + minh = 0; + meshsizefilename = NULL; + startinsurface = 0; + checkoverlap = 1; + checkoverlappingboundary = 1; + checkchartboundary = 1; + curvaturesafety = 2; + segmentsperedge = 1; + parthread = 0; + + elsizeweight = 0.2; + giveuptol2d = 200; + giveuptol = 10; + maxoutersteps = 10; + starshapeclass = 5; + baseelnp = 0; + sloppy = 1; + + badellimit = 175; + check_impossible = 0; + 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 + << " giveuptol2d = " << giveuptol2d << 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(meshsizefilename), other.meshsizefilename); + //const_cast(meshsizefilename) = other.meshsizefilename; //??? + startinsurface = other.startinsurface; + checkoverlap = other.checkoverlap; + checkoverlappingboundary = other.checkoverlappingboundary; + checkchartboundary = other.checkchartboundary; + curvaturesafety = other.curvaturesafety; + segmentsperedge = other.segmentsperedge; + parthread = other.parthread; + elsizeweight = other.elsizeweight; + giveuptol2d = other.giveuptol2d; + 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/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp new file mode 100644 index 00000000..339f764f --- /dev/null +++ b/libsrc/meshing/meshtype.hpp @@ -0,0 +1,1229 @@ +#ifndef MESHTYPE +#define MESHTYPE + + +/**************************************************************************/ +/* 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 }; + + + +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 << " " << gi.u << " " << gi.v); +} + +inline istream & operator>> (istream & ist, PointGeomInfo & gi) +{ + return (ist >> gi.trignum >> gi.u >> gi.v); +} + + + +#define MULTIPOINTGEOMINFO_MAX 100 +class MultiPointGeomInfo +{ + int cnt; + PointGeomInfo mgi[MULTIPOINTGEOMINFO_MAX]; +public: + MultiPointGeomInfo () { cnt = 0; } + int AddPointGeomInfo (const PointGeomInfo & gi); + void Init () { cnt = 0; } + void DeleteAll () { cnt = 0; } + + int GetNPGI () const { return cnt; } + const PointGeomInfo & GetPGI (int i) const { return mgi[i-1]; } +}; + + +class EdgePointGeomInfo +{ +public: + int edgenr; + int body; // for ACIS + double dist; // for 2d meshing + double u, v; // for OCC Meshing + +public: + EdgePointGeomInfo () + : edgenr(0), body(0), dist(0.0), u(0.0), v(0.0) { ; } + + + EdgePointGeomInfo & operator= (const EdgePointGeomInfo & gi2) + { + edgenr = gi2.edgenr; + body = gi2.body; + dist = gi2.dist; + u = gi2.u; v = gi2.v; + return *this; + } +}; + +inline ostream & operator<< (ostream & ost, const EdgePointGeomInfo & gi) +{ + ost << "epgi: edgnr=" << gi.edgenr << ", dist=" << gi.dist; + return ost; +} + + + + + +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 PointIndex(hi); } + PointIndex operator-- (int) { int hi = i; i--; return PointIndex(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. + */ +class MeshPoint : public Point<3> +{ + int layer; + double singular; // singular factor for hp-refinement + POINTTYPE type; + +#ifdef PARALLEL + bool isghost; +#endif + +public: + MeshPoint () : layer(1), singular(0.), type(INNERPOINT) +{ +#ifdef PARALLEL + isghost = 0; +#endif + ; +} + + MeshPoint (const Point<3> & ap, int alayer = 1, POINTTYPE apt = INNERPOINT) + : Point<3> (ap), layer(alayer), singular(0.),type(apt) + { +#ifdef PARALLEL + isghost = 0; +#endif + ; + } + + void SetPoint (const Point<3> & ap) + { + Point<3>::operator= (ap); + layer = 0; + singular = 0; +#ifdef PARALLEL + isghost = 0; +#endif + } + + int GetLayer() const { return layer; } + + POINTTYPE Type() const { return type; } + void SetType(POINTTYPE at) { type = at; } + + double Singularity() const { return singular; } + void Singularity(double s) { singular = s; } + bool IsSingular() const { return (singular != 0.0); } + +#ifdef PARALLEL + bool IsGhost () const { return isghost; } + void SetGhost ( bool aisghost ) { isghost = aisghost; } +#endif + +}; + +ostream & operator<<(ostream & s, const MeshPoint & pt); + + + + +typedef MoveableArray T_POINTS; +// typedef ARRAY 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 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 strongrefflag:1; + bool deleted:1; // element is deleted + + /// order for hp-FEM + unsigned int orderx:6; + unsigned int ordery:6; + +#ifdef PARALLEL + bool isghost; + int partitionNumber; +#endif + + /// a linked list for all segments in the same face + SurfaceElementIndex next; + +public: + /// + Element2d (); + /// + Element2d (int anp); + /// + 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 orderx; } + void SetOrder (int aorder) { orderx = ordery = aorder; } + + + void GetOrder (int & ox, int & oy) const { ox = orderx, oy =ordery;}; + void GetOrder (int & ox, int & oy, int & oz) const { ox = orderx; oy = ordery; oz=0; } + void SetOrder (int ox, int oy, int /* oz */) { orderx = ox; ordery = oy;} + void SetOrder (int ox, int oy) { orderx = ox; ordery = oy;} + + + /// + 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 & 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; + void GetShapeNew (const Point<2> & p, class FlatVector & shape) const; + /// matrix 2 * np + void GetDShape (const Point2d & p, class DenseMatrix & dshape) const; + void GetDShapeNew (const Point<2> & p, class MatrixFixWidth<2> & dshape) const; + /// matrix 2 * np + void GetPointMatrix (const ARRAY & points, + class DenseMatrix & pmat) const; + + void ComputeIntegrationPointData () const; + + + double CalcJacobianBadness (const ARRAY & points) const; + double CalcJacobianBadness (const T_POINTS & points, + const Vec<3> & n) const; + double CalcJacobianBadnessDirDeriv (const ARRAY & 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; } + + void SetStrongRefinementFlag (bool rflag = 1) + { strongrefflag = rflag; } + bool TestStrongRefinementFlag () const + { return strongrefflag; } + + + bool operator==(const Element2d & el2) const; + + int HasFace(const Element2d& el) const; + /// + int meshdocval; + /// + int hp_elnr; + +#ifdef PARALLEL + bool IsGhost () const { return isghost; } + void SetGhost ( bool aisghost ) { isghost = aisghost; } + + // by JS, only for 2D meshes ???? + int GetPartition () const { return partitionNumber; } + void SetPartition (int nr) { partitionNumber = nr; }; +#endif + +}; + + + + +class IntegrationPointData +{ +public: + Point<3> 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 strongrefflag:1; + bool deleted:1; // element is deleted, will be removed from array + bool fixed:1; // don't change element in optimization + }; + + /// sub-domain index + short int index; + /// order for hp-FEM + unsigned int orderx:6; + unsigned int ordery:6; + unsigned int orderz:6; + /* unsigned int levelx:6; + unsigned int levely:6; + unsigned int levelz:6; */ + /// stored shape-badness of element + float badness; + +#ifdef PARALLEL + /// number of partition for parallel computation + int partitionNumber; + bool isghost; +#endif + +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: + case TET10: + return 4; + case PRISM12: + case PRISM: + return 6; + case PYRAMID: + return 5; + case HEX: + return 8; + default: +#ifdef DEBUG + PrintSysError ("Element3d::GetNV not implemented for typ ", typ) +#endif + ; + } + return np; + } + + bool operator==(const Element & el2) const; + + // 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 orderx; } + void SetOrder (const int aorder) ; + + void GetOrder (int & ox, int & oy, int & oz) const { ox = orderx; oy = ordery; oz = orderz; } + void SetOrder (const int ox, const int oy, const int oz); + // void GetLevel (int & ox, int & oy, int & oz) const { ox = levelx; oy = levely; oz = levelz; } + // void SetLevel (int ox, int oy, int oz) { levelx = ox; levely = oy; levelz = oz; } + + + /// + 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 & locels) const; + /// split into 4 node tets, local point nrs + void GetTetsLocal (ARRAY & locels) const; + /// returns coordinates of nodes + // void GetNodesLocal (ARRAY > & points) const; + void GetNodesLocalNew (ARRAY > & points) const; + + /// split surface into 3 node trigs + void GetSurfaceTriangles (ARRAY & surftrigs) const; + + + /// get number of 'integration points' + int GetNIP () const; + void GetIntegrationPoint (int ip, Point<3> & 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 Point<3> & p, class Vector & shape) const; + void GetShapeNew (const Point<3> & p, class FlatVector & shape) const; + /// matrix 2 * np + void GetDShape (const Point<3> & 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, Vec<3> & dir, double & dd) const; + double CalcJacobianBadnessGradient (const T_POINTS & points, + int pi, Vec<3> & grad) const; + + /// + friend ostream & operator<<(ostream & s, const Element & el); + + void SetRefinementFlag (bool rflag = 1) + { flags.refflag = rflag; } + int TestRefinementFlag () const + { return flags.refflag; } + + void SetStrongRefinementFlag (bool rflag = 1) + { flags.strongrefflag = rflag; } + int TestStrongRefinementFlag () const + { return flags.strongrefflag; } + + 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; + } + +#ifdef PARALLEL + int GetPartition () const { return partitionNumber; } + void SetPartition (int nr) { partitionNumber = nr; }; +#endif + + int hp_elnr; + +#ifdef PARALLEL + bool IsGhost () const { return isghost; } + + void SetGhost ( const bool aisghost ) { isghost = aisghost; } +#endif + + friend class Mesh; +}; + + +class Segment; +ostream & operator<<(ostream & s, const Segment & seg); + + +/** + Edge segment. + */ +class Segment +{ +public: + /// + Segment(); + Segment (const Segment& other); + + ~Segment() + { ; } + + friend ostream & operator<<(ostream & s, const Segment & seg); + + /// point index 1 + PointIndex p1; + /// point index 2 + PointIndex p2; + /// edge nr + int edgenr; + /// + double singedge_left; + double singedge_right; + + /// 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; + +private: + string* bcname; + +public: + 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; + + void SetBCName ( string * abcname ) + { + bcname = abcname; + } + + string * BCNamePtr () + { return bcname; } + + const string * BCNamePtr () const + { return bcname; } + + string GetBCName () const + { + if (! bcname ) + { + return "default"; + } + return *bcname; + } + + +}; + + +// 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; + + /// + string * bcname; + /// root of linked list + SurfaceElementIndex firstelement; + +public: + /// + double domin_singular; + double domout_singular; +public: + FaceDescriptor(); + FaceDescriptor(int surfnri, int domini, int domouti, int tlosurfi); + FaceDescriptor(const Segment & seg); + FaceDescriptor(const FaceDescriptor& other); + ~FaceDescriptor() { ; } + + 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; } + string GetBCName () const; + // string * BCNamePtr () { return bcname; } + // const string * BCNamePtr () const { return bcname; } + void SetSurfNr (int sn) { surfnr = sn; } + void SetDomainIn (int di) { domin = di; } + void SetDomainOut (int dom) { domout = dom; } + void SetBCProperty (int bc) { bcprop = bc; } + void SetBCName (string * bcn) { bcname = bcn; } + + friend ostream & operator<<(ostream & s, const FaceDescriptor & fd); + friend class Mesh; +}; + + + + + + +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 + */ + const 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 + **/ + const 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; + /// minimal mesh size + double minh; + /// file for meshsize + const char * meshsizefilename; + /// start surfacemeshing from everywhere in surface + int startinsurface; + /// check overlapping surfaces (debug) + int checkoverlap; + /// check overlapping surface mesh before volume meshing + int checkoverlappingboundary; + /// 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, 2d meshing + int giveuptol2d; + /// give up quality class, 3d meshing + 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; + + bool check_impossible; + + /// + int secondorder; + /// high order element curvature + int elementorder; + /// quad-dominated surface meshing + int quad; + /// + int inverttets; + /// + int inverttrigs; + /// + int autozrefine; + /// + 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 +{ +public: + enum ID_TYPE { UNDEFINED = 1, PERIODIC = 2, CLOSESURFACES = 3, CLOSEEDGES = 4}; + + +private: + class Mesh & mesh; + + /// identify points (thin layers, periodic b.c.) + INDEX_2_HASHTABLE * identifiedpoints; + + /// the same, with info about the id-nr + INDEX_3_HASHTABLE * identifiedpoints_nr; + + /// sorted by identification nr + TABLE idpoints_table; + + ARRAY type; + + /// number of identifications (or, actually used identifications ?) + int maxidentnr; + +public: + /// + Identifications (class 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; + + bool Get (PointIndex pi1, PointIndex pi2, int identnr) const; + bool GetSymmetric (PointIndex pi1, PointIndex pi2, int identnr) const; + + /// + INDEX_2_HASHTABLE & 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 & identmap, bool symmetric = false) const; + /// + ID_TYPE GetType(int identnr) const + { + if(identnr <= type.Size()) + return type[identnr-1]; + else + return UNDEFINED; + } + void SetType(int identnr, ID_TYPE t) + { + while(type.Size() < identnr) + type.Append(UNDEFINED); + type[identnr-1] = t; + } + + /// + void GetPairs (int identnr, ARRAY & identpairs) const; + /// + int GetMaxNr () const { return maxidentnr; } + + /// remove secondorder + void SetMaxPointNr (int maxpnum); + + void Print (ostream & ost) const; +}; + + + + + + + +#endif + diff --git a/libsrc/meshing/msghandler.cpp b/libsrc/meshing/msghandler.cpp new file mode 100644 index 00000000..88e30fb1 --- /dev/null +++ b/libsrc/meshing/msghandler.cpp @@ -0,0 +1,226 @@ +//File for handling warnings, errors, messages +#include + +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 msgstatus_stack(0); +static ARRAY threadpercent_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); + threadpercent_stack.SetSize(0); + + // multithread.task = ""; + multithread.percent = 100.; +} + +void PushStatus(const MyStr& s) +{ + msgstatus_stack.Append(new MyStr (s)); + SetStatMsg(s); + threadpercent_stack.Append(0); +} + +void PushStatusF(const MyStr& s) +{ + msgstatus_stack.Append(new MyStr (s)); + SetStatMsg(s); + threadpercent_stack.Append(0); + PrintFnStart(s); +} + +void PopStatus() +{ + if (msgstatus_stack.Size()) + { + if (msgstatus_stack.Size() > 1) + SetStatMsg (*msgstatus_stack.Last()); + else + SetStatMsg (""); + delete msgstatus_stack.Last(); + msgstatus_stack.DeleteLast(); + threadpercent_stack.DeleteLast(); + if(threadpercent_stack.Size() > 0) + multithread.percent = threadpercent_stack.Last(); + else + multithread.percent = 100.; + } + 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; + if(threadpercent_stack.Size() > 0) + threadpercent_stack.Last() = percent; +} + + +void GetStatus(MyStr & s, double & percentage) +{ + if(threadpercent_stack.Size() > 0) + percentage = threadpercent_stack.Last(); + else + percentage = multithread.percent; + + if ( msgstatus_stack.Size() ) + s = *msgstatus_stack.Last(); + else + s = "idle"; +} + + +#ifdef SMALLLIB +#define SMALLLIBORNOTCL +#endif +#ifdef NOTCL +#define SMALLLIBORNOTCL +#endif + +#ifdef SMALLLIBORNOTCL +void Ng_PrintDest(const char * s){cout << s < +#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 & 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 left, right, allleft, allright; + + 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 (int i = 1; i <= transfreezone.Size(); i++) + { + if (freesetinequ.Get(i, 1) * p1.X() + freesetinequ.Get(i, 2) * p1.Y() + + freesetinequ.Get(i, 3) > -1e-8 && // -1e-6 + freesetinequ.Get(i, 1) * p2.X() + freesetinequ.Get(i, 2) * p2.Y() + + freesetinequ.Get(i, 3) > -1e-8 // -1e-6 + ) return 0; + } + + double nx = (p2.Y() - p1.Y()); + double ny = -(p2.X() - p1.X()); + double nl = sqrt (nx * nx + ny * ny); + if (nl > 1e-8) + { + nx /= nl; + ny /= nl; + double c = - (p1.X() * nx + p1.Y() * ny); + + allleft = 1; + allright = 1; + + for (int 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++) + { + const bool counterclockwise = CCW (transfreezone.Get(i), + transfreezone.Get(i % n + 1), + transfreezone.Get( (i+1) % n + 1 ), + 1e-7); + //(*testout) << "ccw " << counterclockwise << endl << " p1 " << transfreezone.Get(i) << " p2 " << transfreezone.Get(i % n + 1) + // << " p3 " << transfreezone.Get( (i+1) % n + 1 ) << endl; + if (!counterclockwise ) + 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 * ltf = &linetolerances.Get(li); + return ltf->f1 * dx * dx + ltf->f2 * dx * dy + ltf->f3 * dy * dy; +} + + + + +/* +int GetNRules () + { + return rules.Size(); + } +*/ + + + + + + + + + + + +} diff --git a/libsrc/meshing/netrule3.cpp b/libsrc/meshing/netrule3.cpp new file mode 100644 index 00000000..2b7bdfd9 --- /dev/null +++ b/libsrc/meshing/netrule3.cpp @@ -0,0 +1,1140 @@ +#include +#include "meshing.hpp" + +// #define MARK +// #include + + +namespace netgen +{ + + +vnetrule :: vnetrule () +{ + name = new char[1]; + name[0] = char(0); + 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 & 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 & freeset = *freesets.Get(fs); + const ARRAY & freesetedges = *freeedges.Get(fs); + // const ARRAY & 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 & 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 & pi, int newone) +{ + int fs; + int infreeset, cannot = 0; + + + static ARRAY 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 & 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 & 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 activefaces; + int isin; + + + // MARK(triinfz); + + ARRAY & 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 lambda1 = rs1 * vii22 - rs2 * vii12; + double lambda2 = rs2 * vii11 - rs1 * vii12; + + if (fabs (lambda1) > fabs (lambda2)) + { + if (lambda1 < 0) + an *= -1; + } + else + { + if (lambda2 < 0) + an *= -1; + } + + + if (lambda1 * lambda2 < 0 && 0) + { + if (fabs (lambda1) > 1e-14 && fabs (lambda2) > 1e-14) + { + // (*mycout) << "lambda1 lambda2 < 0" << endl; + (*testout) << "lambdai 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) << "lambdai = " << lambda1 << ", " << lambda2 << 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 lambda1 = rs1 * vii22 - rs2 * vii12; + double lambda2 = rs2 * vii11 - rs1 * vii12; + + // (*testout) << "lambda1, lambda2 = " << lambda1 << ", " << lambda2 << endl; + + + if (fabs (lambda1) > fabs (lambda2)) + { + if (lambda1 < 0) + an *= -1; + } + else + { + if (lambda2 < 0) + an *= -1; + } + + + if (lambda1 * lambda2 < 0) + { + if (fabs (lambda1) > 1e-14 && fabs (lambda2) > 1e-14) + { + // (*mycout) << "lambda1 lambda2 < 0" << endl; + (*testout) << "lambdai 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) << "lambdai = " << lambda1 << ", " << lambda2 << 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 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 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 & pi, int newone) +{ + int fs; + int infreeset, cannot = 0; + + + static ARRAY 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 & 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 & 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 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 cntpused(points.Size()); + ARRAY edge1, edge2; + ARRAY 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/libsrc/meshing/parser2.cpp b/libsrc/meshing/parser2.cpp new file mode 100644 index 00000000..eb502cfe --- /dev/null +++ b/libsrc/meshing/parser2.cpp @@ -0,0 +1,603 @@ +#include +#include "meshing.hpp" + +#ifdef WIN32 +#define COMMASIGN ':' +#else +#define COMMASIGN ',' +#endif + + +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 == COMMASIGN) + 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); + //(*testout) << "name " << name << endl; + // (*mycout) << "Rule " << name << " found." << endl; + + do + { + ist >> buf; + + //(*testout) << "buf " << buf << endl; + + 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; // ')' + + + //(*testout) << "read line " << lin.I1() << " " << lin.I2() << endl; + 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; + + //(*testout) << "mapl1" << endl; + ist >> ch; + while (ch != ';') + { + //(*testout) << "working on character \""<> 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' + //(*testout) << "read del" << endl; + } + + ist >> ch; + //(*testout) << "read character \""<> ch; + //(*testout) << "read next character \""<> 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 == COMMASIGN) + { + ist >> elements.Last().PNum(2); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + ist >> elements.Last().PNum(3); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + 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); + + //(*testout) << "loadr1" << endl; + + 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()); + + + //(*testout) << "loadr2" << endl; + + { + char ok; + int minn; + ARRAY 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; + + //(*testout) << "loadr3" << endl; + 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); + //(*testout) << "loadr4" << endl; + + 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)); + } + } + //(*testout) << "loadr5" << endl; + + 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 (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); + } + + //(*testout) << "loadr6" << endl; +} + + + + +extern const char * triarules[]; +extern const char * quadrules[]; + +void Meshing2 :: LoadRules (const char * filename) +{ + char buf[256]; + istream * ist; + //char *tr1 = NULL; + string tr1; + + /* + 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"); + } + + size_t len = 0; + while (*hcp) + { + // (*testout) << "POS2 *hcp " << *hcp << endl; + len += strlen (*hcp); + hcp++; + } + //tr1 = new char[len+1]; + //tr1[0] = 0; + tr1.reserve(len+1); + + + if (!mparam.quad) + hcp = triarules; + else + hcp = quadrules; + + + //char * tt1 = tr1; + while (*hcp) + { + //strcat (tt1, *hcp); + //tt1 += strlen (*hcp); + tr1.append(*hcp); + hcp++; + } + +#ifdef WIN32 + // VC++ 2005 workaround + for(string::size_type i=0; igood()) + { + 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) + { + //(*testout) << "found rule" << endl; + netrule * rule = new netrule; + //(*testout) << "fr1" << endl; + rule -> LoadRule(*ist); + //(*testout) << "fr2" << endl; + + rules.Append (rule); + } + //(*testout) << "loop" << endl; + } + //(*testout) << "POS3" << endl; + + delete ist; + //delete [] tr1; +} + +} diff --git a/libsrc/meshing/parser3.cpp b/libsrc/meshing/parser3.cpp new file mode 100644 index 00000000..382ae9df --- /dev/null +++ b/libsrc/meshing/parser3.cpp @@ -0,0 +1,1019 @@ +#include +#include "meshing.hpp" + +#ifdef WIN32 +#define COMMASIGN ':' +#else +#define COMMASIGN ',' +#endif + + +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 == COMMASIGN) + ist >> ch; + } +} + + + + + +int vnetrule :: NeighbourTrianglePoint (const threeint & t1, const threeint & t2) const +{ + ARRAY tr1(3); + ARRAY 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); + + 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, "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 == COMMASIGN) + { + 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 == COMMASIGN) + { + 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 k, nfp; + + 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 k, nfp; + 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); + + 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 == COMMASIGN) + { + // elements.Last().SetNP(2); + ist >> elements.Last().PNum(2); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(3); + ist >> elements.Last().PNum(3); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(4); + elements.Last().SetType(TET); + ist >> elements.Last().PNum(4); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(5); + elements.Last().SetType(PYRAMID); + ist >> elements.Last().PNum(5); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // 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); + 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); + + ARRAY & freeset = *freesets.Elem(fs); + ARRAY & 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)); + } + + + { + int minn; + // ARRAY 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 <= edges.Size(); i++) + { + int pi1 = edges.Get(i).i1; + int pi2 = edges.Get(i).i2; + + 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; + } + } + + + for (i = 1; i <= elements.Size(); i++) + if (elements.Get(i).GetNP() == 6) // prism rule + { + 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); + + 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)); + } + + // (*testout) << "rule " << name << ", pnear = " << pnearness << endl; + } + + + //Table of edges: + for (fs = 1; fs <= freesets.Size(); fs++) + { + freeedges.Append (new ARRAY); + + // ARRAY & freeset = *freesets.Get(fs); + ARRAY & freesetedges = *freeedges.Last(); + ARRAY & 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 ed(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)) + { + ed.I(1) = f1.I(f11); + ed.I(2) = f1.I(f12); + } + // (*testout) << "ed = " << ed.I(1) << "-" << ed.I(2) << endl; + // (*testout) << "ind = " << ind << " ed = " << ed << endl; + for (int eli = 1; eli <= GetNOldF(); eli++) + { + if (GetNP(eli) == 4) + { + for (int elr = 1; elr <= 4; elr++) + { + if (GetPointNrMod (eli, elr) == ed.I(1) && + GetPointNrMod (eli, elr+2) == ed.I(2)) + { + /* + (*testout) << "ed is diagonal of rectangle" << endl; + (*testout) << "ed = " << ed.I(1) << "-" << ed.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; + size_t 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++; + } + + +#ifdef WIN32 + // VC++ 2005 workaround + for(size_t i=0; igood()) + { + 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/libsrc/meshing/prism2rls.cpp b/libsrc/meshing/prism2rls.cpp new file mode 100644 index 00000000..7e696554 --- /dev/null +++ b/libsrc/meshing/prism2rls.cpp @@ -0,0 +1,457 @@ +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/libsrc/meshing/prism2rls_2.cpp b/libsrc/meshing/prism2rls_2.cpp new file mode 100644 index 00000000..baf0bef3 --- /dev/null +++ b/libsrc/meshing/prism2rls_2.cpp @@ -0,0 +1,446 @@ +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/libsrc/meshing/pyramid2rls.cpp b/libsrc/meshing/pyramid2rls.cpp new file mode 100644 index 00000000..a97e7f13 --- /dev/null +++ b/libsrc/meshing/pyramid2rls.cpp @@ -0,0 +1,309 @@ +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/libsrc/meshing/pyramidrls.cpp b/libsrc/meshing/pyramidrls.cpp new file mode 100644 index 00000000..d4e997c1 --- /dev/null +++ b/libsrc/meshing/pyramidrls.cpp @@ -0,0 +1,263 @@ +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/libsrc/meshing/quadrls.cpp b/libsrc/meshing/quadrls.cpp new file mode 100644 index 00000000..1c2cd23b --- /dev/null +++ b/libsrc/meshing/quadrls.cpp @@ -0,0 +1,887 @@ +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 P Right (150)\"\n",\ +"\n",\ +"quality 150\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",\ +"orientations\n",\ +"(1, 2, 3);\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",\ +"rule \"Left P Quad (150)\"\n",\ +"\n",\ +"quality 150\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",\ +"rule \"Triangle Vis A Vis (200)\"\n",\ +"\n",\ +"quality 200\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",\ +"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/libsrc/meshing/refine.cpp b/libsrc/meshing/refine.cpp new file mode 100644 index 00000000..f34aa6a4 --- /dev/null +++ b/libsrc/meshing/refine.cpp @@ -0,0 +1,749 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + void Refinement :: Refine (Mesh & mesh) + { + // reduce 2nd order + mesh.ComputeNVertices(); + mesh.SetNP(mesh.GetNV()); + + + INDEX_2_HASHTABLE between(mesh.GetNP() + 5); + + int oldne, oldns, oldnf; + + // refine edges + + ARRAY 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 + { + Point<3> 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 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 pnums(6); + ArrayMem 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(); + + Point<3> 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 pnums(9); + ArrayMem pgis(9); + + static int betw[5][3] = + { { 1, 2, 5 }, + { 2, 3, 6 }, + { 3, 4, 7 }, + { 1, 4, 8 }, + { 5, 7, 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 + { + Point<3> 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 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 bool reverse[8] = + { + false, false, false, false, false, true, false, true + }; + + 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 = !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 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 }, + }; + */ + + // udpated by anonymous supporter, donations please to Karo W. + static int fbetw[12][3] = + { { 11, 12, 22 }, + { 9, 10, 22 }, + { 13, 14, 23 }, + { 15, 16, 23 }, + { 9, 13, 24 }, + { 17, 18, 24 }, + { 12, 16, 25 }, + { 18, 19, 25 }, + { 19, 20, 26 }, + { 10, 14, 26 }, + { 11, 15, 27 }, + { 17, 20, 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 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 }, + }; + +// he: 15.jul 08, old version is wrong +// produces double points ad quad faces and inconsistent mesh +// static int fbetw[6][3] = +// { { 1, 6, 16 }, +// { 3, 4, 16 }, +// { 1, 5, 17 }, +// { 2, 4, 17 }, +// { 2, 6, 18 }, +// { 3, 5, 18 }, +// }; + + static int fbetw[6][3] = + { { 7, 10, 16 }, + { 14, 13, 16 }, + { 11, 8, 17 }, + { 13, 15, 17 }, + { 12, 9, 18 }, + { 14, 15, 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 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 > should(np); + ARRAY > 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 = 0; j < 3; j++) + mesh.Point(i)(j) = + lam * should.Get(i)(j) + + (1-lam) * can.Get(i)(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/libsrc/meshing/ruler2.cpp b/libsrc/meshing/ruler2.cpp new file mode 100644 index 00000000..6040ad21 --- /dev/null +++ b/libsrc/meshing/ruler2.cpp @@ -0,0 +1,641 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + +static double CalcElementBadness (const ARRAY & 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 & lpoints, + ARRAY & legalpoints, + int maxlegalpoint, + ARRAY & llines, + int maxlegalline, + ARRAY & elements, + ARRAY & 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 pused, pmap, pfixed; + static ARRAY lmap, lused; + static ARRAY pnearness, lnearness; + + static ARRAY tempnewpoints; + static ARRAY tempnewlines; + static ARRAY tempdellines; + static ARRAY 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; + + lused[1] = 1; // .Set (1, 1); + lmap[1] = 1; // .Set (1, 1); + + for (j = 0; j < 2; j++) + { + pmap.Elem(rule->GetLine(1)[j]) = llines[0][j]; + pused.Elem(llines[0][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 = lpoints.Get(loclin.I2()) - lpoints.Get(loclin.I1()); + + if (rule->CalcLineError (nlok, linevec) > maxerr) + { + ok = 0; + if(loctestmode) + (*testout) << "not ok pos1" << endl; + } + + for (j = 0; j < 2 && ok; j++) + { + // refpi = rule->GetPointNr (nlok, j); + refpi = rule->GetLine(nlok)[j]; + + if (pmap.Get(refpi) != 0) + { + if (pmap.Get(refpi) != loclin[j]) + { + ok = 0; + if(loctestmode) + (*testout) << "not ok pos2" << endl; + } + } + else + { + if (rule->CalcPointDist (refpi, lpoints.Get(loclin[j])) > maxerr + || !legalpoints.Get(loclin[j]) + || pused.Get(loclin[j])) + { + ok = 0; + if(loctestmode) + { + (*testout) << "nok pos3" << endl; + //if(rule->CalcPointDist (refpi, lpoints.Get(loclin[j])) > maxerr) + //(*testout) << "r1" << endl; + //if(!legalpoints.Get(loclin[j])) + //(*testout) << "r2 legalpoints " << legalpoints << " loclin " << loclin << " j " << j << endl; + //if(pused.Get(loclin[j])) + //(*testout) << "r3" << endl; + } + } + } + } + } + } + + if (ok) + { + lused.Elem (locli) = 1; + for (j = 0; j < 2; j++) + { + pmap.Set(rule->GetLine (nlok)[j], loclin[j]); + pused.Elem(loclin[j])++; + } + + nlok++; + } + else + { + lmap.Elem(nlok) = 0; + nlok--; + + lused.Elem (lmap.Get(nlok)) = 0; + for (j = 0; j < 2; j++) + { + pused.Elem(llines.Get(lmap.Get(nlok))[j]) --; + if (! pused.Get (llines.Get (lmap.Get (nlok))[j])) + pmap.Set (rule->GetLine (nlok)[j], 0); + } + } + } + + else + + { + + // all lines are mapped !! + + // map also all points: + + npok = 1; + incnpok = 1; + + pfixed.SetSize (pmap.Size()); + for (i = 0; i < pmap.Size(); i++) + pfixed[i] = (pmap[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->GetLine (i)[0]), + pmap.Get(rule->GetLine (i)[1]))); + } + + + // delete old lines: + for (i = 1; i <= rule->GetNDelL(); i++) + dellines.Append (lmap.Get(rule->GetDelLine(i))); + + // dellines.Append (lmap[rule->GetDelLines()]); + // lmap[rule->GetDelLines()]; + + + // 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 < 0.99*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 = lpoints.Range (noldlp, lpoints.Size()); + tempnewlines = llines.Range (noldll, llines.Size()); + tempdellines = dellines; + tempelements = elements; + } + + 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) + { + lpoints.Append (tempnewpoints); + llines.Append (tempnewlines); + dellines.Append (tempdellines); + elements.Append (tempelements); + } + + + return found; +} + + + + + +} diff --git a/libsrc/meshing/ruler2.hpp b/libsrc/meshing/ruler2.hpp new file mode 100644 index 00000000..bfb71f9c --- /dev/null +++ b/libsrc/meshing/ruler2.hpp @@ -0,0 +1,167 @@ +#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 points; + /// + ARRAY lines; + /// + ARRAY freezone, freezonelimit; + /// + ARRAY transfreezone; + + /// + ARRAY dellines; + /// + ARRAY elements; + /// + ARRAY tolerances, linetolerances; + /// + ARRAY orientations; + /// + DenseMatrix oldutonewu, oldutofreearea, oldutofreearealimit; + /// + ARRAY oldutofreearea_i; + /// + MatrixFixWidth<3> freesetinequ; + + /// + ARRAY linevecs; + + /// + int noldp, noldl; + /// + float fzminx, fzmaxx, fzminy, fzmaxy; + + /// topological distance of line to base element + ARRAY 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); } + /// + const ARRAY & GetDelLines() const { return dellines; } + /// + void GetFreeZone (ARRAY & 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 * tfp = &tolerances.Get(pi); + return tfp->f1 * dx * dx + tfp->f2 * dx * dy + tfp->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 & 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/libsrc/meshing/ruler3.cpp b/libsrc/meshing/ruler3.cpp new file mode 100644 index 00000000..30a812bc --- /dev/null +++ b/libsrc/meshing/ruler3.cpp @@ -0,0 +1,1137 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ +extern double minother; +extern double minwithoutother; + + +static double CalcElementBadness (const ARRAY & 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 & lpoints, // in: local points, out: old+new local points + ARRAY & allowpoint, // in: 2 .. it is allowed to use pointi, 1..will be allowed later, 0..no means + ARRAY & lfaces, // in: local faces, out: old+new local faces + INDEX lfacesplit, // for local faces in outer radius + INDEX_2_HASHTABLE & connectedpairs, // connected pairs for prism-meshing + ARRAY & elements, // out: new elements + ARRAY & 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 + ) + +{ + NgProfiler::RegionTimer regtot(97); + + int i, j, k, ri, nfok, npok, incnpok, refpi, locpi, locfi, locfr; + 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 MiniElement2d * locface = NULL; + int loktestmode; + + + static ARRAY pused; // point is already mapped + static ARRAY fused; // face is already mapped + static ARRAY pmap; // map of reference point to local point + static ARRAY pfixed; // point mapped by face-map + static ARRAY fmapi; // face in reference is mapped to face nr ... + static ARRAY fmapr; // face in reference is rotated to map + static ARRAY transfreezone; // transformed free-zone + static int cnt = 0; + static INDEX_2_CLOSED_HASHTABLE ledges(100); // edges in local environment + + static ARRAY tempnewpoints; + static ARRAY tempnewfaces; + static ARRAY tempdelfaces; + static ARRAY tempelements; + static ARRAY triboxes; // bounding boxes of local faces + + + static ARRAY pnearness; + static ARRAY 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); + + pnearness = INT_MAX/10; + for (j = 0; j < lfaces[0].GetNP(); j++) + pnearness[lfaces[0][j]] = 0; + + NgProfiler::RegionTimer reg2(98); + + NgProfiler::StartTimer (90); + + for (int loop = 0; loop < 2; loop++) + { + + for (i = 0; i < lfacesplit; i++) + { + const MiniElement2d & hface = lfaces[i]; + + int minn = INT_MAX-1; + for (j = 0; j < hface.GetNP(); j++) + { + int hi = pnearness[hface[j]]; + if (hi < minn) minn = hi; + } + if (minn < INT_MAX/10) + for (j = 0; j < hface.GetNP(); j++) + if (pnearness[hface[j]] > minn+1) + pnearness[hface[j]] = 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 (pnearness[edge.I1()] > pnearness[edge.I2()] + 1) + pnearness[edge.I1()] = pnearness[edge.I2()] + 1; + + if (pnearness[edge.I2()] > pnearness[edge.I1()] + 1) + pnearness[edge.I2()] = pnearness[edge.I1()] + 1; + } + + } + + for (i = 0; i < fnearness.Size(); i++) + { + int sum = 0; + for (j = 0; j < lfaces[i].GetNP(); j++) + sum += pnearness[lfaces[i][j]]; + fnearness[i] = sum; + } + + + NgProfiler::StopTimer (90); + NgProfiler::StartTimer (91); + + // find bounding boxes of faces + + triboxes.SetSize (lfaces.Size()); + for (i = 0; i < lfaces.Size(); i++) + { + const MiniElement2d & face = lfaces[i]; + triboxes[i].SetPoint (lpoints.Get(face[0])); + for (j = 1; j < face.GetNP(); j++) + triboxes[i].AddPoint (lpoints.Get(face[j])); + } + + NgProfiler::StopTimer (91); + NgProfiler::StartTimer (92); + + + bool useedges = 0; + for (ri = 0; ri < rules.Size(); ri++) + if (rules[ri]->GetNEd()) useedges = 1; + + if (useedges) + { + ledges.SetSize (5 * lfacesplit); + + for (j = 0; j < lfacesplit; j++) + // if (fnearness[j] <= 5) + { + const MiniElement2d & face = lfaces[j]; + int newp, oldp; + + newp = face[face.GetNP()-1]; + for (k = 0; k < face.GetNP(); k++) + { + oldp = newp; + newp = face[k]; + ledges.Set (INDEX_2::Sort(oldp, newp), 1); + } + } + } + + NgProfiler::StopTimer (92); + + NgProfiler::RegionTimer reg3(99); + + 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; + + + + // impossible, if no rule can be applied at any tolerance class + bool impossible = 1; + + + // check each rule: + + for (ri = 1; ri <= rules.Size(); ri++) + { + int base = (lfaces[0].GetNP() == 3) ? 100 : 200; + NgProfiler::RegionTimer regx1(base); + NgProfiler::RegionTimer regx(base+ri); + + sprintf (problems.Elem(ri), ""); + + rule = rules.Get(ri); + + if (rule->GetNP(1) != lfaces[0].GetNP()) + continue; + + if (rule->GetQuality() > tolerance) + { + if (rule->GetQuality() < 100) impossible = 0; + + if (testmode) + sprintf (problems.Elem(ri), "Quality not ok"); + continue; + } + + if (testmode) + sprintf (problems.Elem(ri), "no mapping found"); + + loktestmode = testmode || rule->TestFlag ('t') || tolerance > 5; + + if (loktestmode) + (*testout) << "Rule " << ri << " = " << rule->Name() << endl; + + pmap.SetSize (rule->GetNP()); + fmapi.SetSize (rule->GetNF()); + fmapr.SetSize (rule->GetNF()); + + fused = 0; + pused = 0; + pmap = 0; + fmapi = 0; + for (i = 1; i <= fmapr.Size(); i++) + fmapr.Set(i, rule->GetNP(i)); + + fused[0] = 1; + fmapi[0] = 1; + fmapr[0] = rotind1; + + + for (j = 1; j <= lfaces.Get(1).GetNP(); j++) + { + locpi = lfaces[0].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; + NgProfiler::RegionTimer regfa(300); + NgProfiler::RegionTimer regx2(base+50+ri); + 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) + { + impossible = 0; + 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 + + { + NgProfiler::RegionTimer regfb(301); + + // 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) || + pnearness.Get(locpi) > rule->GetPNearness(npok)) + { + ok = 0; + } + else if (allowpoint.Get(locpi) != 2) + { + ok = 0; + if (allowpoint.Get(locpi) == 1) + impossible = 0; + } + else + { + const Point3d & lp = lpoints.Get(locpi); + const Point3d & rp = rule->GetPoint(npok); + + if ( Dist2 (lp, rp) * rule->PointDistFactor(npok) > minerr) + { + ok = 0; + impossible = 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 + + { + NgProfiler::RegionTimer regfa2(302); + + // 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++) + { + INDEX_2 in2(pmap.Get(rule->GetEdge(i).i1), + pmap.Get(rule->GetEdge(i).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++) + { + INDEX_2 in2(pmap.Get(el.PNum(j)), + pmap.Get(el.PNum(j+3))); + 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 & 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 lpi(4); + + if (!fused.Get(i)) + { + int triin; + const MiniElement2d & 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); + } + + + // 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)) + { + MiniElement2d 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*n.Length()*v3.Length()) // OR -1e-7??? + if (n * v3 >= -1e-9) + { + if (loktestmode) + { + sprintf (problems.Elem(ri), "Orientation wrong"); + (*testout) << "Orientation wrong ("<< n*v3 << ")" << 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 (teterr > minteterr) impossible = 0; + + 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; + } + + if (found) + { + 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; + + + if (impossible && found == 0) + return -1; + + return found; +} +} diff --git a/libsrc/meshing/ruler3.hpp b/libsrc/meshing/ruler3.hpp new file mode 100644 index 00000000..483d83ed --- /dev/null +++ b/libsrc/meshing/ruler3.hpp @@ -0,0 +1,210 @@ +#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 points; + /// old and new faces in reference numbering + ARRAY faces; + /// additional edges of rule + ARRAY edges; + + /// points of freezone in reference coordinates + ARRAY freezone; + /// points of freezone in reference coordinates if tolcalss to infty + ARRAY freezonelimit; + /// point index, if point equal to mappoint, otherwise 0 + ARRAY freezonepi; + /// faces of each convex part of freezone + ARRAY*> freefaces; + /// set of points of each convex part of freezone + ARRAY*> freesets; + /// points of transformed freezone + ARRAY transfreezone; + /// edges of each convex part of freezone + ARRAY*> freeedges; + + /// face numbers to be deleted + ARRAY delfaces; + /// elements to be generated + ARRAY elements; + /// tolerances for points and faces (used ??) + ARRAY 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 freefaceinequ; + /// + ARRAY orientations; + /** + flags specified in rule-description file: + t .. test rule + */ + ARRAY flags; + + /** + topological distance of face to base element + non-connected: > 100 (??) + */ + ARRAY fnearness; + ARRAY 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 & pi, int newone); + /// + int IsQuadInFreeZone (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + const ARRAY & pi, int newone); + /// + int IsTriangleInFreeSet (const Point3d & p1, const Point3d & p2, + const Point3d & p3, int fs, const ARRAY & pi, int newone); + + /// + int IsQuadInFreeSet (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + int fs, const ARRAY & 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 & GetTransFreeZone () { return transfreezone; } + /// + int TestOk () const; + + /// + friend void TestRules (); + /// + // friend void Plot3DRule (const ROT3D & r, char key); +}; + + + +#endif + diff --git a/libsrc/meshing/secondorder.cpp b/libsrc/meshing/secondorder.cpp new file mode 100644 index 00000000..66c91cfe --- /dev/null +++ b/libsrc/meshing/secondorder.cpp @@ -0,0 +1,486 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + + + + + void Refinement :: MakeSecondOrder (Mesh & mesh) + { + int nseg, nse, ne; + + mesh.ComputeNVertices(); + mesh.SetNP(mesh.GetNV()); + + INDEX_2_HASHTABLE 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 + { + Point<3> 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(0); + + 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](NULL); + + 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 + { + Point<3> 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++) + { + const Element & el = mesh.VolumeElement(i); + int onp(0); + + Element newel; + newel.SetIndex (el.GetIndex()); + + static int betw_tet[6][3] = + { { 0, 1, 4 }, + { 0, 2, 5 }, + { 0, 3, 6 }, + { 1, 2, 7 }, + { 1, 3, 8 }, + { 2, 3, 9 } }; + static int betw_prism[6][3] = + { + { 0, 2, 6 }, + { 0, 1, 7 }, + { 1, 2, 8 }, + { 3, 5, 9 }, + { 3, 4, 10 }, + { 4, 5, 11 }, + }; + int (*betw)[3](NULL); + + 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[betw[j][0]], + newel[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 identmap; + mesh.GetIdentifications().GetMap (i, identmap); + + for (INDEX_2_HASHTABLE::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::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 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 & 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 > should(np); + ARRAY > 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 = 0; j < 3; j++) + mesh.Point(i)(j) = + lam * should.Get(i)(j) + + (1-lam) * can.Get(i)(j); + } + else + mesh.Point(i) = Point<3> (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/libsrc/meshing/smoothing2.5.cpp b/libsrc/meshing/smoothing2.5.cpp new file mode 100644 index 00000000..2789b785 --- /dev/null +++ b/libsrc/meshing/smoothing2.5.cpp @@ -0,0 +1,265 @@ +#include + +#include "meshing.hpp" +#include + +namespace netgen +{ + + + void MeshOptimize2d :: ProjectBoundaryPoints(ARRAY & surfaceindex, + const ARRAY* > & from, ARRAY* > & dest) + { + for(int i=0; i= 0) + { + *dest[i] = *from[i]; + ProjectPoint(surfaceindex[i],*dest[i]); + } + } + + + } + + void MeshOptimize2d :: ImproveVolumeMesh (Mesh & mesh) + { + + if (!faceindex) + { + PrintMessage (3, "Smoothing"); + + for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) + { + ImproveVolumeMesh (mesh); + if (multithread.terminate) + throw NgException ("Meshing stopped"); + } + faceindex = 0; + return; + } + + + + static int timer = NgProfiler::CreateTimer ("MeshSmoothing 2D"); + NgProfiler::RegionTimer reg (timer); + + + + CheckMeshApproximation (mesh); + + int i, j, k; + SurfaceElementIndex sei; + + ARRAY 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; + bool moveisok; + + PointGeomInfo ngi; + Point<3> origp; + + Vector x(3); + + ARRAY savepoints(mesh.GetNP()); + + ARRAY 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 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]); + } + + + JacobianPointFunction pf(mesh.Points(),mesh.VolumeElements()); + + + +// Opti2SurfaceMinFunction surfminf(mesh); +// Opti2EdgeMinFunction edgeminf(mesh); +// Opti2SurfaceMinFunctionJacobian surfminfj(mesh); + + OptiParameters par; + par.maxit_linsearch = 8; + par.maxit_bfgs = 5; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + + BitArray badnodes(np); + badnodes.Clear(); + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + double bad = el.CalcJacobianBadness (mesh.Points()); + if (bad > 1) + for (j = 1; j <= el.GetNP(); j++) + badnodes.Set (el.PNum(j)); + } + + + 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; + + + ARRAY locelements(0); + ARRAY locrots(0); + + for (PointIndex pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + { + if (mesh[pi].Type() != SURFACEPOINT) + continue; + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + int surfi(-1); + + if(elementsonpoint[pi].Size() == 0) + continue; + + Element2d & hel = mesh[elementsonpoint[pi][0]]; + + if(hel.GetIndex() != faceindex) + continue; + + cnt++; + if (cnt % modplot == 0 && writestatus) + { + printeddot = 1; + PrintDot (plotchar); + } + + + int hpi = 0; + for (j = 1; j <= hel.GetNP(); j++) + if (hel.PNum(j) == pi) + { + hpi = j; + break; + } + PointGeomInfo gi1 = hel.GeomInfoPi(hpi); + + locelements.SetSize(0); + locrots.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; + } + } + + + double lh = mesh.GetH(mesh.Point(pi)); + par.typx = lh; + + pf.SetPointIndex(pi); + + x = 0; + bool pok = (pf.Func (x) < 1e10); + + if (pok) + { + BFGS (x, pf, par); + + origp = mesh[pi]; + loci = 1; + fact = 1; + moveisok = false; + + + //optimizer loop (if whole distance is not possible, move only a bit!!!!) + while (loci <= 5 && !moveisok) + { + loci ++; + mesh[pi](0) = origp(0) + x.Get(1)*fact; + mesh[pi](1) = origp(1) + x.Get(2)*fact; + mesh[pi](2) = origp(2) + x.Get(3)*fact; + fact = fact/2.; + + + //cout << "origp " << origp << " newp " << mesh[pi]; + + ngi = gi1; + moveisok = (ProjectPointGI (surfi, mesh[pi], ngi) != 0); + + //cout << " projected " << mesh[pi] << endl; + + // point lies on same chart in stlsurface + + if (moveisok) + { + for (j = 0; j < locelements.Size(); j++) + mesh[locelements[j]].GeomInfoPi(locrots[j]) = ngi; + + //cout << "moved " << origp << " to " << mesh[pi] << endl; + } + else + { + mesh[pi] = origp; + } + + } + } + else + { + cout << "el not ok (point " << pi << ": " << mesh[pi] << ")" << endl; + } + } + + if (printeddot) + PrintDot ('\n'); + + CheckMeshApproximation (mesh); + mesh.SetNextTimeStamp(); + } + + +} diff --git a/libsrc/meshing/smoothing2.cpp b/libsrc/meshing/smoothing2.cpp new file mode 100644 index 00000000..e4335282 --- /dev/null +++ b/libsrc/meshing/smoothing2.cpp @@ -0,0 +1,985 @@ +#include + +#include "meshing.hpp" +#include + +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 = 0.14433756; // sqrt(3.0) / 12 + static const double c_trig4 = 0.57735026; // sqrt(3.0) / 3 + + 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) + + 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 Vec<3> normal, t1, t2; + static ARRAY locelements(0); + static ARRAY locrots(0); + static ARRAY 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 FuncDeriv (const Vector & x, const Vector & dir, double & deriv) 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 + { + Vec<3> n, vgrad; + Point<3> pp1; + double g1x, g1y; + double badness, hbadness; + + vgrad = 0; + badness = 0; + + meshthis -> GetNormalVector (surfi, sp1, gi1, n); + pp1 = sp1 + x(0) * t1 + x(1) * 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]]; + + Vec<3> e1 = mesh[bel.PNumMod(roti + 1)] - pp1; + Vec<3> e2 = mesh[bel.PNumMod(roti + 2)] - pp1; + + 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 -= e1e2 * e1; + double e2l = e2.Length(); + + CalcTriangleBadness ( e1l, e1e2, e2l, locmetricweight, loch, + hbadness, g1x, g1y); + + badness += hbadness; + vgrad += g1x * e1 + (g1y/e2l) * e2; + } + else + { + (*testout) << "very very bad badness" << endl; + badness += 1e8; + } + } + + vgrad -= (vgrad * n) * n; + + grad(0) = vgrad * t1; + grad(1) = vgrad * t2; + return badness; + } + + + + + double Opti2SurfaceMinFunction :: + FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + Vec<3> n, vgrad; + Point<3> pp1; + double g1x, g1y; + double badness, hbadness; + + vgrad = 0; + badness = 0; + + meshthis -> GetNormalVector (surfi, sp1, gi1, n); + + pp1 = sp1 + x(0) * t1 + x(1) * t2; + + for (int j = 0; j < locelements.Size(); j++) + { + int roti = locrots[j]; + + const Element2d & bel = mesh[locelements[j]]; + + Vec<3> e1 = mesh[bel.PNumMod(roti + 1)] - pp1; + Vec<3> e2 = mesh[bel.PNumMod(roti + 2)] - pp1; + + 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 -= e1e2 * e1; + double e2l = e2.Length(); + + CalcTriangleBadness ( e1l, e1e2, e2l, locmetricweight, loch, + hbadness, g1x, g1y); + + badness += hbadness; + vgrad += g1x * e1 + (g1y / e2l) * e2; + } + else + { + (*testout) << "very very bad badness" << endl; + badness += 1e8; + } + } + + vgrad -= (vgrad * n) * n; + deriv = dir(0) * (vgrad*t1) + dir(1) * (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; + Vec<3> n1, n2, v1, v2, e1, e2, vgrad; + Point<3> pp1; + Vec<2> g1; + double badness, hbadness; + + vgrad = 0.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(0), g1(1)); + + badness += hbadness; + vgrad += g1(0) * e1 + g1(1) * e2; + } + + meshthis -> GetNormalVector (surfi, pp1, n1); + meshthis -> GetNormalVector (surfi2, pp1, n2); + + v1 = Cross (n1, n2); + v1.Normalize(); + + grad(0) = (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 lpi, gpi; + Vec<3> n, vgrad; + Point<3> pp1; + Vec2d g1, vdir; + double badness, hbad, hderiv; + + vgrad = 0; + badness = 0; + + meshthis -> GetNormalVector (surfi, sp1, gi1, n); + + pp1 = sp1 + x(0) * t1 + x(1) * t2; + + // meshthis -> ProjectPoint (surfi, pp1); + // meshthis -> GetNormalVector (surfi, pp1, n); + + static ARRAY pts2d; + pts2d.SetSize(mesh.GetNP()); + + grad = 0; + + for (int j = 1; j <= locelements.Size(); j++) + { + lpi = locrots.Get(j); + const Element2d & bel = + mesh[locelements.Get(j)]; + + gpi = bel.PNum(lpi); + + for (int 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 (int 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; + Vec<3> n, vgrad; + Point<3> pp1; + Vec2d g1, vdir; + double badness, hbad, hderiv; + + vgrad = 0; + badness = 0; + + meshthis -> GetNormalVector (surfi, sp1, gi1, n); + + // pp1 = sp1; + // pp1.Add2 (x.Get(1), t1, x.Get(2), t2); + pp1 = sp1 + x.Get(1) * t1 + x.Get(2) * t2; + + static ARRAY 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 Point<3> & 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; + } + + + + static int timer = NgProfiler::CreateTimer ("MeshSmoothing 2D"); + NgProfiler::RegionTimer reg (timer); + + + CheckMeshApproximation (mesh); + + SurfaceElementIndex sei; + + ARRAY seia; + mesh.GetSurfaceElementsOfFace (faceindex, seia); + + bool mixed = 0; + for (int 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 savepoints(mesh.GetNP()); + uselocalh = mparam.uselocalh; + + ARRAY nelementsonpoint(mesh.GetNP()); + + nelementsonpoint = 0; + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + nelementsonpoint[el[j]]++; + } + + TABLE elementsonpoint(nelementsonpoint); + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int 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; + + /* + int i, j, k; + + 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[pi].Type() == SURFACEPOINT) + { + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + 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 (int 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 (int 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 (int 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, normal); + t1 = normal.GetNormal (); + t2 = Cross (normal, t1); + + // save points, and project to tangential plane + for (int j = 0; j < locelements.Size(); j++) + { + const Element2d & el = mesh[locelements[j]]; + for (int k = 0; k < el.GetNP(); k++) + savepoints[el[k]] = mesh[el[k]]; + } + + for (int j = 0; j < locelements.Size(); j++) + { + const Element2d & el = mesh[locelements[j]]; + for (int k = 0; k < el.GetNP(); k++) + { + PointIndex hhpi = el[k]; + double lam = normal * (mesh[hhpi] - sp1); + mesh[hhpi] -= lam * normal; + } + } + + x = 0; + par.typx = lochs[0]; + + if (mixed) + { + // (*testout) << "vorher : " << surfminfj.Func (x) << endl; + BFGS (x, surfminfj, par, 1e-6); + // (*testout) << "nachher: " << surfminfj.Func (x) << endl; + // (*testout) << "x = " << x << endl; + } + else + { + // (*testout) << "vorher : " << surfminf.Func (x) << endl; + BFGS (x, surfminf, par, 1e-6); + // (*testout) << "nachher: " << surfminf.Func (x) << endl; + // (*testout) << "x = " << x << endl; + } + + + origp = mesh[pi]; + loci = 1; + fact = 1; + moveisok = 0; + + // restore other points + for (int j = 0; j < locelements.Size(); j++) + { + const Element2d & el = mesh[locelements[j]]; + for (int k = 0; k < el.GetNP(); k++) + { + PointIndex hhpi = el[k]; + if (hhpi != pi) mesh[hhpi] = savepoints[hhpi]; + } + } + + + //optimizer loop (if 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; + */ + Vec<3> hv = x(0) * t1 + x(1) * t2; + Point3d hnp = origp + Vec3d (hv); + mesh[pi](0) = hnp.X(); + mesh[pi](1) = hnp.Y(); + mesh[pi](2) = hnp.Z(); + + fact = fact/2.; + + // ProjectPoint (surfi, mesh[pi]); + // moveisok = CalcPointGeomInfo(surfi, ngi, mesh[pi]); + + ngi = gi1; + moveisok = ProjectPointGI (surfi, mesh[pi], ngi); + // point lies on same chart in stlsurface + + if (moveisok) + { + for (int j = 0; j < locelements.Size(); j++) + mesh[locelements[j]].GeomInfoPi(locrots[j]) = ngi; + } + else + { + mesh[pi] = Point<3> (origp); + } + + } + } + + if (printeddot) + PrintDot ('\n'); + + CheckMeshApproximation (mesh); + mesh.SetNextTimeStamp(); + } + + void MeshOptimize2d :: GetNormalVector(INDEX /* surfind */, const Point<3> & p, Vec<3> & nv) const + { + nv = Vec<3> (0, 0, 1); + } + + void MeshOptimize2d :: GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & gi, Vec<3> & n) const + { + GetNormalVector (surfind, p, n); + } +} diff --git a/libsrc/meshing/smoothing3.cpp b/libsrc/meshing/smoothing3.cpp new file mode 100644 index 00000000..7b905a66 --- /dev/null +++ b/libsrc/meshing/smoothing3.cpp @@ -0,0 +1,1908 @@ +#include + +#include "meshing.hpp" +#ifdef SOLIDGEOM +#include +#endif +#include + + +namespace netgen +{ + + + double MinFunctionSum :: Func (const Vector & x) const + { + double retval = 0; + for(int i=0; iFunc(x); + + return retval; + } + + void MinFunctionSum :: Grad (const Vector & x, Vector & g) const + { + g = 0.; + static Vector gi(3); + for(int i=0; iGrad(x,gi); + for(int j=0; jFuncGrad(x,gi); + for(int j=0; jFuncDeriv(x,dir,derivi); + deriv += derivi; + } + return retval; + } + + double MinFunctionSum :: GradStopping (const Vector & x) const + { + double minfs(0), mini; + for(int i=0; iGradStopping(x); + if(i==0 || mini < minfs) + minfs = mini; + } + return minfs; + } + + + void MinFunctionSum :: AddFunction(MinFunction & fun) + { + functions.Append(&fun); + } + + const MinFunction & MinFunctionSum :: Function(int i) const + { + return *functions[i]; + } + MinFunction & MinFunctionSum :: Function(int i) + { + return *functions[i]; + } + + + PointFunction1 :: PointFunction1 (Mesh::T_POINTS & apoints, + const ARRAY & afaces, + double ah) + : points(apoints), faces(afaces) + { + h = ah; + } + + + double PointFunction1 :: Func (const Vector & vp) const + { + double badness = 0; + Point<3> pp(vp(0), vp(1), vp(2)); + + for (int 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 */ + + // is it used ???? + class CheapPointFunction1 : public MinFunction + { + Mesh::T_POINTS & points; + const ARRAY & faces; + DenseMatrix m; + double h; + public: + CheapPointFunction1 (Mesh::T_POINTS & apoints, + const ARRAY & 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 & afaces, + double ah) + : points(apoints), faces(afaces) + { + h = ah; + + + int nf = faces.Size(); + + m.SetSize (nf, 4); + + for (int 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 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 Point<3> & pp) const; + virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const; + virtual double PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & 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 Point<3> & pp) const + { + int j; + INDEX eli; + const Element * el; + double badness; + // ARRAY p(4); + Point<3> hp; + + badness = 0; + + hp = points[actpind]; + points[actpind] = Point<3> (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] = Point<3> (hp); + return badness; + } + + + double PointFunction :: PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const + { + double f;//, delta = h * 1e-6; + // Point<3> 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 + // double badness; + Point<3> hp; + Vec<3> vgradi, vgrad(0,0,0); + + // badness = 0; + + hp = points[actpind]; + points[actpind] = Point<3> (pp); + + for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + { + INDEX eli = elementsonpoint[actpind][j]; + const Element & el = elements.Get(eli); + + for (int 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] = Point<3> (hp); + + grad = vgrad; + return f; + } + + + double PointFunction :: PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & dir, + double & deriv) const + { + double f; + // Point<3> hpp; + + Vec<3> dirn (dir); + //double ldir = dir.Length(); + + int j, k; + INDEX eli; + // double badness; + Point<3> hp; + Vec<3> 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] = Point<3> (hp); + deriv = dir * vgrad; + return f; + } + + int PointFunction :: MovePointToInner () + { + // try point movement + ARRAY faces; + + for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + { + const Element & el = + elements.Get(elementsonpoint[actpind][j]); + + for (int 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] = Point<3> (hp); + } + else + ; + // cout << "no inner point found" << endl; + + /* + Point3d hp2; + int hi2 = FindInnerPoint (points, faces, hp2); + if (hi2) + { + cout << "new: inner point found" << endl; + } + else + cout << "new: no inner point found" << endl; + + (*testout) << "hi(orig) = " << hi << ", hi(new) = " << hi2; + if (hi != hi2) (*testout) << "hi different" << 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 Point<3> & pp) const; + virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const; + }; + + + CheapPointFunction :: CheapPointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements) + : PointFunction (apoints, aelements) + { + ; + } + + + void CheapPointFunction :: SetPointIndex (PointIndex aactpind) + { + actpind = aactpind; + + int ne = elementsonpoint[actpind].Size(); + int i, j; + int pi1, pi2, pi3; + + m.SetSize (ne, 4); + + for (i = 0; i < ne; 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, 1) = n.X(); + m.Elem(i+1, 2) = n.Y(); + m.Elem(i+1, 3) = n.Z(); + m.Elem(i+1, 4) = - (n.X() * p1.X() + n.Y() * p1.Y() + n.Z() * p1.Z()); + } + } + + double CheapPointFunction :: PointFunctionValue (const Point<3> & pp) const + { + static Vector p4(4); + static Vector di; + int n = m.Height(); + + p4.Elem(1) = pp(0); + p4.Elem(2) = pp(1); + p4.Elem(3) = pp(2); + 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 Point<3> & pp, Vec<3> & grad) const + { + static Vector p4(4); + static Vector di; + + int n = m.Height(); + + p4.Elem(1) = pp(0); + p4.Elem(2) = pp(1); + p4.Elem(3) = pp(2); + 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(0) -= idi * idi * m.Get(i, 1); + grad(1) -= idi * idi * m.Get(i, 2); + grad(2) -= idi * idi * m.Get(i, 3); + } + else + { + return 1e16; + } + } + return sum; + } + + + + + + + + + class Opti3FreeMinFunction : public MinFunction + { + const PointFunction & pf; + Point<3> sp1; + + public: + Opti3FreeMinFunction (const PointFunction & apf); + void SetPoint (const Point<3> & 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 + { + Point<3> pp; + for (int j = 0; j < 3; j++) + pp(j) = sp1(j) + x(j); + return pf.PointFunctionValue (pp); + } + + double Opti3FreeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const + { + Vec<3> vgrad; + Point<3> pp; + + for (int j = 0; j < 3; j++) + pp(j) = sp1(j) + x(j); + + double val = pf.PointFunctionValueGrad (pp, vgrad); + + for (int j = 0; j < 3; j++) + grad(j) = vgrad(j); + + return val; + } + + double Opti3FreeMinFunction :: FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + Point<3> pp; + + for (int j = 0; j < 3; j++) + pp(j) = sp1(j) + x(j); + + Vec<3> vdir; + for (int j = 0; j < 3; j++) + vdir(j) = dir(j); + + 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(); + + static Vector hx; + hx.SetSize(n); + + double eps = 1e-8; + double f, f11, f22; //, f12, f21 + + f = Func(x); + + for (int i = 1; i <= n; i++) + { + for (int 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 (max2(CalcBad (points, elements.Get(i), 0),1e-10), + 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 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); + } + + onplane = false; +} + +void JacobianPointFunction :: SetPointIndex (PointIndex aactpind) +{ + actpind = aactpind; +} + + +double JacobianPointFunction :: Func (const Vector & v) const +{ + int j; + double badness = 0; + + Point<3> hp = points.Elem(actpind); + + points.Elem(actpind) = hp + Vec<3> (v.Get(1), v.Get(2), v.Get(3)); + + if(onplane) + points.Elem(actpind) -= (v.Get(1)*nv(0)+v.Get(2)*nv(1)+v.Get(3)*nv(2)) * nv; + + + 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; + + Point<3> hp = points.Elem(actpind); + points.Elem(actpind) = hp + Vec<3> (x.Get(1), x.Get(2), x.Get(3)); + + if(onplane) + points.Elem(actpind) -= (x.Get(1)*nv(0)+x.Get(2)*nv(1)+x.Get(3)*nv(2)) * nv; + + Vec<3> 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; + + badness += elements.Get(eli). + CalcJacobianBadnessGradient (points, lpi, hderiv); + + for(k=0; k<3; k++) + g.Elem(k+1) += hderiv(k); + + /* + for (k = 1; k <= 3; k++) + { + vdir = Vec3d(0,0,0); + vdir.X(k) = 1; + + hbad = elements.Get(eli). + CalcJacobianBadnessDirDeriv (points, lpi, vdir, hderiv); + //(*testout) << "hderiv " << k << ": " << hderiv << endl; + g.Elem(k) += hderiv; + if (k == 1) + badness += hbad; + } + */ + } + + if(onplane) + { + double scal = nv(0)*g.Get(1) + nv(1)*g.Get(2) + nv(2)*g.Get(3); + g.Elem(1) -= scal*nv(0); + g.Elem(2) -= scal*nv(1); + g.Elem(3) -= scal*nv(2); + } + + //(*testout) << "g = " << g << endl; + + + 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; + + Point<3> hp = points.Elem(actpind); + points.Elem(actpind) = Point<3> (hp + Vec3d (x.Get(1), x.Get(2), x.Get(3))); + + if(onplane) + points.Elem(actpind) -= (Vec3d (x.Get(1), x.Get(2), x.Get(3))*nv) * nv; + + double hderiv; + deriv = 0; + Vec<3> vdir(dir.Get(1), dir.Get(2), dir.Get(3)); + + if(onplane) + { + double scal = vdir * nv; + vdir -= scal*nv; + } + + 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; + +} + + + + + + + + + + +#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; + } + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh"; + + + TABLE 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; + + int printmod = 1; + char printdot = '.'; + if (points.Size() > 1000) + { + printmod = 10; + printdot = '+'; + } + if (points.Size() > 10000) + { + printmod = 100; + printdot = '*'; + } + + 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 ('+'); + */ + if (i % printmod == 0) PrintDot (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; + + (*testout) << "Improve Mesh" << "\n"; + PrintMessage (3, "ImproveMesh"); + + int np = GetNP(); + int ne = GetNE(); + + + ARRAY 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 (int 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; + + ARRAY pointh (points.Size()); + + if(lochfunc) + { + for(int i=1; i<=points.Size(); i++) + pointh[i] = GetH(points.Get(i)); + } + else + { + pointh = 0; + for(int i=0; i pointh[el.PNum(j)]) + pointh[el.PNum(j)] = h; + } + } + + + int printmod = 1; + char printdot = '.'; + if (points.Size() > 1000) + { + printmod = 10; + printdot = '+'; + } + if (points.Size() > 10000) + { + printmod = 100; + printdot = '*'; + } + + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh"; + + for (PointIndex i = PointIndex::BASE; + i < points.Size()+PointIndex::BASE; i++) + if ( (*this)[i].Type() == 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 ('+'); + */ + if ( (i+1-PointIndex::BASE) % printmod == 0) PrintDot (printdot); + + double lh = pointh[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) + { + //*testout << "start BFGS, pok" << endl; + BFGS (x, freeminf, par); + //*testout << "BFGS complete, pok" << endl; + points[i](0) += x.Get(1); + points[i](1) += x.Get(2); + points[i](2) += 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, const BitArray * usepoint) +{ + 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)); + } + + ARRAY pointh (points.Size()); + + if(lochfunc) + { + for(i = 1; i<=points.Size(); i++) + pointh[i] = GetH(points.Get(i)); + } + else + { + pointh = 0; + for(i=0; i pointh[el.PNum(j)]) + pointh[el.PNum(j)] = h; + } + } + + + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh Jacobian"; + + for (i = 1; i <= points.Size(); i++) + { + if ((*this)[PointIndex(i)].Type() != INNERPOINT) + continue; + + if(usepoint && !usepoint->Test(i)) + continue; + + //(*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 = pointh[i]; + par.typx = lh; + + pf.SetPointIndex (i); + + x = 0; + int pok = (pf.Func (x) < 1e10); + + if (pok) + { + //*testout << "start BFGS, Jacobian" << endl; + BFGS (x, pf, par); + //*testout << "end BFGS, Jacobian" << endl; + points.Elem(i)(0) += x.Get(1); + points.Elem(i)(1) += x.Get(2); + points.Elem(i)(2) += x.Get(3); + } + else + { + cout << "el not ok" << endl; + } + } + PrintDot ('\n'); + + + multithread.task = savetask; +} + + + + +// Improve Condition number of Jacobian, any elements +void Mesh :: ImproveMeshJacobianOnSurface (const BitArray & usepoint, + const ARRAY< Vec<3>* > & nv, + OPTIMIZEGOAL goal, + const ARRAY< ARRAY* > * idmaps) +{ + 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); + + ARRAY< ARRAY* > locidmaps; + const ARRAY< ARRAY* > * used_idmaps; + + if(idmaps) + used_idmaps = idmaps; + else + { + used_idmaps = &locidmaps; + + for(i=1; i<=GetIdentifications().GetMaxNr(); i++) + { + if(GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + locidmaps.Append(new ARRAY); + GetIdentifications().GetMap(i,*locidmaps.Last(),true); + } + } + } + + + bool usesum = (used_idmaps->Size() > 0); + MinFunctionSum pf_sum; + + JacobianPointFunction * pf2ptr = NULL; + if(usesum) + { + pf2ptr = new JacobianPointFunction(points, volelements); + pf_sum.AddFunction(pf); + pf_sum.AddFunction(*pf2ptr); + } + + + 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)); + } + + ARRAY pointh (points.Size()); + + if(lochfunc) + { + for(i=1; i<=points.Size(); i++) + pointh[i] = GetH(points.Get(i)); + } + else + { + pointh = 0; + for(i=0; i pointh[el.PNum(j)]) + pointh[el.PNum(j)] = h; + } + } + + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh Jacobian"; + + for (i = 1; i <= points.Size(); i++) + if ( usepoint.Test(i) ) + { + //(*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 = pointh[i];//GetH(points.Get(i)); + par.typx = lh; + + pf.SetPointIndex (i); + + int brother = -1; + if(usesum) + { + for(j=0; brother == -1 && jSize(); j++) + { + if(i < (*used_idmaps)[j]->Size() + PointIndex::BASE) + { + brother = (*(*used_idmaps)[j])[i]; + if(brother == i || brother == 0) + brother = -1; + } + } + if(brother >= i) + { + pf2ptr->SetPointIndex(brother); + pf2ptr->SetNV(*nv[brother-1]); + } + } + + if(usesum && brother < i) + continue; + + //pf.UnSetNV(); x = 0; + //(*testout) << "before " << pf.Func(x); + + pf.SetNV(*nv[i-1]); + + x = 0; + int pok = (brother == -1) ? (pf.Func (x) < 1e10) : (pf_sum.Func (x) < 1e10); + + if (pok) + { + + if(brother == -1) + BFGS (x, pf, par); + else + BFGS (x, pf_sum, par); + + + for(j=1; j<=3; j++) + points.Elem(i)(j-1) += x.Get(j);// - scal*nv[i-1].X(j); + + if(brother != -1) + for(j=1; j<=3; j++) + points.Elem(brother)(j-1) += x.Get(j);// - scal*nv[brother-1].X(j); + + + } + else + { + cout << "el not ok" << endl; + (*testout) << "el not ok" << endl + << " func " << ((brother == -1) ? pf.Func(x) : pf_sum.Func (x)) << endl; + if(brother != -1) + (*testout) << " func1 " << pf.Func(x) << endl + << " func2 " << pf2ptr->Func(x) << endl; + } + } + + PrintDot ('\n'); + + delete pf2ptr; + for(i=0; i +#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 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 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; + 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++) + { + Point<3> & p = mesh.Point(i); + double rold = sqrt (sqr(p(0)) + sqr(p(1)) + sqr(p(2))); + if (rold < ri) continue; + + double rnew = 1 / (a * rold - b); + double fac = rnew / rold; + p(0) *= fac; + p(1) *= fac; + p(2) *= fac; + } +} +} diff --git a/libsrc/meshing/specials.hpp b/libsrc/meshing/specials.hpp new file mode 100644 index 00000000..700ba459 --- /dev/null +++ b/libsrc/meshing/specials.hpp @@ -0,0 +1,16 @@ +#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/libsrc/meshing/tetrarls.cpp b/libsrc/meshing/tetrarls.cpp new file mode 100644 index 00000000..cb28648b --- /dev/null +++ b/libsrc/meshing/tetrarls.cpp @@ -0,0 +1,1466 @@ +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/libsrc/meshing/topology.cpp b/libsrc/meshing/topology.cpp new file mode 100644 index 00000000..73ee1a87 --- /dev/null +++ b/libsrc/meshing/topology.cpp @@ -0,0 +1,1507 @@ +#include + +#include "meshing.hpp" + +#ifdef PARALLEL +#include +#endif + +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() +{ + static int timer = NgProfiler::CreateTimer ("topology"); + NgProfiler::RegionTimer reg (timer); + +#ifdef PARALLEL + ParallelMeshTopology & paralleltop = mesh.GetParallelTopology(); + + bool isparallel = 0; +#endif + + + 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) << " UPDATE MESH TOPOLOGY " << endl; + (*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 cnt(nv); + ARRAY vnums; + + /* + generate: + vertex to element + vertex to surface element + vertex to segment + */ + + + cnt = 0; + for (ElementIndex ei = 0; ei < ne; ei++) + { + const Element & el = mesh[ei]; + int nelv = el.GetNV(); + for (int j = 0; j < nelv; j++) + cnt[el[j]]++; + } + + vert2element = new TABLE (cnt); + for (ElementIndex ei = 0; ei < ne; ei++) + { + const Element & el = mesh[ei]; + int nelv = el.GetNV(); + for (int j = 0; j < nelv; j++) + vert2element->AddSave (el[j], ei+1); + } + + cnt = 0; + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = mesh[sei]; + int nelv = el.GetNV(); + for (int j = 0; j < nelv; j++) + cnt[el[j]]++; + } + + vert2surfelement = new TABLE (cnt); + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = mesh[sei]; + int nelv = el.GetNV(); + for (int j = 0; j < nelv; j++) + vert2surfelement->AddSave (el[j], sei+1); + } + + cnt = 0; + for (int i = 1; i <= nseg; i++) + { + const Segment & seg = mesh.LineSegment(i); + cnt[seg.p1]++; + cnt[seg.p2]++; + } + + vert2segment = new TABLE (cnt); + for (int i = 1; i <= nseg; i++) + { + const Segment & seg = mesh.LineSegment(i); + vert2segment->AddSave (seg.p1, i); + vert2segment->AddSave (seg.p2, i); + } + + if (buildedges) + { + static int timer1 = NgProfiler::CreateTimer ("topology::buildedges"); + NgProfiler::RegionTimer reg1 (timer1); + + PrintMessage (5, "Update edges "); + + edges.SetSize(ne); + surfedges.SetSize(nse); + segedges.SetSize(nseg); + + for (int i = 0; i < ne; i++) + for (int j = 0; j < 12; j++) + edges[i][j] = 0; + for (int i = 0; i < nse; i++) + for (int j = 0; j < 4; j++) + surfedges[i][j] = 0; + + // keep existing edges + cnt = 0; + for (int i = 0; i < edge2vert.Size(); i++) + cnt[edge2vert[i][0]]++; + TABLE vert2edge (cnt); + for (int i = 0; i < edge2vert.Size(); i++) + vert2edge.AddSave (edge2vert[i][0], i+1); + + // ensure all coarse grid and intermediate level edges + cnt = 0; + for (int i = mesh.mlbetweennodes.Begin(); i < mesh.mlbetweennodes.End(); i++) + { + int pa[2]; + pa[0] = mesh.mlbetweennodes[i].I1(); + pa[1] = mesh.mlbetweennodes[i].I2(); + if (pa[0] > pa[1]) Swap (pa[0], pa[1]); + if (pa[0] > 0) + cnt.Elem(pa[0])++; + } + TABLE vert2vertcoarse (cnt); + for (int i = mesh.mlbetweennodes.Begin(); i < mesh.mlbetweennodes.End(); i++) + { + int pa[2]; + pa[0] = mesh.mlbetweennodes[i].I1(); + pa[1] = mesh.mlbetweennodes[i].I2(); + if (pa[0] > pa[1]) swap (pa[0], pa[1]); + if (pa[0] > 0) + vert2vertcoarse.AddSave1 (pa[0], pa[1]); + } + + + ARRAY edgenr(nv); + ARRAY edgeflag(nv); + edgeflag = 0; + + ned = edge2vert.Size(); + ARRAY missing; + + for (int i = 1; i <= nv; i++) + { + for (int j = 1; j <= vert2edge.EntrySize(i); j++) + { + int ednr = vert2edge.Get(i,j); + int i2 = edge2vert.Get(ednr)[1]; + edgeflag[i2] = i; + edgenr[i2] = ednr; + } + for (int j = 1; j <= vert2vertcoarse.EntrySize(i); j++) + { + int v2 = vert2vertcoarse.Get(i,j); + if (edgeflag[v2] < i) + { + ned++; + edgenr[v2] = ned; + edgeflag[v2] = i; + missing.Append (INDEX_3(i,v2,ned)); + } + } + + for (int 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 (int 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[edge.I2()] < i) + { + ned++; + edgenr[edge.I2()] = ned; + edgeflag[edge.I2()] = i; + } + + int edgenum = edgenr[edge.I2()]; + if (edgedir) edgenum *= -1; + edges.Elem(elnr)[k] = edgenum; + } + } + + for (int 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 (int 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[edge.I2()] < i) + { + ned++; + edgenr[edge.I2()] = ned; + edgeflag[edge.I2()] = i; + } + + int edgenum = edgenr[edge.I2()]; + if (edgedir) edgenum *= -1; + surfedges.Elem(elnr)[k] = edgenum; + } + } + + for (int 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[edge.I2()] < i) + { + ned++; + edgenr[edge.I2()] = ned; + edgeflag[edge.I2()] = i; + } + int edgenum = edgenr[edge.I2()]; + + if (edgedir) edgenum *= -1; + segedges.Elem(elnr) = edgenum; + } + } + + + edge2vert.SetSize (ned); + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement (i); + + int neledges = GetNEdges (el.GetType()); + const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); + + for (int 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 (int i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement (i); + + int neledges = GetNEdges (el.GetType()); + const ELEMENT_EDGE * eledges = GetEdges (el.GetType()); + + for (int 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 (int 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 (int 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 (int i = 1; i <= edge2vert.Size(); i++) + (*testout) << "edge " << i << ", v1,2 = " << edge2vert.Elem(i)[0] << ", " << edge2vert.Elem(i)[1] << endl; + (*testout) << "surfedges:" << endl; + for (int 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; + + // generate faces + if (buildfaces) // && mesh.GetDimension() == 3) + { + int i, j; + + static int timer2 = NgProfiler::CreateTimer ("topology::buildfaces"); + NgProfiler::RegionTimer reg2 (timer2); + + PrintMessage (5, "Update faces "); + + faces.SetSize(ne); + surffaces.SetSize(nse); + + // face2vert.SetSize(0); // keep old faces + nfa = face2vert.Size(); + // INDEX_3_HASHTABLE vert2face(ne+nse+1); + INDEX_3_CLOSED_HASHTABLE 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(face.I1(),face.I2(),face.I3(),0); + face2vert.Append (hface); + // face2vert.SetSize(face2vert.Size()+1); + } + + 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(face4.I1(),face4.I2(),face4.I3(),face4.I4()); + face2vert.Append (hface); + } + + 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(face.I1(),face.I2(),face.I3(),0); + face2vert.Append (hface); + } + + 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(face4.I1(),face4.I2(),face4.I3(),face4.I3()); + 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]+7) / 8; + 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()); + + /* + *testout << "face2vert: "; + face2vert.PrintMemInfo(cout); + *testout << "faces: "; + faces.PrintMemInfo(cout); + *testout << "hashtable: "; + vert2face.PrintMemInfo(cout); + */ + +#ifdef PARALLEL + (*testout) << " RESET Paralleltop" << endl; + + paralleltop.Reset (); +#endif + + ARRAY face_els(nfa), face_surfels(nfa); + face_els = 0; + face_surfels = 0; + ARRAY 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++; +#ifdef PARALLEL + if ( ntasks > 1 ) + { + if ( !paralleltop.DoCoarseUpdate() ) continue; + // "illegal" faces are exchange faces + /* + (*testout) << "exchange face : " << i << endl; + (*testout) << "points = " << face2vert[i] << endl; + */ +// (*testout) << "global points = "; +// for ( int j = 0; j < 3; j++ ) +// // (*testout) << face2vert[i].I(j+1) << " -> " +// // << paralleltop.GetLoc2Glob_Vert( face2vert[i].I(j+1) ) << ", "; +// (*testout) << endl; +// if ( !paralleltop.IsExchangeFace (i+1) ) +// paralleltop.SetRefinementFace (i+1); + + paralleltop.SetExchangeFace (i+1); + + for (int j = 0; j < 4; j++) + { + if ( face2vert[i].I(j+1) > 0 ) + paralleltop.SetExchangeVert(face2vert[i].I(j+1)); + } + + ARRAY faceedges; + GetFaceEdges (i+1, faceedges); + for ( int j = 0; j < faceedges.Size(); j++) + { + paralleltop.SetExchangeEdge ( faceedges[j] ); + int v1, v2; + GetEdgeVertices(faceedges[j], v1, v2 ); + } + + /* + (*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; + */ + } + else + { +#endif + (*testout) << "illegal face : " << i << endl; + (*testout) << "points = " << face2vert[i] << endl; + (*testout) << "pos = "; + for (j = 0; j < 4; j++) + if (face2vert[i].I(j+1) >= 1) + (*testout) << mesh[(PointIndex)face2vert[i].I(j+1)] << " "; + (*testout) << endl; + + FlatArray vertels = GetVertexElements (face2vert[i].I(1)); + for (int k = 0; k < vertels.Size(); k++) + { + int elfaces[10], orient[10]; + int nf = GetElementFaces (vertels[k], elfaces, orient); + for (int l = 0; l < nf; l++) + if (elfaces[l] == i) + { + (*testout) << "is face of element " << vertels[k] << endl; + + if (mesh.coarsemesh && mesh.hpelements->Size() == mesh.GetNE() ) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [ mesh.VolumeElement (vertels[k]).hp_elnr]; + (*testout) << "coarse eleme = " << hpref_el.coarse_elnr << endl; + } + + } + } +#ifdef PARALLEL + } +#endif + } + } + +#ifndef PARALLEL + if (cnt_err) + cout << cnt_err << " elements are not matching !!!" << endl; +#else + if (cnt_err && ntasks == 1) + cout << cnt_err << " elements are not matching !!!" << endl; + else if (cnt_err && ntasks > 1) + { + cout << "p" << id << ": " << cnt_err << " elements are not local" << endl; + isparallel = 1; + } + else if ( ntasks > 1 ) + cout << "p" << id << ": " << "Partition " << id << " is totally local" << endl; +#endif + + } + +#ifdef PARALLEL + + if ( isparallel ) + { + paralleltop.Update(); + if ( paralleltop.DoCoarseUpdate() ) + { + paralleltop.UpdateCoarseGrid(); + } + else + { + // paralleltop.UpdateRefinement(); + } + // paralleltop.Print(); + } + + +#endif + + + + + } + + + + /* +for (i = 1; i <= ne; i++) + { + (*testout) << "Element " << i << endl; + (*testout) << "PNums " << endl; + for( int l=1;l<=8;l++) *testout << mesh.VolumeElement(i).PNum(l) << "\t"; + *testout << endl; + (*testout) << "edges: " << endl; + for (j = 0; j < 9; j++) + (*testout) << edges.Elem(i)[j] << " "; + (*testout) << "faces: " << endl; + for (j = 0; j < 6; j++)m + (*testout) << faces.Elem(i)[j] << " "; + } + + for (i = 1; i <= nse; i++) + { + (*testout) << "SElement " << i << endl; + (*testout) << "PNums " << endl; + for( int l=1;l<=4;l++) *testout << mesh.SurfaceElement(i).PNum(l) << "\t"; + *testout << endl; + } + */ + 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 :: GetNPoints (ELEMENT_TYPE et) +{ + switch (et) + { + case SEGMENT: + return 2; + case SEGMENT3: + return 3; + + case TRIG: + return 3; + case TRIG6: + return 6; + + case QUAD: + case QUAD6: + case QUAD8: + return 4; + + case TET: + return 4; + case TET10: + return 10; + + 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; +} + + + + + + + + +void MeshTopology :: GetElementEdges (int elnr, ARRAY & 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 & elfaces, bool withorientation) 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; + if(withorientation) + { + int orient = (faces.Get(elnr)[i-1]-1) % 8; + if(orient == 1 || orient == 2 || orient == 4 || orient == 7) + elfaces.Elem(i) *= -1; + } + } +} + +void MeshTopology :: GetElementEdgeOrientations (int elnr, ARRAY & 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 & 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 + { + throw NgException("rethink implementation"); + /* + 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 & 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 & 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 & 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 & fedges, bool withorientation) const +{ + ArrayMem pi(4); + ArrayMem eledges; + + fedges.SetSize (0); + GetFaceVertices(fnr, pi); + + // Sort Edges according to global vertex numbers + // e1 = fmax, f2 + // e2 = fmax, f1 + // e3 = op e1(f2,f3) + // e4 = op e2(f1,f3) + + /* ArrayMem fp; + fp[0] = pi[0]; + for(int k=1;kfp[0]) swap(fp[k],fp[0]); + + fp[1] = fp[0]+ */ + + + // GetVertexElements (pi[0], els); + FlatArray 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 nref_faces = GetNFaces (el.GetType()); + const ELEMENT_FACE * ref_faces = GetFaces (el.GetType()); + int nfa_ref_edges = GetNEdges (GetFaceType(fnr)); + + int cntv = 0,fa=-1; + for(int m=0;m0;j++) + for(int k=0;k=0) + { + const ELEMENT_EDGE * fa_ref_edges = GetEdges(GetFaceType(fnr)); + fedges.SetSize(nfa_ref_edges); + 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) // eledges[j] is on face + { + // fedges.Append (eledges[j]); + for(int k=0;k & 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 MeshTopology :: GetVertexElements (int vnr) const +{ + if (vert2element) + return (*vert2element)[vnr]; + return FlatArray (0,0); +} + +FlatArray MeshTopology :: GetVertexSurfaceElements (int vnr) const +{ + if (vert2surfelement) + return (*vert2surfelement)[vnr]; + return FlatArray (0,0); +} + + +void MeshTopology :: GetVertexSurfaceElements( int vnr, + ARRAY& 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); + } +} + + +int MeshTopology :: GetVerticesEdge ( int v1, int v2 ) const +{ + ARRAY elements_v1, elementedges; + GetVertexElements ( v1, elements_v1); + int edv1, edv2; + + for ( int i = 0; i < elements_v1.Size(); i++ ) + { + GetElementEdges( elements_v1[i], elementedges ); + for ( int ed = 0; ed < elementedges.Size(); ed ++) + { + GetEdgeVertices( elementedges[ed], edv1, edv2 ); + if ( ( edv1 == v1 && edv2 == v2 ) || ( edv1 == v2 && edv2 == v1 ) ) + return elementedges[ed]; + } + } + + return -1; +} + + + +void MeshTopology :: GetSegmentVolumeElements ( int segnr, ARRAY & volels ) const +{ + int v1, v2; + GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); + ARRAY volels1, volels2; + GetVertexElements ( v1, volels1 ); + GetVertexElements ( v2, volels2 ); + volels.SetSize(0); + + for ( int eli1=1; eli1 <= volels1.Size(); eli1++) + if ( volels2.Contains( volels1.Elem(eli1) ) ) + volels.Append ( volels1.Elem(eli1) ); + +} +} diff --git a/libsrc/meshing/topology.hpp b/libsrc/meshing/topology.hpp new file mode 100644 index 00000000..9dda8ba1 --- /dev/null +++ b/libsrc/meshing/topology.hpp @@ -0,0 +1,326 @@ +#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; + bool buildedges; + bool buildfaces; + + MoveableArray edge2vert; + MoveableArray face2vert; + MoveableArray edges; + MoveableArray faces; + MoveableArray surfedges; + MoveableArray segedges; + MoveableArray surffaces; + MoveableArray surf2volelement; + MoveableArray face2surfel; + TABLE *vert2element; + TABLE *vert2surfelement; + TABLE *vert2segment; + int timestamp; +public: + int GetNSurfedges() const {return surfedges.Size();} + + MeshTopology (const Mesh & amesh); + ~MeshTopology (); + + void SetBuildEdges (bool be) + { buildedges = be; } + void SetBuildFaces (bool bf) + { buildfaces = bf; } + + bool HasEdges () const + { return buildedges; } + bool HasFaces () const + { return buildfaces; } + + void Update(); + + + int GetNEdges () const + { return edge2vert.Size(); } + int GetNFaces () const + { return face2vert.Size(); } + + static int GetNVertices (ELEMENT_TYPE et); + static int GetNPoints (ELEMENT_TYPE et); + static int GetNEdges (ELEMENT_TYPE et); + static int GetNFaces (ELEMENT_TYPE et); + + static const Point3d * GetVertices (ELEMENT_TYPE et); + inline static const ELEMENT_EDGE * GetEdges (ELEMENT_TYPE et); + inline 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 & edges) const; + void GetElementFaces (int elnr, ARRAY & faces, bool withorientation = false) const; + void GetElementEdgeOrientations (int elnr, ARRAY & eorient) const; + void GetElementFaceOrientations (int elnr, ARRAY & 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 & vertices) const; + void GetFaceVertices (int fnr, int * vertices) const; + void GetEdgeVertices (int fnr, int & v1, int & v2) const; + void GetFaceEdges (int fnr, ARRAY & edges, bool withorientation = false) const; + + ELEMENT_TYPE GetFaceType (int fnr) const; + + void GetSurfaceElementEdges (int elnr, ARRAY & edges) const; + int GetSurfaceElementFace (int elnr) const; + void GetSurfaceElementEdgeOrientations (int elnr, ARRAY & 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 & elements) const; + FlatArray GetVertexElements (int vnr) const; + + void GetVertexSurfaceElements( int vnr, ARRAY& elements ) const; + FlatArray GetVertexSurfaceElements (int vnr) const; + + + + int GetVerticesEdge ( int v1, int v2) const; + void GetSegmentVolumeElements ( int segnr, ARRAY & surfels ) const; +}; + + + + + + + + + + + + + +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 const int trig_faces[1][4] = + { { 1, 2, 3, 0 } }; + static const int quad_faces[1][4] = + { { 1, 2, 3, 4 } }; + + static const int tet_faces[4][4] = + { { 4, 2, 3, 0 }, + { 4, 3, 1, 0 }, + { 4, 1, 2, 0 }, + { 1, 3, 2, 0 } }; + + static const 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 const 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 const 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; +} + + + + + + + + + + + + + + + + + + + + +#endif diff --git a/libsrc/meshing/triarls.cpp b/libsrc/meshing/triarls.cpp new file mode 100644 index 00000000..d82806e9 --- /dev/null +++ b/libsrc/meshing/triarls.cpp @@ -0,0 +1,468 @@ +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 X2, 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/libsrc/meshing/validate.cpp b/libsrc/meshing/validate.cpp new file mode 100644 index 00000000..d519e27c --- /dev/null +++ b/libsrc/meshing/validate.cpp @@ -0,0 +1,587 @@ + +#include +#include "meshing.hpp" + + +namespace netgen +{ + void GetPureBadness(Mesh & mesh, ARRAY & pure_badness, + const BitArray & isnewpoint) + { + //const int ne = mesh.GetNE(); + const int np = mesh.GetNP(); + + pure_badness.SetSize(np+PointIndex::BASE+1); + pure_badness = -1; + + ARRAY< Point<3>* > backup(np); + + for(int i=0; i(mesh.Point(i+1)); + + if(isnewpoint.Test(i+PointIndex::BASE) && + mesh.mlbetweennodes[i+PointIndex::BASE][0] > 0) + { + mesh.Point(i+1) = Center(mesh.Point(mesh.mlbetweennodes[i+PointIndex::BASE][0]), + mesh.Point(mesh.mlbetweennodes[i+PointIndex::BASE][1])); + } + } + for (ElementIndex i = 0; i < mesh.GetNE(); i++) + { + double bad = mesh[i].CalcJacobianBadness (mesh.Points()); + for(int j=0; j pure_badness[mesh[i][j]]) + pure_badness[mesh[i][j]] = bad; + + // save maximum + if(bad > pure_badness.Last()) + pure_badness.Last() = bad; + } + + for(int i=0; i & bad_elements, + const ARRAY & pure_badness, + double max_worsening, const bool uselocalworsening, + ARRAY * quality_loss) + { + PrintMessage(3,"!!!! Validating !!!!"); + //if(max_worsening > 0) + // (*testout) << "badness " << counter++ << endl; + + bad_elements.SetSize(0); + + double loc_pure_badness = -1; + + if(!uselocalworsening) + loc_pure_badness = pure_badness.Last(); // maximum is saved at last position + + + double worsening = -1; + ElementIndex ind; + + if(quality_loss != NULL) + quality_loss->SetSize(mesh.GetNE()); + + for (ElementIndex i = 0; i < mesh.GetNE(); i++) + { + if(uselocalworsening) + { + loc_pure_badness = -1; + for(int j=0; j loc_pure_badness) + loc_pure_badness = pure_badness[mesh[i][j]]; + } + + + double bad = mesh[i].CalcJacobianBadness (mesh.Points()); + if (bad > 1e10 || + (max_worsening > 0 && bad > loc_pure_badness*max_worsening)) + bad_elements.Append(i); + + + if(max_worsening > 0) + { + double actw = bad/loc_pure_badness; + if(quality_loss != NULL) + (*quality_loss)[i] = actw; + + if(actw > worsening) + { + worsening = actw; + ind = i; + } + } + } + return worsening; + } + + + void GetWorkingArea(BitArray & working_elements, BitArray & working_points, + const Mesh & mesh, const ARRAY & bad_elements, + const int width) + { + working_elements.Clear(); + working_points.Clear(); + + for(int i=0; i & bad_elements, + const BitArray & isnewpoint, Refinement & refinement, + const ARRAY & pure_badness, + double max_worsening, const bool uselocalworsening, + const ARRAY< ARRAY* > & idmaps) + { + ostringstream ostrstr; + + const int maxtrials = 100; + + //bool doit; + //cout << "DOIT: " << flush; + //cin >> doit; + + int ne = mesh.GetNE(); + int np = mesh.GetNP(); + + int numbadneighbours = 3; + const int numtopimprove = 3; + + PrintMessage(1,"repairing"); + + PushStatus("Repair Bisection"); + + ARRAY* > should(np); + ARRAY* > can(np); + ARRAY* > nv(np); + for(int i=0; i; + should[i] = new Point<3>; + can[i] = new Point<3>; + } + + BitArray isboundarypoint(np),isedgepoint(np); + isboundarypoint.Clear(); + isedgepoint.Clear(); + + for(int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + isedgepoint.Set(seg.p1); + isedgepoint.Set(seg.p2); + } + + ARRAY surfaceindex(np); + surfaceindex = -1; + + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for (int j = 1; j <= sel.GetNP(); j++) + if(!isedgepoint.Test(sel.PNum(j))) + { + isboundarypoint.Set(sel.PNum(j)); + surfaceindex[sel.PNum(j) - PointIndex::BASE] = + mesh.GetFaceDescriptor(sel.GetIndex()).SurfNr(); + } + } + + + + Validate(mesh,bad_elements,pure_badness, + ((uselocalworsening) ? (0.8*(max_worsening-1.) + 1.) : (0.1*(max_worsening-1.) + 1.)), + uselocalworsening); // -> larger working area + BitArray working_elements(ne); + BitArray working_points(np); + + GetWorkingArea(working_elements,working_points,mesh,bad_elements,numbadneighbours); + //working_elements.Set(); + //working_points.Set(); + + ostrstr.str(""); + ostrstr << "worsening: " << + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + PrintMessage(4,ostrstr.str()); + + + + int auxnum=0; + for(int i=1; i<=np; i++) + if(working_points.Test(i)) + auxnum++; + + ostrstr.str(""); + ostrstr << "Percentage working points: " << 100.*double(auxnum)/np; + PrintMessage(5,ostrstr.str()); + + + BitArray isworkingboundary(np); + for(int i=1; i<=np; i++) + if(working_points.Test(i) && isboundarypoint.Test(i)) + isworkingboundary.Set(i); + else + isworkingboundary.Clear(i); + + + for(int i=0; i 0) + *can[i] = Center(*can[mesh.mlbetweennodes[i+PointIndex::BASE][0]-PointIndex::BASE], + *can[mesh.mlbetweennodes[i+PointIndex::BASE][1]-PointIndex::BASE]); + else + *can[i] = mesh.Point(i+1); + } + + + int cnttrials = 1; + + double lamedge = 0.5; + double lamface = 0.5; + + double facokedge = 0; + double facokface = 0; + double factryedge; + double factryface = 0; + + double oldlamedge,oldlamface; + + MeshOptimize2d * optimizer2d = refinement.Get2dOptimizer(); + if(!optimizer2d) + { + cerr << "No 2D Optimizer!" << endl; + return; + } + + while ((facokedge < 1.-1e-8 || facokface < 1.-1e-8) && + cnttrials < maxtrials && + multithread.terminate != 1) + { + (*testout) << " facokedge " << facokedge << " facokface " << facokface << " cnttrials " << cnttrials << endl + << " perc. " << 95. * max2( min2(facokedge,facokface), + double(cnttrials)/double(maxtrials)) << endl; + + SetThreadPercent(95. * max2( min2(facokedge,facokface), + double(cnttrials)/double(maxtrials))); + + ostrstr.str(""); + ostrstr << "max. worsening " << max_worsening; + PrintMessage(5,ostrstr.str()); + oldlamedge = lamedge; + lamedge *= 6; + if (lamedge > 2) + lamedge = 2; + + if(1==1 || facokedge < 1.-1e-8) + { + for(int i=0; i(0,0,0); + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + Vec<3> auxvec = Cross(mesh.Point(sel.PNum(2))-mesh.Point(sel.PNum(1)), + mesh.Point(sel.PNum(3))-mesh.Point(sel.PNum(1))); + auxvec.Normalize(); + for (int j = 1; j <= sel.GetNP(); j++) + if(!isedgepoint.Test(sel.PNum(j))) + *nv[sel.PNum(j) - PointIndex::BASE] += auxvec; + } + for(int i=0; iNormalize(); + + + do // move edges + { + lamedge *= 0.5; + cnttrials++; + if(cnttrials % 10 == 0) + max_worsening *= 1.1; + + + factryedge = lamedge + (1.-lamedge) * facokedge; + + ostrstr.str(""); + ostrstr << "lamedge = " << lamedge << ", trying: " << factryedge; + PrintMessage(5,ostrstr.str()); + + + for (int i = 1; i <= np; i++) + { + if (isedgepoint.Test(i)) + { + for (int j = 0; j < 3; j++) + mesh.Point(i)(j) = + lamedge * (*should.Get(i))(j) + + (1.-lamedge) * (*can.Get(i))(j); + } + else + mesh.Point(i) = *can.Get(i); + } + if(facokedge < 1.-1e-8) + { + ostrstr.str(""); + ostrstr << "worsening: " << + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + + PrintMessage(5,ostrstr.str()); + } + else + Validate(mesh,bad_elements,pure_badness,-1,uselocalworsening); + + + ostrstr.str(""); + ostrstr << bad_elements.Size() << " bad elements"; + PrintMessage(5,ostrstr.str()); + } + while (bad_elements.Size() > 0 && + cnttrials < maxtrials && + multithread.terminate != 1); + } + + if(cnttrials < maxtrials && + multithread.terminate != 1) + { + facokedge = factryedge; + + // smooth faces + mesh.CalcSurfacesOfNode(); + + mesh.ImproveMeshJacobianOnSurface(isworkingboundary,nv,OPT_QUALITY,&idmaps); + + for (int i = 1; i <= np; i++) + *can.Elem(i) = mesh.Point(i); + + if(optimizer2d) + optimizer2d->ProjectBoundaryPoints(surfaceindex,can,should); + } + + + oldlamface = lamface; + lamface *= 6; + if (lamface > 2) + lamface = 2; + + + if(cnttrials < maxtrials && + multithread.terminate != 1) + { + + do // move faces + { + lamface *= 0.5; + cnttrials++; + if(cnttrials % 10 == 0) + max_worsening *= 1.1; + factryface = lamface + (1.-lamface) * facokface; + + ostrstr.str(""); + ostrstr << "lamface = " << lamface << ", trying: " << factryface; + PrintMessage(5,ostrstr.str()); + + + for (int i = 1; i <= np; i++) + { + if (isboundarypoint.Test(i)) + { + for (int j = 0; j < 3; j++) + mesh.Point(i)(j) = + lamface * (*should.Get(i))(j) + + (1.-lamface) * (*can.Get(i))(j); + } + else + mesh.Point(i) = *can.Get(i); + } + + ostrstr.str(""); + ostrstr << "worsening: " << + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + PrintMessage(5,ostrstr.str()); + + + ostrstr.str(""); + ostrstr << bad_elements.Size() << " bad elements"; + PrintMessage(5,ostrstr.str()); + } + while (bad_elements.Size() > 0 && + cnttrials < maxtrials && + multithread.terminate != 1); + } + + + + if(cnttrials < maxtrials && + multithread.terminate != 1) + { + facokface = factryface; + // smooth interior + + mesh.CalcSurfacesOfNode(); + + mesh.ImproveMeshJacobian (OPT_QUALITY,&working_points); + //mesh.ImproveMeshJacobian (OPT_WORSTCASE,&working_points); + + + for (int i = 1; i <= np; i++) + *can.Elem(i) = mesh.Point(i); + } + + //! + if((facokedge < 1.-1e-8 || facokface < 1.-1e-8) && + cnttrials < maxtrials && + multithread.terminate != 1) + { + MeshOptimize3d optmesh; + for(int i=0; iProjectBoundaryPoints(surfaceindex,can,should); + + + for (int i = 1; i <= np; i++) + if(isboundarypoint.Test(i)) + for(int j=1; j<=3; j++) + mesh.Point(i).X(j) = should.Get(i).X(j); + } + */ + + + if(cnttrials == maxtrials) + { + for (int i = 1; i <= np; i++) + mesh.Point(i) = *should.Get(i); + + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + + for(int i=0; i & pure_badness, + const BitArray & isnewpoint); +double Validate(const Mesh & mesh, ARRAY & bad_elements, + const ARRAY & pure_badness, + double max_worsening, const bool uselocalworsening, + ARRAY * quality_loss = NULL); +void RepairBisection(Mesh & mesh, ARRAY & bad_elements, const BitArray & isnewpoint, Refinement & refinement, + const ARRAY & pure_badness, + double max_worsening, const bool uselocalworsening, + const ARRAY< ARRAY* > & idmaps); + +#endif // VALIDATE_HPP diff --git a/libsrc/meshing/zrefine.cpp b/libsrc/meshing/zrefine.cpp new file mode 100644 index 00000000..1218a6d7 --- /dev/null +++ b/libsrc/meshing/zrefine.cpp @@ -0,0 +1,741 @@ +#include +#include "meshing.hpp" + +#include + +namespace netgen +{ + + // find singular edges + void SelectSingularEdges (const Mesh & mesh, const CSGeometry & geom, + INDEX_2_HASHTABLE & singedges, + ZRefinementOptions & opt) + { + int i, j; + + // edges selected in csg input file + for (i = 1; i <= geom.singedges.Size(); i++) + { + //if(geom.singedges.Get(i)->maxhinit > 0) + // continue; //!!!! + + 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 & 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 & cornernodes) + { + int i, j; + int nseg = mesh.GetNSeg(); + ARRAY 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; + bool found, change; + int cnt = 0; + + + // markers for z-refinement: p1, p2, levels + // p1-p2 is an edge to be refined + ARRAY ref_uniform; + ARRAY ref_singular; + ARRAY ref_slices; + + BitArray first_id(geom->identifications.Size()); + first_id.Set(); + + + INDEX_2_HASHTABLE & 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 + (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 & 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 epgi; + + while (1) + { + cnt++; + PrintMessage (3, "Z-Refinement, level = ", cnt); + INDEX_2_HASHTABLE 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(0); + + 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 + (geom->identifications.Get(idnr)); + + + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (!refedges.Used(edge)) + { + const ARRAY & slices = csid->GetSlices(); + //(*testout) << "idnr " << idnr << " i " << i << endl; + //(*testout) << "slices " << slices << endl; + double slicefac = slices.Get(slicenr); + double slicefaclast = + (slicenr == slices.Size()) ? 1 : slices.Get(slicenr+1); + + Point3d np = p1 + (slicefac / slicefaclast) * (p2-p1); + //(*testout) << "slicenr " << slicenr << " slicefac " << slicefac << " quot " << (slicefac / slicefaclast) << " np " << np << endl; + 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 singedges(mesh.GetNSeg()); + + SelectSingularEdges (mesh, *geom, singedges, opt); + //MakePrismsSingEdge (mesh, singedges); + MakePrismsClosePoints (mesh); + + RefinePrisms (mesh, geom, opt); + } + + + + ZRefinementOptions :: ZRefinementOptions() + { + minref = 0; + } + +} diff --git a/libsrc/occ/Makefile.am b/libsrc/occ/Makefile.am new file mode 100644 index 00000000..411455d2 --- /dev/null +++ b/libsrc/occ/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libocc.a +libocc_a_SOURCES = Partition_Inter2d.cxx Partition_Inter3d.cxx \ + Partition_Loop.cxx Partition_Loop2d.cxx Partition_Loop3d.cxx Partition_Spliter.cxx \ + occconstruction.cpp occgenmesh.cpp occgeom.cpp occmeshsurf.cpp diff --git a/libsrc/occ/Makefile.in b/libsrc/occ/Makefile.in new file mode 100644 index 00000000..ce341bd8 --- /dev/null +++ b/libsrc/occ/Makefile.in @@ -0,0 +1,476 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/occ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libocc_a_AR = $(AR) $(ARFLAGS) +libocc_a_LIBADD = +am_libocc_a_OBJECTS = Partition_Inter2d.$(OBJEXT) \ + Partition_Inter3d.$(OBJEXT) Partition_Loop.$(OBJEXT) \ + Partition_Loop2d.$(OBJEXT) Partition_Loop3d.$(OBJEXT) \ + Partition_Spliter.$(OBJEXT) occconstruction.$(OBJEXT) \ + occgenmesh.$(OBJEXT) occgeom.$(OBJEXT) occmeshsurf.$(OBJEXT) +libocc_a_OBJECTS = $(am_libocc_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libocc_a_SOURCES) +DIST_SOURCES = $(libocc_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libocc.a +libocc_a_SOURCES = Partition_Inter2d.cxx Partition_Inter3d.cxx \ + Partition_Loop.cxx Partition_Loop2d.cxx Partition_Loop3d.cxx Partition_Spliter.cxx \ + occconstruction.cpp occgenmesh.cpp occgeom.cpp occmeshsurf.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .cxx .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/occ/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/occ/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libocc.a: $(libocc_a_OBJECTS) $(libocc_a_DEPENDENCIES) + -rm -f libocc.a + $(libocc_a_AR) libocc.a $(libocc_a_OBJECTS) $(libocc_a_LIBADD) + $(RANLIB) libocc.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Inter2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Inter3d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Loop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Loop2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Loop3d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Spliter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occconstruction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occgenmesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occgeom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occmeshsurf.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +.cxx.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/occ/Partition_Inter2d.cxx b/libsrc/occ/Partition_Inter2d.cxx new file mode 100644 index 00000000..3bac13b2 --- /dev/null +++ b/libsrc/occ/Partition_Inter2d.cxx @@ -0,0 +1,677 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R& D, LEG, PRINCIPIA R& D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter2d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Inter2d.cxx,v 1.5 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include "Partition_Inter2d.ixx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEB +static Standard_Boolean TestEdges = 0; +static Standard_Integer NbF2d = 0; +static Standard_Integer NbE2d = 0; +#endif + +//======================================================================= +//function : getOtherShape +//purpose : +//======================================================================= + +static TopoDS_Shape getOtherShape(const TopoDS_Shape& theS, + const TopTools_ListOfShape& theSList) +{ + TopTools_ListIteratorOfListOfShape anIt( theSList ); + for ( ; anIt.More(); anIt.Next() ) + if (!theS.IsSame( anIt.Value() )) + return anIt.Value(); + + return TopoDS_Shape(); +} + +//======================================================================= +//function : findVOnE +//purpose : on theE, find a vertex close to theV, such that an edge +// passing through it is an itersection of theF1 and theF2. +// theE intersects theE2 at theV +//======================================================================= + +static Standard_Boolean findVOnE(const TopoDS_Vertex & theV, + const TopoDS_Edge& theE, + const TopoDS_Edge& theE2, + const TopoDS_Shape& theF1, + const TopoDS_Shape& theF2, + const Handle(BRepAlgo_AsDes)& theAsDes, + TopoDS_Vertex & theFoundV) +{ + Standard_Real MinDist2 = ::RealLast(); + gp_Pnt P; + + // check all vertices on theE + const TopTools_ListOfShape& aVList = theAsDes->Descendant( theE ); + TopTools_ListIteratorOfListOfShape anIt( aVList ); + if (anIt.More()) + P = BRep_Tool::Pnt( theV ); + for ( ; anIt.More(); anIt.Next() ) + { + // check by distance + TopoDS_Vertex & V = TopoDS::Vertex( anIt.Value() ); + Standard_Real dist2 = P.SquareDistance( BRep_Tool::Pnt( V )); + if (dist2 < MinDist2) + MinDist2 = dist2; + else + continue; + + // V is a candidate if among edges passing through V there is one + // which is an intersection of theF1 and theF2 + TopTools_ListIteratorOfListOfShape anEIt( theAsDes->Ascendant( V )); + Standard_Boolean isOk = Standard_False; + for ( ; !isOk && anEIt.More(); anEIt.Next() ) + { + const TopoDS_Shape & E2 = anEIt.Value(); + if ( theE2.IsSame( E2 )) + continue; + const TopTools_ListOfShape & aFList = theAsDes->Ascendant( E2 ); + if (aFList.IsEmpty()) + continue; + if ( theF1.IsSame( aFList.First() )) + isOk = theF2.IsSame( aFList.Last() ); + else + isOk = theF2.IsSame( aFList.First() ) && theF1.IsSame( aFList.Last() ); + } + if (isOk) + theFoundV = V; + } + + if (theFoundV.IsNull()) + return Standard_False; + + // check that MinDist2 is not too large + Standard_Real f, l; + TopLoc_Location L; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theE, L, f, l ); + gp_Pnt P1 = aCurve->Value( f ); + gp_Pnt P2 = aCurve->Value( 0.3 * f + 0.7 * l ); + //gp_Pnt P2 = aCurve->Value( 0.5 * ( f + l )); + if (MinDist2 > P1.SquareDistance( P2 )) + return Standard_False; + +#ifdef DEB + MESSAGE("findVOnE: found MinDist = " << sqrt (MinDist2)); +#endif + + return Standard_True; +} + +//======================================================================= +//function : AddVonE +//purpose : Put V in AsDes as intersection of E1 and E2. +// Check that vertex equal to V already exists on one +// of edges, in such a case, V is not added but +// existing vertex is updated to be on E1 and E2 and +// is returned insead of V. +//======================================================================= + +TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV, + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + const TopoDS_Face& theF) + +{ + //------------------------------------------------------------- + // test if the points of intersection already exist. If not, + // add as descendants of the edges. + // nb: theses points are only vertices of intersection. + //------------------------------------------------------------- + const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1); + const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2); + gp_Pnt P1,P2; + TopoDS_Vertex V1,V2; + TopTools_ListIteratorOfListOfShape it; + BRep_Builder B; + TopAbs_Orientation O1,O2; + Standard_Real U1,U2; + Standard_Real Tol,Tol1,Tol2; + Standard_Boolean OnE1,OnE2; + + TopoDS_Vertex V = theV; + + U1 = BRep_Tool::Parameter(V,E1); + U2 = BRep_Tool::Parameter(V,E2); + O1 = V.Orientation(); + O2 = O1; + P1 = BRep_Tool::Pnt(V); + Tol = BRep_Tool::Tolerance( V ); + OnE1 = OnE2 = Standard_False; + + //----------------------------------------------------------------- + // Search if the point of intersection is a vertex of E1. + //----------------------------------------------------------------- + for (it.Initialize(VOnE1); it.More(); it.Next()) { + const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); + if (V.IsSame( CV )) { + V1 = V; + OnE1 = Standard_True; + break; + } + P2 = BRep_Tool::Pnt( CV ); + Tol1 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); + if (P1.SquareDistance(P2) <= Tol1*Tol1) { + V = CV; + V1 = V; + OnE1 = Standard_True; + break; + } + } + if (OnE1) { + //----------------------------------------------------------------- + // Search if the vertex found is still on E2. + //----------------------------------------------------------------- + for (it.Initialize(VOnE2); it.More(); it.Next()) { + if (V.IsSame( it.Value() )) { + OnE2 = Standard_True; + V2 = V; + break; + } + } + } + if (!OnE2) { + for (it.Initialize(VOnE2); it.More(); it.Next()) { + //----------------------------------------------------------------- + // Search if the point of intersection is a vertex of E2. + //----------------------------------------------------------------- + const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); + P2 = BRep_Tool::Pnt( CV ); + Tol2 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); + if (P1.SquareDistance(P2) <= Tol2*Tol2) { + V = CV; + V2 = V; + OnE2 = Standard_True; + break; + } + } + } + + + if (!OnE1 && !OnE2 && !theF.IsNull()) + { + // if 3 faces intersects each others, 3 new edges on them must pass + // through one vertex but real intersection points of each + // pair of edges are sometimes more far than a tolerance. + // Try to analitically find vertices that E1 and E2 must pass trough + + TopoDS_Shape F1 = getOtherShape( theF, AsDes->Ascendant( E1 )); + TopoDS_Shape F2 = getOtherShape( theF, AsDes->Ascendant( E2 )); + if (!F1.IsNull() && !F2.IsNull() && !F1.IsSame( F2 )) + { + OnE1 = findVOnE ( theV, E1, E2, F1, F2, AsDes, V1 ); + OnE2 = findVOnE ( theV, E2, E1, F1, F2, AsDes, V2 ); + if (OnE2) V = V2; + if (OnE1) V = V1; + } + } + + if (OnE1 && OnE2) { + if (!V1.IsSame(V2)) { + // replace V1 with V2 on all edges V1 is on + Standard_Real UV1; + TopoDS_Edge EWE1; + TopoDS_Vertex VI; + const TopTools_ListOfShape& EdgeWithV1 = AsDes->Ascendant(V1); + + for (it.Initialize(EdgeWithV1); it.More(); it.Next()) { + EWE1 = TopoDS::Edge(it.Value()); + VI = V1; + VI.Orientation(TopAbs_INTERNAL); + UV1 = BRep_Tool::Parameter(VI,EWE1); + VI = V2; + VI.Orientation(TopAbs_INTERNAL); + B.UpdateVertex( VI, UV1, EWE1, GetTolerance( VI, UV1, EWE1, AsDes)); + } + AsDes->Replace(V1,V2); + V = V2; + } + } + + // add existing vertices instead of new ones + if (!OnE1) { + if (OnE2) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex (V, U1, E1, GetTolerance( V, U1, E1, AsDes)); + } + V.Orientation(O1); + AsDes->Add(E1,V); + } + if (!OnE2) { + if (OnE1) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex (V, U2, E2, GetTolerance( V, U2, E2, AsDes )); + } + V.Orientation(O2); + AsDes->Add(E2,V); + } + + return V; +} + +//======================================================================= +//function : FindEndVertex +//purpose : Returns a vertex from having parameter on +// closest to or . is True if +// found vertex is closer to . returns parameter +// difference. +//======================================================================= + +TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV, + const Standard_Real f, + const Standard_Real l, + const TopoDS_Edge& E, + Standard_Boolean& isFirst, + Standard_Real& minDU) +{ + TopoDS_Vertex endV; + Standard_Real U, endU, min; + minDU = 1.e10; + + TopTools_ListIteratorOfListOfShape it; + it.Initialize(LV); + for (; it.More(); it.Next()) { + const TopoDS_Vertex& v = TopoDS::Vertex(it.Value()); + U = BRep_Tool::Parameter(v, E); + min = Min( Abs(U-f), Abs(U-l) ); + if (min < minDU) { + endV = v; + endU = U; + minDU = min; + } + } + if (Abs(endU-f) < Abs(endU-l)) + isFirst = Standard_True; + else + isFirst = Standard_False; + + return endV; +} + +//======================================================================= +//function : treatClosed +//purpose : add second vertex to closed edge. Vertex is one of +//======================================================================= + +static void treatClosed (const TopoDS_Edge& E1, + const Standard_Real f, + const Standard_Real l, + TopTools_ListOfShape& LV1, + TopTools_ListOfShape& /*LV2*/) +{ + Standard_Boolean isFirst=0; + Standard_Real minDU = 1.e10; + TopoDS_Vertex endV; + endV = Partition_Inter2d::FindEndVertex(LV1, f,l, E1, isFirst,minDU); + + if (minDU > Precision::PConfusion()) + return; // not end point + + Standard_Real newU; + if (isFirst) + newU = f + (l - f); + else + newU = l - (l - f); + + // update end parameter + BRep_Builder B; + endV.Orientation(TopAbs_INTERNAL); + B.UpdateVertex(endV,newU,E1,BRep_Tool::Tolerance(endV)); +} + +//======================================================================= +//function : EdgesPartition +//purpose : +//======================================================================= + +static void EdgesPartition(const TopoDS_Face& F, + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + const TopTools_MapOfShape& NewEdges, + const Standard_Boolean WithOri) +{ + + Standard_Real f[3],l[3]; + Standard_Real MilTol2; + Standard_Real Tol = Max (BRep_Tool::Tolerance(E1), + BRep_Tool::Tolerance(E2)); + MilTol2 = Tol * Tol * 10; + + BRep_Tool::Range(E1, f[1], l[1]); + BRep_Tool::Range(E2, f[2], l[2]); + + BRepAdaptor_Curve CE1(E1,F); + BRepAdaptor_Curve CE2(E2,F); + + TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2; + TopTools_ListOfShape LV1; // new vertices at intersections on E1 + TopTools_ListOfShape LV2; // ... on E2 + BRep_Builder B; + + // if E1 and E2 are results of intersection of F and two connex faces then + // no need to intersect edges, they can contact by vertices only + // (encounted an exception in TopOpeBRep_EdgesIntersector in such a case) + Standard_Boolean intersect = Standard_True; + TopTools_IndexedMapOfShape ME; + TopExp::MapShapes(F, TopAbs_EDGE, ME); + if (!ME.Contains(E1) && ! ME.Contains(E2)) { // if E1 and E2 are new on F + TopoDS_Shape F1, F2; + const TopTools_ListOfShape& LF1 = AsDes->Ascendant( E1 ); + F1 = F.IsSame( LF1.First() ) ? LF1.Last() : LF1.First(); + const TopTools_ListOfShape& LF2 = AsDes->Ascendant( E2 ); + F2 = F.IsSame( LF2.First() ) ? LF2.Last() : LF2.First(); + if (!F.IsSame(F2) && !F.IsSame(F1) ) { + TopExp_Explorer exp(F2, TopAbs_EDGE); + TopExp::MapShapes(F1, TopAbs_EDGE, ME); + for (; exp.More(); exp.Next()) { + if (ME.Contains( exp.Current())) { + intersect = Standard_False; + break; + } + } + } + } + + if (intersect) { + //------------------------------------------------------ + // compute the points of Intersection in 2D + //----------------------------------------------------- + // i.e. fill LV1 and LV2 + TopOpeBRep_EdgesIntersector EInter; + EInter.SetFaces(F,F); + Standard_Real TolDub = 1.e-7; + EInter.ForceTolerances(TolDub,TolDub); + Standard_Boolean reducesegments = Standard_False; + EInter.Perform (E1,E2,reducesegments); + + Standard_Boolean rejectreducedsegmentpoints = Standard_False; + EInter.InitPoint(rejectreducedsegmentpoints); + for ( ; EInter.MorePoint(); EInter.NextPoint() ) + { + const TopOpeBRep_Point2d& P2D = EInter.Point(); + const gp_Pnt& P = P2D.Value(); + TopoDS_Vertex V = BRepLib_MakeVertex(P); + + //------------------------- + // control the point found. + //------------------------- + gp_Pnt P1 = CE1.Value(P2D.Parameter(1)); + gp_Pnt P2 = CE2.Value(P2D.Parameter(2)); + Standard_Real sqd1 = P1.SquareDistance(P); + Standard_Real sqd2 = P2.SquareDistance(P); + if (sqd1 > MilTol2 || sqd2 > MilTol2 ) + continue; + + // add a new vertex to the both edges + Standard_Real toler = Max( Tol, sqrt( Max( sqd1, sqd2 ))); + Standard_Integer i; + for (i = 1; i <= 2; i++) { + Standard_Real U = P2D.Parameter(i); + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex( V,U,EI[i], toler); + TopAbs_Orientation OO = TopAbs_REVERSED; + if (WithOri) { + if (P2D.IsVertex(i)) + OO = P2D.Vertex(i).Orientation(); + else if (P2D.Transition(i).Before() == TopAbs_OUT) { + OO = TopAbs_FORWARD; + } + V.Orientation(OO); + if (i == 1) LV1.Append(V); + else LV2.Append(V); + } + } + } + } // if (intersect) + + //---------------------------------- + // Test the extremities of the edges. + //---------------------------------- + // add to LV* vertices for vertex-vertex closeness + Standard_Real U1,U2; + Standard_Real TolConf2, TolConf; + TopoDS_Vertex V1[2],V2[2]; + TopExp::Vertices(E1,V1[0],V1[1]); + TopExp::Vertices(E2,V2[0],V2[1]); + + Standard_Integer i,j,k; + for (j = 0; j < 2; j++) { + if (V1[j].IsNull()) continue; + for ( k = 0; k < 2; k++) { + if (V2[k].IsNull()) continue; + gp_Pnt P1 = BRep_Tool::Pnt(V1[j]); + gp_Pnt P2 = BRep_Tool::Pnt(V2[k]); + TolConf = BRep_Tool::Tolerance(V1[j]) + BRep_Tool::Tolerance(V2[k]); + TolConf = Max (Tol, TolConf); + TolConf2 = TolConf * TolConf; + if (!intersect) + TolConf2 *= 100; + Standard_Real SqDist = P1.SquareDistance(P2); + + if (SqDist <= TolConf2) { + TopoDS_Vertex V = BRepLib_MakeVertex(P1); + V.Orientation(TopAbs_INTERNAL); + U1 = (j == 0) ? f[1] : l[1]; + U2 = (k == 0) ? f[2] : l[2]; + B.UpdateVertex(V,U1,E1,TolConf); + B.UpdateVertex(V,U2,E2,TolConf); + LV1.Prepend(V.Oriented(V1[j].Orientation())); + LV2.Prepend(V.Oriented(V2[k].Orientation())); + } + } + } + + Standard_Boolean AffichPurge = Standard_False; + + if ( LV1.IsEmpty()) return; + + //---------------------------------- + // Purge of all the vertices. + //---------------------------------- + // remove one of close vertices + TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1; + gp_Pnt P1,P2; + Standard_Boolean Purge = Standard_True; + + while (Purge) { + i = 1; + Purge = Standard_False; + for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); + it1LV1.More(); + it1LV1.Next(),it1LV2.Next()) { + j = 1; + it2LV1.Initialize(LV1); + while (j < i) { + const TopoDS_Vertex& VE1 = TopoDS::Vertex(it1LV1.Value()); + const TopoDS_Vertex& VE2 = TopoDS::Vertex(it2LV1.Value()); + Standard_Real Tol1 = BRep_Tool::Tolerance( VE1 ); + Standard_Real Tol2 = BRep_Tool::Tolerance( VE2 ); + P1 = BRep_Tool::Pnt( VE1 ); + P2 = BRep_Tool::Pnt( VE2 ); + if (P1.IsEqual(P2, Tol1 + Tol2)) { + LV1.Remove(it1LV1); + LV2.Remove(it1LV2); + Purge = Standard_True; + break; + } + j++; + it2LV1.Next(); + } + if (Purge) break; + i++; + } + } + + // care of new closed edges, they always intersect with seam at end + if (V1[0].IsSame( V1[1] ) && NewEdges.Contains(E1) ) + treatClosed (E1, f[1], l[1], LV1, LV2); + if (V2[0].IsSame( V2[1] ) && NewEdges.Contains(E2) ) + treatClosed (E2, f[2], l[2], LV2, LV1); + + //---------------- + // Stocking vertex + //---------------- + + for ( it1LV1.Initialize( LV1 ); it1LV1.More(); it1LV1.Next()) + Partition_Inter2d::AddVonE (TopoDS::Vertex( it1LV1.Value()), + E1, E2, AsDes, F); +} + +//======================================================================= +//function : CompletPart2d +//purpose : Computes the intersections between the edges stored +// is AsDes as descendants of . Intersections is computed +// between two edges if one of them is bound in NewEdges. +//======================================================================= + +void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, + const TopoDS_Face& F, + const TopTools_MapOfShape& NewEdges) +{ + +#ifdef DEB + NbF2d++; + NbE2d = 0; +#endif + + //Do not intersect the edges of a face + TopTools_IndexedMapOfShape EdgesOfFace; + TopExp::MapShapes( F, TopAbs_EDGE , EdgesOfFace); + + //------------------------------------------------------------------- + // compute the intersection2D on the faces touched by the intersection3D + //------------------------------------------------------------------- + TopTools_ListIteratorOfListOfShape it1LE ; + TopTools_ListIteratorOfListOfShape it2LE ; + + //----------------------------------------------- + // Intersection edge-edge. + //----------------------------------------------- + const TopTools_ListOfShape& LE = AsDes->Descendant(F); + TopoDS_Vertex V1,V2; + Standard_Integer j, i = 1; + + TopoDS_Face FF = F; + FF.Orientation(TopAbs_FORWARD); + + for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) { + const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value()); + j = 1; + it2LE.Initialize(LE); + + while (j < i && it2LE.More()) { + const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value()); + //---------------------------------------------------------- + // Intersections of the new edges obtained by intersection + // between them and with the restrictions edges + //---------------------------------------------------------- + if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) && + (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) { + EdgesPartition(FF,E1,E2,AsDes,NewEdges,Standard_True); + } + it2LE.Next(); + j++; + } + i++; + } +} + +//======================================================================= +//function : GetTolerance +//purpose : Returns tolerance theV must have atfer its +// addition to theE with theU parameter. theAsDes is +// used to find pcurves of theE +//======================================================================= + +Standard_Real Partition_Inter2d::GetTolerance + (const TopoDS_Vertex & theV, + const Standard_Real theU, + const TopoDS_Edge & theE, + const Handle(BRepAlgo_AsDes)& theAsDes) +{ + Standard_Real aTol = BRep_Tool::Tolerance( theV ); + gp_Pnt aPnt = BRep_Tool::Pnt( theV ); + + // check point on 3D curve + Standard_Real f,l; + Handle(Geom_Curve) C = BRep_Tool::Curve( theE, f, l ); + if (!C.IsNull()) + aTol = Max ( aTol, aPnt.Distance( C->Value( theU ))); + + // check points on pcurves + const TopTools_ListOfShape& aFList = theAsDes->Ascendant( theE ); + TopTools_ListIteratorOfListOfShape aFIt( aFList ); + for ( ; aFIt.More(); aFIt.Next() ) + { + const TopoDS_Face& F = TopoDS::Face( aFIt.Value() ); + Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( theE, F, f, l ); + if (!pcurve.IsNull()) + { + gp_Pnt2d aPnt2d = pcurve->Value( theU ); + TopLoc_Location L; + Handle(Geom_Surface) S = BRep_Tool::Surface( F, L ); + gp_Pnt aPntOnS = S->Value( aPnt2d.X(), aPnt2d.Y() ); + if (!L.IsIdentity()) + aPntOnS.Transform( L.Transformation() ); + aTol = Max ( aTol, aPnt.Distance( aPntOnS )); + } + } + + return aTol; +} + +#endif diff --git a/libsrc/occ/Partition_Inter3d.cxx b/libsrc/occ/Partition_Inter3d.cxx new file mode 100644 index 00000000..3775e5b3 --- /dev/null +++ b/libsrc/occ/Partition_Inter3d.cxx @@ -0,0 +1,945 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter3d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Inter3d.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include + +#include "Partition_Inter2d.hxx" +#include "Partition_Inter3d.ixx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEB +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Inter3d +//purpose : +//======================================================================= + +Partition_Inter3d::Partition_Inter3d() +{ +} +//======================================================================= +//function : Partition_Inter3d +//purpose : +//======================================================================= + +Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes) + :myAsDes(AsDes) +{ + mySectionEdgesAD = new BRepAlgo_AsDes; +} + +//======================================================================= +//function : CompletPart3d +//purpose : FaceShapeMap is just to know the shape a face belongs to +//======================================================================= + +void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1, + const TopTools_DataMapOfShapeShape& FaceShapeMap) +{ + if (myAsDes.IsNull()) + myAsDes = new BRepAlgo_AsDes; + + TopTools_ListIteratorOfListOfShape it; + + //--------------------------------------------------------------- + // Construction of bounding boxes. + //--------------------------------------------------------------- + + BRep_Builder B; + TopoDS_Compound CompOS; + B.MakeCompound(CompOS); + for (it.Initialize(SetOfFaces1); it.More(); it.Next()) + B.Add(CompOS, it.Value()); + + TopOpeBRepTool_BoxSort BOS; + BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE); + + for (it.Initialize(SetOfFaces1); it.More(); it.Next()) { + TopoDS_Face F1 = TopoDS::Face(it.Value()); + + // avoid intersecting faces of one shape + TopoDS_Shape S1; + if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1); + + // to filter faces sharing an edge + TopTools_IndexedMapOfShape EM; + TopExp::MapShapes( F1, TopAbs_EDGE, EM); + + TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1); + for (; itLI.More(); itLI.Next()) { + TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI)); + if (F1.IsSame(F2) || IsDone(F1,F2)) + continue; + + TopoDS_Shape S2; + if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2); + if (!S1.IsNull() && S1.IsSame(S2)) + continue; // descendants of one shape + + TopExp_Explorer expE (F2, TopAbs_EDGE); + for ( ; expE.More(); expE.Next()) + if (EM.Contains( expE.Current() )) + break; + if (expE.More()) + { + // faces have a common edge, check if they are a tool and a face + // generated by the tool in another shape; in that case they are + // to be intersected + TopLoc_Location L1, L2; + Handle(Geom_Surface) S1 = BRep_Tool::Surface( F1, L1 ); + Handle(Geom_Surface) S2 = BRep_Tool::Surface( F2, L2 ); + if ( S1 != S2 || L1 != L2 ) + continue; + } + + F1.Orientation(TopAbs_FORWARD); + F2.Orientation(TopAbs_FORWARD); + FacesPartition(F1,F2); + } + + // mark as modified a face which has at least one new edge + if (!myAsDes->HasDescendant( F1 )) + continue; + TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 )); + for ( ; itE.More(); itE.Next()) { + if (myNewEdges.Contains( itE.Value())) { + myTouched.Add( F1 ); + break; + } + } + } +} + +//======================================================================= +//function : PutInBounds +//purpose : +//======================================================================= + +static void PutInBounds (const TopoDS_Face& F, + const TopoDS_Edge& E, + Handle(Geom2d_Curve)& C2d) +{ + Standard_Real umin,umax,vmin,vmax; + Standard_Real f,l; + BRep_Tool::Range(E,f,l); + + TopLoc_Location L; // Recup S avec la location pour eviter la copie. + Handle (Geom_Surface) S = BRep_Tool::Surface(F,L); + + if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { + S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface(); + } + if (!S->IsUPeriodic() && !S->IsVPeriodic()) + return; + + BRepTools::UVBounds(F,umin,umax,vmin,vmax); + + gp_Pnt2d Pf = C2d->Value(f); + gp_Pnt2d Pl = C2d->Value(l); + const Standard_Real Um = 0.34*f + 0.66*l; + gp_Pnt2d Pm = C2d->Value( Um ); + + // sometimes on shpere, pcurve is out of domain by V though S is + // UPeriodic, sometimes it is in domain but nontheless it has + // wrong position. + // Check pcurve position by 3D point + if (S->IsKind(STANDARD_TYPE( Geom_SphericalSurface ))) + { + // get point on the surface + gp_Pnt Ps = S->Value( Pm.X(), Pm.Y() ); + // get point on the edge + Handle(Geom_Curve) C = BRep_Tool::Curve( E, f, l ); + gp_Pnt Pc = C->Value( Um ); + // compare points + Standard_Real TolE = BRep_Tool::Tolerance( E ); + if ( Pc.SquareDistance( Ps ) * 0.95 < TolE * TolE ) + return; // OK + + // find good UV for Pc: project Pc on S + GeomAdaptor_Surface SA (S); + Extrema_ExtPS anExtPS (Pc, SA, + SA.UResolution( TolE ), SA.VResolution( TolE )); + if (anExtPS.IsDone()) + { + Standard_Integer i, nbExt = anExtPS.NbExt(); + Extrema_POnSurf aPOnSurf; + for (i = 1; i <= nbExt; ++i ) + if (anExtPS.Value( i ) <= TolE) { + aPOnSurf = anExtPS.Point( i ); + break; + } + if (i <= nbExt) { + // a point found + Standard_Real u, v; + aPOnSurf.Parameter( u, v ); + gp_Pnt2d aGoodPm ( u, v ); + C2d->Translate( Pm , aGoodPm ); + } + } + } + + //--------------- + // Recadre en U. + //--------------- + if (S->IsUPeriodic()) { + Standard_Real period = S->UPeriod(); + Standard_Real eps = period*1.e-6; + Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X()); + Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X()); + Standard_Real du = 0.; + if (minC< umin - eps) { + du = (int((umin - minC)/period) + 1)*period; + } + if (minC > umax + eps) { + du = -(int((minC - umax)/period) + 1)*period; + } + if (du != 0) { + gp_Vec2d T1(du,0.); + C2d->Translate(T1); + minC += du; maxC += du; + } + // Ajuste au mieux la courbe dans le domaine. + if (maxC > umax +100*eps) { + Standard_Real d1 = maxC - umax; + Standard_Real d2 = umin - minC + period; + if (d2 < d1) du =-period; + if ( du != 0.) { + gp_Vec2d T2(du,0.); + C2d->Translate(T2); + } + } + } + //------------------ + // Recadre en V. + //------------------ + if (S->IsVPeriodic()) { + Standard_Real period = S->VPeriod(); + Standard_Real eps = period*1.e-6; + Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y()); + Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y()); + Standard_Real dv = 0.; + if (minC< vmin - eps) { + dv = (int((vmin - minC)/period) + 1)*period; + } + if (minC > vmax + eps) { + dv = -(int((minC - vmax)/period) + 1)*period; + } + if (dv != 0) { + gp_Vec2d T1(0.,dv); + C2d->Translate(T1); + minC += dv; maxC += dv; + } + // Ajuste au mieux la courbe dans le domaine. + if (maxC > vmax +100*eps) { + Standard_Real d1 = maxC - vmax; + Standard_Real d2 = vmin - minC + period; + if (d2 < d1) dv =-period; + if ( dv != 0.) { + gp_Vec2d T2(0.,dv); + C2d->Translate(T2); + } + } + } +} + +//======================================================================= +//function : Inter3D +//purpose : +//======================================================================= + +void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, + const TopoDS_Face& F2, + TopTools_ListOfShape& L) +{ + BRep_Builder B; + + // fill the data Structure + Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure(); + TopOpeBRep_DSFiller DSFiller; + DSFiller.Insert(F1,F2,DatStr); + + // define the GeomTool used by the DSFiller : + // compute BSpline of degree 1 on intersection curves. + Standard_Real tol3dAPPROX = 1e-7; + Standard_Real tol2dAPPROX = 1e-7; + TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX); + GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX); + TopOpeBRepDS_BuildTool BT(GT2); + + // Perform Section + TopOpeBRepBuild_Builder TopB(BT); + TopB.Perform(DatStr); + + // =============== + // Store new edges + // =============== + + L.Clear(); + TopOpeBRepDS_CurveExplorer cex(DatStr->DS()); + for (; cex.More(); cex.Next()) { + const TopOpeBRepDS_Curve& CDS = cex.Curve(); + Standard_Integer ic = cex.Index(); + Handle(Geom2d_Curve) pc1 = CDS.Curve1(); + Handle(Geom2d_Curve) pc2 = CDS.Curve2(); + + TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic); + while (itLE.More()) { + TopoDS_Edge E = TopoDS::Edge(itLE.Value()); + + PutInBounds (F1,E,pc1); + PutInBounds (F2,E,pc2); + + B.UpdateEdge (E,pc1,F1,0.); + B.UpdateEdge (E,pc2,F2,0.); + + L.Append (E); + + itLE.Next(); + if (itLE.More()) { + pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy()); + pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy()); + } + } + } + + // ======================== + // store same domain faces + // ======================== + + + if ( DatStr->HasSameDomain( F1 )) + { + TopTools_ListOfShape emptyList; + if (!mySameDomainFM.IsBound(F1)) + mySameDomainFM.Bind(F1,emptyList); + if (!mySameDomainFM.IsBound(F2)) + mySameDomainFM.Bind(F2,emptyList); + mySameDomainFM(F1).Append(F2); + mySameDomainFM(F2).Append(F1); + } + + // ==================== + // Store section edges + // ==================== + + const TopOpeBRepDS_DataStructure& DS = DatStr->DS(); + Standard_Integer j,i,nse = DS.NbSectionEdges(); + if (nse == 0) return; + + + TopoDS_Vertex V, sdeV1, sdeV2; + TopTools_MapOfShape MV; + TopTools_ListOfShape LSE; // list of section edges + TopoDS_Face dummyF; + + for (i = 1; i <= nse; i++) + { + const TopoDS_Edge & se = DS.SectionEdge(i); + if (! TopB.IsSplit(se,TopAbs_ON)) + continue; + LSE.Append( se ); + + // add vertices where section edges interferes with other + // edges as its descendant in myAsDes + + TopoDS_Edge sde, oe; // same domain, other edge + if (DatStr->HasSameDomain(se)) { + sde = TopoDS::Edge( DatStr->SameDomain(se).Value() ); + TopExp::Vertices( sde, sdeV1, sdeV2); + } + TColStd_MapOfInteger MIV; // indices of added edges + TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se )); + itP.SupportKind( TopOpeBRepDS_EDGE ); + // loop on intersections of se + for (; itP.More(); itP.Next()) { + oe = TopoDS::Edge( DS.Shape( itP.Support())); + if (itP.IsVertex()) { + // there is a vertex at intersection + if ( !MIV.Add( itP.Current() )) + continue; + V = TopoDS::Vertex( DS.Shape( itP.Current())); + if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) ) + oe = sde; + V = ReplaceSameDomainV( V , oe ); + V.Orientation( TopAbs_INTERNAL); + B.UpdateVertex( V, itP.Parameter(), se, 0.); // AddVonE() sets real U + } + else { + // create a new vertex at the intersection point + const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current()); + V = BRepLib_MakeVertex( DSP.Point() ); + V.Orientation( TopAbs_INTERNAL); + B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance()); + // make V be on the other edge + TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe )); + for (; itOP.More(); itOP.Next()) { + const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current()); + if ( DSP.IsEqual (ODSP)) { + B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance()); + break; + } + } + } + // add V on the both intersecting edges + TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes,dummyF); + if (!addedV.IsSame( V )) + mySameDomainVM.Bind (V, addedV); // equal vertex is already there + + MV.Add( addedV ); // to ease storage of vertices of ON splits + } + } + + // add section edge to the face it intersects and find + // splits ON that do not have same domain pair + + TopB.SplitSectionEdges(); // let TopB find ON splits + + TopTools_MapOfShape SPM; // map of ON splits + TopTools_IndexedMapOfShape ME[2]; + TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]); + TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]); + + TopTools_ListIteratorOfListOfShape itSP, itLSE (LSE); + while ( itLSE.More() ) { + + TopoDS_Edge se = TopoDS::Edge( itLSE.Value() ); + + // move itLSE to the next se + Standard_Integer ancRank = DS.AncestorRank(se); + if (ME[ancRank-1].Contains( se )) + { + LSE.Remove( itLSE ); // se is an edge of face it intersects + continue; + } + else + { + itLSE.Next(); + } + + const TopoDS_Face& F = (ancRank == 1) ? F2 : F1; + + // add se to face but dont add twice + TopTools_ListIteratorOfListOfShape itE( myAsDes->Descendant( F )); + if (myAsDes->HasDescendant( F )) { + for ( ; itE.More(); itE.Next()) + if (se.IsSame( itE.Value() )) + break; + } + if (!itE.More()) + { + myAsDes->Add( F, se ); + + // check se pcurve on F + Standard_Real tol, f,l, umin=1e100, umax=-1e100; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l); + if (pc.IsNull()) { + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) { + const TopoDS_Edge& E = TopoDS::Edge ( itSP.Value()); + BRep_Tool::Range(E, f, l); + umin = Min( umin, f); + umax = Max( umax, l); + } + Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l); + if (umin < umax) // sometimes umin == umax for closed edge + C3d = new Geom_TrimmedCurve( C3d, umin, umax); + pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol); + if (pc.IsNull()) { + MESSAGE (" CANT BUILD PCURVE "); + } + B.UpdateEdge( se, pc, F, tol); + } + } + + // to detect splits that do not have same domain pair + // ie which split a face into parts and not pass by its boundary + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) { + const TopoDS_Shape& SP = itSP.Value(); + if (!SPM.Add( SP )) + SPM.Remove( SP ); + } + } + + // store vertices of ON splits and bind section edges to faces + + for (itLSE.Initialize (LSE); itLSE.More(); itLSE.Next()) + { + const TopoDS_Shape& se = itLSE.Value(); + + Standard_Integer ancRank = DS.AncestorRank(se); + TopoDS_Face F = (ancRank == 1) ? F2 : F1; + + // add vertices of ON splits which have no same domain pair + Standard_Boolean added = Standard_False; + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) + { + if (!SPM.Contains( itSP.Value() )) + continue; + + const TopoDS_Edge& S = TopoDS::Edge ( itSP.Value()); + + added = Standard_True; + mySectionEdgesAD->Add( F, se ); + + TopoDS_Vertex VS[2]; + TopExp::Vertices (S, VS[0], VS[1]); + for (j=0; j<2; ++j) + { + if (mySameDomainVM.IsBound( VS[j] )) + VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] )); + if ( !MV.Contains( VS[j] )) { + // find equal vertex on se - point interference + gp_Pnt P1 = BRep_Tool::Pnt( VS[j] ); + TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) ); + for (; itV.More(); itV.Next()) { + V = TopoDS::Vertex( itV.Value() ); + if ( V.IsSame( VS[j] )) + break; + gp_Pnt P2 = BRep_Tool::Pnt( V ); + if (P1.IsEqual( P2, Precision::Confusion())) { + mySameDomainVM.Bind (VS[j], V); + VS[j] = V; + break; + } + } + if (!itV.More()) // no interferences with edges + myAsDes->Add( se, VS[j]); + } + + // add ends of ON splits to F in order to detect later + // if a split is on face in IsSplitOn() + mySectionEdgesAD->Add( F, VS[j]); + } + // in the descendants of F, first go ends of an ON split and + // then a split itself + mySectionEdgesAD->Add( F, S ); + } + if (!added) + mySectionEdgesAD->Add( F, se ); + + myNewEdges.Add( se ); + } +} + +//======================================================================= +//function : FacesPartition +//purpose : +//======================================================================= + +void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1, + const TopoDS_Face& F2) + //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/) +{ + TopTools_ListOfShape LInt; + + Inter3D (F1,F2,LInt); + + StorePart3d (F1,F2,LInt); +} + +//======================================================================= +//function : SetDone +//purpose : +//======================================================================= + +void Partition_Inter3d::SetDone(const TopoDS_Face& F1, + const TopoDS_Face& F2) +{ + if (!myDone.IsBound(F1)) { + TopTools_ListOfShape emptyList; + myDone.Bind(F1,emptyList); + } + myDone(F1).Append(F2); + if (!myDone.IsBound(F2)) { + TopTools_ListOfShape emptyList; + myDone.Bind(F2,emptyList); + } + myDone(F2).Append(F1); +} + +//======================================================================= +//function : IsDone +//purpose : +//======================================================================= + +Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1, + const TopoDS_Face& F2) + + const +{ + if (myDone.IsBound(F1)) { + TopTools_ListIteratorOfListOfShape it (myDone(F1)); + for (; it.More(); it.Next()) { + if (it.Value().IsSame(F2)) return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : StorePart3d +//purpose : +//======================================================================= + +void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1, + const TopoDS_Face& F2, + const TopTools_ListOfShape& LInt) +{ + if (!LInt.IsEmpty()) { + myAsDes->Add( F1,LInt); + myAsDes->Add( F2,LInt); + + TopTools_ListIteratorOfListOfShape it(LInt); + for (; it.More(); it.Next()) { + + TopoDS_Edge E = TopoDS::Edge(it.Value()); + + BRep_Builder B; + B.SameParameter(E,Standard_False); + BRepLib::SameParameter(E,1.0e-7); + + myNewEdges.Add(E); + } + } + SetDone(F1,F2); +} + +//======================================================================= +//function : TouchedFaces +//purpose : +//======================================================================= + +TopTools_MapOfShape& Partition_Inter3d::TouchedFaces() +{ + return myTouched; +} + +//======================================================================= +//function : AsDes +//purpose : +//======================================================================= + +Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const +{ + return myAsDes; +} + +//======================================================================= +//function : NewEdges +//purpose : +//======================================================================= + +TopTools_MapOfShape& Partition_Inter3d::NewEdges() +{ + return myNewEdges; +} + +//======================================================================= +//function : Affiche +//purpose : +//======================================================================= + +void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const +{ +#ifdef DEB + char PSection[1024]; + char *section=PSection; + Standard_Integer i = 0; + Standard_Real j=1; + TopTools_ListOfShape aList; + TopTools_ListIteratorOfListOfShape it; + for (it.Initialize(SetOfFaces); it.More(); it.Next()) { + const TopoDS_Shape& OS = it.Value(); + aList=myAsDes->Descendant(OS); + MESSAGE ( " the number of items stored in the list " << j << " : " << aList.Extent() ) + j++; + TopTools_ListIteratorOfListOfShape itaList; + for (itaList.Initialize(aList); itaList.More(); itaList.Next()) { + const TopoDS_Shape& SS = itaList.Value(); + i++; + sprintf(PSection,"section_%d",i); + DBRep::Set(section,SS); + } + } +#endif +} + +//======================================================================= +//function : SameDomain +//purpose : +//======================================================================= + +const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const +{ + if (mySameDomainFM.IsBound( F )) + return mySameDomainFM (F); + + static TopTools_ListOfShape emptyList; + return emptyList; +} + +//======================================================================= +//function : HasSameDomainF +//purpose : Return true if F has same domain faces +//======================================================================= + +Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const +{ + return mySameDomainFM.IsBound( F ); +} + +//======================================================================= +//function : IsSameDomain +//purpose : Return true if F1 and F2 are same domain faces +//======================================================================= + +Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1, + const TopoDS_Shape& F2) const +{ + if (mySameDomainFM.IsBound( F1 )) { + TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 )); + for (; it.More(); it.Next()) + if (F2.IsSame( it.Value())) + return Standard_True; + } + return F1.IsSame( F2 ); +} + +//======================================================================= +//function : ReplaceSameDomainV +//purpose : return same domain vertex of V if it was replaced +// and make this vertex to be on E too, else return V +//======================================================================= + +TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V, + const TopoDS_Edge& E) const +{ + TopoDS_Vertex SDV = V; + if (mySameDomainVM.IsBound( V )) { + + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1); + + SDV = TopoDS::Vertex( mySameDomainVM(V) ); + Standard_Real tol = BRep_Tool::Tolerance( V ); + BRep_Builder B; + SDV.Orientation( V.Orientation()); + + if (isClosed) { + Standard_Real f, l; + BRep_Tool::Range (E, f, l); + Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f ); + B.UpdateVertex(SDV, (isFirst ? f : l), E, tol); + SDV.Reverse(); + B.UpdateVertex(SDV, (isFirst ? l : f), E, tol); + } + else + B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol); + + } + return SDV; +} + +//======================================================================= +//function : SectionEdgesAD +//purpose : +//======================================================================= + +Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const +{ + return mySectionEdgesAD; +} + +//======================================================================= +//function : IsSectionEdge +//purpose : return True if E is an edge of a face and it +// intersects an other face +//======================================================================= + +Standard_Boolean + Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const +{ + return mySectionEdgesAD->HasAscendant(E); +} + +//======================================================================= +//function : HasSectionEdge +//purpose : return True if an edge of F intersects an other +// face or F is intersected by edge of an other face +//======================================================================= + +Standard_Boolean + Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const +{ + return mySectionEdgesAD->HasDescendant(F); +} + +//======================================================================= +//function : IsSplitOn +//purpose : return True if NewE is split of OldE on F +//======================================================================= + +Standard_Boolean + Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE, + const TopoDS_Edge& OldE, + const TopoDS_Face& F) const +{ + if (! mySectionEdgesAD->HasDescendant(F)) + return Standard_False; + + TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) ); + for ( ; itE.More(); itE.Next()) { + if ( itE.Value().ShapeType() != TopAbs_EDGE || + ! OldE.IsSame ( itE.Value() )) + continue; + // an edge encountered, its vertices and a split come next + itE.Next(); + if (!itE.More()) break; + const TopoDS_Shape& V3 = itE.Value(); + if (V3.ShapeType() != TopAbs_VERTEX) continue; + itE.Next(); + if (!itE.More()) break; + const TopoDS_Shape& V4 = itE.Value(); + if (V4.ShapeType() != TopAbs_VERTEX) continue; + + TopoDS_Vertex V1, V2; + TopExp::Vertices( OldE, V1, V2); + + if ( V1.IsSame(V2) && + (V1.IsSame(V3) || V1.IsSame(V4)) ) { + // closed old edge; use the split for the test + itE.Next(); + if (!itE.More()) break; + const TopoDS_Edge& split = TopoDS::Edge( itE.Value() ); + // check distance at middle point of NewE + Standard_Real f1,l1, f2,l2; + Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1); + if (!PC1.IsNull()) { + Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2); + gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) ); + Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1); + if (proj.NbPoints() && + proj.LowerDistance() <= Precision::Confusion()) + return Standard_True; + } + else { + Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1); + Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE ,f2,l2); + gp_Pnt P = C2->Value( 0.5*(f2+l2) ); + GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1); + if (proj.NbPoints() && + proj.LowerDistance() <= Precision::Confusion()) + return Standard_True; + } + } + else { + Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE); + Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE); + + Standard_Real f,l, u; + BRep_Tool::Range( NewE, f,l); + u = 0.5*(f+l); + f = Min(u3,u4); + l = Max(u3,u4); + + if (u <= l && u >= f) + return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : SectionEdgeFaces +//purpose : return faces cut by section edge +//======================================================================= + +const TopTools_ListOfShape& + Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const +{ + return mySectionEdgesAD->Ascendant( SecE ); +} + +#endif diff --git a/libsrc/occ/Partition_Loop.cxx b/libsrc/occ/Partition_Loop.cxx new file mode 100644 index 00000000..0511bfd2 --- /dev/null +++ b/libsrc/occ/Partition_Loop.cxx @@ -0,0 +1,473 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Loop.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include +#include + +#include "Partition_Loop.ixx" + +#include "utilities.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static char* name = new char[100]; +static int nbe = 0; + +//======================================================================= +//function : Partition_Loop +//purpose : +//======================================================================= +Partition_Loop::Partition_Loop() +{ +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void Partition_Loop::Init(const TopoDS_Face& F) +{ + myConstEdges.Clear(); + myNewWires .Clear(); + myNewFaces .Clear(); + myFace = F; +} + +//======================================================================= +//function : AddConstEdge +//purpose : +//======================================================================= +void Partition_Loop::AddConstEdge (const TopoDS_Edge& E) +{ + myConstEdges.Append(E); +} + + +//======================================================================= +//function : FindDelta +//purpose : +//======================================================================= +static Standard_Real FindDelta(TopTools_ListOfShape& LE, + const TopoDS_Face& F) +{ + Standard_Real dist, f, l; + Standard_Real d = Precision::Infinite(); + TopTools_ListIteratorOfListOfShape itl; + + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l); + gp_Pnt2d p = C->Value(f); + gp_Pnt2d pp = C->Value(l); + Standard_Real d1 = p.Distance(pp); + if (d1 connected by the vertex in the list . +// Is erased of the list. If is too in the list +// with the same orientation, it's erased of the list +//======================================================================= +static Standard_Boolean SelectEdge(const TopoDS_Face& F, + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + TopTools_ListOfShape& LE) +{ + TopTools_ListIteratorOfListOfShape itl; + NE.Nullify(); + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + LE.Remove(itl); + break; + } + } + + if (LE.Extent() > 1) { + //-------------------------------------------------------------- + // Several possible edges. + // - Test the edges differents of CE + //-------------------------------------------------------------- + Standard_Real cf, cl, f, l; + TopoDS_Face FForward = F; + Handle(Geom2d_Curve) Cc, C; + FForward.Orientation(TopAbs_FORWARD); + + Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl); + Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV); + Standard_Real uc,u; + if (CE.Orientation () == TopAbs_FORWARD) uc = cl; + else uc = cf; + + gp_Pnt2d P2,PV = Cc->Value(uc); + + Standard_Real delta = FindDelta(LE,FForward); + + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (!E.IsSame(CE)) { + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f; + else u = l; + P2 = C->Value(u); + dist = PV.Distance(P2); + if (dist <= distmin){ + distmin = dist; + } + + } + } + + Standard_Real anglemax = - PI; + TopoDS_Edge SelectedEdge; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (!E.IsSame(CE)) { + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f; + else u = l; + P2 = C->Value(u); + dist = PV.Distance(P2); + if (dist <= distmin + (1./3)*delta){ + gp_Pnt2d PC, P; + gp_Vec2d CTg1, CTg2, Tg1, Tg2; + Cc->D2(uc, PC, CTg1, CTg2); + C->D2(u, P, Tg1, Tg2); + + Standard_Real angle; + + if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) { + angle = CTg1.Angle(Tg1.Reversed()); + } + else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) { + angle = (CTg1.Reversed()).Angle(Tg1); + } + else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) { + angle = CTg1.Angle(Tg1); + } + else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) { + angle = (CTg1.Reversed()).Angle(Tg1.Reversed()); + } + if (angle >= anglemax) { + anglemax = angle ; + SelectedEdge = E; + } + } + } + } + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (E.IsEqual(SelectedEdge)) { + NE = TopoDS::Edge(E); + LE.Remove(itl); + break; + } + } + } + else if (LE.Extent() == 1) { + NE = TopoDS::Edge(LE.First()); + LE.RemoveFirst(); + } + else { + return Standard_False; + } + return Standard_True; +} + +//======================================================================= +//function : SamePnt2d +//purpose : +//======================================================================= +static Standard_Boolean SamePnt2d(TopoDS_Vertex V, + TopoDS_Edge& E1, + TopoDS_Edge& E2, + TopoDS_Face& F) +{ + Standard_Real f1,f2,l1,l2; + gp_Pnt2d P1,P2; + TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD); + TopoDS_Face FF = TopoDS::Face(aLocalF); + Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1); + Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2); + if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1); + else P1 = C1->Value(l1); + + if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2); + else P2 = C2->Value(f2); + Standard_Real Tol = 100*BRep_Tool::Tolerance(V); + Standard_Real Dist = P1.Distance(P2); + return Dist < Tol; +} + +//======================================================================= +//function : PurgeNewEdges +//purpose : +//======================================================================= +static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges, + const TopTools_MapOfOrientedShape& UsedEdges) +{ + TopTools_ListIteratorOfListOfShape it(ConstEdges); + while ( it.More()) { + const TopoDS_Shape& NE = it.Value(); + if (!UsedEdges.Contains(NE)) { + ConstEdges.Remove(it); + } + else { + it.Next(); + } + } +} + +//======================================================================= +//function : StoreInMVE +//purpose : +//======================================================================= +static void StoreInMVE (const TopoDS_Face& F, + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) + +{ + TopoDS_Vertex V1, V2; + TopTools_ListOfShape Empty; + + TopExp::Vertices(E,V1,V2); + if (!MVE.IsBound(V1)) { + MVE.Bind(V1,Empty); + } + MVE(V1).Append(E); + + if (!MVE.IsBound(V2)) { + MVE.Bind(V2,Empty); + } + MVE(V2).Append(E); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void Partition_Loop::Perform() +{ + + TopTools_DataMapOfShapeListOfShape MVE; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1; + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + + //----------------------------------- + // Construction map vertex => edges + //----------------------------------- + for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { + TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + StoreInMVE(myFace,E,MVE); + } + + //---------------------------------------------- + // Construction of all the wires and of all the new faces. + //---------------------------------------------- + TopTools_MapOfOrientedShape UsedEdges; + + while (!MVE.IsEmpty()) { + TopoDS_Vertex VF,CV; + TopoDS_Edge CE,NE,EF; + TopoDS_Wire NW; + BRep_Builder B; + Standard_Boolean End= Standard_False; + + B.MakeWire(NW); + //-------------------------------- + // EF first edge. + //-------------------------------- + Mapit.Initialize(MVE); + EF = CE = TopoDS::Edge(Mapit.Value().First()); + + TopExp::Vertices(CE,V1,V2); + //-------------------------------- + // VF first vertex + //-------------------------------- + if (CE.Orientation() == TopAbs_FORWARD) { + CV = VF = V1; + } + else { + CV = VF = V2; + } + if (!MVE.IsBound(CV)) continue; + for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + MVE(CV).Remove(itl); + break; + } + } + + int i = 0; + while (!End) { + //------------------------------- + // Construction of a wire. + //------------------------------- + TopExp::Vertices(CE,V1,V2); + if (!CV.IsSame(V1)) CV = V1; else CV = V2; + B.Add (NW,CE); + UsedEdges.Add(CE); + + //-------------- + // stop test + //-------------- + if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) { + if (CV.IsSame(VF)) { + if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV); + else { + for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + MVE(CV).Remove(itl); + break; + } + } + } + } + End=Standard_True; + } + + //-------------- + // select edge + //-------------- + else { + Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV)); + if (find) { + CE=NE; + if (MVE(CV).IsEmpty()) MVE.UnBind(CV); + if (CE.IsNull() ) { + MESSAGE ( " CE is NULL !!! " ) + End=Standard_True; + } + } + else { + MESSAGE ( " edge doesn't exist " ) + End=Standard_True; + } + } + } + + //----------------------------- + // Test if the wire is closed + //----------------------------- + if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) { + } + else{ + MESSAGE ( "wire not closed" ) + } + myNewWires.Append (NW); + } + + PurgeNewEdges(myConstEdges,UsedEdges); + +} + + +//======================================================================= +//function : NewWires +//purpose : +//======================================================================= +const TopTools_ListOfShape& Partition_Loop::NewWires() const +{ + return myNewWires; +} + +//======================================================================= +//function : NewFaces +//purpose : +//======================================================================= +const TopTools_ListOfShape& Partition_Loop::NewFaces() const +{ + return myNewFaces; +} + +//======================================================================= +//function : WiresToFaces +//purpose : +//======================================================================= +void Partition_Loop::WiresToFaces() +{ + if (!myNewWires.IsEmpty()) { + BRepAlgo_FaceRestrictor FR; + + TopAbs_Orientation OriF = myFace.Orientation(); + TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD); + + FR.Init (TopoDS::Face(aLocalS),Standard_False); + TopTools_ListIteratorOfListOfShape it(myNewWires); + for (; it.More(); it.Next()) { + FR.Add(TopoDS::Wire(it.Value())); + } + + FR.Perform(); + + if (FR.IsDone()) { + for (; FR.More(); FR.Next()) { + myNewFaces.Append(FR.Current().Oriented(OriF)); + } + } + } +} + + +#endif diff --git a/libsrc/occ/Partition_Loop2d.cxx b/libsrc/occ/Partition_Loop2d.cxx new file mode 100644 index 00000000..3c1bd5c2 --- /dev/null +++ b/libsrc/occ/Partition_Loop2d.cxx @@ -0,0 +1,1143 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R& D +// +// +// +// File : Partition_Loop2d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop2d.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include +#include "Partition_Loop2d.ixx" + +#include "utilities.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Loop2d +//purpose : +//======================================================================= + +Partition_Loop2d::Partition_Loop2d() +{ +} + +//======================================================================= +//function : Init +//purpose : Init with the set of edges must have +// pcurves on . +//======================================================================= + +void Partition_Loop2d::Init(const TopoDS_Face& F) +{ + myConstEdges.Clear(); + myNewWires .Clear(); + myNewFaces .Clear(); + myFace = F; + myFaceOri = myFace.Orientation(); + myFace.Orientation( TopAbs_FORWARD ); +} + +//======================================================================= +//function : AddConstEdge +//purpose : Add as unique edge in the result. +//======================================================================= + +void Partition_Loop2d::AddConstEdge (const TopoDS_Edge& E) +{ +#ifdef DEB + Standard_Real f,l; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + if (pc.IsNull()) { + INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE"); + } else +#endif + { + myConstEdges.Append(E); + } +} + +void Partition_Loop2d::AddSectionEdge (const TopoDS_Edge& E) +{ +#ifdef DEB + Standard_Real f,l; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + if (pc.IsNull()) + pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + gp_Vec2d Tg1; + gp_Pnt2d PC; + pc->D1(0.5*(f+l), PC, Tg1); + if (Tg1.Magnitude() <= gp::Resolution()) { + MESSAGE (""); + } + if (pc.IsNull()) { + INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE"); + } else +#endif + { + myConstEdges.Append(E); + myConstEdges.Append(E.Reversed()); + mySectionEdges.Add( E ); + } +} + +//======================================================================= +//function : preciseU +//purpose : find u such that the 3D point on theE is just out of tolerance +// of theV +//======================================================================= + +static Standard_Real preciseU (const BRepAdaptor_Surface& theSurf, + const TopoDS_Edge& theE, + const TopoDS_Vertex& theV, + const Handle(Geom2d_Curve)& theC, + const Standard_Boolean theFirstEnd) +{ + Standard_Boolean isForward = ( theE.Orientation () == TopAbs_FORWARD ); + if (theFirstEnd) isForward = !isForward; + + // find the first point in 2d and 3d + Standard_Real f,l; + BRep_Tool::Range( theE, f, l ); + Standard_Real u0 = isForward ? l : f; + gp_Pnt2d aP2d0 = theC->Value( u0 ); + gp_Pnt aPnt0 = theSurf.Value( aP2d0.X(), aP2d0.Y() ); + + // shift in 2d and 3d + Standard_Real du = ( l - f ) / 100, du3d = 0; + if (isForward) + du = -du; + + // target parameter + Standard_Real u; + + while (du3d < ::RealSmall()) + { + // u for test + u = u0 + du; + du *= 10; // for the next iteration: increase du untill du3d is large enough + + // find out how u is far from u0 in 3D + gp_Pnt2d aP2d = theC->Value( u ); + gp_Pnt aPnt = theSurf.Value( aP2d.X(), aP2d.Y() ); + du3d = aPnt0.Distance( aPnt ); + } + + // find u such that the 3D point is just out of tolerance of theV + Standard_Real tolV = BRep_Tool::Tolerance( theV ) + Precision::Confusion(); + u = u0 + du * tolV / du3d; + + // check that u is within the range + if ( isForward ? (u < f) : (u > l) ) + u = u0 + du; + + return u; +} + +//======================================================================= +//function : SelectEdge +//purpose : Find in the list the edge connected with by +// the vertex . +// is removed from the list. If is in +// with the same orientation, it's removed from the list +//======================================================================= + +static Standard_Boolean SelectEdge(const BRepAdaptor_Surface& Surf, + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + const TopTools_ListOfShape& LE) +{ + NE.Nullify(); + + if (LE.Extent() > 1) { + //-------------------------------------------------------------- + // Several possible edges. + // - Test the edges differents of CE + //-------------------------------------------------------------- + TopoDS_Face FForward = Surf.Face(); + TopoDS_Edge aPrevNE; + + gp_Vec2d CTg1, Tg1, CTg2, Tg2; + gp_Pnt2d PC, P; + + Standard_Real f, l; + Handle(Geom2d_Curve) Cc, C; + Cc = BRep_Tool::CurveOnSurface(CE,FForward,f,l); + + Standard_Boolean isForward = ( CE.Orientation () == TopAbs_FORWARD ); + Standard_Real uc, u, du = Precision::PConfusion(); + uc = isForward ? ( l - du ) : ( f + du ); + Cc->D1(uc, PC, CTg1); + if (!isForward) CTg1.Reverse(); + + Standard_Real anglemin = 3 * PI, tolAng = 1.e-8; + + // select an edge whose first derivative is most left of CTg1 + // ie an angle between Tg1 and CTg1 is least + TopTools_ListIteratorOfListOfShape itl; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (E.IsSame(CE)) + continue; + if (! CV.IsSame( TopExp::FirstVertex( E, Standard_True ))) + continue; + + isForward = ( E.Orientation () == TopAbs_FORWARD ); + + // get E curve + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + // get the first derivative Tg1 + u = isForward ? ( f + du ) : ( l - du ); + C->D1(u, P, Tg1); + if (!isForward) Tg1.Reverse(); + + // -PI < angle < PI + Standard_Real angle = Tg1.Angle(CTg1); + + if (PI - Abs(angle) <= tolAng) + { + // an angle is too close to PI; assure that an angle sign really + // reflects an edge position: +PI - an edge is worst, + // -PI - an edge is best. + u = preciseU( Surf, CE, CV, Cc, Standard_False); + gp_Vec2d CTg; + Cc->D1(u, PC, CTg); + if (CE.Orientation() == TopAbs_REVERSED) CTg.Reverse(); + + u = preciseU( Surf, E, CV, C, Standard_True); + C->D1(u, P, Tg1); + if (!isForward) Tg1.Reverse(); + + angle = Tg1.Angle(CTg); + } + + Standard_Boolean isClose = ( Abs( angle - anglemin ) <= tolAng ); + if (angle <= anglemin) { + if (isClose) + aPrevNE = NE; + else + aPrevNE.Nullify(); + anglemin = angle ; + NE = E; + } + else + if (isClose) + aPrevNE = E; + + } + if (!aPrevNE.IsNull()) { + // select one of close edges, the most left one. + Cc = BRep_Tool::CurveOnSurface( NE, FForward, f, l ); + uc = preciseU( Surf, NE, CV, Cc, Standard_True); + Cc->D1(uc, PC, CTg1); + if (NE.Orientation() != TopAbs_FORWARD) CTg1.Reverse(); + + u = preciseU( Surf, aPrevNE, CV, C, Standard_True); + C->D1(u, P, Tg1); + if (aPrevNE.Orientation() != TopAbs_FORWARD) Tg1.Reverse(); + + if ( Tg1.Angle(CTg1) < 0) + NE = aPrevNE; + } + } + else if (LE.Extent() == 1) { + NE = TopoDS::Edge(LE.First()); + } + else { + return Standard_False; + } + return !NE.IsNull(); +} + +//======================================================================= +//function : SamePnt2d +//purpose : +//======================================================================= + +static Standard_Boolean SamePnt2d(const TopoDS_Vertex& V1, + const TopoDS_Edge& E1, + const TopoDS_Vertex& V2, + const TopoDS_Edge& E2, + const TopoDS_Face& F) +{ + Standard_Real f1,f2,l1,l2; + Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,F,f1,l1); + Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,F,f2,l2); + + gp_Pnt2d P1 = C1->Value( BRep_Tool::Parameter(V1,E1)); + gp_Pnt2d P2 = C2->Value( BRep_Tool::Parameter(V2,E2)); + + Standard_Real Tol = 100 * BRep_Tool::Tolerance(V1); + Standard_Real Dist = P1.Distance(P2); + return Dist < Tol; +} + + +//======================================================================= +//function : StoreInMVE +//purpose : +//======================================================================= + +static void StoreInMVE (const TopoDS_Face& /*F*/, + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) + +{ + TopoDS_Vertex V1, V2; + TopTools_ListOfShape Empty; + + TopExp::Vertices(E,V1,V2); + if (!MVE.IsBound(V1)) { + MVE.Bind(V1,Empty); + } + MVE(V1).Append(E); + + if (!MVE.IsBound(V2)) { + MVE.Bind(V2,Empty); + } + MVE(V2).Append(E); +} + +//======================================================================= +//function : RemoveFromMVE +//purpose : +//======================================================================= + +static void RemoveFromMVE(const TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE) +{ + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + TopExp::Vertices (E,V1,V2); + if (MVE.IsBound(V1)) + for ( itl.Initialize(MVE(V1)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(E)) { + MVE(V1).Remove(itl); + break; + } + } + if (MVE.IsBound(V2)) + for ( itl.Initialize(MVE(V2)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(E)) { + MVE(V2).Remove(itl); + break; + } + } +} +//======================================================================= +//function : addConnected +//purpose : add to all edges reachable from +//======================================================================= + +static void addConnected(const TopoDS_Shape& E, + TopTools_MapOfShape& EM, + TopTools_MapOfShape& VM, + const TopTools_DataMapOfShapeListOfShape& MVE) +{ + // Loop on vertices of E + TopoDS_Iterator itV ( E ); + for ( ; itV.More(); itV.Next()) { + + if ( ! VM.Add ( itV.Value() )) continue; + + // Loop on edges sharing V + TopTools_ListIteratorOfListOfShape itE( MVE( itV.Value() ) ); + for (; itE.More(); itE.Next()) { + if ( EM.Add( itE.Value() )) + addConnected ( itE.Value(), EM, VM, MVE ); + } + } +} +//======================================================================= +//function : canPassToOld +//purpose : +//======================================================================= + +// static Standard_Boolean canPassToOld (const TopoDS_Shape& V, +// TopTools_MapOfShape& UsedShapesMap, +// const TopTools_DataMapOfShapeListOfShape& MVE, +// const TopTools_MapOfShape& SectionEdgesMap) +// { +// TopTools_ListIteratorOfListOfShape itE( MVE(V) ); +// // Loop on edges sharing V +// for (; itE.More(); itE.Next()) { +// if ( !UsedShapesMap.Add( itE.Value() )) +// continue; // already checked + +// if ( !SectionEdgesMap.Contains( itE.Value() )) +// return Standard_True; // WE PASSED + +// TopoDS_Iterator itV( itE.Value() ); +// // Loop on vertices of an edge +// for (; itV.More(); itV.Next()) { +// if ( !UsedShapesMap.Add( itV.Value() )) +// continue; // already checked +// else +// return canPassToOld( itV.Value(), UsedShapesMap, MVE, SectionEdgesMap); +// } +// } +// return Standard_False; +// } + +//======================================================================= +//function : MakeDegenAndSelect +//purpose : Find parameter of intersection of with and +// select an edge with its parameter closest to found one. +// Return new degenerated edge trimming by found parameters +//======================================================================= + +static TopoDS_Edge MakeDegenAndSelect(const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + TopTools_SequenceOfShape& EdgesSeq, + TColStd_SequenceOfReal& USeq, + const TopoDS_Edge& DE) +{ + if (EdgesSeq.Length() < 3) { + if (CE == EdgesSeq.First()) + NE = TopoDS::Edge( EdgesSeq.Last() ); + else + NE = TopoDS::Edge( EdgesSeq.First() ); + return DE; + } + + // find parameter on DE where it intersects CE + + Standard_Real U1; + Standard_Integer i, nb = EdgesSeq.Length(); + for (i=1; i<= nb; ++i) { + if (CE == EdgesSeq(i)) { + U1 = USeq(i); + break; + } + } + + // select NE with param closest to U1 thus finding U2 for a new degen edge + + Standard_Real U2, dU, dUmin = 1.e100; + Standard_Boolean isReversed = ( DE.Orientation() == TopAbs_REVERSED ); + for (i=1; i<= nb; ++i) { + dU = USeq(i) - U1; + if (isReversed ? (dU > 0) : (dU < 0)) + continue; + dU = Abs( dU ); + if ( dU > dUmin || IsEqual( dU, 0.)) + continue; + const TopoDS_Edge& E = TopoDS::Edge ( EdgesSeq(i) ); + if ( ! CV.IsSame( TopExp::FirstVertex( E , Standard_True ))) + continue; + NE = E; + dUmin = dU + Epsilon(dU); + U2 = USeq(i); + } + + // make a new degenerated edge + TopoDS_Edge NewDegen = TopoDS::Edge ( DE.EmptyCopied() ); + + Standard_Real Tol = BRep_Tool::Tolerance( CV ); + TopoDS_Vertex V = CV; + + BRep_Builder B; + V.Orientation( NewDegen.Orientation() ); + B.UpdateVertex( V, U1, NewDegen, Tol); + B.Add ( NewDegen , V ); + + V.Reverse(); + B.UpdateVertex( V, U2, NewDegen, Tol); + B.Add ( NewDegen , V ); + + return NewDegen; +} + +//======================================================================= +//function : prepareDegen +//purpose : Intersect with edges bound to its vertex in +// and store intersection parameter on in +// as well as the edges them-self in . +// Bind to vertex of in +//======================================================================= + +static void prepareDegen (const TopoDS_Edge& DegEdge, + const TopoDS_Face& F, + const TopTools_DataMapOfShapeListOfShape& MVE, + TopTools_SequenceOfShape& EdgesSeq, + TColStd_SequenceOfReal& USeq, + TopTools_DataMapOfShapeInteger& MVDEI, + const Standard_Integer DegEdgeIndex) +{ + const TopoDS_Vertex& V = TopExp::FirstVertex ( DegEdge ); + MVDEI.Bind ( V, DegEdgeIndex ); + + const TopTools_ListOfShape& EdgesList = MVE ( V ); + // if only 2 edges come to degenerated one, no pb in selection and + // no need to intersect them, just simulate asked data + Standard_Boolean doIntersect = ( EdgesList.Extent() > 2 ); + + BRepAdaptor_Curve2d DC, C; + Geom2dInt_GInter InterCC; + Standard_Real Tol = Precision::PConfusion(); + if ( doIntersect ) + DC.Initialize( DegEdge, F ); + + // avoid intersecting twice the same edge + BRepOffset_DataMapOfShapeReal EUMap ( EdgesList.Extent() ); + + Standard_Real U, f, l; + BRep_Tool::Range (DegEdge, f, l); + + TopTools_ListIteratorOfListOfShape itE (EdgesList); + for (; itE.More(); itE.Next()) { + + const TopoDS_Edge& E = TopoDS::Edge ( itE.Value() ); + + if ( !doIntersect) { + U = 0.; // it won't be used + } + else if ( BRep_Tool::IsClosed( E, F )) { + // seam edge: select U among f and l + Standard_Boolean first = Standard_True; + if ( V.IsSame ( TopExp::FirstVertex( E, Standard_True ) )) + first = Standard_False; + if ( DegEdge.Orientation() == TopAbs_REVERSED ) + first = !first; + U = first ? f : l; + } + else if ( EUMap.IsBound( E ) ) { + // same edge already bound + U = EUMap( E ); + } + else { + // intersect 2d curves + C.Initialize( E, F ); + InterCC.Perform ( DC, C , Tol, Tol ); + if (! InterCC.IsDone() || InterCC.NbPoints() == 0) { + MESSAGE ( "NO 2d INTERSECTION ON DEGENERATED EDGE" ); + continue; + } + // hope there is only one point of intersection + U = InterCC.Point( 1 ).ParamOnFirst(); + } + USeq.Append ( U ); + EdgesSeq.Append ( E ); + } +} +//======================================================================= +//function : Perform +//purpose : Make loops. +//======================================================================= + +void Partition_Loop2d::Perform() +{ + + Standard_Integer NbConstEdges = myConstEdges.Extent(); + TopTools_DataMapOfShapeListOfShape MVE(NbConstEdges) , MVE2(NbConstEdges); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit; + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + BRepAdaptor_Surface Surface ( myFace, Standard_False ); + + // degenerated edges and parameters of their 2d intersection with other edges + TopoDS_Edge DE [2]; + TopTools_SequenceOfShape SEID [2]; // seq of edges intersecting degenerated + TColStd_SequenceOfReal SeqU [2]; // n-th U corresponds to n-th edge in SEID + TopTools_DataMapOfShapeInteger MVDEI(2); // map vertex - degenerated edge index + Standard_Integer iDeg = 0; // index of degenerated edge [0,1] + + //--------------------------------------------------------- + // Construction map vertex => edges, find degenerated edges + //--------------------------------------------------------- + for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { + TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if ( BRep_Tool::Degenerated( E )) { + if (DE[0].IsNull()) DE[0] = E; + else DE[1] = E; + } + else + StoreInMVE(myFace,E,MVE); + } + + // fill data for degenerated edges + if ( ! DE[0].IsNull() ) + prepareDegen ( DE[0], myFace, MVE, SEID[0], SeqU[0], MVDEI, 0); + if ( ! DE[1].IsNull() ) + prepareDegen ( DE[1], myFace, MVE, SEID[1], SeqU[1], MVDEI, 1); + + + // to detect internal wires + Standard_Boolean isInternCW = 0; + MVE2 = MVE; + + + //------------------------------ + // Construction of all the wires + //------------------------------ + // first, we collect wire edges in WEL list looking for same edges that + // will be then removed possibly exploding a wire into parts; + // second, build wire(s) + + while (!MVE.IsEmpty()) { + + TopoDS_Vertex VF,CV; + TopoDS_Edge CE,NE,EF; + TopoDS_Wire NW; + BRep_Builder B; + Standard_Boolean End = Standard_False; + TopTools_ListOfShape WEL; + + Mapit.Initialize(MVE); + if (Mapit.Value().IsEmpty()) { + MVE.UnBind(Mapit.Key()); + continue; + } + + // EF first edge. + EF = CE = TopoDS::Edge(Mapit.Value().First()); + // VF first vertex + VF = TopExp::FirstVertex( CE, Standard_True); + + isInternCW = Standard_True; + + TopTools_MapOfShape addedEM (NbConstEdges); // map of edges added to WEL + TopTools_MapOfShape doubleEM (NbConstEdges); // edges encountered twice in WEL + + //------------------------------- + // Construction of a wire. + //------------------------------- + while (!End) { + + // only a seam is allowed twice in a wire, the others should be removed + if (addedEM.Add ( CE ) || BRep_Tool::IsClosed( CE, myFace ) ) + WEL.Append( CE ); + else { + doubleEM.Add( CE ); + RemoveFromMVE (CE,MVE2); + TopoDS_Edge CERev = CE; + CERev.Reverse(); + RemoveFromMVE (CERev,MVE2); + } + + RemoveFromMVE (CE,MVE); + + CV = TopExp::LastVertex( CE, Standard_True); + + if (isInternCW && !mySectionEdges.Contains(CE)) + // wire is internal if all edges are section ones + isInternCW = Standard_False; + + if (MVDEI.IsBound( CV )) { // CE comes to the degeneration + iDeg = MVDEI( CV ); + TopoDS_Edge NewDegen; + NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); + WEL.Append( NewDegen ); + CE = NE; + End = CV.IsSame( VF ); + continue; + } + + //-------------- + // stop test + //-------------- + if (MVE(CV).IsEmpty()) { + End=Standard_True; + MVE.UnBind(CV); + } + else if (CV.IsSame(VF) && SamePnt2d(CV,CE, VF,EF, myFace) ) { + End = Standard_True; + } + else { + //---------------------------- + // select new current edge + //---------------------------- + if (! SelectEdge (Surface,CE,CV,NE,MVE(CV))) { + MESSAGE ( " NOT CLOSED WIRE " ); + End=Standard_True; + } + else + CE = NE; + } + } // while ( !End ) + + + // WEL is built, built wire(s) + + + itl.Initialize( WEL ); + if ( doubleEM.IsEmpty()) { // no double edges + B.MakeWire( NW ); + for (; itl.More(); itl.Next()) + B.Add ( NW, itl.Value()); + if (isInternCW) myInternalWL.Append(NW); + else myNewWires.Append (NW); + } + + else { + // remove double and degenerated edges from WEL + while (itl.More()) { + const TopoDS_Edge& E = TopoDS::Edge ( itl.Value() ); + if ( doubleEM.Contains( E ) || BRep_Tool::Degenerated( E )) + WEL.Remove( itl ); + else + itl.Next(); + } + if ( WEL.IsEmpty()) + continue; + // remove double edges from SEID and SeqU + Standard_Integer i,j; + for (j=0; j<2; ++j) { + for (i=1; i<=SEID[j].Length(); ++i) { + if (doubleEM.Contains( SEID[j].Value(i))) { + SEID[j].Remove( i ); + SeqU[j].Remove( i-- ); + } + } + } + // removal of doulbe edges can explode a wire into parts, + // make new wires of them. + // A Loop like previous one but without 2d check + while ( !WEL.IsEmpty() ) { + CE = TopoDS::Edge( WEL.First() ); + WEL.RemoveFirst(); + B.MakeWire( NW ); + VF = TopExp::FirstVertex ( CE, Standard_True); + + End = Standard_False; + while ( !End) { + B.Add( NW, CE ); + CV = TopExp::LastVertex ( CE, Standard_True); + + if (MVDEI.IsBound( CV )) { // CE comes to the degeneration + iDeg = MVDEI( CV ); + TopoDS_Edge NewDegen; + NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); + B.Add( NW, NewDegen ); + End = CV.IsSame( VF ); + CE = NE; + if (!NE.IsNull()) { // remove NE from WEL + for (itl.Initialize( WEL ); itl.More(); itl.Next()) + if ( NE == itl.Value()) { + WEL.Remove( itl ); + break; + } + } + } // end degeneration + + else { + if (CV.IsSame( VF )) { + End = Standard_True; + continue; + } + // edges in WEL most often are well ordered + // so try to iterate until the End + Standard_Boolean add = Standard_False; + itl.Initialize(WEL); + while ( itl.More() && !End) { + NE = TopoDS::Edge( itl.Value() ); + if ( CV.IsSame( TopExp::FirstVertex( NE, Standard_True ))) { + WEL.Remove( itl ); + if (add) + B.Add( NW, CE ); + CE = NE; + add = Standard_True; + CV = TopExp::LastVertex( CE, Standard_True); + if (MVDEI.IsBound( CV ) || CV.IsSame( VF )) + break; + } + else + itl.Next(); + } + if (!add) + End = Standard_True; + } + } // !End + + myInternalWL.Append( NW ); + } + } // end building new wire(s) from WEL + + } // end Loop on MVE + + // all wires are built + + + // ============================================================ + // select really internal wires i.e. those from which we can`t + // pass to an old (not section) edge + // ============================================================ + + Standard_Integer nbIW = myInternalWL.Extent(); + if (nbIW == 0) + return; + + if ( myNewWires.Extent() != 1 && nbIW > 1) { + TopTools_MapOfShape outerEM (NbConstEdges); // edges connected to non-section ones + TopTools_MapOfShape visitedVM (NbConstEdges); + for ( itl.Initialize( myConstEdges ); itl.More(); itl.Next()) { + if ( ! mySectionEdges.Contains( itl.Value() )) + addConnected (itl.Value(), outerEM, visitedVM, MVE2); + } + // if an edge of a wire is in , the wire is not internal + TopExp_Explorer expIWE; + TopTools_ListIteratorOfListOfShape itIW ( myInternalWL ); + while (itIW.More()) { + expIWE.Init ( itIW.Value() , TopAbs_EDGE ); + if ( outerEM.Contains( expIWE.Current() )) { + myNewWires.Append ( itIW.Value() ); + myInternalWL.Remove( itIW ); // == itIW.Next() + } + else + itIW.Next(); + } + } +} +//======================================================================= +//function : isHole +//purpose : +//======================================================================= + +static Standard_Boolean isHole (const TopoDS_Wire& W, + const TopoDS_Face& F) +{ + BRep_Builder B; + TopoDS_Shape newFace = F.EmptyCopied(); + B.Add(newFace,W.Oriented(TopAbs_FORWARD)); + BRepTopAdaptor_FClass2d classif (TopoDS::Face(newFace), + Precision::PConfusion()); + return (classif.PerformInfinitePoint() == TopAbs_IN); +} + +//======================================================================= +//function : IsInside +//purpose : check if W1 is inside W2. Suppose W2 is not a hole !!!! +//======================================================================= + +static Standard_Boolean isInside(const TopoDS_Face& F, + const TopoDS_Wire& W1, + const TopoDS_Wire& W2) +{ + // make a face with wire W2 + BRep_Builder B; + TopoDS_Shape aLocalShape = F.EmptyCopied(); + TopoDS_Face newFace = TopoDS::Face(aLocalShape); + B.Add(newFace,W2); + + // get any 2d point of W1 + TopExp_Explorer exp(W1,TopAbs_EDGE); + if (BRep_Tool::Degenerated( TopoDS::Edge( exp.Current() ))) + exp.Next(); + const TopoDS_Edge& e = TopoDS::Edge(exp.Current()); + Standard_Real f,l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(e,F,f,l); + gp_Pnt2d pt2d(C2d->Value( 0.5 * ( f + l ))); + + BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion()); + return (classif.Perform(pt2d) == TopAbs_IN); +} + +//======================================================================= +//function : NewWires +//purpose : Returns the list of wires performed. +// can be an empty list. +//======================================================================= + +const TopTools_ListOfShape& Partition_Loop2d::NewWires() const +{ + return myNewWires; +} + +//======================================================================= +//function : NewFaces +//purpose : Returns the list of faces. +//Warning : The method as to be called before. +// can be an empty list. +//======================================================================= + +const TopTools_ListOfShape& Partition_Loop2d::NewFaces() const +{ + return myNewFaces; +} + +//======================================================================= +//function : findEqual +//purpose : move wires form to pairs of wires build of the same edges +//======================================================================= + +static void findEqual (TopTools_ListOfShape& WL, + TopTools_DataMapOfShapeShape& EqWM, + const TopoDS_Face& F) +{ + TopTools_ListIteratorOfListOfShape it1, it2; + Standard_Integer i,j; + TColStd_MapOfInteger IndMap; + for (it1.Initialize(WL), i=1; it1.More(); it1.Next(), i++) { + + if (IndMap.Contains(i)) continue; + const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value()); + + for (it2.Initialize(WL), j=1; it2.More(); it2.Next(), j++) { + + if (j <= i || IndMap.Contains(j)) continue; + + TopTools_IndexedMapOfShape EdgesMap; + TopExp::MapShapes (Wire1, TopAbs_EDGE, EdgesMap); + + const TopoDS_Shape& Wire2 = it2.Value(); + TopoDS_Iterator itE ( Wire2); + for (; itE.More(); itE.Next()) { + if ( !EdgesMap.Contains( itE.Value()) ) + break; + } + if (!itE.More()) { // all edges are same + if (isHole( Wire1, F)) { + EqWM.Bind ( Wire1, Wire2 ); + } + else { + EqWM.Bind ( Wire2, Wire1 ); + } + IndMap.Add(i); + IndMap.Add(j); + break; + } + } + } + // clear WL + it1.Initialize(WL); + i=1; + while (it1.More()) { + if (IndMap.Contains(i)) + WL.Remove(it1); // next node becomes current and with Next() we would miss it + else + it1.Next(); + i++; + } +} + +//======================================================================= +//function : classify +//purpose : bind to a wire a list of internal wires +//======================================================================= + +static void classify(const TopTools_DataMapOfShapeShape& EqWM, + BRepAlgo_AsDes& OuterInner, + const TopoDS_Face& F) +{ + TopTools_DataMapIteratorOfDataMapOfShapeShape it1, it2; + + for (it1.Initialize(EqWM); it1.More(); it1.Next()) { + // find next after it1.Value() + for (it2.Initialize(EqWM); it2.More(); it2.Next()) + if (it1.Value().IsSame( it2.Value() )) + { + it2.Next(); + break; + } + for ( ; it2.More(); it2.Next()) { + const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value() ); + const TopoDS_Wire& Wire2 = TopoDS::Wire( it2.Value() ); + if (isInside(F, Wire1, Wire2)) + OuterInner.Add (Wire2, Wire1); + else if (isInside(F, Wire2, Wire1)) + OuterInner.Add (Wire1, Wire2); + } + } +} +//======================================================================= +//function : WiresToFaces +//purpose : Build faces from the wires result. +// serves to find original edge by new +// one.
contains edges resulting from face +// intersections +//======================================================================= + +void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) +{ + Standard_Integer nbW = myNewWires.Extent() + myInternalWL.Extent(); + if (nbW==0) + return; + + BRepAlgo_FaceRestrictor FR; + FR.Init (myFace,Standard_False); + + // FaceRestrictor is instable in rather simple cases + // (ex. a single face of bellecoque.brep splited by 10 planes: + // sometimes 1-2 faces are missing ). + // So we use it as less as possible: no holes -> make faces by hands + + + // are there holes in myFace ? + Standard_Boolean hasOldHoles = Standard_False; + TopoDS_Iterator itOldW (myFace); + if ( itOldW.More()) { + const TopoDS_Wire& FirstOldWire = TopoDS::Wire( itOldW.Value() ); + itOldW.Next(); + hasOldHoles = itOldW.More() || isHole( FirstOldWire, myFace); + } + if (myInternalWL.IsEmpty() && !hasOldHoles) { + // each wire bounds one face + BRep_Builder B; + TopTools_ListIteratorOfListOfShape itNW (myNewWires); + for (; itNW.More(); itNW.Next()) { + TopoDS_Face NF = TopoDS::Face ( myFace.EmptyCopied() ); + B.Add ( NF, itNW.Value() ); + NF.Orientation( myFaceOri); + myNewFaces.Append ( NF ); + } + return; + } + + // FaceRestrictor can't classify wires build on all the same edges + // and gives incorrect result in such cases (ex. a plane cut into 2 parts by cylinder) + // We must make faces of equal wires separately. One of equal wires makes a + // hole in a face and should come together with outer wires of face. + // The other of a wires pair bounds a face that may have holes in turn. + + // Find equal wires among internal wires + TopTools_DataMapOfShapeShape EqWM; // key is a hole part of a pair of equal wires + findEqual (myInternalWL, EqWM, myFace); + + if (!EqWM.IsEmpty()) { // there are equal wires + + if (hasOldHoles) + myInternalWL.Append( myNewWires ); // an old wire can be inside an equal wire + + // classify equal wire pairs + BRepAlgo_AsDes OuterInner; + classify (EqWM,OuterInner,myFace); + + // make face of most internal of equal wires and its inner wires + while ( !EqWM.IsEmpty()) { + + TopTools_ListOfShape prevHolesL; // list of hole-part of previous most internal equal wires + + // find most internal wires among pairs (key - hole, value - outer part) + TopTools_DataMapIteratorOfDataMapOfShapeShape it(EqWM); + Standard_Integer nbEqW = EqWM.Extent(); // protection against infinite loop + for ( ; it.More(); it.Next()) { + + TopoDS_Wire outerW = TopoDS::Wire ( it.Value() ); + if ( OuterInner.HasDescendant( outerW ) && // has internal + ! OuterInner.Descendant( outerW ).IsEmpty() ) + continue; + + FR.Add( outerW ); + + // add internal wires that are inside of outerW + TopTools_ListIteratorOfListOfShape itIW (myInternalWL); + while ( itIW.More()) { + TopoDS_Wire IW = TopoDS::Wire ( itIW.Value() ); + if ( isInside (myFace, IW, outerW)) { + FR.Add (IW); + myInternalWL.Remove( itIW ); // == itIW.Next() !!! + } + else + itIW.Next(); + } + + // the hole-part of current pair of equal wires will be in the next new face + prevHolesL.Append ( it.Key() ); + + } // Loop on map of equal pairs searching for innermost wires + + // make faces + FR.Perform(); + if (FR.IsDone()) { + for (; FR.More(); FR.Next()) + myNewFaces.Append(FR.Current()); + } + + FR.Clear(); + + // add hole-parts to FaceRestrictor, + // remove them from the EqWM, + // remove found wires as internal of resting classified wires + Standard_Boolean clearOuterInner = ( prevHolesL.Extent() < EqWM.Extent() ); + TopTools_ListIteratorOfListOfShape itPrev (prevHolesL); + for (; itPrev.More(); itPrev.Next()) { + TopoDS_Wire& Hole = TopoDS::Wire ( itPrev.Value() ); + FR.Add ( Hole ); + if (clearOuterInner) { + const TopoDS_Wire& outerW = TopoDS::Wire ( EqWM.Find( Hole ) ); + // Loop on wires including outerW + TopTools_ListIteratorOfListOfShape itO( OuterInner.Ascendant( outerW )); + for (; itO.More(); itO.Next()) { + TopTools_ListOfShape& innerL = OuterInner.ChangeDescendant( itO.Value() ); + TopTools_ListIteratorOfListOfShape itI (innerL); + // Loop on internal wires of current including wire + for (; itI.More(); itI.Next()) + if ( outerW.IsSame( itI.Value() )) { + innerL.Remove( itI ); break; + } + } + } + EqWM.UnBind ( Hole ); + } + + if (nbEqW == EqWM.Extent()) + { + // error: pb with wires classification +#ifdef DEB + MESSAGE("Partition_Loop2d::WiresToFaces(), pb with wires classification"); +#endif + break; + } + + } // while (!EqWM.IsEmpty) + + } // if !EqWM.IsEmpty() + + myNewWires.Append ( myInternalWL ); + + TopTools_ListIteratorOfListOfShape itW (myNewWires); + for (; itW.More(); itW.Next()) { + TopoDS_Wire& W = TopoDS::Wire ( itW.Value() ); + FR.Add(W); + } + FR.Perform(); + for (; FR.IsDone() && FR.More(); FR.Next()) + myNewFaces.Append(FR.Current()); + + + TopTools_ListIteratorOfListOfShape itNF (myNewFaces); + for (; itNF.More(); itNF.Next()) + itNF.Value().Orientation( myFaceOri ); +} + +#endif diff --git a/libsrc/occ/Partition_Loop3d.cxx b/libsrc/occ/Partition_Loop3d.cxx new file mode 100644 index 00000000..3e9acc3c --- /dev/null +++ b/libsrc/occ/Partition_Loop3d.cxx @@ -0,0 +1,356 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.cxx +// Module : GEOM + +//using namespace std; +#include +#include "Partition_Loop3d.ixx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Loop3d +//purpose : +//======================================================================= + +Partition_Loop3d::Partition_Loop3d() +{ +} + +//======================================================================= +//function : AddConstFaces +//purpose : Add faces of as unique faces in the result. +//======================================================================= + +void Partition_Loop3d::AddConstFaces(const TopoDS_Shape& S) +{ + TopExp_Explorer FaceExp(S, TopAbs_FACE); + for (; FaceExp.More(); FaceExp.Next()) + myFaces.Append( FaceExp.Current() ); + + TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, myEFMap); +} + +//======================================================================= +//function : AddSectionFaces +//purpose : Add faces of as double faces in the result. +//======================================================================= + +void Partition_Loop3d::AddSectionFaces(const TopoDS_Shape& S) +{ + AddConstFaces( S ); + AddConstFaces( S.Reversed() ); +} + +//======================================================================= +//function : MakeShells +//purpose : Make and return shells. +// can contain faces that must not be +// added to result shells. +//======================================================================= + +const TopTools_ListOfShape& + Partition_Loop3d::MakeShells (const TopTools_MapOfOrientedShape& AvoidFacesMap) +{ + myNewShells.Clear(); + + BRep_Builder Builder; + TopTools_MapOfShape CheckedEdgesMap; + TopTools_MapOfOrientedShape AddedFacesMap; + + TopTools_ListIteratorOfListOfShape itF (myFaces); + for (; itF.More(); itF.Next()) + { + const TopoDS_Shape& FF = itF.Value(); + if (AvoidFacesMap.Contains( FF ) || + ! AddedFacesMap.Add( FF ) ) + continue; + + // make a new shell + TopoDS_Shell Shell; + Builder.MakeShell(Shell); + Builder.Add(Shell,FF); + + // clear the maps from shapes added to previous Shell + TopTools_MapIteratorOfMapOfShape itEM (CheckedEdgesMap); + for (; itEM.More(); itEM.Next()) { + TopTools_ListOfShape& FL = myEFMap.ChangeFromKey( itEM.Key()); + TopTools_ListIteratorOfListOfShape it (FL); + while ( it.More()) { + if (AddedFacesMap.Contains( it.Value())) + FL.Remove( it ); + else + it.Next(); + } + } + CheckedEdgesMap.Clear(); + + + // loop on faces added to Shell; add their neighbor faces to Shell and so on + TopoDS_Iterator itAddedF (Shell); + for (; itAddedF.More(); itAddedF.Next()) + { + const TopoDS_Face& F = TopoDS::Face (itAddedF.Value()); + + // loop on edges of F; find a good neighbor face of F by E + TopExp_Explorer EdgeExp(F, TopAbs_EDGE); + for (; EdgeExp.More(); EdgeExp.Next()) + { + const TopoDS_Edge& E = TopoDS::Edge( EdgeExp.Current()); + if (! CheckedEdgesMap.Add( E )) + continue; + + // candidate faces list + const TopTools_ListOfShape& FL = myEFMap.ChangeFromKey(E); + if (FL.IsEmpty()) + continue; + // select one of neighbors + TopoDS_Face SelF; + if (FL.Extent() == 2) { + if (! F.IsSame( FL.First() )) + SelF = TopoDS::Face( FL.First() ); + else if (!F.IsSame( FL.Last() )) + SelF = TopoDS::Face( FL.Last() ); + } + else { + // check if a face already added to Shell shares E + TopTools_ListIteratorOfListOfShape it (FL); + Standard_Boolean found = Standard_False; + for (; !found && it.More(); it.Next()) + if (F != it.Value()) + found = AddedFacesMap.Contains( it.Value() ); + if (found) + continue; + // select basing on geometrical check + Standard_Boolean GoodOri, inside; + Standard_Real dot, MaxDot = -100; + TopTools_ListOfShape TangFL; // tangent faces + for ( it.Initialize( FL ) ; it.More(); it.Next()) { + const TopoDS_Face& NeighborF = TopoDS::Face( it.Value()); + if (NeighborF.IsSame( F )) + continue; + inside = Partition_Loop3d::IsInside( E, F, NeighborF, 1, dot, GoodOri); + if (!GoodOri) + continue; + if (!inside) + dot = -dot - 3; + if (dot < MaxDot) + continue; + if ( IsEqual( dot, MaxDot)) + TangFL.Append(SelF); + else + TangFL.Clear(); + MaxDot = dot; + SelF = NeighborF; + } + if (!TangFL.IsEmpty()) { + for (it.Initialize( TangFL ); it.More(); it.Next()) { + const TopoDS_Face& NeighborF = TopoDS::Face( it.Value()); + if (Partition_Loop3d:: IsInside( E, SelF , NeighborF, 0, dot, GoodOri)) + SelF = NeighborF; + } + } + } + if (!SelF.IsNull() && + AddedFacesMap.Add( SelF ) && + !AvoidFacesMap.Contains( SelF )) + Builder.Add( Shell, SelF); + + } // loop on edges of F + + } // loop on the faces added to Shell + + // Shell is complete + myNewShells.Append( Shell ); + + } // loop on myFaces + + + // prepare to the next call + myFaces.Clear(); + myEFMap.Clear(); + + return myNewShells; +} + + + +//======================================================================= +//function : Normal +//purpose : +//======================================================================= + +gp_Vec Partition_Loop3d::Normal(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + gp_Vec Norm, V1, V2; + Standard_Real First, Last; + gp_Pnt Ps; + + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last); + Handle(Geom_Surface) Sf = BRep_Tool::Surface(F); + + gp_Pnt2d p = C2d->Value( 0.5*(First+Last) ); + Sf->D1(p.X(), p.Y(), Ps, V1, V2); + Norm = V1.Crossed(V2); + + if (F.Orientation() == TopAbs_REVERSED ) + Norm.Reverse(); + + return Norm; +} + +//======================================================================= +//function : NextNormal +//purpose : find normal to F at point a little inside F near the middle of E +//warning : E must be properly oriented in F. +//======================================================================= + +static gp_Vec NextNormal(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + Standard_Real First, Last; + + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last); + Handle(Geom_Surface) Sf = BRep_Tool::Surface(F); + + gp_Pnt2d p; + gp_Vec2d v; + C2d->D1( 0.5*(First+Last), p, v); + if (E.Orientation() != F.Orientation()) + v.Reverse(); + gp_Dir2d dir( -v.Y(), v.X() ); // dir inside F + + Standard_Real duv = 1e-6; // this is not Ok and may give incorrect result if + // resolutionUV of compared faces is very different. To have a good result, + //it is necessary to get normal to faces at points equidistant from E in 3D + + p.SetX( p.X() + dir.X()*duv ); + p.SetY( p.Y() + dir.Y()*duv ); + + gp_Pnt Ps; + gp_Vec Norm, V1, V2, VV1, VV2; + Sf->D1( p.X(), p.Y(), Ps, V1, V2); + Norm = V1.Crossed(V2); + + if (F.Orientation() == TopAbs_REVERSED ) + Norm.Reverse(); + + return Norm; +} + + +//======================================================================= +//function : FindEinF +//purpose : find E in F +//======================================================================= + +static TopoDS_Edge FindEinF(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + TopExp_Explorer expl (F, TopAbs_EDGE); + for (; expl.More(); expl.Next()) + if( E.IsSame( expl.Current() )) + return TopoDS::Edge(expl.Current()); + TopoDS_Edge nullE; + return nullE; +} + +//======================================================================= +//function : IsInside +//purpose : check if is inside by edge . +// if , compute : scalar production of +// normalized vectors pointing inside faces, and +// check if faces are oriented well for sewing +//======================================================================= + +Standard_Boolean Partition_Loop3d::IsInside(const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Boolean CountDot, + Standard_Real& Dot, + Standard_Boolean& GoodOri) +{ + Standard_Real f, l; + gp_Pnt P; + gp_Vec Vc1, Vc2, Vin1, Vin2, Nf1, Nf2; + Handle(Geom_Curve) Curve = BRep_Tool::Curve(E,f,l); + Curve->D1( 0.5*(f + l), P, Vc2); + TopoDS_Edge E1, E2 = FindEinF (E, F2); + if (E2.Orientation() == TopAbs_REVERSED ) Vc2.Reverse(); + + Nf1 = Normal(E,F1); + Nf2 = Normal(E,F2); + + Standard_Real sin = + Nf1.CrossSquareMagnitude(Nf2) / Nf1.SquareMagnitude() / Nf2.SquareMagnitude(); + Standard_Boolean tangent = sin < 0.001; + + Standard_Boolean inside = 0; + if (tangent) { + E1 = FindEinF (E, F1); + gp_Vec NNf1 = NextNormal(E1,F1); + gp_Vec NNf2 = NextNormal(E2,F2); + Vin2 = NNf2.Crossed(Vc2); + inside = Vin2 * NNf1 < 0; + } + else { + Vin2 = Nf2.Crossed(Vc2); + inside = Vin2 * Nf1 < 0; + } + + if (!CountDot) return inside; + + if (tangent) + Vin2 = Nf2.Crossed(Vc2); + else + E1 = FindEinF (E, F1); + + Vc1 = Vc2; + if (E1.Orientation() != E2.Orientation()) + Vc1.Reverse(); + Vin1 = Nf1.Crossed(Vc1); + + if (tangent) { + Standard_Real N1N2 = Nf1 * Nf2; + GoodOri = (Vin2 * Vin1 < 0) ? N1N2 > 0 : N1N2 < 0; + } + else { + Standard_Real V1N2 = Vin1 * Nf2; + GoodOri = ( inside ? V1N2 <= 0 : V1N2 >= 0); + } + + Vin1.Normalize(); + Vin2.Normalize(); + + Dot = Vin2 * Vin1; + + return inside; +} + + +#endif diff --git a/libsrc/occ/Partition_Spliter.cxx b/libsrc/occ/Partition_Spliter.cxx new file mode 100644 index 00000000..3c13cf88 --- /dev/null +++ b/libsrc/occ/Partition_Spliter.cxx @@ -0,0 +1,2167 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Spliter.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Spliter.cxx,v 1.7 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include +#include "Partition_Inter2d.hxx" +#include "Partition_Inter3d.hxx" +#include "Partition_Loop2d.hxx" +#include "Partition_Loop3d.hxx" +#include "Partition_Spliter.ixx" + +#include "utilities.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef DEB +//# define PART_PERF +#endif + +#ifdef PART_PERF +# include +#endif + +//======================================================================= +//function : isClosed +//purpose : check id a shape is closed, ie is a solid or a closed shell +//======================================================================= + +static Standard_Boolean isClosed(const TopoDS_Shape& theShape) +{ + Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID); + + if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) { + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF); + for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i) + isClosed = ( MEF(i).Extent() != 1 ); + } + + return isClosed; +} + +//======================================================================= +//function : Partition_Spliter +//purpose : constructor +//======================================================================= + +Partition_Spliter::Partition_Spliter() +{ + myAsDes = new BRepAlgo_AsDes; + Clear(); +} + +//======================================================================= +//function : AddTool +//purpose : add cutting tool that will _NOT_ be in result +//======================================================================= + +void Partition_Spliter::AddTool(const TopoDS_Shape& S) +{ + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + TopoDS_Iterator it (S); + for (; it.More(); it.Next()) + { + AddTool( it.Value()); + myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape + } + return; + } + + for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next()) + { + myMapTools.Add(exp.Current()); + myFaceShapeMap.Bind( exp.Current(), S ); + } + if (isClosed( S )) + myClosedShapes.Add( S ); +} + +//======================================================================= +//function : AddShape +//purpose : add object Shape to be splited +//======================================================================= + +void Partition_Spliter::AddShape(const TopoDS_Shape& S) +{ + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + TopoDS_Iterator it (S); + for (; it.More(); it.Next()) + { + AddShape( it.Value()); + myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape + } + return; + } + + TopExp_Explorer exp(S,TopAbs_FACE); + if (!exp.More()) { // do not split edges and vertices + //myBuilder.Add( myShape, S ); + return; + } + + Standard_Integer nbFacesBefore = myMapFaces.Extent(); // not to add twice the same S + for (; exp.More(); exp.Next()) { + const TopoDS_Shape & aFace = exp.Current(); + if ( ! myFaceShapeMap.IsBound( aFace )) // keep shape of tool face added as object + myFaceShapeMap.Bind( aFace, S ); + if (myMapFaces.Add( aFace )) + myImagesFaces.SetRoot( aFace ); + } + + if (nbFacesBefore == myMapFaces.Extent()) + return; + + // solids must be processed before all + if (S.ShapeType() == TopAbs_SOLID) + myListShapes.Prepend(S); + else + myListShapes.Append(S); + + if (isClosed( S )) + myClosedShapes.Add( S ); + +} + +//======================================================================= +//function : Shape +//purpose : return resulting compound +//======================================================================= + +TopoDS_Shape Partition_Spliter::Shape() const +{ + return myShape; +} + +//======================================================================= +//function : Clear +//purpose : clear fields +//======================================================================= + +void Partition_Spliter::Clear() +{ + myDoneStep = TopAbs_SHAPE; + + myListShapes.Clear(); + myMapFaces.Clear(); + myMapTools.Clear(); + myEqualEdges.Clear(); + myNewSection.Clear(); + myClosedShapes.Clear(); + mySharedFaces.Clear(); + myWrappingSolid.Clear(); + myFaceShapeMap.Clear(); + + myInternalFaces.Clear(); + myIntNotClFaces.Clear(); + + myAsDes->Clear(); + myImagesFaces.Clear(); + myImagesEdges.Clear(); + myImageShape.Clear(); + + // myInter3d = Partition_Inter3d(myAsDes); + Partition_Inter3d hinter3d (myAsDes); + myInter3d = hinter3d; + + myAddedFacesMap.Clear(); + +} + +//======================================================================= +//function : Compute +//purpose : produce a result +//======================================================================= + +void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) +{ + if ((Limit != TopAbs_SHAPE && myDoneStep == Limit) || + (Limit == TopAbs_SHAPE && myDoneStep == TopAbs_SOLID)) + return; + + myBuilder.MakeCompound( myShape ); + + TopTools_MapIteratorOfMapOfShape it; + TopTools_ListIteratorOfListOfShape itl; + TopExp_Explorer exp; + +#ifdef PART_PERF + OSD_Chronometer aCron; +#endif + + if (myDoneStep > TopAbs_VERTEX) { + + TopTools_ListOfShape aListFaces; + aListFaces = myImagesFaces.Roots(); + for (it.Initialize(myMapTools); it.More(); it.Next()) + aListFaces.Append(it.Key()); + +#ifdef PART_PERF + aCron.Start(); +#endif + + //----------------------------------------------- + // Intersection between faces + //----------------------------------------------- + // result is in myAsDes as a map Face - list of new edges; + // special care is done for section edges, same domain faces and vertices: + // data about them is inside myInter3d + myInter3d.CompletPart3d(aListFaces, myFaceShapeMap); + +#ifdef PART_PERF + MESSAGE("+++ CompletPart3d()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + //----------------------------------------------- + // Intersection of edges + //----------------------------------------------- + + // add tool faces which must be reconstructed to myMapFaces too + FindToolsToReconstruct(); + +#ifdef PART_PERF + MESSAGE("+++ FindToolsToReconstruct()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + + // add existing vertices to edges of object faces in myAsDes + TopTools_MapOfShape DoneEM; + for ( it.Initialize(myMapFaces); it.More(); it.Next()) { + const TopoDS_Shape& F = it.Key(); + TopoDS_Face FForward = TopoDS::Face(F.Oriented(TopAbs_FORWARD)); + for (exp.Init(FForward,TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( exp.Current() ); + myAsDes->Add(FForward,E); + if (DoneEM.Add(E)) { + TopoDS_Iterator itV(E); + for (; itV.More(); itV.Next()) { + const TopoDS_Vertex& V = TopoDS::Vertex( itV.Value()); + myAsDes->Add(E, myInter3d.ReplaceSameDomainV( V, E )); + } + } + } + } + + // intersect edges that are descendants of a face in myAsDes + TopTools_MapOfShape& Modif = myInter3d.TouchedFaces(); + for ( it.Initialize(Modif); it.More(); it.Next()) { + const TopoDS_Face& F = TopoDS::Face(it.Key()); + Partition_Inter2d::CompletPart2d (myAsDes, F, myInter3d.NewEdges()); + } + // now myAsDes contains also new vertices made at edge intersection as + // descendant of edges both new and old + + myDoneStep = TopAbs_VERTEX; + +#ifdef PART_PERF + MESSAGE("+++ CompletPart2d()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + } // if (myDoneStep > TopAbs_VERTEX) + + if (Limit == TopAbs_VERTEX) { + // add new vertices to myShape + for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) { + if (! myAsDes->HasDescendant( it.Key() )) + continue; + itl.Initialize( myAsDes->Descendant( it.Key() )); + for (; itl.More(); itl.Next()) + myBuilder.Add ( myShape, itl.Value() ); + } + return; + } + + + if (myDoneStep > TopAbs_EDGE) { + + //----------------------------------------------- + //----------------------------------------------- + // ------- Reconstruction of all the edges.------ + //----------------------------------------------- + //----------------------------------------------- + + // ============== + // cut new edges + // ============== + TopTools_ListOfShape LSE; // all edge splits + for ( it.Initialize(myInter3d.NewEdges()); it.More(); it.Next()) { + + TopoDS_Vertex V1,V2; + TopoDS_Edge EE = TopoDS::Edge(it.Key()); + + TopTools_ListOfShape aListV, aListF; + aListV = myAsDes->Descendant(EE); // intersection vertices + aListF = myAsDes->Ascendant(EE); // intersected faces + + if (aListV.IsEmpty()) + continue; // new edge does not intersect any other edge + + // Add end vertices to new edges only if + // one face is Tool and the other is Shape + Standard_Boolean isTool1 = ! myMapFaces.Contains( aListF.First() ); + Standard_Boolean isTool2 = ! myMapFaces.Contains( aListF.Last() ); + if (isTool1 || isTool2) + { + TopExp::Vertices(EE,V1,V2); + Standard_Real Tol = Max (BRep_Tool::Tolerance( V1 ), + BRep_Tool::Tolerance( V2 )); + + gp_Pnt P1 = BRep_Tool::Pnt(V1); + gp_Pnt P2 = BRep_Tool::Pnt(V2); + Standard_Boolean AddV1 = Standard_True; + Standard_Boolean AddV2 = Standard_True; + + // add only if there is no intersection at end vertex + for (itl.Initialize(aListV); itl.More(); itl.Next()) { + const TopoDS_Vertex& Ve = TopoDS::Vertex(itl.Value()) ; + Standard_Real Tol2 = Max ( Tol, BRep_Tool::Tolerance( Ve )); + Tol2 *= Tol2; + gp_Pnt P = BRep_Tool::Pnt(Ve); + if (AddV1 && P.SquareDistance(P1) <= Tol2) + AddV1 = Standard_False; + + if (AddV2 && P.SquareDistance(P2) <= Tol2) + AddV2 = Standard_False; + } + + if (AddV1) { + aListV.Append(V1); + myAsDes->Add(EE,V1); + } + + if (AddV2) { + aListV.Append(V2); + myAsDes->Add(EE,V2); + } + } + + // cut new edges + Standard_Integer NbV=aListV.Extent() ; + if (NbV>1 || (NbV==1 && V1.IsSame(V2)) ) { + TopTools_ListOfShape LNE; + MakeEdges (EE,aListV, LNE); + myImagesEdges.Bind(EE,LNE); + LSE.Append( LNE ); + } + } + + // ============== + // cut old edges + // ============== + for ( it.Initialize(myMapFaces); it.More(); it.Next()) { + for (exp.Init( it.Key(), TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& EE = TopoDS::Edge( exp.Current() ); + if ( myImagesEdges.HasImage( EE )) + continue; + TopTools_ListOfShape LNE; + const TopTools_ListOfShape& aListVV = myAsDes->Descendant(EE); + MakeEdges (EE, aListVV, LNE); + myImagesEdges.Bind(EE,LNE); + LSE.Append( LNE ); + } + } +#ifdef PART_PERF + MESSAGE("+++ Cut Edges"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + + // process same domain section edges + MergeEqualEdges( LSE ); + + myDoneStep = TopAbs_EDGE; + +#ifdef PART_PERF + MESSAGE("+++ MergeEqualEdges()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + } // if (myDoneStep > TopAbs_EDGE) + + if (Limit == TopAbs_EDGE) { + // add splits of old edges + TopTools_ListIteratorOfListOfShape itNE; + for (itl.Initialize( myListShapes );itl.More();itl.Next()) { + if (myMapTools.Contains( itl.Value() )) + continue; // skip tool faces + for ( exp.Init( itl.Value(), TopAbs_EDGE ); exp.More(); exp.Next()) { + itNE.Initialize( myImagesEdges.Image( exp.Current() )); + for ( ; itNE.More(); itNE.Next()) + myBuilder.Add ( myShape, itNE.Value() ); + } + } + // add splits of new edges + for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) { + itNE.Initialize( myImagesEdges.Image( it.Key() )); + for (; itNE.More(); itNE.Next()) + myBuilder.Add ( myShape, itNE.Value() ); + } + return; + } + + + //----------------------------------------------- + // split faces + //----------------------------------------------- + + if (myDoneStep > TopAbs_FACE) { + + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + TopoDS_Shape FacesComp = MakeFaces ( itl.Value()); + // there is a cunning here: myImagesFaces keeps faces made by Loop2d + // but some of them may be replaced with splits of same domain face + // and myImageShape keeps ultimate result + myImageShape.Bind( itl.Value(), FacesComp ); + } + + myDoneStep = TopAbs_FACE; +#ifdef PART_PERF + MESSAGE("+++ MakeFaces()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + } + + if (Limit == TopAbs_WIRE || + Limit == TopAbs_FACE) { + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + if ( myMapTools.Contains( itl.Value() )) + continue; // no result needed for a tool face + const TopoDS_Shape& FacesComp = myImageShape.Image( itl.Value() ).First(); + for ( exp.Init( FacesComp, Limit); exp.More(); exp.Next()) + myBuilder.Add ( myShape, exp.Current()); + } + return; + } + + + //----------------------------------------------- + // split and add solids and shells + //----------------------------------------------- + + Standard_Boolean makeSolids = (Limit == TopAbs_SHAPE || + Limit < TopAbs_SHELL); + for (itl.Initialize(myListShapes);itl.More();itl.Next()) + { + const TopoDS_Shape & S = itl.Value(); + if (S.ShapeType() > TopAbs_SHELL) + continue; + + TopTools_ListOfShape NSL; // new shape list + MakeShells (S , NSL); + if (makeSolids && S.ShapeType() == TopAbs_SOLID ) + MakeSolids( S, NSL ); + + // store new shells or solids + TopTools_ListIteratorOfListOfShape itNSL (NSL); + for ( ; itNSL.More(); itNSL.Next()) + myBuilder.Add (myShape, itNSL.Value()); + } +#ifdef PART_PERF + MESSAGE("+++ MakeShells()"); + aCron.Show( cout ); +#endif + + //----------------------------------------------- + // add split faces + //----------------------------------------------- + + for (itl.Initialize(myListShapes);itl.More();itl.Next()) + { + const TopoDS_Shape & S = itl.Value(); + if (S.ShapeType() != TopAbs_FACE || + myMapTools.Contains( S )) + continue; + TopoDS_Iterator itS( myImageShape.Image(S).First() ); + for (; itS.More(); itS.Next()) + if (! myAddedFacesMap.Contains( itS.Value() )) + myBuilder.Add (myShape, itS.Value()); + } + + myDoneStep = makeSolids ? TopAbs_SOLID : TopAbs_SHELL; + +} + +//======================================================================= +//function : MakeSolids +//purpose : make solids out of Shells +//======================================================================= + +void Partition_Spliter::MakeSolids(const TopoDS_Shape & theSolid, + TopTools_ListOfShape & theShellList) +{ + // for a solid wrapping other shells or solids without intersection, + // it is necessary to find shells making holes in it + + TopTools_ListOfShape aNewSolids; // result + TopTools_ListOfShape aHoleShells; + TopoDS_Shape anInfinitePointShape; + + Standard_Boolean isWrapping = myWrappingSolid.Contains( theSolid ); + if (!isWrapping && !theShellList.IsEmpty()) + { + // check if theSolid initially has internal shells + TopoDS_Iterator aShellExp (theSolid); + aShellExp.Next(); + isWrapping = aShellExp.More(); + } + + TopTools_ListIteratorOfListOfShape aShellIt(theShellList); + for ( ; aShellIt.More(); aShellIt.Next()) + { + const TopoDS_Shape & aShell = aShellIt.Value(); + + // check if a shell is a hole + if (isWrapping && IsInside (anInfinitePointShape, aShell)) + aHoleShells.Append( aShell ); + else + { + // make a solid from a shell + TopoDS_Solid Solid; + myBuilder.MakeSolid( Solid ); + myBuilder.Add (Solid, aShell); + + aNewSolids.Append (Solid); + } + } + + // find an outer shell most close to each hole shell + TopTools_DataMapOfShapeShape aInOutMap; + for (aShellIt.Initialize( aHoleShells ); aShellIt.More(); aShellIt.Next()) + { + const TopoDS_Shape & aHole = aShellIt.Value(); + TopTools_ListIteratorOfListOfShape aSolisIt (aNewSolids); + for ( ; aSolisIt.More(); aSolisIt.Next()) + { + const TopoDS_Shape & aSolid = aSolisIt.Value(); + if (! IsInside( aHole, aSolid )) + continue; + + if ( aInOutMap.IsBound (aHole)) + { + const TopoDS_Shape & aSolid2 = aInOutMap( aHole ); + if ( IsInside( aSolid, aSolid2 )) + { + aInOutMap.UnBind( aHole ); + aInOutMap.Bind ( aHole, aSolid ); + } + } + else + aInOutMap.Bind ( aHole, aSolid ); + } + + // add aHole to a solid + if (aInOutMap.IsBound( aHole )) + myBuilder.Add ( aInOutMap( aHole ), aHole ); + } + + theShellList.Clear(); + theShellList.Append( aNewSolids ); +} + +//======================================================================= +//function : FindFacesInside +//purpose : return compound of faces of other shapes that are +// inside . +// is an object shape. +// makes avoid faces that do not form a +// closed shell +// makes return already added faces +//======================================================================= + +TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, + const Standard_Boolean CheckClosed, + const Standard_Boolean All) +{ + // ================================================ + // check if internal faces have been already found + // ================================================ + TopExp_Explorer expl; + if (myInternalFaces.IsBound( theShape )) + { + TopoDS_Shape aIntFComp = myInternalFaces.Find ( theShape ); + TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find ( theShape ); + + expl.Init( aIntRemFComp, TopAbs_FACE); + if (CheckClosed || !expl.More()) + return aIntFComp; + + TopoDS_Compound C; + myBuilder.MakeCompound( C ); + // add removed faces + for (; expl.More(); expl.Next()) + myBuilder.Add( C, expl.Current() ); + // add good internal faces + for (expl.Init( aIntFComp, TopAbs_FACE); expl.More(); expl.Next()) + myBuilder.Add( C, expl.Current() ); + return C; + } + + // =================================== + // get data for internal faces search + // =================================== + + // compound of split faces of theShape + const TopoDS_Shape& CSF = myImageShape.Image(theShape).First(); + + TopTools_MapOfShape MSE, MFP; + TopTools_DataMapOfShapeListOfShape DMSEFP; + TopTools_MapIteratorOfMapOfShape itm; + TopTools_ListOfShape EmptyL; + + // MSE filling: map of new section edges of CSF + for (expl.Init(CSF,TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape & resE = expl.Current() ; + if (myNewSection.Contains( resE )) // only new edges + MSE.Add(resE); + } + + // DMEF: map edge of CSF - faces of CSF + TopTools_IndexedDataMapOfShapeListOfShape DMEF; + TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF); + + // Fill + // 1. MFP - a map of faces to process: map of resulting faces except + // those of theShape; we`ll add to C those of them which are inside CSF + // 2. DMSEFP - edge of MSE => faces of MFP + TopTools_ListIteratorOfListOfShape itl; + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + const TopoDS_Shape& aShape = itl.Value(); + if ( theShape.IsSame( aShape )) continue; + // fill maps + // iterate on split faces of aShape + TopoDS_Iterator itF ( myImageShape.Image(aShape).First() ); + for ( ; itF.More(); itF.Next()) { + const TopoDS_Shape& sf = itF.Value(); + MFP.Add(sf); + // iterate on edges of split faces of aShape, + // add to DMSEFP edges that are new + for (expl.Init( sf, TopAbs_EDGE ); expl.More(); expl.Next()) { + TopoDS_Shape se = expl.Current(); + if ( MSE.Contains(se)) {// section edge + if (!DMSEFP.IsBound(se)) + DMSEFP.Bind(se,EmptyL); + DMSEFP(se).Append(sf); + } + } + } + } + + // add tool faces having section edges on faces of theShape to MFP and DMSEFP; + // such tool faces need not to be reconstructed and so they are not in myListShapes + for (itm.Initialize(myMapTools); itm.More(); itm.Next()) + { + const TopoDS_Shape & aToolFace = itm.Key(); + if (myMapFaces.Contains( aToolFace )) + continue; + MFP.Add(aToolFace); + for (expl.Init( aToolFace, TopAbs_EDGE ); expl.More(); expl.Next()) { + TopoDS_Shape se = expl.Current(); + if ( MSE.Contains( se )) {// section edge + if (!DMSEFP.IsBound( se )) + DMSEFP.Bind( se, EmptyL ); + DMSEFP( se ).Append( aToolFace ); + } + } + } + + + // =========================== + // find faces inside theShape + // =========================== + + Standard_Boolean skipAlreadyAdded = Standard_False; + Standard_Boolean GoodOri, inside; + Standard_Real dot; + TopTools_ListOfShape KeepFaces; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit; + + // iterate on section edges, check faces of other shapes + // sharing section edges and put internal faces to KeepFaces + for (Mapit.Initialize(DMSEFP); Mapit.More() ; Mapit.Next() ) { + // a new edge of theShape + const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key()); + // an original edge of which E is a split + const TopoDS_Edge& OrigE = TopoDS::Edge ( myImagesEdges.Root( E )); + // does OrigE itself splits a face + Standard_Boolean isSectionE = myInter3d.IsSectionEdge ( OrigE ); + + // split faces of other shapes sharing E + TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E); + itl.Initialize( LSF ); + while (itl.More()) { + // a split faces of other shape + TopoDS_Face aFace1 = TopoDS::Face(itl.Value()); + // remove aFace1 form DMSEFP and MFP + LSF.Remove( itl ); // == itl.Next(); + if (!MFP.Remove( aFace1 )) + continue; // was not is MFP ( i.e already checked) + // check if aFace1 was already added to 2 shells + if (!All && + myAddedFacesMap.Contains( aFace1 ) && + myAddedFacesMap.Contains( aFace1.Reversed() )) { + skipAlreadyAdded = Standard_True; + continue; + } + + // find another face which originates from the same face as aFace1: + // usually aFace2 is internal if aFace1 is not and vice versa + + TopoDS_Shape anOrigFace = aFace1; + if (myImagesFaces.IsImage(aFace1)) + anOrigFace = myImagesFaces.Root(aFace1); + TopoDS_Shape aFace2; + if ( !isSectionE ) { + while (itl.More()) { + aFace2 = itl.Value(); + if (!MFP.Contains( aFace2 )) { + LSF.Remove( itl ); + continue; + } + if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 ))) + break; + itl.Next(); + } + if (itl.More()) { // aFace2 found, remove it from maps + LSF.Remove( itl ); + MFP.Remove(aFace2); + } + else + aFace2.Nullify(); + itl.Initialize( LSF ); + } + + // check that anOrigFace is not same domain with CSF faces it intersects + + const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E + const TopoDS_Shape& origF1 = myImagesFaces.Root(FL.First()); + const TopoDS_Shape& origF2 = myImagesFaces.Root(FL.Last()); + Standard_Boolean sameDom1 = anOrigFace.IsSame( origF1 ); + Standard_Boolean sameDom2 = anOrigFace.IsSame( origF2 ); + if (!(sameDom1 || sameDom2) && myInter3d.HasSameDomainF( anOrigFace )) { + sameDom1 = myInter3d.IsSameDomainF( anOrigFace, origF1); + if (origF1 == origF2) + sameDom2 = sameDom1; + else + myInter3d.IsSameDomainF( anOrigFace, origF2); + } + if (sameDom1 && sameDom2) + continue; + if ((sameDom1 || sameDom2)) { + inside = Partition_Loop3d::IsInside (E, + TopoDS::Face(FL.First()), + TopoDS::Face(FL.Last()), + 1, dot, GoodOri); + if (inside || (dot + Precision::Angular() >= 1.0)) + continue; // E is convex between origF1 and origF2 or they are tangent + } + + + // keep one of found faces + + //face of CSF sharing E + const TopoDS_Shape& aShapeFace = sameDom1 ? FL.Last() : FL.First(); + // analyse aFace1 state + inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace), aFace1, + 1, dot, GoodOri); + if (inside && isSectionE) + { + // aFace1 must be tested with both adjacent faces of CSF + const TopoDS_Shape& aShapeFace2 = sameDom1 ? FL.First() : FL.Last(); + if (aShapeFace2 != aShapeFace) + inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace2), aFace1, + 1, dot, GoodOri); + } + + // store internal face + if (inside) + KeepFaces.Append(aFace1); + + else if (!aFace2.IsNull()) + { + if (dot + Precision::Angular() >= 1.0) + { + // aFace2 state is not clear, it will be analysed alone, + // put it back to the maps + MFP.Add( aFace2 ); + LSF.Append( aFace2 ); + } + else + KeepFaces.Append(aFace2); + } + } + } + + // =================================================== + // add not distributed faces connected with KeepFaces + // =================================================== + + // ultimate list of internal faces + TopTools_ListOfShape KeptFaces; + + // add to MFP not split tool faces as well, they may be connected with + // tool faces interfering with theShape + for ( itm.Initialize(myMapTools); itm.More(); itm.Next() ) { + const TopoDS_Shape& aToolFace = itm.Key(); + if (!myImageShape.HasImage(aToolFace)) + MFP.Add (aToolFace); + } + + if (MFP.IsEmpty()) + KeptFaces.Append (KeepFaces); + + while (!KeepFaces.IsEmpty()) + { + // KeepEdges : map of edges of faces kept last time + TopTools_IndexedMapOfShape KeepEdges; + for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) { + TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges); + KeptFaces.Append( itl.Value() ); + } + + KeepFaces.Clear(); + + // keep faces connected with already kept faces by KeepEdges + for ( itm.Initialize(MFP); itm.More(); itm.Next() ) { + const TopoDS_Shape& FP = itm.Key(); + for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape& se = expl.Current(); + if (!MSE.Contains(se) && KeepEdges.Contains(se) ) { + KeepFaces.Append(FP); + MFP.Remove(FP); + break; + } + } + } + } + + // =============================================================== + // here MFP contains faces outer of theShape and those of shapes + // which do not interfere with theShape at all and between which + // there may be those wrapped by theShape and whose faces may be + // needed to be returned as well + // =============================================================== + + Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID); + if (All || isSolid) // All is for sub-result removal + { + // loop on not used faces; checked faces will be removed from MFP + // during the loop + for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) { + const TopoDS_Shape & aFace = itm.Key(); + + // a shape which aFace originates from + TopoDS_Shape anOrigShape = GetOriginalShape( aFace ); + + // find out if all split faces of anOrigShape are not in MFP + // and by the way remove them from MFP + Standard_Boolean isAllOut = Standard_True; + TopoDS_Shape aSplitFaces = anOrigShape; + if (myImageShape.HasImage(anOrigShape)) + aSplitFaces = myImageShape.Image(anOrigShape).First(); + + TopTools_ListOfShape aSplitFaceL; // faces candidate to be kept + for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next()) + { + const TopoDS_Shape & aSpFace = expl.Current(); + // a tool face which became object has image but the whole tool shape has not + if (myImageShape.HasImage( aSpFace )) + { + TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE ); + for ( ; exF.More(); exF.Next() ) + { + aSplitFaceL.Append( exF.Current() ); + if ( ! MFP.Remove( exF.Current() ) && isAllOut ) + // a shared face might be removed from MFP during a prev loop + isAllOut = mySharedFaces.Contains( exF.Current() ); + } + } + else + { + aSplitFaceL.Append( aSpFace ); + if ( ! MFP.Remove( aSpFace ) && isAllOut) + // a shared face might be removed from MFP during a prev loop + isAllOut = mySharedFaces.Contains( aSpFace ); + } + } + itm.Initialize( MFP ); // iterate remaining faces + if ( !isAllOut ) + continue; + + // classify anOrigShape against theShape + if (IsInside (anOrigShape, theShape)) + { + if (isSolid && myClosedShapes.Contains( anOrigShape )) + // to make a special care at solid reconstruction + myWrappingSolid.Add ( theShape ); + + // keep faces of an internal shape anOrigShape + KeptFaces.Append( aSplitFaceL ); + } + } + } + + // ==================================================== + // check if kept faces form a shell without free edges + // ==================================================== + + DMEF.Clear(); // edge - kept faces + MFP.Clear(); // reuse it for wrong faces + if (CheckClosed) { + for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) + TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF); + + Standard_Integer i, nb = DMEF.Extent(); + Standard_Boolean isClosed = Standard_False; + while (!isClosed) { + isClosed = Standard_True; + for (i=1; isClosed && i<=nb; ++i) { + const TopoDS_Shape& E = DMEF.FindKey( i ); + if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) && + ! MSE.Contains( E )) + isClosed = ( DMEF(i).Extent() != 1 ); + } + if (!isClosed) { + const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face + MFP.Add( F ); + // remove bad face from DMEF + for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape& E = expl.Current(); + TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E ); + for (itl.Initialize( FL ); itl.More(); itl.Next() ) { + if ( F.IsSame( itl.Value() )) { + FL.Remove( itl ); + break; + } + } + } + } + } + } + + // ============== + // make a result + // ============== + + TopoDS_Compound C; + // compound of removed internal faces + TopoDS_Compound CNotCl; + + myBuilder.MakeCompound(C); + myBuilder.MakeCompound(CNotCl); + + // add to compounds + for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) + { + TopoDS_Shape & aIntFace = itl.Value(); + if (! MFP.Contains( aIntFace )) + myBuilder.Add( C, aIntFace); + else + myBuilder.Add( CNotCl, aIntFace); + } + + if (!skipAlreadyAdded && CheckClosed) + { + myInternalFaces.Bind( theShape, C ); + myIntNotClFaces.Bind( theShape, CNotCl ); + } + + return C; +} + +//======================================================================= +//function : MakeShell +//purpose : split S into compound of shells +//======================================================================= + +void Partition_Spliter::MakeShells(const TopoDS_Shape& S, + TopTools_ListOfShape& NS) +{ + Partition_Loop3d ShellMaker; + // get compound of split faces of S + const TopoDS_Shape& FacesComp = myImageShape.Image(S).First(); + ShellMaker.AddConstFaces( FacesComp ); + // add split faces inside S + if (myClosedShapes.Contains( S )) { + TopoDS_Shape InternalFacesComp = FindFacesInside(S, Standard_True); + ShellMaker.AddSectionFaces( InternalFacesComp ); + } + + NS = ShellMaker.MakeShells( myAddedFacesMap ); + + // Add faces added to new shell to myAddedFacesMap: + // avoid rebuilding twice commont part of 2 solids. + TopTools_ListIteratorOfListOfShape itS(NS); + while ( itS.More()) { + TopExp_Explorer expF (itS.Value(), TopAbs_FACE); + for (; expF.More(); expF.Next()) + myAddedFacesMap.Add (expF.Current()); + + itS.Next(); + } +} + +//======================================================================= +//function : findEqual +//purpose : compare edges of EL1 against edges of EL2, +// Result is in EMM binding EL1 edges to list of equal edges. +// Edges are considered equall only if they have same vertices. +// ==True makes consider same edges as equal +// Put in all equal edges +//======================================================================= + +static void findEqual (const TopTools_ListOfShape& EL1, + const TopTools_ListOfShape& EL2, + const Standard_Boolean addSame, + TopTools_DataMapOfShapeListOfShape& EEM, + TopTools_MapOfShape& AllEqMap) +{ + // map vertices to edges for EL2 + TopTools_DataMapOfShapeListOfShape VEM; + TopTools_ListIteratorOfListOfShape itE1, itE2(EL2); + TopoDS_Iterator itV; + TopTools_ListOfShape emptyL; + for (; itE2.More(); itE2.Next()) { + for (itV.Initialize( itE2.Value() ); itV.More(); itV.Next()) { + const TopoDS_Shape& V = itV.Value(); + if (! VEM.IsBound( V ) ) + VEM.Bind( V, emptyL); + VEM( V ).Append( itE2.Value()); + } + } + + gp_Vec D1, D2; + gp_Pnt P; + Standard_Real f,l,u,tol; + Handle(Geom_Curve) C1, C2; + Extrema_ExtPC Extrema; + TopoDS_Vertex V1, V2, V3, V4; + + AllEqMap.Clear(); + + for (itE1.Initialize(EL1); itE1.More(); itE1.Next()) { + const TopoDS_Edge& E1 = TopoDS::Edge( itE1.Value()); + if (BRep_Tool::Degenerated( E1 ) || AllEqMap.Contains (E1)) + continue; + TopExp::Vertices( E1, V1, V2 ); + + if (VEM.IsBound(V1)) + itE2.Initialize( VEM(V1) ); + for (; itE2.More(); itE2.Next()) { + const TopoDS_Edge& E2 = TopoDS::Edge( itE2.Value()); + if (BRep_Tool::Degenerated( E2 ) || AllEqMap.Contains (E2)) + continue; + + if (E1.IsSame(E2)) { + if (!addSame) + continue; + } + else { + TopExp::Vertices( E2, V3, V4); + if (!V2.IsSame(V4) && !V2.IsSame(V3)) + continue; + // E1 and E2 have same vertices + // check D1 at end points. + C2 = BRep_Tool::Curve( E2, f,l); + C1 = BRep_Tool::Curve( E1, f,l); + u = BRep_Tool::Parameter(V1,E1); + C1->D1(u, P, D1); + u = BRep_Tool::Parameter(V1.IsSame(V3) ? V3 : V4, E2); + C2->D1(u, P, D2); + D1.Normalize(); D2.Normalize(); + if (Abs(D1*D2) + Precision::Angular() < 1.0) + continue; + if (! V1.IsSame(V2)) { + u = BRep_Tool::Parameter(V2,E1); + C1->D1(u, P, D1); + u = BRep_Tool::Parameter(V2.IsSame(V3) ? V3 : V4, E2); + C2->D1(u, P, D2); + D1.Normalize(); D2.Normalize(); + if (Abs(D1*D2) + Precision::Angular() < 1.0) + continue; + } + // check distance at a couple of internal points + tol = Max(BRep_Tool::Tolerance(E1), + BRep_Tool::Tolerance(E2)); + GeomAdaptor_Curve AC1(C1); + Extrema.Initialize(AC1,f,l); + Standard_Boolean ok = Standard_True, hasMin = Standard_False; + BRep_Tool::Range( E2, f, l); + Standard_Integer i=1, nbi=3; + for (; iValue( f+(l-f)*i/nbi )); + Standard_Integer j=1, nbj=Extrema.NbExt(); + for (; j<=nbj && ok; ++j) { + if (Extrema.IsMin(j)) { + hasMin = Standard_True; + ok = Extrema.Value(j) <= tol; + } + } + } + if ( !hasMin || !ok) + continue; + } + // bind E2 to E1 in EEM + if (!EEM.IsBound(E1)) { + EEM.Bind (E1, emptyL); + AllEqMap.Add (E1); + } + EEM(E1).Append(E2); + AllEqMap.Add (E2); + } + } +} + +//======================================================================= +//function : MakeFaces +//purpose : split faces of S, return compound of new faces +//======================================================================= + +TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) +{ + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + TopTools_ListIteratorOfListOfShape itl, itNE; + + TopExp_Explorer exp(S,TopAbs_FACE); + for (; exp.More(); exp.Next()) { + + const TopoDS_Face& F = TopoDS::Face(exp.Current()); + + TopTools_ListOfShape LNF; + + if (myImagesFaces.HasImage( F )) { + myImagesFaces.LastImage( F, LNF ); + TopAbs_Orientation oriF = F.Orientation(); + for ( itl.Initialize( LNF ); itl.More(); itl.Next()) + itl.Value().Orientation( oriF ); + } + else { + + Partition_Loop2d loops; + loops.Init(F); + + TopTools_IndexedMapOfShape EM; + TopExp::MapShapes( F, TopAbs_EDGE, EM); + + TopTools_MapOfShape AddedEqualM, EqualSeamM; + Standard_Boolean needRebuild = Standard_False; + + // add splits to loops + + // LE: old edges + new not splitted edges + const TopTools_ListOfShape& LE = myAsDes->Descendant(F); + for (itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( itl.Value() ); + + Standard_Boolean isSectionE = myInter3d.IsSectionEdge(E); + Standard_Boolean isNewE = !EM.Contains( E ); + + // LSE: list of split edges + TopTools_ListOfShape LSE; + myImagesEdges.LastImage(E,LSE); // splits of E or E itself + + for (itNE.Initialize(LSE); itNE.More(); itNE.Next()) { + + TopoDS_Edge NE = TopoDS::Edge( itNE.Value() ); + Standard_Boolean isSameE = NE.IsSame ( E ); + + if ( isNewE || isSectionE || !isSameE) { + if (AddedEqualM.Contains( NE )) { + // a seam must be twice in a loop + if (!BRep_Tool::IsClosed( E, F ) || !EqualSeamM.Add( NE )) + continue; + } + + if (isNewE) { + if (isSectionE) { + if ( ! myInter3d.IsSplitOn( NE, E, F) ) + continue; + } + else { + TopoDS_Vertex V1,V2; + TopExp::Vertices(NE,V1,V2); + const TopTools_ListOfShape& EL1 = myAsDes->Ascendant(V1); + const TopTools_ListOfShape& EL2 = myAsDes->Ascendant(V2); + if ( EL1.Extent() < 2 && EL2.Extent() < 2 ) + continue; + } + } + else { + NE.Orientation( E.Orientation()); + if (!isSameE) { + // orient NE because it may be a split of other edge + Standard_Real f,l,u; + Handle(Geom_Curve) C3d = BRep_Tool::Curve( E,f,l ); + Handle(Geom_Curve) NC3d = BRep_Tool::Curve( NE,f,l); + if ( C3d != NC3d) { + gp_Vec D1, ND1; gp_Pnt P; + TopoDS_Vertex V = TopExp::FirstVertex(NE); + u = BRep_Tool::Parameter(V,NE); + NC3d->D1 (u, P, ND1); + u = BRep_Tool::Parameter(V,E); + C3d ->D1 (u, P, D1); + if (ND1.Dot(D1) < 0) + NE.Reverse(); + } + } + } + if (myEqualEdges.Contains( NE )) + AddedEqualM.Add( NE ); + + needRebuild = Standard_True; + } + + if (isNewE || isSectionE) + myNewSection.Add( NE ); + + if (isNewE) + loops.AddSectionEdge(NE); + else + loops.AddConstEdge(NE); + } + } + + //------------------- + // Build the faces. + //------------------- + + if (needRebuild) { + + loops.Perform(); + loops.WiresToFaces(myImagesEdges); + + LNF = loops.NewFaces(); + + myImagesFaces.Bind(F,LNF); + + // replace the result faces that have already been built + // during same domain faces reconstruction done earlier + if (myInter3d.HasSameDomainF( F )) + { + // build map edge to same domain faces: EFM + TopTools_IndexedDataMapOfShapeListOfShape EFM; + TopTools_MapOfShape SDFM; // avoid doubling + itl.Initialize( myInter3d.SameDomain( F )); + for (; itl.More(); itl.Next()) { + if ( !myImagesFaces.HasImage( itl.Value() )) + continue; + // loop on splits of a SD face + TopTools_ListIteratorOfListOfShape itNF; + itNF.Initialize (myImagesFaces.Image( itl.Value() )); + for ( ; itNF.More(); itNF.Next()) { + TopoDS_Shape SDF = itNF.Value(); + if (myImagesFaces.HasImage( SDF )) // already replaced + SDF = myImagesFaces.Image( SDF ).First(); + if (SDFM.Add (SDF)) + TopExp::MapShapesAndAncestors(SDF, TopAbs_EDGE, TopAbs_FACE, EFM); + } + } + // do replace faces in the LNF + TopTools_ListOfShape LOF; + if ( !EFM.IsEmpty() ) + itl.Initialize( LNF ); + while (itl.More()) { + const TopoDS_Shape& NF = itl.Value(); + TopExp_Explorer expE ( NF, TopAbs_EDGE ); + const TopoDS_Edge& E = TopoDS::Edge (expE.Current()); + if (EFM.Contains( E )) { + const TopTools_ListOfShape& SDFL = EFM.FindFromKey( E ); + TopoDS_Shape SDF = SDFL.First(); + Standard_Boolean GoodOri; + Standard_Real dot; + Partition_Loop3d::IsInside (E, TopoDS::Face(NF), TopoDS::Face(SDF), + 1, dot, GoodOri); + if (dot < 0) + { + // NF and SDF are on different side of E + if (SDFL.Extent() == 1) { + itl.Next(); + continue; + } + else + SDF = SDFL.Last(); // next face must be on the same side + } + gp_Vec V1 = Partition_Loop3d::Normal( E, TopoDS::Face( NF )); + gp_Vec V2 = Partition_Loop3d::Normal( E, TopoDS::Face( SDF )); + if (V1*V2 < 0) + SDF.Reverse(); + + if (!myImagesFaces.HasImage( NF )) + myImagesFaces.Bind( NF, SDF ); + + // mySharedFaces is used in FindFacesInside() + mySharedFaces.Add( SDF ); + + LOF.Prepend ( SDF ); + LNF.Remove (itl); + } + else + itl.Next(); + } + + LNF.Append (LOF); + } + } // if (needRebuild) + + else { + LNF.Append( F ); + myImagesFaces.Bind(F,LNF); + } + } // if (myImagesFaces.HasImage( F )) + + // fill the resulting compound + for (itl.Initialize(LNF); itl.More(); itl.Next()) + myBuilder.Add ( C, itl.Value()); + + } // loop on faces of S + + return C; +} + + +//======================================================================= +//function : Tri +//purpose : +//======================================================================= + +static void Tri(const TopoDS_Edge& E, + TopTools_SequenceOfShape& Seq, + const Partition_Inter3d & theInter3d) +{ + Standard_Boolean Invert = Standard_True; + Standard_Real U1,U2; + TopoDS_Vertex V1,V2; + + while (Invert) { + Invert = Standard_False; + for ( Standard_Integer i = 1; i < Seq.Length(); i++) { + + V1 = TopoDS::Vertex(Seq.Value(i)); + V2 = TopoDS::Vertex(Seq.Value(i+1)); + + V1.Orientation(TopAbs_INTERNAL); + V2.Orientation(TopAbs_INTERNAL); + + U1 = BRep_Tool::Parameter(V1,E); + U2 = BRep_Tool::Parameter(V2,E); + + if (IsEqual(U1,U2)) { + if (theInter3d.ReplaceSameDomainV( V1, E ).IsSame( V1 )) + Seq.Remove(i+1); // remove V2 + else + Seq.Remove(i); + i--; + continue; + } + if (U2 < U1) { + Seq.Exchange(i,i+1); + Invert = Standard_True; + } + } + } +} + +//======================================================================= +//function : MakeEdges +//purpose : cut E by vertices VOnE, return list of new edges NE +//======================================================================= + +void Partition_Spliter::MakeEdges (const TopoDS_Edge& E, + const TopTools_ListOfShape& VOnE, + TopTools_ListOfShape& NE ) const +{ + TopoDS_Edge WE = E; + WE.Orientation(TopAbs_FORWARD); + + Standard_Real U1,U2, f, l; + TopoDS_Vertex V1,V2,VF,VL; + + BRep_Tool::Range(WE,f,l); + TopExp::Vertices(WE,VF,VL); + + if (VOnE.Extent() < 3) { // do not rebuild not cut edge + if (( VF.IsSame( VOnE.First() ) && VL.IsSame( VOnE.Last() )) || + VL.IsSame( VOnE.First() ) && VF.IsSame( VOnE.Last() ) ) { + NE.Append( E ); + return; + } + } + + TopTools_SequenceOfShape SV; + TopTools_ListIteratorOfListOfShape itv(VOnE); + TopTools_MapOfOrientedShape VM( VOnE.Extent() ); + for (; itv.More(); itv.Next()) + if ( VM.Add( itv.Value() )) + SV.Append(itv.Value()); + + Tri( WE, SV, myInter3d ); + + if (SV.Length() < 3) { // do not rebuild not cut edge + if (( VF.IsSame( SV.First() ) && VL.IsSame( SV.Last() )) || + VL.IsSame( SV.First() ) && VF.IsSame( SV.Last() ) ) { + NE.Append( E ); + return; + } + } + + Standard_Integer iVer, NbVer = SV.Length(); + + + //---------------------------------------------------------------- + // Construction of the new edges . + //---------------------------------------------------------------- + + if (VF.IsSame(VL)) { // closed edge + if (NbVer==1) + SV.Append( SV.First() ); + else if (!SV.First().IsSame(SV.Last())) { + Standard_Boolean isFirst=0; + Standard_Real minDU = 1.e10; + TopoDS_Vertex endV = Partition_Inter2d::FindEndVertex(VOnE, f,l, E, isFirst,minDU); + if (endV.IsSame(SV.First())) + SV.Append(endV); + else if (endV.IsSame(SV.Last())) + SV.Prepend(endV); + else + MESSAGE ("END VERTEX IS IN SEQUNCE MIDDLE"); + } + NbVer = SV.Length(); + } + + for (iVer=1; iVer < NbVer; iVer++) { + V1 = TopoDS::Vertex(SV(iVer)); + V2 = TopoDS::Vertex(SV(iVer+1)); + + TopoDS_Shape NewEdge = WE.EmptyCopied(); + V1.Orientation(TopAbs_FORWARD); + myBuilder.Add (NewEdge,V1); + V2.Orientation(TopAbs_REVERSED); + myBuilder.Add (NewEdge,V2); + + if (iVer==1) + U1 = f; + else { + V1.Orientation(TopAbs_INTERNAL); + U1=BRep_Tool::Parameter(V1,WE); + } + if (iVer+1 == NbVer) + U2 = l; + else { + V2.Orientation(TopAbs_INTERNAL); + U2=BRep_Tool::Parameter(V2,WE); + } + if (Abs(U1-U2) <= Precision::PConfusion()) { + MESSAGE( "MakeEdges(), EQUAL PARAMETERS OF DIFFERENT VERTICES"); + continue; + } + TopoDS_Edge EE=TopoDS::Edge(NewEdge); + myBuilder.Range (EE,U1,U2); + + TopoDS_Edge NEdge = TopoDS::Edge(NewEdge); + myBuilder.SameParameter(NEdge,Standard_False); + + Standard_Real tol = 1.0e-2; + Standard_Boolean flag = BRep_Tool::SameParameter(NEdge); + if (!flag) { + BRepLib::SameParameter(NEdge,tol); + } + NE.Append(NEdge.Oriented(E.Orientation())); + } +} + +//======================================================================= +//function : MergeEqualEdges +//purpose : find equal edges, choose ones to keep and make +// them have pcurves on all faces they are shared by +//======================================================================= + +void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE) +{ + // find equal edges + // map: edge - equal edges + TopTools_DataMapOfShapeListOfShape EEM( LSE.Extent() ); + findEqual (LSE, LSE, 0, EEM, myEqualEdges); + + TopTools_ListOfShape EEL; // list of equal edges + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itM (EEM); + for ( ; itM.More(); itM.Next()) { + EEL = itM.Value(); + EEL.Append( itM.Key() ); + + // choose an edge to keep, section edges have priority + TopoDS_Edge EKeep; + TopTools_ListIteratorOfListOfShape itEE (EEL); + for (; itEE.More(); itEE.Next()) { + EKeep = TopoDS::Edge( itEE.Value() ); + const TopoDS_Edge& EKeepOrig = TopoDS::Edge( myImagesEdges.Root( EKeep )); + if (myInter3d.IsSectionEdge( EKeepOrig )) + break; + } + + // update edge images and build pcurves + Standard_Real f,l, tol; + for (itEE.Initialize (EEL); itEE.More(); itEE.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( itEE.Value() ); + if ( E.IsSame( EKeep )) + continue; + + // 1. build pcurves of the kept edge on faces where replaced edges exist + const TopoDS_Edge& EReplOrig = TopoDS::Edge( myImagesEdges.Root( E )); + TopTools_ListOfShape FL; + FL = myAsDes->Ascendant( EReplOrig ); + Standard_Integer iFace, iFirstSectionFace = FL.Extent() + 1; + // add faces where the replaced edge is a section edge + if (myInter3d.IsSectionEdge( EReplOrig )) { + TopTools_ListIteratorOfListOfShape seIt; + seIt.Initialize( myInter3d.SectionEdgeFaces ( EReplOrig )); + for ( ; seIt.More(); seIt.Next()) + FL.Append( seIt.Value() ); + } + // loop on faces + TopTools_ListIteratorOfListOfShape itF (FL); + for ( iFace = 1 ; itF.More(); itF.Next(), ++iFace ) { + const TopoDS_Face& F = TopoDS::Face( itF.Value()); + + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( EKeep, F, f,l); + if (pc.IsNull()) { + Handle(Geom_Curve) C3d = BRep_Tool::Curve( EKeep, f, l); + C3d = new Geom_TrimmedCurve( C3d, f,l); + pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol); + if (pc.IsNull()) { + MESSAGE (" CANT BUILD PCURVE "); + } + myBuilder.UpdateEdge( EKeep, pc, F, tol); + } + + if (iFace >= iFirstSectionFace || + !BRep_Tool::IsClosed( EReplOrig, F )) + continue; + + // build the second pcurve for a seam + TopoDS_Vertex V = TopExp::FirstVertex( EKeep ); + Standard_Real Ukeep = BRep_Tool::Parameter( V, EKeep ); + Standard_Real Urepl = BRep_Tool::Parameter( V, E ); + + TopoDS_Edge EReplRev = E; + EReplRev.Reverse(); + Handle(Geom2d_Curve) pcRepl1 = BRep_Tool::CurveOnSurface( E, F, f,l); + Handle(Geom2d_Curve) pcRepl2 = BRep_Tool::CurveOnSurface( EReplRev, F, f,l); + + gp_Pnt2d p1r, p2r, pk; + p1r = pcRepl1->Value( Urepl ); + p2r = pcRepl2->Value( Urepl ); + pk = pc->Value( Ukeep ); + + // suppose that pk is equal to either p1r or p2r + Standard_Boolean isUPeriod = + ( Abs( p1r.X() - p2r.X() ) > Abs( p1r.Y() - p2r.Y() )); + Standard_Boolean is1Equal; + if (isUPeriod) + is1Equal = ( Abs( p1r.X() - pk.X() ) < Abs( p2r.X() - pk.X() )); + else + is1Equal = ( Abs( p1r.Y() - pk.Y() ) < Abs( p2r.Y() - pk.Y() )); + + Handle(Geom2d_Curve) pc2 = Handle(Geom2d_Curve)::DownCast + ( pc->Translated( pk, is1Equal ? p2r : p1r ) ); + + if (E.Orientation() == TopAbs_REVERSED) + is1Equal = !is1Equal; + + if (is1Equal) + myBuilder.UpdateEdge( EKeep, pc, pc2, F, tol); + else + myBuilder.UpdateEdge( EKeep, pc2, pc, F, tol); + + } // loop on a Faces where a replaced edge exists + + + // 2. update edge images according to replacement + if (myImagesEdges.HasImage( E )) + myImagesEdges.Remove( E ); + myImagesEdges.Bind( E, EKeep ); + + } // loop on a list of equal edges EEL + } // loop on a map of equal edges EEM +} + +//======================================================================= +//function : KeepShapesInside +//purpose : remove shapes that are outside of S from resul +//======================================================================= + +void Partition_Spliter::KeepShapesInside (const TopoDS_Shape& S) +{ + TopoDS_Iterator it; + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + for (it.Initialize( S ); it.More(); it.Next()) + KeepShapesInside( it.Value()); + return; + } + + Standard_Boolean isTool = Standard_False; + if (!myImageShape.HasImage( S )) { + isTool = CheckTool( S ); + if (!isTool) return; + } + + // build map of internal faces + TopTools_IndexedMapOfShape MIF; + TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF ); + + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE; + if (!MIF.IsEmpty()) + { + // leave in the result only those shapes having a face in MIF + for (it.Initialize( myShape ); it.More(); it.Next()) { + const TopoDS_Shape & aResShape = it.Value(); + TopExp_Explorer expResF( aResShape, TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if ( MIF.Contains( expResF.Current())) { + myBuilder.Add( C, aResShape ); + if (aResShape.ShapeType() < anInternalShapeType) + anInternalShapeType = aResShape.ShapeType(); + break; + } + } + } + } + + // may be S was not split by internal faces then it is missing + // in myShape, add it + if (!isTool && + (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID)) + { + TopTools_IndexedMapOfShape MSF; // map of split faces of S + TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF); + + // find a shape having all faces in MSF + for (it.Initialize( myShape ); it.More(); it.Next()) { + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if (! MSF.Contains( expResF.Current())) + break; + } + if (! expResF.More()) { + myBuilder.Add( C, it.Value() ); + break; + } + } + } + + myShape = C; +} + +//======================================================================= +//function : RemoveShapesInside +//purpose : remove shapes that are inside S from resul +//======================================================================= + +void Partition_Spliter::RemoveShapesInside (const TopoDS_Shape& S) +{ + TopoDS_Iterator it; + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + for (it.Initialize( S ); it.More(); it.Next()) + RemoveShapesInside( it.Value()); + return; + } + Standard_Boolean isTool = Standard_False; + if (!myImageShape.HasImage( S )) { + isTool = CheckTool( S ); + if (!isTool) return; + } + + TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopTools_IndexedMapOfShape MIF; // map of internal faces + TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF); + + if (MIF.IsEmpty()) return; + + // add to MIF split faces of S + if (myImageShape.HasImage(S)) + TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF); + + // leave in the result only those shapes not having all face in MIF + + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + // RMF : faces of removed shapes that encounter once + TopTools_MapOfShape RFM; + + for (it.Initialize( myShape ); it.More(); it.Next()) { + + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) + if (!MIF.Contains( expResF.Current())) + break; + + if (expResF.More()) + // add shape to result + myBuilder.Add( C, it.Value() ); + else + // add faces of a removed shape to RFM + for (expResF.ReInit(); expResF.More(); expResF.Next()) { + const TopoDS_Shape& F = expResF.Current(); + if ( ! RFM.Remove ( F )) + RFM.Add( F ); + } + } + + if (!isTool) { + + // rebuild S, it must remain in the result + + Standard_Boolean isClosed = Standard_False; + switch (S.ShapeType()) { + case TopAbs_SOLID : + isClosed = Standard_True; break; + case TopAbs_SHELL: { + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF); + Standard_Integer i; + for (i=1; isClosed && i<=MEF.Extent(); ++i) + isClosed = ( MEF(i).Extent() != 1 ); + break; + } + default: + isClosed = Standard_False; + } + if (isClosed) { + + // add to a new shape external faces of removed shapes, ie those in RFM + + TopoDS_Shell Shell; + myBuilder.MakeShell( Shell ); + + // exclude redundant internal face with edges encounterd only once + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopTools_MapIteratorOfMapOfShape itF (RFM); + for ( ; itF.More(); itF.Next()) + TopExp::MapShapesAndAncestors(itF.Key(), TopAbs_EDGE, TopAbs_FACE, MEF); + + // add only faces forming a closed shell + for (itF.Reset() ; itF.More(); itF.Next()) + { + TopExp_Explorer expE (itF.Key(), TopAbs_EDGE); + for (; expE.More(); expE.Next()) + if (MEF.FindFromKey(expE.Current()).Extent() == 1) + break; + if (!expE.More()) + myBuilder.Add( Shell, itF.Key()); + } + + if (S.ShapeType() == TopAbs_SOLID) { + TopoDS_Solid Solid; + myBuilder.MakeSolid( Solid ); + myBuilder.Add (Solid, Shell); + myBuilder.Add (C, Solid); + } + else + myBuilder.Add (C, Shell); + } + else { + if (myImageShape.HasImage( S )) { + for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next()) + myBuilder.Add (C, it.Value()); + } + } + } + + myShape = C; +} + +//======================================================================= +//function : CheckTool +//purpose : Return True if is a tool shape. Prepare tool +// faces of for the search of internal faces. +//======================================================================= + +Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S) +{ + // suppose S has not an image + + Standard_Boolean isTool = Standard_False; + TopoDS_Compound C; + myBuilder.MakeCompound( C ); + + TopExp_Explorer expF( S, TopAbs_FACE); + for (; expF.More(); expF.Next()) { + + const TopoDS_Face& F = TopoDS::Face( expF.Current() ); + if (myMapTools.Contains( F )) + isTool = Standard_True; + else + continue; + + if (myImagesFaces.HasImage( F )) { + // F has been reconstructed + TopAbs_Orientation Fori = F.Orientation(); + TopTools_ListOfShape LNF; + myImagesFaces.LastImage( F, LNF); + TopTools_ListIteratorOfListOfShape itF (LNF); + for ( ; itF.More(); itF.Next()) + myBuilder.Add( C, itF.Value().Oriented(Fori) ); + continue; + } + + Standard_Boolean hasSectionE = myInter3d.HasSectionEdge( F ); + Standard_Boolean hasNewE = myAsDes->HasDescendant( F ); + if (!hasSectionE && !hasNewE) + { + // F intersects nothing + myBuilder.Add( C, F ); + continue; + } + + // make an image for F + + TopoDS_Face NF = F; + NF.Orientation(TopAbs_FORWARD); + NF = TopoDS::Face( NF.EmptyCopied() ); // make a copy + TopoDS_Wire NW; + myBuilder.MakeWire( NW ); + + // add edges, as less as possible + TopTools_ListOfShape NEL; + TopTools_ListIteratorOfListOfShape itNE; + if (hasSectionE) { + // add section edges + TopExp_Explorer expE; + for ( ; expE.More(); expE.Next()) { + if (! myImagesEdges.HasImage( expE.Current() )) + continue; + myImagesEdges.LastImage( expE.Current(), NEL ); + for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) + myBuilder.Add ( NW, itNE.Value()); + } + } + if (hasNewE) { + // add new adges + NEL = myAsDes->Descendant( F ); + for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) { + TopTools_ListOfShape SEL; // splits + myImagesEdges.LastImage( itNE.Value(), SEL ); + TopTools_ListIteratorOfListOfShape itSE (SEL); + for ( ; itSE.More(); itSE.Next()) + myBuilder.Add ( NW, itSE.Value()); + } + } + myBuilder.Add( NF, NW ); + myBuilder.Add (C, NF); + + NF.Orientation( F.Orientation() ); // NF is most probably invalid + myImagesFaces.Bind (F, NF); + } + if (isTool) + myImageShape.Bind (S, C); + + return isTool; +} + +//======================================================================= +//function : IsInside +//purpose : Return True if the first vertex of S1 inside S2. +// If S1.IsNull(), check infinite point against S2. +//======================================================================= + +Standard_Boolean Partition_Spliter::IsInside (const TopoDS_Shape& theS1, + const TopoDS_Shape& theS2) +{ + BRepClass3d_SolidClassifier aClassifier( theS2 ); + + TopExp_Explorer expl( theS1, TopAbs_VERTEX ); + if (!expl.More()) + aClassifier.PerformInfinitePoint( ::RealSmall()); + else + { + const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() ); + aClassifier.Perform (BRep_Tool::Pnt( aVertex ), + BRep_Tool::Tolerance( aVertex )); + } + + return ( aClassifier.State() == TopAbs_IN ); +} + +//======================================================================= +//function : GetOriginalShape +//purpose : Return the shape aShape originates from. aShape +// should be a face or more complex result shape +//======================================================================= + +TopoDS_Shape Partition_Spliter::GetOriginalShape(const TopoDS_Shape& theShape) const +{ + TopoDS_Shape anOrigShape; + + TopExp_Explorer expl( theShape, TopAbs_FACE); + if (expl.More()) + { + + TopoDS_Shape aFace = expl.Current(); + if (myImagesFaces.IsImage( aFace )) + aFace = myImagesFaces.Root( aFace ); + anOrigShape = myFaceShapeMap.Find( aFace ); + } + return anOrigShape; +} + +//======================================================================= +//function : FindToolsToReconstruct +//purpose : find and store as objects tools which interfere +// with solids or are inside solids without +// an interference +//======================================================================= + +void Partition_Spliter::FindToolsToReconstruct() +{ + if (myMapTools.IsEmpty()) + return; + + Standard_Integer nbFoundTools = 0; + + // build edge - face map in order to detect interference with section edges + TopTools_IndexedDataMapOfShapeListOfShape EFM; + TopTools_MapIteratorOfMapOfShape aMapIt; + for (aMapIt.Initialize(myMapTools); aMapIt.More(); aMapIt.Next()) + TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); + for (aMapIt.Initialize(myMapFaces); aMapIt.More(); aMapIt.Next()) + TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); + + TopTools_MapOfShape aCurrentSolids, aCheckedShapes; + + // faces cut by new edges + TopTools_MapOfShape & aSectionFaces = myInter3d.TouchedFaces(); + + // keep solids interfering with each other in aCurrentSolids map + // and add tool faces intersecting solids as object shapes + + TopTools_ListIteratorOfListOfShape itS, itF, itCF, itE; + for (itS.Initialize( myListShapes ); itS.More(); itS.Next()) { + TopExp_Explorer expSo (itS.Value(), TopAbs_SOLID); + for (; expSo.More(); expSo.Next()) { + + // check if a solid has been already processed + const TopoDS_Shape & aSo = expSo.Current(); + if (!aCheckedShapes.Add( aSo )) + continue; + aCurrentSolids.Add( aSo ); + + // faces to check + TopTools_ListOfShape aFacesToCheck; + TopExp_Explorer exp( aSo, TopAbs_FACE ); + for ( ; exp.More(); exp.Next()) + aFacesToCheck.Append ( exp.Current()); + + // add other shapes interefering with a solid. + // iterate faces to check while appending new ones + for (itCF.Initialize (aFacesToCheck) ; itCF.More(); itCF.Next()) + { + const TopoDS_Shape& aCheckFace = itCF.Value(); +// if (!aCheckedShapes.Add( aCheckFace )) +// continue; + + // find faces interfering with aCheckFace + TopTools_ListOfShape anIntFaces; + + // ** 1. faces intersecting aCheckFace with creation of new edges on it + if ( myAsDes->HasDescendant( aCheckFace )) + { + // new edges on aCheckFace + const TopTools_ListOfShape& NEL = myAsDes->Descendant( aCheckFace ); + for (itE.Initialize( NEL); itE.More(); itE.Next()) + { + const TopoDS_Shape & aNewEdge = itE.Value(); + if (!aCheckedShapes.Add( aNewEdge )) + continue; + + // faces interfering by aNewEdge + itF.Initialize (myAsDes->Ascendant( aNewEdge )); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + + // ** 2. faces having section edge aNewEdge on aFacesToCheck + if (EFM.Contains( aNewEdge)) + { + itF.Initialize ( EFM.FindFromKey (itE.Value())); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + } + } + } + + // ** 3. faces cut by edges of aCheckFace + TopExp_Explorer expE (aCheckFace, TopAbs_EDGE); + for ( ; expE.More(); expE.Next()) + { + const TopoDS_Shape & aCheckEdge = expE.Current(); + if (aCheckedShapes.Add( aCheckEdge ) && + myInter3d.IsSectionEdge( TopoDS::Edge( aCheckEdge ))) + { + itF.Initialize( myInter3d.SectionEdgeFaces( TopoDS::Edge( aCheckEdge ))); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + } + } + + // process faces interfering with aCheckFace and shapes they + // belong to + for (itF.Initialize (anIntFaces); itF.More(); itF.Next()) + { + const TopoDS_Shape & F = itF.Value(); + if (! aCheckedShapes.Add( F )) + continue; + + Standard_Boolean isTool = myMapTools.Contains( F ); + if (isTool && + myFaceShapeMap( aCheckFace ).ShapeType() == TopAbs_SOLID ) + { + // a tool interfering with a solid + if (aSectionFaces.Contains( F )) + AddShape( F ); + ++ nbFoundTools; + if (nbFoundTools == myMapTools.Extent()) + return; + } + + const TopoDS_Shape & S = myFaceShapeMap( F ); + if (aCheckedShapes.Add( S )) + { + // a new shape interefering with aCurrentSolids is found + if (!isTool && S.ShapeType() == TopAbs_SOLID) + aCurrentSolids.Add ( S ); + // add faces to aFacesToCheck list + for ( exp.Init( S, TopAbs_FACE ); exp.More(); exp.Next()) + aFacesToCheck.Append ( exp.Current() ); + } + } + } // loop on aFacesToCheck + + // Here aCurrentSolids contains all solids interfering with each other. + // aCheckedShapes contains all faces belonging to shapes included + // in or interfering with aCurrentSolids or previously checked solids. + // Test if tool faces that do not interefere with other shapes are + // wrapped by any of aCurrentSolids + + TopTools_MapIteratorOfMapOfShape aSolidIt (aCurrentSolids); + for ( ; aSolidIt.More(); aSolidIt.Next()) + { + const TopoDS_Shape & aSolid = aSolidIt.Key(); + TopTools_MapOfShape aCheckedTools( myMapTools.Extent() ); + + TopTools_MapIteratorOfMapOfShape aToolIt (myMapTools); + for ( ; aToolIt.More(); aToolIt.Next()) + { + const TopoDS_Shape & aToolFace = aToolIt.Key(); + if (aCheckedShapes.Contains( aToolFace ) || // already found + aCheckedTools.Contains( aToolFace )) // checked against aSolid + continue; + + const TopoDS_Shape & aToolShape = myFaceShapeMap( aToolFace ); + TopExp_Explorer aToolFaceIt( aToolShape, TopAbs_FACE ); + + Standard_Boolean isInside = IsInside( aToolShape, aSolid ); + for ( ; aToolFaceIt.More(); aToolFaceIt.Next() ) + { + const TopoDS_Shape & aTool = aToolFaceIt.Current(); + aCheckedTools.Add( aTool ); + if (isInside) + { + if (aSectionFaces.Contains( aTool )) + AddShape( aTool ); + ++ nbFoundTools; + if (nbFoundTools == myMapTools.Extent()) + return; + aCheckedShapes.Add( aTool ); + } + } + } + } + + } // loop on solid shapes + } +} + +#endif diff --git a/libsrc/occ/occconstruction.cpp b/libsrc/occ/occconstruction.cpp new file mode 100644 index 00000000..8da19448 --- /dev/null +++ b/libsrc/occ/occconstruction.cpp @@ -0,0 +1,154 @@ + +#ifdef OCCGEOMETRY + +#include +#include +#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" +#include "Partition_Spliter.hxx" +//#include "VrmlAPI.hxx" +//#include "StlAPI.hxx" + + +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +namespace netgen +{ + + void OCCConstructGeometry (OCCGeometry & geom) + { + cout << "OCC construction" << endl; + + BRep_Builder builder; + BRepPrimAPI_MakeBox mbox(gp_Pnt(-10e5, -15e5, 0), gp_Pnt(20e5, 15e5, 10e5)); + + + /* + TopoDS_Shape air = TopoDS_Solid (mbox); + air = BRepAlgoAPI_Cut (air, geom.somap(1)); + air = BRepAlgoAPI_Cut (air, geom.somap(2)); + air = BRepAlgoAPI_Cut (air, geom.somap(3)); + air = BRepAlgoAPI_Cut (air, geom.somap(4)); + air = BRepAlgoAPI_Cut (air, geom.somap(5)); + air = BRepAlgoAPI_Cut (air, geom.somap(6)); + air = BRepAlgoAPI_Cut (air, geom.somap(7)); + // air = BRepAlgoAPI_Cut (air, geom.somap(8)); + air = BRepAlgoAPI_Cut (air, geom.somap(9)); + // air = BRepAlgoAPI_Cut (air, geom.somap(10)); + */ + + /* + BRepOffsetAPI_MakeOffsetShape dom8plus (geom.somap(8), 1e4, 1e-6); + BRepOffsetAPI_MakeOffsetShape dom6plus (geom.somap(6), 1e4, 1e-6); + dom8plus.Build(); + ShapeFix_Shape fixshape(dom8plus.Shape()); + fixshape.Perform(); + + ShapeFix_Shape fix_dom2(geom.somap(2)); + fix_dom2.Perform(); + + + BRepAlgoAPI_Cut dom2m8(fix_dom2.Shape(), fixshape.Shape()); + ShapeFix_Shape fix_dom2m8 (dom2m8); + fix_dom2m8.Perform(); + + builder.Add (geom.shape, + BRepAlgoAPI_Cut + (BRepAlgoAPI_Cut (geom.somap(2), dom6plus), + dom8plus)); + // builder.Add (geom.shape, fix_dom2m8.Shape()); + // builder.Add (geom.shape, fixshape.Shape()); + */ + + TopoDS_Shape my_fuse; + int cnt = 0; + for (TopExp_Explorer exp_solid(geom.shape, TopAbs_SOLID); exp_solid.More(); exp_solid.Next()) + { + if (cnt == 0) + my_fuse = exp_solid.Current(); + else + { + cout << "fuse, cnt = " << cnt << endl; + if (cnt != 7 && cnt != 9) + my_fuse = BRepAlgoAPI_Fuse (my_fuse, exp_solid.Current()); + } + cnt++; + } + builder.Add (geom.shape, my_fuse); + + /* + ShapeUpgrade_ShellSewing ss; + ss.ApplySewing(geom.shape,1e5); + */ + + /* + BRepAlgo_Sewing sewing(1.e5); + + int cnt = 0; + for (TopExp_Explorer exp_solid(geom.shape, TopAbs_SOLID); exp_solid.More(); exp_solid.Next()) + { + cout << "swe, cnt = " << cnt << endl; + if (cnt != 7 && cnt != 9) + sewing.Add (exp_solid.Current()); + cnt++; + } + + sewing.Perform(); + builder.Add (geom.shape, sewing.SewedShape()); + */ + + + /* + cout << "build air domain" << endl; + TopoDS_Shape air = BRepAlgoAPI_Cut (TopoDS_Solid (mbox), my_fuse); + + cnt = 0; + for (TopExp_Explorer exp_solid(geom.shape, TopAbs_SOLID); exp_solid.More(); exp_solid.Next()) + { + cout << "section, cnt = " << cnt << endl; + if (cnt == 7) + { + builder.Add (geom.shape, + BRepAlgoAPI_Section (air, exp_solid.Current())); + } + cnt++; + } + */ + + + + // builder.Add (geom.shape, air); + for (int i = 1; i <= 10; i++) + builder.Remove (geom.shape, geom.somap(i)); + + + + + geom.BuildFMap(); + geom.BuildVisualizationMesh(); + geom.changed = 1; + } +} + + +#endif diff --git a/libsrc/occ/occgenmesh.cpp b/libsrc/occ/occgenmesh.cpp new file mode 100644 index 00000000..623732d1 --- /dev/null +++ b/libsrc/occ/occgenmesh.cpp @@ -0,0 +1,1540 @@ +#ifdef OCCGEOMETRY + +#include +#include +#include + +#include + + +namespace netgen +{ + +#include "occmeshsurf.hpp" + +#define TCL_OK 0 +#define TCL_ERROR 1 + + extern STLParameters stlparam; + +#define DIVIDEEDGESECTIONS 1000 +#define IGNORECURVELENGTH 1e-4 + + + bool merge_solids = 1; + + inline Point<3> occ2ng (const gp_Pnt & p) + { + return Point<3> (p.X(), p.Y(), p.Z()); + } + + void DivideEdge (TopoDS_Edge & edge, + ARRAY & ps, + ARRAY & params, + Mesh & mesh) + { + double s0, s1; + 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); + + //(*testout) << "mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) " << mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) + // << " pnt.Distance(oldpnt) " << pnt.Distance(oldpnt) << endl; + + + 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) + { + const char * savetask = multithread.task; + multithread.task = "Edge meshing"; + + (*testout) << "edge meshing" << endl; + + int nvertices = geom.vmap.Extent(); + int nedges = geom.emap.Extent(); + + (*testout) << "nvertices = " << nvertices << endl; + (*testout) << "nedges = " << nedges << endl; + + double eps = 1e-6 * geom.GetBoundingBox().Diam(); + + for (int i = 1; i <= nvertices; i++) + { + gp_Pnt pnt = BRep_Tool::Pnt (TopoDS::Vertex(geom.vmap(i))); + MeshPoint mp( Point<3>(pnt.X(), pnt.Y(), pnt.Z()) ); + + bool exists = 0; + if (merge_solids) + for (PointIndex pi = 1; pi <= mesh.GetNP(); pi++) + if ( Dist2 (mesh[pi], Point<3>(mp)) < eps*eps) + { + exists = 1; + break; + } + + if (!exists) + mesh.AddPoint (mp); + } + + (*testout) << "different vertices = " << mesh.GetNP() << endl; + + + int first_ep = mesh.GetNP()+1; + + ARRAY face2solid[2]; + for (int i = 0; i<2; i++) + { + face2solid[i].SetSize (geom.fmap.Extent()); + face2solid[i] = 0; + } + + int solidnr = 0; + for (TopExp_Explorer exp0(geom.shape, TopAbs_SOLID); exp0.More(); exp0.Next()) + { + solidnr++; + for (TopExp_Explorer exp1(exp0.Current(), TopAbs_FACE); exp1.More(); exp1.Next()) + { + TopoDS_Face face = TopoDS::Face(exp1.Current()); + int facenr = geom.fmap.FindIndex(face); + + if (face2solid[0][facenr-1] == 0) + face2solid[0][facenr-1] = solidnr; + else + face2solid[1][facenr-1] = solidnr; + } + } + + + int total = 0; + for (int i3 = 1; i3 <= geom.fmap.Extent(); i3++) + for (TopExp_Explorer exp2(geom.fmap(i3), TopAbs_WIRE); exp2.More(); exp2.Next()) + for (TopExp_Explorer exp3(exp2.Current(), TopAbs_EDGE); exp3.More(); exp3.Next()) + total++; + + + + + int facenr = 0; + int edgenr = 0; + + + (*testout) << "faces = " << geom.fmap.Extent() << endl; + int curr = 0; + + for (int i3 = 1; i3 <= geom.fmap.Extent(); i3++) + { + TopoDS_Face face = TopoDS::Face(geom.fmap(i3)); + facenr = geom.fmap.FindIndex (face); // sollte doch immer == i3 sein ??? JS + + int solidnr0 = face2solid[0][i3-1]; + int solidnr1 = face2solid[1][i3-1]; + + /* auskommentiert am 3.3.05 von robert + for (exp2.Init (geom.somap(solidnr0), TopAbs_FACE); exp2.More(); exp2.Next()) + { + TopoDS_Face face2 = TopoDS::Face(exp2.Current()); + if (geom.fmap.FindIndex(face2) == facenr) + { + // if (face.Orientation() != face2.Orientation()) swap (solidnr0, solidnr1); + } + } + */ + + mesh.AddFaceDescriptor (FaceDescriptor(facenr, solidnr0, solidnr1, 0)); + // ACHTUNG! STIMMT NICHT ALLGEMEIN (RG) + + + Handle(Geom_Surface) occface = BRep_Tool::Surface(face); + + for (TopExp_Explorer exp2 (face, TopAbs_WIRE); exp2.More(); exp2.Next()) + { + TopoDS_Shape wire = exp2.Current(); + + for (TopExp_Explorer exp3 (wire, TopAbs_EDGE); exp3.More(); exp3.Next()) + { + curr++; + (*testout) << "edge nr " << curr << endl; + + multithread.percent = 100 * curr / double (total); + if (multithread.terminate) return; + + TopoDS_Edge edge = TopoDS::Edge (exp3.Current()); + if (BRep_Tool::Degenerated(edge)) + { + //(*testout) << "ignoring degenerated edge" << endl; + continue; + } + + if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) == + geom.vmap.FindIndex(TopExp::LastVertex (edge))) + { + GProp_GProps system; + BRepGProp::LinearProperties(edge, system); + + if (system.Mass() < eps) + { + cout << "ignoring edge " << geom.emap.FindIndex (edge) + << ". closed edge with length < " << eps << endl; + continue; + } + } + + + Handle(Geom2d_Curve) cof; + double s0, s1; + cof = BRep_Tool::CurveOnSurface (edge, face, s0, s1); + + int geomedgenr = geom.emap.FindIndex(edge); + + ARRAY mp; + ARRAY params; + + DivideEdge (edge, mp, params, mesh); + + + ARRAY pnums; + pnums.SetSize (mp.Size()+2); + + if (!merge_solids) + { + pnums[0] = geom.vmap.FindIndex (TopExp::FirstVertex (edge)); + pnums[pnums.Size()-1] = geom.vmap.FindIndex (TopExp::LastVertex (edge)); + } + else + { + Point<3> fp = occ2ng (BRep_Tool::Pnt (TopExp::FirstVertex (edge))); + Point<3> lp = occ2ng (BRep_Tool::Pnt (TopExp::LastVertex (edge))); + + pnums[0] = -1; + pnums.Last() = -1; + for (PointIndex pi = 1; pi < first_ep; pi++) + { + if (Dist2 (mesh[pi], fp) < eps*eps) pnums[0] = pi; + if (Dist2 (mesh[pi], lp) < eps*eps) pnums.Last() = pi; + } + } + + + for (int i = 1; i <= mp.Size(); i++) + { + bool exists = 0; + int j; + for (j = first_ep; j <= mesh.GetNP(); j++) + if ((mesh.Point(j)-Point<3>(mp[i-1])).Length() < eps) + { + exists = 1; + break; + } + + if (exists) + pnums[i] = j; + else + { + mesh.AddPoint (mp[i-1]); + (*testout) << "add meshpoint " << mp[i-1] << endl; + pnums[i] = mesh.GetNP(); + } + } + (*testout) << "NP = " << mesh.GetNP() << endl; + + //(*testout) << pnums[pnums.Size()-1] << endl; + + for (int 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); + + //edgesegments[geomedgenr-1]->Append(mesh.GetNSeg()); + + } + } + } + } + + // for(i=1; i<=mesh.GetNSeg(); i++) + // (*testout) << "edge " << mesh.LineSegment(i).edgenr << " face " << mesh.LineSegment(i).si + // << " p1 " << mesh.LineSegment(i).p1 << " p2 " << mesh.LineSegment(i).p2 << endl; + // exit(10); + + mesh.CalcSurfacesOfNode(); + multithread.task = savetask; + } + + + + + static void OCCMeshSurface (OCCGeometry & geom, Mesh & mesh, int perfstepsend) + { + int i, j, k; + int changed; + + const char * savetask = multithread.task; + multithread.task = "Surface meshing"; + + geom.facemeshstatus = 0; + + int noldp = mesh.GetNP(); + + double starttime = GetTime(); + + ARRAY glob2loc(noldp); + + //int projecttype = PARAMETERSPACE; + + int projecttype = PARAMETERSPACE; + + int notrys = 1; + + int surfmesherror = 0; + + for (k = 1; k <= mesh.GetNFD(); k++) + { + if(1==0 && !geom.fvispar[k-1].IsDrawable()) + { + (*testout) << "ignoring face " << k << endl; + cout << "ignoring face " << k << endl; + continue; + } + + (*testout) << "mesh face " << k << endl; + multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); + geom.facemeshstatus[k-1] = -1; + + + /* + if (k != 42) + { + cout << "skipped" << endl; + continue; + } + */ + + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + + int oldnf = mesh.GetNSE(); + + Box<3> bb = geom.GetBoundingBox(); + + // int projecttype = PLANESPACE; + + 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(); + + GProp_GProps sprops; + BRepGProp::SurfaceProperties(TopoDS::Face(geom.fmap(k)),sprops); + meshing.SetMaxArea(2.*sprops.Mass()); + + 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); + + } + + ofstream problemfile("occmesh.rep"); + + problemfile << "SURFACEMESHING" << endl << endl; + + if (surfmesherror) + { + cout << "WARNING! NOT ALL FACES HAVE 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; + problemfile << "problem with face " << i << endl; + problemfile << "vertices: " << endl; + TopExp_Explorer exp0,exp1,exp2; + for ( exp0.Init(TopoDS::Face (geom.fmap(i)), TopAbs_WIRE); exp0.More(); exp0.Next() ) + { + TopoDS_Wire wire = TopoDS::Wire(exp0.Current()); + for ( exp1.Init(wire,TopAbs_EDGE); exp1.More(); exp1.Next() ) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + for ( exp2.Init(edge,TopAbs_VERTEX); exp2.More(); exp2.Next() ) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp2.Current()); + gp_Pnt point = BRep_Tool::Pnt(vertex); + problemfile << point.X() << " " << point.Y() << " " << point.Z() << endl; + } + } + } + problemfile << endl; + + } + cout << endl << endl; + cout << "for more information open IGES/STEP Topology Explorer" << endl; + problemfile.close(); + throw NgException ("Problem in Surface mesh generation"); + } + else + { + problemfile << "OK" << endl << endl; + problemfile.close(); + } + + + + + if (multithread.terminate || perfstepsend < MESHCONST_OPTSURFACE) + return; + + multithread.task = "Optimizing surface"; + + static int timer_opt2d = NgProfiler::CreateTimer ("Optimization 2D"); + NgProfiler::StartTimer (timer_opt2d); + + for (k = 1; k <= mesh.GetNFD(); k++) + { + // if (k != 42) continue; + // if (k != 36) continue; + + // (*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++) + { + // (*testout) << "optstep " << i << endl; + if (multithread.terminate) return; + + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (0.2); + meshopt.SetWriteStatus (0); + + // (*testout) << "EdgeSwapping (mesh, (i > mparam.optsteps2d/2))" << endl; + 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); + + // (*testout) << "ImproveMesh (mesh)" << endl; + meshopt.ImproveMesh (mesh); + } + + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (0.2); + meshopt.SetWriteStatus (0); + + // (*testout) << "CombineImprove (mesh)" << endl; + meshopt.CombineImprove (mesh); + } + + if (multithread.terminate) return; + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (0.2); + meshopt.SetWriteStatus (0); + + // (*testout) << "ImproveMesh (mesh)" << endl; + meshopt.ImproveMesh (mesh); + } + } + + } + + + mesh.CalcSurfacesOfNode(); + mesh.Compress(); + + NgProfiler::StopTimer (timer_opt2d); + + 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, const 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) + { + double curvature = 0; + + prop->SetParameters (parmid.X(), parmid.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature())); + + prop->SetParameters (par0.X(), par0.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + prop->SetParameters (par1.X(), par1.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + prop->SetParameters (par2.X(), par2.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + //(*testout) << "curvature " << curvature << endl; + + if (curvature < 1e-3) + { + //(*testout) << "curvature too small (" << curvature << ")!" << endl; + return; + // return war bis 10.2.05 auskommentiert + } + + + + h = ComputeH (curvature+1e-10); + + if(h < 1e-4*maxside) + return; + + + if (h > 30) return; + } + + if (h < maxside) // && depth < 5) + { + //cout << "\r h " << h << flush; + gp_Pnt2d pm0; + gp_Pnt2d pm1; + gp_Pnt2d pm2; + + //cout << "h " << h << " maxside " << maxside << " depth " << depth << endl; + //cout << "par0 " << par0.X() << " " << par0.Y() + //<< " par1 " << par1.X() << " " << par1.Y() + // << " par2 " << par2.X() << " " << par2.Y()<< endl; + + + 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, 0.5*maxside, depth+1, h); + RestrictHTriangle (par0, pm1, pm2, prop, mesh, 0.5*maxside, depth+1, h); + RestrictHTriangle (par1, pm0, pm2, prop, mesh, 0.5*maxside, depth+1, h); + RestrictHTriangle (par2, pm1, pm0, prop, mesh, 0.5*maxside, depth+1, h); + } + else + { + gp_Pnt pnt; + Point3d p3d; + + prop->SetParameters (parmid.X(), parmid.Y()); + pnt = prop->Value(); + p3d = Point3d(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); + + } + } + */ + + + void RestrictHTriangle (gp_Pnt2d & par0, gp_Pnt2d & par1, gp_Pnt2d & par2, + BRepLProp_SLProps * prop, Mesh & mesh, int depth, double h = 0) + { + int ls = -1; + + gp_Pnt pnt0,pnt1,pnt2; + + prop->SetParameters (par0.X(), par0.Y()); + pnt0 = prop->Value(); + + prop->SetParameters (par1.X(), par1.Y()); + pnt1 = prop->Value(); + + prop->SetParameters (par2.X(), par2.Y()); + pnt2 = prop->Value(); + + double aux; + double maxside = pnt0.Distance(pnt1); + ls = 2; + aux = pnt1.Distance(pnt2); + if(aux > maxside) + { + maxside = aux; + ls = 0; + } + aux = pnt2.Distance(pnt0); + if(aux > maxside) + { + maxside = aux; + ls = 1; + } + + + + 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%3 == 0) + { + double curvature = 0; + + prop->SetParameters (parmid.X(), parmid.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature())); + + prop->SetParameters (par0.X(), par0.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + prop->SetParameters (par1.X(), par1.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + prop->SetParameters (par2.X(), par2.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + //(*testout) << "curvature " << curvature << endl; + + if (curvature < 1e-3) + { + //(*testout) << "curvature too small (" << curvature << ")!" << endl; + return; + // return war bis 10.2.05 auskommentiert + } + + + + h = ComputeH (curvature+1e-10); + + if(h < 1e-4*maxside) + return; + + + if (h > 30) return; + } + + if (h < maxside && depth < 10) + { + //cout << "\r h " << h << flush; + gp_Pnt2d pm; + + //cout << "h " << h << " maxside " << maxside << " depth " << depth << endl; + //cout << "par0 " << par0.X() << " " << par0.Y() + //<< " par1 " << par1.X() << " " << par1.Y() + // << " par2 " << par2.X() << " " << par2.Y()<< endl; + + if(ls == 0) + { + pm.SetX(0.5*(par1.X()+par2.X())); pm.SetY(0.5*(par1.Y()+par2.Y())); + RestrictHTriangle(pm, par2, par0, prop, mesh, depth+1, h); + RestrictHTriangle(pm, par0, par1, prop, mesh, depth+1, h); + } + else if(ls == 1) + { + pm.SetX(0.5*(par0.X()+par2.X())); pm.SetY(0.5*(par0.Y()+par2.Y())); + RestrictHTriangle(pm, par1, par2, prop, mesh, depth+1, h); + RestrictHTriangle(pm, par0, par1, prop, mesh, depth+1, h); + } + else if(ls == 2) + { + pm.SetX(0.5*(par0.X()+par1.X())); pm.SetY(0.5*(par0.Y()+par1.Y())); + RestrictHTriangle(pm, par1, par2, prop, mesh, depth+1, h); + RestrictHTriangle(pm, par2, par0, prop, mesh, depth+1, h); + } + + } + else + { + gp_Pnt pnt; + Point3d p3d; + + prop->SetParameters (parmid.X(), parmid.Y()); + pnt = prop->Value(); + p3d = Point3d(pnt.X(), pnt.Y(), pnt.Z()); + mesh.RestrictLocalH (p3d, h); + + p3d = Point3d(pnt0.X(), pnt0.Y(), pnt0.Z()); + mesh.RestrictLocalH (p3d, h); + + p3d = Point3d(pnt1.X(), pnt1.Y(), pnt1.Z()); + mesh.RestrictLocalH (p3d, h); + + p3d = Point3d(pnt2.X(), pnt2.Y(), pnt2.Z()); + mesh.RestrictLocalH (p3d, h); + + //(*testout) << "p = " << p3d << ", h = " << h << ", maxside = " << maxside << 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->geomtype = Mesh::GEOM_OCC; + mesh->SetGlobalH (mparam.maxh); + mesh->SetMinimalH (mparam.minh); + + ARRAY 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) + { + + const char * savetask = multithread.task; + multithread.percent = 0; + + mesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); + + int nedges = geom.emap.Extent(); + + double maxedgelen = 0; + double minedgelen = 1e99; + + + multithread.task = "Setting local mesh size (elements per edge)"; + + // setting elements per edge + + for (int 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 maxj = 2 * (int) ceil (localh/len); + for (int j = 0; j <= maxj; 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 = 20; + + for (int i = 1; i <= nedges && !multithread.terminate; i++) + { + double maxcur = 0; + 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); + + for (int j = 1; j <= nsections; j++) + { + double s = s0 + j/(double) nsections * (s1-s0); + prop.SetParameter (s); + double curvature = prop.Curvature(); + if(curvature > maxcur) maxcur = curvature; + + if (curvature >= 1e99) + continue; + + + gp_Pnt pnt = c->Value (s); + + mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), + ComputeH (fabs(curvature))); + } + // (*testout) << "edge " << i << " max. curvature: " << maxcur << endl; + } + + + + multithread.task = "Setting local mesh size (face curvature)"; + + // setting face curvature + + int nfaces = geom.fmap.Extent(); + + for (int 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 (int j = 1; j <= ntriangles; j++) + { + gp_Pnt p[3]; + gp_Pnt2d par[3]; + + for (int 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])); + //cout << "\rFace " << i << " pos11 ntriangles " << ntriangles << " maxside " << maxside << flush; + + RestrictHTriangle (par[0], par[1], par[2], &prop, *mesh, 0); + //cout << "\rFace " << i << " pos12 ntriangles " << ntriangles << flush; + } + } + + + // setting close edges + + if (stlparam.resthcloseedgeenable) + { + multithread.task = "Setting local mesh size (close edges)"; + + int sections = 100; + + ARRAY 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 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; + (*testout) << "somewhere near " << line.p0 << " - " << line.p1 << 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 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); + + ofstream problemfile("occmesh.rep",ios_base::app); + + problemfile << "VOLUMEMESHING" << endl << endl; + if(res != MESHING3_OK) + problemfile << "ERROR" << endl << endl; + else + problemfile << "OK" << endl + << mesh->GetNE() << " elements" << endl << endl; + + problemfile.close(); + + 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 (int i = 1; i <= mesh->GetNP(); i++) + (*testout) << mesh->Point(i) << endl; + + (*testout) << endl << "NSegments: " << mesh->GetNSeg() << endl; + for (int i = 1; i <= mesh->GetNSeg(); i++) + (*testout) << mesh->LineSegment(i) << endl; + + + + return TCL_OK; + } +} + +#endif diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp new file mode 100644 index 00000000..44dd47b6 --- /dev/null +++ b/libsrc/occ/occgeom.cpp @@ -0,0 +1,1536 @@ + +#ifdef OCCGEOMETRY + +#include +#include +#include "ShapeAnalysis_ShapeTolerance.hxx" +#include "ShapeAnalysis_ShapeContents.hxx" +#include "ShapeAnalysis_CheckSmallFace.hxx" +#include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx" +#include "ShapeAnalysis_Surface.hxx" +#include "BRepAlgoAPI_Fuse.hxx" +#include "BRepCheck_Analyzer.hxx" +#include "BRepLib.hxx" +#include "ShapeBuild_ReShape.hxx" +#include "ShapeFix.hxx" +#include "ShapeFix_FixSmallFace.hxx" +#include "Partition_Spliter.hxx" +//#include "VrmlAPI.hxx" +//#include "StlAPI.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 exp0; + TopExp_Explorer exp1; + + + for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++; + for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++; + + double surfacecont = 0; + + + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + BuildFMap(); + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + GProp_GProps system; + BRepGProp::SurfaceProperties(face, system); + surfacecont += system.Mass(); + } + + + cout << "Starting geometry healing procedure (tolerance: " << tolerance << ")" << endl + << "-----------------------------------" << endl; + + { + cout << endl << "- repairing faces" << endl; + + Handle(ShapeFix_Face) sff; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face (exp0.Current()); + + sff = new ShapeFix_Face (face); + sff->FixAddNaturalBoundMode() = Standard_True; + sff->FixSmallAreaWireMode() = Standard_True; + sff->Perform(); + + if(sff->Status(ShapeExtend_DONE1) || + sff->Status(ShapeExtend_DONE2) || + sff->Status(ShapeExtend_DONE3) || + sff->Status(ShapeExtend_DONE4) || + sff->Status(ShapeExtend_DONE5)) + { + cout << "repaired face " << fmap.FindIndex(face) << " "; + if(sff->Status(ShapeExtend_DONE1)) + cout << "(some wires are fixed)" <Status(ShapeExtend_DONE2)) + cout << "(orientation of wires fixed)" <Status(ShapeExtend_DONE3)) + cout << "(missing seam added)" <Status(ShapeExtend_DONE4)) + cout << "(small area wire removed)" <Status(ShapeExtend_DONE5)) + cout << "(natural bounds added)" <Face(); + + rebuild->Replace(face, newface, Standard_False); + } + + //delete sff; sff = NULL; + } + shape = rebuild->Apply(shape); + + //delete rebuild; rebuild = NULL; + } + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + + if (fixsmalledges) + { + cout << endl << "- fixing small edges" << endl; + + Handle(ShapeFix_Wire) sfw; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + for (exp1.Init (face, TopAbs_WIRE); exp1.More(); exp1.Next()) + { + TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current()); + sfw = new ShapeFix_Wire (oldwire, face ,tolerance); + sfw->ModifyTopologyMode() = Standard_True; + + sfw->ClosedWireMode() = Standard_True; + + bool replace = false; + + replace = sfw->FixReorder() || replace; + + replace = sfw->FixConnected() || replace; + + + + if (sfw->FixSmall (Standard_False, tolerance) && ! (sfw->StatusSmall(ShapeExtend_FAIL1) || + sfw->StatusSmall(ShapeExtend_FAIL2) || + sfw->StatusSmall(ShapeExtend_FAIL3))) + { + cout << "Fixed small edge in wire " << wmap.FindIndex (oldwire) << endl; + replace = true; + + } + else if (sfw->StatusSmall(ShapeExtend_FAIL1)) + cerr << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) + << ", edge cannot be checked (no 3d curve and no pcurve)" << endl; + else if (sfw->StatusSmall(ShapeExtend_FAIL2)) + cerr << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) + << ", edge is null-length and has different vertives at begin and end, and lockvtx is True or ModifiyTopologyMode is False" << endl; + else if (sfw->StatusSmall(ShapeExtend_FAIL3)) + cerr << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) + << ", CheckConnected has failed" << endl; + + replace = sfw->FixEdgeCurves() || replace; + + replace = sfw->FixDegenerated() || replace; + + replace = sfw->FixSelfIntersection() || replace; + + replace = sfw->FixLacking(Standard_True) || replace; + + if(replace) + { + TopoDS_Wire newwire = sfw->Wire(); + rebuild->Replace(oldwire, newwire, Standard_False); + } + + //delete sfw; sfw = NULL; + + } + } + + shape = rebuild->Apply(shape); + + + + { + BuildFMap(); + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + + 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) + << " from vertex " << vmap.FindIndex(TopExp::FirstVertex (edge)) + << " to vertex " << vmap.FindIndex(TopExp::LastVertex (edge)) << endl; + rebuild->Remove(edge, false); + } + } + } + shape = rebuild->Apply(shape); + + //delete rebuild; rebuild = NULL; + } + + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + + + + Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe; + sfwf->SetPrecision(tolerance); + sfwf->Load (shape); + sfwf->ModeDropSmallEdges() = Standard_True; + + sfwf->SetPrecision(boundingbox.Diam()); + + 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; + } + + sfwf->SetPrecision(tolerance); + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 4" << endl; + } + } + + + + 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; + } + + + + shape = sfwf->Shape(); + + //delete sfwf; sfwf = NULL; + //delete rebuild; rebuild = NULL; + + } + + + + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 5" << endl; + } + } + + + + + 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(); + //delete sffsm; sffsm = NULL; + } + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 6" << endl; + } + } + + + + if (sewfaces) + { + cout << endl << "- sewing faces" << endl; + + 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"; + } + + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + + if (makesolids) + { + cout << endl << "- making solids" << endl; + + 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; + } + + //delete sfs; sfs = NULL; + } + else + cout << " not possible" << endl; + } + } + + + + if (splitpartitions) + { + cout << "- running SALOME partition splitter" << endl; + + TopExp_Explorer e2; + Partition_Spliter ps; + int count = 0; + + for (e2.Init (shape, TopAbs_SOLID); + e2.More(); e2.Next()) + { + count++; + ps.AddShape (e2.Current()); + } + + ps.Compute(); + shape = ps.Shape(); + + cout << " before: " << count << " solids" << endl; + + count = 0; + for (e2.Init (shape, TopAbs_SOLID); + e2.More(); e2.Next()) count++; + + cout << " after : " << count << " solids" << endl; + } + + BuildFMap(); + + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 8" << endl; + } + } + + + double newsurfacecont = 0; + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face(exp0.Current()); + GProp_GProps system; + BRepGProp::SurfaceProperties(face, 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 (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nnrc++; + for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.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; + +// cout << "Write: " << flush; +// char answer; +// cin >> answer; +// if(answer == 'y') +// { +// cout << "Writing VRML" << endl; +// VrmlAPI::Write(shape,"test2.vrml"); +// cout << "Writing STL" << endl; +// StlAPI::Write(shape,"test2.stl"); +// } + + } + + + + + 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_COMPOUND); + exp0.More(); exp0.Next()) + { + TopoDS_Compound compound = TopoDS::Compound (exp0.Current()); + (*testout) << "compound" << endl; + int i = 0; + for (exp1.Init(compound, TopAbs_SHELL); + exp1.More(); exp1.Next()) + { + (*testout) << "shell " << ++i << endl; + } + } + + for (exp0.Init(shape, TopAbs_SOLID); + exp0.More(); exp0.Next()) + { + TopoDS_Solid solid = TopoDS::Solid (exp0.Current()); + + if (somap.FindIndex(solid) < 1) + { + somap.Add (solid); + + for (exp1.Init(solid, TopAbs_SHELL); + exp1.More(); exp1.Next()) + { + // TopoDS_Shell shell = TopoDS::Shell (exp1.Current().Composed (exp0.Current().Orientation())); + TopoDS_Shell shell = TopoDS::Shell (exp1.Current()); + 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())); + TopoDS_Face face = TopoDS::Face(exp2.Current()); + if (fmap.FindIndex(face) < 1) + { + fmap.Add (face); + (*testout) << "face " << fmap.FindIndex(face) << " "; + (*testout) << ((face.Orientation() == TopAbs_REVERSED) ? "-" : "+") << ", "; + (*testout) << ((exp2.Current().Orientation() == TopAbs_REVERSED) ? "-" : "+") << endl; + for (exp3.Init(exp2.Current(), TopAbs_WIRE); + exp3.More(); exp3.Next()) + { + // TopoDS_Wire wire = TopoDS::Wire (exp3.Current().Composed(face.Orientation())); + 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().Composed(wire.Orientation())); + 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 Shells + for (exp1.Init(shape, TopAbs_SHELL, TopAbs_SOLID); + // for (exp1.Init(exp0.Current(), TopAbs_SHELL, TopAbs_SOLID); + exp1.More(); exp1.Next()) + { + // TopoDS_Shape shell = exp1.Current().Composed (exp0.Current().Orientation()); + TopoDS_Shell shell = TopoDS::Shell(exp1.Current()); + if (shmap.FindIndex(shell) < 1) + { + shmap.Add (shell); + + (*testout) << "shell " << shmap.FindIndex(shell) << " "; + (*testout) << ((shell.Orientation() == TopAbs_REVERSED) ? "-" : "+") << ", "; + (*testout) << ((exp1.Current().Orientation() == TopAbs_REVERSED) ? "-" : "+") << endl; + + for (exp2.Init(shell, TopAbs_FACE); + exp2.More(); exp2.Next()) + { + TopoDS_Face face = TopoDS::Face(exp2.Current()); + // TopoDS_Face face = TopoDS::Face(exp2.Current().Composed(shell.Orientation())); + if (fmap.FindIndex(face) < 1) + { + fmap.Add (face); + + for (exp3.Init(face, TopAbs_WIRE); + exp3.More(); exp3.Next()) + { + // TopoDS_Wire wire = TopoDS::Wire (exp3.Current().Composed(face.Orientation())); + TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); + if (wmap.FindIndex(wire) < 1) + { + wmap.Add (wire); + + for (exp4.Init(wire, TopAbs_EDGE); + exp4.More(); exp4.Next()) + { + // TopoDS_Edge edge = TopoDS::Edge(exp4.Current().Composed(wire.Orientation())); + TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); + if (emap.FindIndex(edge) < 1) + { + emap.Add (edge); + for (exp5.Init(edge, TopAbs_VERTEX); + exp5.More(); exp5.Next()) + { + // TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current().Composed(edge.Orientation())); + 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().Composed(shape.Orientation())); + 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().Composed(face.Orientation())); + 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().Composed(wire.Orientation())); + 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().Composed(edge.Orientation())); + 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()); + + fsingular.SetSize (fmap.Extent()); + esingular.SetSize (emap.Extent()); + vsingular.SetSize (vmap.Extent()); + + fsingular = esingular = vsingular = false; + } + + + + 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; + } + + //delete sfs; sfs = NULL; + + cout << " done" << endl; + } + else + cout << " not possible" << endl; + } + + + void OCCGeometry :: BuildVisualizationMesh () + { + + cout << "Preparing visualization (deflection = " << vispar.occdeflection << ") ... " << flush; + + + BRepTools::Clean (shape); + //WriteOCC_STL("test.stl"); + 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(); + + + } + + + void OCCGeometry :: 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)); + + //(*testout) << "before " << pnt.X() << " "<< pnt.Y() << " "<< pnt.Z() << " " << endl; + + + /* + GeomAPI_ProjectPointOnSurf proj(pnt, BRep_Tool::Surface(TopoDS::Face(fmap(surfi)))); + if (proj.NbPoints() == 0) + { + cout << "Projection fails" << endl; + } + else + { + pnt = proj.NearestPoint(); + //(*testout) << "after " << pnt.X() << " "<< pnt.Y() << " "<< pnt.Z() << " " << endl; + + p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + } + */ + + + double u,v; + Handle( Geom_Surface ) thesurf = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( thesurf ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(fmap(surfi)) ) ); + suval.Coord( u, v); + pnt = thesurf->Value( u, v ); + + + p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + + } + + + 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; + } + + + void OCCGeometry :: WriteOCC_STL(char * filename) + { + cout << "writing stl..."; cout.flush(); + StlAPI_Writer writer; + writer.RelativeMode() = Standard_False; + + writer.SetDeflection(0.02); + writer.Write(shape,filename); + + cout << "done" << endl; + } + + + 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 + //reader.PrintTransferInfo(IFSelect_FailAndWarn,IFSelect_ListByItem); + + occgeo->shape = reader.OneShape(); + occgeo->changed = 1; + occgeo->BuildFMap(); + + // + // Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + // sfs->Init(occgeo->shape); + // sfs->Perform(); + // Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(occgeo->shape); + // //sfwf->DropSmallEdgesMode() = Standard_True; + // sfwf->FixSmallEdges(); + // sfwf->FixWireGaps(); + + // + + + 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(); + // + //Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + //sfs->Init(occgeo->shape); + //sfs->Perform(); + //Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(occgeo->shape); + //sfwf->FixSmallEdges(); + //sfwf->FixWireGaps(); + + + + /* + // JS + TopoDS_Compound aRes; + BRep_Builder aBuilder; + aBuilder.MakeCompound (aRes); + + for (TopExp_Explorer exp(occgeo->shape, TopAbs_SOLID); exp.More(); exp.Next()) + { + aBuilder.Add (aRes, exp.Current()); + cout << "solid" << endl; + } + + for (TopExp_Explorer exp(aRes, TopAbs_SOLID); exp.More(); exp.Next()) + { + cout << "compound has shapes solid" << endl; + } + occgeo->shape = aRes; + occgeo->changed = 1; + occgeo->BuildFMap(); + */ + + + // + occgeo->BuildVisualizationMesh(); + PrintContents (occgeo); + + return occgeo; + } + + OCCGeometry * LoadOCC_BREP (const char * filename) + { + OCCGeometry * occgeo; + occgeo = new OCCGeometry; + + BRep_Builder aBuilder; + Standard_Boolean result = BRepTools::Read(occgeo->shape, const_cast (filename),aBuilder); + + +// cout << "Writing VRML" << endl; +// VrmlAPI::Write(occgeo->shape,"test.vrml"); +// cout << "Writing STL" << endl; +// StlAPI::Write(occgeo->shape,"test.stl"); + + + 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 edgeLengths; + ARRAY 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/libsrc/occ/occmeshsurf.cpp b/libsrc/occ/occmeshsurf.cpp new file mode 100644 index 00000000..ccde30bf --- /dev/null +++ b/libsrc/occ/occmeshsurf.cpp @@ -0,0 +1,735 @@ +#ifdef OCCGEOMETRY + +#include + +#include +#include +#include +#include + + +namespace netgen +{ +#include "occmeshsurf.hpp" + + + bool glob_testout(false); + + 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(); + */ + + + + GeomLProp_SLProps lprop(occface,geominfo.u,geominfo.v,1,1e-5); + double setu=geominfo.u,setv=geominfo.v; + + if(lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5) + { + double ustep = 0.01*(umax-umin); + double vstep = 0.01*(vmax-vmin); + + n=0; + + while(setu < umax && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setu += ustep; + if(setu < umax) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setu = geominfo.u; + while(setu > umin && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setu -= ustep; + if(setu > umin) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setu = geominfo.u; + + while(setv < vmax && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setv += ustep; + if(setv < vmax) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setv = geominfo.v; + while(setv > vmin && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setv -= ustep; + if(setv > vmin) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setv = geominfo.v; + + n.Normalize(); + } + else + { + n(0)=lprop.Normal().X(); + n(1)=lprop.Normal().Y(); + n(2)=lprop.Normal().Z(); + } + + if(glob_testout) + { + (*testout) << "u " << geominfo.u << " v " << geominfo.v + << " du " << lprop.D1U().X() << " "<< lprop.D1U().Y() << " "<< lprop.D1U().Z() + << " dv " << lprop.D1V().X() << " "<< lprop.D1V().Y() << " "<< lprop.D1V().Z() << endl; + } + + + + 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; + //cout << "ex " << ex << " ey " << ey << " ez " << ez << endl; + } + 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; + + /* + if(zone == -1) + { + (*testout) << "zone = -1 for " << p3d << " 2D: " << pplane << " n " << n << " nmid " << nmid << endl; + glob_testout = true; + GetNormalVector (p3d, geominfo, n); + glob_testout = false; + } + */ + } + 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)); + + //(*testout) << "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); + */ + + double u,v; + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( topods_face ) ); + suval.Coord( u, v); + pnt = occface->Value( u, v ); + + //(*testout) << "pnt(proj) = " << pnt.X() << ", " << pnt.Y() << ", " << pnt.Z() << endl; + gi.u = u; + gi.v = 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(Box<3>(abb.PMin(), abb.PMax())), surface(TopoDS::Face(asurf), aprojecttype) + { + ; + } + + + void Meshing2OCCSurfaces :: DefineTransformation (const Point3d & p1, const 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, Point<3> & p) const + { + geometry.Project (surfind, p); + } + + + int MeshOptimize2dOCCSurfaces :: ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const + { + double u = gi.u; + double v = gi.v; + + Point<3> hp = p; + if (geometry.FastProject (surfind, hp, u, v)) + { + p = hp; + return 1; + } + ProjectPoint (surfind, p); + return CalcPointGeomInfo (surfind, gi, p); + } + + + void MeshOptimize2dOCCSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, + Point<3> & 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(0), p(1), p(2)); + GeomAPI_ProjectPointOnCurve proj(pnt, c); + pnt = proj.NearestPoint(); + p(0) = pnt.X(); + p(1) = pnt.Y(); + p(2) = pnt.Z(); + + } + + void MeshOptimize2dOCCSurfaces :: + GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & geominfo, Vec<3> & 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 Point<3> & p, Vec<3> & n) const + { + // static int cnt = 0; + // if (cnt++ % 1000 == 0) cout << "GetNV cnt = " << cnt << endl; + Standard_Real u,v; + + gp_Pnt pnt(p(0), p(1), p(2)); + + 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); + */ + + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(geometry.fmap(surfind)) ) ); + suval.Coord( u, v); + pnt = occface->Value( 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 Point<3> & p) const + { + Standard_Real u,v; + + gp_Pnt pnt(p(0), p(1), p(2)); + + 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); + */ + + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(geometry.fmap(surfind)) ) ); + suval.Coord( u, v); + //pnt = occface->Value( 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 Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & 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; + newgi.u = u; + newgi.v = v; + } + + newp = hnewp; + } + + + void OCCRefinementSurfaces :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & 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/libsrc/opti/Makefile.am b/libsrc/opti/Makefile.am new file mode 100644 index 00000000..7a2ace30 --- /dev/null +++ b/libsrc/opti/Makefile.am @@ -0,0 +1,4 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libopti.a +libopti_a_SOURCES = bfgs.cpp linopt.cpp linsearch.cpp diff --git a/libsrc/opti/Makefile.in b/libsrc/opti/Makefile.in new file mode 100644 index 00000000..dc65f0b3 --- /dev/null +++ b/libsrc/opti/Makefile.in @@ -0,0 +1,442 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/opti +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libopti_a_AR = $(AR) $(ARFLAGS) +libopti_a_LIBADD = +am_libopti_a_OBJECTS = bfgs.$(OBJEXT) linopt.$(OBJEXT) \ + linsearch.$(OBJEXT) +libopti_a_OBJECTS = $(am_libopti_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libopti_a_SOURCES) +DIST_SOURCES = $(libopti_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libopti.a +libopti_a_SOURCES = bfgs.cpp linopt.cpp linsearch.cpp +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/opti/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/opti/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libopti.a: $(libopti_a_OBJECTS) $(libopti_a_DEPENDENCIES) + -rm -f libopti.a + $(libopti_a_AR) libopti.a $(libopti_a_OBJECTS) $(libopti_a_LIBADD) + $(RANLIB) libopti.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bfgs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linsearch.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/opti/bfgs.cpp b/libsrc/opti/bfgs.cpp new file mode 100644 index 00000000..d106b6f1 --- /dev/null +++ b/libsrc/opti/bfgs.cpp @@ -0,0 +1,410 @@ +/***************************************************************************/ +/* */ +/* Vorlesung Optimierung I, Gfrerer, WS94/95 */ +/* BFGS-Verfahren zur Lösung freier nichtlinearer Optimierungsprobleme */ +/* */ +/* Programmautor: Joachim Schöberl */ +/* Matrikelnummer: 9155284 */ +/* */ +/***************************************************************************/ + +#include +#include + +#include +#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); + } + */ + + + + double val; + + int n = l.Height(); + p = g; + + for (int i = 0; i < n; i++) + { + val = 0; + for (int j = i; j < n; j++) + val += p(j) * l(j, i); + p(i) = val; + } + + for (int i = 0; i < n; i++) + p(i) *= d(i); + + for (int i = n-1; i >= 0; i--) + { + val = 0; + for (int j = 0; j <= i; j++) + val += p(j) * l(i, j); + p(i) = val; + } +} + +void SolveLDLt (const DenseMatrix & l, const Vector & d, const Vector & g, Vector & p) +{ + double val; + + int n = l.Height(); + p = g; + + for (int i = 0; i < n; i++) + { + val = 0; + for (int j = 0; j < i; j++) + val += p(j) * l(i,j); + p(i) -= val; + } + + for (int i = 0; i < n; i++) + p(i) /= d(i); + + for (int i = n-1; i >= 0; i--) + { + val = 0; + for (int j = i+1; j < n; j++) + val += p(j) * l(j, i); + p(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) + { + (*testout) << "update err, t = " << t << endl; + 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); + + // (*testout) << "l " << l << endl +// << "d " << d << endl +// << "g " << g << endl +// << "p " << p << endl; + + + 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(ifail == 1) + (*testout) << "no success with linesearch" << endl; + + /* + // 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 << "BFGS update error1" << endl; + (*testout) << "BFGS update error1" << endl; + (*testout) << "l " << endl << l << endl + << "d " << d << endl; + ifail = 1; + break; + } + + if (LDLtUpdate (l, d, -1 / a2, bs) != 0) + { + cerr << "BFGS update error2" << endl; + (*testout) << "BFGS update error2" << endl; + (*testout) << "l " << endl << l << endl + << "d " << d << 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/libsrc/opti/linopt.cpp b/libsrc/opti/linopt.cpp new file mode 100644 index 00000000..a5d381e6 --- /dev/null +++ b/libsrc/opti/linopt.cpp @@ -0,0 +1,73 @@ +#include +#include + +#include +#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/libsrc/opti/linsearch.cpp b/libsrc/opti/linsearch.cpp new file mode 100644 index 00000000..4c297fd9 --- /dev/null +++ b/libsrc/opti/linsearch.cpp @@ -0,0 +1,351 @@ +/***************************************************************************/ +/* */ +/* Problem: Liniensuche */ +/* */ +/* Programmautor: Joachim Schöberl */ +/* Matrikelnummer: 9155284 */ +/* */ +/* Algorithmus nach: */ +/* */ +/* Optimierung I, Gfrerer, WS94/95 */ +/* Algorithmus 2.1: Liniensuche Problem (ii) */ +/* */ +/***************************************************************************/ + + + +#include + +#include // min, max, sqr + +#include +#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 +{ + cerr << "Grad of MinFunction called" << endl; + return 0; + /* + int n = x.Size(); + + static Vector xr; + static Vector xl; + xr.SetSize(n); + xl.SetSize(n); + + double eps = 1e-6; + double fl, fr; + + for (int i = 1; i <= n; i++) + { + xr.Set (1, x); + xl.Set (1, x); + + xr.Elem(i) += eps; + fr = Func (xr); + + xl.Elem(i) -= eps; + fl = Func (xl); + + 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; + } + + ifail = 1; // Markus + + phi1prime = phi0prime; + + // (*testout) << "phi0prime = " << phi0prime << endl; + + // it = 100000l; + it = 0; + + while (it++ <= par.maxit_linsearch) + { + + xneu.Set2 (1, x, alphahat, p); + + + // f = fun.FuncGrad (xneu, g); + // f = fun.Func (xneu); + f = fun.FuncDeriv (xneu, p, phihatprime); + + // (*testout) << "lines, 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/libsrc/opti/opti.hpp b/libsrc/opti/opti.hpp new file mode 100644 index 00000000..98757869 --- /dev/null +++ b/libsrc/opti/opti.hpp @@ -0,0 +1,142 @@ +#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 + + + + + /** + Solver for 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/libsrc/parallel/Makefile.am b/libsrc/parallel/Makefile.am new file mode 100644 index 00000000..4edf2056 --- /dev/null +++ b/libsrc/parallel/Makefile.am @@ -0,0 +1,2 @@ +INCLUDES = +METASOURCES = AUTO diff --git a/libsrc/parallel/Makefile.in b/libsrc/parallel/Makefile.in new file mode 100644 index 00000000..3b5b4c98 --- /dev/null +++ b/libsrc/parallel/Makefile.in @@ -0,0 +1,331 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/parallel +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = +METASOURCES = AUTO +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/parallel/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/parallel/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/parallel/parallel.hpp b/libsrc/parallel/parallel.hpp new file mode 100644 index 00000000..ca50faf8 --- /dev/null +++ b/libsrc/parallel/parallel.hpp @@ -0,0 +1,274 @@ +#ifndef FILE_PARALLEL +#define FILE_PARALLEL + + + +#ifdef VTRACE +#include "vt_user.h" +#else + #define VT_USER_START(n) + #define VT_USER_END(n) + #define VT_TRACER(n) +#endif + +#ifndef PARALLEL + + + +namespace netgen +{ + //using namespace netgen; + enum { id = 0 }; + enum { ntasks = 0 }; +} + + +#else // if PARALLEL + +// #include +#include +#include "incvis.hpp" + + +//#include "parallelfunc.hpp" +extern MPI_Group MPI_HIGHORDER_WORLD; +extern MPI_Comm MPI_HIGHORDER_COMM; + +namespace netgen +{ + extern int id, ntasks; + + template + MPI_Datatype MyGetMPIType ( ) { cerr << "ERROR in GetMPIType() -- no type found" << endl;return 0;} + + template <> + inline MPI_Datatype MyGetMPIType ( ) + { return MPI_INT; } + + template <> + inline MPI_Datatype MyGetMPIType ( ) + { return MPI_DOUBLE; } + + + // damit gehen auch echte Konstante ohne Adresse + inline void MyMPI_Send (int i, int dest) + { + int hi = i; + MPI_Send( &hi, 1, MPI_INT, dest, 1, MPI_COMM_WORLD); + } + + inline void MyMPI_Recv (int & i, int src) + { + MPI_Status status; + MPI_Recv( &i, 1, MPI_INT, src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + } + + + + inline void MyMPI_Send (const string & s, int dest) + { + MPI_Send( const_cast (s.c_str()), s.length(), MPI_CHAR, dest, 1, MPI_COMM_WORLD); + } + + inline void MyMPI_Recv (string & s, int src) + { + MPI_Status status; + int len; + MPI_Probe (src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + MPI_Get_count (&status, MPI_CHAR, &len); + s.assign (len, ' '); + MPI_Recv( &s[0], len, MPI_CHAR, src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + } + + + + + template + inline void MyMPI_Send (FlatArray s, int dest) + { + MPI_Send( &s.First(), s.Size(), MyGetMPIType(), dest, 1, MPI_COMM_WORLD); + } + + template + inline void MyMPI_Recv ( FlatArray s, int src) + { + MPI_Status status; + MPI_Recv( &s.First(), s.Size(), MyGetMPIType(), src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + } + + template + inline void MyMPI_Recv ( ARRAY & s, int src) + { + MPI_Status status; + int len; + MPI_Probe (src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + MPI_Get_count (&status, MyGetMPIType(), &len); + + s.SetSize (len); + MPI_Recv( &s.First(), len, MyGetMPIType(), src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + } + + template + inline int MyMPI_Recv ( ARRAY & s) + { + MPI_Status status; + int len; + MPI_Probe (MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + + int src = status.MPI_SOURCE; + + MPI_Get_count (&status, MyGetMPIType(), &len); + + s.SetSize (len); + MPI_Recv( &s.First(), len, MyGetMPIType(), src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + + return src; + } + + + + template + inline void MyMPI_ISend (FlatArray s, int dest, MPI_Request & request) + { + MPI_Isend( &s.First(), s.Size(), MyGetMPIType(), dest, 1, MPI_COMM_WORLD, & request); + } + + + template + inline void MyMPI_IRecv (FlatArray s, int dest, MPI_Request & request) + { + MPI_Irecv( &s.First(), s.Size(), MyGetMPIType(), dest, 1, MPI_COMM_WORLD, & request); + } + + template + inline void MyMPI_ISendTag (FlatArray s, int dest, int tag, MPI_Request & request) + { + MPI_Isend( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD, & request); + } + + + template + inline void MyMPI_IRecvTag (FlatArray s, int dest, int tag, MPI_Request & request) + { + MPI_Irecv( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD, & request); + } + + + template + inline MPI_Request MyMPI_ISend (FlatArray s, int dest) + { + MPI_Request request; + MPI_Isend( &s.First(), s.Size(), MyGetMPIType(), dest, 1, MPI_COMM_WORLD, &request); + return request; + // MPI_Request_free (&request); + } + + + template + inline MPI_Request MyMPI_IRecv (FlatArray s, int dest) + { + MPI_Request request; + MPI_Irecv( &s.First(), s.Size(), MyGetMPIType(), dest, 1, MPI_COMM_WORLD, &request); + return request; + // MPI_Request_free (&request); + } + + + + + template + inline void MyMPI_Bcast (T & s, MPI_Comm comm = MPI_COMM_WORLD) + { + MPI_Bcast (&s, 1, MyGetMPIType(), 0, comm); + } + + template + inline void MyMPI_Bcast (ARRAY & s, MPI_Comm comm = MPI_COMM_WORLD) + { + int size = s.Size(); + MyMPI_Bcast (size, comm); + if (id != 0) s.SetSize (size); + MPI_Bcast (&s[0], size, MyGetMPIType(), 0, comm); + } + + template + inline void MyMPI_Bcast (ARRAY & s, int root, MPI_Comm comm = MPI_COMM_WORLD) + { + int id; + MPI_Comm_rank(MPI_HIGHORDER_COMM, &id); + + int size = s.Size(); + MPI_Bcast (&size, 1, MPI_INT, root, comm); + if (id != root) s.SetSize (size); + if ( !size ) return; + MPI_Bcast (&s[0], size, MyGetMPIType(), root, comm); + } + + + template + inline void MyMPI_Allgather (const T & send, FlatArray recv, MPI_Comm comm) + { + MPI_Allgather( const_cast (&send), 1, MyGetMPIType(), &recv[0], 1, MyGetMPIType(), comm); + } + + template + inline void MyMPI_Alltoall (FlatArray send, FlatArray recv, MPI_Comm comm) + { + MPI_Alltoall( &send[0], 1, MyGetMPIType(), &recv[0], 1, MyGetMPIType(), comm); + } + +// template +// inline void MyMPI_Alltoall_Block (FlatArray send, FlatArray recv, int blocklen, MPI_Comm comm) +// { +// MPI_Alltoall( &send[0], blocklen, MyGetMPIType(), &recv[0], blocklen, MyGetMPIType(), comm); +// } + + + + inline void MyMPI_Send ( int *& s, int & len, int dest) + { + MPI_Send( &len, 1, MPI_INT, dest, 1, MPI_COMM_WORLD); + MPI_Send( s, len, MPI_INT, dest, 1, MPI_COMM_WORLD); + } + + + inline void MyMPI_Recv ( int *& s, int & len, int src) + { + MPI_Status status; + MPI_Recv( &len, 1, MPI_INT, src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + if ( s ) + delete [] s; + s = new int [len]; + MPI_Recv( s, len, MPI_INT, src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + } + + + + inline void MyMPI_Send ( double * s, int len, int dest) + { + MPI_Send( &len, 1, MPI_INT, dest, 1, MPI_COMM_WORLD); + MPI_Send( s, len, MPI_DOUBLE, dest, 1, MPI_COMM_WORLD); + } + + + inline void MyMPI_Recv ( double *& s, int & len, int src) + { + MPI_Status status; + MPI_Recv( &len, 1, MPI_INT, src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + if ( s ) + delete [] s; + s = new double [len]; + MPI_Recv( s, len, MPI_DOUBLE, src, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + } + + +// #include "parallelmesh.hpp" +#include "paralleltop.hpp" + +#include "parallelinterface.hpp" + +} + +#endif // PARALLEL + +#endif diff --git a/libsrc/parallel/parallelfunc.hpp b/libsrc/parallel/parallelfunc.hpp new file mode 100644 index 00000000..fe41ad04 --- /dev/null +++ b/libsrc/parallel/parallelfunc.hpp @@ -0,0 +1,15 @@ +#ifndef FILE_PARALLELFUNC +#define FILE_PARALLELFUNC + + + +void ParallelRun(); + +void LoadPDEParallel ( const char* filename ); + + +#ifdef NGSOLVE +void NGS_ParallelRun ( const string & message); +#endif + +#endif diff --git a/libsrc/parallel/parallelinterface.hpp b/libsrc/parallel/parallelinterface.hpp new file mode 100644 index 00000000..ed262e6b --- /dev/null +++ b/libsrc/parallel/parallelinterface.hpp @@ -0,0 +1,52 @@ +#ifndef FILE_PARALLELINTERFACE +#define FILE_PARALLELINTERFACE + +#ifdef PARALLEL + +#ifdef __cplusplus +extern "C" { +#endif + + // this interface is 0-base !! + +// // these functions have O(N) complexity +// int NgPar_Glob2Loc_SurfEl ( int globnum ) ; +// int NgPar_Glob2Loc_VolEl ( int globnum ) ; +// int NgPar_Glob2Loc_Segm ( int globnum ) ; +// int NgPar_Glob2Loc_Vert ( int globnum ) ; + + + int NgPar_GetLoc2Glob_VolEl ( int locnum ); + + // int NgPar_GetDistantNodeNums ( int nt, int locnum, int * procs, int * distnum); + + // number on distant processor + + // gibt anzahl an distant pnums zurueck + // * pnums entspricht ARRAY + int NgPar_GetDistantNodeNums ( int nodetype, int locnum, int * pnums ); + int NgPar_GetNDistantNodeNums ( int nodetype, int locnum ); + + int NgPar_GetDistantPNum ( int proc, int locnum ) ; + int NgPar_GetDistantEdgeNum ( int proc, int locnum ) ; + int NgPar_GetDistantFaceNum ( int proc, int locnum ) ; + int NgPar_GetDistantElNum ( int proc, int locnum ); + + bool NgPar_IsExchangeFace ( int fnr ) ; + bool NgPar_IsExchangeVert ( int vnum ); + bool NgPar_IsExchangeEdge ( int ednum ); + bool NgPar_IsExchangeElement ( int elnum ); + + void NgPar_PrintParallelMeshTopology (); + bool NgPar_IsElementInPartition ( int elnum, int dest ); + + bool NgPar_IsGhostFace ( int facenum ); + bool NgPar_IsGhostEdge ( int edgenum ); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/libsrc/parallel/paralleltop.hpp b/libsrc/parallel/paralleltop.hpp new file mode 100644 index 00000000..4c6c128a --- /dev/null +++ b/libsrc/parallel/paralleltop.hpp @@ -0,0 +1,267 @@ +#ifndef FILE_PARALLELTOP +#define FILE_PARALLELTOP + +extern int ntasks; + +class ParallelMeshTopology +{ + const Mesh & mesh; + + // number of local elements, vertices, points (?), edges, faces + int ne, nv, np, ned, nfa; + + // number of local segments and surface elements + int nseg, nsurfel; + + // number of global elements, vertices, ???, faces + int neglob, nvglob; + int nparel; + int nfaglob; + + /** + mapping from local to distant vertex number + each row of the table corresponds to one vertex + each row contains a list of pairs (procnr, dist_vnum) + */ + TABLE loc2distvert; + TABLE loc2distedge, loc2distface, loc2distel; + TABLE loc2distsegm, loc2distsurfel; + + BitArray * isexchangeface, * isexchangevert, * isexchangeedge, * isexchangeel; + + BitArray isghostedge, isghostface; + + bool coarseupdate; + int overlap; + +public: + + ParallelMeshTopology (const Mesh & amesh); + ~ParallelMeshTopology (); + + /// set number of local vertices, reset sizes of loc2dist_vert, isexchangevert... + void SetNV ( int anv ); + void SetNE ( int ane ); + void SetNSE ( int anse ); + void SetNSegm ( int anseg ); + + void Reset (); + + void SetLoc2Glob_Vert ( int locnum, int globnum ) { loc2distvert[locnum][0] = globnum; } + void SetLoc2Glob_VolEl ( int locnum, int globnum ) { loc2distel[locnum-1][0] = globnum; } + void SetLoc2Glob_SurfEl ( int locnum, int globnum ) { loc2distsurfel[locnum-1][0] = globnum; } + void SetLoc2Glob_Segm ( int locnum, int globnum ) { loc2distsegm[locnum-1][0] = globnum; } + + int GetLoc2Glob_Vert ( int locnum ) const { return loc2distvert[locnum][0]; } + int GetLoc2Glob_VolEl ( int locnum ) const { return loc2distel[locnum-1][0]; } + + void GetVertNeighbours ( int vnum, ARRAY & dests ) const; + + int Glob2Loc_SurfEl ( int globnum ); + int Glob2Loc_VolEl ( int globnum ); + int Glob2Loc_Segm ( int globnum ); + int Glob2Loc_Vert ( int globnum ); + + int GetNDistantPNums ( int locpnum ) const { return loc2distvert[locpnum].Size() / 2 + 1; } + int GetNDistantFaceNums ( int locfacenum ) const { return loc2distface[locfacenum-1].Size() / 2 + 1; } + int GetNDistantEdgeNums ( int locedgenum ) const { return loc2distedge[locedgenum-1].Size() / 2 + 1; } + int GetNDistantElNums ( int locelnum ) const { return loc2distel[locelnum-1].Size() / 2 + 1; } + + int GetDistantPNum ( int proc, int locpnum ) const; + int GetDistantEdgeNum ( int proc, int locedgenum ) const; + int GetDistantFaceNum ( int proc, int locedgenum ) const; + int GetDistantElNum ( int proc, int locelnum ) const; + + int GetDistantPNums ( int locpnum, int * distpnums ) const; + int GetDistantEdgeNums ( int locedgenum, int * distedgenums ) const; + int GetDistantFaceNums ( int locedgenum, int * distfacenums ) const; + int GetDistantElNums ( int locelnum, int * distfacenums ) const; + + void Print() const; + + void SetExchangeFace ( int fnr ) { isexchangeface->Set( (fnr-1)*(ntasks+1) ); } + void SetExchangeVert ( int vnum ) { isexchangevert->Set( (vnum-1)*(ntasks+1) ); } + void SetExchangeElement ( int elnum ) { isexchangeel->Set((elnum-1)*(ntasks+1) ); } + void SetExchangeEdge ( int ednum ) { isexchangeedge->Set ((ednum-1)*(ntasks+1)); } + + + // fuer diese Fkts kann man ja O(N) - bitarrays lassen + bool IsExchangeVert ( PointIndex vnum ) const + { + return loc2distvert[vnum].Size() > 1; + // return isexchangevert->Test((vnum-1)*(ntasks+1)); + } + + bool IsExchangeEdge ( int ednum ) const + { + /* + if ( isexchangeedge->Test( (ednum-1)*(ntasks+1) ) != + ( loc2distedge[ednum-1].Size() > 1) ) + { + cerr << "isexedge differs, id = " << id << ", ednum = " << ednum << endl; + } + */ + // return loc2distedge[ednum-1].Size() > 1; + int i = (ednum-1)*(ntasks+1); + return isexchangeedge->Test(i); + } + + bool IsExchangeFace ( int fnum ) const + { + /* + if ( isexchangeface->Test( (fnum-1)*(ntasks+1) ) != + ( loc2distface[fnum-1].Size() > 1) ) + { + cerr << "it differs, id = " << id << ", fnum = " << fnum << endl; + } + */ + // nur hier funktioniert's so nicht ???? (JS) + // return loc2distface[fnum-1].Size() > 1; + return isexchangeface->Test( (fnum-1)*(ntasks+1) ); + } + + bool IsExchangeElement ( int elnum ) const + { + // return loc2distel[elnum-1].Size() > 1; + return isexchangeel->Test((elnum-1)*(ntasks+1)); + } + + bool IsExchangeSEl ( int selnum ) const + { + return loc2distsurfel[selnum-1].Size() > 1; + } + + + void SetExchangeFace (int dest, int fnr ) + { + // isexchangeface->Set((fnr-1)*(ntasks+1) + (dest+1)); + } + + void SetExchangeVert (int dest, int vnum ) + { + // isexchangevert->Set((vnum-1)*(ntasks+1) + (dest+1) ); + } + + void SetExchangeElement (int dest, int vnum ) + { + isexchangeel->Set( (vnum-1)*(ntasks+1) + (dest+1) ); + } + + void SetExchangeEdge (int dest, int ednum ) + { + // isexchangeedge->Set ( (ednum-1)*(ntasks+1) + (dest+1) ); + } + + + bool IsExchangeVert (int dest, int vnum ) const + { + FlatArray exchange = loc2distvert[vnum]; + for (int i = 1; i < exchange.Size(); i += 2) + if (exchange[i] == dest) return true; + return false; + // return isexchangevert->Test((vnum-1)*(ntasks+1) + (dest+1) ); + } + + bool IsExchangeEdge (int dest, int ednum ) const + { + FlatArray exchange = loc2distedge[ednum-1]; + for (int i = 1; i < exchange.Size(); i += 2) + if (exchange[i] == dest) return true; + return false; + + // return isexchangeedge->Test((ednum-1)*(ntasks+1) + (dest+1)); + } + + bool IsExchangeFace (int dest, int fnum ) const + { + FlatArray exchange = loc2distface[fnum-1]; + for (int i = 1; i < exchange.Size(); i += 2) + if (exchange[i] == dest) return true; + return false; + + // return isexchangeface->Test((fnum-1)*(ntasks+1) + (dest+1) ); + } + + bool IsExchangeElement (int dest, int elnum ) const + { + // das geht auch nicht + /* + FlatArray exchange = loc2distel[elnum-1]; + for (int i = 1; i < exchange.Size(); i += 2) + if (exchange[i] == dest) return true; + return false; + */ + return isexchangeel->Test((elnum-1)*(ntasks+1) + (dest+1)); + } + + int Overlap() const + { return overlap; } + + int IncreaseOverlap () + { overlap++; return overlap; } + + void Update(); + + void UpdateCoarseGrid(); + void UpdateCoarseGridOverlap(); + void UpdateRefinement (); + void UpdateTopology (); + void UpdateExchangeElements(); + + void UpdateCoarseGridGlobal(); + + const bool DoCoarseUpdate() const + { return !coarseupdate; } + + + void SetDistantFaceNum ( int dest, int locnum, int distnum ); + void SetDistantPNum ( int dest, int locnum, int distnum ); + void SetDistantEdgeNum ( int dest, int locnum, int distnum ); + void SetDistantEl ( int dest, int locnum, int distnum ); + void SetDistantSurfEl ( int dest, int locnum, int distnum ); + void SetDistantSegm ( int dest, int locnum, int distnum ); + + bool IsGhostEl ( int elnum ) const { return mesh.VolumeElement(elnum).IsGhost(); } + bool IsGhostFace ( int fanum ) const { return isghostface.Test(fanum-1); } + bool IsGhostEdge ( int ednum ) const { return isghostedge.Test(ednum-1); } + bool IsGhostVert ( int pnum ) const { return mesh.Point(pnum).IsGhost(); } + +// inline void SetGhostVert ( const int pnum ) +// { isghostvert.Set(pnum-1); } + + void SetGhostEdge ( int ednum ) + { isghostedge.Set(ednum-1); } + + void ClearGhostEdge ( int ednum ) + { isghostedge.Clear(ednum-1); } + + void SetGhostFace ( int fanum ) + { isghostface.Set(fanum-1); } + + void ClearGhostFace ( int fanum ) + { isghostface.Clear(fanum-1); } + + bool IsElementInPartition ( int elnum, int dest ) const + { + return IsExchangeElement ( dest, elnum); + } + + void SetElementInPartition ( int elnum, int dest ) + { + SetExchangeElement ( dest, elnum ); + } + + void SetNVGlob ( int anvglob ) { nvglob = anvglob; } + void SetNEGlob ( int aneglob ) { neglob = aneglob; } + + int GetNVGlob () { return nvglob; } + int GetNEGlob () { return neglob; } +}; + + + + + + + +#endif diff --git a/libsrc/stlgeom/Makefile.am b/libsrc/stlgeom/Makefile.am new file mode 100644 index 00000000..b204ef09 --- /dev/null +++ b/libsrc/stlgeom/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libstl.a +libstl_a_SOURCES = meshstlsurface.cpp stlgeom.cpp stlgeomchart.cpp \ + stlgeommesh.cpp stlline.cpp stltool.cpp stltopology.cpp diff --git a/libsrc/stlgeom/Makefile.in b/libsrc/stlgeom/Makefile.in new file mode 100644 index 00000000..3b574c5b --- /dev/null +++ b/libsrc/stlgeom/Makefile.in @@ -0,0 +1,449 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/stlgeom +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libstl_a_AR = $(AR) $(ARFLAGS) +libstl_a_LIBADD = +am_libstl_a_OBJECTS = meshstlsurface.$(OBJEXT) stlgeom.$(OBJEXT) \ + stlgeomchart.$(OBJEXT) stlgeommesh.$(OBJEXT) stlline.$(OBJEXT) \ + stltool.$(OBJEXT) stltopology.$(OBJEXT) +libstl_a_OBJECTS = $(am_libstl_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstl_a_SOURCES) +DIST_SOURCES = $(libstl_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libstl.a +libstl_a_SOURCES = meshstlsurface.cpp stlgeom.cpp stlgeomchart.cpp \ + stlgeommesh.cpp stlline.cpp stltool.cpp stltopology.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/stlgeom/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/stlgeom/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libstl.a: $(libstl_a_OBJECTS) $(libstl_a_DEPENDENCIES) + -rm -f libstl.a + $(libstl_a_AR) libstl.a $(libstl_a_OBJECTS) $(libstl_a_LIBADD) + $(RANLIB) libstl.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshstlsurface.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlgeom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlgeomchart.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlgeommesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stltool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stltopology.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/stlgeom/meshstlsurface.cpp b/libsrc/stlgeom/meshstlsurface.cpp new file mode 100644 index 00000000..da23f877 --- /dev/null +++ b/libsrc/stlgeom/meshstlsurface.cpp @@ -0,0 +1,1133 @@ +#include +#include + +#include +#include + +#include + + +#include "stlgeom.hpp" + + +namespace netgen +{ + +static void STLFindEdges (STLGeometry & geom, + class Mesh & mesh) +{ + int i, j; + double h; + + h = mparam.maxh; + + // mark edge points: + //int ngp = geom.GetNP(); + + geom.RestrictLocalH(mesh, h); + + PushStatusF("Mesh Lines"); + + ARRAY meshlines; + ARRAY 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 + int pim; + for (i = 1; i <= meshpoints.Size(); i++) + { + geom.meshpoints.Append(meshpoints.Get(i)); //testing + + 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 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 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 + if(mesh.CheckOverlappingBoundary()) + { + return MESHING3_BADSURFACEMESH; + } + + + 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 refpts; + ARRAY 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; + double h; + + + h = mparam.maxh; + + mesh.FindOpenSegments(); + + ARRAY 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 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 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 & meshparam) +{ + PrintFnStart("optimize STL Surface"); + + + MeshOptimizeSTLSurface optmesh(geom); + // + + int i; + /* + 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 (meshparam.elsizeweight); + + PrintMessage(5,"optimize string = ", meshparam.optimize2d, " elsizew = ", meshparam.elsizeweight); + + for (i = 1; i <= meshparam.optsteps2d; i++) + for (size_t j = 1; j <= strlen(meshparam.optimize2d); j++) + { + if (multithread.terminate) + break; + + //(*testout) << "optimize, before, step = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl; + + mesh.CalcSurfacesOfNode(); + switch (meshparam.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 = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl; + } + + geom.surfaceoptimized = 1; + + mesh.Compress(); + mesh.CalcSurfacesOfNode(); + + +} + + + +MeshingSTLSurface :: MeshingSTLSurface (STLGeometry & ageom) + : Meshing2(ageom.GetBoundingBox()), geom(ageom) +{ + ; +} + +void MeshingSTLSurface :: DefineTransformation (const Point3d & p1, const 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 & points, + ARRAY & points3d, + ARRAY & 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 Point<3> & p, + const PointGeomInfo & gi) +{ + // (*testout) << "sel char: " << gi.trignum << endl; + + geom.SelectChartOfTriangle (gi.trignum); + // geom.SelectChartOfPoint (p); +} + + +void MeshOptimizeSTLSurface :: ProjectPoint (INDEX surfind, Point<3> & p) const +{ + if (!geom.Project (p)) + { + PrintMessage(7,"project failed"); + + if (!geom.ProjectOnWholeSurface(p)) + { + PrintMessage(7, "project on whole surface failed"); + } + } + + // geometry.GetSurface(surfind)->Project (p); +} + +void MeshOptimizeSTLSurface :: ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const +{ + /* + ProjectToEdge ( geometry.GetSurface(surfind), + geometry.GetSurface(surfind2), p); + */ +} + +int MeshOptimizeSTLSurface :: CalcPointGeomInfo(PointGeomInfo& gi, const Point<3> & p3) const +{ + Point<3> hp = p3; + gi.trignum = geom.Project (hp); + + if (gi.trignum) + { + return 1; + } + + return 0; + +} + +void MeshOptimizeSTLSurface :: GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & 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 Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & 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 Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & gi1, + const EdgePointGeomInfo & gi2, + Point<3> & 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/libsrc/stlgeom/meshstlsurface.hpp b/libsrc/stlgeom/meshstlsurface.hpp new file mode 100644 index 00000000..c132b30c --- /dev/null +++ b/libsrc/stlgeom/meshstlsurface.hpp @@ -0,0 +1,121 @@ +#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 (const Point3d & p1, const 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 & points, + ARRAY & poitns3d, + ARRAY & 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 Point<3> & p, + const PointGeomInfo & gi); + /// + virtual void ProjectPoint (INDEX surfind, Point<3> & p) const; + /// + virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const; + /// + virtual int CalcPointGeomInfo(PointGeomInfo& gi, const Point<3> & p3) const; + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const; +}; + + + + +class RefinementSTLGeometry : public Refinement +{ + const STLGeometry & geom; + +public: + RefinementSTLGeometry (const STLGeometry & ageom); + virtual ~RefinementSTLGeometry (); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & 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/libsrc/stlgeom/stlgeom.cpp b/libsrc/stlgeom/stlgeom.cpp new file mode 100644 index 00000000..e376fa07 --- /dev/null +++ b/libsrc/stlgeom/stlgeom.cpp @@ -0,0 +1,3471 @@ +#include + +#include +#include +#include + +#include + +#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(), selectedmultiedge() +{ + edgedata = new STLEdgeDataList(*this); + 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() +{ + delete edgedata; +} + +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 lp1,lp2; + 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)), lp1, lp2); + if (!IsEdge(lp1,lp2)) + { + 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 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 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 ap1, int ap2) +{ + STLEdge e(ap1,ap2); + e.SetLeftTrig(GetLeftTrig(ap1,ap2)); + e.SetRightTrig(GetRightTrig(ap1,ap2)); + return edges.Append(e); +} + +void STLGeometry :: STLDoctorConfirmEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CONFIRMED); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CONFIRMED); + } + } + } +} + +void STLGeometry :: STLDoctorCandidateEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CANDIDATE); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CANDIDATE); + } + } + } +} + +void STLGeometry :: STLDoctorExcludeEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_EXCLUDED); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_EXCLUDED); + } + } + } +} + +void STLGeometry :: STLDoctorUndefinedEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_UNDEFINED); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).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 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 > 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 >& eps) +{ + int i; + int ne = eps.Size()/2; + + ARRAY epsi; + Box<3> bb = GetBoundingBox(); + bb.Increase(1); + + Point3dTree ptree (bb.PMin(), + bb.PMax()); + ARRAY pintersect; + + double gtol = GetBoundingBox().Diam()/1.E10; + Point<3> p; + + for (i = 1; i <= GetNP(); i++) + { + p = GetPoint(i); + ptree.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); + + ptree.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 importpoints; + ARRAY importlines; + ARRAY 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); + + 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 ptree (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 pintersect; + + double gtol = GetBoundingBox().Diam()/1.E6; + + for (i = 1; i <= GetNP(); i++) + { + Point3d p = GetPoint(i); + // (*testout) << "stlpt: " << p << endl; + ptree.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); + + ptree.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 ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } +} + +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 ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } + } + } +} + +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 ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } + } + } +} + +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 ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } + } + } +} + +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 ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (IsExternalEdge(ap1,ap2)) {DeleteExternalEdge(ap1,ap2);} + } + } + } +} + +void STLGeometry :: AddExternalEdgesFromGeomLine() +{ + StoreExternalEdges(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + + if (IsEdge(ap1,ap2)) + { + int edgenum = IsEdgeNum(ap1,ap2); + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + + int noend = 1; + int startp = ap1; + 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 = ap2; + 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 ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + if (IsExternalEdge(ap1,ap2)) {DeleteExternalEdge(ap1,ap2);} + } +} + +void STLGeometry :: DeleteExternalEdgeInVicinity() +{ + StoreExternalEdges(); + if (!stldoctor.showvicinity || vicinity.Size() != GetNT()) {return;} + + int i, j, ap1, ap2; + + for (i = 1; i <= GetNT(); i++) + { + if (vicinity.Elem(i)) + { + for (j = 1; j <= 3; j++) + { + ap1 = GetTriangle(i).PNum(j); + ap2 = GetTriangle(i).PNumMod(j+1); + + if (IsExternalEdge(ap1,ap2)) + { + DeleteExternalEdge(ap1,ap2); + } + } + } + } +} + +void STLGeometry :: BuildExternalEdgesFromEdges() +{ + StoreExternalEdges(); + + if (GetNE() == 0) {PrintWarning("Edges possibly not generated!");} + + int i; + externaledges.SetSize(0); + + for (i = 1; i <= GetNE(); i++) + { + STLEdge e = GetEdge(i); + AddExternalEdge(e.PNum(1), e.PNum(2)); + } + +} + + +void STLGeometry :: AddExternalEdge(int ap1, int ap2) +{ + externaledges.Append(twoint(ap1,ap2)); +} + +void STLGeometry :: DeleteExternalEdge(int ap1, int ap2) +{ + + int i; + int found = 0; + for (i = 1; i <= NOExternalEdges(); i++) + { + if ((GetExternalEdge(i).i1 == ap1 && GetExternalEdge(i).i2 == ap2) || + (GetExternalEdge(i).i1 == ap2 && GetExternalEdge(i).i2 == ap1)) {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 ap1, int ap2) +{ + int i; + for (i = 1; i <= NOExternalEdges(); i++) + { + if ((GetExternalEdge(i).i1 == ap1 && GetExternalEdge(i).i2 == ap2) || + (GetExternalEdge(i).i1 == ap2 && GetExternalEdge(i).i2 == ap1)) {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& ap1 = GetPoint(tr.PNum(1)); + const Point3d& ap2 = GetPoint(tr.PNum(2)); + const Point3d& ap3 = GetPoint(tr.PNum(3)); + + Vec3d normal = Cross (ap2-ap1, ap3-ap1); + + 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 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) + { + + Point<3> ap1, ap2; + for (i = 1; i <= n; i++) + { + fin >> ap1(0); fin >> ap1(1); fin >> ap1(2); + fin >> ap2(0); fin >> ap2(1); fin >> ap2(2); + AddMarkedSeg(ap1,ap2); + } + } +} + +void STLGeometry :: SaveMarkedTrigs() +{ + PrintFnStart("save marked trigs to file 'markedtrigs.ng'"); + ofstream fout("markedtrigs.ng"); + + int n = GetNT(); + fout << n << endl; + + int i; + for (i = 1; i <= n; i++) + { + fout << IsMarkedTrig(i) << "\n"; + } + + n = GetNMarkedSegs(); + fout << n << endl; + + Point<3> ap1,ap2; + for (i = 1; i <= n; i++) + { + GetMarkedSeg(i,ap1,ap2); + fout << ap1(0) << " " << ap1(1) << " " << ap1(2) << " "; + fout << ap2(0) << " " << ap2(1) << " " << ap2(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& vic) +{ + if (starttrig == 0 || starttrig > GetNT()) {return;} + + ARRAY 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 list1; + list1.SetSize(0); + ARRAY 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 list1; + list1.SetSize(0); + ARRAY 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 ap1, ap2; + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), ap1, ap2); + + if (!IsEdge(ap1,ap2) && 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 ap1, ap2; + for (i = 1; i <= GetNT(); i++) + { + found = 0; + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), ap1, ap2); + + if (!IsEdge(ap1,ap2)) + { + 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 ap1, ap2; + + 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)),ap1,ap2); + if (Dist(GetPoint(ap1),GetPoint(ap2)) >= maxlen) + { + foundtrig = NeighbourTrig(i,j); + maxlen = Dist(GetPoint(ap1),GetPoint(ap2)); + } + } + } + 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 & readtrias) +{ + PrintFnStart("Init STL Geometry"); + STLTopology::InitSTLGeometry(readtrias); + + int i, 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 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 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 Point<3> *trip1[3], *trip2[3]; + Point<3> 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 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 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 ap1, int ap2) +{ + int i,j; + for (i = 1; i <= GetNEPP(ap1); i++) + { + for (j = 1; j <= GetNEPP(ap2); j++) + { + if (GetEdgePP(ap1,i) == GetEdgePP(ap2,j)) {return 1;} + } + } + return 0; +} + +int STLGeometry :: IsEdgeNum(int ap1, int ap2) +{ + int i,j; + for (i = 1; i <= GetNEPP(ap1); i++) + { + for (j = 1; j <= GetNEPP(ap2); j++) + { + if (GetEdgePP(ap1,i) == GetEdgePP(ap2,j)) {return GetEdgePP(ap1,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; + 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"); + + int i; + + 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; + 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 edgecnt; + ARRAY 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, ap1, ap2; + 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),ap1,ap2); + AddEdge(ap1,ap2); + 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(0); + int edgecnt = 0; + int found; + int rev(0); //indicates, that edge is inserted reverse + + //worked edges + ARRAY 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 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 ap1, ap2; + line->GetSeg(ii,ap1,ap2); + // (*mycout) << "SEG " << p1 << " - " << p2 << endl; + } + } + + PopStatus(); +} + +int STLGeometry :: GetNOBodys() +{ + int markedtrigs1 = 0; + int starttrig = 1; + int i, k, nnt; + int bodycnt = 0; + + ARRAY bodynum(GetNT()); + + for (i = 1; i <= GetNT(); i++) + bodynum.Elem(i)=0; + + + while (markedtrigs1 < 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 todolist; + ARRAY nextlist; + bodycnt++; + markedtrigs1++; + bodynum.Elem(starttrig) = bodycnt; + todolist.Append(starttrig); + + 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; + markedtrigs1++; + } + } + } + + 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 markedtrigs1 = 0; + int starttrig(0); + int laststarttrig = 1; + int i, k, nnt; + facecnt = 0; + + + for (i = 1; i <= GetNT(); i++) + GetTriangle(i).SetFaceNum(0); + + + while (markedtrigs1 < 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 todolist; + ARRAY nextlist; + facecnt++; + markedtrigs1++; + GetTriangle(starttrig).SetFaceNum(facecnt); + todolist.Append(starttrig); + int ap1, ap2; + + 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,ap1,ap2); + if (!IsEdge(ap1,ap2)) + { + nextlist.Append(nnt); + nt.SetFaceNum(facecnt); + markedtrigs1++; + } + } + } + } + + 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 (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); + + ng1 = trig.GeomNormal(points); + ng1 /= (ng1.Length() + 1e-24); + + for (j = 1; j <= 3; j++) + { + int nbt = NeighbourTrig (i, j); + + 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& 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 trigsaroundp; + ARRAY 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 ap1, ap2, 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, ap1, ap2); + if (IsEdge(ap1,ap2)) 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, ap1, ap2); + if (IsEdge(ap1,ap2)) 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(ap1,ap2); + se.SetLeftTrig(tn1); + se.SetRightTrig(tn2); + int edgenum = AddEdge(se); + AddEdgePP(ap1,edgenum); + AddEdgePP(ap2,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, ap1, ap2); + if (IsEdge(ap1,ap2)) 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, ap1, ap2); + if (IsEdge(ap1,ap2)) 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(ap1,ap2); + se.SetLeftTrig(tn1); + se.SetRightTrig(tn2); + int edgenum = AddEdge(se); + AddEdgePP(ap1,edgenum); + AddEdgePP(ap2,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)), ap1, ap2); + if (IsEdge(ap1,ap2)) {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& trigs) +{ + int acttrig = starttrig; + trigs.SetAllocSize(trigsperpoint.EntrySize(p)); + trigs.SetSize(0); + trigs.Append(acttrig); + int i, j, t, ap1, ap2, locindex1(0), locindex2(0); + + //(*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, ap1, ap2); + if (ap2 == p) {Swap(ap1,ap2);} + if (ap1 != p) {PrintSysError("In GetSortedTrianglesAroundPoint!!!");} + + for (j = 1; j <= 3; j++) + { + if (at.PNum(j) == ap1) {locindex1 = j;}; + if (at.PNum(j) == ap2) {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; + + double maxerr0, maxerr; + + for (i = 1; i <= GetNP(); 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/libsrc/stlgeom/stlgeom.hpp b/libsrc/stlgeom/stlgeom.hpp new file mode 100644 index 00000000..198804aa --- /dev/null +++ b/libsrc/stlgeom/stlgeom.hpp @@ -0,0 +1,450 @@ +#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 +#include + + + +namespace netgen +{ + extern int IsInArray(int n, const ARRAY& ia); + extern int AddIfNotExists(ARRAY& list, int x); + + +#include "stltopology.hpp" +#include "stltool.hpp" +#include "stlline.hpp" + + + + + + + + class STLEdgeDataList + { + ARRAY 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& line); + void BuildClusterWithEdge(int ep1, int ep2, ARRAY& line); + + int GetNEPPStat(int p, int status) const; + int GetNConfCandEPP(int p) const; + }; + + + + + + + class STLGeometry : public STLTopology + { + // edges to be meshed: + ARRAY edges; + //edges per point + TABLE edgesperpoint; + + // line: a connection of edges + ARRAY lines; + ARRAY lineendpoints; //per geometrypoint, 1 = is endpoint; 0 = no endpoint, + + ARRAY normals; //normals belong to points! + + ARRAY externaledges; + + int undoexternaledges; + ARRAY storedexternaledges; + + STLEdgeDataList * edgedata; + // STLEdgeDataList edgedata_store; + int calcedgedataanglesnew; + + int edgedatastored; + + + + int facecnt; + //meshpoint is only set, if an edge is at this point!!! + + ARRAY vicinity; //is one, if a triangle belongs to vicinity (eg. of selecttrig) + ARRAY markedtrigs; //is one, if a triangle belongs to marked triangles (calcdirtystrigs) + ARRAY markedsegs; //every pointpair is a segment!!! + ARRAY selectedmultiedge; + + + //spiralpoints: + ARRAY spiralpoints; + // + ARRAY atlas; + //marks all already charted trigs with chartnumber + ARRAY chartmark; + //outerchartspertrig, ascending sorted + TABLE outerchartspertrig; + + + //for meshing and project: + ARRAY meshcharttrigs; //per trig: 1=belong to chart, 0 not + int meshchart; + + ARRAY ha_points; // help array, np long, filled with 0 + + + // sharp geometric edges not declared as edges + // (not considered for spiral check) + INDEX_2_HASHTABLE * 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 meshlines; + ARRAY 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& SelectedMultiEdge() {return selectedmultiedge;} + twoint GetNearestSelectedDefinedEdge(); + void BuildSelectedMultiEdge(twoint ep); + void BuildSelectedEdge(twoint ep); + void BuildSelectedCluster(twoint ep); + + void ImportEdges(); + void AddEdges(const ARRAY >& 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> & ap1, const Point<3> & ap2) + { + markedsegs.Append(ap1);markedsegs.Append(ap2); + } + + void GetMarkedSeg(int i, Point<3> & ap1, Point<3> & ap2) + { + ap1=markedsegs.Get(i*2-1); + ap2=markedsegs.Get(i*2); + } + int GetNMarkedSegs() {return markedsegs.Size()/2;} + void CalcVicinity(int starttrig); + void GetVicinity(int starttrig, int size, ARRAY& 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 & 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& outercharttrigs, + ARRAY& chartpointchecked, ARRAY& 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& 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& limes, int chartnum); + + //FOR MESHING + int GetMeshChartNr () { return meshchart; } + void GetMeshChartBoundary (ARRAY & points, + ARRAY & points3d, + ARRAY & 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& 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/libsrc/stlgeom/stlgeomchart.cpp b/libsrc/stlgeom/stlgeomchart.cpp new file mode 100644 index 00000000..d075067d --- /dev/null +++ b/libsrc/stlgeom/stlgeomchart.cpp @@ -0,0 +1,798 @@ +//20.11.1999 third part of stlgeom.cc, functions with chart and atlas + +#include + +#include +#include +#include + +#include + +#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; + + 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 outermark(GetNT()); //marks all trigs form actual outer region + ARRAY outertested(GetNT()); //marks tested trigs for outer region + ARRAY pointstochart(GetNP()); //point in chart becomes chartnum + ARRAY innerpointstochart(GetNP()); //point in chart becomes chartnum + ARRAY chartpoints; //point in chart becomes chartnum + ARRAY innerchartpoints; + ARRAY dirtycharttrigs; + ARRAY chartpointchecked; + + ARRAY 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 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++) + { + //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 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); + mesh.SetMinimalH(mparam.minh); + + + 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& 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& limes, int chartnum) +{ + int j, k; + + int t, nt, np1, np2; + + 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& outercharttrigs, + ARRAY& chartpointchecked, + ARRAY& 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 ap1, ap2, tn1, tn2, l, problem, pn; + ARRAY 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; + + 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, ap1, ap2); + if (IsEdge(ap1,ap2)) 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, ap1, ap2); + if (IsEdge(ap1,ap2)) 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/libsrc/stlgeom/stlgeommesh.cpp b/libsrc/stlgeom/stlgeommesh.cpp new file mode 100644 index 00000000..2742a924 --- /dev/null +++ b/libsrc/stlgeom/stlgeommesh.cpp @@ -0,0 +1,1590 @@ +//20.11.1999 second part of stlgeom.cc, mainly mesh functions + +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ +int EdgeUsed(int p1, int p2, ARRAY& edges, INDEX_2_HASHTABLE& 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> & ap1, int t1, + const Point<3> & ap2, int t2) +{ + //funktioniert nicht in allen Fällen! + + PrintWarning("Point between"); + + + ClearMarkedSegs(); + + InitMarkedTrigs(); + SetMarkedTrig(t1,1); + SetMarkedTrig(t2,1); + + TABLE edgepoints; + TABLE edgepointdists; + TABLE edgepointorigines; + TABLE edgepointoriginps; + + ARRAY edgetrigs; + ARRAY edgepointnums; + ARRAY edgetriglocinds; + + int size = 3*GetNT(); + INDEX_2_HASHTABLE 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 edgelist1; + ARRAY 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(ap1,pbtw); + + edgepoints.Add1(edgecnt,pbtw); + edgepointdists.Add1(edgecnt,Dist(pbtw,ap1)); + edgepointorigines.Add1(edgecnt,0); + edgepointoriginps.Add1(edgecnt,0); + } + } + + int finished = 0; + int endpointorigine = 0; + int endpointoriginp = 0; + double endpointmindist = 1E50; + + 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; + 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(0); + for (m = 1; m <= divisions; m++) + { + const Point3d& p = edgepoints.Get(en,m); + if (Dist(ap2,p) + edgepointdists.Get(en,m) < mindist) + {mindist = Dist(ap2,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 plist; + + plist.Append(ap2); + 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(ap1); + + 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(ap1,ap2);} + + 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 & apoints, + ARRAY & points3d, + ARRAY & alines, double h) +{ + int i, j; + twoint seg, newseg; + int zone; + 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); + apoints.Append (p2d); + + lpi = apoints.Size(); + ha_points.Elem(pi) = lpi; + } + else + lpi = ha_points.Get(pi); + + i2.I(j) = lpi; + } + alines.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; + + ARRAY 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; + while (*htrigs) + { + if (TrigIsInOC (*htrigs, meshchart)) + { + foundinchart = 1; + break; + } + htrigs++; + } + } + + else + { + ARRAY trigsinbox; + + if (!geomsearchtreeon) + { + //alter chart-tree + Box<3> box(locpoint, locpoint); + box.Increase (range); + chart.GetTrianglesInBox (box.PMin(), box.PMax(), trigsinbox); + } + else + { + ARRAY 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; + 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; + 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 ap1,ap2,p3,p4; + Point<3> p1p, p2p, p3p, p4p; + Vec<3> n, ntn; + double rzyl, 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 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,ap1,ap2,p3); + + //checken, ob ap1-ap2 eine Kante sind + if (IsEdge(ap1,ap2)) continue; + + p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - ap1 - ap2; + + p1p = GetPoint(ap1); p2p = GetPoint(ap2); + 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(ap1) = min2(minh.Elem(ap1),localh); + minh.Elem(ap2) = min2(minh.Elem(ap2),localh); + } + + mesh.RestrictLocalHLine(p1p, p2p, localh); + } + + } + } + PrintMessage(5, "done\nATLAS H: nmin local h=", mincalch); + PrintMessage(5, "ATLAS H: max local h=", maxcalch); + PrintMessage(5, "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 ap1,ap2,p3,p4; + Point3d p1p, p2p, p3p, p4p; + Vec3d n, ntn; + double rzyl, 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 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,ap1,ap2,p3); + + //checken, ob ap1-ap2 eine Kante sind + if (IsEdge(ap1,ap2)) continue; + + p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - ap1 - ap2; + + p1p = GetPoint(ap1); p2p = GetPoint(ap2); + 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(ap1) = min2(minh.Elem(ap1),localh); + minh.Elem(ap2) = min2(minh.Elem(ap2),localh); + } + + //if (localh < 0.2) {localh = 0.2;} + + if(localh < objectsize) + mesh.RestrictLocalHLine(p1p, p2p, localh); + (*testout) << "restrict h along " << p1p << " - " << p2p << " to " << localh << endl; + + 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; + double mindist = 1E50; + + PrintMessage(7,"build search tree..."); + Box3dTree* lsearchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1), + GetBoundingBox().PMax() + Vec3d(1,1,1)); + + ARRAY pmins(GetNLines()); + ARRAY 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); + + lsearchtree->Insert (box.PMin(), box.PMax(), i); + pmins.Elem(i) = box.PMin(); + pmaxs.Elem(i) = box.PMax(); + } + + ARRAY linenums; + int k2; + + for (i = 1; i <= GetNLines(); i++) + { + SetThreadPercent((double)i/(double)GetNLines()*100.); + if (multithread.terminate) + {PopStatus(); return;} + + linenums.SetSize(0); + lsearchtree->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 lp1, lp2; + Vec3d v1,v2; + mincalch = 1E50; + 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 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& pp1 = GetPoint(GetLine(i)->StartP()); + const Point3d& pp2 = GetPoint(GetLine(i)->EndP()); + + if (l != 0) + { + minhl = min2(minhl,l*linefact); + + mesh.RestrictLocalH(pp1, l*linefact); + mesh.RestrictLocalH(pp2, l*linefact); + } + } + PopStatus(); + PrintMessage(5, "minh due to line length=", minhl); + } +} + +void STLGeometry :: RestrictHChartDistOneChart(int chartnum, ARRAY& 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 limes1; + ARRAY limes2; + + ARRAY plimes1; + ARRAY plimes2; + + ARRAY plimes1trigs; //check from wich trig the points come + ARRAY plimes2trigs; + + ARRAY 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 foundpts; + + for (j = 1; j <= plimes1.Size(); j++) + { + double mindist = 1E50; + double dist; + + const Point3d & ap1 = plimes1.Get(j); + double boxs = mesh.GetH (plimes1.Get(j)) * limessafety; + + Point3d pmin = ap1 - Vec3d (boxs, boxs, boxs); + Point3d pmax = ap1 + 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 & ap1 = plimes1.Get(j); + double his = mesh.GetH (plimes1.Get(j)); + + double xmin = ap1.X() - his * limessafety; + double xmax = ap1.X() + his * limessafety; + double ymin = ap1.Y() - his * limessafety; + double ymax = ap1.Y() + his * limessafety; + double zmin = ap1.Z() - his * limessafety; + double zmax = ap1.Z() + his * limessafety; + + for (k = 1; k <= plimes2.Size(); k++) + { + const Point3d & ap2 = plimes2.Get(k); + if (ap2.X() >= xmin && ap2.X() <= xmax && + ap2.Y() >= ymin && ap2.Y() <= ymax && + ap2.Z() >= zmin && ap2.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/libsrc/stlgeom/stlline.cpp b/libsrc/stlgeom/stlline.cpp new file mode 100644 index 00000000..f141fda3 --- /dev/null +++ b/libsrc/stlgeom/stlline.cpp @@ -0,0 +1,780 @@ +#include + +#include +#include +#include + +#include + +#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& 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& line) +{ + int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); + + int found, pstart, p(0), en, pnew(0), ennew(0); + 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& 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& line) +{ + int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); + + int p(0), en; + int j, i, k; + int oldend; + int newend = 1; + int pnew, ennew(0); + + 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 >& ap, int nr) const +{ + return Dist(ap.Get(PNum(nr)),ap.Get(PNum(nr+1))); +} + +double STLLine :: GetLength(const ARRAY >& 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 > & 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 >& 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 >& ap, + ARRAY& 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 inthi(GetNS()*nph); + ARRAY 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/libsrc/stlgeom/stlline.hpp b/libsrc/stlgeom/stlline.hpp new file mode 100644 index 00000000..70393ca0 --- /dev/null +++ b/libsrc/stlgeom/stlline.hpp @@ -0,0 +1,188 @@ +#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 hashtab; + ARRAY edgedata; + TABLE 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& 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 pts; + ARRAY lefttrigs; + ARRAY righttrigs; + ARRAY 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 >& 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 > & 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 >& 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 >& ap, double dist, int& index) const; + + //return a meshed polyline + STLLine* Mesh(const ARRAY >& ap, + ARRAY& mp, double ghi, + class Mesh& mesh) const; + + void DoSplit() {split = 1;} + int ShouldSplit() const {return split;} +}; + +#endif diff --git a/libsrc/stlgeom/stltool.cpp b/libsrc/stlgeom/stltool.cpp new file mode 100644 index 00000000..921fddd5 --- /dev/null +++ b/libsrc/stlgeom/stltool.cpp @@ -0,0 +1,1288 @@ +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ + + +//add a point into a pointlist, return pointnumber +int AddPointIfNotExists(ARRAY& 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 >& 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 >& 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 >& 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 >& 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 >& 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 >& 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 >& 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 > & 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 >& 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 (0,0); + outertrigs = new ARRAY (0,0); + ilimit = new ARRAY (0,0); + olimit = new ARRAY (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 & 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& 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& 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 > & 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 >& points, double eps) +{ + + if (usechartnormal) + return TestSegChartNV (p1, p2, sn); + + // for statistics + { + int i; + static ARRAY 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 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/libsrc/stlgeom/stltool.hpp b/libsrc/stlgeom/stltool.hpp new file mode 100644 index 00000000..278a7ce4 --- /dev/null +++ b/libsrc/stlgeom/stltool.hpp @@ -0,0 +1,271 @@ +#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& 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 * ARRAYINTPTR; + +class STLGeometry; + +class STLChart +{ +private: + STLGeometry * geometry; + ARRAY* charttrigs; // trigs which only belong to this chart + ARRAY* outertrigs; // trigs which belong to other charts + Box3dTree * searchtree; // ADT containing outer trigs + + ARRAY* olimit; //outer limit of outer chart + ARRAY* 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 & 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& trigs); + void DelChartTrigs(const ARRAY& 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 > & 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 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 >& 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/libsrc/stlgeom/stltopology.cpp b/libsrc/stlgeom/stltopology.cpp new file mode 100644 index 00000000..53deb52e --- /dev/null +++ b/libsrc/stlgeom/stltopology.cpp @@ -0,0 +1,1067 @@ +#include + +#include +#include +#include + +#include + +#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 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 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 > 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) +{ + size_t i; + STLGeometry * geom = new STLGeometry(); + + ARRAY 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; + + size_t 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 & readtrigs) +{ + int i, 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 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 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 * oldedges = ht_topedges; + ht_topedges = new INDEX_2_HASHTABLE (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(0); + 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 & btrias) const +{ + if (searchtree) + + searchtree -> GetIntersecting (box.PMin(), box.PMax(), btrias); + + else + { + int i; + Box<3> box1 = box; + box1.Increase (1e-4); + + btrias.SetSize(0); + + int nt = GetNT(); + for (i = 1; i <= nt; i++) + { + if (box1.Intersect (GetTriangle(i).box)) + { + btrias.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 oriented; + oriented.SetSize(GetNT()); + int i; + for (i = 1; i <= oriented.Size(); i++) + { + oriented.Elem(i) = 0; + } + + oriented.Elem(starttrig) = 1; + + int k; + + ARRAY list1; + list1.SetSize(0); + ARRAY 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/libsrc/stlgeom/stltopology.hpp b/libsrc/stlgeom/stltopology.hpp new file mode 100644 index 00000000..80e5a681 --- /dev/null +++ b/libsrc/stlgeom/stltopology.hpp @@ -0,0 +1,362 @@ +#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 >& 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 >& ap, + const Vec<3> & n, Point<3> & pp) const; + //project with the triangle's normal vector in plane + void ProjectInPlain(const ARRAY > & 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 >& ap, + const Vec<3> & nproj, + Point<3> & pp, Vec<3> & lam) const; + + int PointInside(const ARRAY >& ap, const Point<3> & pp) const; + + //get nearest point on triangle and distance to it + double GetNearestPoint(const ARRAY >& ap, + Point<3> & p3d) const; + + double Area(const ARRAY >& ap) const; + + double MinHeight(const ARRAY >& ap) const; + double MaxLength(const ARRAY >& 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 trias; + ARRAY topedges; + ARRAY > points; + + // mapping of sorted pair of points to topedge + INDEX_2_HASHTABLE * ht_topedges; + // mapping of node to trigs + TABLE trigsperpoint; + // mapping of node to edges + TABLE 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 & readtrigs); + + virtual void TopologyChanged() {}; //do some things, if topology changed! + + /// Generate topology tables + void FindNeighbourTrigs(); + + + void GetTrianglesInBox (const Box<3> & box, + ARRAY & 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 >& 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 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/libsrc/visualization/Makefile.am b/libsrc/visualization/Makefile.am new file mode 100644 index 00000000..ca492a2c --- /dev/null +++ b/libsrc/visualization/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libvisual.a +libvisual_a_SOURCES = meshdoc.cpp mvdraw.cpp stlmeshing.cpp vscsg.cpp \ + vsfieldlines.cpp vsmesh.cpp vsocc.cpp vssolution.cpp +AM_CXXFLAGS = -DOPENGL diff --git a/libsrc/visualization/Makefile.in b/libsrc/visualization/Makefile.in new file mode 100644 index 00000000..d7072be3 --- /dev/null +++ b/libsrc/visualization/Makefile.in @@ -0,0 +1,451 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = libsrc/visualization +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libvisual_a_AR = $(AR) $(ARFLAGS) +libvisual_a_LIBADD = +am_libvisual_a_OBJECTS = meshdoc.$(OBJEXT) mvdraw.$(OBJEXT) \ + stlmeshing.$(OBJEXT) vscsg.$(OBJEXT) vsfieldlines.$(OBJEXT) \ + vsmesh.$(OBJEXT) vsocc.$(OBJEXT) vssolution.$(OBJEXT) +libvisual_a_OBJECTS = $(am_libvisual_a_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libvisual_a_SOURCES) +DIST_SOURCES = $(libvisual_a_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LIBRARIES = libvisual.a +libvisual_a_SOURCES = meshdoc.cpp mvdraw.cpp stlmeshing.cpp vscsg.cpp \ + vsfieldlines.cpp vsmesh.cpp vsocc.cpp vssolution.cpp + +AM_CXXFLAGS = -DOPENGL +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libsrc/visualization/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu libsrc/visualization/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libvisual.a: $(libvisual_a_OBJECTS) $(libvisual_a_DEPENDENCIES) + -rm -f libvisual.a + $(libvisual_a_AR) libvisual.a $(libvisual_a_OBJECTS) $(libvisual_a_LIBADD) + $(RANLIB) libvisual.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshdoc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mvdraw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlmeshing.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vscsg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsfieldlines.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsmesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsocc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vssolution.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libsrc/visualization/meshdoc.cpp b/libsrc/visualization/meshdoc.cpp new file mode 100644 index 00000000..defc39b3 --- /dev/null +++ b/libsrc/visualization/meshdoc.cpp @@ -0,0 +1,620 @@ +#ifndef NOTCL + +#include + +#include + +#include "incvis.hpp" + + + +namespace netgen +{ +#include "mvdraw.hpp" +#include "meshdoc.hpp" + + +MeshDoctorParameters meshdoctor; +VisualSceneMeshDoctor vsmeshdoc; + +extern AutoPtr 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); +} +} + + +#endif // NOTCL diff --git a/libsrc/visualization/meshdoc.hpp b/libsrc/visualization/meshdoc.hpp new file mode 100644 index 00000000..5cc11aef --- /dev/null +++ b/libsrc/visualization/meshdoc.hpp @@ -0,0 +1,37 @@ + +class VisualSceneMeshDoctor : public VisualScene +{ + int filledlist; + int outlinelist; + int edgelist; + + int selelement, locpi; + int selpoint, selpoint2; + + // for edgemarking: + ARRAY 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/libsrc/visualization/mvdraw.cpp b/libsrc/visualization/mvdraw.cpp new file mode 100644 index 00000000..e4b33e2d --- /dev/null +++ b/libsrc/visualization/mvdraw.cpp @@ -0,0 +1,1464 @@ +#include +#include +#include +#include +#include +#include + +#include "incvis.hpp" + +#include +#include + + + +#ifndef WIN32 + +#define GLX_GLXEXT_LEGACY + +#include +#include +#include /* for XA_RGB_DEFAULT_MAP atom */ +#include +#endif + + + + + +namespace netgen +{ + 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]; + + int VisualScene :: selface; + int VisualScene :: selelement; + int VisualScene :: selpoint; + int VisualScene :: selpoint2; + int VisualScene :: locpi; + int VisualScene :: seledge; + + int VisualScene :: selecttimestamp; + + + 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 geometry2d; + extern AutoPtr mesh; + extern ARRAY specpoints; + extern ARRAY > boxes; + + 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 & alpha, const ARRAY & vec) + { + glPushMatrix(); + + glLoadIdentity(); + + for(int i=0; i a(1); a[0] = alpha; + ARRAY 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.99; // 0.95; + GLdouble pvx2 = deltax, pvy2 = -deltay, pvz2 = 0.99; // 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); + + // cout << "deltay = " << deltay << endl; + // cout << "float_bug = " << (float(deltay)/100) << endl; gives wrong result with icc 9.0.021 + glScaled (exp (double (-deltay)/100), + exp (double (-deltay)/100), + exp (double (-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 val, double valmin, double valmax, + int logscale) + { + double value; + + if (!logscale) + value = (val - valmin) / (valmax - valmin); + else + { + if (valmax <= 0) valmax = 1; + if (valmin <= 0) valmin = 1e-4 * valmax; + value = (log(fabs(val)) - log(valmin)) / (log(valmax) - log(valmin)); + } + + if (!invcolor) + value = 1 - value; + + glTexCoord1f ( 0.998 * value + 0.001); + // glTexCoord1f ( val ); + + glTexCoord2f ( 0.998 * value + 0.001, 1.5); + // 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 (linear) ncols = 32; + else ncols = 8; + + + if (ntexcols != ncols) + { + ntexcols = ncols; + + GLubyte colortexture[4*32]; + + 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]; + + if(r > 1e-3) + for (int j = 0; j < 3; j++) + col[j] = (1.-r) * colp[iv][j] + r * colp[iv+1][j]; + else + for (int j = 0; j < 3; j++) + col[j] = colp[iv][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); + + glTexImage1D (GL_TEXTURE_1D, 0, 4, ncols, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture); + glTexImage2D (GL_TEXTURE_2D, 0, 4, ncols, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture); + + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, typ); // DECAL or MODULATE + + GLfloat bcol[] = { 1, 1, 1, 1.0 }; + glTexParameterfv (GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR, bcol); + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + + glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bcol); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + if (linear) + { + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, 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); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, 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; + + glDisable (GL_LIGHTING); + 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); + 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 (GLsizei(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); + + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + GLfloat textcol[3] = { 1 - backcolor, + 1 - backcolor, + 1 - backcolor }; + glColor3fv (textcol); + + glLineWidth (1.0f); + + double len = 1; + + glBegin(GL_LINES); + glVertex3d (0, 0, 0); + glVertex3d (len, 0, 0); + glVertex3d (0.0f, 0.0f, 0.0f); + glVertex3d (0.0f, len, 0.0f); + glVertex3d (0.0f, 0.0f, 0.0f); + glVertex3d (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 (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + glRasterPos3d (0.0f, len, 0.0f); + sprintf (buf, "y"); + glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + glRasterPos3d (0.0f, 0.0f, len); + sprintf (buf, "z"); + glCallLists (GLsizei(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[] = "Netgen 4.5"; + + glRasterPos3d (0.0f, 0.0f, 0.0f); + glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + + glPopAttrib (); + + glEnable (GL_LIGHTING); + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + glEnable (GL_DEPTH_TEST); + } + + + + + + + +#ifdef PARALLELGL + void VisualScene :: InitParallelGL () + { + static int init = 0; + + if (!init) + { + init = 1; + + if (id == 0) + { + string displname; + + Display * dpy = glXGetCurrentDisplay(); + GLXDrawable drawable = glXGetCurrentDrawable(); + GLXContext ctx = glXGetCurrentContext(); + GLXContextID xid = glXGetContextIDEXT (ctx); + + displname = XDisplayName (0); + + cout << "Init Parallel GL" << endl; + cout << "DisplayName = " << displname << endl; + cout << "current display = " << dpy << endl; + cout << "current drawable = " << drawable << endl; + cout << "current context = " << ctx << endl; + + cout << "contextid = " << xid << endl; + cout << "isdirect = " << glXIsDirect ( dpy, ctx ) << endl; + cout << "extensionstring = " << glXQueryExtensionsString( dpy, 0 ) << endl; + + ARRAY request(ntasks); + MPI_Status status; + for ( int dest = 1; dest < ntasks; dest++ ) + { + MyMPI_Send ("redraw", dest); + MyMPI_Send ("init", dest); + + MyMPI_Send (displname, dest); + MyMPI_Send (int (drawable), dest); + MyMPI_Send (int (xid), dest); + + int hi; + MPI_Irecv( &hi, 1, MPI_INT, dest, MPI_ANY_TAG, MPI_COMM_WORLD, &request[dest]); + // MyMPI_IRecv (hi, dest, request[dest]); + } + for ( int dest = 1; dest < ntasks; dest++ ) + { + MPI_Wait(&request[dest], &status); + } + } + } + } + + + void VisualScene :: Broadcast () + { + if (ntasks == 1) return; + + if (id == 0) + { + for (int dest = 1; dest < ntasks; dest++) + { + MyMPI_Send ("redraw", dest); + MyMPI_Send ("broadcast", dest); + } + } + + MyMPI_Bcast (selface); + + vssolution.Broadcast (); + } +#endif + + + + + + + /* *********************** 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 > 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] ); + glVertex3dv ( (*mesh)[seg.p2] ); + // glVertex3dv ( &(*mesh)[seg.p1].X() ); + // glVertex3dv ( &(*mesh)[seg.p2].X() ); + } + glEnd(); + } + + glColor3d (1, 0, 0); + glBegin (GL_LINES); + for (int i = 0; i < boxes.Size(); i++) + { + glVertex3dv ( boxes[i].PMin() ); + glVertex3dv ( boxes[i].PMax() ); + } + 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 (GLsizei(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 (GLsizei(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/libsrc/visualization/mvdraw.hpp b/libsrc/visualization/mvdraw.hpp new file mode 100644 index 00000000..1db51d0a --- /dev/null +++ b/libsrc/visualization/mvdraw.hpp @@ -0,0 +1,327 @@ +#ifndef FILE_MVDRAW +#define FILE_MVDRAW + +#include "vispar.hpp" + + + + + +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; + + static int selface; + static int selelement; + static int selpoint; + static int selpoint2; + static int locpi; + static int seledge; + + static int selecttimestamp; + +public: + static GLuint fontbase; + // static Tcl_Obj* fontbase; // Togl 2.0 + + // 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 & alpha, const ARRAY & 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); + + +#ifdef PARALLELGL + void InitParallelGL (); + void Broadcast (); +#endif +}; + + +class VisualSceneGeometry : public VisualScene +{ + ARRAY 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 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 trilists; + ARRAY 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 gllists; + +public: + VisualSceneSTEPGeometry (); + virtual ~VisualSceneSTEPGeometry (); + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); +}; +#endif + + +class VisualSceneSTLMeshing : public VisualScene +{ + ARRAY 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 edgelist; + int pointnumberlist; + + int tetlist; + int prismlist; + int pyramidlist; + int hexlist; + + int badellist; + int identifiedlist; + int domainsurflist; + + int vstimestamp;//, selecttimestamp; + int filledtimestamp; + int linetimestamp; + int edgetimestamp; + int pointnumbertimestamp; + + int tettimestamp; + int prismtimestamp; + int pyramidtimestamp; + int hextimestamp; + + int badeltimestamp; + int identifiedtimestamp; + int domainsurftimestamp; + + +#ifdef PARALLELGL + ARRAY par_linelists; + ARRAY par_filledlists; +#endif + + + 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; } + void BuildFilledList(); + // private: + void BuildLineList(); + void BuildEdgeList(); + 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); + + +void MouseDblClickSelect (const int px, const int py, + const GLdouble * clipplane, const GLdouble backcolor, + const float * transformationmat, + const Point3d & center, + const double rad, + const int displaylist, + int & selelement, int & selface, int & seledge, int & selpoint, + int & selpoint2, int & locpi); + +#endif + diff --git a/libsrc/visualization/soldata.hpp b/libsrc/visualization/soldata.hpp new file mode 100644 index 00000000..41c3fcc7 --- /dev/null +++ b/libsrc/visualization/soldata.hpp @@ -0,0 +1,58 @@ +#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 GetValue (int selnr, + const double xref[], const double x[], const double dxdxref[], + double * values) + { return GetValue (selnr, xref[0], xref[1], xref[2], values); } + + + virtual bool GetSurfValue (int /* selnr */, + double /* lam1 */, double /* lam2 */, + double * /* values */) + { return false; } + + + virtual bool GetSurfValue (int selnr, + const double xref[], const double x[], const double dxdxref[], + double * values) + { return GetSurfValue (selnr, xref[0], xref[1], values); } + + + void SetMultiDimComponent (int mc) + { multidimcomponent = mc; } +}; + + +#endif + diff --git a/libsrc/visualization/stlmeshing.cpp b/libsrc/visualization/stlmeshing.cpp new file mode 100644 index 00000000..e2d149ff --- /dev/null +++ b/libsrc/visualization/stlmeshing.cpp @@ -0,0 +1,1076 @@ +#include +#include + +#include +#include + +#include +#ifndef NOTCL +#include +#endif + +namespace netgen +{ + +/* +//mmm +#include "stlgeom/modeller.hpp" +*/ + +/* *********************** Draw STL Geometry **************** */ + +extern STLGeometry * stlgeometry; +extern AutoPtr 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 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& 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/libsrc/visualization/vispar.hpp b/libsrc/visualization/vispar.hpp new file mode 100644 index 00000000..50484c46 --- /dev/null +++ b/libsrc/visualization/vispar.hpp @@ -0,0 +1,102 @@ +#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 clipdomain; + int donotclipdomain; + + 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; + + // ACIS + + bool ACISshowfaces; + bool ACISshowedges; + int ACISshowsolidnr; + int ACISshowsolidnr2; + + bool whitebackground; + int stereo; + bool usedispllists; + bool drawcoordinatecross; + bool drawcolorbar; + bool drawnetgenlogo; + + bool use_center_coords; + double centerx,centery,centerz; + + bool drawspecpoint; + double specpointx,specpointy,specpointz; + + +public: + VisualizationParameters(); +}; +extern VisualizationParameters vispar; + +#endif diff --git a/libsrc/visualization/visual.hpp b/libsrc/visualization/visual.hpp new file mode 100644 index 00000000..27dbfe6c --- /dev/null +++ b/libsrc/visualization/visual.hpp @@ -0,0 +1,26 @@ +#ifndef FILE_VISUAL +#define FILE_VISUAL + +/* *************************************************************************/ +/* File: visual.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 02. Dec. 01 */ +/* *************************************************************************/ + +/* + +Visualization + +*/ + +#include "../include/incvis.hpp" + +namespace netgen +{ +#include "mvdraw.hpp" +#include "soldata.hpp" +#include "vssolution.hpp" +#include "meshdoc.hpp" +} + +#endif diff --git a/libsrc/visualization/vscsg.cpp b/libsrc/visualization/vscsg.cpp new file mode 100644 index 00000000..4d84d202 --- /dev/null +++ b/libsrc/visualization/vscsg.cpp @@ -0,0 +1,265 @@ +#ifndef NOTCL + +#include +#include "incvis.hpp" + +#include +#include +#include +#include + + +namespace netgen +{ +#include "mvdraw.hpp" + +/* *********************** Draw Geometry **************** */ + + + + +extern AutoPtr 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); + + + + /* + glFlush(); + + int err; + do + { + err = glGetError(); + // cout << "glerr,1 = " << err << endl; + } + while (err != GL_NO_ERROR); + + + // CreateTexture (0, 1, GL_DECAL); + CreateTexture (0, 1, GL_MODULATE); + glEnable (GL_TEXTURE_1D); + + float mat_col[] = { 1.0, 1.0, 1.0 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glDisable (GL_BLEND); + glDisable (GL_COLOR_MATERIAL); + glEnable (GL_NORMALIZE); + + if (geometry->GetNTopLevelObjects()) + { + cout << "call list" << endl; + glCallList (trilists[0]); + } + + glColor3d (1.0, 1.0, 1.0); + + glBegin (GL_TRIANGLES); + glNormal3f (0, 0, 1); + SetOpenGlColor (-1.0, 0, 1, 0); + glVertex3f (0.0, 0.0, 0.0); + SetOpenGlColor (0.5, 0, 1, 0); + glNormal3f (0, 0, 1); + glVertex3f (1.0, 0.0, 0.0); + SetOpenGlColor (2.0, 0, 1, 0); + glNormal3f (0, 0, 1); + glVertex3f (0.0, 1.0, 0.0); + + glEnd (); + + cout << "trig drawn" << endl; + + glDisable (GL_TEXTURE_1D); + glDisable (GL_COLOR_MATERIAL); + glFlush(); + + cout << "glerr,2 = " << glGetError() << endl; + */ + + + + DrawCoordinateCross (); + DrawNetgenLogo (); + + glFinish(); +} + + +void VisualSceneGeometry :: BuildScene (int zoomall) +{ + Box<3> box; + int hasp = 0; + for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const TriangleApproximation & ta = + *geometry->GetTriApprox(i); + if (!&ta) continue; + + for (int 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 (int i = 0; i < trilists.Size(); i++) + glDeleteLists (trilists[i], 1); + trilists.SetSize(0); + + for (int 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 (int j = 0; j < ta.GetNT(); j++) + { + + for (int 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 (); + } + +} + + + + + +} + + +#endif // NOTCL diff --git a/libsrc/visualization/vsfieldlines.cpp b/libsrc/visualization/vsfieldlines.cpp new file mode 100644 index 00000000..161ad082 --- /dev/null +++ b/libsrc/visualization/vsfieldlines.cpp @@ -0,0 +1,722 @@ +#ifndef NOTCL + +#include +#include "incvis.hpp" + + +#include +#include +#include +#include + +#include + + +namespace netgen +{ + + extern AutoPtr mesh; + + + + RKStepper :: ~RKStepper() + { + delete a; + } + + RKStepper :: RKStepper(int type) : a(NULL), tolerance(1e100) + { + notrestarted = 0; + + if (type == 0) // explicit Euler + { + c.SetSize(1); c[0] = 0; + b.SetSize(1); b[0] = 1; + steps = order = 1; + } + else if (type == 1) // Euler-Cauchy + { + c.SetSize(2); c[0] = 0; c[1] = 0.5; + b.SetSize(2); b[0] = 0; b[1] = 1; + ARRAY size(2); + size[0] = 0; size[1] = 1; + a = new TABLE(size); + a->Set(2,1,0.5); // Set, Get: 1-based! + steps = order = 2; + } + else if (type == 2) // Simpson + { + c.SetSize(3); c[0] = 0; c[1] = 1; c[2] = 0.5; + b.SetSize(3); b[0] = b[1] = 1./6.; b[2] = 2./3.; + ARRAY size(3); + size[0] = 0; size[1] = 1; size[2] = 2; + a = new TABLE(size); + a->Set(2,1,1); + a->Set(3,1,0.25); a->Set(3,2,0.25); + steps = order = 3; + } + else if (type == 3) // classical Runge-Kutta + { + c.SetSize(4); c[0] = 0; c[1] = c[2] = 0.5; c[3] = 1; + b.SetSize(4); b[0] = b[3] = 1./6.; b[1] = b[2] = 1./3.; + ARRAY size(4); + size[0] = 0; size[1] = 1; size[2] = 2; size[3] = 3; + a = new TABLE(size); + a->Set(2,1,0.5); + a->Set(3,1,0); a->Set(3,2,0.5); + a->Set(4,1,0); a->Set(4,2,0); a->Set(4,3,1); + steps = order = 4; + } + + K.SetSize(steps); + } + + void RKStepper :: StartNextValCalc(const Point3d & astartval, const double astartt, const double ah, const bool aadaptive) + { + //cout << "Starting RK-Step with h=" << ah << endl; + + stepcount = 0; + h = ah; + startt = astartt; + startval = astartval; + adaptive = aadaptive; + adrun = 0; + } + + bool RKStepper :: GetNextData(Point3d & val, double & t, double & ah) + { + bool finished(false); + + + //cout << "stepcount " << stepcount << endl; + + if(stepcount <= steps) + { + t = startt + c[stepcount-1]*h; + val = startval; + for(int i=0; iGet(stepcount,i+1) * K[i]; + } + + + if(stepcount == steps) + { + val = startval; + for(int i=0; i 1.3) fac = 1.3; + + if(fac < 1 || notrestarted >= 2) + ah = 2.*h * fac; + + if(err < tolerance) + { + finished = true; + notrestarted++; + //(*testout) << "finished RK-Step, new h=" << ah << " tolerance " << tolerance << " err " << err << endl; + } + else + { + //ah *= 0.9; + notrestarted = 0; + //(*testout) << "restarting h " << 2.*h << " ah " << ah << " tolerance " << tolerance << " err " << err << endl; + StartNextValCalc(startval_bak,startt_bak, ah, adaptive); + } + } + } + else + { + t = startt + h; + finished = true; + } + + } + + if(stepcount == 0) + { + t = startt + c[stepcount]*h; + val = startval; + for(int i=0; iGet(stepcount,i) * K[i]; + } + + return finished; + } + + + bool RKStepper :: FeedNextF(const Vec3d & f) + { + K[stepcount] = f; + stepcount++; + return true; + } + + + + void FieldLineCalc :: GenerateFieldLines(ARRAY & potential_startpoints, const int numlines, const int gllist, + const double minval, const double maxval, const int logscale, double phaser, double phasei) + { + glNewList(gllist, GL_COMPILE); + + + ARRAY points; + ARRAY values; + ARRAY drawelems; + ARRAY dirstart; + + + if(vsol -> iscomplex) + SetPhase(phaser,phasei); + + double crit; + + if(randomized) + { + double sum = 0; + double lami[3]; + double values[6]; + Vec3d v; + + for(int i=0; iiscomplex, phaser, phasei); + + sum += v.Length(); + } + + crit = sum/double(numlines); + } + + + int calculated = 0; + + cout << endl; + + for(int i=0; i= numlines) break; + + Calc(potential_startpoints[i],points,values,drawelems,dirstart); + + bool usable = false; + + for(int j=1; j 0) ? rel_length : 0.5; + maxlength *= 2.*rad; + + thickness = (rel_thickness > 0) ? rel_thickness : 0.0015; + thickness *= 2.*rad; + + double auxtolerance = (rel_tolerance > 0) ? rel_tolerance : 1.5e-3; + auxtolerance *= 2.*rad; + + stepper.SetTolerance(auxtolerance); + + direction = adirection; + + + maxpoints = amaxpoints; + + if(direction == 0) + { + maxlength *= 0.5; + maxpoints /= 2; + } + + + phaser = 1; + phasei = 0; + + critical_value = -1; + + randomized = false; + + } + + + + + void FieldLineCalc :: Calc(const Point3d & startpoint, ARRAY & points, ARRAY & vals, ARRAY & drawelems, ARRAY & dirstart) + { + double lami[3], startlami[3]; + double values[6]; + double dummyt(0); + Vec3d v; + Vec3d startv; + Point3d newp; + double h; + + double startval; + bool startdraw; + bool drawelem; + int elnr; + + for (int i=0; i<6; i++) values[i]=0.0; + for (int i=0; i<3; i++) lami[i]=0.0; + for (int i=0; i<3; i++) startlami[i]=0.0; + + points.SetSize(0); + vals.SetSize(0); + drawelems.SetSize(0); + + dirstart.SetSize(0); + dirstart.Append(0); + + + int startelnr = mesh.GetElementOfPoint(startpoint,startlami,true) - 1; + (*testout) << "p = " << startpoint << "; elnr = " << startelnr << endl; + if (startelnr == -1) + return; + + mesh.SetPointSearchStartElement(startelnr); + + if (mesh.GetDimension()==3) + startdraw = vss.GetValues ( vsol, startelnr, startlami[0], startlami[1], startlami[2], values); + else + startdraw = vss.GetSurfValues ( vsol, startelnr, startlami[0], startlami[1], values); + + VisualSceneSolution::RealVec3d ( values, startv, vsol->iscomplex, phaser, phasei); + + startval = startv.Length(); + + if(critical_value > 0 && fabs(startval) < critical_value) + return; + + //cout << "p = " << startpoint << "; elnr = " << startelnr << endl; + + + + for(int dir = 1; dir >= -1; dir -= 2) + { + if(dir*direction < 0) continue; + + points.Append(startpoint); + vals.Append(startval); + drawelems.Append(startdraw); + + h = 0.001*rad/startval; // otherwise no nice lines; should be made accessible from outside + + v = startv; + if(dir == -1) v *= -1.; + + elnr = startelnr; + lami[0] = startlami[0]; lami[1] = startlami[1]; lami[2] = startlami[2]; + + + for(double length = 0; length < maxlength; length += h*vals.Last()) + { + if(v.Length() < 1e-12*rad) + { + (*testout) << "Current fieldlinecalculation came to a stillstand at " << points.Last() << endl; + break; + } + + stepper.StartNextValCalc(points.Last(),dummyt,h,true); + stepper.FeedNextF(v); + + while(!stepper.GetNextData(newp,dummyt,h) && elnr != -1) + { + elnr = mesh.GetElementOfPoint(newp,lami,true) - 1; + if(elnr != -1) + { + mesh.SetPointSearchStartElement(elnr); + if (mesh.GetDimension()==3) + drawelem = vss.GetValues (vsol, elnr, lami[0], lami[1], lami[2], values); + else + drawelem = vss.GetSurfValues (vsol, elnr, lami[0], lami[1], values); + + VisualSceneSolution::RealVec3d (values, v, vsol->iscomplex, phaser, phasei); + if(dir == -1) v *= -1.; + stepper.FeedNextF(v); + } + } + + if (elnr == -1) + { + //cout << "direction " < 1) + (*testout) << "Points in current fieldline: " << points.Size() << ", current position: " << newp << endl; + + if(maxpoints > 0 && points.Size() >= maxpoints) + { + break; + } + + //cout << "length " << length << " h " << h << " vals.Last() " << vals.Last() << " maxlength " << maxlength << endl; + } + dirstart.Append(points.Size()); + } + } + + + + + + void VisualSceneSolution :: BuildFieldLinesFromBox(ARRAY & startpoints) + { + if(fieldlines_startarea_parameter[0] > fieldlines_startarea_parameter[3] || + fieldlines_startarea_parameter[1] > fieldlines_startarea_parameter[4] || + fieldlines_startarea_parameter[2] > fieldlines_startarea_parameter[5]) + { + Point3d pmin, pmax; + mesh->GetBox (pmin, pmax); + + fieldlines_startarea_parameter[0] = pmin.X(); + fieldlines_startarea_parameter[1] = pmin.Y(); + fieldlines_startarea_parameter[2] = pmin.Z(); + fieldlines_startarea_parameter[3] = pmax.X(); + fieldlines_startarea_parameter[4] = pmax.Y(); + fieldlines_startarea_parameter[5] = pmax.Z(); + } + + for (int i = 1; i <= startpoints.Size(); i++) + { + Point3d p (fieldlines_startarea_parameter[0] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[3]-fieldlines_startarea_parameter[0]), + fieldlines_startarea_parameter[1] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[4]-fieldlines_startarea_parameter[1]), + fieldlines_startarea_parameter[2] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[5]-fieldlines_startarea_parameter[2])); + + startpoints[i-1] = p; + } + } + + void VisualSceneSolution :: BuildFieldLinesFromLine(ARRAY & startpoints) + { + for (int i = 1; i <= startpoints.Size(); i++) + { + double s = double (rand()) / RAND_MAX; + + Point3d p (fieldlines_startarea_parameter[0] + s * (fieldlines_startarea_parameter[3]-fieldlines_startarea_parameter[0]), + fieldlines_startarea_parameter[1] + s * (fieldlines_startarea_parameter[4]-fieldlines_startarea_parameter[1]), + fieldlines_startarea_parameter[2] + s * (fieldlines_startarea_parameter[5]-fieldlines_startarea_parameter[2])); + + startpoints[i-1] = p; + } + } + + + void VisualSceneSolution :: BuildFieldLinesFromFile(ARRAY & startpoints) + { + ifstream * infile; + + infile = new ifstream(fieldlines_filename.c_str()); + + //cout << "reading from file " << fieldlines_filename << endl; + + int numpoints = 0; + + string keyword; + + + double dparam; + int iparam; + + while(infile->good()) + { + (*infile) >> keyword; + + if(keyword == "point") numpoints++; + else if(keyword == "line" || keyword == "box") + { + for(int i=0; i<6; i++) (*infile) >> dparam; + (*infile) >> iparam; + numpoints += iparam; + } + } + + delete infile; + + + //cout << numpoints << " startpoints" << endl; + + startpoints.SetSize(numpoints); + + infile = new ifstream(fieldlines_filename.c_str()); + + numpoints = 0; + + while(infile->good()) + { + (*infile) >> keyword; + + if (keyword == "point") + { + (*infile) >> startpoints[numpoints].X(); (*infile) >> startpoints[numpoints].Y(); (*infile) >> startpoints[numpoints].Z(); + numpoints++; + } + else if (keyword == "line" || keyword == "box") + { + for(int i=0; i<6; i++) (*infile) >> fieldlines_startarea_parameter[i]; + (*infile) >> iparam; + + ARRAY auxpoints(iparam); + + if (keyword == "box") + BuildFieldLinesFromBox(auxpoints); + else if (keyword == "line") + BuildFieldLinesFromLine(auxpoints); + + for(int i=0; i & startpoints) + { + ARRAY elements_2d; + + //cout << "fieldlines_startface " << fieldlines_startface << endl; + mesh->GetSurfaceElementsOfFace(fieldlines_startface,elements_2d); + if(elements_2d.Size() == 0) + { + cerr << "No Elements on selected face (?)" << endl; + return; + } + Vec3d v1,v2,cross; + + double area = 0; + + int i; + for(i=0; iSurfaceElement(elements_2d[i]); + + v1 = mesh->Point(elem[1]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + area += cross.Length(); + + if(elem.GetNV() == 4) + { + v1 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[3]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + area += cross.Length(); + } + } + + int startpointsp = 0; + i = 0; + + while(startpointsp < startpoints.Size()) + { + const Element2d & elem = mesh->SurfaceElement(elements_2d[i]); + + int numtri = (elem.GetNV() == 3) ? 1 : 2; + + for(int tri = 0; startpointsp < startpoints.Size() && triPoint(elem[1]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + } + else if(tri == 1) + { + v1 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[3]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + } + + double thisarea = cross.Length(); + + int numloc = int(startpoints.Size()*thisarea/area); + if(double (rand()) / RAND_MAX < startpoints.Size()*thisarea/area - numloc) + numloc++; + + for(int j=0; startpointsp < startpoints.Size() && j 1) + { + s = 1.-s; t = 1.-t; + } + startpoints[startpointsp] = mesh->Point(elem[0]) + s*v1 +t*v2; + startpointsp++; + } + } + i++; + if(i == elements_2d.Size()) i = 0; + } + + } + + + void VisualSceneSolution :: BuildFieldLinesPlot () + { + if (fieldlinestimestamp >= solutiontimestamp) + return; + fieldlinestimestamp = solutiontimestamp; + + + if (fieldlineslist) + glDeleteLists (fieldlineslist, num_fieldlineslists); + + if (vecfunction == -1) + return; + + const SolData * vsol = soldata[fieldlines_vecfunction]; + + num_fieldlineslists = (vsol -> iscomplex && !fieldlines_fixedphase) ? 100 : 1; + + + FieldLineCalc linecalc(*mesh,*this,vsol, + fieldlines_rellength,fieldlines_maxpoints,fieldlines_relthickness,fieldlines_reltolerance,fieldlines_rktype); + + if(fieldlines_randomstart) + linecalc.Randomized(); + + fieldlineslist = glGenLists (num_fieldlineslists); + + int num_startpoints = num_fieldlines / num_fieldlineslists; + if (num_fieldlines % num_fieldlineslists != 0) num_startpoints++; + + if(fieldlines_randomstart) + num_startpoints *= 10; + + + ARRAY startpoints(num_startpoints); + + + for (int ln = 0; ln < num_fieldlineslists; ln++) + { + if(fieldlines_startarea == 0) + BuildFieldLinesFromBox(startpoints); + else if(fieldlines_startarea == 1) + BuildFieldLinesFromFile(startpoints); + else if(fieldlines_startarea == 2) + BuildFieldLinesFromFace(startpoints); + + + + double phi; + + if(vsol -> iscomplex) + { + if(fieldlines_fixedphase) + phi = fieldlines_phase; + else + phi = 2*M_PI*ln / num_fieldlineslists; + } + else + phi = 0; + + cout << "phi = " << phi << endl; + + double phaser = cos(phi), phasei = sin(phi); + + + + linecalc.GenerateFieldLines(startpoints,num_fieldlines / num_fieldlineslists+1, + fieldlineslist+ln,minval,maxval,logscale,phaser,phasei); + } + } + + + + +} + + +#endif // NOTCL diff --git a/libsrc/visualization/vsmesh.cpp b/libsrc/visualization/vsmesh.cpp new file mode 100644 index 00000000..4ef9bb35 --- /dev/null +++ b/libsrc/visualization/vsmesh.cpp @@ -0,0 +1,3674 @@ +#ifndef NOTCL + +#include +#include "incvis.hpp" + + +#include +#include +#include +#include + +#include + + + + + +namespace netgen +{ + +#include "mvdraw.hpp" + + + // #define FAST3DELEMENTS + + + + extern AutoPtr mesh; + extern STLGeometry * stlgeometry; + VisualSceneMesh vsmesh; + + + + VisualSceneMesh :: VisualSceneMesh () + : VisualScene() + { + filledlist = 0; + linelist = 0; + edgelist = 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(); + edgetimestamp = 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 drawel; + + void VisualSceneMesh :: DrawScene () + { + if (!mesh) + { + VisualScene::DrawScene(); + return; + } + + lock = NULL; + + clock_t starttime, endtime; + starttime = clock(); + + 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); + + +#ifdef PARALLEL + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#endif + + + 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 (); + } + +#ifdef PARALLELGL + if (ntasks > 1 && vispar.drawtetsdomain > 0 && vispar.drawtetsdomain < ntasks) + glCallList (par_filledlists[vispar.drawtetsdomain]); + else +#endif + glCallList (filledlist); + } + + if (vispar.drawbadels) + glCallList (badellist); + + if (vispar.drawprisms) + { + BuildPrismList (); + glCallList (prismlist); + } + + if (vispar.drawpyramids) + { + BuildPyramidList (); + glCallList (pyramidlist); + } + + if (vispar.drawhexes) + { + BuildHexList (); + glCallList (hexlist); + } + + if (vispar.drawtets) + { + BuildTetList (); + 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 (); + +#ifdef PARALLELGL + if (ntasks > 1 && vispar.drawtetsdomain > 0 && vispar.drawtetsdomain < ntasks) + // for (int dest = 1; dest < ntasks; dest++) + // if (vispar.drawtetsdomain == dest) + glCallList (par_linelists[vispar.drawtetsdomain]); + else +#endif + 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) + { + BuildEdgeList(); + glCallList (edgelist); + } + + + if (selpoint > 0 && selpoint <= mesh->GetNP()) + { + /* + glPointSize (3.0); + glColor3d (0, 0, 1); + 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(); + */ + + glColor3d (0, 0, 1); + + static GLubyte cross[] = + { + 0xc6, 0xee, 0x7c, 0x38, 0x7c, 0xee, 0xc6 + }; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glDisable (GL_COLOR_MATERIAL); + glDisable (GL_LIGHTING); + glDisable (GL_CLIP_PLANE0); + + const Point3d p = mesh->Point(selpoint); + glRasterPos3d (p.X(), p.Y(), p.Z()); + glBitmap (7, 7, 3, 3, 0, 0, &cross[0]); + } + + + glDisable(GL_CLIP_PLANE0); + + glPopMatrix(); + + if (vispar.colormeshsize) + DrawColorBar (minh, maxh, 1); + + DrawCoordinateCross (); + DrawNetgenLogo (); + + if (lock) + { + lock -> UnLock(); + delete lock; + lock = NULL; + } + + glFinish(); + + + endtime = clock(); + // cout << 1.0 / (double(endtime - starttime)/CLOCKS_PER_SEC) << " frames/sec" << endl; + } + + + void VisualSceneMesh :: BuildScene (int zoomall) + { + if (!mesh) + { + VisualScene::BuildScene (zoomall); + return; + } + + int i, j; + + + Point3d pmin, pmax; + static double oldrad = 0; + + ARRAY faces; + + int meshtimestamp = mesh->GetTimeStamp(); + if (meshtimestamp > vstimestamp || zoomall) + { + if (mesh->GetDimension() == 2) + { + // works in NGSolve, mesh view + mesh->GetBox (pmin, pmax); + } + else + { + // otherwise strange zooms douring mesh generation + mesh->GetBox (pmin, pmax, SURFACEPOINT); + } + + if (vispar.use_center_coords && zoomall == 2) + { + center.X() = vispar.centerx; center.Y() = vispar.centery; center.Z() = vispar.centerz; + } + else if (selpoint >= 1 && zoomall == 2) + center = mesh->Point (selpoint); + 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 == 0) rad = 1; + + 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) + { + /* + for (SegmentIndex i = 0; i < mesh->GetNSeg(); i++) + { + const Segment & seg = (*mesh)[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); + } + */ + + 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 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); + } + } + + + + if (vispar.drawelementnumbers) + { + ARRAY v; + for (i = 1; i <= mesh->GetNE(); i++) + { + const ELEMENTTYPE & eltype = mesh->ElementType(i); + ARRAY pnums; + + Point3d p; + const Element & el = mesh->VolumeElement (i); + + if ( ! el.PNum(5)) // eltype == TET ) + { + + pnums.SetSize(4); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p4 = mesh->Point(pnums[3]); + p = Center (p1, p2, p3, p4); + } + else if ( ! el.PNum(6)) // eltype == PYRAMID + { + pnums.SetSize(5); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p4 = mesh->Point(pnums[3]); + const Point3d & p5 = mesh->Point(pnums[4]); + + p.X() = 0.3 * p5.X() + 0.7 * Center ( Center(p1, p3) , Center(p2, p4) ) . X(); + p.Y() = 0.3 * p5.Y() + 0.7 * Center ( Center(p1, p3) , Center(p2, p4) ) . Y(); + p.Z() = 0.3 * p5.Z() + 0.7 * Center ( Center(p1, p3) , Center(p2, p4) ) . Z(); + + } + else if ( ! el.PNum(7) ) // eltype == PRISM + { + pnums.SetSize(6); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p11 = mesh->Point(pnums[3]); + const Point3d & p12 = mesh->Point(pnums[4]); + const Point3d & p13 = mesh->Point(pnums[5]); + p = Center ( Center (p1, p2, p3) , Center(p11, p12, p13) ) ; + + } + else if (! el.PNum(9) ) // eltype == HEX + { + pnums.SetSize(8); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p4 = mesh->Point(pnums[3]); + const Point3d & p5 = mesh->Point(pnums[4]); + const Point3d & p6 = mesh->Point(pnums[5]); + const Point3d & p7 = mesh->Point(pnums[6]); + const Point3d & p8 = mesh->Point(pnums[7]); + + p = Center ( Center ( Center(p1, p3), Center(p2, p4) ) , Center( Center(p5, p7) , Center(p6, p8 ) ) ); + } + + 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])) ); + glVertex3dv ( mesh->Point (el.PNum(lines[j][0])) ); + } + 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 & 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() + { + static int timer = NgProfiler::CreateTimer ("Mesh::BuildFilledList"); + NgProfiler::RegionTimer reg (timer); + + +#ifdef PARALLELGL + + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + par_filledlists.SetSize (ntasks); + + for ( int dest = 1; dest < ntasks; dest++ ) + { + MyMPI_Send ("redraw", dest); + MyMPI_Send ("filledlist", dest); + } + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_filledlists[dest], dest); + + if (filledlist) + glDeleteLists (filledlist, 1); + + filledlist = glGenLists (1); + glNewList (filledlist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_filledlists[dest]); + + glEndList(); + + + + filledtimestamp = NextTimeStamp(); + return; + } + +#endif + + + // 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 }; +#ifdef PARALLEL + GLfloat mat_coll_transp[] = { 0, 1, 0, 0.3 }; + GLfloat mat_coll_transp_sel[] = { 1, 0, 0, 0.3 }; +#endif + + 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]; + +#ifdef PARALLEL + if ( el.IsGhost() ) + { + if ( col == 2 ) + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_coll_transp_sel); + else + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_coll_transp); + } + else + { + if (col == 2) + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolsel); + else + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol); + } +#endif + + + 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)) + { + if (hoplotn > 128) hoplotn = 128; + Point<3> xa[129]; + Vec<3> na[129]; + + for (int i = 0; i < hoplotn; i++) + { + glBegin (GL_TRIANGLE_STRIP); + + for (int j = 0; j <= hoplotn-i; j++) + for (int k = 0; k < 2; k++) + { + if (j == hoplotn-i && k == 1) continue; + + if (i > 0 && k == 0) + { + glNormal3dv (na[j]); + glVertex3dv (xa[j]); + continue; + } + + Point<2> xref (double(j) / hoplotn, double(i+k) / hoplotn); + Point<3> xglob; + Mat<3,2> dxdxi; + Vec<3> dx, dy, n; + + curv.CalcSurfaceTransformation (xref, sei, xglob, dxdxi); + for (int i = 0; i < 3; i++) + { + dx(i) = dxdxi(i,0); + dy(i) = dxdxi(i,1); + } + n = Cross (dx, dy); + glNormal3dv (n); + glVertex3dv (xglob); + + if (k == 1) + { + na[j] = n; + xa[j] = xglob; + } + } + 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); + n.Normalize(); + 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++) + { + const Point<3> & lp1 = mesh->Point (el.PNum(trigs[j][0])); + const Point<3> & lp2 = mesh->Point (el.PNum(trigs[j][1])); + const Point<3> & lp3 = mesh->Point (el.PNum(trigs[j][2])); + // Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + Vec<3> n = Cross (lp2-lp1, lp3-lp1); + glNormal3dv (n); + + glVertex3dv (lp1); + glVertex3dv (lp2); + glVertex3dv (lp3); + } + 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++) + { + const 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++) + { + const 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 (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (filledlist, 0); +#endif + + // endtime = clock(); + // cout << "BuildFillList time = " << double(endtime - starttime)/CLOCKS_PER_SEC << endl; + } + + + void VisualSceneMesh :: BuildLineList() + { + static int timer = NgProfiler::CreateTimer ("Mesh::BuildLineList"); + NgProfiler::RegionTimer reg (timer); + +#ifdef PARALLELGL + + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + par_linelists.SetSize (ntasks); + + for ( int dest = 1; dest < ntasks; dest++ ) + { + MyMPI_Send ("redraw", dest); + MyMPI_Send ("linelist", dest); + } + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_linelists[dest], dest); + + if (linelist) + glDeleteLists (linelist, 1); + + linelist = glGenLists (1); + glNewList (linelist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_linelists[dest]); + + glEndList(); + + + linetimestamp = NextTimeStamp(); + return; + } + +#endif + + 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); + + // cout << "linelist = " << linelist << endl; + + glLineWidth (1.0f); + + + int hoplotn = 1 << vispar.subdivisions; + + // PrintMessage (3, "nse = ", mesh->GetNSE()); + 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; + + 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 (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (linelist, 0); +#endif + } + + + + void VisualSceneMesh :: BuildEdgeList() + { + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + if (edgetimestamp > mesh->GetTimeStamp () && vispar.shrink == 1) + return; + + edgetimestamp = NextTimeStamp(); + + if (edgelist) + glDeleteLists (edgelist, 1); + + edgelist = glGenLists (1); + glNewList (edgelist, GL_COMPILE); + + + GLfloat matcoledge[] = { 0, 0, 1, 1 }; + GLfloat matcolsingedge[] = { 1, 0, 1, 1 }; + + glEnable (GL_POLYGON_OFFSET_LINE); + glPolygonOffset (1, -1); + + glEnable (GL_COLOR_MATERIAL); + glDisable (GL_LIGHTING); + + 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.singedge_left || seg.singedge_right) + glColor3fv (matcolsingedge); + else + glColor3fv (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)); + /* + cout << "x = " << x(0) << ", " << x(1) << ", " << x(2) + << ", norm = 1+" << sqrt(x(0)*x(0)+x(1)*x(1))-1 + << ", phi = " << atan2(x(1), x(0))/M_PI << endl; + */ + } + + glEnd(); + + } + else + { + glBegin (GL_LINES); + Point<3> hp1 = p1; + Point<3> hp2 = p2; + Point<3> c = Center(p1, p2); + if (vispar.shrink < 1) + { + hp1 = c + vispar.shrink * (hp1 - c); + hp2 = c + vispar.shrink * (hp2 - c); + } + glVertex3dv (hp1); + glVertex3dv (hp2); // p2.X(), p2.Y(), p2.Z()); + glEnd(); + } + } + + glLineWidth (2); + glDisable (GL_POLYGON_OFFSET_LINE); + + glDisable (GL_COLOR_MATERIAL); + glEnable (GL_LIGHTING); + + glEndList(); + } + + + + + void VisualSceneMesh :: BuildPointNumberList() + { + ; + } + + + + // Bernstein Pol B_{n,i}(x) = n! / i! / (n-i)! (1-x)^{n-i} x^i + static inline double Bernstein (int n, int i, double x) + { + double val = 1; + for (int j = 1; j <= i; j++) + val *= x; + for (int j = 1; j <= n-i; j++) + val *= (1-x) * (j+i) / j; + return val; + } + + 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) = Bernstein (order, j, x); + } + + 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 + + + int i, j; + ARRAY 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(); + +#ifdef PARALLEL + static float tetcols[][8] = + { + { 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 }, + { 1.0f, 1.0f, 0.0f, 0.3f }, + { 1.0f, 0.0f, 0.0f, 0.3f }, + { 0.0f, 1.0f, 0.0f, 0.3f }, + { 0.0f, 0.0f, 1.0f, 0.3f } + }; + +#else + 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 } + }; +#endif + + ARRAY elfaces; + + const MeshTopology & top = mesh->GetTopology(); + CurvedElements & curv = mesh->GetCurvedElements(); + + ARRAY 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 (" << i << ") = " << ind << endl; + +#ifdef PARALLEL + if ( mesh -> VolumeElement(i).IsGhost() ) + { + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind+4]); + } + else + { + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); + } +#else + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); +#endif + + 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); + + + + ARRAY faces; + + BitArray shownode(mesh->GetNP()); + if (vispar.clipenable) + { + shownode.Clear(); + for (int i = 1; i <= shownode.Size(); i++) + { + Point<3> p = mesh->Point(i); + + double val = + p[0] * clipplane[0] + + p[1] * clipplane[1] + + p[2] * clipplane[2] + + clipplane[3]; + + if (val > 0) shownode.Set (i); + } + } + else + shownode.Set(); + + +#ifdef PARALLEL + static float tetcols[][8] = + { + { 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 }, + { 1.0f, 1.0f, 0.0f, 0.3f }, + { 1.0f, 0.0f, 0.0f, 0.3f }, + { 0.0f, 1.0f, 0.0f, 0.3f }, + { 0.0f, 0.0f, 1.0f, 0.3f } + }; + +#else + 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 } + }; +#endif + + + CurvedElements & curv = mesh->GetCurvedElements(); + + + if (!curv.IsHighOrder()) + glShadeModel (GL_FLAT); + else + glShadeModel (GL_SMOOTH); + + int hoplotn = max (2, 1 << vispar.subdivisions); + + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + if (vispar.drawtetsdomain > 0 && + vispar.drawtetsdomain != (*mesh)[ei].GetIndex()) + continue; + + const Element & el = (*mesh)[ei]; + + if ((el.GetType() == TET || el.GetType() == TET10) && !el.IsDeleted()) + { + + bool drawtet = 1; + for (int j = 0; j < 4; j++) + if (!shownode.Test(el[j])) + drawtet = 0; + if (!drawtet) continue; + + + int ind = el.GetIndex() % 4; + + +#ifdef PARALLEL + if (vispar.drawmetispartition && (el.GetPartition()!=-1)) + ind = el.GetPartition() % 4; + // (*testout) << "ind (" << i << ") = " << ind << endl; + + + if ( el.IsGhost() ) + { + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, tetcols[ind+4]); + } + else + { + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); + } +#else + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); +#endif + + + + + 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); + } + */ + + + + int order = curv.GetOrder(); + + ARRAY > ploc ( (order+1)*(order+1) ); + ARRAY > pglob ( (order+1)*(order+1) ); + Point<3> fpts[3]; + + 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, ii = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++, ii++) + { + 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); + + ploc[ii] = xl; + } + + curv.CalcMultiPointElementTransformation (&ploc, ei, &pglob, 0); + + Point<3> grid[11][11]; + for (int ix = 0, ii = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++, ii++) + grid[ix][iy] = pglob[ii]; + + 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(hoplotn, 0.0, 0.9999, hoplotn, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, hoplotn, 0, hoplotn); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + } + + else + + { + Point<3> pts[4]; + for (int j = 0; j < 4; j++) + pts[j] = (*mesh)[el[j]]; + + if (vispar.shrink < 1) + { + Point<3> c = Center (pts[0], pts[1], pts[2], pts[3]); + for (int j = 0; j < 4; j++) + pts[j] = c + vispar.shrink * (pts[j]-c); + } + + + Vec<3> n; + + glBegin (GL_TRIANGLE_STRIP); + + n = Cross (pts[1]-pts[0], pts[2]-pts[0]); + glNormal3dv (n); + glVertex3dv (pts[0]); + glVertex3dv (pts[1]); + glVertex3dv (pts[2]); + + n = Cross (pts[3]-pts[1], pts[2]-pts[1]); + glNormal3dv (n); + glVertex3dv (pts[3]); + + n = Cross (pts[3]-pts[2], pts[0]-pts[2]); + glNormal3dv (n); + glVertex3dv (pts[0]); + + n = Cross (pts[1]-pts[3], pts[0]-pts[3]); + glNormal3dv (n); + glVertex3dv (pts[1]); + + 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 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 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 }; + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pyramidcol); + + glLineWidth (1.0f); + ARRAY 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); + + 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) + { + if(lock) + { + lock->UnLock(); + delete lock; + lock = NULL; + } + + + + MouseDblClickSelect(px,py,clipplane,backcolor,transformationmat,center,rad, + filledlist,selelement,selface,seledge,selpoint,selpoint2,locpi); + + selecttimestamp = NextTimeStamp(); + + /* + 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]; + + 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(); + */ + + } + + + + + + void MouseDblClickSelect (const int px, const int py, + const GLdouble * clipplane, const GLdouble backcolor, + const float * transformationmat, + const Point3d & center, + const double rad, + const int displaylist, + int & selelement, int & selface, int & seledge, int & selpoint, + int & selpoint2, int & locpi) + { + 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 (displaylist); + + 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); + + + +#ifdef PARALLELGL + vsmesh.Broadcast (); +#endif + } + + + void VisualSceneMesh :: SetSelectedFace (int asf) + { + selface = asf; + selecttimestamp = GetTimeStamp(); + } + + + + +} + + + +#endif // NOTCL diff --git a/libsrc/visualization/vsocc.cpp b/libsrc/visualization/vsocc.cpp new file mode 100644 index 00000000..f2905830 --- /dev/null +++ b/libsrc/visualization/vsocc.cpp @@ -0,0 +1,752 @@ +#ifndef NOTCL + +#ifdef OCCGEOMETRY + + +#include +#include +#include + +// #include +// #include + +#include + +#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 () +{ + 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++) + { + if (!occgeometry->fvispar[i-1].IsVisible()) continue; + + 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); + gp_Pnt p[3]; + for (int k = 1; k <= 3; k++) + p[k-1] = (triangulation -> Nodes())(triangle(k)).Transformed(loc); + + for (int k = 1; k <= 3; k++) + { + uv = (triangulation -> UVNodes())(triangle(k)); + prop.SetParameters (uv.X(), uv.Y()); + + // 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); + gp_Vec a(p[0],p[1]); + gp_Vec b(p[0],p[2]); + n = b^a; + } + + if (face.Orientation() == TopAbs_REVERSED) n *= -1; + glNormal3f (n.X(), n.Y(), n.Z()); + glVertex3f (p[k-1].X(), p[k-1].Y(), p[k-1].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 + +#endif // NOTCL + diff --git a/libsrc/visualization/vssolution.cpp b/libsrc/visualization/vssolution.cpp new file mode 100644 index 00000000..9ce92957 --- /dev/null +++ b/libsrc/visualization/vssolution.cpp @@ -0,0 +1,4980 @@ +#ifndef NOTCL +#include +#include "incvis.hpp" + + +#include +#include +#include +#include + +#include +#include + + +namespace netgen +{ + + extern AutoPtr mesh; + + extern VisualSceneMesh vsmesh; + + + 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; + isosurface_list = 0; + + fieldlineslist = 0; + pointcurvelist = 0; + + num_fieldlineslists = 0; + + + surfeltimestamp = GetTimeStamp(); + surfellinetimestamp = GetTimeStamp(); + clipplanetimestamp = GetTimeStamp(); + solutiontimestamp = GetTimeStamp(); + fieldlinestimestamp = GetTimeStamp(); + pointcurve_timestamp = GetTimeStamp(); + surface_vector_timestamp = GetTimeStamp(); + isosurface_timestamp = GetTimeStamp(); + timetimestamp = GetTimeStamp(); + AddVisualizationScene ("solution", &vssolution); + } + + VisualSceneSolution :: ~VisualSceneSolution () + { + ClearSolutionData(); + } + + void VisualSceneSolution :: AddSolutionData (SolData * sd) + { + NgLock meshlock1 (mesh->MajorMutex(), 1); + + 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); + + + if (strcmp (&filename[strlen(filename)-3], "sol") == 0) + { + ofstream ost(filename); + for (int 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 (int j = 0; j < sol.size; j++) + { + for (int k = 0; k < sol.components; k++) + ost << sol.data[j*sol.dist+k] << " "; + ost << "\n"; + } + } + } + + + if (strcmp (&filename[strlen(filename)-3], "vtk") == 0) + { + string surf_fn = filename; + surf_fn.erase (strlen(filename)-4); + surf_fn += "_surf.vtk"; + + cout << "surface mesh = " << surf_fn << endl; + + ofstream surf_ost(surf_fn.c_str()); + + surf_ost << "# vtk DataFile Version 1.0\n" + << "NGSolve surface mesh\n" + << "ASCII\n" + << "DATASET UNSTRUCTURED_GRID\n\n"; + + surf_ost << "POINTS " << mesh->GetNP() << " float\n"; + for (PointIndex pi = PointIndex::BASE; pi < mesh->GetNP()+PointIndex::BASE; pi++) + { + const MeshPoint & mp = (*mesh)[pi]; + surf_ost << mp(0) << " " << mp(1) << " " << mp(2) << "\n"; + } + + int cntverts = 0; + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + cntverts += 1 + (*mesh)[sei].GetNP(); + + surf_ost << "\nCELLS " << mesh->GetNSE() << " " << cntverts << "\n"; + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + { + const Element2d & el = (*mesh)[sei]; + surf_ost << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + surf_ost << " " << el[j] - PointIndex::BASE; + surf_ost << "\n"; + } + surf_ost << "\nCELL_TYPES " << mesh->GetNSE() << "\n"; + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + { + const Element2d & el = (*mesh)[sei]; + switch (el.GetType()) + { + case QUAD: surf_ost << 9; break; + case TRIG: surf_ost << 5; break; + } + surf_ost << "\n"; + } + + + + ofstream ost(filename); + + ost << "# vtk DataFile Version 1.0\n" + << "NGSolve solution\n" + << "ASCII\n" + << "DATASET UNSTRUCTURED_GRID\n\n"; + + ost << "POINTS " << mesh->GetNP() << " float\n"; + for (PointIndex pi = PointIndex::BASE; pi < mesh->GetNP()+PointIndex::BASE; pi++) + { + const MeshPoint & mp = (*mesh)[pi]; + ost << mp(0) << " " << mp(1) << " " << mp(2) << "\n"; + } + + cntverts = 0; + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + cntverts += 1 + (*mesh)[ei].GetNP(); + + ost << "\nCELLS " << mesh->GetNE() << " " << cntverts << "\n"; + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + ost << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + ost << " " << el[j] - PointIndex::BASE; + ost << "\n"; + } + ost << "\nCELL_TYPES " << mesh->GetNE() << "\n"; + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + switch (el.GetType()) + { + case TET: ost << 10; break; + } + ost << "\n"; + } + + + ost << "CELL_DATA " << mesh->GetNE() << "\n"; + for (int i = 0; i < soldata.Size(); i++) + { + ost << "VECTORS bfield float\n"; + SolutionData & sol = *(soldata[i] -> solclass); + double values[3]; + + for (int elnr = 0; elnr < mesh->GetNE(); elnr++) + { + sol.GetValue (elnr, 0.25, 0.25, 0.25, values); + ost << values[0] << " " << values[1] << " " << values[2] << "\n"; + } + } + + /* + ost << "POINT_DATA " << mesh->GetNP() << "\n"; + for (int i = 0; i < soldata.Size(); i++) + { + ost << "VECTORS bfield float\n"; + SolutionData & sol = *(soldata[i] -> solclass); + + for (PointIndex pi = PointIndex::BASE; + pi < mesh->GetNP()+PointIndex::BASE; pi++) + { + double values[3], sumvalues[3] = { 0, 0, 0 }; + + FlatArray els = mesh->GetTopology().GetVertexElements(pi); + + for (int j = 0; j < els.Size(); j++) + { + sol.GetValue (els[j]-1, 0.25, 0.25, 0.25, values); + for (int k = 0; k < 3; k++) + sumvalues[k] += values[k]; + } + for (int k = 0; k < 3; k++) + sumvalues[k] /= els.Size(); + + ost << sumvalues[0] << " " << sumvalues[1] << " " << sumvalues[2] << "\n"; + } + } + */ + } + + } + + + + + void VisualSceneSolution :: DrawScene () + { + clock_t starttime, endtime; + starttime = clock(); + + + if (!mesh) + { + VisualScene::DrawScene(); + return; + } + + static NgLock mem_lock(mem_mutex); + mem_lock.Lock(); + + NgLock meshlock1 (mesh->MajorMutex(), true); + NgLock meshlock (mesh->Mutex(), true); + + 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); + + glEnable (GL_POLYGON_OFFSET_FILL); + + glEnable (GL_COLOR_MATERIAL); + + if (usetexture) + { + if (usetexture == 1) + { + glEnable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + } + else + { + glEnable (GL_TEXTURE_2D); + glDisable (GL_TEXTURE_1D); + } + + glMatrixMode (GL_TEXTURE); + glLoadIdentity(); + + if (usetexture == 1) + { + double hmax = maxval; + double hmin = minval; + if (invcolor) Swap (hmax, hmin); + + if (fabs (hmax - hmin) > 1e-30) + glScaled (1.0 / (hmin - hmax), 0, 0); + else + glScaled (1e30, 0, 0); + + glTranslatef (-hmax, 0, 0); + } + else + { + glTranslatef (0.5, 0, 0); + glRotatef(360 * vssolution.time, 0, 0, -1); + if (fabs (maxval) > 1e-10) + glScalef(0.5/maxval, 0.5/maxval, 0.5/maxval); + else + glScalef (1e10, 1e10, 1e10); + } + glMatrixMode (GL_MODELVIEW); + } + + 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) + { + SetClippingPlane(); + 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); + } + } + glDisable(GL_CLIP_PLANE0); + } + + if(drawpointcurves) + { + glCallList(pointcurvelist); + } + + glMatrixMode (GL_TEXTURE); + glLoadIdentity(); + glMatrixMode (GL_MODELVIEW); + + if (usetexture) + { + glDisable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + } + + + glDisable (GL_POLYGON_OFFSET_FILL); + glDisable (GL_COLOR_MATERIAL); + + if (draw_isosurface) + glCallList (isosurface_list); + + + 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(); + + + endtime = clock(); + // cout << 1.0 / (double(endtime - starttime)/CLOCKS_PER_SEC) << " frames/sec" << endl; + } + + + + void VisualSceneSolution :: 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]; + } + } + } + + + void VisualSceneSolution :: 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) + { + 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 || !sol) + { + 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; + } + } + + DrawSurfaceElements(); + + surfeltimestamp = max2 (solutiontimestamp, mesh->GetTimeStamp()); + } + + if (mesh->GetTimeStamp() > surfellinetimestamp || + subdivision_timestamp > surfellinetimestamp || + (deform && 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 == 2) + { + // 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 cpt; + ARRAY pts; + GetClippingPlaneTrigs (cpt, pts); + + glNormal3d (-clipplane[0], -clipplane[1], -clipplane[2]); + glColor3d (1.0, 1.0, 1.0); + + glDisable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + + if (usetexture == 1) + glEnable (GL_TEXTURE_1D); + if (usetexture == 2) + glEnable (GL_TEXTURE_2D); + + glBegin (GL_TRIANGLES); + // for (int i = 0; i < cpt.Size(); i++) + // DrawClipPlaneTrig (sol, scalcomp, cpt[i], 0); + DrawClipPlaneTrigs (sol, scalcomp, cpt, pts); + glEnd(); + + glEnable(GL_CLIP_PLANE0); + } + + + if (vispar.clipenable && clipsolution == 2 && vsol) + { + if (autoscale) + GetMinMax (vecfunction, 0, minval, maxval); + + + bool drawelem; + ARRAY cpp; + GetClippingPlaneGrid (cpp); + + for (int i = 0; i < cpp.Size(); i++) + { + const ClipPlanePoint & p = cpp[i]; + double values[6]; + Vec3d v; + + drawelem = GetValues (vsol, p.elnr, p.lami(0), p.lami(1), p.lami(2), 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 (mesh->GetTimeStamp() > isosurface_timestamp || + solutiontimestamp > isosurface_timestamp || + zoomall) + { + if (isosurface_list) + glDeleteLists (isosurface_list, 1); + + isosurface_list = glGenLists (1); + glNewList (isosurface_list, GL_COMPILE); + + glEnable (GL_NORMALIZE); + DrawIsoSurface(sol, vsol, scalcomp); + + glEndList (); + + isosurface_timestamp = + max2 (mesh->GetTimeStamp(), solutiontimestamp); + } + + if(mesh->GetTimeStamp() > pointcurve_timestamp || + solutiontimestamp > pointcurve_timestamp) + { + if(pointcurvelist) + glDeleteLists(pointcurvelist,1); + + + if(mesh->GetNumPointCurves() > 0) + { + pointcurvelist = glGenLists(1); + glNewList(pointcurvelist,GL_COMPILE); + //glColor3f (1.0f, 0.f, 0.f); + + for(int i=0; iGetNumPointCurves(); i++) + { + Box3d box; + box.SetPoint(mesh->GetPointCurvePoint(i,0)); + for(int j=1; jGetNumPointsOfPointCurve(i); j++) + box.AddPoint(mesh->GetPointCurvePoint(i,j)); + double diam = box.CalcDiam(); + + double thick = min2(0.1*diam, 0.001*rad); + + double red,green,blue; + mesh->GetPointCurveColor(i,red,green,blue); + glColor3f (red, green, blue); + for(int j=0; jGetNumPointsOfPointCurve(i)-1; j++) + { + DrawCylinder(mesh->GetPointCurvePoint(i,j), + mesh->GetPointCurvePoint(i,j+1), + thick); + } + } + 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(); + + CurvedElements & curv = mesh->GetCurvedElements(); + + if (sol) + { + glBegin (GL_LINES); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( el . IsGhost() ) continue; +#endif + bool curved = curv.IsHighOrder(); // && curv.IsSurfaceElementCurved(sei); + + if (el.GetType() == TRIG || el.GetType() == TRIG6) + { + Point<3> lp1, lp2, lp3; + if (!curved) + { + 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 (curved) + mesh->GetCurvedElements(). + CalcSurfaceTransformation (xref, sei, points[ii]); + else + points[ii] = lp3 + x * (lp1-lp3) + y * (lp2-lp3); + + if (deform) + { + points[ii] += GetSurfDeformation (sei, x, y); + } + 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 (!curved) + { + 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 (curved) + mesh->GetCurvedElements(). + CalcSurfaceTransformation (xref, sei, points[ii]); + else + points[ii] = lpi[0] + x * vx + y * vy + x*y * vtwist; + + if (deform) + points[ii] += GetSurfDeformation (sei, x, y); + } + + 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 cpt; + ARRAY pts; + GetClippingPlaneTrigs (cpt, pts); + bool drawelem; + + glNormal3d (-clipplane[0], -clipplane[1], -clipplane[2]); + + if (numisolines) + for (int i = 0; i < cpt.Size(); i++) + { + const ClipPlaneTrig & trig = cpt[i]; + double vali[3]; + for (int j = 0; j < 3; j++) + { + Point<3> lami = pts[trig.points[j].pnr].lami; + drawelem = GetValue (sol, trig.elnr, lami(0), lami(1), lami(2), + scalcomp, vali[j]); + } + if ( drawelem ) + DrawIsoLines (pts[trig.points[0].pnr].p, + pts[trig.points[1].pnr].p, + pts[trig.points[2].pnr].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 :: DrawSurfaceElements () + { + static int timer = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements"); + NgProfiler::RegionTimer reg (timer); + + +#ifdef PARALLELGL + + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + par_surfellists.SetSize (ntasks); + + for ( int dest = 1; dest < ntasks; dest++ ) + { + MyMPI_Send ("redraw", dest); + MyMPI_Send ("solsurfellist", dest); + } + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_surfellists[dest], dest); + + if (surfellist) + glDeleteLists (surfellist, 1); + + surfellist = glGenLists (1); + glNewList (surfellist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_surfellists[dest]); + + glEndList(); + return; + } +#endif + + + + if (surfellist) + glDeleteLists (surfellist, 1); + + surfellist = glGenLists (1); + glNewList (surfellist, GL_COMPILE); + + + 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); + + ARRAY > pref; + ARRAY > points; + ARRAY > dxdxis; + + /* + Point<2> pref[1100]; + Point<3> points[1100]; + Mat<3,2> dxdxis[1100]; + */ + + Vec<3> nvs[1100]; + double values[1100]; + double valuesc[1100][2]; + + + int nse = mesh->GetNSE(); + + if ( usetexture ) + glColor3d (1.0, 1.0, 1.0); + else + glColor3d (0.6, 0.6, 0.6); + CurvedElements & curv = mesh->GetCurvedElements(); + + int n = 1 << subdivisions; + int npt = sqr(n+1); + + pref.SetSize (npt); + points.SetSize (npt); + dxdxis.SetSize (npt); + + glBegin (GL_QUADS); + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( el . IsGhost() ) continue; +#endif + 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 ) + { + bool curved = curv.IsHighOrder(); // && curv.IsSurfaceElementCurved(sei); + + Point<3> lpi[4]; + Vec<3> vx, vy, vtwist; + + if (! curved) + { + 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); + + + /* + for (int iy = 0, ii = 0; iy <= n; iy++) + for (int ix = 0; ix <= n; ix++, ii++) + { + double x = double(ix) / n; + double y = double(iy) / n; + + if (sol && sol->draw_surface) + { + if (usetexture == 2) + drawelem = GetSurfValueComplex (sol, sei, x, y, scalcomp, valuesc[ii][0], valuesc[ii][1]); + else + drawelem = GetSurfValue (sol, sei, x, y, scalcomp, values[ii]); + } + + if (curved) + { + Point<2> xref(x,y); + Mat<3,2> dxdxi; + + 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) + { + points[ii] += GetSurfDeformation (sei, x, y); + } + + ii++; + } + */ + + for (int iy = 0, ii = 0; iy <= n; iy++) + for (int ix = 0; ix <= n; ix++, ii++) + pref[ii] = Point<2> (double(ix)/n, double(iy/n)); + + int npt = (n+1)*(n+1); + if (curved) + for (int ii = 0; ii < npt; ii++) + { + Point<2> xref = pref[ii]; + Mat<3,2> dxdxi; + + mesh->GetCurvedElements(). + CalcSurfaceTransformation (xref, sei, points[ii], dxdxi); + nvs[ii] = Cross (dxdxi.Col(0), dxdxi.Col(1)); + nvs[ii].Normalize(); + } + else + { + for (int ii = 0; ii < npt; ii++) + { + double x = pref[ii](0); + double y = pref[ii](1); + points[ii] = lpi[0] + x * vx + y * vy + x*y * vtwist; + } + + Vec<3> nv = Cross (vx, vy); + nv.Normalize(); + for (int ii = 0; ii < npt; ii++) + nvs[ii] = nv; + } + + if (sol && sol->draw_surface) + { + if (usetexture == 2) + for (int ii = 0; ii < npt; ii++) + drawelem = GetSurfValueComplex (sol, sei, pref[ii](0), pref[ii](1), scalcomp, valuesc[ii][0], valuesc[ii][1]); + else + for (int ii = 0; ii < npt; ii++) + drawelem = GetSurfValue (sol, sei, pref[ii](0), pref[ii](1), scalcomp, values[ii]); + } + + if (deform) + for (int ii = 0; ii < npt; ii++) + points[ii] += GetSurfDeformation (sei, pref[ii](0), pref[ii](1)); + + + + int ii = 0; + for (int iy = 0; iy < n; iy++, ii++) + for (int 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) + { + if (usetexture == 2) + { + if(drawelem) + glTexCoord2f ( valuesc[index[j]][0], + valuesc[index[j]][1] ); + else + glTexCoord2f ( minval,minval); + } + else + { + if(drawelem) + SetOpenGlColor (values[index[j]]); + else + glColor3d(0.6,0.6,0.6); + } + } + + glNormal3dv (nvs[index[j]]); + glVertex3dv (points[index[j]]); + } + } + } + } + glEnd(); + + n = 1 << subdivisions; + double invn = 1.0 / n; + npt = (n+1)*(n+2)/2; + + pref.SetSize ( npt ); + points.SetSize ( npt ); + dxdxis.SetSize ( npt ); + + + for(SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( el . IsGhost() ) continue; +#endif + + // if ( mesh->GetFaceDescriptor(el.GetIndex()).BCProperty() != 1) continue; + + + 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 ) + { + bool curved = curv.IsHighOrder(); // && curv.IsSurfaceElementCurved(sei); + // if (el.GetType() == TRIG6) curved = true; + + Point<3> p1, p2, p3; + Mat<3,2> dxdxi; + + if (! curved) + { + GetPointDeformation (el[0]-1, p1, sei); + GetPointDeformation (el[1]-1, p2, sei); + GetPointDeformation (el[2]-1, p3, sei); + + for (int i = 0; i < 3; i++) + { + dxdxi(i, 0) = p1(i)-p3(i); + dxdxi(i, 1) = p2(i)-p3(i); + } + } + + + /* + for (int iy = 0, ii = 0; iy <= n; iy++) + for (int ix = 0; ix <= n-iy; ix++, ii++) + { + Point<2> pref(ix*invn,iy*invn); + if (curved) + { + mesh->GetCurvedElements(). + CalcSurfaceTransformation (pref, sei, points[ii], dxdxi); + } + else + { + points[ii] = p3 + (invn*ix) * (p1-p3) + (invn*iy) * (p2-p3); + } + + nvs[ii] = Cross (dxdxi.Col(0), dxdxi.Col(1)); + nvs[ii].Normalize(); + + if (sol && sol->draw_surface) + { + if (usetexture == 2) + drawelem = GetSurfValueComplex (sol, sei, ix*invn, iy*invn, scalcomp, + valuesc[ii][0], valuesc[ii][1]); + else + drawelem = GetSurfValue (sol, sei, pref, points[ii], &dxdxi(0,0), scalcomp, values[ii]); + } + + if (deform) + points[ii] += GetSurfDeformation (sei, invn*ix, invn*iy); + } + */ + + + for (int iy = 0, ii = 0; iy <= n; iy++) + for (int ix = 0; ix <= n-iy; ix++, ii++) + pref[ii] = Point<2> (ix*invn, iy*invn); + + npt = (n+1)*(n+2)/2; + if (curved) + { + mesh->GetCurvedElements(). + CalcMultiPointSurfaceTransformation (&pref, sei, &points, &dxdxis); + + for (int ii = 0; ii < npt; ii++) + nvs[ii] = Cross (dxdxis[ii].Col(0), dxdxis[ii].Col(1)).Normalize(); + } + else + { + Vec<3> vx = (p1-p3); + Vec<3> vy = (p2-p3); + for (int ii = 0; ii < npt; ii++) + { + double x = pref[ii](0); + double y = pref[ii](1); + points[ii] = p3 + x * vx + y * vy; + + for (int j = 0; j < 3; j++) + { + dxdxis[ii](j,0) = vx(j); + dxdxis[ii](j,1) = vy(j); + } + } + + Vec<3> nv = Cross (vx, vy).Normalize(); + for (int ii = 0; ii < npt; ii++) + nvs[ii] = nv; + } + + if (sol && sol->draw_surface) + { + if (usetexture == 2) + for (int ii = 0; ii < npt; ii++) + drawelem = GetSurfValueComplex (sol, sei, pref[ii](0), pref[ii](1), scalcomp, valuesc[ii][0], valuesc[ii][1]); + else + for (int ii = 0; ii < npt; ii++) + { + drawelem = GetSurfValue (sol, sei, &pref[ii](0), &points[ii](0), &dxdxis[ii](0), scalcomp, values[ii]); + // drawelem = GetSurfValue (sol, sei, pref[ii](0), pref[ii](1), scalcomp, values[ii]); + } + } + + if (deform) + for (int ii = 0; ii < npt; ii++) + points[ii] += GetSurfDeformation (sei, pref[ii](0), pref[ii](1)); + + + + + + + + + for (int iy = 0, ii = 0; iy < n; iy++) + { + glBegin (GL_TRIANGLE_STRIP); + for (int ix = 0; ix <= n-iy; ix++, ii++) + for (int k = 0; k < 2; k++) + { + if (ix+iy+k > n) continue; + int hi = (k == 0) ? ii : ii+n-iy+1; + + if (sol && sol->draw_surface) + { + switch (usetexture) + { + case 0: + if(drawelem) + SetOpenGlColor (values[hi]); + else + glColor3d(0.6,0.6,0.6); + //SetOpenGlColor (minval); + break; + case 1: + if(drawelem) + glTexCoord1f ( values[hi] ); + else + glTexCoord1f (minval); + break; + case 2: + if(drawelem) + glTexCoord2f ( valuesc[hi][0], valuesc[hi][1] ); + else + glTexCoord2f ( minval,minval); + break; + } + } + + glNormal3dv (nvs[hi]); + glVertex3dv (points[hi]); + } + glEnd(); + } + } + } + glEndList (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (surfellist, 0); +#endif + } + + + // Bernstein Pol B_{n,i}(x) = n! / i! / (n-i)! (1-x)^{n-i} x^i + static inline double Bernstein (int n, int i, double x) + { + double val = 1; + for (int j = 1; j <= i; j++) + val *= x; + for (int j = 1; j <= n-i; j++) + val *= (1-x) * (j+i) / j; + return val; + } + + void VisualSceneSolution :: DrawSurfaceElementLines () + { + glLineWidth (1.0f); + glNormal3d (1, 0, 0); + + int nse = mesh->GetNSE(); + + CurvedElements & curv = mesh->GetCurvedElements(); + bool curved = curv.IsHighOrder(); // && curv.IsSurfaceElementCurved(sei); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + Element2d & el = (*mesh)[sei]; + + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( el . IsGhost() ) continue; +#endif + + + int nv; + if (el.GetType() == TRIG || el.GetType() == TRIG6) + nv = 3; + else + nv = 4; + + Point<3> p1, p2, p3, p4; + if (!curved) + { + p1 = (*mesh)[el[0]]; + p2 = (*mesh)[el[1]]; + p3 = (*mesh)[el[2]]; + if (nv == 4) + p4 = (*mesh)[el[3]]; + } + + + int n = 1 << subdivisions; + + Point<3> pnt; + for (int 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); + + if (curved) + { + ArrayMem, 65> ptsloc(n+1); + ArrayMem, 65> ptsglob(n+1); + + for (int ix = 0; ix <= n; ix++) + ptsloc[ix] = p0 + (double(ix) / n) * vtau; + + mesh->GetCurvedElements(). + CalcMultiPointSurfaceTransformation (&ptsloc, sei, &ptsglob, 0); + + for (int ix = 0; ix <= n; ix++) + { + if (deform) + ptsglob[ix] += GetSurfDeformation (sei, ptsloc[ix](0), ptsloc[ix](1)); + glVertex3dv (ptsglob[ix]); + } + } + else + { + for (int ix = 0; ix <= n; ix++) + { + Point<2> p = p0 + (double(ix) / n) * vtau; + + if (nv == 3) + pnt = p3 + p(0) * (p1-p3) + p(1) * (p2-p3); + else + pnt = p1 + p(0) * (p2-p1) + p(1) * (p4-p1) + p(0)*p(1) * ( (p1-p2)+(p3-p4) ); + + if (deform) + pnt += GetSurfDeformation (sei, p(0), p(1) ); + + glVertex3dv (pnt); + } + } + glEnd (); + } + } + + } + + + + + + + + + + void VisualSceneSolution :: DrawIsoSurface(const SolData * sol, + const SolData * vsol, + int comp) + { + if (!draw_isosurface) return; + if (!sol) return; + + + glColor3d (1.0, 0, 0); + glDisable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + glEnable (GL_COLOR_MATERIAL); + + /* + GLfloat matcol0[] = { 0.5, 0, 0, 1 }; + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + + 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); + */ + + glBegin (GL_TRIANGLES); + + int np = mesh->GetNP(); + int ne = mesh->GetNE(); + + + const int edgei[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + double edgelam[6]; + Point<3> edgep[6]; + Vec<3> normp[6]; + double nodevali[4]; + + int cntce; + int cpe1 = 0, cpe2 = 0, cpe3 = 0; + + int n = 1 << subdivisions; + int n3 = (n+1)*(n+1)*(n+1); + + ARRAY > grid(n3); + ARRAY > locgrid(n3); + ARRAY > trans(n3); + ARRAY val(n3); + ARRAY > grads(n3); + ARRAY compress(n3); + + MatrixFixWidth<3> pointmat(8); + grads = Vec<3> (0.0); + + for (ElementIndex ei = 0; ei < ne; ei++) + { + // if(vispar.clipdomain > 0 && vispar.clipdomain != (*mesh)[ei].GetIndex()) continue; + // if(vispar.donotclipdomain > 0 && vispar.donotclipdomain == (*mesh)[ei].GetIndex()) continue; + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( (*mesh)[ei] . IsGhost() ) continue; +#endif + + ELEMENT_TYPE type = (*mesh)[ei].GetType(); + if (type == HEX || type == PRISM || type == TET || type == PYRAMID) + { + const Element & el = (*mesh)[ei]; + + int ii = 0; + int cnt_valid = 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; + compress[ii] = ii; + + switch (type) + { + case PRISM: + if (ix+iy <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + case TET: + if (ix+iy+iz <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + case HEX: + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + break; + case PYRAMID: + ploc = Point<3> (double(ix) / n * (1-double(iz)/n), + double(iy) / n * (1-double(iz)/n), + double(iz)/n); + break; + } + if (compress[ii] != -1) + locgrid[compress[ii]] = ploc; + } + + if (type != TET && type != PRISM) cnt_valid = n3; + + + if (mesh->GetCurvedElements().IsHighOrder() || 1) + { + mesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&locgrid, ei, &grid, &trans); + } + else + { + Vector shape(el.GetNP()); + for (int k = 0; k < el.GetNP(); k++) + for (int j = 0; j < 3; j++) + pointmat(k,j) = (*mesh)[el[k]](j); + + for (int i = 0; i < cnt_valid; i++) + { + el.GetShapeNew (locgrid[i], shape); + Point<3> pglob; + for (int j = 0; j < 3; j++) + { + pglob(j) = 0; + for (int k = 0; k < el.GetNP(); k++) + pglob(j) += shape(k) * pointmat(k,j); + } + grid[i] = pglob; + } + } + + bool has_pos = 0, has_neg = 0; + + for (int i = 0; i < cnt_valid; i++) + { + GetValue (sol, ei, &locgrid[i](0), &grid[i](0), &trans[i](0), comp, val[i]); + + val[i] -= minval; + + if (vsol) + GetValues (vsol, ei, &locgrid[i](0), &grid[i](0), &trans[i](0), &grads[i](0)); + grads[i] *= -1; + + + if (val[i] > 0) + has_pos = 1; + else + has_neg = 1; + } + + if (!has_pos || !has_neg) continue; + + 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 }; + + for (int j = 0; j < 8; j++) + pi[j] = compress[pi[j]]; + + int tets[6][4] = + { { 1, 2, 4, 5 }, + { 4, 5, 2, 8 }, + { 2, 8, 5, 6 }, + { 2, 3, 4, 8 }, + { 2, 3, 8, 6 }, + { 3, 8, 6, 7 } }; + + for (int ii = 0; ii < 6; ii++) + { + int teti[4]; + for (int k = 0; k < 4; k++) + teti[k] = pi[tets[ii][k]-1]; + + bool is_valid = 1; + for (int j = 0; j < 4; j++) + if (teti[j] == -1) is_valid = 0; + + if (!is_valid) continue; + + for (int j = 0; j < 4; j++) + nodevali[j] = val[teti[j]]; + + cntce = 0; + for (int j = 0; j < 6; j++) + { + int lpi1 = edgei[j][0]; + int lpi2 = edgei[j][1]; + if ( (nodevali[lpi1] > 0) != + (nodevali[lpi2] > 0) ) + { + Point<3> p1 = grid[teti[lpi1]]; + Point<3> p2 = grid[teti[lpi2]]; + + edgelam[j] = nodevali[lpi2] / (nodevali[lpi2] - nodevali[lpi1]); + edgep[j] = grid[teti[lpi1]] + (1-edgelam[j]) * (grid[teti[lpi2]]-grid[teti[lpi1]]); + normp[j] = grads[teti[lpi1]] + (1-edgelam[j]) * (grads[teti[lpi2]]-grads[teti[lpi1]]); + + cntce++; + cpe3 = cpe2; + cpe2 = cpe1; + cpe1 = j; + if (cntce >= 3) + { + if (!vsol) + { + Point<3> points[3]; + + points[0] = edgep[cpe1]; + points[1] = edgep[cpe2]; + points[2] = edgep[cpe3]; + + + Vec<3> normal = Cross (points[2]-points[0], points[1]-points[0]); + if ( (normal * (p2-p1)) > 0 == nodevali[lpi1] < 0) + normal *= -1; + glNormal3dv (normal); + + glVertex3dv (points[0]); + glVertex3dv (points[1]); + glVertex3dv (points[2]); + } + else + { + // glNormal3dv (grads[teti[0]]); + + glNormal3dv (normp[cpe1]); + glVertex3dv (edgep[cpe1]); + glNormal3dv (normp[cpe2]); + glVertex3dv (edgep[cpe2]); + glNormal3dv (normp[cpe3]); + glVertex3dv (edgep[cpe3]); + } + } + } + } + } + } + } + } + glEnd(); + } + + + + + + + + + void VisualSceneSolution :: DrawTrigSurfaceVectors(const ARRAY< Point<3> > & lp, const Point<3> & pmin, const Point<3> & pmax, + const int sei, const SolData * vsol) + { + int dir,dir1,dir2; + double s,t; + bool drawelem; + + 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; + + Point<2> p2d[3]; + + int k; + + 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); // change JS + + if (val > 1e-10 * maxval) + v *= (rad / val / gridsize * 0.5); + else + drawelem = 0; + + 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 :: 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 (autoscale) + // GetMinMax (vecfunction, 0, minval, maxval); + + glColor3d (1.0, 1.0, 1.0); + // glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + if (vsol->draw_surface && showsurfacesolution) + { + int nse = mesh->GetNSE(); + for (sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( el . IsGhost() ) continue; +#endif + + if (el.GetType() == TRIG || el.GetType() == TRIG6) + { + + ARRAY< 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]); + + DrawTrigSurfaceVectors(lp,pmin,pmax,sei,vsol); + + /* + 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); + else drawelem = 0; + // "drawelem": added 07.04.2004 (FB) + if ( drawelem ) DrawCone (cp, cp+4*v, 0.8*rad / gridsize); + + + } + } + */ + } + else if (el.GetType() == QUAD) + { + ARRAY < Point<3> > lp(3); + + lp[0] = mesh->Point(el[0]); + lp[1] = mesh->Point(el[1]); + lp[2] = mesh->Point(el[2]); + + DrawTrigSurfaceVectors(lp,pmin,pmax,sei,vsol); + + lp[0] = mesh->Point(el[0]); + lp[1] = mesh->Point(el[2]); + lp[2] = mesh->Point(el[3]); + + DrawTrigSurfaceVectors(lp,pmin,pmax,sei,vsol); + + /* + Point<3> lp[4]; + Point<2> p2d[4]; + + for (k = 0; k < 4; k++) + lp[k] = mesh->Point (el[k]); + + + 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 < 4; 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 < 4; 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)); + } + + 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 lami[3]; + Point3d p3d(2*rad*s+pmin(0), 2*rad*t+pmin(1),0); + + if (mesh->PointContainedIn2DElement (p3d, lami, sei+1)) + { + Point<3> cp = p3d; + double lam1 = lami[0]; + double lam2 = lami[1]; + + //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); + (*testout) << "sei " << sei << " lam1 " << lam1 << " lam2 " << lam2 << " drawelem " << drawelem << endl; + + 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); + + (*testout) << "v " << v << endl; + + if (val > 1e-10 * maxval) + v *= (rad / val / gridsize * 0.5); + + (*testout) << "v " << v << endl; + + if ( drawelem ) + { + DrawCone (cp, cp+4*v, 0.8*rad / gridsize); + (*testout) << "cp " << cp << " rad " << rad << " gridsize " << gridsize << endl; + } + + } + } + */ + } + } + } + } + + + + + void VisualSceneSolution :: + DrawIsoLines (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + double val1, double val2, double val3) + { + 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 Point<3> & hp1, + const Point<3> & hp2, + const Point<3> & hp3, + const Point<3> & hp4, + double val1, double val2, double val3, double val4) + { + int n = numisolines; + Point<3> p1, p2, p3, p4; + if (val1 < val2) + { + p1 = hp1; p2 = hp2; + } + else + { + p1 = hp2; p2 = hp1; + swap (val1, val2); + } + + if (val3 < val4) + { + p3 = hp3; p4 = hp4; + } + else + { + p3 = hp4; p4 = hp3; + swap (val3, val4); + } + + 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; 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) + { + Point<3> lp1 = p1 + lam1 * (p2-p1); + Point<3> lp2 = p3 + lam2 * (p4-p3); + glVertex3dv (lp1 ); + glVertex3dv (lp2 ); + // glVertex3dv (lp2 ); // better ? + // glVertex3dv (lp1 ); + } + } + } + + + + void VisualSceneSolution :: + GetMinMax (int funcnr, int comp, double & minv, double & maxv) const + { + 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) + ELEMENT_TYPE type = mesh->SurfaceElement(i+1).GetType(); + if (type == QUAD) + considerElem = GetSurfValue (sol, i, 0.5, 0.5, comp, val); + else + considerElem = GetSurfValue (sol, i, 0.3333333, 0.3333333, comp, val); + if (considerElem) + { + if (val > maxv || !hasit) + maxv = val; + if (val < minv || !hasit) + minv = val; + hasit = true; + } + } + } + } + if (minv == maxv) maxv = minv+1e-6; + } + + + + + + 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 :: + GetValues (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const + { + bool ok; + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ok = data->solclass->GetValue (elnr, xref, x, dxdxref, values); + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetValue (data, elnr, xref[0], xref[1], xref[2], i+1, values[i]); + } + } + return ok; + } + + + bool VisualSceneSolution :: + GetValue (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const + { + + double lam1 = xref[0]; + double lam2 = xref[1]; + double lam3 = xref[2]; + + val = 0; + bool ok = 0; + + + if (comp == 0) + { + ArrayMem values(data->components); + ok = GetValues (data, elnr, xref, x, dxdxref, &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 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, xref, x, dxdxref, 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 :: + 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 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 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 :: + GetValueComplex (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + int comp, double & valr, double & vali) const + { + + valr = 0; + vali = 0; + bool ok = 0; + + + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + double values[20]; + ok = data->solclass->GetValue (elnr, lam1, lam2, lam3, values); + valr = values[comp-1]; + vali = values[comp]; + return ok; + } + + } + 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); + // ok = 1; + // values[0] = 1.0; + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetSurfValue (data, selnr, lam1, lam2, i+1, values[i]); + } + } + return ok; + } + + + bool VisualSceneSolution :: + GetSurfValues (const SolData * data, SurfaceElementIndex selnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const + { + bool ok; + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ok = data->solclass->GetSurfValue (selnr, xref, x, dxdxref, values); + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetSurfValue (data, selnr, xref[0], xref[1], i+1, values[i]); + } + } + return ok; + } + + + + bool VisualSceneSolution :: + GetSurfValueComplex (const SolData * data, SurfaceElementIndex selnr, + double lam1, double lam2, + int comp, double & valr, double & vali) const + { + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ArrayMem values(data->components); + bool ok; + + ok = data->solclass->GetSurfValue (selnr, lam1, lam2, &values[0]); + + if (ok) + { + if (!data->iscomplex) + { + valr = values[comp-1]; + vali = 0; + } + else + { + valr = values[comp-1]; + vali = values[comp]; + } + } + + return ok; + } + } + return 0; + } + + 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 values(data->components); + ok = GetSurfValues (data, selnr, lam1, lam2, &values[0]); + // ok = 1; + // values[0] = 1.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 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 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; + + // old version: val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); + // SZ: Sept 06 + if(comp%2==0) + val = values[comp-1]*cos(3*time) - values[comp-2]*sin(3*time); + else + 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; + } + + + + + + + + + + + + + bool VisualSceneSolution :: + GetSurfValue (const SolData * data, SurfaceElementIndex selnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const + { + double lam1 = xref[0], lam2 = xref[1]; + + bool ok; + if (comp == 0) + { + val = 0; + ArrayMem values(data->components); + ok = GetSurfValues (data, selnr, xref, x, dxdxref, &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 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 values(data->components); + bool ok; + + // ok = data->solclass->GetSurfValue (selnr, lam1, lam2, &values[0]); + // cout << "data->solclass = " << flush << data->solclass << endl; + ok = data->solclass->GetSurfValue (selnr, xref, x, dxdxref, &values[0]); + // ok = 1; + // values[0] = 1.0; + + if (ok) + { + if (!data->iscomplex) + val = values[comp-1]; + else + { + // cout << "time = " << time << ", cos = " << cos(time) << endl; + + // old version: val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); + // SZ: Sept 06 + if(comp%2==0) + val = values[comp-1]*cos(3*time) - values[comp-2]*sin(3*time); + else + 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; + } + + + + + + + + + + Vec<3> VisualSceneSolution :: + GetDeformation (ElementIndex elnr, const Point<3> & p) const + { + Vec<3> def; + if (deform && vecfunction != -1) + { + GetValues (soldata[vecfunction], elnr, p(0), p(1), p(2), &def(0)); + def *= scaledeform; + + if (soldata[vecfunction]->dist == 2) def(2) = 0; + } + else + def = 0; + return def; + } + + + Vec<3> VisualSceneSolution :: + GetSurfDeformation (SurfaceElementIndex elnr, double lam1, double lam2) const + { + Vec<3> def; + if (deform && vecfunction != -1) + { + GetSurfValues (soldata[vecfunction], elnr, lam1, lam2, &def(0)); + def *= scaledeform; + + if (soldata[vecfunction]->dist == 2) def(2) = 0; + } + else if (deform && scalfunction != -1 && mesh->GetDimension()==2) + { // he: allow for 3d plots of 2d surfaces: usage: turn deformation on + def = 0; + GetSurfValue (soldata[scalfunction], elnr, lam1, lam2, scalcomp, def(2)); + def *= scaledeform; + } + else + def = 0; + return def; + } + + 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 & trigs, + ARRAY & pts) + { + static int timer1 = NgProfiler::CreateTimer ("ClipPlaneTrigs1"); + static int timer2 = NgProfiler::CreateTimer ("ClipPlaneTrigs2"); + static int timer3 = NgProfiler::CreateTimer ("ClipPlaneTrigs3"); + static int timer4 = NgProfiler::CreateTimer ("ClipPlaneTrigs4"); + + + NgProfiler::RegionTimer reg1 (timer1); + + int np = mesh->GetNP(); + int ne = mesh->GetNE(); + + 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 loctets; + // ARRAY loctetsloc; + // ARRAY > pointsloc; + + int n = 1 << subdivisions; + int n3 = (n+1)*(n+1)*(n+1); + + ARRAY > grid(n3); + ARRAY > locgrid(n3); + ARRAY > trans(n3); + ARRAY val(n3); + ARRAY compress(n3); + + + for (ElementIndex ei = 0; ei < ne; ei++) + { + int first_point_of_element = pts.Size(); + +#ifdef PARALLEL + // parallel visualization --> dont draw ghost elements + if ( (*mesh)[ei] . IsGhost() ) continue; +#endif + + locgrid.SetSize(n3); + if(vispar.clipdomain > 0 && vispar.clipdomain != (*mesh)[ei].GetIndex()) continue; + if(vispar.donotclipdomain > 0 && vispar.donotclipdomain == (*mesh)[ei].GetIndex()) continue; + + ELEMENT_TYPE type = (*mesh)[ei].GetType(); + if (type == HEX || type == PRISM || type == TET || type == TET10 || type == PYRAMID) + { + const Element & el = (*mesh)[ei]; + + int ii = 0; + int cnt_valid = 0; + + NgProfiler::StartTimer (timer2); + + + if (type == TET || type == TET10) + { + for (int ix = 0; ix <= n; ix++) + for (int iy = 0; iy <= n; iy++) + for (int iz = 0; iz <= n; iz++, ii++) + { + if (ix+iy+iz <= n) + { + compress[ii] = cnt_valid; + locgrid[cnt_valid] = + Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + cnt_valid++; + } + else + compress[ii] = -1; + } + } + + else + + 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; + compress[ii] = ii; + + switch (type) + { + case PRISM: + if (ix+iy <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + /* + case TET: + case TET10: + if (ix+iy+iz <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + */ + case HEX: + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + break; + case PYRAMID: + ploc = Point<3> (double(ix) / n * (1-double(iz)/n), + double(iy) / n * (1-double(iz)/n), + double(iz)/n); + if (iz == n) ploc = Point<3> (0,0,1-1e-8); + break; + } + if (compress[ii] != -1) + locgrid[compress[ii]] = ploc; + } + + if (type != TET && type != TET10 && type != PRISM) cnt_valid = n3; + + locgrid.SetSize(cnt_valid); + + NgProfiler::StopTimer (timer2); + NgProfiler::RegionTimer reg4(timer4); + + if (mesh->GetCurvedElements().IsHighOrder()) + { + mesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&locgrid, ei, &grid, 0); + } + else + { + Vector shape(el.GetNP()); + MatrixFixWidth<3> pointmat(el.GetNP()); + + for (int k = 0; k < el.GetNP(); k++) + for (int j = 0; j < 3; j++) + pointmat(k,j) = (*mesh)[el[k]](j); + + for (int i = 0; i < cnt_valid; i++) + { + el.GetShapeNew (locgrid[i], shape); + Point<3> pglob; + for (int j = 0; j < 3; j++) + { + pglob(j) = 0; + for (int k = 0; k < el.GetNP(); k++) + pglob(j) += shape(k) * pointmat(k,j); + } + grid[i] = pglob; + } + } + + NgProfiler::RegionTimer reg3(timer3); + + bool has_pos = 0, has_neg = 0; + + for (int i = 0; i < cnt_valid; i++) + { + val[i] = + grid[i](0) * clipplane[0] + + grid[i](1) * clipplane[1] + + grid[i](2) * clipplane[2] + + clipplane[3]; + + if (val[i] > 0) + has_pos = 1; + else + has_neg = 1; + } + + if (!has_pos || !has_neg) continue; + + + 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 }; + + for (int j = 0; j < 8; j++) + pi[j] = compress[pi[j]]; + + const int tets[6][4] = + { { 1, 2, 4, 5 }, + { 4, 5, 2, 8 }, + { 2, 8, 5, 6 }, + { 2, 3, 4, 8 }, + { 2, 3, 8, 6 }, + { 3, 8, 6, 7 } }; + + for (int ii = 0; ii < 6; ii++) + { + int teti[4]; + for (int k = 0; k < 4; k++) + teti[k] = pi[tets[ii][k]-1]; + + bool is_valid = 1; + for (int j = 0; j < 4; j++) + if (teti[j] == -1) is_valid = 0; + if (!is_valid) continue; + + for (int j = 0; j < 4; j++) + nodevali[j] = val[teti[j]]; + + cntce = 0; + for (int 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]]; + + // cpt.points[k].lami = p2 + edgelam[ednr] * (p1-p2); + + ClipPlanePoint cppt; + cppt.elnr = ei; + cppt.p = edgep[ednr]; + cppt.lami = p2 + edgelam[ednr] * (p1-p2); + + int pnr = -1; + + for (int l = first_point_of_element; l < pts.Size(); l++) + if (fabs (cppt.lami(0)-pts[l].lami(0)) < 1e-8 && + fabs (cppt.lami(1)-pts[l].lami(1)) < 1e-8 && + fabs (cppt.lami(2)-pts[l].lami(2)) < 1e-8) + { + pnr = l; + break; + } + + if (pnr == -1) + pnr = pts.Append (cppt)-1; + + cpt.points[k].pnr = pnr; + cpt.points[k].locpnr = pnr-first_point_of_element; + } + + trigs.Append (cpt); + } + } + } + } + } + } + + else + { // other elements not supported (JS, June 2007) + return; + /* + + + ARRAY 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 Element & el = mesh->VolumeElement(i); + + (*mesh)[ei].GetTets (loctets); + (*mesh)[ei].GetTetsLocal (loctetsloc); + // (*mesh)[ei].GetNodesLocal (pointsloc); + (*mesh)[ei].GetNodesLocalNew (pointsloc); + + for (int ii = 0; ii < loctets.Size(); ii++) + { + const Element & el = loctets[ii]; + + for (int j = 0; j < 4; j++) + nodevali[j] = nodevals.Get(el[j]); + + cntce = 0; + for (int 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 (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 = pointsloc.Get (loctetsloc[ii][pi1]); + Point<3> p2 = pointsloc.Get (loctetsloc[ii][pi2]); + for (int 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 & 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; + + + int cindex(-1); + bool allowindex(true); + if(vispar.clipdomain > 0) + { + cindex = vispar.clipdomain; + } + else if(vispar.donotclipdomain > 0) + { + allowindex = false; + cindex = vispar.donotclipdomain; + } + elnr = mesh->GetElementOfPoint (hp, lami,0,cindex,allowindex)-1; + + if (elnr != -1) + { + ClipPlanePoint cpp; + cpp.p = hp; + cpp.elnr = elnr; + cpp.lami(0) = lami[0]; + cpp.lami(1) = lami[1]; + cpp.lami(2) = lami[2]; + pts.Append (cpp); + } + } + }; + + + + void VisualSceneSolution :: + SetOpenGlColor(double val) + { + if (usetexture == 1 && !logscale) + { + glColor3d (1, 1, 1); + glTexCoord1f ( val ); + return; + } + + double valmin = minval; + double valmax = maxval; + + double value; + + if (!logscale) + value = (val - valmin) / (valmax - valmin); + else + { + if (valmax <= 0) valmax = 1; + if (valmin <= 0) valmin = 1e-4 * valmax; + value = (log(fabs(val)) - log(valmin)) / (log(valmax) - log(valmin)); + } + + if (!invcolor) + value = 1 - value; + + if (usetexture) + { + glColor3d (1, 1, 1); + 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 :: + SetOpenGlColor(double h, double valmin, double valmax, int logscale) + { + if (usetexture == 1 && !logscale) + { + glColor3d (1, 1, 1); + glTexCoord1f ( h ); + return; + } + + + double value; + + if (!logscale) + value = (h - valmin) / (valmax - valmin); + else + { + if (valmax <= 0) valmax = 1; + if (valmin <= 0) valmin = 1e-4 * valmax; + value = (log(fabs(h)) - log(valmin)) / (log(valmax) - log(valmin)); + } + + if (!invcolor) + value = 1 - value; + + if (usetexture) + { + glColor3d (1, 1, 1); + 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) + { + vsmesh.SetClippingPlane(); + vsmesh.BuildFilledList(); + vsmesh.MouseDblClick(px,py); + } + + + void VisualSceneSolution :: + DrawClipPlaneTrigs (const SolData * sol, int comp, + const ARRAY & trigs, + const ARRAY & points) + { + int maxlpnr = 0; + for (int i = 0; i < trigs.Size(); i++) + for (int j = 0; j < 3; j++) + maxlpnr = max2 (maxlpnr, trigs[i].points[j].locpnr); + + ArrayMem vals(maxlpnr+1); + ArrayMem elnrs(maxlpnr+1); + ArrayMem trigok(maxlpnr+1); + trigok = false; + elnrs = -1; + + Point<3> p[3]; + double val[3],vali[3]; + + for (int i = 0; i < trigs.Size(); i++) + { + const ClipPlaneTrig & trig = trigs[i]; + bool ok = true; + for (int j = 0; ok && j < 3; j++) + { + p[j] = points[trig.points[j].pnr].p; + Point<3> ploc = points[trig.points[j].pnr].lami; + + if (deform) + p[j] += GetDeformation (trig.elnr, ploc); + + if (usetexture != 2 || !sol->iscomplex) + { + if (elnrs[trig.points[j].locpnr] != trig.elnr) + { + elnrs[trig.points[j].locpnr] = trig.elnr; + + Point<3> pglob; + Mat<3> trans; + + mesh->GetCurvedElements(). + CalcElementTransformation (ploc, trig.elnr, pglob, trans); + + //double val; + ok = GetValue (sol, trig.elnr, &ploc(0), &pglob(0), &trans(0,0), scalcomp, val[j]); + vals[trig.points[j].locpnr] = val[j]; + trigok[trig.points[j].locpnr] = ok; + } + else + { + ok = trigok[trig.points[j].locpnr]; + //SetOpenGlColor (vals[trig.points[j].locpnr]); + } + } + else + { + //double valr, vali; + ok = GetValueComplex (sol, trig.elnr, ploc(0), ploc(1), ploc(2), + scalcomp, val[j], vali[j]); + + //glTexCoord2f ( valr, vali ); + } + //glVertex3dv (p); + } + + if(ok) + for(int j=0; j<3; j++) + { + if (usetexture != 2 || !sol->iscomplex) + { + if (elnrs[trig.points[j].locpnr] != trig.elnr) + SetOpenGlColor(val[j]); + else + SetOpenGlColor (vals[trig.points[j].locpnr]); + } + else + glTexCoord2f ( val[j], vali[j] ); + + glVertex3dv (p[j]); + } + + } + } + + +#ifdef PARALLELGL + + void VisualSceneSolution :: Broadcast () + { + MyMPI_Bcast (usetexture); + MyMPI_Bcast (clipsolution); + MyMPI_Bcast (scalfunction); + MyMPI_Bcast (scalcomp); + MyMPI_Bcast (vecfunction); + MyMPI_Bcast (gridsize); + + MyMPI_Bcast (autoscale); + MyMPI_Bcast (logscale); + MyMPI_Bcast (minval); + MyMPI_Bcast (maxval); + MyMPI_Bcast (numisolines); + MyMPI_Bcast (subdivisions); + } + +#endif + + + 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", TCL_GLOBAL_ONLY)); + vssolution.usetexture = + atoi (Tcl_GetVar (interp, "::visoptions.usetexture", TCL_GLOBAL_ONLY)); + if (atoi (Tcl_GetVar (interp, "::visoptions.redrawperiodic", TCL_GLOBAL_ONLY))) + vssolution.usetexture = 2; + + vssolution.invcolor = + atoi (Tcl_GetVar (interp, "::visoptions.invcolor", TCL_GLOBAL_ONLY)); + + vssolution.clipsolution = 0; + + if (strcmp (Tcl_GetVar (interp, "::visoptions.clipsolution", TCL_GLOBAL_ONLY), + "scal") == 0) + vssolution.clipsolution = 1; + if (strcmp (Tcl_GetVar (interp, "::visoptions.clipsolution", TCL_GLOBAL_ONLY), + "vec") == 0) + vssolution.clipsolution = 2; + + tcl_const char * scalname = + Tcl_GetVar (interp, "::visoptions.scalfunction", TCL_GLOBAL_ONLY); + tcl_const char * vecname = + Tcl_GetVar (interp, "::visoptions.vecfunction", TCL_GLOBAL_ONLY); + tcl_const char * fieldlines_vecname = + Tcl_GetVar (interp, "::visoptions.fieldlinesvecfunction", TCL_GLOBAL_ONLY); + + + vssolution.scalfunction = -1; + vssolution.vecfunction = -1; + vssolution.fieldlines_vecfunction = -1; + + int pointpos; // SZ + const char * 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 ( vssolution.scalcomp > vssolution.soldata[i]->components ) + vssolution.scalcomp = 1; + char newscalname[100]; + for ( int ii = 0; ii < pointpos; ii++ ) + newscalname[ii] = scalname[ii]; + newscalname[pointpos] = '.'; + sprintf (newscalname+pointpos, "%i", vssolution.scalcomp); + + if (strcmp (scalname, newscalname) != 0) + Tcl_SetVar ( interp, "::visoptions.scalfunction", newscalname, TCL_GLOBAL_ONLY ); + + } + if (strcmp (vssolution.soldata[i]->name, vecname) == 0) + { + vssolution.vecfunction = i; + //cout << "set vecfunction to " << i << endl; + } + if (strcmp (vssolution.soldata[i]->name, fieldlines_vecname) == 0) + { + vssolution.fieldlines_vecfunction = i; + //cout << "set fieldlines-vecfunction to " << i << endl; + } + } + + if(vssolution.fieldlines_vecfunction != -1 && + vssolution.vecfunction == -1) + { + //cout << "WARNING: Setting vector function in Visualization toolbox to value from Fieldlines toolbox!" << endl; + vssolution.vecfunction = vssolution.fieldlines_vecfunction; + } + + // reset visoptions.scalfunction and visoptions.vecfunction if not avialable + if ( vssolution.scalfunction == -1 && strcmp (scalname, "none") != 0) + Tcl_SetVar ( interp, "::visoptions.scalfunction", "none", TCL_GLOBAL_ONLY ); + if ( vssolution.vecfunction == -1 && strcmp (vecname, "none") != 0) + Tcl_SetVar ( interp, "::visoptions.vecfunction", "none", TCL_GLOBAL_ONLY ); + + tcl_const char * evalname = + Tcl_GetVar (interp, "::visoptions.evaluate", TCL_GLOBAL_ONLY); + + 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", TCL_GLOBAL_ONLY)); + + vssolution.xoffset = + atof (Tcl_GetVar (interp, "::visoptions.xoffset", TCL_GLOBAL_ONLY)); + + // cout << "x-offset:" << vssolution.xoffset << endl; + + vssolution.yoffset = + atof (Tcl_GetVar (interp, "::visoptions.yoffset", TCL_GLOBAL_ONLY)); + + vssolution.autoscale = + atoi (Tcl_GetVar (interp, "::visoptions.autoscale", TCL_GLOBAL_ONLY)); + + + /* + vssolution.linear_colors = + atoi (Tcl_GetVar (interp, "::visoptions.lineartexture", TCL_GLOBAL_ONLY)); + */ + vssolution.logscale = + atoi (Tcl_GetVar (interp, "::visoptions.logscale", TCL_GLOBAL_ONLY)); + + vssolution.mminval = + atof (Tcl_GetVar (interp, "::visoptions.mminval", TCL_GLOBAL_ONLY)); + vssolution.mmaxval = + atof (Tcl_GetVar (interp, "::visoptions.mmaxval", TCL_GLOBAL_ONLY)); + + vssolution.showclipsolution = + atoi (Tcl_GetVar (interp, "::visoptions.showclipsolution", TCL_GLOBAL_ONLY)); + vssolution.showsurfacesolution = + atoi (Tcl_GetVar (interp, "::visoptions.showsurfacesolution", TCL_GLOBAL_ONLY)); + vssolution.lineartexture = + atoi (Tcl_GetVar (interp, "::visoptions.lineartexture", TCL_GLOBAL_ONLY)); + vssolution.numtexturecols = + atoi (Tcl_GetVar (interp, "::visoptions.numtexturecols", TCL_GLOBAL_ONLY)); + + vssolution.multidimcomponent = + atoi (Tcl_GetVar (interp, "::visoptions.multidimcomponent", TCL_GLOBAL_ONLY)); + + vssolution.drawpointcurves = + atoi (Tcl_GetVar (interp, "::visoptions.drawpointcurves", TCL_GLOBAL_ONLY)); + + vssolution.draw_fieldlines = + atoi (Tcl_GetVar (interp, "::visoptions.drawfieldlines", TCL_GLOBAL_ONLY)); + vssolution.num_fieldlines = + atoi (Tcl_GetVar (interp, "::visoptions.numfieldlines", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_randomstart = + atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesrandomstart", TCL_GLOBAL_ONLY)); + + vssolution.fieldlines_reltolerance = + atof (Tcl_GetVar (interp, "::visoptions.fieldlinestolerance", TCL_GLOBAL_ONLY)); + + if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "euler") == 0) + vssolution.fieldlines_rktype = 0; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "eulercauchy") == 0) + vssolution.fieldlines_rktype = 1; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "simpson") == 0) + vssolution.fieldlines_rktype = 2; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "crungekutta") == 0) + vssolution.fieldlines_rktype = 3; + + + vssolution.fieldlines_rellength = + atof (Tcl_GetVar (interp, "::visoptions.fieldlineslength", TCL_GLOBAL_ONLY)); + + vssolution.fieldlines_maxpoints = + atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesmaxpoints", TCL_GLOBAL_ONLY)); + + vssolution.fieldlines_relthickness = + atof (Tcl_GetVar (interp, "::visoptions.fieldlinesthickness", TCL_GLOBAL_ONLY)); + + + vssolution.fieldlines_fixedphase = + (atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesonlyonephase", TCL_GLOBAL_ONLY)) != 0); + + if(vssolution.fieldlines_fixedphase) + vssolution.fieldlines_phase = + atof (Tcl_GetVar (interp, "::visoptions.fieldlinesphase", TCL_GLOBAL_ONLY)); + + + if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesstartarea", TCL_GLOBAL_ONLY), + "box") == 0) + vssolution.fieldlines_startarea = 0; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesstartarea", TCL_GLOBAL_ONLY), + "file") == 0) + vssolution.fieldlines_startarea = 1; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesstartarea", TCL_GLOBAL_ONLY), + "face") == 0) + vssolution.fieldlines_startarea = 2; + + + if (vssolution.fieldlines_startarea == 0) + { + vssolution.fieldlines_startarea_parameter.SetSize(6); + vssolution.fieldlines_startarea_parameter[0] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap1x", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[1] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap1y", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[2] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap1z", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[3] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap2x", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[4] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap2y", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[5] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap2z", TCL_GLOBAL_ONLY)); + } + else if (vssolution.fieldlines_startarea == 1) + { + vssolution.fieldlines_filename = Tcl_GetVar (interp, "::visoptions.fieldlinesfilename", TCL_GLOBAL_ONLY); + } + else if (vssolution.fieldlines_startarea == 2) + { + vssolution.fieldlines_startface = atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesstartface", TCL_GLOBAL_ONLY)); + } + + + vssolution.deform = + atoi (Tcl_GetVar (interp, "::visoptions.deformation", TCL_GLOBAL_ONLY)); + vssolution.scaledeform = + atof (Tcl_GetVar (interp, "::visoptions.scaledeform1", TCL_GLOBAL_ONLY)) * + atof (Tcl_GetVar (interp, "::visoptions.scaledeform2", TCL_GLOBAL_ONLY)); + + + if (atoi (Tcl_GetVar (interp, "::visoptions.isolines", TCL_GLOBAL_ONLY))) + vssolution.numisolines = atoi (Tcl_GetVar (interp, "::visoptions.numiso", TCL_GLOBAL_ONLY)); + else + vssolution.numisolines = 0; + vssolution.draw_isosurface = + atoi (Tcl_GetVar (interp, "::visoptions.isosurf", TCL_GLOBAL_ONLY)); + + vssolution.SetSubdivision(atoi (Tcl_GetVar (interp, "::visoptions.subdivisions", TCL_GLOBAL_ONLY))); + + vssolution.UpdateSolutionTimeStamp(); + } + + if (strcmp (argv[1], "parametersrange") == 0) + { + vssolution.invcolor = + atoi (Tcl_GetVar (interp, "::visoptions.invcolor", TCL_GLOBAL_ONLY)); + vssolution.mminval = + atof (Tcl_GetVar (interp, "::visoptions.mminval", TCL_GLOBAL_ONLY)); + vssolution.mmaxval = + atof (Tcl_GetVar (interp, "::visoptions.mmaxval", TCL_GLOBAL_ONLY)); + vssolution.lineartexture = + atoi (Tcl_GetVar (interp, "::visoptions.lineartexture", TCL_GLOBAL_ONLY)); + vssolution.numtexturecols = + atoi (Tcl_GetVar (interp, "::visoptions.numtexturecols", TCL_GLOBAL_ONLY)); + + if (vssolution.usetexture == 0 || vssolution.logscale) + vssolution.UpdateSolutionTimeStamp(); + } + + + if (argc >= 3 && strcmp (argv[1], "time") == 0) + { + vssolution.time = double (atoi (argv[2])) / 1000; + + vssolution.timetimestamp = NextTimeStamp(); + cout << "\rtime = " << vssolution.time << " " << flush; + } + + } + +#ifdef PARALLELGL + vsmesh.Broadcast (); +#endif + + + 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; + } +} + +#endif // NOTCL diff --git a/libsrc/visualization/vssolution.hpp b/libsrc/visualization/vssolution.hpp new file mode 100644 index 00000000..139aa496 --- /dev/null +++ b/libsrc/visualization/vssolution.hpp @@ -0,0 +1,414 @@ +#ifndef FILE_VSSOLUTION +#define FILE_VSSOLUTION + + + +#ifndef SMALLLIB +#ifndef NOTCL + +extern int Ng_Vis_Set (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); +#endif +#endif + +class FieldLineCalc; + +class VisualSceneSolution : public VisualScene +{ + friend class FieldLineCalc; + + class ClipPlaneTrig + { + public: + struct ps + { + int pnr, locpnr; + }; + ps points[3]; + ElementIndex elnr; + }; + + class ClipPlanePoint + { + public: + ElementIndex elnr; + Point<3> lami; + Point<3> p; + }; + + + int surfellist; + int linelist; + int clipplanelist; + int isolinelist; + int clipplane_isolinelist; + int surface_vector_list; + int cone_list; + int isosurface_list; + + int pointcurvelist; + + bool draw_fieldlines; + bool drawpointcurves; + bool draw_isosurface; + int num_fieldlines; + bool fieldlines_randomstart; + int fieldlineslist; + int num_fieldlineslists; + int fieldlines_startarea; + ARRAY fieldlines_startarea_parameter; + int fieldlines_startface; + string fieldlines_filename; + double fieldlines_reltolerance; + int fieldlines_rktype; + double fieldlines_rellength; + double fieldlines_relthickness; + int fieldlines_vecfunction; + bool fieldlines_fixedphase; + float fieldlines_phase; + int fieldlines_maxpoints; + + + int surfeltimestamp, clipplanetimestamp, solutiontimestamp; + int surfellinetimestamp; + int fieldlinestimestamp, surface_vector_timestamp; + int pointcurve_timestamp; + int isosurface_timestamp; + int subdivision_timestamp; + int timetimestamp; + double minval, maxval; + + NgLock *lock; + + +#ifdef PARALLELGL + ARRAY par_linelists; + ARRAY par_surfellists; +#endif + + +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; + + + + + int usetexture; // 0..no, 1..1D texture (standard), 2..2D-texture (complex) + 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; + +private: + void BuildFieldLinesFromFile(ARRAY & startpoints); + void BuildFieldLinesFromFace(ARRAY & startpoints); + void BuildFieldLinesFromBox(ARRAY & startpoints); + void BuildFieldLinesFromLine(ARRAY & startpoints); + +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); + + + static void RealVec3d (const double * values, Vec3d & v, + bool iscomplex, bool imag); + static void RealVec3d (const double * values, Vec3d & v, + bool iscomplex, double phaser, double phasei); + + + void SetSubdivision (int sd) + { + subdivisions = sd; + subdivision_timestamp = solutiontimestamp = NextTimeStamp(); + } + +private: + void GetMinMax (int funcnr, int comp, double & minv, double & maxv) const; + + void GetClippingPlaneTrigs (ARRAY & trigs, ARRAY & pts); + void GetClippingPlaneGrid (ARRAY & 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 GetValue (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const; + + bool GetValueComplex (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + int comp, double & valr, double & vali) const; + + bool GetValues (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + double * values) const; + + bool GetValues (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const; + + bool GetSurfValue (const SolData * data, SurfaceElementIndex elnr, + double lam1, double lam2, + int comp, double & val) const; + + bool GetSurfValue (const SolData * data, SurfaceElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const; + + bool GetSurfValueComplex (const SolData * data, SurfaceElementIndex elnr, + double lam1, double lam2, + int comp, double & valr, double & vali) const; + + bool GetSurfValues (const SolData * data, SurfaceElementIndex elnr, + double lam1, double lam2, + double * values) const; + + bool GetSurfValues (const SolData * data, SurfaceElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const; + + + + Vec<3> GetDeformation (ElementIndex elnr, const Point<3> & p) const; + Vec<3> GetSurfDeformation (SurfaceElementIndex selnr, double lam1, double lam2) const; + + void GetPointDeformation (int pnum, Point<3> & p, SurfaceElementIndex elnr = -1) const; + +public: + /// draw elements (build lists) + void DrawSurfaceElements (); + void DrawSurfaceElementLines (); + void DrawSurfaceVectors (); + void DrawTrigSurfaceVectors(const ARRAY< Point<3> > & lp, const Point<3> & pmin, const Point<3> & pmax, + const int sei, const SolData * vsol); + void DrawIsoSurface(const SolData * sol, const SolData * grad, int comp); + + void DrawIsoLines (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & 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 Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + const Point<3> & p4, + double val1, double val2, double val3, double val4); + + // double minval, double maxval, int n); + + + void DrawClipPlaneTrigs (const SolData * sol, int comp, + const ARRAY & trigs, + const ARRAY & points); + + void SetOpenGlColor(double val, double valmin, double valmax, int logscale = 0); + + void SetOpenGlColor(double val); + +#ifndef SMALLLIB +#ifndef NOTCL + + friend int Ng_Vis_Set (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + +#endif +#endif + + +#ifdef PARALLELGL + void Broadcast (); +#endif + + +}; + + + + +class RKStepper +{ +private: + ARRAY c,b; + TABLE *a; + int steps; + int order; + + double tolerance; + + ARRAY K; + + int stepcount; + + double h; + double startt; + double startt_bak; + Point3d startval; + Point3d startval_bak; + + bool adaptive; + int adrun; + Point3d valh; + + int notrestarted; + +public: + + ~RKStepper(); + + RKStepper(int type = 0); + + void SetTolerance(const double tol){tolerance = tol;} + + void StartNextValCalc(const Point3d & astartval, const double astartt, const double ah, const bool aadaptive = false); + + bool GetNextData(Point3d & val, double & t, double & ah); + + bool FeedNextF(const Vec3d & f); +}; + + + + + +class FieldLineCalc +{ +private: + const Mesh & mesh; + + VisualSceneSolution & vss; + + const VisualSceneSolution::SolData * vsol; + + RKStepper stepper; + + double maxlength; + + int maxpoints; + + int direction; + + Point3d pmin, pmax; + double rad; + double phaser, phasei; + + double critical_value; + + bool randomized; + + double thickness; + +public: + FieldLineCalc(const Mesh & amesh, VisualSceneSolution & avss, const VisualSceneSolution::SolData * solution, + const double rel_length, const int amaxpoints = -1, + const double rel_thickness = -1, const double rel_tolerance = -1, const int rk_type = 0, const int adirection = 0); + + void SetPhase(const double real, const double imag) { phaser = real; phasei = imag; } + + void SetCriticalValue(const double val) { critical_value = val; } + + void Randomized(void) { randomized = true; } + void NotRandomized(void) { randomized = false; } + + void Calc(const Point3d & startpoint, ARRAY & points, ARRAY & vals, ARRAY & drawelems, ARRAY & dirstart); + + void GenerateFieldLines(ARRAY & potential_startpoints, const int numlines, const int gllist, + const double minval, const double maxval, const int logscale, double phaser, double phasei); +}; + + + + +extern VisualSceneSolution vssolution; + + + + +#endif + diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 00000000..b36c4ad3 --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,8406 @@ +# Generated from ltmain.m4sh. + +# ltmain.sh (GNU libtool) 2.2.6 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print informational messages (default) +# --version print version information +# -h, --help print short or long help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.2.6 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=2.2.6 +TIMESTAMP="" +package_revision=1.3012 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# NLS nuisances: We save the old values to restore during execute mode. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done + +$lt_unset CDPATH + + + + + +: ${CP="cp -f"} +: ${ECHO="echo"} +: ${EGREP="/usr/bin/grep -E"} +: ${FGREP="/usr/bin/grep -F"} +: ${GREP="/usr/bin/grep"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SED="/opt/local/bin/gsed"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` +} + +# Generated shell functions inserted here. + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +# In the unlikely event $progname began with a '-', it would play havoc with +# func_echo (imagine progname=-n), so we prepend ./ in that case: +func_dirname_and_basename "$progpath" +progname=$func_basename_result +case $progname in + -*) progname=./$progname ;; +esac + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=: + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname${mode+: }$mode: $*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` + done + my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "X$my_tmpdir" | $Xsed +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "X$1" | $Xsed \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + + + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $SED -n '/^# Usage:/,/# -h/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + $ECHO + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help +# Echo long help message to standard output and exit. +func_help () +{ + $SED -n '/^# Usage:/,/# Report bugs to/ { + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + p + }' < "$progpath" + exit $? +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + func_error "missing argument for $1" + exit_cmd=exit +} + +exit_cmd=: + + + + + +# Check that we have a working $ECHO. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then + # Yippee, $ECHO works! + : +else + # Restart under the correct shell, and then maybe $ECHO will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# Parse options once, thoroughly. This comes as soon as possible in +# the script to make things like `libtool --version' happen quickly. +{ + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Parse non-mode specific arguments: + while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --config) func_config ;; + + --debug) preserve_args="$preserve_args $opt" + func_echo "enabling shell trace mode" + opt_debug='set -x' + $opt_debug + ;; + + -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break + execute_dlfiles="$execute_dlfiles $1" + shift + ;; + + --dry-run | -n) opt_dry_run=: ;; + --features) func_features ;; + --finish) mode="finish" ;; + + --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break + case $1 in + # Valid mode arguments: + clean) ;; + compile) ;; + execute) ;; + finish) ;; + install) ;; + link) ;; + relink) ;; + uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; + esac + + mode="$1" + shift + ;; + + --preserve-dup-deps) + opt_duplicate_deps=: ;; + + --quiet|--silent) preserve_args="$preserve_args $opt" + opt_silent=: + ;; + + --verbose| -v) preserve_args="$preserve_args $opt" + opt_silent=false + ;; + + --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break + preserve_args="$preserve_args $opt $1" + func_enable_tag "$1" # tagname is set here + shift + ;; + + # Separate optargs to long options: + -dlopen=*|--mode=*|--tag=*) + func_opt_split "$opt" + set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} + shift + ;; + + -\?|-h) func_usage ;; + --help) opt_help=: ;; + --version) func_version ;; + + -*) func_fatal_help "unrecognized option \`$opt'" ;; + + *) nonopt="$opt" + break + ;; + esac + done + + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_duplicate_deps + ;; + esac + + # Having warned about all mis-specified options, bail out if + # anything was wrong. + $exit_cmd $EXIT_FAILURE +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +## ----------- ## +## Main. ## +## ----------- ## + +$opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + test -z "$mode" && func_fatal_error "error: you must specify a MODE." + + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$mode' for more information." +} + + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_ltwrapper_scriptname_result="" + if func_ltwrapper_executable_p "$1"; then + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + fi +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_quote_for_eval "$arg" + CC_quoted="$CC_quoted $func_quote_for_eval_result" + done + case "$@ " in + " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + removelist="$removelist $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + removelist="$removelist $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + command="$command -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { +test "$mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$mode'" + ;; + esac + + $ECHO + $ECHO "Try \`$progname --help' for more information about other modes." + + exit $? +} + + # Now that we've collected a possible --mode arg, show help if necessary + $opt_help && func_mode_help + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_quote_for_eval "$file" + args="$args $func_quote_for_eval_result" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + $ECHO "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + $ECHO "X----------------------------------------------------------------------" | $Xsed + $ECHO "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + $ECHO + $ECHO "If you ever happen to want to link against installed libraries" + $ECHO "in a given directory, LIBDIR, you must either use libtool, and" + $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" + $ECHO "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" + $ECHO " during execution" + fi + if test -n "$runpath_var"; then + $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" + $ECHO " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $ECHO + + $ECHO "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" + $ECHO "pages." + ;; + *) + $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + $ECHO "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS +} + +test "$mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $ECHO "X$nonopt" | $GREP shtool >/dev/null; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + install_prog="$install_prog$func_quote_for_eval_result" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + install_prog="$install_prog $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_verbose "extracting global C symbols from \`$progfile'" + $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + $ECHO >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +" + case $host in + *cygwin* | *mingw* | *cegcc* ) + $ECHO >> "$output_objdir/$my_dlsyms" "\ +/* DATA imports from DLLs on WIN32 con't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs. */" + lt_dlsym_const= ;; + *osf5*) + echo >> "$output_objdir/$my_dlsyms" "\ +/* This system does not cope well with relocations in const data */" + lt_dlsym_const= ;; + *) + lt_dlsym_const=const ;; + esac + + $ECHO >> "$output_objdir/$my_dlsyms" "\ +extern $lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +$lt_dlsym_const lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + $ECHO >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) symtab_cflags="$symtab_cflags $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + + +# func_emit_wrapper_part1 [arg=no] +# +# Emit the first part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part1 () +{ + func_emit_wrapper_part1_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part1_arg1=$1 + fi + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + ECHO=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$ECHO works! + : + else + # Restart under the correct shell, and then maybe \$ECHO will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $ECHO "\ + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done +" +} +# end: func_emit_wrapper_part1 + +# func_emit_wrapper_part2 [arg=no] +# +# Emit the second part of a libtool wrapper script on stdout. +# For more information, see the description associated with +# func_emit_wrapper(), below. +func_emit_wrapper_part2 () +{ + func_emit_wrapper_part2_arg1=no + if test -n "$1" ; then + func_emit_wrapper_part2_arg1=$1 + fi + + $ECHO "\ + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} +# end: func_emit_wrapper_part2 + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=no + if test -n "$1" ; then + func_emit_wrapper_arg1=$1 + fi + + # split this up so that func_emit_cwrapperexe_src + # can call each part independently. + func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" + func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" +} + + +# func_to_host_path arg +# +# Convert paths to host format when used with build tools. +# Intended for use with "native" mingw (where libtool itself +# is running under the msys shell), or in the following cross- +# build environments: +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# where wine is equipped with the `winepath' executable. +# In the native mingw case, the (msys) shell automatically +# converts paths for any non-msys applications it launches, +# but that facility isn't available from inside the cwrapper. +# Similar accommodations are necessary for $host mingw and +# $build cygwin. Calling this function does no harm for other +# $host/$build combinations not listed above. +# +# ARG is the path (on $build) that should be converted to +# the proper representation for $host. The result is stored +# in $func_to_host_path_result. +func_to_host_path () +{ + func_to_host_path_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + case $build in + *mingw* ) # actually, msys + # awkward: cmd appends spaces to result + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_path_tmp1=`( cmd //c echo "$1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_path_tmp1=`cygpath -w "$1"` + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # Unfortunately, winepath does not exit with a non-zero + # error code, so we are forced to check the contents of + # stdout. On the other hand, if the command is not + # found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both + # error code of zero AND non-empty stdout, which explains + # the odd construction: + func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then + func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ + $SED -e "$lt_sed_naive_backslashify"` + else + # Allow warning below. + func_to_host_path_result="" + fi + ;; + esac + if test -z "$func_to_host_path_result" ; then + func_error "Could not determine host path corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_path_result="$1" + fi + ;; + esac + fi +} +# end: func_to_host_path + +# func_to_host_pathlist arg +# +# Convert pathlists to host format when used with build tools. +# See func_to_host_path(), above. This function supports the +# following $build/$host combinations (but does no harm for +# combinations not listed here): +# $build $host +# mingw (msys) mingw [e.g. native] +# cygwin mingw +# *nix + wine mingw +# +# Path separators are also converted from $build format to +# $host format. If ARG begins or ends with a path separator +# character, it is preserved (but converted to $host format) +# on output. +# +# ARG is a pathlist (on $build) that should be converted to +# the proper representation on $host. The result is stored +# in $func_to_host_pathlist_result. +func_to_host_pathlist () +{ + func_to_host_pathlist_result="$1" + if test -n "$1" ; then + case $host in + *mingw* ) + lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_to_host_pathlist_tmp2="$1" + # Once set for this call, this variable should not be + # reassigned. It is used in tha fallback case. + func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e 's|^:*||' -e 's|:*$||'` + case $build in + *mingw* ) # Actually, msys. + # Awkward: cmd appends spaces to result. + lt_sed_strip_trailing_spaces="s/[ ]*\$//" + func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + *cygwin* ) + func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ + $SED -e "$lt_sed_naive_backslashify"` + ;; + * ) + # unfortunately, winepath doesn't convert pathlists + func_to_host_pathlist_result="" + func_to_host_pathlist_oldIFS=$IFS + IFS=: + for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do + IFS=$func_to_host_pathlist_oldIFS + if test -n "$func_to_host_pathlist_f" ; then + func_to_host_path "$func_to_host_pathlist_f" + if test -n "$func_to_host_path_result" ; then + if test -z "$func_to_host_pathlist_result" ; then + func_to_host_pathlist_result="$func_to_host_path_result" + else + func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" + fi + fi + fi + IFS=: + done + IFS=$func_to_host_pathlist_oldIFS + ;; + esac + if test -z "$func_to_host_pathlist_result" ; then + func_error "Could not determine the host path(s) corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This may break if $1 contains DOS-style drive + # specifications. The fix is not to complicate the expression + # below, but for the user to provide a working wine installation + # with winepath so that path translation in the cross-to-mingw + # case works properly. + lt_replace_pathsep_nix_to_dos="s|:|;|g" + func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ + $SED -e "$lt_replace_pathsep_nix_to_dos"` + fi + # Now, add the leading and trailing path separators back + case "$1" in + :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" + ;; + esac + case "$1" in + *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" + ;; + esac + ;; + esac + fi +} +# end: func_to_host_pathlist + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +# define setmode _setmode +#else +# include +# include +# ifdef __CYGWIN__ +# include +# define HAVE_SETENV +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +#ifdef _MSC_VER +# define S_IXUSR _S_IEXEC +# define stat _stat +# ifndef _INTPTR_T_DEFINED +# define intptr_t int +# endif +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifdef __CYGWIN__ +# define FOPEN_WB "wb" +#endif + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#undef LTWRAPPER_DEBUGPRINTF +#if defined DEBUGWRAPPER +# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args +static void +ltwrapper_debugprintf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); +} +#else +# define LTWRAPPER_DEBUGPRINTF(args) +#endif + +const char *program_name = NULL; + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_fatal (const char *message, ...); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_opt_process_env_set (const char *arg); +void lt_opt_process_env_prepend (const char *arg); +void lt_opt_process_env_append (const char *arg); +int lt_split_name_value (const char *arg, char** name, char** value); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); + +static const char *script_text_part1 = +EOF + + func_emit_wrapper_part1 yes | + $SED -e 's/\([\\"]\)/\\\1/g' \ + -e 's/^/ "/' -e 's/$/\\n"/' + echo ";" + cat <"))); + for (i = 0; i < newargc; i++) + { + LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", + path ? (*path ? path : "EMPTY!") : "NULL!")); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", + wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", + tmp_pathspec)); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + char *errstr = strerror (errno); + lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal ("Could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} + +void +lt_setenv (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", + (name ? name : ""), + (value ? value : ""))); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +int +lt_split_name_value (const char *arg, char** name, char** value) +{ + const char *p; + int len; + if (!arg || !*arg) + return 1; + + p = strchr (arg, (int)'='); + + if (!p) + return 1; + + *value = xstrdup (++p); + + len = strlen (arg) - strlen (*value); + *name = XMALLOC (char, len); + strncpy (*name, arg, len-1); + (*name)[len - 1] = '\0'; + + return 0; +} + +void +lt_opt_process_env_set (const char *arg) +{ + char *name = NULL; + char *value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); + } + + lt_setenv (name, value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_prepend (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_opt_process_env_append (const char *arg) +{ + char *name = NULL; + char *value = NULL; + char *new_value = NULL; + + if (lt_split_name_value (arg, &name, &value) != 0) + { + XFREE (name); + XFREE (value); + lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); + } + + new_value = lt_extend_str (getenv (name), value, 1); + lt_setenv (name, new_value); + XFREE (new_value); + XFREE (name); + XFREE (value); +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + (name ? name : ""), + (value ? value : ""))); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + + +EOF +} +# end: func_emit_cwrapperexe_src + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) deplibs="$deplibs $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + weak_libs="$weak_libs $arg" + prev= + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname '-L' '' "$arg" + dir=$func_stripname_result + if test -z "$dir"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + arg="$arg $wl$func_quote_for_eval_result" + compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" + linker_flags="$linker_flags $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_duplicate_deps ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + case $lib in + *.la) func_source "$lib" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` + case " $weak_libs " in + *" $deplib_base "*) ;; + *) deplibs="$deplibs $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + dir=$func_stripname_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $ECHO + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because the file extensions .$libext of this argument makes me believe" + $ECHO "*** that it is just a static archive that I should not use here." + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + newlib_search_path="$newlib_search_path $func_stripname_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) temp_rpath="$temp_rpath$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + notinst_deplibs="$notinst_deplibs $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + $ECHO + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $ECHO + $ECHO "*** And there doesn't seem to be a static archive available" + $ECHO "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $ECHO + $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $ECHO "*** But as you try to build a module library, libtool will still create " + $ECHO "*** a static module, that should work as long as the dlopening application" + $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if $opt_duplicate_deps ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_dirname "$deplib" "" "." + dir="$func_dirname_result" + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + $ECHO + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + libobjs="$libobjs $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` + # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` + # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $ECHO + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + $ECHO "*** I have the capability to make that library automatically link in when" + $ECHO "*** you link to this library. But I can only do this if you have a" + $ECHO "*** shared version of the library, which you do not appear to have" + $ECHO "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ + -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` + done + fi + if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | + $GREP . >/dev/null; then + $ECHO + if test "X$deplibs_check_method" = "Xnone"; then + $ECHO "*** Warning: inter-library dependencies are not supported in this platform." + else + $ECHO "*** Warning: inter-library dependencies are not known to be supported." + fi + $ECHO "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $ECHO + $ECHO "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + $ECHO "*** a static module, that should work as long as the dlopening" + $ECHO "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $ECHO + $ECHO "*** However, this would only work if libtool was able to extract symbol" + $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" + $ECHO "*** not find such a program. So, this module is probably useless." + $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $ECHO "*** The inter-library dependencies that have been dropped here will be" + $ECHO "*** automatically added whenever a program is linked with this library" + $ECHO "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $ECHO + $ECHO "*** Since this library must not contain undefined symbols," + $ECHO "*** because either the platform does not support them or" + $ECHO "*** it was explicitly requested with -no-undefined," + $ECHO "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + delfiles="$delfiles $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$ECHO "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + $ECHO 'INPUT (' > $output + for obj in $save_libobjs + do + $ECHO "$obj" >> $output + done + $ECHO ')' >> $output + delfiles="$delfiles $output" + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + $ECHO "$obj" >> $output + done + delfiles="$delfiles $output" + output=$firstobj\"$file_list_spec$output\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + delfiles="$delfiles $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + libobjs="$libobjs $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *cegcc) + # Disable wrappers for cegcc, we are cross compiling anyway. + wrappers_required=no + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $ECHO for shipping. + if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + oldobjs="$oldobjs $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $dlprefiles + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $ECHO "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlfiles="$newdlfiles $libdir/$name" + ;; + *) newdlfiles="$newdlfiles $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + newdlprefiles="$newdlprefiles $libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$mode" = link || test "$mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) RM="$RM $arg"; rmforce=yes ;; + -*) RM="$RM $arg" ;; + *) files="$files $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + rmfiles="$rmfiles $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$mode" = uninstall || test "$mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/missing b/missing new file mode 100755 index 00000000..6a37006e --- /dev/null +++ b/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# 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 to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1Help2man' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 00000000..d2d5f21b --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/ng/Makefile.am b/ng/Makefile.am new file mode 100644 index 00000000..5751fef7 --- /dev/null +++ b/ng/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface +METASOURCES = AUTO +bin_PROGRAMS = netgen +netgen_SOURCES = demoview.cpp ngappinit.cpp ngpkg.cpp onetcl.cpp +netgen_LDADD = $(top_builddir)/libsrc/occ/libocc.a \ + $(top_builddir)/libsrc/csg/libcsg.a $(top_builddir)/libsrc/geom2d/libgeom2d.a \ + $(top_builddir)/libsrc/stlgeom/libstl.a $(top_builddir)/libsrc/visualization/libvisual.a \ + $(top_builddir)/libsrc/interface/libinterface.a $(top_builddir)/libsrc/meshing/libmesh.a \ + $(top_builddir)/libsrc/opti/libopti.a $(top_builddir)/libsrc/linalg/libla.a \ + $(top_builddir)/libsrc/gprim/libgprim.a $(top_builddir)/libsrc/general/libgeneral.a -lTKSTL -lTKSTEP -lTKBRep \ + -lTKIGES -L/usr/lib/tcl/Tix8.4.3 -L/usr/local/lib/Togl1.7 -lGLU -lTix8.4.3 \ + -lTogl1.7 -ltcl8.5 -ltk8.5 + +AM_CXXFLAGS = -DOPENGL diff --git a/ng/Makefile.in b/ng/Makefile.in new file mode 100644 index 00000000..697370a8 --- /dev/null +++ b/ng/Makefile.in @@ -0,0 +1,490 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = netgen$(EXEEXT) +subdir = ng +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_netgen_OBJECTS = demoview.$(OBJEXT) ngappinit.$(OBJEXT) \ + ngpkg.$(OBJEXT) onetcl.$(OBJEXT) +netgen_OBJECTS = $(am_netgen_OBJECTS) +netgen_DEPENDENCIES = $(top_builddir)/libsrc/occ/libocc.a \ + $(top_builddir)/libsrc/csg/libcsg.a \ + $(top_builddir)/libsrc/geom2d/libgeom2d.a \ + $(top_builddir)/libsrc/stlgeom/libstl.a \ + $(top_builddir)/libsrc/visualization/libvisual.a \ + $(top_builddir)/libsrc/interface/libinterface.a \ + $(top_builddir)/libsrc/meshing/libmesh.a \ + $(top_builddir)/libsrc/opti/libopti.a \ + $(top_builddir)/libsrc/linalg/libla.a \ + $(top_builddir)/libsrc/gprim/libgprim.a \ + $(top_builddir)/libsrc/general/libgeneral.a +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(netgen_SOURCES) +DIST_SOURCES = $(netgen_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface +METASOURCES = AUTO +netgen_SOURCES = demoview.cpp ngappinit.cpp ngpkg.cpp onetcl.cpp +netgen_LDADD = $(top_builddir)/libsrc/occ/libocc.a \ + $(top_builddir)/libsrc/csg/libcsg.a $(top_builddir)/libsrc/geom2d/libgeom2d.a \ + $(top_builddir)/libsrc/stlgeom/libstl.a $(top_builddir)/libsrc/visualization/libvisual.a \ + $(top_builddir)/libsrc/interface/libinterface.a $(top_builddir)/libsrc/meshing/libmesh.a \ + $(top_builddir)/libsrc/opti/libopti.a $(top_builddir)/libsrc/linalg/libla.a \ + $(top_builddir)/libsrc/gprim/libgprim.a $(top_builddir)/libsrc/general/libgeneral.a -lTKSTL -lTKSTEP -lTKBRep \ + -lTKIGES -L/usr/lib/tcl/Tix8.4.3 -L/usr/local/lib/Togl1.7 -lGLU -lTix8.4.3 \ + -lTogl1.7 -ltcl8.5 -ltk8.5 + +AM_CXXFLAGS = -DOPENGL +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ng/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu ng/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +netgen$(EXEEXT): $(netgen_OBJECTS) $(netgen_DEPENDENCIES) + @rm -f netgen$(EXEEXT) + $(CXXLINK) $(netgen_OBJECTS) $(netgen_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demoview.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngappinit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngpkg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onetcl.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ng/demoview.cpp b/ng/demoview.cpp new file mode 100644 index 00000000..71aec004 --- /dev/null +++ b/ng/demoview.cpp @@ -0,0 +1,442 @@ +/*********************************************************************/ +/* File: demoview.cpp */ +/* Author: Robert, Joachim */ +/* Date: 6. Mar. 2003 */ +/*********************************************************************/ + + +#include + + +//#include +#include +#include +#include +#include +#include +#include +#include +#include "incvis.hpp" +#include + +namespace netgen { + extern VisualScene *vs; +#include "demoview.hpp" + + + /* + static demokwstruct defkw[] = + { + { TOK_TIME, "t" }, + { TOK_CAMPOS, "camerapos" }, + { TOK_CAMPOINT, "camerapointto" }, + { TOK_CAMUP, "cameraup" } + }; + */ + + + static demoview_kwstruct demoview_defkw[] = + { + { DTOK_TIME, "t" }, + { DTOK_CAMPOS, "camerapos" }, + { DTOK_CAMPOINT, "camerapointto" }, + { DTOK_CAMUP, "cameraup" } + }; + + + DemoScanner :: DemoScanner (ifstream & ascanin) + { + int i; + + scanin = &ascanin; + token = DTOK_END; + num_value = 0; + linenum = 1; + } + + + + void DemoScanner :: ReadNext () + { + char ch; + + + // whitespaces ueberspringen + do + { + scanin->get(ch); + + if (ch == '\n') + linenum++; + + // end of file reached + if (scanin->eof()) + { + token = DTOK_END; + return; + } + + // skip comment line + if (ch == '#') + { + while (ch != '\n') + { + scanin->get(ch); + if (scanin->eof()) + { + token = DTOK_END; + return; + } + } + linenum++; + } + } + while (isspace(ch)); + + switch (ch) + { + case '(': case ')': + case '[': case ']': + case '-': case ':': + case '=': case ',': + case ';': case '+': + { + token = DEMOVIEW_TOKEN_TYPE (ch); + break; + } + + default: + { + if (isdigit (ch) || ch == '.') + { + scanin->putback (ch); + (*scanin) >> num_value; + token = DTOK_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); + } + + int nr = 0; + while (demoview_defkw[nr].kw) + { + if (string_value == demoview_defkw[nr].name) + { + token = demoview_defkw[nr].kw; + return; + } + nr++; + } + + token = DTOK_STRING; + } + } + } + + + + void DemoScanner :: Error (const string & err) + { + stringstream errstr; + errstr << "Parsing error in line " << linenum << ": " << endl << err << endl; + throw string(errstr.str()); + } + + + + void ParseChar (DemoScanner & scan, char ch) + { + char str[2]; + str[0] = ch; + str[1] = 0; + if (scan.GetToken() != DEMOVIEW_TOKEN_TYPE(ch)) + scan.Error (string ("token '") + string(str) + string("' expected")); + scan.ReadNext(); + } + + + + double ParseNumber(DemoScanner & scan) + { + if (scan.GetToken() == '-') + { + scan.ReadNext(); + return -ParseNumber (scan); + } + if (scan.GetToken() != DTOK_NUM) scan.Error ("number expected"); + double val = scan.GetNumValue(); + scan.ReadNext(); + return val; + } + + + Vec<3> ParseVector (DemoScanner & scan) + { + Vec<3> s; + + s(0) = ParseNumber (scan); + ParseChar (scan, ','); + + s(1) = ParseNumber (scan); + ParseChar (scan, ','); + + s(2) = ParseNumber (scan); + + return s; + } + + + void ParseConstLineOrSpline (DemoScanner & scan, double * t, Vec<3> * s) + { + int np = 1; + + scan.ReadNext(); + ParseChar (scan, '('); + + t[0] = ParseNumber (scan)*1000; + ParseChar (scan, ':'); + + s[0] = ParseVector (scan); + + if (scan.GetToken() != DTOK_RP && + scan.GetToken() != DTOK_SEMICOLON) + scan.Error (") or ; expected"); + + if (scan.GetToken() == DTOK_SEMICOLON) + { + np++; + + scan.ReadNext(); + + t[1] = ParseNumber (scan)*1000; + ParseChar (scan, ':'); + + s[1] = ParseVector (scan); + + if (scan.GetToken() != DTOK_RP && + scan.GetToken() != DTOK_SEMICOLON) + scan.Error (") or ; expected"); + + if (scan.GetToken() == DTOK_SEMICOLON) + { + np++; + + scan.ReadNext(); + + t[2] = ParseNumber (scan)*1000; + ParseChar (scan, ':'); + + s[2] = ParseVector (scan); + + ParseChar (scan, ')'); + ParseChar (scan, ';'); + } + else if (scan.GetToken() == DTOK_RP) + { + scan.ReadNext(); + ParseChar (scan, ';'); + } + } + else if (scan.GetToken() == DTOK_RP) + { + scan.ReadNext(); + ParseChar (scan, ';'); + } + + if (np == 1) // constant spline + { + t[1] = t[2] = t[0]; + s[1] = s[2] = s[0]; + } + if (np == 2) // linear spline + { + t[2] = t[1]; t[1] = 0.5*(t[0] + t[2]); + s[2] = s[1]; s[1] = 0.5*(s[0] + s[2]); + } + } + + + + + template + void InterpolationSpline :: AddSpline(double t1, double t2, double t3, S s1, S s2, S s3) + { + int pos, i, j; + // find pos to insert interpotation point + for (pos = 0; pos < ip.Size() && ip[pos][0].GetT() < t1; pos++) ; + + ip.SetSize( ip.Size()+1 ); + for (i = ip.Size()-2; i >= pos; i--) + for (j = 0; j < 3; j++) + ip[i+1][j] = ip[i][j]; + + ip[pos][0].SetTS (t1, s1); + ip[pos][1].SetTS (t2, s2); + ip[pos][2].SetTS (t3, s3); + } + + + + template + S InterpolationSpline :: Evaluate (double t) + { + if (t < ip[0][0].GetT()) + return (ip[0][0].GetS()); + + if (t > ip[ip.Size()-1][2].GetT()) + { + finished = 1; + return (ip[ip.Size()-1][2].GetS()); + } + + int pos; + for (pos = 0; pos < ip.Size() && t >= ip[pos][0].GetT(); pos++) ; + pos--; + + if (t >= ip[pos][0].GetT() && t <= ip[pos][2].GetT()) + { + double t0 = ip[pos][0].GetT(); + double t1 = ip[pos][2].GetT(); + + double t01 = (t-t0)/(t1-t0); + + double b1, b2, b3, w; + + b1 = (1-t01)*(1-t01); + b2 = sqrt(2.0) * t01 * (1-t01); + b3 = t01 * t01; + w = b1 + b2 + b3; + + return ( (1/w) * (b1 * ip[pos][0].GetS() + + b2 * ip[pos][1].GetS() + + b3 * ip[pos][2].GetS()) ); + } + else + return (ip[pos][2].GetS()); + } + + + + DemoView :: DemoView (const char * filename) + : campos( Vec<3>(5,0,0) ), + campoint ( Vec<3>(0,0,0) ), + camup ( Vec<3>(0,0,1) ) + { + double time = 0; + + ifstream istr; + istr.open(filename); + + DemoScanner scan(istr); + + double t[3]; + Vec<3> s[3]; + + scan.ReadNext(); + + try + { + while (1) + { + if (scan.GetToken() == DTOK_END) break; + + if (scan.GetToken() == DTOK_CAMPOS) + { + ParseConstLineOrSpline (scan, &t[0], &s[0]); + campos.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]); + } + + else if (scan.GetToken() == DTOK_CAMUP) + { + ParseConstLineOrSpline (scan, &t[0], &s[0]); + camup.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]); + } + + else if (scan.GetToken() == DTOK_CAMPOINT) + { + ParseConstLineOrSpline (scan, &t[0], &s[0]); + campoint.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]); + } + + else if (scan.GetToken() == DTOK_TIME) + { + scan.ReadNext(); + + if (scan.GetToken() != DTOK_EQU && + scan.GetToken() != DTOK_PLUS) + scan.Error ("= or += expected"); + + if (scan.GetToken() == DTOK_EQU) + { + scan.ReadNext(); + time = ParseNumber (scan)*1000; + ParseChar (scan, ';'); + } + else if (scan.GetToken() == DTOK_PLUS) + { + scan.ReadNext(); + ParseChar (scan, '='); + time += ParseNumber (scan)*1000; + ParseChar (scan, ';'); + } + } + + else + { + cout << "read unidentified token " << scan.GetToken() + << " string = " << scan.GetStringValue() << endl; + scan.ReadNext(); + } + } + } + catch (string errstr) + { + cout << "caught error " << errstr << endl; + } + + + } + + + DemoView :: ~DemoView () + { + ; + } + + int DemoView :: SetTime (double time) + { + /* + cout << "time = " << time << endl; + + cout << "campos : " << campos.Evaluate (time) << endl; + cout << "campoint: " << campoint.Evaluate (time) << endl; + cout << "camup : " << camup.Evaluate (time) << endl; + */ + + + vs -> LookAt ( Point<3>( campos.Evaluate (time)), + Point<3>(campoint.Evaluate (time)), + Point<3>( camup.Evaluate (time)) ); + + if (campos.IsFinished() && + campoint.IsFinished() && + camup.IsFinished()) + { + return -1; + } + + return 0; + } + + +} diff --git a/ng/demoview.hpp b/ng/demoview.hpp new file mode 100644 index 00000000..27092bd0 --- /dev/null +++ b/ng/demoview.hpp @@ -0,0 +1,146 @@ +#ifndef FILE_DEMOVIEW +#define FILE_DEMOVIEW + +/*********************************************************************/ +/* File: demoview.hpp */ +/* Author: Robert, Joachim */ +/* Date: 6. Mar. 2003 */ +/*********************************************************************/ + +using namespace netgen; + + +enum DEMOVIEW_TOKEN_TYPE + { + DTOK_MINUS = '-', DTOK_LP = '(', DTOK_RP = ')', DTOK_LSP = '[', DTOK_RSP = ']', + DTOK_EQU = '=', DTOK_COMMA = ',', DTOK_SEMICOLON = ';', DTOK_COLON = ':', DTOK_PLUS = '+', + DTOK_NUM = 100, DTOK_STRING, DTOK_TIME, DTOK_CAMPOS, DTOK_CAMPOINT, DTOK_CAMUP, + DTOK_END + }; + +struct demoview_kwstruct +{ + DEMOVIEW_TOKEN_TYPE kw; + const char * name; +}; + + + + +class DemoScanner +{ + DEMOVIEW_TOKEN_TYPE token; + double num_value; + string string_value; + + int linenum; + ifstream * scanin; + +public: + + DemoScanner (ifstream & ascanin); + + DEMOVIEW_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); +}; + + +void ParseChar (DemoScanner & scan, char ch); + +double ParseNumber(DemoScanner & scan); + +Vec<3> ParseVector (DemoScanner & scan); + + + +template +class InterpolationPoint +{ + double t; + S s; + +public: + InterpolationPoint() + {}; + + ~InterpolationPoint() + {}; + + double GetT() const + { return t; }; + + S GetS() const + { return s; }; + + void SetTS(double at, S as) + { t = at; s = as; }; + + InterpolationPoint & operator= (const InterpolationPoint & ip2) + { + SetTS (ip2.t, ip2.s); + return (*this); + }; + +}; + + + +template +class InterpolationSpline +{ +protected: + ARRAY < InterpolationPoint[3] > ip; + int finished; + +public: + InterpolationSpline() : finished(0) + {}; + + InterpolationSpline( S s1 ) : finished(0) + { + AddSpline (-1e99, -1e99, -1e99, s1, s1, s1); + // InterpolationSpline(); + } + + ~InterpolationSpline() + {}; + + void AddSpline(double t1, double t2, double t3, S s1, S s2, S s3); + + S Evaluate (double t); + + int IsFinished() const + { + return finished; + } +}; + + + + + +class DemoView +{ + InterpolationSpline< Vec<3> > campos; + InterpolationSpline< Vec<3> > campoint; + InterpolationSpline< Vec<3> > camup; + +public: + DemoView (const char * filename); + ~DemoView (); + + int SetTime (double time); +}; + + + +#endif diff --git a/ng/ng_acis.hpp b/ng/ng_acis.hpp new file mode 100644 index 00000000..fd26cee3 --- /dev/null +++ b/ng/ng_acis.hpp @@ -0,0 +1,193 @@ +#include +#ifdef ACIS_R17 +extern void unlock_spatial_products_661(); +#endif + + +namespace netgen { + + +ACISGeometry * acisgeometry = NULL; + +static VisualSceneACISGeometry vsacisgeom; + + +extern int ACISGenerateMesh (ACISGeometry & geometry, Mesh*& mesh, + int perfstepsstart, int perfstepsend, char* optstring); + + + + + + + + + + + int Ng_ACISCommand (ClientData /* clientData */, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc >= 2) + { + if (strcmp (argv[1], "isACISavailable") == 0) + { + Tcl_SetResult (interp, (char*)"yes", TCL_STATIC); + return TCL_OK; + } + } + + + if (!acisgeometry) + { + Tcl_SetResult (interp, (char*)"This operation needs an ACIS geometry", TCL_STATIC); + return TCL_ERROR; + } + + + + + if (argc >= 2 && strcmp (argv[1], "getentities") == 0) + { + stringstream str; + const ENTITY_LIST & entlist = acisgeometry -> entlist; + + + ENTITY_LIST cellList; + api_ct_get_all_cells( entlist, cellList ); + for(int j=0; jattrib(); + int k = 0; + + while (ap) + { + ATTRIB_GEN_INTEGER * aip = dynamic_cast(ap); + if (aip) + str << "cell" << j << "/attrib" << k + << " { name = " << aip->name() << " val = " << aip->value() << "} \n"; + else + str << "cell" << j << "/attrib" << k + << " { typename = " << ap->type_name() << "} \n"; + + ap = ap->next(); + k++; + } + } + + + for (int i = 0; i < entlist.count(); i++) + { + str << "entity" << i << " {Entity " << i << "} \n"; + ENTITY_LIST faceList; + ENTITY_LIST edgeList; + + api_get_faces_from_all_entities(entlist[i], faceList); + + for(int j=0; jattrib(); + int k = 0; + + while (ap) + { + ATTRIB_GEN_INTEGER * aip = dynamic_cast(ap); + if (aip) + str << "entity" << i << "/face" << j << "/attrib" << k + << " { name = " << aip->name() << " val = " << aip->value() << "} \n"; + else + str << "entity" << i << "/face" << j << "/attrib" << k + << " { typename = " << ap->type_name() << "} \n"; + + ap = ap->next(); + k++; + } + + SPAbox * box = face->bound(); + str << "entity" << i << "/face" << j << "/bbox" + << " { BBox (" + << box->low().x() << ", " << box->low().y() << ", " << box->low().z() << ";" + << box->high().x() << ", " << box->high().y() << ", " << box->high().z() << ")" + << " }\n"; + } + + + api_get_edges_from_all_entities(entlist[i], edgeList); + + for(int j=0; j= 2 && strcmp (argv[1], "selectentity") == 0) + { + int ientry = -1, iface = -1; + + string select = argv[2]; + cout << "ACIS selectentity: " << select << endl; + + int pos_ent1 = select.find("entity", 0); + int pos_ent2 = select.find("/", pos_ent1); + if (pos_ent1 != -1 && pos_ent2 == -1) pos_ent2 = select.length(); + if (pos_ent1 != -1) ientry = atoi (select.substr(pos_ent1+6, pos_ent2).c_str()); + + int pos_face1 = select.find("face", 0); + int pos_face2 = select.find("/", pos_face1); + if (pos_face1 != -1 && pos_face2 == -1) pos_face2 = select.length(); + if (pos_face1 != -1) iface = atoi (select.substr(pos_face1+4, pos_face2).c_str()); + + cout << "entry = " << ientry << ", face = " << iface << endl; + + const ENTITY_LIST & entlist = acisgeometry -> entlist; + + if (ientry != -1 && iface == -1) + vsacisgeom.SelectEntity (entlist[ientry]); + + if (iface != -1) + { + ENTITY_LIST faceList; + api_get_faces_from_all_entities(entlist[ientry], faceList); + vsacisgeom.SelectEntity (faceList[iface]); + } + } + + + if (argc >= 2 && strcmp (argv[1], "createct") == 0) + { + acisgeometry -> CreateCT(); + } + + if (argc >= 2 && strcmp (argv[1], "combineall") == 0) + { + cout << "combineall " << endl; + acisgeometry -> Combine(); + } + + + + if (argc >= 4) + { + if (strcmp (argv[1], "subtract") == 0) + { + cout << "subtract " << argv[2] << " minus " << argv[3] << endl; + acisgeometry -> Subtract (atoi (argv[2])-1, atoi (argv[3])-1); + } + + } + + return TCL_OK; + } + + +} diff --git a/ng/ngappinit.cpp b/ng/ngappinit.cpp new file mode 100644 index 00000000..31a63264 --- /dev/null +++ b/ng/ngappinit.cpp @@ -0,0 +1,533 @@ +/* + The main function of netgen. + This file is a modification of tkAppInit.c from the Tcl/Tk package +*/ + +#include +#include "incvis.hpp" +#include + +#ifdef LINUX +#include +#include +#endif + + +#ifdef PARALLEL +#include + +namespace netgen +{ + int id, ntasks; +} +MPI_Group MPI_HIGHORDER_WORLD; +MPI_Comm MPI_HIGHORDER_COMM; + +#endif + +#include "../libsrc/parallel/parallel.hpp" +#include "../libsrc/parallel/parallelfunc.hpp" + + + +namespace netgen +{ +#include "writeuser.hpp" + extern string ngdir; +} + + + + +using netgen::parameters; +using netgen::ngdir; +using netgen::verbose; +using netgen::ARRAY; +using netgen::RegisterUserFormats; + + +#ifdef NGSOLVE + extern "C" int NGSolve_Init (Tcl_Interp * interp); +#endif + +// void * ngsolve_handle; // dynamic library handle + + + + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ +#if !defined(__WIN32__) && !defined(MAC_TCL) +// extern "C" int matherr(); +int *tclDummyMathPtr = (int *) matherr; +#endif + +extern "C" int Ng_ServerSocketManagerInit (int port); +extern "C" int Ng_ServerSocketManagerRun (void); + +bool nodisplay = false; +bool shellmode = false; + +/* + * + * The Netgen main function + * + */ + +int main(int argc, char ** argv) +{ + +#ifdef PARALLEL + // parallel profiling +#pragma pomp inst init + + MPI_Init(&argc, &argv); + + MPI_Comm_size(MPI_COMM_WORLD, &netgen::ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &netgen::id); + + MPI_Group MPI_GROUP_WORLD; + + int n_ho = netgen::ntasks - 1; + int * process_ranks = new int[netgen::ntasks-1]; + for ( int i = 0; i < netgen::ntasks-1; i++ ) + process_ranks[i] = i+1; + + MPI_Comm_group ( MPI_COMM_WORLD, &MPI_GROUP_WORLD); + MPI_Group_incl ( MPI_GROUP_WORLD, n_ho, process_ranks, & MPI_HIGHORDER_WORLD); + MPI_Comm_create ( MPI_COMM_WORLD, MPI_HIGHORDER_WORLD, &MPI_HIGHORDER_COMM); + +#pragma pomp inst begin(main) +#endif + + // ngsolve_handle = dlopen ("libngsolves.so", RTLD_LAZY | RTLD_GLOBAL); + // cout << "ngsolve_handle = " << ngsolve_handle << endl; + + if ( netgen::id == 0 ) + { +#ifdef NGSOLVE + cout << "NETGEN/NGSolve V4.5-RC2" << endl; +#else + cout << "NETGEN V4.5-RC2" << endl; +#endif + + + cout << "Developed at RWTH Aachen University, Germany" << endl + << "and Johannes Kepler University Linz, Austria" << endl; + +#ifdef OCCGEOMETRY + cout << "Including OpenCascade geometry kernel" << endl; +#endif + +#ifdef ACIS + cout << "Including ACIS geometry kernel" << endl; +#endif + +#ifdef LINUX + //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW); + //cout << "Handle Floating Point Exceptions: " << fegetexcept() << endl; +#endif + +#ifdef DEBUG + cout << "You are running the debug version !" << endl; +#endif + +#ifdef USE_SUPERLU + cout << "Including sparse direct solver SuperLU by Lawrence Berkeley National Laboratory" << endl; +#endif +#ifdef USE_PARDISO + cout << "Including sparse direct solver Pardiso" << endl; +#endif + +#ifdef _OPENMP + cout << "Running OpenMP - parallel using " << omp_get_max_threads() << " threads" << endl; + // cout << "(can be changed by setting OMP_NUM_THREADS)" << endl; +#endif + +#ifdef PARALLEL + cout << "Including MPI " << endl; + cout << "Using " << netgen::ntasks << " processor" + << ((netgen::ntasks > 1) ? "s " : " ") << endl; +#endif + } + else + { + ;// nodisplay = true; + } + + + // command line arguments: + for (int i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + parameters.SetCommandLineFlag (argv[i]); + else + parameters.SetFlag ("geofile", argv[i]); + } + + + if (getenv ("NETGENDIR") && strlen (getenv ("NETGENDIR"))) + ngdir = getenv ("NETGENDIR"); + else + ngdir = "."; + + verbose = parameters.GetDefineFlag ("V"); + + if (verbose) + cout << "NETGENDIR = " << ngdir << endl; + + + if ( netgen::id == 0 ) + { + netgen::testout = new ofstream (parameters.GetStringFlag ("testout", "test.out")); + + +#ifdef SOCKETS + Ng_ServerSocketManagerInit(static_cast(parameters.GetNumFlag("serversocket",-1))); + if(parameters.GetNumFlag("serversocket",-1) > 0 && !parameters.GetDefineFlag("display")) + nodisplay = true; +#endif + + if(parameters.GetDefineFlag("batchmode")) + nodisplay = true; + + if(parameters.GetDefineFlag("shellmode")) + { + nodisplay = true; + shellmode = true; + } + + Tcl_FindExecutable(NULL); + + // initialize application + Tcl_Interp * myinterp = Tcl_CreateInterp (); + if (Tcl_AppInit (myinterp) == TCL_ERROR) + { + cerr << "Exit Netgen due to initialization problem" << endl; + exit (1); + } + + + + // parse tcl-script + int errcode; + + bool internaltcl = true; + if (shellmode) + internaltcl = false; + +#ifdef PARALLEL + internaltcl = false; +#endif + + if (verbose) + { + cout << "Tcl header version = " << TCL_PATCH_LEVEL << endl; + Tcl_Eval (myinterp, "puts \"Tcl runtime version = [info patchlevel] \";"); + } + + if (parameters.GetDefineFlag ("internaltcl")) + internaltcl=true; + if (parameters.GetDefineFlag ("externaltcl")) + internaltcl=false; + + + if (internaltcl) + { + if (verbose) + cout << "using internal Tcl-script" << endl; + + // connect to one string + extern const char * ngscript[]; + const char ** hcp = ngscript; + int len = 0; + while (*hcp) + len += strlen (*hcp++); + + char * tr1 = new char[len+1]; + *tr1 = 0; + hcp = ngscript; + + char * tt1 = tr1; + while (*hcp) + { + strcat (tt1, *hcp); + tt1 += strlen (*hcp++); + } + + errcode = Tcl_Eval (myinterp, tr1); + delete [] tr1; + } + + else + + { + string startfile = ngdir + "/ng.tcl"; + + if (verbose) + cout << "Load Tcl-script from " << startfile << endl; + + errcode = Tcl_EvalFile (myinterp, (char*)startfile.c_str()); + } + + if (errcode) + { + cout << "Error in Tcl-Script:" << endl; + cout << "result = " << myinterp->result << endl; + cout << "in line " << myinterp->errorLine << endl; + + if (myinterp->errorLine == 1) + cout << "\nMake sure to set environment variable NETGENDIR" << endl; + + exit (1); + } + + + // lookup user file formats and insert into format list: + ARRAY userformats; + RegisterUserFormats (userformats); + + ostringstream fstr; + for (int i = 1; i <= userformats.Size(); i++) + fstr << ".ngmenu.file.filetype add radio -label \"" + << userformats.Get(i) << "\" -variable exportfiletype\n"; + + + Tcl_Eval (myinterp, (char*)fstr.str().c_str()); + Tcl_SetVar (myinterp, "exportfiletype", "Neutral Format", 0); + + + // For adding an application, parse the file here, + // and call the init-procedure below + // #define DEMOAPP +#ifdef DEMOAPP + Tcl_EvalFile (myinterp, "demoapp/demoapp.tcl"); +#endif + +#ifdef ADDON + Tcl_EvalFile (myinterp, "addon/addon.tcl"); +#endif + +#ifdef SOCKETS + Ng_ServerSocketManagerRun(); +#endif + + // start event-loop + Tk_MainLoop(); + + Tcl_DeleteInterp (myinterp); + +#ifdef PARALLEL +#pragma pomp inst altend(main) + + // MPI beenden + MPI_Barrier(MPI_COMM_WORLD); + MPI_Finalize(); +#endif + + Tcl_Exit(0); + } +#ifdef PARALLEL + else + { + // main for parallel processors + ParallelRun(); + +#pragma pomp inst end(main) + + // MPI beenden + MPI_Barrier(MPI_COMM_WORLD); + MPI_Finalize(); + } +#endif + + return 0; +} + + + +extern "C" int Tix_Init (Tcl_Interp * interp); +extern "C" int Itcl_Init (Tcl_Interp * interp); +extern "C" int Itk_Init (Tcl_Interp * interp); +extern "C" int Ng_Init (Tcl_Interp * interp); +extern "C" int Ng_Vis_Init (Tcl_Interp * interp); + + + +// extern Tcl_PackageInitProc * Tk_SafeInit; + + +/* + * + * Initialize packages + * + */ + +int Tcl_AppInit(Tcl_Interp * interp) +{ + + if (Tcl_Init(interp) == TCL_ERROR) { + cerr << "Problem in Tcl_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + + if (!nodisplay && Tk_Init(interp) == TCL_ERROR) { + cerr << "Problem in Tk_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + + + // if ITcl and ITk are installed on the system, then + // they must also be initialized + /* + if (Itcl_Init(interp) == TCL_ERROR) { + cerr << "Problem in Itcl_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + + if (Itk_Init(interp) == TCL_ERROR) { + cerr << "Problem in Itk_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + */ + + if (!nodisplay && Tix_Init(interp) == TCL_ERROR) { + cerr << "Problem in Tix_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + + if (Ng_Init(interp) == TCL_ERROR) { + cerr << "Problem in Ng_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + + if (!nodisplay && Ng_Vis_Init(interp) == TCL_ERROR) { + cerr << "Problem in Ng_Vis_Init: " << endl; + cerr << interp->result << endl; + // return TCL_ERROR; + } + + +#ifdef DEMOAPP + extern int DemoApp_Init (Tcl_Interp * interp); + if (DemoApp_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } +#endif +#ifdef ADDON + extern int AddOn_Init (Tcl_Interp * interp); + if (AddOn_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } +#endif +#ifdef METIS_OLD + extern int NgMetis_Init (Tcl_Interp * interp); + if (NgMetis_Init(interp) == TCL_ERROR) + { + return TCL_ERROR; + } +#endif + +#ifdef TRAFO + // extern int Trafo_Init (Tcl_Interp * interp); + // if (Trafo_Init(interp) == TCL_ERROR) + // { + // cerr << "Problem in Trafo_Init: " << endl; + // cerr << interp->result << endl; + // return TCL_ERROR; + // } +#endif + +#ifdef EBGELAST + extern int EBGElast_Init (Tcl_Interp * interp); + if(EBGElast_Init(interp) == TCL_ERROR) + { + cerr << "Problem in EBGElast_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif + +#ifdef SMALLTRAFO + extern int SmallModels_Init (Tcl_Interp * interp); + if(SmallModels_Init(interp) == TCL_ERROR) + { + cerr << "Problem in SmallModel_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif + + /* + if (ngsolve_handle) + { + void (*ngs_init)(Tcl_Interp*); + ngs_init = ( void (*)(Tcl_Interp*) ) dlsym (ngsolve_handle, "NGSolve_Init"); + cout << "symbolhandle = " << (void*)ngs_init << endl; + if (ngs_init) (*ngs_init)(interp); + } + */ + + +#ifdef NGSOLVE + if (NGSolve_Init(interp) == TCL_ERROR) + { + cerr << "Problem in NgSolve_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#ifdef SOCKETS + extern int NGS_Socket_Init (Tcl_Interp * interp); + if (NGS_Socket_Init(interp) == TCL_ERROR) + { + cerr << "Problem in NGS_Socket_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif // SOCKETS +#endif // NGSOLVE + + +#ifdef SOCKETS + extern int Ng_Socket_Init (Tcl_Interp * interp); + if ( Ng_Socket_Init(interp) == TCL_ERROR) + { + cerr << "Problem in Ng_Socket_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif + + + +#ifdef ZUGSTANGE + extern int Zugstange_Init (Tcl_Interp * interp); + if (Zugstange_Init(interp) == TCL_ERROR) + { + cerr << "Problem in Zugstange_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } +#endif + + + Tcl_StaticPackage(interp, "Tk", Tk_Init, 0); + + return TCL_OK; +} diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp new file mode 100644 index 00000000..8ff10987 --- /dev/null +++ b/ng/ngpkg.cpp @@ -0,0 +1,5096 @@ +/* + +The interface between the GUI and the netgen library + +*/ + + +#include + +#ifdef LINUX +#include +#include +#endif + + +#include +#include +#include + +#ifdef OCCGEOMETRY +#include +#endif + + + +#include +#include + +#include +#include +#include + +#ifdef SOCKETS +#include "../libsrc/sockets/sockets.hpp" +#include "../libsrc/sockets/socketmanager.hpp" +#endif + +#include + + +extern bool nodisplay; + +namespace netgen +{ +#include "../libsrc/interface/writeuser.hpp" +#include "demoview.hpp" +} + + +#ifdef ACIS +#include "ng_acis.hpp" +#endif + + +#ifdef VIDEOCLIP +#include +extern "C" { +#include +} +#endif + +#ifdef NGSOLVE +extern "C" void NGSolve_Exit(); +#endif + +// extern void * ngsolve_handle; + + +namespace netgen +{ + + NetgenOutStream operator<< ( ostream & ost, Imp imp ) + { + return ( NetgenOutStream ( &ost, imp ) ); + } + + NetgenOutStream operator<< ( ostream & ost, Proc proc ) + { + return ( NetgenOutStream ( &ost, proc ) ); + } + + + NetgenOutStream operator<< ( ostream & ost, Procs & procs ) + { + return ( NetgenOutStream ( &ost, procs ) ); + } + + + // global variable mesh (should not be used in libraries) + AutoPtr mesh; + + // geometry: either CSG, or, if an other is non-null, + // then the other + AutoPtr geometry (new CSGeometry("")); + + STLGeometry * stlgeometry = NULL; + AutoPtr geometry2d (0); + +#ifdef OCCGEOMETRY + OCCGeometry * occgeometry = NULL; +#endif + + + + Tcl_Interp * tcl_interp; + +#ifdef SOCKETS + AutoPtr clientsocket; + ServerSocketManager serversocketmanager; + //ARRAY< AutoPtr < ServerInfo > > servers; + ARRAY< ServerInfo* > servers; + AutoPtr serversocketusernetgen; +#endif + + // OpenGL near and far clipping planes + extern double pnear; + extern double pfar; + + + // visualization scenes, pointer vs selects which one is drawn: + + static VisualScene vscross; + static VisualSceneGeometry vsgeom; + static VisualSceneGeometry2d vsgeom2d; +#ifdef OPENGL + static VisualSceneSTLGeometry vsstlgeom; + extern VisualSceneSTLMeshing vsstlmeshing; +#endif + +#ifdef OCCGEOMETRY + static VisualSceneOCCGeometry vsoccgeom; +#endif + + + +#ifdef OPENGL + extern VisualSceneSurfaceMeshing vssurfacemeshing; +#endif + extern VisualSceneMesh vsmesh; + extern VisualSceneMeshDoctor vsmeshdoc; + static VisualSceneSpecPoints vsspecpoints; + + VisualSceneSolution vssolution; + + +#ifdef STEP + static VisualSceneSTEPGeometry vsstepgeom; +#endif + + +#ifdef MODELLER + VisualScene * vsmodeller = NULL; +#endif + + VisualScene *vs = &vscross; + + + + static char * err_needsmesh = (char*) "This operation needs a mesh"; + static char * err_needsstlgeometry = (char*) "This operation needs an STL geometry"; + static char * err_jobrunning = (char*) "Meshing Job already running"; + + + + +#ifdef _MSC_VER + + // Afx - Threads need different return - value: + + static void* (*sfun)(void *); + unsigned int fun2 (void * val) + { + sfun (val); + return 0; + } + + void RunParallel ( void* (*fun)(void *), void * in) + { + sfun = fun; + if (mparam.parthread) + AfxBeginThread (fun2, in); + //AfxBeginThread (fun2, NULL); + else + fun (in); + } + +#else + +// #include + + static pthread_t meshingthread; + void RunParallel ( void * (*fun)(void *), void * in) + { + if (mparam.parthread) + { + pthread_attr_t attr; + pthread_attr_init (&attr); + // the following call can be removed if not available: + pthread_attr_setstacksize(&attr, 1000000); + //pthread_create (&meshingthread, &attr, fun, NULL); + pthread_create (&meshingthread, &attr, fun, in); + } + else + fun (in); + } + +#endif + + + +#ifndef SMALLLIB + // Destination for messages, errors, ... + void Ng_PrintDest(const char * s) + { +#ifdef PARALLEL + int id, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); +#else + int id = 0; int ntasks = 1; +#endif + + + if ( ntasks == 1 ) + (*mycout) << s << flush; + else + (*mycout) << "p" << id << ": " << s << flush ; + } + + void MyError(const char * ch) + { + cout << ch; + (*testout) << "Error !!! " << ch << endl << flush; + } +#endif + + static clock_t starttimea; + void ResetTime () + { + starttimea = clock(); + } + +#ifndef SMALLLIB + double GetTime () + { + return double(clock() - starttimea) / CLOCKS_PER_SEC; + } +#endif + + + + + + // file handling .. + int Ng_New (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (strcmp (argv[1], "mesh") == 0) + mesh.Reset(); + + + if (strcmp (argv[1], "geom") == 0) + { + geometry.Reset (new CSGeometry ("")); + + if (stlgeometry) + { + delete stlgeometry; + stlgeometry = NULL; + } +#ifdef OCCGEOMETRY + if (occgeometry) + { + delete occgeometry; + occgeometry = NULL; + } +#endif + } + + return TCL_OK; + } + + + + + int Ng_ImportMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + + int Ng_LoadMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + string filename (argv[1]); + + if ( (strlen (filename.c_str()) > 4) && + strcmp (&filename[strlen (filename.c_str())-4], ".vol") != 0 ) + { + return Ng_ImportMesh(clientData,interp,argc,argv); + } + + PrintMessage (1, "load mesh from file ", filename); + + mesh.Reset (new Mesh()); + + try + { + //mesh -> Load (filename); + ifstream infile(filename.c_str()); + mesh -> Load(infile); + string auxstring; + if(infile.good()) + { + infile >> auxstring; + if(auxstring == "csgsurfaces") + { + if (geometry) + geometry.Reset (new CSGeometry ("")); + if (stlgeometry) + { + delete stlgeometry; + stlgeometry = NULL; + } +#ifdef OCCGEOMETRY + if (occgeometry) + { + delete occgeometry; + occgeometry = NULL; + } +#endif + geometry2d.Reset (0); + + + geometry -> LoadSurfaces(infile); + } + } + } + catch (NgException e) + { + PrintMessage (3, e.What()); + return TCL_ERROR; + } + + PrintMessage (2, mesh->GetNP(), " Points, ", + mesh->GetNE(), " Elements."); + + return TCL_OK; + } + + + + + + int Ng_SaveMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + const string filename (argv[1]); + PrintMessage (1, "Save mesh to file ", filename); + + + //mesh -> Save (filename); + + ofstream outfile(filename.c_str()); + mesh -> Save (outfile); + + outfile << endl << endl << "endmesh" << endl << endl; + + if (geometry && geometry->GetNSurf()) geometry->SaveSurfaces(outfile); + + + return TCL_OK; + } + + + + + + int Ng_MergeMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + string filename (argv[1]); + + PrintMessage (1, "merge with mesh from file ", filename); + + try + { + //mesh -> Merge (filename); + ifstream infile(filename.c_str()); + const int offset = (geometry) ? geometry->GetNSurf() : 0; + mesh -> Merge(infile,offset); + string auxstring; + if(infile.good()) + { + infile >> auxstring; + if(auxstring == "csgsurfaces") + geometry -> LoadSurfaces(infile); + } + } + catch (NgException e) + { + PrintMessage (3, e.What()); + return TCL_ERROR; + } + + PrintMessage (2, mesh->GetNP(), " Points, ", + mesh->GetNSE(), " Surface Elements."); + + return TCL_OK; + } + + + + + + int Ng_ExportMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + string filename (argv[1]); + string filetype (argv[2]); + + if (WriteUserFormat (filetype, *mesh, *geometry, filename)) + { + ostringstream ost; + ost << "Sorry, nothing known about file format " << filetype << endl; + Tcl_SetResult (interp, (char*)ost.str().c_str(), TCL_VOLATILE); + return TCL_ERROR; + } + + return TCL_OK; + } + + + + int Ng_ImportMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + const string filename (argv[1]); + PrintMessage (1, "import mesh from ", filename); + + mesh.Reset (new Mesh()); + + ReadFile (*mesh, filename); + PrintMessage (2, mesh->GetNP(), " Points, ", + mesh->GetNE(), " Elements."); + + mesh->SetGlobalH (mparam.maxh); + mesh->CalcLocalH(); + + return TCL_OK; + } + + + + int Ng_ImportSolution (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + const char * filename = argv[1]; + PrintMessage (1, "Import solution from file ", filename); + + ImportSolution (filename); + return TCL_OK; + } + + + + static DemoView * demoview = 0; + int Ng_ShowDemo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + const char * filename = argv[1]; + PrintMessage (1, "Show demo ", filename); + demoview = new DemoView (filename); + + return TCL_OK; + } + + + + int Ng_DemoSetTime (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + cout << "demosettime, time = " << argv[1] << endl; + int result = -1; + + static char strminusone[] = "-1"; + static char str0[] = "0"; + + if (demoview) + result = demoview->SetTime (atof (argv[1])); + + if (result == -1) + Tcl_SetResult (interp, strminusone, TCL_STATIC); + else + Tcl_SetResult (interp, str0, TCL_STATIC); + + return TCL_OK; + } + + + + + + + + int Ng_SaveSolution (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + const char * filename = argv[1]; + PrintMessage (1, "Save solution to file ", filename); + + vssolution.SaveSolutionData (filename); + return TCL_OK; + } + + + + + + + + int Ng_LoadGeometry (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + tcl_const char * lgfilename = argv[1]; + +#ifdef LOG_STREAM + (*logout) << "Load geometry file: " << lgfilename << endl; +#endif + +#ifdef STAT_STREAM + (*statout) << lgfilename << " & " << endl; +#endif + + if (geometry) + geometry.Reset (new CSGeometry ("")); + if (stlgeometry) + { + delete stlgeometry; + stlgeometry = NULL; + } +#ifdef OCCGEOMETRY + if (occgeometry) + { + delete occgeometry; + occgeometry = NULL; + } +#endif + geometry2d.Reset (0); + + + try + { + + ifstream infile(lgfilename); + + if (strlen(lgfilename) < 4) + { + cout << "ERROR: cannot recognise file format!" << endl; + } + else + { + if (strcmp (&lgfilename[strlen(lgfilename)-3], "geo") == 0) + { + // strcpy (geomfilename, lgfilename); + PrintMessage (1, "Load geometry file ", lgfilename); + + + extern CSGeometry * ParseCSG (istream & istr); + // ifstream infile(lgfilename); + CSGeometry * hgeom = ParseCSG (infile); + if (hgeom) + geometry.Reset (hgeom); + else + { + geometry.Reset (new CSGeometry ("")); + Tcl_SetResult (interp, (char*)"geo-file should start with 'algebraic3d'", TCL_STATIC); + return TCL_ERROR; + } + + //geometry -> FindIdenticSurfaces(geometry->GetIdEps() * geometry->MaxSize()); // 1e-8*geometry->MaxSize() + geometry -> FindIdenticSurfaces(1e-8 * geometry->MaxSize()); // 1e-8*geometry->MaxSize() + } + else if (strcmp (&lgfilename[strlen(lgfilename)-3], "ngg") == 0) + { + // strcpy (geomfilename, lgfilename); + + PrintMessage (1, "Load new geometry file ", lgfilename); + geometry.Reset (new CSGeometry("")); + geometry -> Load (infile); + } + + // strcpy (geomfilename, lgfilename); + // (*mycout) << "Load geometry file " << lgfilename << endl; + + else if (strcmp (&lgfilename[strlen(lgfilename)-3], "stl") == 0) + { + // strcpy (geomfilename, lgfilename); + PrintMessage (1, "Load stl geometry file ", lgfilename); + stlgeometry = STLGeometry :: Load (infile); + stlgeometry->edgesfound = 0; + } + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "iges") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "igs") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "IGS") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "IGES") == 0)) + { +#ifdef OCCGEOMETRY + // strcpy (geomfilename, lgfilename); + PrintMessage (1, "Load IGES geometry file ", lgfilename); + occgeometry = LoadOCC_IGES (lgfilename); +#else + Tcl_SetResult (interp, "IGES import requires the OpenCascade geometry kernel. " + "Please install OpenCascade as described in the Netgen-website", + TCL_STATIC); + return TCL_ERROR; +#endif + } + + else if (strcmp (&lgfilename[strlen(lgfilename)-3], "sat") == 0) + { +#ifdef ACIS + PrintMessage (1, "Load ACIS geometry file ", lgfilename); + acisgeometry = netgen::LoadACIS_SAT (lgfilename); +#endif + } + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "step") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "stp") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "STP") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "STEP") == 0)) + { +#ifdef ACISxxx + PrintMessage (1, "Load STEP geometry file ", lgfilename); + acisgeometry = netgen::LoadACIS_STEP (lgfilename); +#else +#ifdef OCCGEOMETRY + // strcpy (geomfilename, lgfilename); + PrintMessage (1, "Load STEP geometry file ", lgfilename); + occgeometry = LoadOCC_STEP (lgfilename); +#else + Tcl_SetResult (interp, "IGES import requires the OpenCascade geometry kernel. " + "Please install OpenCascade as described in the Netgen-website", + TCL_STATIC); + return TCL_ERROR; +#endif +#endif + } + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "brep") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "Brep") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "BREP") == 0)) + { +#ifdef OCCGEOMETRY + // strcpy (geomfilename, lgfilename); + PrintMessage (1, "Load BREP geometry file ", lgfilename); + occgeometry = LoadOCC_BREP (lgfilename); +#else + Tcl_SetResult (interp, "BREP import requires the OpenCascade geometry kernel. " + "Please install OpenCascade as described in the Netgen-website", + TCL_STATIC); + return TCL_ERROR; +#endif + } + + else if (strcmp (&lgfilename[strlen(lgfilename)-4], "stlb") == 0) + { + // strcpy (geomfilename, lgfilename); + + PrintMessage (1, "Load stl geometry file ", lgfilename, " in binary format"); + stlgeometry = STLGeometry :: LoadBinary (infile); + stlgeometry->edgesfound = 0; + } + + else if (strcmp (&lgfilename[strlen(lgfilename)-3], "nao") == 0) + { + // strcpy (geomfilename, lgfilename); + + PrintMessage (1, "Load naomi (F. Kickinger) geometry file ", lgfilename); + stlgeometry = STLGeometry :: LoadNaomi (infile); + stlgeometry->edgesfound = 0; + } + + else if (strcmp (&lgfilename[strlen(lgfilename)-4], "in2d") == 0) + { + // strcpy (geomfilename, lgfilename); + geometry2d.Reset (new SplineGeometry2d()); + geometry2d -> Load (lgfilename); + } + } + } + catch (NgException e) + { + Tcl_SetResult (interp, const_cast (e.What().c_str()), TCL_VOLATILE); + return TCL_ERROR; + } + + mesh.Reset(); + + return TCL_OK; + } + + + + + + + + + + + int Ng_SaveGeometry (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc == 2) + { + const char * cfilename = argv[1]; + PrintMessage (1, "Save geometry to file ", cfilename); + + if (strlen(cfilename) < 4) {cout << "ERROR: can not recognise file format!!!" << endl;} + else + { +#ifdef ACIS + if (acisgeometry) + { + char * filename = const_cast (argv[1]); + if (strcmp (&filename[strlen(filename)-3], "sat") == 0) + { + acisgeometry -> SaveSATFile (filename); + } + } +#endif +#ifdef OCCGEOMETRY + if (occgeometry) + { + char * filename = const_cast (argv[1]); + if (strcmp (&filename[strlen(filename)-3], "igs") == 0) + { + IGESControl_Writer writer("millimeters", 1); + writer.AddShape (occgeometry->shape); + writer.Write (filename); + } + else if (strcmp (&filename[strlen(filename)-3], "stp") == 0) + { + STEPControl_Writer writer; + writer.Transfer (occgeometry->shape, STEPControl_AsIs); + writer.Write (filename); + } + else if (strcmp (&filename[strlen(filename)-3], "stl") == 0) + { + StlAPI_Writer writer; + writer.ASCIIMode() = Standard_True; + writer.Write (occgeometry->shape, filename); + } + else if (strcmp (&filename[strlen(filename)-4], "stlb") == 0) + { + StlAPI_Writer writer; + writer.ASCIIMode() = Standard_False; + writer.Write (occgeometry->shape, filename); + } + } + else +#endif + if (strcmp (&cfilename[strlen(cfilename)-3], "ngg") == 0) + { + if (geometry) + { + ofstream of(cfilename); + geometry->Save (of); + } + } + else if (strlen(cfilename) > 3 && + strcmp (&cfilename[strlen(cfilename)-3], "stl") == 0) + { + if (stlgeometry) + stlgeometry->Save (cfilename); + } + else if (strlen(cfilename) > 4 && + strcmp (&cfilename[strlen(cfilename)-4], "stlb") == 0) + { + if (stlgeometry) + stlgeometry->SaveBinary (cfilename,"Binary STL Geometry"); + } + else if (strlen(cfilename) > 4 && + strcmp (&cfilename[strlen(cfilename)-4], "stle") == 0) + { + if (stlgeometry) + stlgeometry->SaveSTLE (cfilename); + } + } + } + + else + { + if (geometry) + geometry->Save (cout); + } + return TCL_OK; + } + + + + int Ng_ParseGeometry (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + if (!stlgeometry && !geometry2d && !occgeometry) +#else + if (!stlgeometry && !geometry2d) +#endif + { + double detail = atof (Tcl_GetVar (interp, "::geooptions.detail", 0)); + double facets = atof (Tcl_GetVar (interp, "::geooptions.facets", 0)); + Box<3> box (geometry->BoundingBox()); + + if (atoi (Tcl_GetVar (interp, "::geooptions.drawcsg", 0))) + geometry->CalcTriangleApproximation(box, detail, facets); + } + return TCL_OK; + } + + + + + /* + NgLock * ngpkg_lock = NULL; + + + int Ng_Lock (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + delete ngpkg_lock; + ngpkg_lock = NULL; + + if(strcmp (argv[1], "mesh") == 0) + { + ngpkg_lock = new NgLock(mesh->Mutex()); + } + else if(strcmp (argv[1], "unlock") == 0) + { + ; + } + + return TCL_OK; + } + */ + + int Ng_GeometryOptions (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + const char * command = argv[1]; + + if (strcmp (command, "get") == 0) + { + char buf[20]; + Point3d pmin = geometry->BoundingBox ().PMin(); + Point3d pmax = geometry->BoundingBox ().PMax(); + + sprintf (buf, "%5.1lf", pmin.X()); + Tcl_SetVar (interp, "::geooptions.minx", buf, 0); + sprintf (buf, "%5.1lf", pmin.Y()); + Tcl_SetVar (interp, "::geooptions.miny", buf, 0); + sprintf (buf, "%5.1lf", pmin.Z()); + Tcl_SetVar (interp, "::geooptions.minz", buf, 0); + + sprintf (buf, "%5.1lf", pmax.X()); + Tcl_SetVar (interp, "::geooptions.maxx", buf, 0); + sprintf (buf, "%5.1lf", pmax.Y()); + Tcl_SetVar (interp, "::geooptions.maxy", buf, 0); + sprintf (buf, "%5.1lf", pmax.Z()); + Tcl_SetVar (interp, "::geooptions.maxz", buf, 0); + } + else if (strcmp (command, "set") == 0) + { + Point<3> pmin (atof (Tcl_GetVar (interp, "::geooptions.minx", 0)), + atof (Tcl_GetVar (interp, "::geooptions.miny", 0)), + atof (Tcl_GetVar (interp, "::geooptions.minz", 0))); + Point<3> pmax (atof (Tcl_GetVar (interp, "::geooptions.maxx", 0)), + atof (Tcl_GetVar (interp, "::geooptions.maxy", 0)), + atof (Tcl_GetVar (interp, "::geooptions.maxz", 0))); + Box<3> box (pmin, pmax); + geometry -> SetBoundingBox (box); + CSGeometry::SetDefaultBoundingBox (box); + } + + return TCL_OK; + } + + + + + + // attempt of a simple modeller + + int Ng_CreatePrimitive (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * classname = argv[1]; + tcl_const char * name = argv[2]; + + cout << "Create primitive, class = " << classname + << ", name = " << name << endl; + + Primitive * nprim = Primitive::CreatePrimitive (classname); + Solid * nsol = new Solid (nprim); + + char sname[100]; + for (int j = 1; j <= nprim->GetNSurfaces(); j++) + { + sprintf (sname, "%s,%d", name, j); + geometry -> AddSurface (sname, &nprim->GetSurface(j)); + nprim -> SetSurfaceId (j, geometry->GetNSurf()); + } + + geometry->SetSolid (name, nsol); + + return TCL_OK; + } + + + int Ng_SetPrimitiveData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * name = argv[1]; + tcl_const char * value = argv[2]; + + ARRAY coeffs; + + + cout << "Set primitive data, name = " << name + << ", value = " << value << endl; + + + istringstream vst (value); + double val; + while (!vst.eof()) + { + vst >> val; + coeffs.Append (val); + } + + ((Primitive*) + geometry->GetSolid (name)->GetPrimitive())->SetPrimitiveData (coeffs); + + return TCL_OK; + } + + + + int Ng_SetSolidData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * name = argv[1]; + tcl_const char * val = argv[2]; + + cout << "Set Solid Data, name = " << name + << ", value = " << val << endl; + + istringstream vst (val); + + Solid * nsol = Solid::CreateSolid (vst, geometry->GetSolids()); + geometry->SetSolid (name, nsol); + + return TCL_OK; + } + + + int Ng_GetPrimitiveData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * name = argv[1]; + tcl_const char * classnamevar = argv[2]; + tcl_const char * valuevar = argv[3]; + + const char * classname; + + ARRAY coeffs; + + geometry->GetSolid (name)->GetPrimitive()->GetPrimitiveData (classname, coeffs); + + ostringstream vst; + for (int i = 1; i <= coeffs.Size(); i++) + vst << coeffs.Get(i) << " "; + + cout << "GetPrimitiveData, name = " << name + << ", classnamevar = " << classnamevar + << ", classname = " << classname << endl + << " valuevar = " << valuevar + << ", values = " << vst.str() << endl; + + Tcl_SetVar (interp, classnamevar, (char*)classname, 0); + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + int Ng_GetSolidData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * name = argv[1]; + tcl_const char * valuevar = argv[2]; + + ostringstream vst; + + const Solid * sol = geometry->GetSolid (name); + sol->GetSolidData (vst); + + cout << "GetSolidData, name = " << name << ", data = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + int Ng_GetPrimitiveList (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * valuevar = argv[1]; + int i; + + stringstream vst; + + for (i = 1; i <= geometry->GetNSolids(); i++) + { + const Solid * sol = geometry->GetSolid(i); + if (sol->GetPrimitive()) + vst << sol->Name() << " "; + } + + cout << "primnames = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + + int Ng_GetSurfaceList (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * valuevar = argv[1]; + int i; + + stringstream vst; + + for (i = 1; i <= geometry->GetNSurf(); i++) + { + const Surface * surf = geometry->GetSurface(i); + vst << surf->Name() << " "; + } + + cout << "surfnames = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + int Ng_GetSolidList (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + tcl_const char * valuevar = argv[1]; + int i; + + stringstream vst; + + for (i = 1; i <= geometry->GetNSolids(); i++) + { + const Solid * sol = geometry->GetSolid(i); + if (!sol->GetPrimitive()) + vst << sol->Name() << " "; + } + + cout << "solnames = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + int Ng_TopLevel (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int i; + /* + for (i = 0; i < argc; i++) + cout << argv[i] << ", "; + cout << endl; + */ + + if (strcmp (argv[1], "getlist") == 0) + { + stringstream vst; + + for (i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const Solid * sol; + const Surface * surf; + geometry->GetTopLevelObject (i, sol, surf); + + if (!surf) + vst << "{ " << sol->Name() << " } "; + else + vst << "{ " << sol->Name() << " " << surf->Name() << " } "; + } + + tcl_const char * valuevar = argv[2]; + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + } + + if (strcmp (argv[1], "set") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + geometry->SetTopLevelObject (sol, surf); + } + + if (strcmp (argv[1], "remove") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + geometry->RemoveTopLevelObject (sol, surf); + } + + if (strcmp (argv[1], "setprop") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + tcl_const char * propvar = argv[4]; + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + TopLevelObject * tlo = geometry->GetTopLevelObject (sol, surf); + + if (!tlo) return TCL_OK; + + char varname[50]; + sprintf (varname, "%s(red)", propvar); + double red = atof (Tcl_GetVar (interp, varname, 0)); + sprintf (varname, "%s(blue)", propvar); + double blue = atof (Tcl_GetVar (interp, varname, 0)); + sprintf (varname, "%s(green)", propvar); + double green = atof (Tcl_GetVar (interp, varname, 0)); + tlo -> SetRGB (red, green, blue); + + sprintf (varname, "%s(visible)", propvar); + tlo -> SetVisible (bool(atoi (Tcl_GetVar (interp, varname, 0)))); + sprintf (varname, "%s(transp)", propvar); + tlo -> SetTransparent (bool(atoi (Tcl_GetVar (interp, varname, 0)))); + } + + if (strcmp (argv[1], "getprop") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + tcl_const char * propvar = argv[4]; + + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + TopLevelObject * tlo = geometry->GetTopLevelObject (sol, surf); + + if (!tlo) return TCL_OK; + + char varname[50], varval[10]; + + sprintf (varname, "%s(red)", propvar); + sprintf (varval, "%lf", tlo->GetRed()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(green)", propvar); + sprintf (varval, "%lf", tlo->GetGreen()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(blue)", propvar); + sprintf (varval, "%lf", tlo->GetBlue()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(visible)", propvar); + sprintf (varval, "%d", tlo->GetVisible()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(transp)", propvar); + sprintf (varval, "%d", tlo->GetTransparent()); + Tcl_SetVar (interp, varname, varval, 0); + } + + + return TCL_OK; + } + + + + + + + int Ng_ReadStatus (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + char buf[20], lstring[200]; + if (mesh.Ptr()) + { + sprintf (buf, "%d", mesh->GetNP()); + Tcl_SetVar (interp, "::status_np", buf, 0); + sprintf (buf, "%d", mesh->GetNE()); + Tcl_SetVar (interp, "::status_ne", buf, 0); + sprintf (buf, "%d", mesh->GetNSE()); + Tcl_SetVar (interp, "::status_nse", buf, 0); + } + else + { + Tcl_SetVar (interp, "::status_np", "0", 0); + Tcl_SetVar (interp, "::status_ne", "0", 0); + Tcl_SetVar (interp, "::status_nse", "0", 0); + } + + if (multithread.running) + Tcl_SetVar (interp, "::status_working", "working", 0); + else + Tcl_SetVar (interp, "::status_working", " ", 0); + + Tcl_SetVar (interp, "::status_task", const_cast(multithread.task), 0); + sprintf (buf, "%lf", multithread.percent); + Tcl_SetVar (interp, "::status_percent", buf, 0); + + int i; + lstring[0] = 0; + for (i = 1; i <= tets_in_qualclass.Size(); i++) + { + sprintf (buf, " %d", tets_in_qualclass.Get(i)); + strcat (lstring, buf); + } + for (i = tets_in_qualclass.Size()+1; i <= 20; i++) + strcat (lstring, " 0"); + Tcl_SetVar (interp, "::status_tetqualclasses", lstring, 0); + + return TCL_OK; + } + + + int Ng_MemInfo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + static char buf[100]; + if (argc < 2) return TCL_ERROR; + if (strcmp (argv[1], "moveable") == 0) + { + sprintf (buf, "%6.1f", double(BaseMoveableMem::used)/1048576); + Tcl_SetResult (interp, buf, TCL_STATIC); + return TCL_OK; + } + + + if (strcmp (argv[1], "usedmb") == 0) + { // returns string of 512 '0' or '1' + + static char usedmb[513]; + for (int i = 0; i < 512; i++) + usedmb[i] = (i % 7 == 0) ? '1' : '0'; + + usedmb[512] = 0; + BaseDynamicMem::GetUsed (512, usedmb); + Tcl_SetResult (interp, usedmb, TCL_STATIC); + return TCL_OK; + } + + + + + return TCL_ERROR; + } + + + + int Ng_BCProp (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + static char buf[100]; + + if (argc < 2) + { + Tcl_SetResult (interp, (char*)"Ng_BCProp needs arguments", TCL_STATIC); + return TCL_ERROR; + } + + if (strcmp (argv[1], "setbc") == 0) + { + int facenr = atoi (argv[2]); + int bcnr = atoi (argv[3]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + mesh->GetFaceDescriptor (facenr).SetBCProperty (bcnr); + } + + if (strcmp (argv[1], "setall") == 0) + { + int bcnr = atoi (argv[2]); + if (mesh.Ptr()) + { + int nfd = mesh->GetNFD(); + for (int i = 1; i <= nfd; i++) + mesh->GetFaceDescriptor (i).SetBCProperty (bcnr); + } + } + + if (strcmp (argv[1], "getbc") == 0) + { + int facenr = atoi (argv[2]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + { + sprintf (buf, "%d", mesh->GetFaceDescriptor(facenr).BCProperty()); + } + else + { + strcpy (buf, "0"); + } + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "getbcname") == 0) + { + int facenr = atoi (argv[2]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + { + sprintf (buf, "%s", mesh->GetFaceDescriptor(facenr).GetBCName().c_str()); + } + else + { + strcpy (buf, "-"); + } + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + + if (strcmp (argv[1], "getactive") == 0) + { + sprintf (buf, "%d", vsmesh.SelectedFace()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "setactive") == 0) + { + int facenr = atoi (argv[2]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + { + vsmesh.SetSelectedFace (facenr); + } + } + + if (strcmp (argv[1], "getnfd") == 0) + { + if (mesh.Ptr()) + sprintf (buf, "%d", mesh->GetNFD()); + else + sprintf (buf, "0"); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + return TCL_OK; + } + + + int Ng_SetNextTimeStamp (ClientData clientData, + Tcl_Interp * interp, + int argqc, tcl_const char *argv[]) + { + if (mesh.Ptr()) + mesh -> SetNextTimeStamp(); + return TCL_OK; + } + + + + int Ng_Refine (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + + if (stlgeometry) + { + RefinementSTLGeometry ref (*stlgeometry); + ref.Refine (*mesh); + } + + else if (geometry2d) + { + Refinement2d ref (*geometry2d); + ref.Refine (*mesh); + } + +#ifdef OCCGEOMETRY + else if (occgeometry) + { + OCCRefinementSurfaces ref (*occgeometry); + ref.Refine (*mesh); + } +#endif +#ifdef ACIS + else if (acisgeometry) + { + ACISRefinementSurfaces ref (*acisgeometry); + ACISMeshOptimize2dSurfaces opt(*acisgeometry); + ref.Set2dOptimizer(&opt); + ref.Refine (*mesh); + } +#endif + else + { + RefinementSurfaces ref (*geometry); + MeshOptimize2dSurfaces opt(*geometry); + ref.Set2dOptimizer(&opt); + ref.Refine (*mesh); + } + + return TCL_OK; + } + + int Ng_SecondOrder (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + if (stlgeometry) + { + RefinementSTLGeometry ref (*stlgeometry); + ref.MakeSecondOrder (*mesh); + } +#ifdef OCCGEOMETRY + else if (occgeometry) + { + OCCRefinementSurfaces ref (*occgeometry); + ref.MakeSecondOrder (*mesh); + } +#endif + else if (geometry2d) + { + Refinement2d ref (*geometry2d); + ref.MakeSecondOrder (*mesh); + } + else + { + RefinementSurfaces ref (*geometry); + ref.MakeSecondOrder (*mesh); + } + + return TCL_OK; + } + + + void * HighOrderDummy (void *) + { + // mparam.elementorder = atoi (Tcl_GetVar (interp, "options.elementorder", 0)); + const char * savetask = multithread.task; + + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif +#ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces(*acisgeometry); + } +#endif + else + { + ref = new RefinementSurfaces (*geometry); + } + + // if (!mesh -> coarsemesh) + mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + /* + else + { + mesh -> coarsemesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + mesh -> GetCurvedElements().SetHighOrder(mparam.elementorder); + } + */ + delete ref; + + // + // cout << "WARNING: Ng_HighOrder! ref is not deleted for edge projection visualization" << endl; + + multithread.task = savetask; + multithread.running = 0; + multithread.terminate = 1; + + mesh -> SetNextMajorTimeStamp(); + return 0; + } + + int Ng_HighOrder (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + + multithread.running = 1; + multithread.terminate = 0; + + mparam.elementorder = atoi(argv[1]); + + // if(argc > 2 && strcmp(argv[2],"noparallel") == 0) + HighOrderDummy(NULL); + // else + // RunParallel (HighOrderDummy, NULL); + + return TCL_OK; + } + + + + void * ValidateDummy (void *) + { + RefinementSTLGeometry ref (*stlgeometry); + ref.ValidateSecondOrder (*mesh); + + multithread.running = 0; + return NULL; + } + + + + int Ng_ValidateSecondOrder (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + multithread.running = 1; + RunParallel (ValidateDummy, NULL); + + return TCL_OK; + } + + + int Ng_ZRefinement (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + ZRefinementOptions opt; + opt.minref = 5; + + if (argc >= 2) opt.minref = atoi (argv[1]); + + ZRefinement (*mesh, geometry.Ptr(), opt); + + return TCL_OK; + } + + int Ng_HPRefinement (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + int levels = atoi (argv[1]); + + + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif + else + ref = new RefinementSurfaces (*geometry); + + + HPRefinement (*mesh, ref, levels); + return TCL_OK; + } + + + int Ng_LoadMeshSize (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->LoadLocalMeshSize(argv[1]); + return TCL_OK; + } + + + int Ng_MeshSizeFromSurfaceMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->SetGlobalH (mparam.maxh); + mesh->CalcLocalH(); + + return TCL_OK; + } + + int Ng_SingularPointMS (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int i; + double globh = mparam.maxh; + for (i = 1; i <= geometry->singpoints.Size(); i++) + geometry->singpoints.Get(i)->SetMeshSize (*mesh, globh); + return TCL_OK; + } + + + + int Ng_SingularEdgeMS (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + double globh = mparam.maxh; + for (int i = 1; i <= geometry->singedges.Size(); i++) + geometry->singedges.Get(i)->SetMeshSize (*mesh, globh); + return TCL_OK; + } + + + int Ng_InsertVirtualBL (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + InsertVirtualBoundaryLayer (*mesh); + return TCL_OK; + } + + int Ng_CutOffAndCombine (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + Mesh othermesh; + othermesh.Load (argv[1]); + othermesh.SetGlobalH (mparam.maxh); + othermesh.CalcLocalH(); + + CutOffAndCombine (*mesh, othermesh); + return TCL_OK; + } + + + int Ng_HelmholtzMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + HelmholtzMesh (*mesh); + return TCL_OK; + } + + + + + int Ng_SetMeshingParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + mparam.maxh = atof (Tcl_GetVar (interp, "::options.meshsize", 0)); + mparam.minh = atof (Tcl_GetVar (interp, "::options.minmeshsize", 0)); + mparam.meshsizefilename = Tcl_GetVar (interp, "::options.meshsizefilename", 0); + if (!strlen (mparam.meshsizefilename)) + mparam.meshsizefilename = NULL; + + mparam.curvaturesafety = atof (Tcl_GetVar (interp, "::options.curvaturesafety", 0)); + mparam.segmentsperedge = atof (Tcl_GetVar (interp, "::options.segmentsperedge", 0)); + mparam.badellimit = atof (Tcl_GetVar (interp, "::options.badellimit", 0)); + mparam.secondorder = atoi (Tcl_GetVar (interp, "::options.secondorder", 0)); + mparam.elementorder = atoi (Tcl_GetVar (interp, "::options.elementorder", 0)); + mparam.quad = atoi (Tcl_GetVar (interp, "::options.quad", 0)); + + mparam.inverttets = atoi (Tcl_GetVar (interp, "::options.inverttets", 0)); + mparam.inverttrigs = atoi (Tcl_GetVar (interp, "::options.inverttrigs", 0)); + mparam.uselocalh = atoi (Tcl_GetVar (interp, "::options.localh", 0)); + mparam.grading = atof (Tcl_GetVar (interp, "::options.grading", 0)); + mparam.delaunay = atoi (Tcl_GetVar (interp, "::options.delaunay", 0)); + mparam.checkoverlap = atoi (Tcl_GetVar (interp, "::options.checkoverlap", 0)); + mparam.checkoverlappingboundary = atoi (Tcl_GetVar (interp, "::options.checkoverlappingboundary", 0)); + mparam.checkchartboundary = atoi (Tcl_GetVar (interp, "::options.checkchartboundary", 0)); + mparam.optsteps3d = atoi (Tcl_GetVar (interp, "::options.optsteps3d", 0)); + mparam.optsteps2d = atoi (Tcl_GetVar (interp, "::options.optsteps2d", 0)); + mparam.opterrpow = atof (Tcl_GetVar (interp, "::options.opterrpow", 0)); + + mparam.parthread = atoi (Tcl_GetVar (interp, "::options.parthread", 0)); + mparam.elsizeweight = atof (Tcl_GetVar (interp, "::options.elsizeweight", 0)); + + mparam.autozrefine = atoi (Tcl_GetVar (interp, "::options.autozrefine", 0)); + + extern int printmessage_importance; + extern int printdots; + printmessage_importance = atoi (Tcl_GetVar (interp, "::options.printmsg", 0)); + printdots = (printmessage_importance >= 4); + + BaseMoveableMem::totalsize = + 1048576 * atoi (Tcl_GetVar (interp, "::options.memory", 0)); + if (mesh.Ptr()) + { + mesh->SetGlobalH (mparam.maxh); + mesh->SetMinimalH (mparam.minh); + } + + return TCL_OK; + } + + + + int Ng_SetDebugParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + debugparam.slowchecks = atoi (Tcl_GetVar (interp, "::debug.slowchecks", 0)); + debugparam.debugoutput = atoi (Tcl_GetVar (interp, "::debug.debugoutput", 0)); + debugparam.haltexistingline = atoi (Tcl_GetVar (interp, "::debug.haltexistingline", 0)); + debugparam.haltoverlap = atoi (Tcl_GetVar (interp, "::debug.haltoverlap", 0)); + debugparam.haltsuccess = atoi (Tcl_GetVar (interp, "::debug.haltsuccess", 0)); + debugparam.haltnosuccess = atoi (Tcl_GetVar (interp, "::debug.haltnosuccess", 0)); + debugparam.haltlargequalclass = atoi (Tcl_GetVar (interp, "::debug.haltlargequalclass", 0)); + debugparam.haltsegment = atoi (Tcl_GetVar (interp, "::debug.haltsegment", 0)); + debugparam.haltnode = atoi (Tcl_GetVar (interp, "::debug.haltnode", 0)); + debugparam.haltface = atoi (Tcl_GetVar (interp, "::debug.haltface", 0)); + debugparam.haltsegmentp1 = atoi (Tcl_GetVar (interp, "::debug.haltsegmentp1", 0)); + debugparam.haltsegmentp2 = atoi (Tcl_GetVar (interp, "::debug.haltsegmentp2", 0)); + debugparam.haltfacenr = atoi (Tcl_GetVar (interp, "::debug.haltfacenr", 0)); + return TCL_OK; + } + + + + int Ng_SetSTLParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + + stlparam.yangle = + atof (Tcl_GetVar (interp, "::stloptions.yangle", 0)); + stlparam.contyangle = + atof (Tcl_GetVar (interp, "::stloptions.contyangle", 0)); + stlparam.edgecornerangle = + atof (Tcl_GetVar (interp, "::stloptions.edgecornerangle", 0)); + stlparam.chartangle = + atof (Tcl_GetVar (interp, "::stloptions.chartangle", 0)); + stlparam.outerchartangle = + atof (Tcl_GetVar (interp, "::stloptions.outerchartangle", 0)); + + stlparam.usesearchtree = + atoi (Tcl_GetVar (interp, "::stloptions.usesearchtree", 0)); + + + stlparam.atlasminh = + atof (Tcl_GetVar (interp, "::stloptions.atlasminh", 0)); + + stlparam.resthsurfcurvfac = + atof (Tcl_GetVar (interp, "::stloptions.resthsurfcurvfac", 0)); + stlparam.resthsurfcurvenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthsurfcurvenable", 0)); + + stlparam.resthatlasfac = + atof (Tcl_GetVar (interp, "::stloptions.resthatlasfac", 0)); + stlparam.resthatlasenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthatlasenable", 0)); + + stlparam.resthchartdistfac = + atof (Tcl_GetVar (interp, "::stloptions.resthchartdistfac", 0)); + stlparam.resthchartdistenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthchartdistenable", 0)); + + stlparam.resthlinelengthfac = + atof (Tcl_GetVar (interp, "::stloptions.resthlinelengthfac", 0)); + stlparam.resthlinelengthenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthlinelengthenable", 0)); + + stlparam.resthcloseedgefac = + atof (Tcl_GetVar (interp, "::stloptions.resthcloseedgefac", 0)); + stlparam.resthcloseedgeenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthcloseedgeenable", 0)); + + stlparam.resthedgeanglefac = + atof (Tcl_GetVar (interp, "::stloptions.resthedgeanglefac", 0)); + stlparam.resthedgeangleenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthedgeangleenable", 0)); + + stlparam.resthsurfmeshcurvfac = + atof (Tcl_GetVar (interp, "::stloptions.resthsurfmeshcurvfac", 0)); + stlparam.resthsurfmeshcurvenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthsurfmeshcurvenable", 0)); + + stlparam.recalc_h_opt = + atoi (Tcl_GetVar (interp, "::stloptions.recalchopt", 0)); + // stlparam.Print (cout); + return TCL_OK; + } + + + int Ng_GetCommandLineParameter (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc != 2) + { + Tcl_SetResult (interp, (char*)"Ng_GetCommandLineParameter needs 1 parameter", + TCL_STATIC); + return TCL_ERROR; + } + + static char buf[10]; + + if (parameters.StringFlagDefined (argv[1])) + Tcl_SetResult (interp, + (char*)parameters.GetStringFlag (argv[1], NULL), TCL_STATIC); + else if (parameters.NumFlagDefined (argv[1])) + { + sprintf (buf, "%lf", parameters.GetNumFlag (argv[1], 0)); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + else if (parameters.GetDefineFlag (argv[1])) + Tcl_SetResult (interp, (char*)"defined", TCL_STATIC); + else + Tcl_SetResult (interp, (char*)"undefined", TCL_STATIC); + + return TCL_OK; + } + + + + + extern int GenerateMesh (CSGeometry & geom, + Mesh *& mesh, int perfstepsstart, int perfstepsend, + const char * optstr); + + extern int STLMeshingDummy (STLGeometry* stlgeometry, Mesh*& mesh, + int perfstepsstart, int perfstepsend, char* optstring); + +#ifdef OCCGEOMETRY + extern int OCCGenerateMesh (OCCGeometry & occgeometry, Mesh*& mesh, + int perfstepsstart, int perfstepsend, char* optstring); +#endif + + + + static int perfstepsstart; + static int perfstepsend; + static char* optstring = NULL; + static char* optstringcsg = NULL; + + void * MeshingDummy (void *) + { + + const char * savetask = multithread.task; + multithread.task = "Generate Mesh"; + + ResetTime(); + + + try + { + +#ifdef LOG_STREAM + (*logout) << "Start meshing" << endl; + (*logout) << "Meshing parameters:" << endl; + mparam.Print (*logout); +#endif + + if (stlgeometry) + { +#ifdef LOG_STREAM + (*logout) << "STL parameters:" << endl; + stlparam.Print (*logout); +#endif + + STLMeshingDummy(stlgeometry, mesh.Ptr(), perfstepsstart, perfstepsend, optstring); + } +#ifdef OCCGEOMETRY + else if (occgeometry) + { + OCCGenerateMesh(*occgeometry, mesh.Ptr(), perfstepsstart, perfstepsend, optstring); + } +#endif +#ifdef ACIS + else if (acisgeometry) + { + ACISGenerateMesh(*acisgeometry, mesh.Ptr(), perfstepsstart, perfstepsend, optstring); + } +#endif + + else if (geometry2d) + { + extern void MeshFromSpline2D (SplineGeometry2d & geometry2d, + Mesh *& mesh, MeshingParameters & mp); + MeshFromSpline2D (*geometry2d, mesh.Ptr(), mparam); + } + else + { + int res = + GenerateMesh (*geometry, mesh.Ptr(), perfstepsstart, perfstepsend, optstringcsg); + if (res != MESHING3_OK) return 0; + + if(mparam.autozrefine) + { + ZRefinementOptions opt; + opt.minref = 5; + ZRefinement (*mesh, geometry.Ptr(), opt); + } + } + + + if (mparam.secondorder) + { + if (stlgeometry) + { + RefinementSTLGeometry ref (*stlgeometry); + ref.MakeSecondOrder (*mesh); + } +#ifdef OCCGEOMETRY + else if (occgeometry) + { + OCCRefinementSurfaces ref (*occgeometry); + ref.MakeSecondOrder (*mesh); + } +#endif + else if (geometry2d) + { + Refinement2d ref (*geometry2d); + ref.MakeSecondOrder (*mesh); + } + else + { + RefinementSurfaces ref (*geometry); + ref.MakeSecondOrder (*mesh); + } + } + + if (mparam.elementorder > 1) + { + + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif +#ifdef ACIS + else if (acisgeometry) + ref = new ACISRefinementSurfaces(*acisgeometry); +#endif + else + ref = new RefinementSurfaces (*geometry); + + + mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + + // cout << "WARNING: Ng_HighOrder! ref is not deleted for edge projection visualization" << endl; + + delete ref; + + mesh -> SetNextMajorTimeStamp(); + + } + + + PrintMessage (1, "Meshing done, time = ", GetTime(), " sec"); +#ifdef LOG_STREAM + (*logout) << "Meshing done, time = " << GetTime() << endl; +#endif + } + catch (NgException e) + { + cout << e.What() << endl; + } + multithread.task = savetask; + multithread.running = 0; + +#ifdef OCCGEOMETRY + if (occgeometry) + { + if (occgeometry->ErrorInSurfaceMeshing()) + { + char script[] = "rebuildoccdialog"; + int errcode = Tcl_GlobalEval (tcl_interp, script); + } + } +#endif + + + return NULL; + } + + + int MeshingVal(tcl_const char* str) + { + if (strcmp(str, "ag") == 0) {return MESHCONST_ANALYSE;} + if (strcmp(str, "me") == 0) {return MESHCONST_MESHEDGES;} + if (strcmp(str, "ms") == 0) {return MESHCONST_MESHSURFACE;} + if (strcmp(str, "os") == 0) {return MESHCONST_OPTSURFACE;} + if (strcmp(str, "mv") == 0) {return MESHCONST_MESHVOLUME;} + if (strcmp(str, "ov") == 0) {return MESHCONST_OPTVOLUME;} + + cout << "TCL TK ERROR, wrong meshing value, return='" << str << "'" << endl; + return 0; + } + + int Ng_GenerateMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + multithread.running = 1; + multithread.terminate = 0; + + Ng_SetSTLParameters (clientData, interp, 0, argv); + Ng_SetMeshingParameters (clientData, interp, 0, argv); + + perfstepsstart = 1; + perfstepsend = 6; + + if (optstringcsg) delete optstringcsg; + optstringcsg = NULL; + if (optstring) delete optstring; + optstring = NULL; + + if (argc == 2) + { + perfstepsstart = 1; + perfstepsend = MeshingVal(argv[1]); + } + else if (argc == 3) + { + perfstepsstart = MeshingVal(argv[1]); + perfstepsend = MeshingVal(argv[2]); + } + else if (argc == 4) + { + perfstepsstart = MeshingVal(argv[1]); + perfstepsend = MeshingVal(argv[2]); + optstring = new char[strlen(argv[3])+1]; + strcpy(optstring, argv[3]); + optstringcsg = new char[strlen(argv[3])+1]; + strcpy(optstringcsg, argv[3]); + } + + RunParallel (MeshingDummy, NULL); + + return TCL_OK; + } + + + int Ng_StopMeshing (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + multithread.terminate = 1; + return TCL_OK; + } + + int Ng_MeshInfo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + ostringstream str; + + if (argc >= 2 && strcmp (argv[1], "dim") == 0) + str << mesh->GetDimension(); + else if (argc >= 2 && strcmp (argv[1], "np") == 0) + str << mesh->GetNP(); + else if (argc >= 2 && strcmp (argv[1], "ne") == 0) + str << mesh->GetNE(); + else if (argc >= 2 && strcmp (argv[1], "nse") == 0) + str << mesh->GetNSE(); + else if (argc >= 2 && strcmp (argv[1], "nseg") == 0) + str << mesh->GetNSeg(); + else if (argc >= 2 && strcmp (argv[1], "bbox") == 0) + { + Point3d pmin, pmax; + mesh->GetBox (pmin, pmax); + str << pmin.X() << " " << pmax.X() << " " + << pmin.Y() << " " << pmax.Y() << " " + << pmin.Z() << " " << pmax.Z() << endl; + } + else + { + cout << "argv[1] = " << argv[1] << endl; + Tcl_SetResult (interp, (char*)"Ng_MeshInfo requires an argument out of \n dim np ne", TCL_STATIC); + return TCL_ERROR; + } + + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + return TCL_OK; + } + + int Ng_MeshQuality (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + double angles[4]; + char buf[10]; + + if (mesh.Ptr()) + mesh->CalcMinMaxAngle(mparam.badellimit, angles); + else + { + angles[0] = angles[1] = angles[2] = angles[3] = 0; + } + sprintf (buf, "%5.1lf", angles[0]); + Tcl_SetVar (interp, argv[1], buf, 0); + sprintf (buf, "%5.1lf", angles[1]); + Tcl_SetVar (interp, argv[2], buf, 0); + sprintf (buf, "%5.1lf", angles[2]); + Tcl_SetVar (interp, argv[3], buf, 0); + sprintf (buf, "%5.1lf", angles[3]); + Tcl_SetVar (interp, argv[4], buf, 0); + + return TCL_OK; + } + + int Ng_CheckSurfaceMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->FindOpenElements(); + if (mesh->CheckConsistentBoundary()) + { + PrintMessage (1, "surface mesh not consistent, trying orientation"); + mesh->SurfaceMeshOrientation(); + } + else + { + PrintMessage (1, "surface mesh consistent"); + } + + mesh->CheckOverlappingBoundary(); + return TCL_OK; + } + + int Ng_CheckVolumeMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->CheckVolumeMesh(); + return TCL_OK; + } + + + int Ng_DeleteVolMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (mesh.Ptr()) + mesh->ClearVolumeElements(); + + return TCL_OK; + } + + + int Ng_SplitSeparatedFaces (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (mesh.Ptr()) + mesh->SplitSeparatedFaces (); + return TCL_OK; + } + + + + int Ng_RestrictH (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + if (argc != 3) + return TCL_OK; + if (!mesh.Ptr()) + return TCL_OK; + + + double loch = atof (argv[2]); + if (strcmp (argv[1], "face") == 0) + { + cout << "Restrict h at face to " << loch << endl; + mesh -> RestrictLocalH (RESTRICTH_FACE, vsmesh.SelectedFace(), loch); + } + if (strcmp (argv[1], "edge") == 0) + { + cout << "Restrict h at edge to " << loch << endl; + mesh -> RestrictLocalH (RESTRICTH_EDGE, vsmesh.SelectedEdge(), loch); + } + if (strcmp (argv[1], "point") == 0) + { + cout << "Restrict h at point to " << loch << endl; + mesh -> RestrictLocalH (RESTRICTH_POINT, vsmesh.SelectedPoint(), loch); + } + + return TCL_OK; + } + + + + + + int Ng_Anisotropy (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + if (argc != 2) + return TCL_OK; + if (!mesh.Ptr()) + return TCL_OK; + + if (strcmp (argv[1], "edge") == 0) + { + int edgenr = vsmesh.SelectedEdge(); + for (int i = 1; i <= mesh->GetNSeg(); i++) + { + Segment & seg = mesh->LineSegment(i); + if (seg.edgenr == edgenr) + { + seg.singedge_left = 1 - seg.singedge_left; + seg.singedge_right = 1 - seg.singedge_right; + } + } + } + + return TCL_OK; + } + + + + + BisectionOptions biopt; + + void * BisectDummy (void *) + { + Refinement * ref; + MeshOptimize2d * opt = NULL; + if (stlgeometry) + ref = new RefinementSTLGeometry(*stlgeometry); +#ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); +#endif +#ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces(*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } +#endif + else + { + ref = new RefinementSurfaces(*geometry); + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + + if(!mesh->LocalHFunctionGenerated()) + mesh->CalcLocalH(); + + mesh->LocalHFunction().SetGrading (mparam.grading); + ref -> Bisect (*mesh, biopt); + mesh -> UpdateTopology(); + mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + + multithread.running = 0; + delete ref; + delete opt; + return NULL; + } + + + int Ng_Bisect (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + + if (multithread.running) + { + cout << "Thread alrad running" << endl; + return TCL_OK; + } + multithread.running = 1; + + biopt.outfilename = NULL; // "ngfepp.vol"; + biopt.femcode = "fepp"; + biopt.refinementfilename = NULL; + + if (argc >= 2) + biopt.refinementfilename = argv[1]; + + + // pthread_create (&meshingthread, NULL, &BisectDummy, NULL); + BisectDummy (0); + + /* + extern void BisectTets (Mesh &, const CSGeometry *); + BisectTets (*mesh, geometry); + */ + return TCL_OK; + } + + + + // int Ng_BisectCopyMesh (ClientData clientData, + // Tcl_Interp * interp, + // int argc, tcl_const char *argv[]) + // { + // if (!mesh.Ptr()) + // { + // Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + // return TCL_ERROR; + // } + // if (multithread.running) + // { + // Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + // return TCL_ERROR; + // } + + // BisectTetsCopyMesh (*mesh, geometry.Ptr(), biopt); + // return TCL_OK; + // } + + + + + + + int Ng_Split2Tets (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->Split2Tets (); + + return TCL_OK; + } + + + + + + + + + + + int Ng_STLDoctor (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + //cout << "STL doctor" << endl; + + + stldoctor.drawmeshededges = + atoi (Tcl_GetVar (interp, "::stldoctor.drawmeshededges", 0)); + + stldoctor.geom_tol_fact = + atof (Tcl_GetVar (interp, "::stldoctor.geom_tol_fact", 0)); + + + stldoctor.useexternaledges = + atoi (Tcl_GetVar (interp, "::stldoctor.useexternaledges", 0)); + + stldoctor.showfaces = + atoi (Tcl_GetVar (interp, "::stldoctor.showfaces", 0)); + + stldoctor.conecheck = + atoi (Tcl_GetVar (interp, "::stldoctor.conecheck", 0)); + + stldoctor.spiralcheck = + atoi (Tcl_GetVar (interp, "::stldoctor.spiralcheck", 0)); + + stldoctor.selectwithmouse = + atoi (Tcl_GetVar (interp, "::stldoctor.selectwithmouse", 0)); + + stldoctor.showedgecornerpoints = + atoi (Tcl_GetVar (interp, "::stldoctor.showedgecornerpoints", 0)); + + stldoctor.showmarkedtrigs = + atoi (Tcl_GetVar (interp, "::stldoctor.showmarkedtrigs", 0)); + + stldoctor.showtouchedtrigchart = + atoi (Tcl_GetVar (interp, "::stldoctor.showtouchedtrigchart", 0)); + + //cout << "smt=" << stldoctor.showmarkedtrigs << endl; + + stldoctor.dirtytrigfact = + atof (Tcl_GetVar (interp, "::stldoctor.dirtytrigfact", 0)); + + stldoctor.smoothnormalsweight = + atof (Tcl_GetVar (interp, "::stldoctor.smoothnormalsweight", 0)); + + stldoctor.smoothangle = + atof (Tcl_GetVar (interp, "::stldoctor.smoothangle", 0)); + + stldoctor.selectmode = + atoi (Tcl_GetVar (interp, "::stldoctor.selectmode", 0)); + + stldoctor.edgeselectmode = + atoi (Tcl_GetVar (interp, "::stldoctor.edgeselectmode", 0)); + + stldoctor.longlinefact = + atoi (Tcl_GetVar (interp, "::stldoctor.longlinefact", 0)); + + stldoctor.showexcluded = + atoi (Tcl_GetVar (interp, "::stldoctor.showexcluded", 0)); + + + + if (!stldoctor.selectwithmouse) + { + stldoctor.selecttrig = + atoi (Tcl_GetVar (interp, "::stldoctor.selecttrig", 0)); + + stldoctor.nodeofseltrig = + atoi (Tcl_GetVar (interp, "::stldoctor.nodeofseltrig", 0)); + } + + stldoctor.showvicinity = + atoi (Tcl_GetVar (interp, "::stldoctor.showvicinity", 0)); + + stldoctor.vicinity = + atoi (Tcl_GetVar (interp, "::stldoctor.vicinity", 0)); + + + if (argc >= 2) + { + if (!stlgeometry) + { + Tcl_SetResult (interp, err_needsstlgeometry, TCL_STATIC); + return TCL_ERROR; + } + + if (strcmp (argv[1], "destroy0trigs") == 0) + { + stlgeometry->DestroyDirtyTrigs(); + } + else if (strcmp (argv[1], "movepointtomiddle") == 0) + { + stlgeometry->MoveSelectedPointToMiddle(); + } + else if (strcmp (argv[1], "calcnormals") == 0) + { + stlgeometry->CalcNormalsFromGeometry(); + } + else if (strcmp (argv[1], "showchartnum") == 0) + { + stlgeometry->ShowSelectedTrigChartnum(); + } + else if (strcmp (argv[1], "showcoords") == 0) + { + stlgeometry->ShowSelectedTrigCoords(); + } + else if (strcmp (argv[1], "loadmarkedtrigs") == 0) + { + stlgeometry->LoadMarkedTrigs(); + } + else if (strcmp (argv[1], "savemarkedtrigs") == 0) + { + stlgeometry->SaveMarkedTrigs(); + } + else if (strcmp (argv[1], "neighbourangles") == 0) + { + stlgeometry->NeighbourAnglesOfSelectedTrig(); + } + else if (strcmp (argv[1], "vicinity") == 0) + { + stlgeometry->CalcVicinity(stldoctor.selecttrig); + } + else if (strcmp (argv[1], "markdirtytrigs") == 0) + { + stlgeometry->MarkDirtyTrigs(); + } + else if (strcmp (argv[1], "smoothdirtytrigs") == 0) + { + stlgeometry->SmoothDirtyTrigs(); + } + else if (strcmp (argv[1], "smoothrevertedtrigs") == 0) + { + stlgeometry->GeomSmoothRevertedTrigs(); + } + else if (strcmp (argv[1], "invertselectedtrig") == 0) + { + stlgeometry->InvertTrig(stlgeometry->GetSelectTrig()); + } + else if (strcmp (argv[1], "deleteselectedtrig") == 0) + { + stlgeometry->DeleteTrig(stlgeometry->GetSelectTrig()); + } + else if (strcmp (argv[1], "smoothgeometry") == 0) + { + stlgeometry->SmoothGeometry(); + } + else if (strcmp (argv[1], "orientafterselectedtrig") == 0) + { + stlgeometry->OrientAfterTrig(stlgeometry->GetSelectTrig()); + } + else if (strcmp (argv[1], "marktoperrortrigs") == 0) + { + stlgeometry->MarkTopErrorTrigs(); + } + else if (strcmp (argv[1], "exportedges") == 0) + { + stlgeometry->ExportEdges(); + } + else if (strcmp (argv[1], "importedges") == 0) + { + stlgeometry->ImportEdges(); + } + else if (strcmp (argv[1], "importexternaledges") == 0) + { + stlgeometry->ImportExternalEdges(argv[2]); + } + else if (strcmp (argv[1], "loadedgedata") == 0) + { + if (argc >= 3) + { + stlgeometry->LoadEdgeData(argv[2]); + } + } + else if (strcmp (argv[1], "saveedgedata") == 0) + { + if (argc >= 3) + { + stlgeometry->SaveEdgeData(argv[2]); + } + } + + else if (strcmp (argv[1], "buildexternaledges") == 0) + { + stlgeometry->BuildExternalEdgesFromEdges(); + } + else if (strcmp (argv[1], "smoothnormals") == 0) + { + stlgeometry->SmoothNormals(); + } + else if (strcmp (argv[1], "marknonsmoothnormals") == 0) + { + stlgeometry->MarkNonSmoothNormals(); + } + else if (strcmp (argv[1], "addexternaledge") == 0) + { + stlgeometry->AddExternalEdgeAtSelected(); + } + else if (strcmp (argv[1], "addgeomline") == 0) + { + stlgeometry->AddExternalEdgesFromGeomLine(); + } + else if (strcmp (argv[1], "addlonglines") == 0) + { + stlgeometry->AddLongLinesToExternalEdges(); + } + else if (strcmp (argv[1], "addclosedlines") == 0) + { + stlgeometry->AddClosedLinesToExternalEdges(); + } + else if (strcmp (argv[1], "addnotsinglelines") == 0) + { + stlgeometry->AddAllNotSingleLinesToExternalEdges(); + } + else if (strcmp (argv[1], "deletedirtyexternaledges") == 0) + { + stlgeometry->DeleteDirtyExternalEdges(); + } + else if (strcmp (argv[1], "deleteexternaledge") == 0) + { + stlgeometry->DeleteExternalEdgeAtSelected(); + } + else if (strcmp (argv[1], "deletevicexternaledge") == 0) + { + stlgeometry->DeleteExternalEdgeInVicinity(); + } + + else if (strcmp (argv[1], "addlonglines") == 0) + { + stlgeometry->STLDoctorLongLinesToCandidates(); + } + else if (strcmp (argv[1], "deletedirtyedges") == 0) + { + stlgeometry->STLDoctorDirtyEdgesToCandidates(); + } + else if (strcmp (argv[1], "undoedgechange") == 0) + { + stlgeometry->UndoEdgeChange(); + } + else if (strcmp (argv[1], "buildedges") == 0) + { + stlgeometry->STLDoctorBuildEdges(); + } + else if (strcmp (argv[1], "confirmedge") == 0) + { + stlgeometry->STLDoctorConfirmEdge(); + } + else if (strcmp (argv[1], "candidateedge") == 0) + { + stlgeometry->STLDoctorCandidateEdge(); + } + else if (strcmp (argv[1], "excludeedge") == 0) + { + stlgeometry->STLDoctorExcludeEdge(); + } + else if (strcmp (argv[1], "undefinededge") == 0) + { + stlgeometry->STLDoctorUndefinedEdge(); + } + else if (strcmp (argv[1], "setallundefinededges") == 0) + { + stlgeometry->STLDoctorSetAllUndefinedEdges(); + } + else if (strcmp (argv[1], "erasecandidateedges") == 0) + { + stlgeometry->STLDoctorEraseCandidateEdges(); + } + else if (strcmp (argv[1], "confirmcandidateedges") == 0) + { + stlgeometry->STLDoctorConfirmCandidateEdges(); + } + else if (strcmp (argv[1], "confirmedtocandidateedges") == 0) + { + stlgeometry->STLDoctorConfirmedToCandidateEdges(); + } + } + + return TCL_OK; + } + + + + + + extern int Ng_MeshDoctor (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + + + int Ng_STLInfo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + double data[10]; + static char buf[20]; + + if (!stlgeometry) + { + Tcl_SetResult (interp, err_needsstlgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + + if (stlgeometry) + { + stlgeometry->STLInfo(data); + // cout << "NT=" << data[0] << endl; + + if (argc == 2) + { + if (strcmp (argv[1], "status") == 0) + { + switch (stlgeometry->GetStatus()) + { + case STLGeometry::STL_GOOD: + strcpy (buf, "GOOD"); break; + case STLGeometry::STL_WARNING: + strcpy (buf, "WARNING"); break; + case STLGeometry::STL_ERROR: + strcpy (buf, "ERROR"); break; + } + Tcl_SetResult (interp, buf, TCL_STATIC); + return TCL_OK; + } + if (strcmp (argv[1], "statustext") == 0) + { + Tcl_SetResult (interp, (char*)stlgeometry->GetStatusText().c_str(), TCL_STATIC); + return TCL_OK; + } + if (strcmp (argv[1], "topology_ok") == 0) + { + sprintf (buf, "%d", stlgeometry->Topology_Ok()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + if (strcmp (argv[1], "orientation_ok") == 0) + { + sprintf (buf, "%d", stlgeometry->Orientation_Ok()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + } + } + else + { + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = 0; + data[7] = 0; + } + + + + + sprintf (buf, "%i", (int)data[0]); + Tcl_SetVar (interp, argv[1], buf, 0); + + sprintf (buf, "%5.3g", data[1]); + Tcl_SetVar (interp, argv[2], buf, 0); + sprintf (buf, "%5.3g", data[2]); + Tcl_SetVar (interp, argv[3], buf, 0); + sprintf (buf, "%5.3g", data[3]); + Tcl_SetVar (interp, argv[4], buf, 0); + + sprintf (buf, "%5.3g", data[4]); + Tcl_SetVar (interp, argv[5], buf, 0); + sprintf (buf, "%5.3g", data[5]); + Tcl_SetVar (interp, argv[6], buf, 0); + sprintf (buf, "%5.3g", data[6]); + Tcl_SetVar (interp, argv[7], buf, 0); + + sprintf (buf, "%i", (int)data[7]); + Tcl_SetVar (interp, argv[8], buf, 0); + + return TCL_OK; + } + + + int Ng_STLCalcLocalH (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + + Ng_SetSTLParameters (clientData, interp, argc, argv); + Ng_SetMeshingParameters (clientData, interp, argc, argv); + + if (mesh.Ptr() && stlgeometry) + { + mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), + stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), + mparam.grading); + stlgeometry -> RestrictLocalH(*mesh, mparam.maxh); + + if (stlparam.resthsurfmeshcurvenable) + mesh -> CalcLocalHFromSurfaceCurvature (stlparam.resthsurfmeshcurvfac); + } + + return TCL_OK; + } + + + + // Togl + + SYMBOLTABLE & GetVisualizationScenes () + { + static SYMBOLTABLE vss; + return vss; + } + + void AddVisualizationScene (const string & name, + VisualScene * avs) + { + GetVisualizationScenes().Set (name.c_str(), avs); + } + + + void SetVisualScene (Tcl_Interp * interp) + { +#ifdef OPENGL +#ifndef SMALLLIB + const char * vismode = vispar.selectvisual; + // Tcl_GetVar (interp, "selectvisual", 0); + vs = &vscross; + if (GetVisualizationScenes().Used(vismode)) + { + vs = GetVisualizationScenes().Get(vismode); + } + else if (vismode) + { + if (strcmp (vismode, "geometry") == 0) + { + if (stlgeometry != NULL) + vs = &vsstlmeshing; + else if (geometry2d) + vs = &vsgeom2d; + +#ifdef OCCGEOMETRY + else if (occgeometry) + vs = &vsoccgeom; +#endif // OCCGEOMETRY +#ifdef ACIS + else if (acisgeometry) + vs = &vsacisgeom; +#endif // ACIS + else + vs = &vsgeom; + + // vs = &vsstlgeom; + } + if (strcmp (vismode, "mesh") == 0) + { + if (!meshdoctor.active) + vs = &vsmesh; + else + vs = &vsmeshdoc; + } + // if (strcmp (vismode, "surfmeshing") == 0) vs = &vssurfacemeshing; + if (strcmp (vismode, "specpoints") == 0) vs = &vsspecpoints; + // if (strcmp (vismode, "solution") == 0) vs = &vssolution; + } +#endif // !SMALLLIB +#endif // OPENGL + } + + + static void init( struct Togl *togl ) + { + VisualScene::fontbase = Togl_LoadBitmapFont( togl, TOGL_BITMAP_8_BY_13 ); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + SetVisualScene (Togl_Interp(togl)); + vs->DrawScene(); + } + + + static void zap( struct Togl *togl ) + { + ; + } + + static void draw( struct Togl *togl ) + { + Tcl_Interp * interp = Togl_Interp(togl); + + SetVisualScene (interp); + +#ifdef STEREO + if (1) // vispar.stereo) + { + glMatrixMode (GL_MODELVIEW); + glPushMatrix(); + + glLoadIdentity (); + + // glTranslatef (0.1, 0, 0); + gluLookAt (0.3, 0, 6, 0, 0, 0, 0, 1, 0); + Togl_StereoDrawBuffer(GL_BACK_RIGHT); + vs->DrawScene(); + + glLoadIdentity (); + // glTranslatef (-0.1, 0, 0); + gluLookAt (-0.3, 0, 6, 0, 0, 0, 0, 1, 0); + Togl_StereoDrawBuffer(GL_BACK_LEFT); + vs->DrawScene(); + glPopMatrix(); + + Togl_SwapBuffers(togl); + } + else +#endif + { + glPushMatrix(); + glLoadIdentity(); + // gluLookAt (0, 0, 6, 0, 0, 0, 0, 1, 0); + vs->DrawScene(); + + Togl_SwapBuffers(togl); + glPopMatrix(); + } + } + + +#ifndef VIDEOCLIP + static int Ng_SnapShot (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + const char * filename = argv[2]; + + char str[250]; + char filename2[250]; + int len = strlen(filename); + strcpy (filename2, filename); + + filename2[len-3] = 'p'; + filename2[len-2] = 'p'; + filename2[len-1] = 'm'; + filename2[len] = 0; + + cout << "Snapshot to file '" << filename << endl; + + int w = Togl_Width (togl); + w = int((w + 1) / 4) * 4 + 4; + int h = Togl_Height (togl); + + // unsigned char * buffer = new unsigned char[w*h*4]; + unsigned char * buffer = new unsigned char[w*h*3]; + glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer); + + ofstream outfile(filename2); + outfile << "P6" << endl + << "# CREATOR: Netgen" << endl + << w << " " << h << endl + << "255" << endl; + for (int i = 0; i < h; i++) + for (int j = 0; j < w; j++) + for (int k = 0; k < 3; k++) + outfile.put (buffer[k+3*j+3*w*(h-i-1)]); + outfile << flush; + + delete[] buffer; + + // convert image file (Unix/Linux only): + sprintf(str,"convert -quality 100 %s %s", filename2, filename); + + int err = system(str); + if (err != 0) + { + Tcl_SetResult (Togl_Interp(togl), (char*)"Cannot convert image file", TCL_VOLATILE); + return TCL_ERROR; + } + sprintf(str,"rm %s", filename2); + system(str); + + return TCL_OK; + } + + + +#else + + + static int Ng_SnapShot (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + const char * filename = argv[2]; + int len = strlen(filename); + + if (strcmp ("jpg", filename+len-3) == 0) + { + cout << "Snapshot to file '" << filename << "'" << endl; + + int w = Togl_Width (togl); + w = int((w + 1) / 4) * 4 + 4; + int h = Togl_Height (togl); + + // unsigned char * buffer = new unsigned char[w*h*4]; + unsigned char * buffer = new unsigned char[w*h*3]; + glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer); + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE *outfile = fopen(filename,"wb"); + JSAMPROW row_pointer[1]; + int row_stride, quality = 85; // 1...100 + + cinfo.err = jpeg_std_error( &jerr ); + jpeg_create_compress( &cinfo ); + jpeg_stdio_dest( &cinfo, outfile ); + + + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults( &cinfo ); + jpeg_set_quality( &cinfo, quality, TRUE ); + jpeg_start_compress( &cinfo, TRUE ); + + row_stride = 3*w; + while( cinfo.next_scanline < cinfo.image_height ) { + row_pointer[0] = &buffer[ (h-1-cinfo.next_scanline) * row_stride ]; + (void)jpeg_write_scanlines( &cinfo, row_pointer, 1 ); + } + + jpeg_finish_compress( &cinfo ); + fclose( outfile ); + + jpeg_destroy_compress( &cinfo ); + fprintf( stdout, "done [ok]\n" ); + fflush( stdout ); + + free( buffer ); + return TCL_OK; + } + else + { + cout << "Snapshot to " << filename << " not supported" << endl; + return TCL_ERROR; + } + } + + +#endif + + +#ifdef VIDEOCLIP + // VIDEO CLIP: + +#define INBUF_SIZE 4096 +#define STATE_READY 0 +#define STATE_STARTED 1 +#define DEFAULT_B_FRAMES 3 + // #define DEFAULT_B_FRAMES 0 +#define DEFAULT_GOP_SIZE 200 + // #define DEFAULT_GOP_SIZE 10 + // #define DEFAULT_BITRATE 500000 +#define DEFAULT_BITRATE 5000000 + // #define DEFAULT_MPG_BUFSIZE 500000 +#define DEFAULT_MPG_BUFSIZE 500000 + + + typedef struct buffer_s { + uint8_t *MPG; + uint8_t *YUV; + uint8_t *RGB; + uint8_t *ROW; + } buffer_t; + + void free_buffers( buffer_t *buff ) { + free( buff->MPG ); + free( buff->YUV ); + free( buff->RGB ); + free( buff->ROW ); + } + + static double psnr( double d ) { + if( d==0 ) + return INFINITY; + return -10.0*log( d )/log( 10.0 ); + } + + void print_info( int count_frames, AVCodecContext *context, int bytes ) { + double tmp = context->width * context->height * 255.0 * 255.0; + double Ypsnr = psnr( context->coded_frame->error[0] / tmp ); + double quality = context->coded_frame->quality/(double)FF_QP2LAMBDA; + char pict_type = av_get_pict_type_char(context->coded_frame->pict_type); + cout << "video: frame=" << count_frames << " type=" << pict_type; + cout << " size=" << bytes << " PSNR(Y)=" << Ypsnr << " dB q=" << (float)quality << endl; + } + + static int Ng_VideoClip (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + static AVCodec *codec = NULL; + static AVCodecContext *context = NULL; + static AVFrame *YUVpicture = NULL; + static AVFrame *RGBpicture = NULL; + static int bytes, PIXsize, stride; + static int y, nx, ny, ox, oy, viewp[4]; + static int i_state = STATE_READY; + static int initialized = 0; + static int count_frames = 0; + static int bitrate = DEFAULT_BITRATE; + static int gopsize = DEFAULT_GOP_SIZE; + static int bframes = DEFAULT_B_FRAMES; + static int MPGbufsize = DEFAULT_MPG_BUFSIZE; + static CodecID codec_id = CODEC_ID_MPEG1VIDEO; + static FILE *MPGfile; + static buffer_t buff; + + + if (strcmp (argv[2], "init") == 0) + { + // Can't initialize when running: + //------------------------------- + if( i_state != STATE_READY ) { + cout << "cannot initialize: already running" << endl; + return TCL_ERROR; + } + + // Open output file: + //------------------- + const char * filename = argv[3]; + cout << "Saving videoclip to file '" << filename << "'" << endl; + MPGfile = fopen(filename, "wb"); + + // Determine picture size: + //------------------------ + nx = Togl_Width (togl); + nx = int((nx + 1) / 4) * 4 + 4; + ny = Togl_Height (togl); + ny = 2 * (ny/2); + cout << "Width=" << nx << ", height=" << ny << endl; + + // Allocate buffers: + //------------------ + PIXsize = nx*ny; + stride = 3*nx; + buff.RGB = (uint8_t*)malloc(stride*ny); + buff.ROW = (uint8_t*)malloc(stride); + buff.YUV = (uint8_t*)malloc(3*(PIXsize/2)); + buff.MPG = (uint8_t*)malloc(MPGbufsize); + + // Initialize libavcodec: + //----------------------- + if( !initialized ) { + avcodec_init(); + avcodec_register_all(); + initialized = 1; + } + + // Choose codec: + //-------------- + codec = avcodec_find_encoder( codec_id ); + if( !codec ) { + free_buffers( &buff ); + fclose( MPGfile ); + cout << "can't find codec" << endl; + return TCL_ERROR; + } + + // Init codec context etc.: + //-------------------------- + context = avcodec_alloc_context(); + context->bit_rate = bitrate; + context->width = nx; + context->height = ny; + context->time_base = (AVRational){ 1, 25 }; + context->gop_size = gopsize; + context->max_b_frames = bframes; + context->pix_fmt = PIX_FMT_YUV420P; + context->flags |= CODEC_FLAG_PSNR; + + if( avcodec_open( context, codec ) < 0 ) { + avcodec_close( context ); + av_free( context ); + free_buffers( &buff ); + fclose( MPGfile ); + cout << "can't open codec" << endl; + return TCL_ERROR; + } + + YUVpicture = avcodec_alloc_frame(); + + YUVpicture->data[0] = buff.YUV; + YUVpicture->data[1] = buff.YUV + PIXsize; + YUVpicture->data[2] = buff.YUV + PIXsize + PIXsize / 4; + YUVpicture->linesize[0] = nx; + YUVpicture->linesize[1] = nx / 2; + YUVpicture->linesize[2] = nx / 2; + + RGBpicture = avcodec_alloc_frame(); + + RGBpicture->data[0] = buff.RGB; + RGBpicture->data[1] = buff.RGB; + RGBpicture->data[2] = buff.RGB; + RGBpicture->linesize[0] = stride; + RGBpicture->linesize[1] = stride; + RGBpicture->linesize[2] = stride; + + // Set state "started": + //---------------------- + i_state = STATE_STARTED; + cout << "savempg: state: started" << endl; + + return TCL_OK; + } + + else if (strcmp (argv[2], "addframe") == 0) + { + // Can't compress if status != started: + //------------------------------------- + if( i_state != STATE_STARTED ) { + cout << "cannot add frame: codec not initialized" << endl; + return TCL_ERROR; + } + + // Read RGB data: + //--------------- + glReadPixels (0, 0, nx, ny, GL_RGB, GL_UNSIGNED_BYTE, buff.RGB ); + + // The picture is upside down - flip it: + //--------------------------------------- + for( y=0; yMouseMove (oldx, oldy, newx, newy, argv[5][0]); + + return TCL_OK; + } + + + int Ng_MouseDblClick (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int px, py; + + px = atoi (argv[1]); + py = atoi (argv[2]); + + SetVisualScene(interp); + vs->MouseDblClick (px, py); + + return TCL_OK; + } + + + int Ng_ZoomAll (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + vs->BuildScene (1); + + return TCL_OK; + } + + + int Ng_Center (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + vs->BuildScene (2); + + return TCL_OK; + } + + + int Ng_StandardRotation (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + vs->StandardRotation (argv[1]); + + return TCL_OK; + } + + int Ng_ArbitraryRotation (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + ARRAY alpha; + ARRAY vec; + + for(int i=1; iArbitraryRotation (alpha,vec); + + return TCL_OK; + } + + + int Ng_Metis (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef METIS + + if (!mesh) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + // METIS Partitioning + + if (mesh->GetDimension() == 3) + { + using namespace metis; + + int ne = mesh->GetNE(); + if (ne < 3) + { + Tcl_SetResult (interp, "This operation needs a volume mesh", TCL_STATIC); + return TCL_ERROR; + } + + int nn = mesh->GetNP(); + + ELEMENT_TYPE elementtype = mesh->VolumeElement(1).GetType(); + int npe = mesh->VolumeElement(1).GetNP(); + + for (int i = 2; i<=ne; i++) + if (mesh->VolumeElement(i).GetType() != elementtype) + { + Tcl_SetResult (interp, "Works in 3D only uniformal tet or hex meshes", TCL_STATIC); + return TCL_ERROR; + } + + idxtype *elmnts; + elmnts = new idxtype[ne*npe]; + + int etype; + if (elementtype == TET) + etype = 2; + else if (elementtype == HEX) + etype = 3; + else + { + Tcl_SetResult (interp, "Works in 3D only uniformal tet or hex meshes", TCL_STATIC); + return TCL_ERROR; + } + + for (int i=1; i<=ne; i++) + for (int j=1; j<=npe; j++) + elmnts[(i-1)*npe+(j-1)] = mesh->VolumeElement(i).PNum(j)-1; + + + int numflag = 0; + int nparts = atoi (argv[1]); + int edgecut; + idxtype *epart, *npart; + epart = new idxtype[ne]; + npart = new idxtype[nn]; + + cout << "Starting Metis (" << ne << " Elements, " << nn << " Nodes, " << nparts << " Partitions) ... " << flush; + + METIS_PartMeshNodal (&ne, &nn, elmnts, &etype, &numflag, &nparts, + &edgecut, epart, npart); + + cout << "done" << endl; + + cout << "edge-cut: " << edgecut << ", balance: " << ComputeElementBalance(ne, nparts, epart) << endl; + + for (int i=1; i<=ne; i++) + mesh->VolumeElement(i).SetPartition(epart[i-1]); + + mesh->SetNextTimeStamp(); + } + + +#endif + return TCL_OK; + } + + + + + + + int Ng_SetOCCVisParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + int showvolume; + + showvolume = atoi (Tcl_GetVar (interp, "::occoptions.showvolumenr", 0)); + + if (showvolume != vispar.occshowvolumenr) + { + if (showvolume < 0 || showvolume > occgeometry->NrSolids()) + { + char buf[20]; + sprintf (buf, "%5i", vispar.occshowvolumenr); + Tcl_SetVar (interp, "::occoptions.showvolumenr", buf, 0); + } + else + { + vispar.occshowvolumenr = showvolume; + if (occgeometry) + occgeometry -> changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + } + + int temp; + + temp = atoi (Tcl_GetVar (interp, "::occoptions.visproblemfaces", 0)); + + if ((bool) temp != vispar.occvisproblemfaces) + { + vispar.occvisproblemfaces = temp; + if (occgeometry) + occgeometry -> changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + vispar.occshowsurfaces = atoi (Tcl_GetVar (interp, "::occoptions.showsurfaces", 0)); + vispar.occshowedges = atoi (Tcl_GetVar (interp, "::occoptions.showedges", 0)); + vispar.occzoomtohighlightedentity = atoi (Tcl_GetVar (interp, "::occoptions.zoomtohighlightedentity", 0)); + vispar.occdeflection = pow(10.0,-1-atof (Tcl_GetVar (interp, "::occoptions.deflection", 0))); + +#endif + + + + + +#ifdef ACIS + vispar.ACISshowfaces = atoi (Tcl_GetVar (interp, "::occoptions.showsurfaces", 0)); + vispar.ACISshowedges = atoi (Tcl_GetVar (interp, "::occoptions.showedges", 0)); + vispar.ACISshowsolidnr = atoi (Tcl_GetVar (interp, "::occoptions.showsolidnr", 0)); + vispar.ACISshowsolidnr2 = atoi (Tcl_GetVar (interp, "::occoptions.showsolidnr2", 0)); + +#endif + + + + return TCL_OK; + } + + void SelectFaceInOCCDialogTree (int facenr) + { + char script[50]; + sprintf (script, "selectentity {Face %i}", facenr); + int errcode = Tcl_GlobalEval (tcl_interp, script); + } + + + + int Ng_GetOCCData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + + static char buf[1000]; + buf[0] = 0; + stringstream str; + + if (argc >= 2) + { + if (strcmp (argv[1], "getentities") == 0) + { + if (occgeometry) + { + occgeometry->GetTopologyTree(str); + } + } + } + + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + +#endif + return TCL_OK; + } + + int Ng_OCCCommand (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + + stringstream str; + if (argc >= 2) + { + if (strcmp (argv[1], "isoccgeometryloaded") == 0) + { + if (occgeometry) + str << "1 " << flush; + else str << "0 " << flush; + + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (occgeometry) + { + if (strcmp (argv[1], "buildvisualizationmesh") == 0) + { + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "mesherror") == 0) + { + if (occgeometry->ErrorInSurfaceMeshing()) + str << 1; + else + str << 0; + } + if (strcmp (argv[1], "sewfaces") == 0) + { + cout << "Before operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->SewFaces(); + occgeometry->BuildFMap(); + cout << endl << "After operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "makesolid") == 0) + { + cout << "Before operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->MakeSolid(); + occgeometry->BuildFMap(); + cout << endl << "After operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "upgradetopology") == 0) + { + cout << "Before operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->SewFaces(); + occgeometry->MakeSolid(); + occgeometry->BuildFMap(); + cout << endl << "After operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "shapehealing") == 0) + { + occgeometry->tolerance = + atof (Tcl_GetVar (interp, "::occoptions.tolerance", 0)); + occgeometry->fixsmalledges = + atoi (Tcl_GetVar (interp, "::occoptions.fixsmalledges", 0)); + occgeometry->fixspotstripfaces = + atoi (Tcl_GetVar (interp, "::occoptions.fixspotstripfaces", 0)); + occgeometry->sewfaces = + atoi (Tcl_GetVar (interp, "::occoptions.sewfaces", 0)); + occgeometry->makesolids = + atoi (Tcl_GetVar (interp, "::occoptions.makesolids", 0)); + occgeometry->splitpartitions = + atoi (Tcl_GetVar (interp, "::occoptions.splitpartitions", 0)); + + // cout << "Before operation:" << endl; + // occgeometry->PrintNrShapes(); + occgeometry->HealGeometry(); + occgeometry->BuildFMap(); + // cout << endl << "After operation:" << endl; + // occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + + if (strcmp (argv[1], "highlightentity") == 0) + { + if (strcmp (argv[2], "Face") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + occgeometry->fvispar[nr-1].Highlight(); + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[2], "Shell") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->shmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Highlight(); + } + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[2], "Solid") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->somap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Highlight(); + } + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + /* + if (strcmp (argv[2], "CompSolid") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->cmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Highlight(); + } + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + */ + + if (strcmp (argv[2], "Edge") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + occgeometry->evispar[nr-1].Highlight(); + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[2], "Wire") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->wmap(nr), TopAbs_EDGE); + exp.More(); exp.Next()) + { + int i = occgeometry->emap.FindIndex (TopoDS::Edge(exp.Current())); + occgeometry->evispar[i-1].Highlight(); + } + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + if (strcmp (argv[2], "Vertex") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + occgeometry->vvispar[nr-1].Highlight(); + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + } + + + + if (strcmp (argv[1], "show") == 0) + { + int nr = atoi (argv[3]); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + + if (strcmp (argv[2], "Face") == 0) + { + occgeometry->fvispar[nr-1].Show(); + } + if (strcmp (argv[2], "Shell") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->shmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Show(); + } + } + if (strcmp (argv[2], "Solid") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->somap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Show(); + } + } + if (strcmp (argv[2], "Edge") == 0) + { + occgeometry->evispar[nr-1].Show(); + } + if (strcmp (argv[2], "Wire") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->wmap(nr), TopAbs_EDGE); + exp.More(); exp.Next()) + { + int i = occgeometry->emap.FindIndex (TopoDS::Edge(exp.Current())); + occgeometry->evispar[i-1].Show(); + } + } + } + + + if (strcmp (argv[1], "hide") == 0) + { + int nr = atoi (argv[3]); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + + if (strcmp (argv[2], "Face") == 0) + { + occgeometry->fvispar[nr-1].Hide(); + } + if (strcmp (argv[2], "Shell") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->shmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Hide(); + } + } + if (strcmp (argv[2], "Solid") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->somap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Hide(); + } + } + if (strcmp (argv[2], "Edge") == 0) + { + occgeometry->evispar[nr-1].Hide(); + } + if (strcmp (argv[2], "Wire") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->wmap(nr), TopAbs_EDGE); + exp.More(); exp.Next()) + { + int i = occgeometry->emap.FindIndex (TopoDS::Edge(exp.Current())); + occgeometry->evispar[i-1].Hide(); + } + } + } + + + + if (strcmp (argv[1], "findsmallentities") == 0) + { + stringstream str(""); + occgeometry->CheckIrregularEntities(str); + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (strcmp (argv[1], "getunmeshedfaceinfo") == 0) + { + occgeometry->GetUnmeshedFaceInfo(str); + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (strcmp (argv[1], "getnotdrawablefaces") == 0) + { + occgeometry->GetNotDrawableFaces(str); + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (strcmp (argv[1], "redrawstatus") == 0) + { + int i = atoi (argv[2]); + occgeometry->changed = i; + } + if (strcmp (argv[1], "swaporientation") == 0) + { + IGESControl_Writer writer("millimeters", 1); + writer.AddShape (occgeometry->shape); + writer.Write ("1.igs"); + /* + int nr = atoi (argv[3]); + + // const_cast (occgeometry->fmap(nr)).Reverse(); + + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(occgeometry->shape); + + TopoDS_Shape sh; + + // if (strcmp (argv[2], "CompSolid") == 0) sh = occgeometry->cmap(nr); + if (strcmp (argv[2], "Solid") == 0) sh = occgeometry->somap(nr); + if (strcmp (argv[2], "Shell") == 0) sh = occgeometry->shmap(nr); + if (strcmp (argv[2], "Face") == 0) sh = occgeometry->fmap(nr); + if (strcmp (argv[2], "Wire") == 0) sh = occgeometry->wmap(nr); + if (strcmp (argv[2], "Edge") == 0) sh = occgeometry->emap(nr); + + rebuild->Replace(sh, sh.Reversed(), Standard_False); + + TopoDS_Shape newshape = rebuild->Apply(occgeometry->shape, TopAbs_SHELL, 1); + occgeometry->shape = newshape; + + occgeometry->BuildFMap(); + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + */ + } + if (strcmp (argv[1], "marksingular") == 0) + { + int nr = atoi (argv[3]); + cout << "marking " << argv[2] << " " << nr << endl; + char buf[2]; buf[0] = '0'; buf[1] = 0; + bool sing = false; + if (strcmp (argv[2], "Face") == 0) + sing = occgeometry->fsingular[nr-1] = !occgeometry->fsingular[nr-1]; + if (strcmp (argv[2], "Edge") == 0) + sing = occgeometry->esingular[nr-1] = !occgeometry->esingular[nr-1]; + if (strcmp (argv[2], "Vertex") == 0) + sing = occgeometry->vsingular[nr-1] = !occgeometry->vsingular[nr-1]; + + if (sing) buf[0] = '1'; + + Tcl_SetVar (interp, "::ismarkedsingular", buf, 0); + + stringstream str; + occgeometry->GetTopologyTree (str); + + char* cstr = (char*)str.str().c_str(); + + (*testout) << cstr << endl; + + char helpstr[1000]; + + while (strchr (cstr, '}')) + { + strncpy (helpstr, cstr+2, strlen(strchr(cstr+2, '}'))); + (*testout) << "***" << cstr << "***" << endl; + cstr = strchr (cstr, '}'); + } + } + } + } + +#endif + return TCL_OK; + } + + + +#ifdef OCCGEOMETRY + + void OCCConstructGeometry (OCCGeometry & geom); + + int Ng_OCCConstruction (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (occgeometry) + OCCConstructGeometry (*occgeometry); + return TCL_OK; + } +#endif + + + +#ifndef ACIS + int Ng_ACISCommand (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc >= 2) + { + if (strcmp (argv[1], "isACISavailable") == 0) + { + Tcl_SetResult (interp, "no", TCL_STATIC); + return TCL_OK; + } + } + Tcl_SetResult (interp, "undefined ACiS command", TCL_STATIC); + return TCL_ERROR; + } +#endif + + + + + int Ng_SetVisParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!Tcl_GetVar (interp, "::viewoptions.light.amb", TCL_GLOBAL_ONLY)) + return TCL_ERROR; + + vispar.lightamb = atof (Tcl_GetVar (interp, "::viewoptions.light.amb", TCL_GLOBAL_ONLY)); + vispar.lightdiff = atof (Tcl_GetVar (interp, "::viewoptions.light.diff", TCL_GLOBAL_ONLY)); + vispar.lightspec = atof (Tcl_GetVar (interp, "::viewoptions.light.spec", TCL_GLOBAL_ONLY)); + vispar.shininess = atof (Tcl_GetVar (interp, "::viewoptions.mat.shininess", TCL_GLOBAL_ONLY)); + vispar.locviewer = atoi (Tcl_GetVar (interp, "::viewoptions.light.locviewer", TCL_GLOBAL_ONLY)); + vispar.transp = atof (Tcl_GetVar (interp, "::viewoptions.mat.transp", TCL_GLOBAL_ONLY)); + + vispar.clipnormal.X() = atof (Tcl_GetVar (interp, "::viewoptions.clipping.nx", TCL_GLOBAL_ONLY)); + vispar.clipnormal.Y() = atof (Tcl_GetVar (interp, "::viewoptions.clipping.ny", TCL_GLOBAL_ONLY)); + vispar.clipnormal.Z() = atof (Tcl_GetVar (interp, "::viewoptions.clipping.nz", TCL_GLOBAL_ONLY)); + vispar.clipdist = atof (Tcl_GetVar (interp, "::viewoptions.clipping.dist", TCL_GLOBAL_ONLY)); + vispar.clipenable = atoi (Tcl_GetVar (interp, "::viewoptions.clipping.enable", TCL_GLOBAL_ONLY)); + vispar.clipdomain = + atoi (Tcl_GetVar (interp, "::viewoptions.clipping.onlydomain", TCL_GLOBAL_ONLY)); + vispar.donotclipdomain = + atoi (Tcl_GetVar (interp, "::viewoptions.clipping.notdomain", TCL_GLOBAL_ONLY)); + + vispar.clipplanetimestamp = NextTimeStamp(); + + + vispar.whitebackground = atoi (Tcl_GetVar (interp, "::viewoptions.whitebackground", TCL_GLOBAL_ONLY)); + vispar.drawcoordinatecross = atoi (Tcl_GetVar (interp, "::viewoptions.drawcoordinatecross", TCL_GLOBAL_ONLY)); + vispar.drawcolorbar = atoi (Tcl_GetVar (interp, "::viewoptions.drawcolorbar", TCL_GLOBAL_ONLY)); + vispar.drawnetgenlogo = atoi (Tcl_GetVar (interp, "::viewoptions.drawnetgenlogo", TCL_GLOBAL_ONLY)); + vispar.stereo = atoi (Tcl_GetVar (interp, "::viewoptions.stereo", TCL_GLOBAL_ONLY)); + vispar.colormeshsize = atoi (Tcl_GetVar (interp, "::viewoptions.colormeshsize", TCL_GLOBAL_ONLY)); + + VisualScene :: SetBackGroundColor (vispar.whitebackground ? 1 : 0); + + strcpy (vispar.selectvisual, Tcl_GetVar (interp, "::selectvisual", TCL_GLOBAL_ONLY)); + + // vispar.showstltrias = atoi (Tcl_GetVar (interp, "::viewoptions.stl.showtrias", TCL_GLOBAL_ONLY)); + + vispar.stlshowtrias = + atoi (Tcl_GetVar (interp, "::stloptions.showtrias", TCL_GLOBAL_ONLY)); + vispar.stlshowfilledtrias = + atoi (Tcl_GetVar (interp, "::stloptions.showfilledtrias", TCL_GLOBAL_ONLY)); + vispar.stlshowedges = + atoi (Tcl_GetVar (interp, "::stloptions.showedges", TCL_GLOBAL_ONLY)); + vispar.stlshowmarktrias = + atoi (Tcl_GetVar (interp, "::stloptions.showmarktrias", TCL_GLOBAL_ONLY)); + vispar.stlshowactivechart = + atoi (Tcl_GetVar (interp, "::stloptions.showactivechart", TCL_GLOBAL_ONLY)); + vispar.stlchartnumber = + atoi (Tcl_GetVar (interp, "::stloptions.chartnumber", TCL_GLOBAL_ONLY)); + vispar.stlchartnumberoffset = + atoi (Tcl_GetVar (interp, "::stloptions.chartnumberoffset", TCL_GLOBAL_ONLY)); + + vispar.occshowsurfaces = + atoi (Tcl_GetVar (interp, "::occoptions.showsurfaces", TCL_GLOBAL_ONLY)); + vispar.occshowedges = + atoi (Tcl_GetVar (interp, "::occoptions.showedges", TCL_GLOBAL_ONLY)); + + vispar.drawoutline = + atoi (Tcl_GetVar (interp, "::viewoptions.drawoutline", TCL_GLOBAL_ONLY)); + vispar.drawfilledtrigs = + atoi (Tcl_GetVar (interp, "::viewoptions.drawfilledtrigs", TCL_GLOBAL_ONLY)); + vispar.subdivisions = + atoi (Tcl_GetVar (interp, "::visoptions.subdivisions", TCL_GLOBAL_ONLY)); + vispar.drawbadels = + atoi (Tcl_GetVar (interp, "::viewoptions.drawbadels", TCL_GLOBAL_ONLY)); + vispar.drawedges = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedges", TCL_GLOBAL_ONLY)); + + vispar.drawtetsdomain = + atoi (Tcl_GetVar (interp, "::viewoptions.drawtetsdomain", TCL_GLOBAL_ONLY)); + vispar.drawtets = + atoi (Tcl_GetVar (interp, "::viewoptions.drawtets", TCL_GLOBAL_ONLY)); + vispar.drawprisms = + atoi (Tcl_GetVar (interp, "::viewoptions.drawprisms", TCL_GLOBAL_ONLY)); + vispar.drawpyramids = + atoi (Tcl_GetVar (interp, "::viewoptions.drawpyramids", TCL_GLOBAL_ONLY)); + vispar.drawhexes = + atoi (Tcl_GetVar (interp, "::viewoptions.drawhexes", TCL_GLOBAL_ONLY)); + vispar.shrink = + atof (Tcl_GetVar (interp, "::viewoptions.shrink", TCL_GLOBAL_ONLY)); + vispar.drawidentified = + atoi (Tcl_GetVar (interp, "::viewoptions.drawidentified", TCL_GLOBAL_ONLY)); + vispar.drawpointnumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawpointnumbers", TCL_GLOBAL_ONLY)); + vispar.drawedgenumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedgenumbers", TCL_GLOBAL_ONLY)); + vispar.drawfacenumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawfacenumbers", TCL_GLOBAL_ONLY)); + vispar.drawelementnumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawelementnumbers", TCL_GLOBAL_ONLY)); + vispar.drawdomainsurf = + atoi (Tcl_GetVar (interp, "::viewoptions.drawdomainsurf", TCL_GLOBAL_ONLY)); + + vispar.drawededges = + atoi (Tcl_GetVar (interp, "::viewoptions.drawededges", TCL_GLOBAL_ONLY)); + vispar.drawedpoints = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedpoints", TCL_GLOBAL_ONLY)); + vispar.drawedpointnrs = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedpointnrs", TCL_GLOBAL_ONLY)); + vispar.drawedtangents = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedtangents", TCL_GLOBAL_ONLY)); + vispar.drawededgenrs = + atoi (Tcl_GetVar (interp, "::viewoptions.drawededgenrs", TCL_GLOBAL_ONLY)); + + vispar.drawcurveproj = + atoi (Tcl_GetVar (interp, "::viewoptions.drawcurveproj", TCL_GLOBAL_ONLY)); + vispar.drawcurveprojedge = + atoi (Tcl_GetVar (interp, "::viewoptions.drawcurveprojedge", TCL_GLOBAL_ONLY)); + + vispar.centerpoint = + atoi (Tcl_GetVar (interp, "::viewoptions.centerpoint", TCL_GLOBAL_ONLY)); + vispar.use_center_coords = + atoi (Tcl_GetVar (interp, "::viewoptions.usecentercoords", TCL_GLOBAL_ONLY)) > 0; + vispar.centerx = + atof (Tcl_GetVar (interp, "::viewoptions.centerx", TCL_GLOBAL_ONLY)); + vispar.centery = + atof (Tcl_GetVar (interp, "::viewoptions.centery", TCL_GLOBAL_ONLY)); + vispar.centerz = + atof (Tcl_GetVar (interp, "::viewoptions.centerz", TCL_GLOBAL_ONLY)); + vispar.drawelement = + atoi (Tcl_GetVar (interp, "::viewoptions.drawelement", TCL_GLOBAL_ONLY)); + vispar.drawmetispartition = + atoi (Tcl_GetVar (interp, "::viewoptions.drawmetispartition", TCL_GLOBAL_ONLY)); + + vispar.drawspecpoint = + atoi (Tcl_GetVar (interp, "::viewoptions.drawspecpoint", TCL_GLOBAL_ONLY)); + vispar.specpointx = + atof (Tcl_GetVar (interp, "::viewoptions.specpointx", TCL_GLOBAL_ONLY)); + vispar.specpointy = + atof (Tcl_GetVar (interp, "::viewoptions.specpointy", TCL_GLOBAL_ONLY)); + vispar.specpointz = + atof (Tcl_GetVar (interp, "::viewoptions.specpointz", TCL_GLOBAL_ONLY)); + + + vsspecpoints.len = + atof (Tcl_GetVar (interp, "::viewoptions.specpointvlen", TCL_GLOBAL_ONLY)); + + + + +#ifdef OCCGEOMETRY + vispar.occdeflection = pow(10.0,-1-atof (Tcl_GetVar (interp, "::occoptions.deflection", TCL_GLOBAL_ONLY))); +#endif + +#ifdef PARALLELGL + vsmesh.Broadcast (); +#endif + + return TCL_OK; + } + + + + int Ng_SelectSurface (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int surfnr = atoi (argv[1]); + vsgeom.SelectSurface (surfnr); + return TCL_OK; + } + + + int Ng_BuildFieldLines (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + vssolution.BuildFieldLinesPlot(); + return TCL_OK; + } + +#ifdef PARALLEL + int Ng_VisualizeAll (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + + string visualizationmode = Tcl_GetVar (interp, "::selectvisual", 0); + string scalfun = Tcl_GetVar (interp, "::visoptions.scalfunction", 0); + for ( int dest = 1; dest < ntasks; dest++) + { + MyMPI_Send ( "visualize", dest ); + MyMPI_Send ( visualizationmode, dest); + if ( visualizationmode == "solution" ) + MyMPI_Send ( scalfun, dest); + } + return TCL_OK; + } + + int Ng_VisualizeOne (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + + string visualizationmode = Tcl_GetVar (interp, "::selectvisual", 0); + string scalfun = Tcl_GetVar (interp, "::visoptions.scalfunction", 0); + + MyMPI_Send ( "visualize", 1 ); + MyMPI_Send ( visualizationmode, 1); + + if ( visualizationmode == "solution" ) + MyMPI_Send ( scalfun, 1); + return TCL_OK; + } + + int Ng_IncrOverlap ( ClientData clientDate, + Tcl_Interp * interp, + int argc, tcl_const char * argv[] ) + { + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + + for ( int dest = 1; dest < ntasks; dest++) + { + MyMPI_Send ( "overlap++", dest ); + } + mesh->UpdateOverlap(); + return TCL_OK; + + } + + int Ng_SetSelectVisual ( ClientData clientDate, + Tcl_Interp * interp, + int argc, tcl_const char * argv[] ) + { + string visualizationmode; + MyMPI_Recv ( visualizationmode, 0); + Tcl_SetVar (interp, "::selectvisual", visualizationmode.c_str(), 0); + return TCL_OK; + } + + int Ng_SetScalarFunction ( ClientData clientDate, + Tcl_Interp * interp, + int argc, tcl_const char * argv[] ) + { + string visualizationmode; + string scalarfun; + visualizationmode = Tcl_GetVar (interp, "::selectvisual", 0); + + if ( visualizationmode == "solution" ) + { + MyMPI_Recv ( scalarfun, 0); + Tcl_SetVar (interp, "::visoptions.scalfunction", scalarfun.c_str(), 0); + } + return TCL_OK; + } + + +#endif + + int Ng_IsParallel (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef PARALLEL + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + if ( ntasks > 1 ) + Tcl_SetVar (interp, "::parallel_netgen", "1", 0); + else + Tcl_SetVar (interp, "::parallel_netgen", "0", 0); +#else + Tcl_SetVar (interp, "::parallel_netgen", "0", 0); +#endif + return TCL_OK; + } + + int Ng_Exit (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef PARALLEL + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + if ( id != 0 ) + return TCL_OK; +#endif + + + /* + if (ngsolve_handle) + { + void (*ngs_exit)(); + ngs_exit = ( void (*)() ) dlsym (ngsolve_handle, "NGSolve_Exit"); + if (ngs_exit) (*ngs_exit)(); + } + */ + +#ifdef NGSOLVE + NGSolve_Exit (); +#endif + + + + + delete stlgeometry; + stlgeometry = NULL; + + geometry.Reset (0); + geometry2d.Reset (0); + + +#ifdef ACIS + outcome res; + res = api_terminate_faceter(); + if(!res.ok()) + cerr << "problem with terminating acis faceter" << endl; + res = api_terminate_constructors(); + if(!res.ok()) + cerr << "problem with terminating acis constructors" << endl; + res = api_terminate_kernel(); + if(!res.ok()) + cerr << "problem with terminating acis kernel" << endl; + res = api_stop_modeller(); + if(!res.ok()) + cerr << "problem with terminating acis modeller" << endl; + + //cout << "stopped acis, outcome = " << res.ok() << endl; +#endif + +#ifdef PARALLEL + + for ( int dest = 1; dest < ntasks; dest++) + MyMPI_Send ( "end", dest ); +#endif + delete testout; + + return TCL_OK; + } + + +#ifdef SOCKETS + void * ServerSocketManagerRunDummy ( void * nix ) + { + serversocketmanager.Run(); + return NULL; + } + + extern "C" int Ng_ServerSocketManagerRun( void ); + int Ng_ServerSocketManagerRun( void ) + { + if(mparam.parthread) + RunParallel(ServerSocketManagerRunDummy,NULL); + else + serversocketmanager.Run(); + + return TCL_OK; + } + + extern "C" int Ng_ServerSocketManagerInit(int port); + int Ng_ServerSocketManagerInit(int port) + { + serversocketmanager.Init(port); + return TCL_OK; + } +#endif //SOCKETS + + + extern "C" int Ng_Init (Tcl_Interp * interp); + + // int main_Eero (ClientData clientData, + // Tcl_Interp * interp, + // int argc, tcl_const char *argv[]); + + + int Ng_Init (Tcl_Interp * interp) + { +#ifdef SOCKETS + if(serversocketmanager.Good()) + serversocketusernetgen.Reset(new ServerSocketUserNetgen (serversocketmanager, mesh, geometry)); +#endif + + tcl_interp = interp; + + // Tcl_CreateCommand (interp, "Ng_Eero", main_Eero, + // (ClientData)NULL, + // (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_New", Ng_New, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + // Tcl_CreateCommand (interp, "Ng_Lock", Ng_Lock, + // (ClientData)NULL, + // (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_LoadGeometry", Ng_LoadGeometry, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SaveGeometry", Ng_SaveGeometry, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ParseGeometry", Ng_ParseGeometry, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_LoadMesh", Ng_LoadMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SaveMesh", Ng_SaveMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MergeMesh", Ng_MergeMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ExportMesh", Ng_ExportMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ImportMesh", Ng_ImportMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ImportSolution", Ng_ImportSolution, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ShowDemo", Ng_ShowDemo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_DemoSetTime", Ng_DemoSetTime, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SaveSolution", Ng_SaveSolution, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GeometryOptions", Ng_GeometryOptions, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + // geometry + Tcl_CreateCommand (interp, "Ng_CreatePrimitive", Ng_CreatePrimitive, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetPrimitiveData", Ng_SetPrimitiveData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetPrimitiveData", Ng_GetPrimitiveData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetPrimitiveList", Ng_GetPrimitiveList, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_GetSurfaceList", Ng_GetSurfaceList, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + Tcl_CreateCommand (interp, "Ng_SetSolidData", Ng_SetSolidData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetSolidData", Ng_GetSolidData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetSolidList", Ng_GetSolidList, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_TopLevel", Ng_TopLevel, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + + // meshing + Tcl_CreateCommand (interp, "Ng_GenerateMesh", Ng_GenerateMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_StopMeshing", Ng_StopMeshing, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshInfo", Ng_MeshInfo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshQuality", Ng_MeshQuality, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_CheckSurfaceMesh", Ng_CheckSurfaceMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_CheckVolumeMesh", Ng_CheckVolumeMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_DeleteVolMesh", Ng_DeleteVolMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SplitSeparatedFaces", Ng_SplitSeparatedFaces, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetNextTimeStamp", Ng_SetNextTimeStamp, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Refine", Ng_Refine, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SecondOrder", Ng_SecondOrder, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_HighOrder", Ng_HighOrder, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ValidateSecondOrder", Ng_ValidateSecondOrder, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_RestrictH", Ng_RestrictH, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Anisotropy", Ng_Anisotropy, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Bisect", Ng_Bisect, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + // Tcl_CreateCommand (interp, "Ng_BisectCopyMesh", Ng_BisectCopyMesh, + // (ClientData)NULL, + // (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Split2Tets", Ng_Split2Tets, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ZRefinement", Ng_ZRefinement, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_HPRefinement", Ng_HPRefinement, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_LoadMeshSize", Ng_LoadMeshSize, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshSizeFromSurfaceMesh", Ng_MeshSizeFromSurfaceMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SingularEdgeMS", Ng_SingularEdgeMS, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SingularPointMS", Ng_SingularPointMS, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_InsertVirtualBL", Ng_InsertVirtualBL, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_CutOffAndCombine", Ng_CutOffAndCombine, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_HelmholtzMesh", Ng_HelmholtzMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ReadStatus", Ng_ReadStatus, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MemInfo", Ng_MemInfo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_STLDoctor", Ng_STLDoctor, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshDoctor", Ng_MeshDoctor, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_BCProp", Ng_BCProp, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_STLInfo", Ng_STLInfo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_STLCalcLocalH", + Ng_STLCalcLocalH, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetOCCVisParameters", + Ng_SetOCCVisParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetOCCData", + Ng_GetOCCData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + +#ifdef OCCGEOMETRY + Tcl_CreateCommand (interp, "Ng_OCCConstruction", + Ng_OCCConstruction, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); +#endif + + Tcl_CreateCommand (interp, "Ng_OCCCommand", + Ng_OCCCommand, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ACISCommand", + Ng_ACISCommand, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_MouseMove", Ng_MouseMove, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MouseDblClick", Ng_MouseDblClick, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_ZoomAll", Ng_ZoomAll, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Center", Ng_Center, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_StandardRotation", Ng_StandardRotation, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ArbitraryRotation", Ng_ArbitraryRotation, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_SetVisParameters", Ng_SetVisParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetMeshingParameters", Ng_SetMeshingParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetDebugParameters", Ng_SetDebugParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetSTLParameters", Ng_SetSTLParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + Tcl_CreateCommand (interp, "Ng_SelectSurface", Ng_SelectSurface, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetCommandLineParameter", + Ng_GetCommandLineParameter, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Exit", + Ng_Exit, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Metis", + Ng_Metis, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_BuildFieldLines", + Ng_BuildFieldLines, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + +#ifdef PARALLEL + Tcl_CreateCommand (interp, "Ng_VisualizeAll", Ng_VisualizeAll, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_VisualizeOne", Ng_VisualizeOne, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_IncrOverlap", Ng_IncrOverlap, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetSelectVisual", Ng_SetSelectVisual, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetScalarFunction", Ng_SetScalarFunction, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + +#endif + Tcl_CreateCommand (interp, "Ng_IsParallel", Ng_IsParallel, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + if (!nodisplay && Togl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + + /* + * Specify the C callback functions for widget creation, display, + * and reshape. + */ + if(!nodisplay) + { + Togl_CreateFunc( init ); + Togl_DestroyFunc( zap ); + Togl_DisplayFunc( draw ); + Togl_ReshapeFunc( reshape ); + // Togl_TimerFunc( idle ); + Togl_CreateCommand( (char*)"Ng_SnapShot", Ng_SnapShot); + Togl_CreateCommand( (char*)"Ng_VideoClip", Ng_VideoClip); + // Togl_CreateCommand("position",position); + } + + multithread.pause = 0; + multithread.testmode = 0; + multithread.redraw = 0; + multithread.drawing = 1; + multithread.terminate = 0; + multithread.running = 0; + + multithread.task = ""; + multithread.percent = 20; + + + Tcl_LinkVar (interp, "multithread_pause", + (char*)&multithread.pause, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_testmode", + (char*)&multithread.testmode, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_redraw", + (char*)&multithread.redraw, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_drawing", + (char*)&multithread.drawing, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_terminate", + (char*)&multithread.terminate, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_running", + (char*)&multithread.running, TCL_LINK_INT); + + + //testout->setstate(ios_base::badbit); + + myerr = &cerr; + extern ostream * mycout; + mycout = &cout; + + testmode = 0; + +#ifdef ACIS + outcome res; + res = api_start_modeller (0); + if(!res.ok()) + cerr << "problem with starting acis modeller" << endl; + +#ifdef ACIS_R17 + unlock_spatial_products_661(); +#endif + res = api_initialize_kernel(); + if(!res.ok()) + cerr << "problem with starting acis kernel" << endl; + res = api_initialize_constructors(); + if(!res.ok()) + cerr << "problem with starting acis constructors" << endl; + res = api_initialize_faceter(); + if(!res.ok()) + cerr << "problem with starting acis faceter" << endl; +#endif + + + return TCL_OK; + } + + +} + + + +namespace netgen { + extern CSGeometry * ParseCSG (istream & istr); +} + +void Netgen_Test () +{ + ifstream infile ("examples/cube.geo"); + netgen::geometry.Reset (netgen::ParseCSG (infile) ); + netgen:: geometry -> FindIdenticSurfaces(1e-10); + netgen::GenerateMesh (*netgen::geometry.Ptr(), netgen::mesh.Ptr(), 1, 6, ""); +} diff --git a/ng/onetcl.cpp b/ng/onetcl.cpp new file mode 100644 index 00000000..149f9657 --- /dev/null +++ b/ng/onetcl.cpp @@ -0,0 +1,8276 @@ +const char * ngscript[] = { +"\n",\ +"\n",\ +"set userlevel 3\n",\ +"if { [Ng_GetCommandLineParameter expert]==\"defined\" } {\n",\ +" set userlevel 3\n",\ +"}\n",\ +"\n",\ +"set progname \"NETGEN\"\n",\ +"\n",\ +"set ngdir \"\"\n",\ +"if { [lsearch [array names env] NETGENDIR] != -1 } {\n",\ +" set ngdir $env(NETGENDIR) \n",\ +"}\n",\ +"if { [string length $ngdir] == 0 } {\n",\ +" set ngdir \".\" \n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"set batchmode [Ng_GetCommandLineParameter batchmode]\n",\ +"\n",\ +"set solvemode 0\n",\ +"if { [Ng_GetCommandLineParameter solve] != \"undefined\" || [Ng_GetCommandLineParameter recent] == \"defined\" } {\n",\ +" set solvemode defined\n",\ +"}\n",\ +"\n",\ +"set shellmode [Ng_GetCommandLineParameter shellmode]\n",\ +"\n",\ +"if { $shellmode == \"defined\" } {\n",\ +" set batchmode \"defined\"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"if { $batchmode != \"defined\" } {\n",\ +" catch {\n",\ +" wm withdraw .\n",\ +" \n",\ +" wm title . $progname\n",\ +" wm geometry . =800x600\n",\ +" wm minsize . 400 300\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set drawmode rotate\n",\ +"set selectvisual geometry\n",\ +"\n",\ +"set dirname .\n",\ +"set basefilename filename\n",\ +"\n",\ +"set meshoptions.fineness 3\n",\ +"set meshoptions.firststep ag\n",\ +"set meshoptions.laststep ov\n",\ +"set options.memory 0\n",\ +"\n",\ +"set options.localh 1\n",\ +"set options.delaunay 1\n",\ +"set options.checkoverlap 1\n",\ +"set options.checkoverlappingboundary 0\n",\ +"set options.checkchartboundary 1\n",\ +"set options.startinsurface 0\n",\ +"set options.blockfill 1\n",\ +"set options.debugmode 0\n",\ +"set options.dooptimize 1\n",\ +"set options.parthread 1\n",\ +"set options.elsizeweight 0.2\n",\ +"set options.secondorder 0\n",\ +"set options.elementorder 1\n",\ +"set options.quad 0\n",\ +"set options.inverttets 0\n",\ +"set options.inverttrigs 0\n",\ +"set options.autozrefine 0\n",\ +"\n",\ +"\n",\ +"set options.meshsize 1000\n",\ +"set options.minmeshsize 0\n",\ +"\n",\ +"set options.curvaturesafety 2\n",\ +"set options.segmentsperedge 2\n",\ +"set options.meshsizefilename \"\"\n",\ +"set options.badellimit 175\n",\ +"set options.optsteps2d 3\n",\ +"set options.optsteps3d 5\n",\ +"set options.opterrpow 2\n",\ +"\n",\ +"set options.grading 0.5\n",\ +"set options.printmsg 2\n",\ +"\n",\ +"set debug.slowchecks 0\n",\ +"set debug.debugoutput 0\n",\ +"set debug.haltexistingline 0\n",\ +"set debug.haltoverlap 0\n",\ +"set debug.haltsuccess 0\n",\ +"set debug.haltnosuccess 0\n",\ +"set debug.haltlargequalclass 0\n",\ +"set debug.haltsegment 0\n",\ +"set debug.haltnode 0\n",\ +"set debug.haltface 0\n",\ +"set debug.haltfacenr 0\n",\ +"set debug.haltsegmentp1 0\n",\ +"set debug.haltsegmentp2 0\n",\ +"\n",\ +"set geooptions.drawcsg 1\n",\ +"set geooptions.detail 0.001\n",\ +"set geooptions.accuracy 1e-6\n",\ +"set geooptions.facets 20\n",\ +"set geooptions.minx -1000\n",\ +"set geooptions.miny -1000\n",\ +"set geooptions.minz -1000\n",\ +"set geooptions.maxx 1000\n",\ +"set geooptions.maxy 1000\n",\ +"set geooptions.maxz 1000\n",\ +"\n",\ +"set viewqualityplot 0\n",\ +"set memuseplot 0\n",\ +"set viewrotatebutton 0\n",\ +"set showsensitivehelp 0\n",\ +"set showhelpline 0\n",\ +"\n",\ +"set viewoptions.specpointvlen 0.3\n",\ +"set viewoptions.light.amb 0.3\n",\ +"set viewoptions.light.diff 0.7\n",\ +"set viewoptions.light.spec 1\n",\ +"set viewoptions.light.locviewer 0\n",\ +"set viewoptions.mat.shininess 50\n",\ +"set viewoptions.mat.transp 0.3\n",\ +"set viewoptions.colormeshsize 0\n",\ +"set viewoptions.whitebackground 1\n",\ +"set viewoptions.drawcoordinatecross 1\n",\ +"set viewoptions.drawcolorbar 1\n",\ +"set viewoptions.drawnetgenlogo 1\n",\ +"set viewoptions.stereo 0\n",\ +"set viewoptions.shrink 1\n",\ +"\n",\ +"set viewoptions.drawfilledtrigs 1\n",\ +"set viewoptions.drawedges 0\n",\ +"set viewoptions.drawbadels 0\n",\ +"set viewoptions.centerpoint 0\n",\ +"set viewoptions.drawelement 0\n",\ +"set viewoptions.drawoutline 1\n",\ +"set viewoptions.drawtets 0\n",\ +"set viewoptions.drawtetsdomain 0\n",\ +"set viewoptions.drawprisms 0\n",\ +"set viewoptions.drawpyramids 0\n",\ +"set viewoptions.drawhexes 0\n",\ +"set viewoptions.drawidentified 0\n",\ +"set viewoptions.drawpointnumbers 0\n",\ +"set viewoptions.drawedgenumbers 0\n",\ +"set viewoptions.drawfacenumbers 0\n",\ +"set viewoptions.drawelementnumbers 0\n",\ +"set viewoptions.drawdomainsurf 0\n",\ +"\n",\ +"set viewoptions.drawededges 1\n",\ +"set viewoptions.drawedpoints 1\n",\ +"set viewoptions.drawedpointnrs 0\n",\ +"set viewoptions.drawedtangents 0\n",\ +"set viewoptions.drawededgenrs 0\n",\ +"set viewoptions.drawmetispartition 0\n",\ +"\n",\ +"set viewoptions.drawcurveproj 0\n",\ +"set viewoptions.drawcurveprojedge 1\n",\ +"\n",\ +"set viewoptions.clipping.nx 0\n",\ +"set viewoptions.clipping.ny 1\n",\ +"set viewoptions.clipping.nz 0\n",\ +"set viewoptions.clipping.dist 0\n",\ +"set viewoptions.clipping.enable 0\n",\ +"set viewoptions.clipping.onlydomain 0\n",\ +"set viewoptions.clipping.notdomain 0\n",\ +"\n",\ +"set viewoptions.usecentercoords 0\n",\ +"set viewoptions.centerx 0\n",\ +"set viewoptions.centery 0\n",\ +"set viewoptions.centerz 0\n",\ +"\n",\ +"set viewoptions.drawspecpoint 0\n",\ +"set viewoptions.specpointx 0\n",\ +"set viewoptions.specpointy 0\n",\ +"set viewoptions.specpointz 0\n",\ +"\n",\ +"\n",\ +"set stloptions.showtrias 0\n",\ +"set stloptions.showfilledtrias 1\n",\ +"set stloptions.showedges 1\n",\ +"set stloptions.showmarktrias 0\n",\ +"set stloptions.showactivechart 0\n",\ +"set stloptions.yangle 30\n",\ +"set stloptions.contyangle 20\n",\ +"set stloptions.edgecornerangle 60\n",\ +"set stloptions.chartangle 15\n",\ +"set stloptions.outerchartangle 70\n",\ +"set stloptions.usesearchtree 0\n",\ +"set stloptions.chartnumber 1\n",\ +"set stloptions.charttrignumber 1\n",\ +"set stloptions.chartnumberoffset 0\n",\ +"\n",\ +"set stloptions.atlasminh 0.1\n",\ +"set stloptions.resthsurfcurvfac 2\n",\ +"set stloptions.resthsurfcurvenable 0\n",\ +"set stloptions.resthatlasfac 2\n",\ +"set stloptions.resthatlasenable 1\n",\ +"set stloptions.resthchartdistfac 1.2\n",\ +"set stloptions.resthchartdistenable 1\n",\ +"set stloptions.resthlinelengthfac 0.5\n",\ +"set stloptions.resthlinelengthenable 1\n",\ +"set stloptions.resthcloseedgefac 1\n",\ +"set stloptions.resthcloseedgeenable 1\n",\ +"set stloptions.resthedgeanglefac 1\n",\ +"set stloptions.resthedgeangleenable 0\n",\ +"set stloptions.resthsurfmeshcurvfac 1\n",\ +"set stloptions.resthsurfmeshcurvenable 0\n",\ +"set stloptions.recalchopt 1\n",\ +"\n",\ +"set stldoctor.drawmeshededges 1\n",\ +"set stldoctor.geom_tol_fact 0.000001\n",\ +"set stldoctor.useexternaledges 0\n",\ +"set stldoctor.showfaces 0\n",\ +"set stldoctor.conecheck 1\n",\ +"set stldoctor.spiralcheck 1\n",\ +"set stldoctor.selecttrig 0\n",\ +"set stldoctor.selectmode 1\n",\ +"set stldoctor.longlinefact 0\n",\ +"set stldoctor.showexcluded 1\n",\ +"set stldoctor.edgeselectmode 0\n",\ +"set stldoctor.nodeofseltrig 1\n",\ +"set stldoctor.showtouchedtrigchart 0\n",\ +"set stldoctor.showedgecornerpoints 0\n",\ +"set stldoctor.showmarkedtrigs 1\n",\ +"set stldoctor.dirtytrigfact 0.01\n",\ +"set stldoctor.smoothangle 90\n",\ +"set stldoctor.selectwithmouse 1\n",\ +"set stldoctor.showvicinity 0\n",\ +"set stldoctor.vicinity 50\n",\ +"set stldoctor.smoothnormalsweight 0.2\n",\ +"\n",\ +"set occoptions.showvolumenr 0\n",\ +"set occoptions.showsurfaces 1\n",\ +"set occoptions.showedges 1\n",\ +"set occoptions.showsolidnr 0\n",\ +"set occoptions.showsolidnr2 0\n",\ +"set occoptions.visproblemfaces 0\n",\ +"set occoptions.zoomtohighlightedentity 0\n",\ +"set occoptions.deflection 1\n",\ +"set occoptions.tolerance 1e-3\n",\ +"set occoptions.fixsmalledges 1\n",\ +"set occoptions.fixspotstripfaces 1\n",\ +"set occoptions.sewfaces 1\n",\ +"set occoptions.makesolids 1\n",\ +"set occoptions.splitpartitions 0\n",\ +"\n",\ +"set meshdoctor.active 0\n",\ +"set meshdoctor.markedgedist 1\n",\ +"\n",\ +"\n",\ +"set status_np 0\n",\ +"set status_ne 0\n",\ +"set status_nse 0\n",\ +"set status_working \" \"\n",\ +"set status_task \" \"\n",\ +"set status_percent 0\n",\ +"set status_filename 0\n",\ +"set status_tetqualclasses \"10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40\"\n",\ +"\n",\ +"set exportfiletype PERMAS\n",\ +"\n",\ +"set preproc.facenr 0\n",\ +"set preproc.selectmode query\n",\ +"set preproc.numtrig 0\n",\ +"\n",\ +"set mem_moveable 0\n",\ +"\n",\ +"\n",\ +"set multithread_pause 0\n",\ +"set multithread_testmode 0\n",\ +"set multithread_redraw 0\n",\ +"set multithread_drawing 0\n",\ +"set multithread_terminate 0\n",\ +"set multithread_running 0\n",\ +"\n",\ +"set level 0\n",\ +"\n",\ +"\n",\ +"set tablesforoutput {}\n",\ +"\n",\ +"\n",\ +"\n",\ +"set optlist {\n",\ +" options.localh \n",\ +" options.delaunay \n",\ +" options.checkoverlap \n",\ +" options.startinsurface \n",\ +" options.blockfill \n",\ +" options.dooptimize \n",\ +" options.elsizeweight \n",\ +" options.meshsize \n",\ +" options.minmeshsize \n",\ +" options.curvaturesafety \n",\ +" options.optsteps2d \n",\ +" options.optsteps3d \n",\ +" options.secondorder\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set visoptions.usetexture 0\n",\ +"set visoptions.invcolor 0\n",\ +"set visoptions.imaginary 0\n",\ +"set visoptions.lineartexture 1\n",\ +"set visoptions.numtexturecols 16\n",\ +"set visoptions.showclipsolution 1\n",\ +"set visoptions.showsurfacesolution 0\n",\ +"set visoptions.drawfieldlines 0\n",\ +"set visoptions.drawpointcurves 1\n",\ +"set visoptions.numfieldlines 100\n",\ +"set visoptions.fieldlinesrandomstart 0\n",\ +"set visoptions.fieldlinesstartarea box\n",\ +"set visoptions.fieldlinesstartareap1x 1\n",\ +"set visoptions.fieldlinesstartareap1y 1\n",\ +"set visoptions.fieldlinesstartareap1z 1\n",\ +"set visoptions.fieldlinesstartareap2x 0\n",\ +"set visoptions.fieldlinesstartareap2y 0\n",\ +"set visoptions.fieldlinesstartareap2z 0\n",\ +"set visoptions.fieldlinesstartface -1\n",\ +"set visoptions.fieldlinesfilename none\n",\ +"set visoptions.fieldlinestolerance 0.0005\n",\ +"set visoptions.fieldlinesrktype crungekutta\n",\ +"set visoptions.fieldlineslength 0.5\n",\ +"set visoptions.fieldlinesmaxpoints 500\n",\ +"set visoptions.fieldlinesthickness 0.0015\n",\ +"set visoptions.fieldlinesvecfunction none\n",\ +"set visoptions.fieldlinesphase 0\n",\ +"set visoptions.fieldlinesonlyonephase 1\n",\ +"\n",\ +"\n",\ +"set visoptions.lineplotfile empty\n",\ +"set visoptions.lineplotsource file\n",\ +"set visoptions.lineplotusingx 0\n",\ +"set visoptions.lineplotusingy 1\n",\ +"set visoptions.lineplotautoscale 1\n",\ +"set visoptions.lineplotxmin 0\n",\ +"set visoptions.lineplotxmax 1\n",\ +"set visoptions.lineplotymin 0\n",\ +"set visoptions.lineplotymax 1\n",\ +"set visoptions.lineplotcurrentnum -1\n",\ +"set visoptions.lineplotinfos \"\"\n",\ +"set visoptions.lineplotselected none\n",\ +"set visoptions.lineplotselector \"\"\n",\ +"set visoptions.lineplotcolor red\n",\ +"set visoptions.lineplotsizex 500\n",\ +"set visoptions.lineplotsizey 400\n",\ +"set visoptions.lineplotselectedeval 0\n",\ +"set visoptions.lineplotdatadescr \"column1 column2 column3\"\n",\ +"set visoptions.lineplotxcoordselector \"\"\n",\ +"set visoptions.lineplotycoordselector \"\"\n",\ +"set visoptions.evaluatefilenames none\n",\ +"set visoptions.evaluatefiledescriptions none\n",\ +"\n",\ +"\n",\ +"set visoptions.clipsolution none\n",\ +"set visoptions.scalfunction none\n",\ +"set visoptions.vecfunction none\n",\ +"set visoptions.evaluate abs\n",\ +"set visoptions.gridsize 20\n",\ +"set visoptions.xoffset 0\n",\ +"set visoptions.yoffset 0\n",\ +"set visoptions.autoscale 1\n",\ +"set visoptions.lineartexture 1\n",\ +"set visoptions.redrawperiodic 0\n",\ +"set visoptions.logscale 0\n",\ +"set visoptions.mminval 0\n",\ +"set visoptions.mmaxval 1\n",\ +"set visoptions.isolines 0\n",\ +"set visoptions.isosurf 0\n",\ +"set visoptions.subdivisions 1\n",\ +"set visoptions.numiso 10\n",\ +"set visoptions.autoredraw 0\n",\ +"set visoptions.autoredrawtime 2\n",\ +"set visoptions.simulationtime 0\n",\ +"set visoptions.multidimcomponent 0\n",\ +"\n",\ +"set visoptions.deformation 0\n",\ +"set visoptions.scaledeform1 1\n",\ +"set visoptions.scaledeform2 1\n",\ +"\n",\ +"set parallel_netgen 0\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set optfilename ng.opt\n",\ +"global env\n",\ +"if { [llength [array names env NG_OPT]] == 1 } {\n",\ +" if { [string length $env(NG_OPT)] > 0 } {\n",\ +" set optfilename $env(NG_OPT) \n",\ +" }\n",\ +"}\n",\ +"\n",\ +"if { [file exists $optfilename] == 1 } {\n",\ +" set datei [open $optfilename r]\n",\ +" while { [gets $datei line] >= 0 } {\n",\ +" set [lindex $line 0] [lindex $line 1]\n",\ +" }\n",\ +" close $datei\n",\ +"} {\n",\ +" puts \"optfile $optfilename does not exist - using default values\"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc saveoptions { } {\n",\ +" uplevel 1 {\n",\ +" set file ng.opt \n",\ +" \n",\ +" if {$file != \"\"} {\n",\ +" set datei [open $file w]\n",\ +" \n",\ +" puts $datei \"meshoptions.fineness ${meshoptions.fineness}\"\n",\ +" puts $datei \"meshoptions.firststep ${meshoptions.firststep}\"\n",\ +" puts $datei \"meshoptions.laststep ${meshoptions.laststep}\" \n",\ +" puts $datei \"options.localh ${options.localh}\"\n",\ +" puts $datei \"options.delaunay ${options.delaunay}\"\n",\ +" puts $datei \"options.checkoverlap ${options.checkoverlap}\"\n",\ +" puts $datei \"options.checkchartboundary ${options.checkchartboundary}\"\n",\ +" puts $datei \"options.startinsurface ${options.startinsurface}\" \n",\ +" puts $datei \"options.blockfill ${options.blockfill}\" \n",\ +" puts $datei \"options.debugmode ${options.debugmode}\" \n",\ +" puts $datei \"options.dooptimize ${options.dooptimize}\" \n",\ +" puts $datei \"options.parthread ${options.parthread}\" \n",\ +" puts $datei \"options.elsizeweight ${options.elsizeweight}\" \n",\ +" puts $datei \"options.secondorder ${options.secondorder}\" \n",\ +" puts $datei \"options.elementorder ${options.elementorder}\" \n",\ +" puts $datei \"options.memory ${options.memory}\" \n",\ +" puts $datei \"options.quad ${options.quad}\" \n",\ +" puts $datei \"options.inverttets ${options.inverttets}\" \n",\ +" puts $datei \"options.inverttrigs ${options.inverttrigs}\" \n",\ +" puts $datei \"options.autozrefine ${options.autozrefine}\" \n",\ +" puts $datei \"options.meshsize ${options.meshsize}\" \n",\ +" puts $datei \"options.minmeshsize ${options.minmeshsize}\" \n",\ +" puts $datei \"options.curvaturesafety ${options.curvaturesafety}\" \n",\ +" puts $datei \"options.segmentsperedge ${options.segmentsperedge}\" \n",\ +" puts $datei \"options.meshsizefilename ${options.meshsizefilename}\" \n",\ +" puts $datei \"options.badellimit ${options.badellimit}\" \n",\ +" puts $datei \"options.optsteps2d ${options.optsteps2d}\" \n",\ +" puts $datei \"options.optsteps3d ${options.optsteps3d}\" \n",\ +" puts $datei \"options.opterrpow ${options.opterrpow}\" \n",\ +" puts $datei \"options.grading ${options.grading}\" \n",\ +" puts $datei \"options.printmsg ${options.printmsg}\" \n",\ +" puts $datei \"geooptions.drawcsg ${geooptions.drawcsg}\" \n",\ +" puts $datei \"geooptions.detail ${geooptions.detail}\" \n",\ +" puts $datei \"geooptions.accuracy ${geooptions.accuracy}\" \n",\ +" puts $datei \"geooptions.facets ${geooptions.facets}\" \n",\ +" puts $datei \"geooptions.minx ${geooptions.minx}\" \n",\ +" puts $datei \"geooptions.miny ${geooptions.miny}\" \n",\ +" puts $datei \"geooptions.minz ${geooptions.minz}\" \n",\ +" puts $datei \"geooptions.maxx ${geooptions.maxx}\" \n",\ +" puts $datei \"geooptions.maxy ${geooptions.maxy}\" \n",\ +" puts $datei \"geooptions.maxz ${geooptions.maxz}\" \n",\ +" puts $datei \"viewoptions.specpointvlen ${viewoptions.specpointvlen}\" \n",\ +" puts $datei \"viewoptions.light.amb ${viewoptions.light.amb}\" \n",\ +" puts $datei \"viewoptions.light.diff ${viewoptions.light.diff}\"\n",\ +" puts $datei \"viewoptions.light.spec ${viewoptions.light.spec}\"\n",\ +" puts $datei \"viewoptions.light.locviewer ${viewoptions.light.locviewer}\"\n",\ +" puts $datei \"viewoptions.mat.shininess ${viewoptions.mat.shininess}\" \n",\ +" puts $datei \"viewoptions.mat.transp ${viewoptions.mat.transp}\" \n",\ +" puts $datei \"viewoptions.colormeshsize ${viewoptions.colormeshsize}\"\n",\ +" puts $datei \"viewoptions.whitebackground ${viewoptions.whitebackground}\" \n",\ +" puts $datei \"viewoptions.drawcolorbar ${viewoptions.drawcolorbar}\" \n",\ +" puts $datei \"viewoptions.drawcoordinatecross ${viewoptions.drawcoordinatecross}\" \n",\ +" puts $datei \"viewoptions.drawnetgenlogo ${viewoptions.drawnetgenlogo}\" \n",\ +" puts $datei \"viewoptions.stereo ${viewoptions.stereo}\" \n",\ +" puts $datei \"viewoptions.drawfilledtrigs ${viewoptions.drawfilledtrigs}\" \n",\ +" puts $datei \"viewoptions.drawedges ${viewoptions.drawedges}\" \n",\ +" puts $datei \"viewoptions.drawbadels ${viewoptions.drawbadels}\" \n",\ +" puts $datei \"viewoptions.centerpoint ${viewoptions.centerpoint}\" \n",\ +" puts $datei \"viewoptions.drawelement ${viewoptions.drawelement}\" \n",\ +" puts $datei \"viewoptions.drawoutline ${viewoptions.drawoutline}\" \n",\ +" puts $datei \"viewoptions.drawtets ${viewoptions.drawtets}\"\n",\ +" puts $datei \"viewoptions.drawprisms ${viewoptions.drawprisms}\"\n",\ +" puts $datei \"viewoptions.drawpyramids ${viewoptions.drawpyramids}\" \n",\ +" puts $datei \"viewoptions.drawhexes ${viewoptions.drawhexes}\" \n",\ +" puts $datei \"viewoptions.drawidentified ${viewoptions.drawidentified}\" \n",\ +" puts $datei \"viewoptions.drawpointnumbers ${viewoptions.drawpointnumbers}\" \n",\ +" \n",\ +" puts $datei \"viewoptions.drawededges ${viewoptions.drawededges}\" \n",\ +" puts $datei \"viewoptions.drawedpoints ${viewoptions.drawedpoints}\" \n",\ +" puts $datei \"viewoptions.drawedpointnrs ${viewoptions.drawedpointnrs}\" \n",\ +" puts $datei \"viewoptions.drawedtangents ${viewoptions.drawedtangents}\" \n",\ +" puts $datei \"viewoptions.shrink ${viewoptions.shrink}\" \n",\ +" \n",\ +" puts $datei \"stloptions.showtrias ${stloptions.showtrias}\" \n",\ +" puts $datei \"stloptions.showfilledtrias ${stloptions.showfilledtrias}\" \n",\ +" puts $datei \"stloptions.showedges ${stloptions.showedges}\" \n",\ +" puts $datei \"stloptions.showmarktrias ${stloptions.showmarktrias}\" \n",\ +" puts $datei \"stloptions.showactivechart ${stloptions.showactivechart}\" \n",\ +" puts $datei \"stloptions.yangle ${stloptions.yangle}\" \n",\ +" puts $datei \"stloptions.contyangle ${stloptions.contyangle}\" \n",\ +" puts $datei \"stloptions.edgecornerangle ${stloptions.edgecornerangle}\" \n",\ +" puts $datei \"stloptions.chartangle ${stloptions.chartangle}\" \n",\ +" puts $datei \"stloptions.outerchartangle ${stloptions.outerchartangle}\" \n",\ +" puts $datei \"stloptions.usesearchtree ${stloptions.usesearchtree}\" \n",\ +" puts $datei \"stloptions.chartnumber ${stloptions.chartnumber}\" \n",\ +" puts $datei \"stloptions.charttrignumber ${stloptions.charttrignumber}\" \n",\ +" puts $datei \"stloptions.chartnumberoffset ${stloptions.chartnumberoffset}\" \n",\ +" puts $datei \"stloptions.atlasminh ${stloptions.atlasminh}\" \n",\ +" puts $datei \"stloptions.resthsurfcurvfac ${stloptions.resthsurfcurvfac}\" \n",\ +" puts $datei \"stloptions.resthsurfcurvenable ${stloptions.resthsurfcurvenable}\" \n",\ +" puts $datei \"stloptions.resthatlasfac ${stloptions.resthatlasfac}\" \n",\ +" puts $datei \"stloptions.resthatlasenable ${stloptions.resthatlasenable}\" \n",\ +" puts $datei \"stloptions.resthchartdistfac ${stloptions.resthchartdistfac}\" \n",\ +" puts $datei \"stloptions.resthchartdistenable ${stloptions.resthchartdistenable}\" \n",\ +" puts $datei \"stloptions.resthlinelengthfac ${stloptions.resthlinelengthfac}\" \n",\ +" puts $datei \"stloptions.resthlinelengthenable ${stloptions.resthlinelengthenable}\" \n",\ +" puts $datei \"stloptions.resthcloseedgefac ${stloptions.resthcloseedgefac}\" \n",\ +" puts $datei \"stloptions.resthcloseedgeenable ${stloptions.resthcloseedgeenable}\" \n",\ +" puts $datei \"stloptions.resthedgeanglefac ${stloptions.resthedgeanglefac}\" \n",\ +" puts $datei \"stloptions.resthedgeangleenable ${stloptions.resthedgeangleenable}\" \n",\ +" puts $datei \"stloptions.resthsurfmeshcurvfac ${stloptions.resthsurfmeshcurvfac}\" \n",\ +" puts $datei \"stloptions.resthsurfmeshcurvenable ${stloptions.resthsurfmeshcurvenable}\" \n",\ +" puts $datei \"stloptions.recalchopt ${stloptions.recalchopt}\" \n",\ +" \n",\ +" puts $datei \"visoptions.subdivisions ${visoptions.subdivisions}\"\n",\ +"\n",\ +"\n",\ +" if { [info exists trafooptions.solver] == 1 } {\n",\ +" puts $datei \"trafooptions.solver ${trafooptions.solver}\" \n",\ +" puts $datei \"trafooptions.levels ${trafooptions.levels}\" \n",\ +" puts $datei \"trafooptions.linits ${trafooptions.linits}\" \n",\ +" puts $datei \"trafooptions.nonlinits ${trafooptions.nonlinits}\" \n",\ +" puts $datei \"trafooptions.stabcurrent ${trafooptions.stabcurrent}\" \n",\ +" puts $datei \"trafooptions.checkcond ${trafooptions.checkcond}\" \n",\ +" puts $datei \"trafooptions.maxdirect ${trafooptions.maxdirect}\" \n",\ +" puts $datei \"trafooptions.secondorder ${trafooptions.secondorder}\" \n",\ +" puts $datei \"trafooptions.homogenizedcore ${trafooptions.homogenizedcore}\" \n",\ +" puts $datei \"trafooptions.ordercore ${trafooptions.ordercore}\" \n",\ +" puts $datei \"trafooptions.simplecurrents ${trafooptions.simplecurrents}\" \n",\ +" puts $datei \"trafooptions.assemblecomplexmatrix ${trafooptions.assemblecomplexmatrix}\" \n",\ +"\n",\ +" puts $datei \"trafooptions.meshcasing ${trafooptions.meshcasing}\" \n",\ +" puts $datei \"trafooptions.meshcore ${trafooptions.meshcore}\" \n",\ +" puts $datei \"trafooptions.meshclumps ${trafooptions.meshclumps}\" \n",\ +" puts $datei \"trafooptions.meshshields ${trafooptions.meshshields}\" \n",\ +" puts $datei \"trafooptions.meshcoils ${trafooptions.meshcoils}\" \n",\ +" puts $datei \"trafooptions.bcmdirectory ${trafooptions.bcmdirectory}\" \n",\ +" puts $datei \"trafooptions.lossdensityfile ${trafooptions.lossdensityfile}\" \n",\ +" }\n",\ +"\n",\ +" if { [info exists smalltrafomodell.tankheight] == 1 } {\n",\ +" puts $datei \"smalltrafomodell.tankheight ${smalltrafomodell.tankheight}\"\n",\ +" puts $datei \"smalltrafomodell.tankwidth ${smalltrafomodell.tankwidth}\"\n",\ +" puts $datei \"smalltrafomodell.tanklength ${smalltrafomodell.tanklength}\"\n",\ +" puts $datei \"smalltrafomodell.corewidth ${smalltrafomodell.corewidth}\"\n",\ +" puts $datei \"smalltrafomodell.windowheight ${smalltrafomodell.windowheight}\"\n",\ +" puts $datei \"smalltrafomodell.limbdistance ${smalltrafomodell.limbdistance}\"\n",\ +" puts $datei \"smalltrafomodell.xposcore ${smalltrafomodell.xposcore}\"\n",\ +" puts $datei \"smalltrafomodell.yposcore ${smalltrafomodell.yposcore}\"\n",\ +" puts $datei \"smalltrafomodell.zposcore ${smalltrafomodell.zposcore}\"\n",\ +" puts $datei \"smalltrafomodell.leakagefluxguidethickness ${smalltrafomodell.leakagefluxguidethickness}\"\n",\ +" puts $datei \"smalltrafomodell.leakagefluxguidewidth ${smalltrafomodell.leakagefluxguidewidth}\"\n",\ +" puts $datei \"smalltrafomodell.leakagefluxguidezposition ${smalltrafomodell.leakagefluxguidezposition}\"\n",\ +" puts $datei \"smalltrafomodell.limbcoil.1 ${smalltrafomodell.limbcoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.ricoil.1 ${smalltrafomodell.ricoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.rocoil.1 ${smalltrafomodell.rocoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.zposcoil.1 ${smalltrafomodell.zposcoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.heightcoil.1 ${smalltrafomodell.heightcoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.currentcoil.1 ${smalltrafomodell.currentcoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.nturnscoil.1 ${smalltrafomodell.nturnscoil.1}\"\n",\ +" puts $datei \"smalltrafomodell.limbcoil.2 ${smalltrafomodell.limbcoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.ricoil.2 ${smalltrafomodell.ricoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.rocoil.2 ${smalltrafomodell.rocoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.zposcoil.2 ${smalltrafomodell.zposcoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.heightcoil.2 ${smalltrafomodell.heightcoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.currentcoil.2 ${smalltrafomodell.currentcoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.nturnscoil.2 ${smalltrafomodell.nturnscoil.2}\"\n",\ +" puts $datei \"smalltrafomodell.limbcoil.3 ${smalltrafomodell.limbcoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.ricoil.3 ${smalltrafomodell.ricoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.rocoil.3 ${smalltrafomodell.rocoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.zposcoil.3 ${smalltrafomodell.zposcoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.heightcoil.3 ${smalltrafomodell.heightcoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.currentcoil.3 ${smalltrafomodell.currentcoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.nturnscoil.3 ${smalltrafomodell.nturnscoil.3}\"\n",\ +" puts $datei \"smalltrafomodell.limbcoil.4 ${smalltrafomodell.limbcoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.ricoil.4 ${smalltrafomodell.ricoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.rocoil.4 ${smalltrafomodell.rocoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.zposcoil.4 ${smalltrafomodell.zposcoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.heightcoil.4 ${smalltrafomodell.heightcoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.currentcoil.4 ${smalltrafomodell.currentcoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.nturnscoil.4 ${smalltrafomodell.nturnscoil.4}\"\n",\ +" puts $datei \"smalltrafomodell.limbcoil.5 ${smalltrafomodell.limbcoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.ricoil.5 ${smalltrafomodell.ricoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.rocoil.5 ${smalltrafomodell.rocoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.zposcoil.5 ${smalltrafomodell.zposcoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.heightcoil.5 ${smalltrafomodell.heightcoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.currentcoil.5 ${smalltrafomodell.currentcoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.nturnscoil.5 ${smalltrafomodell.nturnscoil.5}\"\n",\ +" puts $datei \"smalltrafomodell.limbcoil.6 ${smalltrafomodell.limbcoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.ricoil.6 ${smalltrafomodell.ricoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.rocoil.6 ${smalltrafomodell.rocoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.zposcoil.6 ${smalltrafomodell.zposcoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.heightcoil.6 ${smalltrafomodell.heightcoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.currentcoil.6 ${smalltrafomodell.currentcoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.nturnscoil.6 ${smalltrafomodell.nturnscoil.6}\"\n",\ +" puts $datei \"smalltrafomodell.limbtest.1 ${smalltrafomodell.limbtest.1}\"\n",\ +" puts $datei \"smalltrafomodell.heighttest.1 ${smalltrafomodell.heighttest.1}\"\n",\ +" puts $datei \"smalltrafomodell.widthtest.1 ${smalltrafomodell.widthtest.1}\"\n",\ +" puts $datei \"smalltrafomodell.rtest.1 ${smalltrafomodell.rtest.1}\"\n",\ +" puts $datei \"smalltrafomodell.zpostest.1 ${smalltrafomodell.zpostest.1}\"\n",\ +" puts $datei \"smalltrafomodell.edgeradiustest.1 ${smalltrafomodell.edgeradiustest.1}\"\n",\ +" puts $datei \"smalltrafomodell.finetest.1 ${smalltrafomodell.finetest.1}\"\n",\ +" puts $datei \"smalltrafomodell.conductivetest.1 ${smalltrafomodell.conductivetest.1}\"\n",\ +" puts $datei \"smalltrafomodell.limbtest.2 ${smalltrafomodell.limbtest.2}\"\n",\ +" puts $datei \"smalltrafomodell.heighttest.2 ${smalltrafomodell.heighttest.2}\"\n",\ +" puts $datei \"smalltrafomodell.widthtest.2 ${smalltrafomodell.widthtest.2}\"\n",\ +" puts $datei \"smalltrafomodell.rtest.2 ${smalltrafomodell.rtest.2}\"\n",\ +" puts $datei \"smalltrafomodell.zpostest.2 ${smalltrafomodell.zpostest.2}\"\n",\ +" puts $datei \"smalltrafomodell.edgeradiustest.2 ${smalltrafomodell.edgeradiustest.2}\"\n",\ +" puts $datei \"smalltrafomodell.finetest.2 ${smalltrafomodell.finetest.2}\"\n",\ +" puts $datei \"smalltrafomodell.conductivetest.2 ${smalltrafomodell.conductivetest.2}\"\n",\ +" puts $datei \"smalltrafomodell.limbtest.3 ${smalltrafomodell.limbtest.3}\"\n",\ +" puts $datei \"smalltrafomodell.heighttest.3 ${smalltrafomodell.heighttest.3}\"\n",\ +" puts $datei \"smalltrafomodell.widthtest.3 ${smalltrafomodell.widthtest.3}\"\n",\ +" puts $datei \"smalltrafomodell.rtest.3 ${smalltrafomodell.rtest.3}\"\n",\ +" puts $datei \"smalltrafomodell.zpostest.3 ${smalltrafomodell.zpostest.3}\"\n",\ +" puts $datei \"smalltrafomodell.edgeradiustest.3 ${smalltrafomodell.edgeradiustest.3}\"\n",\ +" puts $datei \"smalltrafomodell.finetest.3 ${smalltrafomodell.finetest.3}\"\n",\ +" puts $datei \"smalltrafomodell.conductivetest.3 ${smalltrafomodell.conductivetest.3}\"\n",\ +" puts $datei \"smalltrafomodell.limbtest.4 ${smalltrafomodell.limbtest.4}\"\n",\ +" puts $datei \"smalltrafomodell.heighttest.4 ${smalltrafomodell.heighttest.4}\"\n",\ +" puts $datei \"smalltrafomodell.widthtest.4 ${smalltrafomodell.widthtest.4}\"\n",\ +" puts $datei \"smalltrafomodell.rtest.4 ${smalltrafomodell.rtest.4}\"\n",\ +" puts $datei \"smalltrafomodell.zpostest.4 ${smalltrafomodell.zpostest.4}\"\n",\ +" puts $datei \"smalltrafomodell.edgeradiustest.4 ${smalltrafomodell.edgeradiustest.4}\"\n",\ +" puts $datei \"smalltrafomodell.finetest.4 ${smalltrafomodell.finetest.4}\"\n",\ +" puts $datei \"smalltrafomodell.conductivetest.4 ${smalltrafomodell.conductivetest.4}\"\n",\ +" puts $datei \"smalltrafomodell.nperitest ${smalltrafomodell.nperitest}\"\n",\ +" puts $datei \"smalltrafomodell.filename ${smalltrafomodell.filename}\"\n",\ +" puts $datei \"smalltrafomodell.murlfguide ${smalltrafomodell.murlfguide}\"\n",\ +" puts $datei \"smalltrafomodell.murtestwire ${smalltrafomodell.murtestwire}\"\n",\ +" puts $datei \"smalltrafomodell.murcore ${smalltrafomodell.murcore}\"\n",\ +" puts $datei \"smalltrafomodell.kappalfguide ${smalltrafomodell.kappalfguide}\"\n",\ +" puts $datei \"smalltrafomodell.kappatestwire ${smalltrafomodell.kappatestwire}\"\n",\ +" puts $datei \"smalltrafomodell.kappacore ${smalltrafomodell.kappacore}\"\n",\ +" }\n",\ +" \n",\ +" \n",\ +" close $datei\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc saveinifile { } {\n",\ +" uplevel 1 {\n",\ +" set datei [open ng.ini w]\n",\ +" for { set i [.ngmenu.file.recent index last] } { $i >= 1 } { incr i -1 } {\n",\ +" puts $datei \"recentfile \\\"[.ngmenu.file.recent entrycget $i -label]\\\"\"\n",\ +" }\n",\ +" \n",\ +" close $datei\n",\ +" } \n",\ +"\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc savemeshinifile { } {\n",\ +" uplevel 1 {\n",\ +" set datei [open ngmesh.ini w]\n",\ +" for { set i [.ngmenu.file.recentmesh index last] } { $i >= 1 } { incr i -1 } {\n",\ +" puts $datei \"recentfile \\\"[.ngmenu.file.recentmesh entrycget $i -label]\\\"\"\n",\ +" }\n",\ +" \n",\ +" close $datei\n",\ +" } \n",\ +"\n",\ +"\n",\ +"}\n",\ +"\n",\ +"proc loadinifile { } {\n",\ +" if { [file exists ng.ini] == 1 } {\n",\ +" set datei [open ng.ini r]\n",\ +" while { [gets $datei line] >= 0 } {\n",\ +" if {[lindex $line 0] == \"recentfile\"} {\n",\ +" set filename [lindex $line 1]\n",\ +" AddRecentFile $filename\n",\ +" }\n",\ +" }\n",\ +" close $datei\n",\ +" }\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc loadmeshinifile { } {\n",\ +" if { [file exists ngmesh.ini] == 1 } {\n",\ +" set datei [open ngmesh.ini r]\n",\ +" while { [gets $datei line] >= 0 } {\n",\ +" if {[lindex $line 0] == \"recentfile\"} {\n",\ +" set filename [lindex $line 1]\n",\ +" AddRecentMeshFile $filename\n",\ +" }\n",\ +" }\n",\ +" close $datei\n",\ +" }\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc setgranularity { gran } {\n",\ +" if {$gran == 6} { return }\n",\ +" set gran [expr $gran - 1]\n",\ +" global options.curvaturesafety\n",\ +" set surfcurvlist { 1 1.5 2 3 5 }\n",\ +" set options.curvaturesafety [lindex $surfcurvlist $gran]\n",\ +"\n",\ +" global options.segmentsperedge\n",\ +" set spelist { 0.3 0.5 1 2 3 }\n",\ +" set options.segmentsperedge [lindex $spelist $gran]\n",\ +" \n",\ +" global stloptions.resthsurfcurvfac\n",\ +" set surfcurvfaclist { 0.25 0.5 1 1.5 3 }\n",\ +" set stloptions.resthsurfcurvfac [lindex $surfcurvfaclist $gran]\n",\ +"\n",\ +" global stloptions.resthchartdistfac\n",\ +" set chartdistfaclist { 0.8 1 1.5 2 5 }\n",\ +" set stloptions.resthchartdistfac [lindex $chartdistfaclist $gran]\n",\ +"\n",\ +" global stloptions.resthlinelengthfac\n",\ +" set linelengthfaclist { 0.2 0.35 0.5 1.5 3 }\n",\ +" set stloptions.resthlinelengthfac [lindex $linelengthfaclist $gran]\n",\ +"\n",\ +" global stloptions.resthcloseedgefac\n",\ +" set closeedgefaclist { 0.5 1 2 3.5 5 }\n",\ +" set stloptions.resthcloseedgefac [lindex $closeedgefaclist $gran]\n",\ +"\n",\ +" global stloptions.resthedgeanglefac\n",\ +" set edgeanglefaclist { 0.25 0.5 1 1.5 3 }\n",\ +" set stloptions.resthedgeanglefac [lindex $edgeanglefaclist $gran]\n",\ +"\n",\ +"\n",\ +" global stloptions.resthsurfmeshcurvfac \n",\ +" set surfmeshcurvlist { 1 1.5 2 3 5 }\n",\ +" set stloptions.resthsurfmeshcurvfac [lindex $surfmeshcurvlist $gran]\n",\ +"\n",\ +"\n",\ +" global options.grading\n",\ +" set gradinglist { 0.7 0.5 0.3 0.2 0.1 }\n",\ +" set options.grading [lindex $gradinglist $gran]\n",\ +" \n",\ +"}\n",\ +"\n",\ +"\n",\ +"if { $batchmode != \"defined\" } {\n",\ +" \n",\ +"\n",\ +"menu .ngmenu -tearoff 0 -relief raised -bd 2\n",\ +". configure -menu .ngmenu\n",\ +"\n",\ +".ngmenu add cascade -label \"File\" -menu .ngmenu.file -underline 0\n",\ +".ngmenu add cascade -label \"Geometry\" -menu .ngmenu.geometry -underline 0\n",\ +".ngmenu add cascade -label \"Mesh\" -menu .ngmenu.mesh -underline 0\n",\ +".ngmenu add cascade -label \"View\" -menu .ngmenu.view -underline 0\n",\ +".ngmenu add cascade -label \"Refinement\" -menu .ngmenu.meshsize -underline 5\n",\ +"\n",\ +"if { $userlevel == 3} {\n",\ +" .ngmenu add cascade -label \"Special\" -menu .ngmenu.special -underline 3\n",\ +"}\n",\ +"\n",\ +".ngmenu add cascade -label \"Help\" -menu .ngmenu.help -underline 0\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.file\n",\ +"\n",\ +".ngmenu.file add command -label \"Load Geometry...\" -accelerator \"\" \\\n",\ +" -command { \n",\ +" set types {\n",\ +" {\"All Geometry types\" { .stl .stlb .step .stp .geo .in2d .igs .iges .brep .in2dnew .sat} }\n",\ +" {\"IGES Geometry\" {.igs .iges} }\n",\ +" {\"BREP OpenCascade Geometry\" {.brep} }\n",\ +" {\"STL Geometry\" {.stl} }\n",\ +" {\"Binary STL Geometry\" {.stlb} }\n",\ +" {\"STEP Geometry\" {.step .stp} }\n",\ +" {\"Geometry file\" {.geo} }\n",\ +" {\"2D Geometry\" {.in2d } } \n",\ +" {\"2D Geometry New\" {.in2dnew } } \n",\ +" } \n",\ +"\n",\ +" set ACISavailable [Ng_ACISCommand isACISavailable]\n",\ +" if {$ACISavailable == \"yes\" } {\n",\ +" lappend types {\"ACIS Geometry\" {.sat} }\n",\ +" }\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +" set file [tk_getOpenFile -filetypes $types]\n",\ +" if {$file != \"\"} {\n",\ +" AddRecentFile $file\n",\ +" Ng_LoadGeometry $file \n",\ +" Ng_ParseGeometry\n",\ +" set selectvisual geometry\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" wm title . [concat \"$progname - \" $file]\n",\ +" set dirname [file dirname $file]\n",\ +" set basefilename [file tail [file rootname $file]]\n",\ +"\n",\ +" rebuildoccdialog\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Save Geometry...\" \\\n",\ +" -command { \n",\ +" set occgeometryloaded [Ng_OCCCommand isoccgeometryloaded]\n",\ +" puts $occgeometryloaded\n",\ +" if {$occgeometryloaded == 1 } {\n",\ +" set types {\n",\ +" {\"IGES Geometry file\" {.igs} } \n",\ +" {\"STEP Geometry file\" {.stp} } \n",\ +" {\"STL Geometry file\" {.stl} } \n",\ +" {\"STL BIN Geometry file\" {.stlb} } \n",\ +" }\n",\ +" } {\n",\ +" set types {\n",\ +" {\"STL Geometry file\" {.stl} } \n",\ +" {\"STL BIN Geometry file\" {.stlb} } \n",\ +" }\n",\ +" }\n",\ +"\n",\ +" set ACISavailable [Ng_ACISCommand isACISavailable]\n",\ +" puts $ACISavailable\n",\ +" if {$ACISavailable == \"yes\" } {\n",\ +" lappend types {\"ACIS Geometry\" {.sat} }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" set file [tk_getSaveFile -filetypes $types -initialdir $dirname -initialfile $basefilename ]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_SaveGeometry $file \n",\ +" }\n",\ +" }\n",\ +" \n",\ +"\n",\ +"\n",\ +".ngmenu.file add cascade -label \"Recent Files\" -menu .ngmenu.file.recent \n",\ +"menu .ngmenu.file.recent\n",\ +"\n",\ +"\n",\ +"proc AddRecentFile { filename } {\n",\ +" global progname\n",\ +" global dirname\n",\ +" catch { [.ngmenu.file.recent delete $filename] }\n",\ +" .ngmenu.file.recent insert 0 command -label $filename \\\n",\ +" -command \"AddRecentFile {$filename}; \n",\ +" Ng_LoadGeometry {$filename}; \n",\ +" Ng_ParseGeometry;\n",\ +" set selectvisual geometry;\n",\ +" Ng_SetVisParameters;\n",\ +" redraw;\n",\ +" wm title . [concat \\\" $progname - $filename \\\"];\n",\ +" set dirname {[file dirname $filename]};\n",\ +" set basefilename {[file tail [file rootname $filename]]};\n",\ +" rebuildoccdialog;\"\n",\ +" \n",\ +" if { [.ngmenu.file.recent index last] >= 6 } {\n",\ +" .ngmenu.file.recent delete last }\n",\ +" \n",\ +" saveinifile;\n",\ +" }\n",\ +"loadinifile;\n",\ +"\n",\ +"\n",\ +".ngmenu.file add separator\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Load Mesh...\" -accelerator \"\" \\\n",\ +" -command {\n",\ +" set types {\n",\ +" {\"Mesh file\" {.vol} } }\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".vol\"]\n",\ +" if {$file != \"\"} {\n",\ +" AddRecentMeshFile $file;\n",\ +" Ng_LoadMesh $file; \n",\ +" set selectvisual mesh\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" Ng_ReadStatus; \n",\ +" set dirname [file dirname $file]\n",\ +" set basefilename [file tail [file rootname $file]]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.file add cascade -label \"Recent Meshes\" -menu .ngmenu.file.recentmesh \n",\ +"menu .ngmenu.file.recentmesh\n",\ +"\n",\ +"\n",\ +"proc AddRecentMeshFile { filename } {\n",\ +" global progname\n",\ +" global dirname\n",\ +" catch { [.ngmenu.file.recentmesh delete $filename] }\n",\ +" .ngmenu.file.recentmesh insert 0 command -label $filename \\\n",\ +" -command \"AddRecentMeshFile {$filename}; \n",\ +" Ng_LoadMesh {$filename};\n",\ +" set selectvisual mesh;\n",\ +" Ng_SetVisParameters;\n",\ +" redraw;\n",\ +" wm title . [concat \\\" $progname - $filename \\\"];\n",\ +" set dirname {[file dirname $filename]};\n",\ +" set basefilename {[file tail [file rootname $filename]]};\n",\ +" rebuildoccdialog;\"\n",\ +" \n",\ +" if { [.ngmenu.file.recentmesh index last] >= 6 } {\n",\ +" .ngmenu.file.recentmesh delete last }\n",\ +" \n",\ +" savemeshinifile;\n",\ +" }\n",\ +"loadmeshinifile;\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Save Mesh...\" -accelerator \"\" \\\n",\ +" -command {\n",\ +" set types {\n",\ +" {\"Mesh file\" {.vol} } }\n",\ +"\n",\ +" set file [tk_getSaveFile -filetypes $types -defaultextension \".vol\" -initialfile $basefilename -initialdir $dirname ]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_SaveMesh $file }\n",\ +" AddRecentMeshFile $file;\n",\ +"\n",\ +" }\n",\ +"\n",\ +".ngmenu.file add command -label \"Merge Mesh...\" \\\n",\ +" -command {\n",\ +" set types {\n",\ +" {\"Mesh file\" {.vol} } }\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".vol\"]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_MergeMesh $file; \n",\ +" set selectvisual mesh\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" Ng_ReadStatus; \n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Import Mesh...\" \\\n",\ +" -command { \n",\ +" set types {\n",\ +" {\"Neutral format\" {.mesh .emt} }\n",\ +" {\"Surface mesh format\" {.surf} }\n",\ +" {\"Universal format\" {.unv} }\n",\ +" {\"Olaf format\" {.emt} }\n",\ +" {\"TET format\" {.tet} }\n",\ +" {\"Pro/ENGINEER neutral format\" {.fnf} }\n",\ +" }\n",\ +" set file [tk_getOpenFile -filetypes $types ]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_ImportMesh $file \n",\ +" set selectvisual mesh\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" Ng_ReadStatus; \n",\ +" }\n",\ +" }\n",\ +"\n",\ +".ngmenu.file add command -label \"Export Mesh...\" \\\n",\ +" -command {\n",\ +" if { $exportfiletype == \"Elmer Format\" } {\n",\ +" set file [tk_chooseDirectory]\n",\ +" } else {\n",\ +" set file [tk_getSaveFile]\n",\ +" }\n",\ +" if {$file != \"\"} {\n",\ +" Ng_ExportMesh $file $exportfiletype \n",\ +" }\n",\ +" }\n",\ +"\n",\ +".ngmenu.file add cascade -label \"Export Filetype\" -menu .ngmenu.file.filetype \n",\ +"\n",\ +"menu .ngmenu.file.filetype \n",\ +"\n",\ +"\n",\ +".ngmenu.file add separator\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Save Solution...\" \\\n",\ +" -command { \n",\ +" set types { \n",\ +" {\"Solution File\" {.sol} } \n",\ +" {\"VTK File\" {.vtk} } \n",\ +" }\n",\ +" set file [tk_getSaveFile -filetypes $types ]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_SaveSolution $file \n",\ +" }\n",\ +" }\n",\ +"\n",\ +".ngmenu.file add command -label \"Import Solution...\" \\\n",\ +" -command { \n",\ +" set types { {\"Solution File\" {.sol} } }\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".sol\" ]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_ImportSolution $file \n",\ +" set selectvisual solution\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set demostarttime [clock clicks -millisecond]\n",\ +"set stopdemo 0\n",\ +"proc demoredraw { } {\n",\ +" global demostarttime\n",\ +" global stopdemo\n",\ +" set curtime [clock clicks -millisecond]\n",\ +" set result [ Ng_DemoSetTime [expr $curtime - $demostarttime] ]\n",\ +" redraw\n",\ +" global videoactive\n",\ +" if { $videoactive == 1 } {\n",\ +" puts \"addframe\"\n",\ +" .ndraw Ng_VideoClip addframe\n",\ +" }\n",\ +" if { $result == 0 && $stopdemo == 0 } {\n",\ +" after 1 { demoredraw }\n",\ +" }\n",\ +"}\n",\ +".ngmenu.file add command -label \"Show Demo...\" \\\n",\ +" -command {\n",\ +" set types { {\"Demo File\" {.dem} } }\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".dem\" ]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_ShowDemo $file \n",\ +" set demostarttime [clock clicks -millisecond]\n",\ +" set stopdemo 0\n",\ +" demoredraw\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.file add separator\n",\ +"\n",\ +".ngmenu.file add command -label \"Snapshot...\" \\\n",\ +" -command { \n",\ +" set types { \n",\ +" {\"JPG file\" {.jpg} } \n",\ +" {\"GIF file\" {.gif} } \n",\ +" {\"PPM file\" {.ppm} } \n",\ +" }\n",\ +" set file [tk_getSaveFile -filetypes $types]\n",\ +" if {$file != \"\"} {\n",\ +" .ndraw Ng_SnapShot $file }\n",\ +" }\n",\ +"\n",\ +"\n",\ +".ngmenu.file add cascade -label \"Video clip\" -menu .ngmenu.file.video\n",\ +"menu .ngmenu.file.video\n",\ +"\n",\ +"set videoactive 0\n",\ +".ngmenu.file.video add command -label \"start...\" \\\n",\ +" -command { \n",\ +" set types { \n",\ +" {\"MPG file\" {.mpg} } \n",\ +" }\n",\ +" set file [tk_getSaveFile -filetypes $types]\n",\ +" if {$file != \"\"} {\n",\ +" .ndraw Ng_VideoClip init $file \n",\ +" global videoactive\n",\ +" set videoactive 1\n",\ +" }\n",\ +" }\n",\ +"\n",\ +".ngmenu.file.video add command -label \"add frame...\" \\\n",\ +" -command {.ndraw Ng_VideoClip addframe }\n",\ +"\n",\ +".ngmenu.file.video add command -label \"one cycle\" \\\n",\ +" -command {\n",\ +" set visoptions.redrawperiodic 1\n",\ +" for { set j 0 } { $j < 100 } { incr j } {\n",\ +" puts \"j = $j\"\n",\ +" Ng_Vis_Set time [expr (1000 * $j / 100)]\n",\ +" redraw\n",\ +" .ndraw Ng_VideoClip addframe \n",\ +" after 200\n",\ +" }\n",\ +" }\n",\ +"\n",\ +".ngmenu.file.video add command -label \"finalize...\" \\\n",\ +" -command {\n",\ +" .ndraw Ng_VideoClip finalize \n",\ +" global videoactive\n",\ +" set videoactive 0\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Save Options\" \\\n",\ +" -command { saveoptions }\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +".ngmenu.file add separator\n",\ +"\n",\ +"\n",\ +".ngmenu.file add command -label \"Run tests ...\" \\\n",\ +" -command { runtestdialog }\n",\ +".ngmenu.file add separator\n",\ +"\n",\ +".ngmenu.file add command -label \"Quit\" -accelerator \"\" \\\n",\ +" -command { puts \"Thank you for using $progname\"; Ng_Exit; destroy . }\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.mesh\n",\ +".ngmenu.mesh add command -label \"Generate Mesh\" -accelerator \"\" \\\n",\ +" -command { \n",\ +" Ng_GenerateMesh ${meshoptions.firststep} ${meshoptions.laststep}\n",\ +" Ng_ReadStatus\n",\ +" set selectvisual mesh\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Stop Meshing\" \\\n",\ +" -command { Ng_StopMeshing }\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Meshing Options...\" \\\n",\ +" -command meshingoptionsdialog\n",\ +"\n",\ +".ngmenu.mesh add separator\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Delete Mesh\" \\\n",\ +" -command { Ng_New mesh; Ng_ReadStatus; redraw }\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Delete Vol Mesh\" \\\n",\ +" -command { Ng_DeleteVolMesh; Ng_ReadStatus; redraw }\n",\ +"\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Mesh Info\" \\\n",\ +" -command {\n",\ +" set dim [Ng_MeshInfo dim]\n",\ +" set np [Ng_MeshInfo np]\n",\ +" set ne [Ng_MeshInfo ne]\n",\ +" set nse [Ng_MeshInfo nse]\n",\ +" set nseg [Ng_MeshInfo nseg]\n",\ +" set bbox [Ng_MeshInfo bbox]\n",\ +" tk_messageBox -message \"Dimension: $dim\\nPoints: $np\\nElements: $ne\\nSurface Els: $nse\\nSegments: $nseg\\nxmin [lindex $bbox 0] xmax [lindex $bbox 1]\\nymin [lindex $bbox 2] ymax [lindex $bbox 3]\\nzmin [lindex $bbox 4] zmax [lindex $bbox 5]\"\n",\ +" }\n",\ +"\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Mesh Quality\" \\\n",\ +" -command {\n",\ +" set inplanemin 0\n",\ +" set inplanemax 0\n",\ +" set betplanemin 0\n",\ +" set betplanemax 0\n",\ +" Ng_MeshQuality inplanemin inplanemax betplanemin betplanemax\n",\ +" puts \"Triangle angles : $inplanemin - $inplanemax\"\n",\ +" puts \"Tet angles : $betplanemin - $betplanemax\"\n",\ +" tk_messageBox -message \"Triangle angles : $inplanemin - $inplanemax \\n Tet angles : $betplanemin - $betplanemax\"\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Check Surface Mesh\" \\\n",\ +" -command { Ng_CheckSurfaceMesh }\n",\ +".ngmenu.mesh add command -label \"Check Volume Mesh\" \\\n",\ +" -command { Ng_CheckVolumeMesh }\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Edit Boundary Conditions...\" \\\n",\ +" -command { bcpropdialog }\n",\ +"\n",\ +"if { $userlevel == 3 } {\n",\ +" .ngmenu.mesh add command -label \"Mesh Doctor...\" \\\n",\ +" -command { meshdoctordialog }\n",\ +"}\n",\ +"\n",\ +".ngmenu.mesh add command -label \"METIS Mesh Partitioning...\" \\\n",\ +" -command { METISdialog }\n",\ +"\n",\ +".ngmenu.mesh add separator\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Analyze Geometry\" \\\n",\ +" -command { Ng_GenerateMesh ag ag; Ng_ReadStatus; redraw }\n",\ +".ngmenu.mesh add command -label \"Mesh Edges\" \\\n",\ +" -command { Ng_GenerateMesh me me; Ng_ReadStatus; redraw }\n",\ +".ngmenu.mesh add command -label \"Mesh Surface\" \\\n",\ +" -command { set selectvisual mesh; Ng_SetVisParameters; \\\n",\ +" Ng_GenerateMesh ms ms; Ng_ReadStatus; redraw }\n",\ +"\n",\ +".ngmenu.mesh add command -label \"Optimize Surface\" \\\n",\ +" -command { Ng_GenerateMesh os os cmsmSm; redraw }\n",\ +"\n",\ +".ngmenu.mesh add cascade -label \"Surface Optim. Step\" -menu .ngmenu.mesh.surfoptstep \n",\ +"\n",\ +"menu .ngmenu.mesh.surfoptstep \n",\ +".ngmenu.mesh.surfoptstep add command -label \"Mesh Smoothing\" \\\n",\ +" -command { Ng_GenerateMesh os os m; redraw}\n",\ +".ngmenu.mesh.surfoptstep add command -label \"Edge swapping (topologic)\" \\\n",\ +" -command { Ng_GenerateMesh os os s; redraw}\n",\ +".ngmenu.mesh.surfoptstep add command -label \"Edge swapping (metric)\" \\\n",\ +" -command { Ng_GenerateMesh os os S; redraw}\n",\ +".ngmenu.mesh.surfoptstep add command -label \"Combine points\" \\\n",\ +" -command { Ng_GenerateMesh os os c; redraw}\n",\ +"\n",\ +"\n",\ +".ngmenu.mesh add separator\n",\ +".ngmenu.mesh add command -label \"Mesh Volume\" \\\n",\ +" -command { Ng_GenerateMesh mv mv; Ng_ReadStatus }\n",\ +".ngmenu.mesh add command -label \"Optimize Volume\" \\\n",\ +" -command { Ng_GenerateMesh ov ov; Ng_ReadStatus }\n",\ +".ngmenu.mesh add command -label \"Smooth Opt Volume\" \\\n",\ +" -command { Ng_GenerateMesh ov ov m; Ng_ReadStatus }\n",\ +".ngmenu.mesh add command -label \"Smooth Opt Volume Jacobian\" \\\n",\ +" -command { Ng_GenerateMesh ov ov j; Ng_ReadStatus }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.geometry\n",\ +".ngmenu.geometry add command -label \"Scan CSG Geometry\" -command { Ng_ParseGeometry }\n",\ +".ngmenu.geometry add command -label \"CSG Options...\" -command geometryoptionsdialog\n",\ +".ngmenu.geometry add command -label \"CSG Properties...\" \\\n",\ +" -command topleveldialog2 \n",\ +"\n",\ +".ngmenu.geometry add separator\n",\ +"\n",\ +".ngmenu.geometry add command -label \"STL Doctor...\" \\\n",\ +" -command { stldoctordialog; }\n",\ +"\n",\ +".ngmenu.geometry add command -label \"STL Info\" \\\n",\ +" -command {\n",\ +" set notriangles 0\n",\ +" set minx 0\n",\ +" set maxx 0\n",\ +" set miny 0\n",\ +" set maxy 0\n",\ +" set minz 0\n",\ +" set maxz 0\n",\ +" set trigscons 0\n",\ +" Ng_STLInfo notriangles minx maxx miny maxy minz maxz trigscons\n",\ +" set msgtext \"NO STL-Triangles : $notriangles\\nGeometry:\\nX = $minx - $maxx\\nY = $miny - $maxy\\nZ = $minz - $maxz\\nConsistency Check = $trigscons\\n\"\n",\ +" set msgtext \"$msgtext Status: [Ng_STLInfo status]\"\n",\ +" tk_messageBox -title \"STL Info\" -message $msgtext -type ok \n",\ +" }\n",\ +"\n",\ +".ngmenu.geometry add separator\n",\ +"\n",\ +".ngmenu.geometry add command -label \"IGES/STEP Topology Explorer/Doctor...\" \\\n",\ +" -command { occdialog; }\n",\ +"\n",\ +"\n",\ +".ngmenu.geometry add command -label \"OCC Construction\" \\\n",\ +" -command { Ng_OCCConstruction; }\n",\ +"\n",\ +"if { [Ng_ACISCommand isACISavailable] == \"yes\" } {\n",\ +" .ngmenu.geometry add command -label \"ACIS Topology Explorer...\" \\\n",\ +" -command { acisdialog; }\n",\ +"\n",\ +" .ngmenu.geometry add command -label \"ACIS combine all\" \\\n",\ +" -command { Ng_ACISCommand combineall }\n",\ +" .ngmenu.geometry add command -label \"ACIS Create CT\" \\\n",\ +" -command { Ng_ACISCommand createct }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.view\n",\ +".ngmenu.view add command -label \"Zoom all\" \\\n",\ +" -command { Ng_ZoomAll; redraw }\n",\ +".ngmenu.view add command -label \"Center\" \\\n",\ +" -command { Ng_Center; redraw }\n",\ +"\n",\ +".ngmenu.view add command -label \"x-y plane\" \\\n",\ +" -command { Ng_StandardRotation xy; redraw }\n",\ +".ngmenu.view add command -label \"y-x plane\" \\\n",\ +" -command { Ng_StandardRotation yx; redraw }\n",\ +".ngmenu.view add command -label \"x-z plane\" \\\n",\ +" -command { Ng_StandardRotation xz; redraw }\n",\ +".ngmenu.view add command -label \"z-x plane\" \\\n",\ +" -command { Ng_StandardRotation zx; redraw }\n",\ +".ngmenu.view add command -label \"y-z plane\" \\\n",\ +" -command { Ng_StandardRotation yz; redraw }\n",\ +".ngmenu.view add command -label \"z-y plane\" \\\n",\ +" -command { Ng_StandardRotation zy; redraw }\n",\ +"\n",\ +".ngmenu.view add command -label \"Viewing Options...\" \\\n",\ +" -command { viewingoptionsdialog; redraw }\n",\ +".ngmenu.view add command -label \"Clipping Plane...\" \\\n",\ +" -command { clippingdialog; redraw }\n",\ +".ngmenu.view add command -label \"Solution Data...\" \\\n",\ +" -command { visual_dialog; redraw }\n",\ +".ngmenu.view add checkbutton -variable viewqualityplot \\\n",\ +" -label \"Quality Plot\" \\\n",\ +" -command { qualityviewdialog $viewqualityplot }\n",\ +".ngmenu.view add checkbutton -variable memuseplot \\\n",\ +" -label \"Memory Usage\" \\\n",\ +" -command { memusedialog $memuseplot }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.meshsize\n",\ +".ngmenu.meshsize add command -label \"Refine uniform\" \\\n",\ +" -command { Ng_Refine; Ng_HighOrder ${options.elementorder}; Ng_ReadStatus; redraw }\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Second Order\" \\\n",\ +" -command { Ng_SecondOrder; Ng_ReadStatus; redraw }\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Validate Second Order\" \\\n",\ +" -command { Ng_ValidateSecondOrder; Ng_ReadStatus; redraw }\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"High Order\" \\\n",\ +" -command { Ng_HighOrder ${options.elementorder}; Ng_ReadStatus; redraw }\n",\ +"\n",\ +".ngmenu.meshsize add separator\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Refinement Dialog...\" \\\n",\ +" -command { refinementdialog }\n",\ +".ngmenu.meshsize add command -label \"Load Meshsize...\" \\\n",\ +" -command {\n",\ +" set types {\n",\ +" {\"Meshsize file\" {.msz} } }\n",\ +" set file [tk_getOpenFile -filetypes $types]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_LoadMeshSize $file; \n",\ +" }\n",\ +" }\n",\ +".ngmenu.meshsize add command -label \"MS from Surf Mesh\" \\\n",\ +" -command { Ng_MeshSizeFromSurfaceMesh }\n",\ +"\n",\ +"\n",\ +"if { $userlevel == 3 } {\n",\ +".ngmenu.meshsize add command -label \"Singular point ms\" \\\n",\ +" -command { Ng_SingularPointMS; }\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Singular edge ms\" \\\n",\ +" -command { Ng_SingularEdgeMS; }\n",\ +"\n",\ +".ngmenu.meshsize add separator\n",\ +"\n",\ +"set bisectfilename \"\";\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Bisection\" \\\n",\ +" -command { Ng_ReadStatus; set oldnp 0; set newnp $status_np; \n",\ +" Ng_ReadStatus;\n",\ +" \n",\ +" while { $oldnp < $newnp } {\n",\ +" set level [expr $level+1]\n",\ +" if { $bisectfilename == \"\"} {\n",\ +" Ng_Bisect;\n",\ +" } else {\n",\ +" Ng_Bisect $bisectfilename;\n",\ +" }\n",\ +" Ng_ReadStatus;\n",\ +" redraw; \n",\ +" \n",\ +" if { $bisectfilename == \"\"} {\n",\ +" set oldnp $newnp;\n",\ +" set newnp $status_np;\n",\ +" puts \"oldnp $oldnp newnp $newnp\";\n",\ +" } else {\n",\ +" set oldnp $newnp;\n",\ +" }\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"}\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Load Refinement Info...\" \\\n",\ +" -command {\n",\ +" set types {\n",\ +" {\"Refinement info\" {.refine} }}\n",\ +" set bisectfilename [tk_getOpenFile -filetypes $types]\n",\ +" }\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Z-Refinement\" \\\n",\ +" -command { Ng_ZRefinement 2; Ng_ReadStatus; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.meshsize add cascade -label \"hp-Refinement\" -menu .ngmenu.meshsize.hpref\n",\ +"menu .ngmenu.meshsize.hpref\n",\ +".ngmenu.meshsize.hpref add command -label \"1 Level\" \\\n",\ +" -command { Ng_HPRefinement 1; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"2 Levels\" \\\n",\ +" -command { Ng_HPRefinement 2; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"3 Levels\" \\\n",\ +" -command { Ng_HPRefinement 3; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"4 Levels\" \\\n",\ +" -command { Ng_HPRefinement 4; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"5 Levels\" \\\n",\ +" -command { Ng_HPRefinement 5; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"6 Levels\" \\\n",\ +" -command { Ng_HPRefinement 6; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"7 Levels\" \\\n",\ +" -command { Ng_HPRefinement 7; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"8 Levels\" \\\n",\ +" -command { Ng_HPRefinement 8; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"9 Levels\" \\\n",\ +" -command { Ng_HPRefinement 9; Ng_ReadStatus; redraw }\n",\ +".ngmenu.meshsize.hpref add command -label \"10 Levels\" \\\n",\ +" -command { Ng_HPRefinement 10; Ng_ReadStatus; redraw }\n",\ +"\n",\ +"\n",\ +".ngmenu.meshsize add command -label \"Split to Tets\" \\\n",\ +" -command { Ng_Split2Tets; Ng_ReadStatus; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.special\n",\ +".ngmenu.special add command -label \"Insert virtual boundary layer\" \\\n",\ +" -command { Ng_InsertVirtualBL; redraw }\n",\ +".ngmenu.special add command -label \"Cut off and combine with other\" \\\n",\ +" -command { \n",\ +" set types { {\"Mesh file\" {.vol} } }\n",\ +" set file [tk_getOpenFile -filetypes $types]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_CutOffAndCombine $file; }\n",\ +" redraw \n",\ +" }\n",\ +".ngmenu.special add command -label \"Helmholtz Mesh grading\" \\\n",\ +" -command { Ng_HelmholtzMesh; }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"menu .ngmenu.help\n",\ +".ngmenu.help add command -label \"Ng Help...\" \\\n",\ +" -command { help_main }\n",\ +".ngmenu.view add checkbutton -label \"Help Line\" -variable showhelpline \\\n",\ +" -command {\n",\ +" if { $showhelpline == 1} {\n",\ +" pack .helpline -before .statbar -side bottom -fill x -padx 3p\n",\ +" } {\n",\ +" pack forget .helpline \n",\ +" }\n",\ +"} \n",\ +"\n",\ +".ngmenu.help add command -label \"About...\" \\\n",\ +" -command {\n",\ +"tk_messageBox -message \"This is NETGEN \\n mainly written by \\n Joachim Sch�erl \\n thanks to \\n R. Gaisbauer, J. Gerstmayr\"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"frame .bubar -relief raised -bd 2\n",\ +"pack .bubar -side top -fill x\n",\ +"\n",\ +"button .bubar.testb -text \"Test\" -command { Ng_SaveGeometry }\n",\ +"button .bubar.surfm -text \"Generate Mesh\" -command \\\n",\ +" { set selectvisual mesh; \n",\ +" Ng_SetVisParameters;\n",\ +" Ng_GenerateMesh ${meshoptions.firststep} ${meshoptions.laststep}\n",\ +" redraw \n",\ +" }\n",\ +"button .bubar.stopm -text \"Stop\" -command \\\n",\ +" { Ng_StopMeshing; set stopdemo 1 }\n",\ +"button .bubar.exitb -text \"Quit\" \\\n",\ +" -command { .ngmenu.file invoke \"Quit\" }\n",\ +"pack .bubar.exitb .bubar.surfm .bubar.stopm -side left\n",\ +"\n",\ +"\n",\ +"Ng_IsParallel;\n",\ +"if { $parallel_netgen } {\n",\ +" button .bubar.visallb -text \"Parallel\" -command \\\n",\ +" { paralleldialog; redraw } \n",\ +" pack .bubar.visallb -side left \n",\ +"}\n",\ +"\n",\ +"button .bubar.zoomall -text \"Zoom All\" \\\n",\ +" -command { Ng_ZoomAll; redraw }\n",\ +"\n",\ +"button .bubar.center -text \"Center\" \\\n",\ +" -command { Ng_Center; redraw }\n",\ +"\n",\ +"tixOptionMenu .bubar.modesel \\\n",\ +" -options {\n",\ +" label.width 0\n",\ +" label.anchor e\n",\ +" menubutton.width 6\n",\ +" } \\\n",\ +" -variable drawmode\n",\ +"\n",\ +".bubar.modesel add command rotate -label Rotate\n",\ +".bubar.modesel add command move -label Move\n",\ +".bubar.modesel add command zoom -label Zoom\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set viewvals { geometry specpoints mesh solution}\n",\ +"if { $userlevel == 3} {\n",\ +" set viewvals { geometry mesh specpoints surfmeshing modelview solution}\n",\ +"}\n",\ +"\n",\ +"set viewvallabs(cross) \"Cross\" \n",\ +"set viewvallabs(geometry) \"Geometry\" \n",\ +"set viewvallabs(mesh) \"Mesh\" \n",\ +"set viewvallabs(specpoints) \"Edges\" \n",\ +"set viewvallabs(surfmeshing) \"Mesh Gen\" \n",\ +"set viewvallabs(modelview) \"Modeller\" \n",\ +"set viewvallabs(solution) \"Solution\" \n",\ +"\n",\ +"tixOptionMenu .bubar.selview \\\n",\ +" -options {\n",\ +" label.width 0\n",\ +" label.anchor e\n",\ +" menubutton.width 10\n",\ +" } \\\n",\ +"\n",\ +"foreach viewv $viewvals {\n",\ +" .bubar.selview add command $viewv -label $viewvallabs($viewv)\n",\ +"}\n",\ +"\n",\ +"\n",\ +".bubar.selview config -variable selectvisual\n",\ +".bubar.selview config -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +"\n",\ +"pack .bubar.modesel -side right\n",\ +"pack forget .bubar.modesel\n",\ +"pack .bubar.center .bubar.zoomall .bubar.selview -side right\n",\ +"\n",\ +".ngmenu.view add checkbutton -variable viewrotatebutton \\\n",\ +" -label \"Enable LeftButton Selection\" \\\n",\ +" -command { \n",\ +" if { $viewrotatebutton } {\n",\ +" pack .bubar.modesel -side right\n",\ +" } {\n",\ +" pack forget .bubar.modesel\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"label .helpline -text \"None\"\n",\ +"pack forget .helpline -side bottom -fill x\n",\ +"\n",\ +"frame .statbar -relief flat -bd 2\n",\ +"pack .statbar -side bottom -fill x\n",\ +"\n",\ +"label .statbar.ptslabel -text \"Points: \"\n",\ +"label .statbar.ptsval -textvariable status_np\n",\ +"label .statbar.elslabel -text \" Elements: \"\n",\ +"label .statbar.elsval -textvariable status_ne\n",\ +"label .statbar.selslabel -text \" Surf Elements: \"\n",\ +"label .statbar.selsval -textvariable status_nse\n",\ +"label .statbar.task -textvariable status_task\n",\ +"\n",\ +"pack .statbar.ptslabel .statbar.ptsval -side left -ipady 3p \n",\ +"pack .statbar.elslabel .statbar.elsval -side left -ipady 3p \n",\ +"pack .statbar.selslabel .statbar.selsval -side left -ipady 3p\n",\ +"\n",\ +"\n",\ +"\n",\ +"tixMeter .statbar.per -value 0 -text 0%\n",\ +".statbar.per configure -fillcolor blue\n",\ +"\n",\ +"pack .statbar.per -side right\n",\ +"pack .statbar.task -side right -ipady 4\n",\ +"\n",\ +"set qualbaraxis(0) 0\n",\ +"set qualbar(0) 0\n",\ +"set qualbarnull(0) 0\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc timer2 { } {\n",\ +" global status_np\n",\ +" global status_ne\n",\ +" global status_nse\n",\ +" global multithread_running\n",\ +" global multithread_redraw\n",\ +" global status_working\n",\ +" global status_task\n",\ +" global status_percent\n",\ +" global status_tetqualclasses\n",\ +" \n",\ +"\n",\ +" Ng_ReadStatus \n",\ +"\n",\ +" if { $multithread_redraw == 1 } {\n",\ +" set multithread_redraw 0;\n",\ +" redraw;\n",\ +" \n",\ +" global videoactive\n",\ +" if { $videoactive == 1 } {\n",\ +" puts \"addframe\"\n",\ +" .ndraw Ng_VideoClip addframe\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" global mem_moveable\n",\ +" set mem_moveable [Ng_MemInfo moveable]\n",\ +"\n",\ +"\n",\ +" .statbar.per config -value [expr $status_percent/100] -text [format %2.1f [expr 0.1*int(10*$status_percent)]]%\n",\ +"\n",\ +"\n",\ +" if { $multithread_running } {\n",\ +" pack .statbar.per -side right -before .statbar.task -padx 6\n",\ +" } { \n",\ +" pack forget .statbar.per\n",\ +" }\n",\ +" \n",\ +"\n",\ +"\n",\ +" if {[winfo exists .qualityview_dlg] == 1} {\n",\ +" \n",\ +" global qualbar\n",\ +" global qualbarnull\n",\ +" global qualbaraxis\n",\ +"\n",\ +" set maxval 0\n",\ +" for {set i 0} {$i < 20} {incr i} {\n",\ +" if {[lindex $status_tetqualclasses $i] > $maxval} {\n",\ +" set maxval [lindex $status_tetqualclasses $i]\n",\ +" }\n",\ +" } \n",\ +"\n",\ +" set ubound 1\n",\ +" while { $ubound < $maxval } {\n",\ +" set ubound [expr {10 * $ubound}]\n",\ +" }\n",\ +" if { $ubound/5 > $maxval } {\n",\ +" set ubound [expr $ubound/5]\n",\ +" }\n",\ +" if { $ubound/2 > $maxval } {\n",\ +" set ubound [expr $ubound/2]\n",\ +" }\n",\ +"\n",\ +"\n",\ +" \n",\ +" for {set i 1} {$i <= 5} {incr i} {\n",\ +" \n",\ +" set value [expr { $i * $ubound / 5 }]\n",\ +" .qualityview_dlg.c dchars $qualbaraxis($i) 0 end\n",\ +" .qualityview_dlg.c insert $qualbaraxis($i) end $value \n",\ +" }\n",\ +"\n",\ +" \n",\ +" for {set i 0} {$i < 20} {incr i} {\n",\ +" set x1 [expr {100 + ($i*15) + 2}]\n",\ +" set x2 [expr {$x1+10}]\n",\ +" \n",\ +" set nbrs [lindex $status_tetqualclasses $i]\n",\ +" set y [expr (249 - (200 * $nbrs / $ubound ) )]\n",\ +" \n",\ +" .qualityview_dlg.c coords $qualbar($i) $x1 250 $x2 $y\n",\ +"\n",\ +" if { $nbrs == 0 } {\n",\ +" .qualityview_dlg.c itemconfigure $qualbarnull($i) -text 0\n",\ +" } {\n",\ +" .qualityview_dlg.c itemconfigure $qualbarnull($i) -text \"\" \n",\ +" } \n",\ +" }\n",\ +" \n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" if {[winfo exists .memuse_dlg] == 1} { \n",\ +" \n",\ +" global memmark\n",\ +" set usemb [Ng_MemInfo usedmb]\n",\ +" for {set i 0} {$i < [string length $usemb] } {incr i} {\n",\ +" if { [string index $usemb $i] == 0 } {\n",\ +" .memuse_dlg.c coords $memmark($i) [expr 50+$i] 68 [expr 50+$i] 70\n",\ +" } {\n",\ +" .memuse_dlg.c coords $memmark($i) [expr 50+$i] 50 [expr 50+$i] 70\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" after 200 { timer2 }\n",\ +"}\n",\ +"timer2\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc bgerror { error } {\n",\ +" global errorInfo userlevel\n",\ +" if { $userlevel == 3} {\n",\ +" puts \"ERROR: $error\" \n",\ +" puts \"errinfo: $errorInfo\"\n",\ +" }\n",\ +" tk_messageBox -title \"Error Message\" -message $error -type ok \n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc smh2 { menuitem } {\n",\ +" if {[catch {$menuitem entrycget active -label} name]} {\n",\ +" set name \" \"\n",\ +" } \n",\ +" show_menu_help $name \n",\ +" update idletasks\n",\ +"}\n",\ +"\n",\ +"bind .ngmenu <> { smh2 %W }\n",\ +"bind .ngmenu.file <> { smh2 %W }\n",\ +"bind .ngmenu.geometry <> { smh2 %W }\n",\ +"bind .ngmenu.mesh <> { smh2 %W }\n",\ +"bind .ngmenu.view <> { smh2 %W }\n",\ +"bind .ngmenu.meshsize <> { smh2 %W }\n",\ +"bind .ngmenu.special <> { smh2 %W }\n",\ +"bind .ngmenu.help <> { smh2 %W }\n",\ +"\n",\ +"\n",\ +"bind . { .ngmenu.file invoke \"Quit\" }\n",\ +"bind . { .ngmenu.file invoke \"Load Geometry...\" } ; \n",\ +"bind . { .ngmenu.file invoke \"Load Mesh...\" } ;\n",\ +"bind . { .ngmenu.file invoke \"Save Mesh...\" } ;\n",\ +"bind . { .ngmenu.file activate \"Recent Files\" } ;\n",\ +"bind .

{ newprimitivedialog } ; bind .

{ editprimitivedialog }\n",\ +"bind . { newsoliddialog }\n",\ +"bind . { .ngmenu.mesh invoke \"Generate Mesh\" } ;\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc meshingoptionsdialog { } {\n",\ +"\n",\ +" set w .options_dlg\n",\ +" \n",\ +" if {[winfo exists .options_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +"\n",\ +"\n",\ +" tixNoteBook $w.nb -ipadx 6 -ipady 6\n",\ +" \n",\ +" $w.nb add general -label \"General\" -underline 0\n",\ +" $w.nb add meshsize -label \"Mesh Size\" -underline 0\n",\ +" $w.nb add chartopt -label \"STL Charts\" -underline 0\n",\ +" $w.nb add optimizer -label \"Optimizer\" -underline 0\n",\ +" $w.nb add insider -label \"Insider\" -underline 0\n",\ +" $w.nb add debug -label \"Debug\" -underline 0\n",\ +"\n",\ +"\n",\ +" pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top \n",\ +"\n",\ +"\n",\ +" \n",\ +" set f [$w.nb subwidget general]\n",\ +"\n",\ +" set finevals { 1 2 3 4 5 6 }\n",\ +" set finelabs(1) \"very coarse\" \n",\ +" set finelabs(2) \"coarse\" \n",\ +" set finelabs(3) \"moderate\" \n",\ +" set finelabs(4) \"fine\" \n",\ +" set finelabs(5) \"very fine\" \n",\ +" set finelabs(6) \"user defined\"\n",\ +"\n",\ +" tixOptionMenu $f.fine -label \"Mesh granularity : \" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +"\n",\ +"\n",\ +" foreach finev $finevals {\n",\ +" $f.fine add command $finev -label $finelabs($finev)\n",\ +" }\n",\ +" $f.fine config -variable meshoptions.fineness\n",\ +" $f.fine config -command { setgranularity }\n",\ +" global meshoptions.fineness\n",\ +" pack $f.fine\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +" set mgsteps { ag me ms os mv ov }\n",\ +" set mgsteplabel(ag) \"Analyze Geometry\"\n",\ +" set mgsteplabel(me) \"Mesh Edges\"\n",\ +" set mgsteplabel(ms) \"Mesh Surface\"\n",\ +" set mgsteplabel(os) \"Optimize Surface\"\n",\ +" set mgsteplabel(mv) \"Mesh Volume\"\n",\ +" set mgsteplabel(ov) \"Optimize Volume\"\n",\ +"\n",\ +" \n",\ +" tixOptionMenu $f.first -label \"First Step : \" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +"\n",\ +" tixOptionMenu $f.last -label \"Last Step : \" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +"\n",\ +" foreach step $mgsteps {\n",\ +" $f.first add command $step -label $mgsteplabel($step)\n",\ +" $f.last add command $step -label $mgsteplabel($step)\n",\ +" }\n",\ +"\n",\ +" $f.first config -variable meshoptions.firststep \n",\ +" $f.last config -variable meshoptions.laststep \n",\ +"\n",\ +" pack $f.first $f.last\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set msg(0) \"None\"\n",\ +" set msg(1) \"Least\"\n",\ +" set msg(2) \"Little\"\n",\ +" set msg(3) \"Moderate\"\n",\ +" set msg(4) \"Much\"\n",\ +" set msg(5) \"Most\"\n",\ +" \n",\ +" tixOptionMenu $f.msg -label \"Print Messages : \" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +"\n",\ +" foreach step {0 1 2 3 4 5 } {\n",\ +" $f.msg add command $step -label $msg($step)\n",\ +" }\n",\ +"\n",\ +" $f.msg config -variable options.printmsg \n",\ +" pack $f.msg\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +" checkbutton $f.parthread -text \"Parallel meshing thread\" \\\n",\ +" -variable options.parthread\n",\ +" checkbutton $f.second -text \"Second order elements\" \\\n",\ +" -variable options.secondorder\n",\ +" checkbutton $f.quad -text \"Quad dominated\" \\\n",\ +" -variable options.quad -command {\n",\ +" if { ${options.quad} } {\n",\ +" set meshoptions.laststep os\n",\ +" }\n",\ +" }\n",\ +" checkbutton $f.invtets -text \"Invert volume elements\" \\\n",\ +" -variable options.inverttets\n",\ +" checkbutton $f.invtrigs -text \"Invert surface elements\" \\\n",\ +" -variable options.inverttrigs\n",\ +" checkbutton $f.azref -text \"Automatic Z-refinement\" \\\n",\ +" -variable options.autozrefine\n",\ +"\n",\ +" pack $f.parthread $f.second $f.quad $f.invtets $f.invtrigs $f.azref \n",\ +"\n",\ +"\n",\ +"\n",\ +" tixControl $f.elementorder -label \"Element order: \" -integer true \\\n",\ +" -variable options.elementorder -min 1 -max 20 \\\n",\ +" -options {\n",\ +" entry.width 2\n",\ +" label.width 20\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" pack $f.elementorder\n",\ +"\n",\ +"\n",\ +" tixControl $f.memory -label \"Large Memory \\[MB\\]: \" -integer true \\\n",\ +" -variable options.memory -min 0 -max 2000 \\\n",\ +" -options {\n",\ +" entry.width 5\n",\ +" label.width 20\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" global userlevel\n",\ +" if { $userlevel >= 3} { pack $f.memory }\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget meshsize]\n",\ +"\n",\ +" tixControl $f.meshsize -label \"max mesh-size: \" -integer false \\\n",\ +" -variable options.meshsize -min 1e-9 -max 1e6 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" tixControl $f.minmeshsize -label \"min mesh-size: \" -integer false \\\n",\ +" -variable options.minmeshsize -min 0 -max 1e6 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" tixControl $f.grading -label \"mesh-size grading: \" -integer false \\\n",\ +" -variable options.grading -min 0.1 -max 1 -step 0.1 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +" \n",\ +" pack $f.meshsize $f.minmeshsize $f.grading\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $f.msf \n",\ +" pack $f.msf\n",\ +"\n",\ +" tixLabelEntry $f.msf.ent -label \"mesh-size file: \" \\\n",\ +" -labelside top \\\n",\ +" -options { \n",\ +" entry.textVariable options.meshsizefilename \n",\ +" entry.width 35\n",\ +" label.width 25\n",\ +" label.anchor w\n",\ +" } \n",\ +" button $f.msf.btn -text \"Browse\" -command {\n",\ +" global options.meshsizefilename\n",\ +" set types {\n",\ +" {\"Meshsize file\" {.msz} } }\n",\ +" set options.meshsizefilename [tk_getOpenFile -filetypes $types -initialfile ${options.meshsizefilename}]\n",\ +" }\n",\ +"\n",\ +" pack $f.msf.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4\n",\ +" pack $f.msf.btn -side left -anchor s -padx 4 -pady 4\n",\ +"\n",\ +"\n",\ +" label $f.lab -text \"Additional mesh size restrictions:\"\n",\ +"\n",\ +" \n",\ +" frame $f.csg -relief groove -borderwidth 3\n",\ +" pack $f.csg -fill x\n",\ +"\n",\ +"\n",\ +" frame $f.csg.curv\n",\ +" pack $f.csg.curv -anchor w\n",\ +"\n",\ +" scale $f.csg.curv.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable options.curvaturesafety\n",\ +" label $f.csg.curv.la -text \"Elements per curvature radius\"\n",\ +" pack $f.csg.curv.sc $f.csg.curv.la -side left \n",\ +"\n",\ +" frame $f.csg.elen\n",\ +" pack $f.csg.elen -anchor w\n",\ +" scale $f.csg.elen.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable options.segmentsperedge\n",\ +" label $f.csg.elen.la -text \"Elements per edge\"\n",\ +" pack $f.csg.elen.sc $f.csg.elen.la -side left\n",\ +" \n",\ +"\n",\ +" \n",\ +" frame $f.stl -relief groove -borderwidth 3\n",\ +" pack $f.stl -fill x\n",\ +"\n",\ +" frame $f.stl.r2\n",\ +" pack $f.stl.r2 -anchor w\n",\ +" scale $f.stl.r2.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable stloptions.resthchartdistfac\n",\ +" checkbutton $f.stl.r2.bu -text \"STL - chart distance\" \\\n",\ +" -variable stloptions.resthchartdistenable\n",\ +" pack $f.stl.r2.sc $f.stl.r2.bu -side left\n",\ +" \n",\ +" frame $f.stl.r6\n",\ +" pack $f.stl.r6 -anchor w\n",\ +" scale $f.stl.r6.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable stloptions.resthlinelengthfac\n",\ +" checkbutton $f.stl.r6.bu -text \"STL - line length\" \\\n",\ +" -variable stloptions.resthlinelengthenable\n",\ +" pack $f.stl.r6.sc $f.stl.r6.bu -side left\n",\ +" \n",\ +" frame $f.stl.r3\n",\ +" pack $f.stl.r3 -anchor w\n",\ +" scale $f.stl.r3.sc -orient horizontal -length 200 -from 0.2 -to 8 \\\n",\ +" -resolution 0.1 -variable stloptions.resthcloseedgefac\n",\ +" checkbutton $f.stl.r3.bu -text \"STL/IGES/STEP - close edges\" \\\n",\ +" -variable stloptions.resthcloseedgeenable\n",\ +" pack $f.stl.r3.sc $f.stl.r3.bu -side left\n",\ +" \n",\ +" frame $f.stl.r1\n",\ +" pack $f.stl.r1 -anchor w\n",\ +" scale $f.stl.r1.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable stloptions.resthsurfcurvfac\n",\ +" checkbutton $f.stl.r1.bu -text \"STL - surface curvature\" \\\n",\ +" -variable stloptions.resthsurfcurvenable\n",\ +" pack $f.stl.r1.sc $f.stl.r1.bu -side left\n",\ +"\n",\ +" frame $f.stl.r3b\n",\ +" pack $f.stl.r3b -anchor w\n",\ +" scale $f.stl.r3b.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable stloptions.resthedgeanglefac\n",\ +" checkbutton $f.stl.r3b.bu -text \"STL - edge angle\" \\\n",\ +" -variable stloptions.resthedgeangleenable\n",\ +" pack $f.stl.r3b.sc $f.stl.r3b.bu -side left\n",\ +" \n",\ +" frame $f.stl.r5\n",\ +" pack $f.stl.r5 -anchor w\n",\ +" scale $f.stl.r5.sc -orient horizontal -length 200 -from 0.2 -to 5 \\\n",\ +" -resolution 0.1 -variable stloptions.resthsurfmeshcurvfac\n",\ +" checkbutton $f.stl.r5.bu -text \"STL - surface mesh curv\" \\\n",\ +" -variable stloptions.resthsurfmeshcurvenable\n",\ +" pack $f.stl.r5.sc $f.stl.r5.bu -side left\n",\ +" \n",\ +" \n",\ +" checkbutton $f.stl.recalch -text \"STL - Recalc mesh size for surface optimization\" \\\n",\ +" -variable stloptions.recalchopt\n",\ +" pack $f.stl.recalch\n",\ +"\n",\ +" button $f.stl.calch -text \"Calc New H\" -command { redraw; Ng_STLCalcLocalH }\n",\ +" pack $f.stl.calch\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget chartopt]\n",\ +"\n",\ +"\n",\ +" label $f.lab1 -text \"Yellow Edges Angle ()\"\n",\ +" scale $f.scale1 -orient horizontal -length 300 \\\n",\ +" -from 0 -to 90 -resolution 1 -tickinterval 10 \\\n",\ +" -variable stloptions.yangle \n",\ +"\n",\ +" pack $f.lab1 $f.scale1\n",\ +"\n",\ +" label $f.lab2e -text \"Edge Corner Angle ()\"\n",\ +" scale $f.scale2e -orient horizontal -length 360 -from 0 -to 180 \\\n",\ +" -resolution 1 -tickinterval 20 \\\n",\ +" -variable stloptions.edgecornerangle \n",\ +" pack $f.lab2e $f.scale2e\n",\ +" \n",\ +" label $f.lab2 -text \"Chart Angle ()\"\n",\ +" scale $f.scale2 -orient horizontal -length 360 -from 0 -to 180 \\\n",\ +" -resolution 1 -tickinterval 20 \\\n",\ +" -variable stloptions.chartangle \n",\ +" pack $f.lab2 $f.scale2\n",\ +" \n",\ +" label $f.lab2b -text \"Outer Chart Angle ()\"\n",\ +" scale $f.scale2b -orient horizontal -length 360 -from 0 -to 180 \\\n",\ +" -resolution 1 -tickinterval 20 \\\n",\ +" -variable stloptions.outerchartangle \n",\ +" pack $f.lab2b $f.scale2b\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +" set f [$w.nb subwidget optimizer]\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +" tixControl $f.os2d -label \"Surface opt steps: \" -integer true \\\n",\ +" -variable options.optsteps2d -min 0 -max 99 -step 1 \\\n",\ +" -options {\n",\ +" entry.width 3\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" tixControl $f.os3d -label \"Volume opt steps: \" -integer true \\\n",\ +" -variable options.optsteps3d -min 0 -max 99 -step 1 \\\n",\ +" -options {\n",\ +" entry.width 3\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +" \n",\ +" tixControl $f.elw -label \"Element size weight: \" -integer false \\\n",\ +" -variable options.elsizeweight -min 0 -max 1 -step 0.1 \\\n",\ +" -options {\n",\ +" entry.width 3\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" tixControl $f.wem -label \"Worst element measure: \" -integer false \\\n",\ +" -variable options.opterrpow -min 1 -max 10 -step 1 \\\n",\ +" -options {\n",\ +" entry.width 3\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" pack $f.os2d $f.os3d $f.elw $f.wem\n",\ +" \n",\ +" frame $f.badellimit\n",\ +" pack $f.badellimit -fill x\n",\ +" label $f.badellimit.lab -text \"bad element criterion\";\n",\ +" scale $f.badellimit.scale -orient horizontal -length 150 \\\n",\ +" -from 160 -to 180 -resolution 1 \\\n",\ +" -variable options.badellimit\n",\ +" pack $f.badellimit.scale $f.badellimit.lab -side right -anchor s\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget insider]\n",\ +" \n",\ +"\n",\ +"\n",\ +" checkbutton $f.localh -text \"Use Local Meshsize\" \\\n",\ +" -variable options.localh\n",\ +" checkbutton $f.delauney -text \"Use Delaunay\" \\\n",\ +" -variable options.delaunay\n",\ +" checkbutton $f.checkoverlap -text \"Check Overlapping\" \\\n",\ +" -variable options.checkoverlap\n",\ +" checkbutton $f.checkcb -text \"Check Chart Boundary\" \\\n",\ +" -variable options.checkchartboundary\n",\ +" checkbutton $f.blockfill -text \"Do Blockfilling\" \\\n",\ +" -variable options.blockfill\n",\ +"\n",\ +" pack $f.localh $f.delauney $f.checkoverlap $f.blockfill $f.checkcb -anchor w\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +" set f [$w.nb subwidget debug]\n",\ +"\n",\ +" frame $f.cb\n",\ +" pack $f.cb -side top\n",\ +"\n",\ +" \n",\ +"\n",\ +" checkbutton $f.cb.slowchecks -text \"Slow checks\" \\\n",\ +" -variable debug.slowchecks -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.debugoutput -text \"Debugging outout\" \\\n",\ +" -variable debug.debugoutput -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltexline -text \"Halt on exising line\" \\\n",\ +" -variable debug.haltexistingline -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltoverlap -text \"Halt on Overlap\" \\\n",\ +" -variable debug.haltoverlap -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltsuc -text \"Halt on success\" \\\n",\ +" -variable debug.haltsuccess -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltnosuc -text \"Halt on no success\" \\\n",\ +" -variable debug.haltnosuccess -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltlargequal -text \"Halt on large quality class\" \\\n",\ +" -variable debug.haltlargequalclass -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltseg -text \"Halt on Segment:\" \\\n",\ +" -variable debug.haltsegment -command { Ng_SetDebugParameters }\n",\ +" checkbutton $f.cb.haltnode -text \"Halt on Node:\" \\\n",\ +" -variable debug.haltnode -command { Ng_SetDebugParameters }\n",\ +"\n",\ +"\n",\ +" pack $f.cb.slowchecks $f.cb.debugoutput $f.cb.haltexline $f.cb.haltoverlap $f.cb.haltsuc $f.cb.haltnosuc $f.cb.haltlargequal $f.cb.haltseg $f.cb.haltnode \n",\ +"\n",\ +" frame $f.cb.hf\n",\ +" pack $f.cb.hf -pady 5\n",\ +" checkbutton $f.cb.hf.cb -text \"Halt on Face:\" \\\n",\ +" -variable debug.haltface -command { Ng_SetDebugParameters }\n",\ +" entry $f.cb.hf.ent -textvariable debug.haltfacenr -width 5 \n",\ +" pack $f.cb.hf.cb $f.cb.hf.ent -side left \n",\ +"\n",\ +" checkbutton $f.cb.showactivechart -text \"Show Active Meshing-Chart\" \\\n",\ +" -variable stloptions.showactivechart -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" pack $f.cb.showactivechart\n",\ +" \n",\ +"\n",\ +" frame $f.segs\n",\ +" pack $f.segs -pady 5\n",\ +" label $f.segs.lab1 -text \"P1:\";\n",\ +" entry $f.segs.ent1 -width 8 -relief sunken \\\n",\ +" -textvariable debug.haltsegmentp1 \n",\ +" label $f.segs.lab2 -text \"P2:\";\n",\ +" entry $f.segs.ent2 -width 8 -relief sunken \\\n",\ +" -textvariable debug.haltsegmentp2 \n",\ +" pack $f.segs.lab1 $f.segs.ent1 $f.segs.lab2 $f.segs.ent2 -side left\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $f.cont -relief groove -borderwidth 3\n",\ +" pack $f.cont \n",\ +" \n",\ +" checkbutton $f.cont.multidrawing -text \"Draw Meshing\" \\\n",\ +" -variable multithread_drawing \n",\ +" pack $f.cont.multidrawing\n",\ +" \n",\ +" checkbutton $f.cont.multitestmode -text \"Meshing Testmode\" \\\n",\ +" -variable multithread_testmode \n",\ +" pack $f.cont.multitestmode\n",\ +" \n",\ +" button $f.cont.goon -text \"Go On\" -command { set multithread_pause 0 }\n",\ +" pack $f.cont.multidrawing $f.cont.multitestmode $f.cont.goon -side left -expand yes\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +" global userlevel\n",\ +" if { $userlevel < 3} {\n",\ +" $w.nb delete insider\n",\ +" $w.nb delete debug\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +" \n",\ +" \n",\ +" \n",\ +"\n",\ +" \n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +" button $w.bu.apl -text \"Apply\" -command { \n",\ +" [.options_dlg.nb subwidget meshsize].meshsize invoke\n",\ +" [.options_dlg.nb subwidget meshsize].grading invoke\n",\ +" [.options_dlg.nb subwidget optimizer].os2d invoke\n",\ +" [.options_dlg.nb subwidget optimizer].os3d invoke\n",\ +" [.options_dlg.nb subwidget optimizer].elw invoke\n",\ +" [.options_dlg.nb subwidget optimizer].wem invoke\n",\ +"\n",\ +" Ng_SetMeshingParameters \n",\ +" Ng_SetDebugParameters\n",\ +" }\n",\ +"\n",\ +" button $w.bu.ok -text \"Done\" -command {\n",\ +" [.options_dlg.nb subwidget meshsize].meshsize invoke\n",\ +" [.options_dlg.nb subwidget meshsize].grading invoke\n",\ +" [.options_dlg.nb subwidget optimizer].os2d invoke\n",\ +" [.options_dlg.nb subwidget optimizer].os3d invoke\n",\ +" [.options_dlg.nb subwidget optimizer].elw invoke\n",\ +" [.options_dlg.nb subwidget optimizer].wem invoke\n",\ +"\n",\ +" Ng_SetMeshingParameters\n",\ +" Ng_SetDebugParameters\n",\ +" wm withdraw .options_dlg\n",\ +" }\n",\ +"\n",\ +" pack $w.bu.apl $w.bu.ok -side left -expand yes\n",\ +" \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Meshing Options\"\n",\ +" focus .options_dlg\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"meshingoptionsdialog\n",\ +"wm withdraw .options_dlg\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc geometryoptionsdialog { } {\n",\ +"\n",\ +"\n",\ +" set w .geometry_dlg\n",\ +" \n",\ +" if {[winfo exists .geometry_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +" \n",\ +" global geooptions\n",\ +" \n",\ +" Ng_GeometryOptions get\n",\ +"\n",\ +" checkbutton $w.drawcsg -text \"Draw Geometry\" \\\n",\ +" -variable geooptions.drawcsg \n",\ +" pack $w.drawcsg\n",\ +"\n",\ +" frame $w.fac\n",\ +" pack $w.fac -pady 5\n",\ +" label $w.fac.lab -text \"Facets:\";\n",\ +" entry $w.fac.ent -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.facets\n",\ +" pack $w.fac.lab $w.fac.ent -side left\n",\ +" \n",\ +" \n",\ +" frame $w.det\n",\ +" pack $w.det -pady 5\n",\ +" label $w.det.lab -text \"Detail:\";\n",\ +" entry $w.det.ent -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.detail\n",\ +" pack $w.det.lab $w.det.ent -side left\n",\ +" \n",\ +" frame $w.cox\n",\ +" pack $w.cox -pady 5\n",\ +" label $w.cox.lab -text \"min/max x:\";\n",\ +" entry $w.cox.ent1 -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.minx\n",\ +" entry $w.cox.ent2 -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.maxx\n",\ +" pack $w.cox.lab $w.cox.ent1 \\\n",\ +" $w.cox.ent2 -side left\n",\ +" \n",\ +" frame $w.coy\n",\ +" pack $w.coy -pady 5\n",\ +" label $w.coy.lab -text \"min/max y:\";\n",\ +" entry $w.coy.ent1 -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.miny\n",\ +" entry $w.coy.ent2 -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.maxy\n",\ +" pack $w.coy.lab $w.coy.ent1 \\\n",\ +" $w.coy.ent2 -side left\n",\ +" \n",\ +" frame $w.coz\n",\ +" pack $w.coz -pady 5\n",\ +" label $w.coz.lab -text \"min/max z:\";\n",\ +" entry $w.coz.ent1 -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.minz\n",\ +" entry $w.coz.ent2 -width 8 -relief sunken \\\n",\ +" -textvariable geooptions.maxz\n",\ +" pack $w.coz.lab $w.coz.ent1 \\\n",\ +" $w.coz.ent2 -side left\n",\ +" \n",\ +"\n",\ +"\n",\ +" \n",\ +" \n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" button $w.bu.app -text \"Apply\" -command {\n",\ +" Ng_GeometryOptions set\n",\ +" }\n",\ +" button $w.bu.ok -text \"Done\" -command {\n",\ +" Ng_GeometryOptions set\n",\ +" destroy .geometry_dlg\n",\ +" }\n",\ +" pack $w.bu.app $w.bu.ok -side left -expand yes\n",\ +" \n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Geometry options\"\n",\ +" focus $w\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"proc viewingoptionsdialog { } {\n",\ +"\n",\ +" global userlevel\n",\ +"\n",\ +" set w .viewopts_dlg\n",\ +" \n",\ +" if {[winfo exists .viewopts_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +" tixNoteBook $w.nb -ipadx 6 -ipady 6\n",\ +" \n",\ +" $w.nb add general -label \"General\" -underline 0\n",\ +" $w.nb add stl -label \"STL\" -underline 0\n",\ +" $w.nb add occ -label \"IGES/STEP\" -underline 0\n",\ +" $w.nb add mesh -label \"Mesh\" -underline 0\n",\ +" $w.nb add light -label \"Light\" -underline 0\n",\ +" $w.nb add edges -label \"Edges\" -underline 0\n",\ +" $w.nb add misc -label \"Misc.\" -underline 3\n",\ +"\n",\ +"\n",\ +" pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget general]\n",\ +"\n",\ +" checkbutton $f.backcol -text \"White Background\" \\\n",\ +" -variable viewoptions.whitebackground \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.cross -text \"Draw Coordinate Cross\" \\\n",\ +" -variable viewoptions.drawcoordinatecross \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.color -text \"Draw Color-bar\" \\\n",\ +" -variable viewoptions.drawcolorbar \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.netgen -text \"Draw Netgen-logo\" \\\n",\ +" -variable viewoptions.drawnetgenlogo \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" pack $f.backcol $f.cross $f.color $f.netgen\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget stl]\n",\ +"\n",\ +" frame $f.show -relief groove -borderwidth 3\n",\ +" pack $f.show\n",\ +" checkbutton $f.show.showtrias -text \"Show STL-Triangles\" \\\n",\ +" -variable stloptions.showtrias -command { Ng_SetVisParameters; redraw }\n",\ +" pack $f.show.showtrias -anchor w\n",\ +" \n",\ +" checkbutton $f.show.showfilledtrias -text \"Show Filled Triangles\" \\\n",\ +" -variable stloptions.showfilledtrias -command { Ng_SetVisParameters; redraw }\n",\ +" pack $f.show.showfilledtrias -anchor w\n",\ +" \n",\ +" checkbutton $f.show.showactivechart -text \"Show Active Meshing-Chart\" \\\n",\ +" -variable stloptions.showactivechart -command { Ng_SetVisParameters; redraw }\n",\ +" pack $f.show.showactivechart -anchor w\n",\ +" \n",\ +" checkbutton $f.show.showedges -text \"Show Edges\" \\\n",\ +" -variable stloptions.showedges -command { Ng_SetVisParameters; redraw }\n",\ +" pack $f.show.showedges -anchor w\n",\ +" \n",\ +" frame $f.special -relief groove -borderwidth 3\n",\ +" pack $f.special\n",\ +" checkbutton $f.special.showmarktrias -text \"Show Chart Triangles\" \\\n",\ +" -variable stloptions.showmarktrias \\\n",\ +" -command {set stldoctor.showfaces 0; Ng_STLDoctor; Ng_SetVisParameters; redraw }\n",\ +" pack $f.special.showmarktrias -side left\n",\ +"\n",\ +" checkbutton $f.special.showfaces -text \"Show Faces\" \\\n",\ +" -variable stldoctor.showfaces \\\n",\ +" -command {set stloptions.showmarktrias 0; Ng_STLDoctor; Ng_SetVisParameters; redraw} \n",\ +" pack $f.special.showfaces -side left\n",\ +"\n",\ +" frame $f.fn -relief groove -borderwidth 3\n",\ +" pack $f.fn\n",\ +" label $f.fn.lab3 -text \"Chart/Face number:\"\n",\ +" scale $f.fn.scale3 -orient horizontal -length 200 -from 0 -to 200 \\\n",\ +" -resolution 1 -tickinterval 50 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable stloptions.chartnumber \n",\ +" pack $f.fn.lab3 $f.fn.scale3 -side left\n",\ +" \n",\ +" frame $f.fo -relief groove -borderwidth 3\n",\ +" pack $f.fo\n",\ +" label $f.fo.lab -text \"Chart/Face Offset:\";\n",\ +" entry $f.fo.ent -width 5 -relief sunken \\\n",\ +" -textvariable stloptions.chartnumberoffset\n",\ +" pack $f.fo.lab $f.fo.ent -side left\n",\ +"\n",\ +" frame $f.mt\n",\ +" pack $f.mt -fill x\n",\ +" checkbutton $f.mt.bu -text \"Show Marked (Dirty) Triangles\" \\\n",\ +" -variable stldoctor.showmarkedtrigs \\\n",\ +" -command {Ng_STLDoctor; redraw} \n",\ +" pack $f.mt.bu\n",\ +"\n",\ +" frame $f.ep\n",\ +" pack $f.ep -fill x\n",\ +" checkbutton $f.ep.bu -text \"show edge corner points\" \\\n",\ +" -variable stldoctor.showedgecornerpoints \\\n",\ +" -command {Ng_STLDoctor; redraw} \n",\ +" pack $f.ep.bu\n",\ +"\n",\ +" frame $f.stt\n",\ +" pack $f.stt -fill x\n",\ +" checkbutton $f.stt.bu -text \"show touched triangle chart\" \\\n",\ +" -variable stldoctor.showtouchedtrigchart \\\n",\ +" -command {set stldoctor.showfaces 0; set stloptions.showmarktrias 1; \\\n",\ +" Ng_STLDoctor; Ng_SetVisParameters; redraw} \n",\ +" pack $f.stt.bu\n",\ +"\n",\ +" frame $f.sml\n",\ +" pack $f.sml -fill x\n",\ +" checkbutton $f.sml.bu -text \"draw meshed edges\" \\\n",\ +" -variable stldoctor.drawmeshededges \\\n",\ +" -command {Ng_STLDoctor;} \n",\ +" pack $f.sml.bu\n",\ +" \n",\ +" \n",\ +" frame $f.sm\n",\ +" pack $f.sm -fill x\n",\ +" checkbutton $f.sm.bu -text \"select with mouse\" \\\n",\ +" -variable stldoctor.selectwithmouse\n",\ +" pack $f.sm.bu\n",\ +" \n",\ +" frame $f.st -relief groove -borderwidth 3\n",\ +" pack $f.st -fill x\n",\ +" label $f.st.lab -text \"Select triangle by number\";\n",\ +" entry $f.st.ent -width 5 -relief sunken \\\n",\ +" -textvariable stldoctor.selecttrig\n",\ +" pack $f.st.ent $f.st.lab -side left -expand yes\n",\ +" \n",\ +" frame $f.vc -relief groove -borderwidth 3\n",\ +" pack $f.vc -fill x\n",\ +" checkbutton $f.vc.bu -text \"show vicinity\" \\\n",\ +" -variable stldoctor.showvicinity \\\n",\ +" -command {Ng_STLDoctor vicinity; redraw}\n",\ +" label $f.vc.lab -text \"vicinity size\";\n",\ +" scale $f.vc.sc -orient horizontal -length 200 -from 0 -to 200 \\\n",\ +" -resolution 1 -variable stldoctor.vicinity \\\n",\ +" -command { Ng_STLDoctor vicinity; redraw }\n",\ +" pack $f.vc.bu $f.vc.lab $f.vc.sc -expand yes\n",\ +" \n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget occ]\n",\ +" \n",\ +" checkbutton $f.occshowsurfaces -text \"Show surfaces \" \\\n",\ +" -variable occoptions.showsurfaces \\\n",\ +" -command { Ng_SetOCCVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.occshowedges -text \"Show edges \" \\\n",\ +" -variable occoptions.showedges \\\n",\ +" -command { Ng_SetOCCVisParameters; redraw }\n",\ +"\n",\ +" frame $f.deflection -relief groove -borderwidth 3\n",\ +" pack $f.deflection -fill x\n",\ +" button $f.deflection.lab -text \"Rebuild visualization data\" \\\n",\ +" -command {\n",\ +" Ng_SetOCCVisParameters\n",\ +" Ng_OCCCommand buildvisualizationmesh\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +" tixControl $f.deflection.ent -label \"Visualization smoothness\" -integer false \\\n",\ +" -variable occoptions.deflection -min 0.1 -max 3 -step 0.1 \\\n",\ +" -options { entry.width 3 } \\\n",\ +" -command { Ng_SetOCCVisParameters }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" pack $f.deflection.ent $f.deflection.lab -side left -expand yes\n",\ +" pack $f.occshowsurfaces $f.occshowedges\n",\ +"\n",\ +"\n",\ +" \n",\ +" tixControl $f.showsolid -label \"Show solid (0 for all)\" -integer true \\\n",\ +" -variable occoptions.showsolidnr -min 0 -max 999 \\\n",\ +" -options { entry.width 3 } \\\n",\ +" -command { Ng_SetOCCVisParameters; redraw }\n",\ +" \n",\ +" tixControl $f.showsolid2 -label \"Show solid 2\" -integer true \\\n",\ +" -variable occoptions.showsolidnr2 -min 0 -max 999 \\\n",\ +" -options { entry.width 3 } \\\n",\ +" -command { Ng_SetOCCVisParameters; redraw }\n",\ +"\n",\ +" button $f.subtract -text \"Subtract (2 minus 1)\" \\\n",\ +" -command {\n",\ +" Ng_ACISCommand subtract ${occoptions.showsolidnr} ${occoptions.showsolidnr2}\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +" button $f.combine -text \"Combine all\" \\\n",\ +" -command {\n",\ +" Ng_ACISCommand combineall\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +" pack $f.showsolid $f.showsolid2 $f.subtract $f.combine\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget mesh]\n",\ +"\n",\ +" checkbutton $f.showcolor -text \"Colored Meshsize Visualization\" \\\n",\ +" -variable viewoptions.colormeshsize \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +"\n",\ +" checkbutton $f.showfilledtrigs -text \"Show filled triangles\" \\\n",\ +" -variable viewoptions.drawfilledtrigs \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" \n",\ +" checkbutton $f.showedges -text \"Show edges\" \\\n",\ +" -variable viewoptions.drawedges \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" \n",\ +"\n",\ +" checkbutton $f.showoutline -text \"Show Triangle Outline\" \\\n",\ +" -variable viewoptions.drawoutline \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" \n",\ +" tixControl $f.subdiv -label \"Subdivision\" -integer true \\\n",\ +" -variable visoptions.subdivisions -min 0 -max 8 \\\n",\ +" -options { entry.width 2 } \\\n",\ +" -command { puts \"mesh-subdivision\"; Ng_SetVisParameters; Ng_Vis_Set parameters; Ng_SetNextTimeStamp; redraw }\n",\ +" \n",\ +" \n",\ +" checkbutton $f.showbadels -text \"Show bad elements\" \\\n",\ +" -variable viewoptions.drawbadels \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +" checkbutton $f.showprisms -text \"Show prisms\" \\\n",\ +" -variable viewoptions.drawprisms \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.showpyramids -text \"Show pyramids\" \\\n",\ +" -variable viewoptions.drawpyramids \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.showhexes -text \"Show hexes\" \\\n",\ +" -variable viewoptions.drawhexes \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" frame $f.fshrink\n",\ +" label $f.fshrink.lab -text \"Shrink elements\"\n",\ +" scale $f.fshrink.scale -orient horizontal -length 200 -from 0 -to 1.0001 \\\n",\ +" -resolution 0.01 -tickinterval 0.25 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable viewoptions.shrink\n",\ +"\n",\ +"\n",\ +" checkbutton $f.showidentified -text \"Show identified points\" \\\n",\ +" -variable viewoptions.drawidentified \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.showmetispartition -text \"Show METIS Partition\" \\\n",\ +" -variable viewoptions.drawmetispartition \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" checkbutton $f.showpointnumbers -text \"Show Point-numbers\" \\\n",\ +" -variable viewoptions.drawpointnumbers \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.showedgenumbers -text \"Show Edge-numbers\" \\\n",\ +" -variable viewoptions.drawedgenumbers \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.showfacenumbers -text \"Show Face-numbers\" \\\n",\ +" -variable viewoptions.drawfacenumbers \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.showelementnumbers -text \"Show Element-numbers\" \\\n",\ +" -variable viewoptions.drawelementnumbers \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" \n",\ +" \n",\ +" tixControl $f.showdomain -label \"Show surface of domain\" -integer true \\\n",\ +" -variable viewoptions.drawdomainsurf -min 0 -max 50 \\\n",\ +" -options { entry.width 2 } \\\n",\ +" -command { Ng_SetVisParameters; Ng_Vis_Set parameters; redraw }\n",\ +" \n",\ +" \n",\ +" \n",\ +"\n",\ +" frame $f.center -relief groove -borderwidth 3\n",\ +" pack $f.center -fill x\n",\ +" button $f.center.lab -text \"Set Center Point\" \\\n",\ +" -command { Ng_SetVisParameters; Ng_Center; redraw }\n",\ +" entry $f.center.ent -width 5 -relief sunken \\\n",\ +" -textvariable viewoptions.centerpoint \n",\ +" pack $f.center.ent $f.center.lab -side left -expand yes\n",\ +" \n",\ +" frame $f.drawel -relief groove -borderwidth 3\n",\ +" pack $f.drawel -fill x\n",\ +" button $f.drawel.lab -text \"Draw Element\" \\\n",\ +" -command { Ng_SetVisParameters; Ng_ZoomAll; redraw }\n",\ +" entry $f.drawel.ent -width 5 -relief sunken \\\n",\ +" -textvariable viewoptions.drawelement \n",\ +" pack $f.drawel.ent $f.drawel.lab -side left -expand yes\n",\ +"\n",\ +" pack $f.showfilledtrigs\n",\ +" pack $f.showoutline $f.subdiv $f.showedges $f.showbadels \n",\ +" pack $f.showdomain \n",\ +" pack $f.showpointnumbers \n",\ +" pack $f.showedgenumbers $f.showfacenumbers $f.showelementnumbers \n",\ +" pack $f.showmetispartition\n",\ +"\n",\ +"\n",\ +" frame $f.frametets\n",\ +" checkbutton $f.frametets.showtets -text \"Show Tets in domain \" \\\n",\ +" -variable viewoptions.drawtets \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" tixControl $f.frametets.showtetsdomain -label \"\" -integer true \\\n",\ +" -variable viewoptions.drawtetsdomain -min 0 -max 500 \\\n",\ +" -options { entry.width 2 } \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" pack $f.frametets\n",\ +" pack $f.frametets.showtets $f.frametets.showtetsdomain -side left\n",\ +"\n",\ +"\n",\ +" pack $f.showcolor $f.showpyramids $f.showprisms $f.showhexes $f.showidentified\n",\ +" \n",\ +" pack $f.fshrink \n",\ +" pack $f.fshrink.lab $f.fshrink.scale -side left\n",\ +" \n",\ +" \n",\ +" \n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget light]\n",\ +" \n",\ +" label $f.lab1 -text \"Ambient Light\"\n",\ +" scale $f.scale1 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable viewoptions.light.amb \n",\ +" label $f.lab2 -text \"Diffuse Light\"\n",\ +" scale $f.scale2 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable viewoptions.light.diff \n",\ +" label $f.lab3 -text \"Specular Light\"\n",\ +" scale $f.scale3 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable viewoptions.light.spec \n",\ +" label $f.lab4 -text \"Material Shininess\"\n",\ +" scale $f.scale4 -orient horizontal -length 300 -from 0 -to 128 \\\n",\ +" -resolution 1 -tickinterval 32 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable viewoptions.mat.shininess \n",\ +" label $f.lab5 -text \"Material Transparency\"\n",\ +" scale $f.scale5 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_SetVisParameters; redraw } -variable viewoptions.mat.transp \n",\ +" \n",\ +" pack $f.lab1 $f.scale1 $f.lab2 $f.scale2 $f.lab3 $f.scale3 $f.lab4 $f.scale4 $f.lab5 $f.scale5\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget edges]\n",\ +"\n",\ +" checkbutton $f.showedges -text \"Show Edges\" \\\n",\ +" -variable viewoptions.drawededges \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.showpoints -text \"Show Points\" \\\n",\ +" -variable viewoptions.drawedpoints \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.showpointnrs -text \"Show Points Nrs\" \\\n",\ +" -variable viewoptions.drawedpointnrs \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.showtang -text \"Show CP Tangents\" \\\n",\ +" -variable viewoptions.drawedtangents \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" checkbutton $f.drawedgenrs -text \"Show Edge Nrs\" \\\n",\ +" -variable viewoptions.drawededgenrs \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" \n",\ +" pack $f.showedges $f.showpoints $f.showpointnrs $f.showtang $f.drawedgenrs\n",\ +"\n",\ +" frame $f.center -relief groove -borderwidth 3\n",\ +" pack $f.center -fill x\n",\ +" button $f.center.lab -text \"Set Center Point\" \\\n",\ +" -command { Ng_SetVisParameters; Ng_Center; redraw }\n",\ +" entry $f.center.ent -width 5 -relief sunken \\\n",\ +" -textvariable viewoptions.centerpoint \n",\ +" pack $f.center.ent $f.center.lab -side left -expand yes\n",\ +" \n",\ +"\n",\ +"\n",\ +" frame $f.f1\n",\ +" pack $f.f1 -pady 5\n",\ +" label $f.f1.lab -text \"SpecPoint Veclen\"\n",\ +" entry $f.f1.ent -width 5 -relief sunken -textvariable viewoptions.specpointvlen\n",\ +" pack $f.f1.lab $f.f1.ent\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$w.nb subwidget misc]\n",\ +"\n",\ +" frame $f.point -relief groove -borderwidth 3\n",\ +"\n",\ +" frame $f.point.dp\n",\ +" \n",\ +" checkbutton $f.point.dp.drawpoint -text \"Draw Point\" \\\n",\ +" -variable viewoptions.drawspecpoint \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" entry $f.point.dp.px -width 8 -relief sunken -textvariable viewoptions.specpointx\n",\ +" entry $f.point.dp.py -width 8 -relief sunken -textvariable viewoptions.specpointy\n",\ +" entry $f.point.dp.pz -width 8 -relief sunken -textvariable viewoptions.specpointz\n",\ +"\n",\ +" pack $f.point.dp.drawpoint $f.point.dp.px $f.point.dp.py $f.point.dp.pz -side left\n",\ +"\n",\ +" pack $f.point.dp\n",\ +"\n",\ +" checkbutton $f.point.center -text \"Use as Center\" \\\n",\ +" -variable viewoptions.usecentercoords \\\n",\ +" -command { \n",\ +" if { ${viewoptions.usecentercoords} } {\n",\ +" set viewoptions.centerx ${viewoptions.specpointx}\n",\ +" set viewoptions.centery ${viewoptions.specpointy}\n",\ +" set viewoptions.centerz ${viewoptions.specpointz}\n",\ +" Ng_SetVisParameters; Ng_Center\n",\ +" redraw\n",\ +" } {\n",\ +" Ng_SetVisParameters\n",\ +" }\n",\ +" \n",\ +" \n",\ +" }\n",\ +"\n",\ +" pack $f.point.center\n",\ +" \n",\ +" pack $f.point -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" \n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" button $w.bu.done -text \"Done\" -command {\n",\ +" Ng_SetVisParameters;\n",\ +" redraw\n",\ +" destroy .viewopts_dlg\n",\ +" }\n",\ +" button $w.bu.apply -text \"Apply\" -command {\n",\ +" Ng_SetVisParameters;\n",\ +" redraw\n",\ +" }\n",\ +" pack $w.bu.apply $w.bu.done -expand yes -side left\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Viewing options\"\n",\ +" focus $w\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set clippingdialog_pop1 0\n",\ +"set clippingdialog_pop2 0\n",\ +"set clippingdialog_pop3 0\n",\ +"set clippingdialog_pop4 0\n",\ +"\n",\ +"\n",\ +"proc clippingdialog { } {\n",\ +"\n",\ +" global clippingdialog_pop1\n",\ +" global clippingdialog_pop2\n",\ +" global clippingdialog_pop3\n",\ +" global clippingdialog_pop4\n",\ +" set clippingdialog_pop1 1\n",\ +" set clippingdialog_pop2 1\n",\ +" set clippingdialog_pop3 1\n",\ +" set clippingdialog_pop4 1\n",\ +" \n",\ +" set w .clipping_dlg\n",\ +" \n",\ +" if {[winfo exists .clipping_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +"\n",\ +" label $w.lab1 -text \"Normal x\"\n",\ +" scale $w.scale1 -orient horizontal -length 300 -from -1 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.5 \\\n",\ +" -variable viewoptions.clipping.nx \\\n",\ +" -command { popupcheckredraw2 clippingdialog_pop1 ${viewoptions.clipping.enable} }\n",\ +"\n",\ +" \n",\ +" label $w.lab2 -text \"Normal y\"\n",\ +" scale $w.scale2 -orient horizontal -length 300 -from -1 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.5 \\\n",\ +" -variable viewoptions.clipping.ny \\\n",\ +" -command { popupcheckredraw2 clippingdialog_pop2 ${viewoptions.clipping.enable} }\n",\ +"\n",\ +" label $w.lab3 -text \"Normal z\"\n",\ +" scale $w.scale3 -orient horizontal -length 300 -from -1 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.5 \\\n",\ +" -variable viewoptions.clipping.nz \\\n",\ +" -command { popupcheckredraw2 clippingdialog_pop3 ${viewoptions.clipping.enable} }\n",\ +" label $w.lab4 -text \"Distance\"\n",\ +" scale $w.scale4 -orient horizontal -length 300 -from -1 -to 1.001 \\\n",\ +" -resolution 0.0001 -tickinterval 0.5 \\\n",\ +" -variable viewoptions.clipping.dist \\\n",\ +" -command { popupcheckredraw2 clippingdialog_pop4 ${viewoptions.clipping.enable} }\n",\ +" \n",\ +" \n",\ +" tixControl $w.clipdomain -label \"Clip only domain\" -integer true \\\n",\ +" -variable viewoptions.clipping.onlydomain -min 0 -max 50 \\\n",\ +" -options { entry.width 2 } \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" tixControl $w.donotclipdomain -label \"Do not clip domain\" -integer true \\\n",\ +" -variable viewoptions.clipping.notdomain -min 0 -max 50 \\\n",\ +" -options { entry.width 2 } \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" pack $w.lab1 $w.scale1 $w.lab2 $w.scale2 $w.lab3 $w.scale3 $w.lab4 $w.scale4 $w.clipdomain $w.donotclipdomain\n",\ +"\n",\ +" \n",\ +" checkbutton $w.cb1 -text \"Enable clipping\" \\\n",\ +" -variable viewoptions.clipping.enable \\\n",\ +" -command { Ng_SetVisParameters; redraw } \n",\ +" \n",\ +" pack $w.cb1\n",\ +" \n",\ +"\n",\ +" \n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +" button $w.bu.cancle -text \"Done\" -command \"destroy $w\"\n",\ +" pack $w.bu.cancle -expand yes\n",\ +" \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Clipping Plane\"\n",\ +" focus $w\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc refinementdialog { } {\n",\ +"\n",\ +" set w .refinement_dlg\n",\ +" \n",\ +" if {[winfo exists .refinement_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +"\n",\ +" \n",\ +" tixControl $w.meshsize -label \"max mesh-size: \" -integer false \\\n",\ +" -variable options.meshsize -min 1e-6 -max 1e6 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" pack $w.meshsize\n",\ +"\n",\ +" global localh\n",\ +" set localh 1\n",\ +" tixControl $w.loch -label \"local mesh-size: \" -integer false \\\n",\ +" -variable localh -min 1e-6 -max 1e6 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +" \n",\ +" pack $w.loch\n",\ +" \n",\ +" \n",\ +" button $w.restface -text \"Restrict H at face\" \\\n",\ +" -command {\n",\ +" .refinement_dlg.meshsize invoke\n",\ +" .refinement_dlg.loch invoke\n",\ +" Ng_RestrictH face $localh\n",\ +" }\n",\ +" button $w.restedge -text \"Restrict H at edge\" \\\n",\ +" -command {\n",\ +" .refinement_dlg.meshsize invoke\n",\ +" .refinement_dlg.loch invoke\n",\ +" Ng_RestrictH edge $localh\n",\ +" }\n",\ +" button $w.restelement -text \"Restrict H at element\" \\\n",\ +" -command {\n",\ +" .refinement_dlg.meshsize invoke\n",\ +" .refinement_dlg.loch invoke\n",\ +" Ng_RestrictH element $localh\n",\ +" }\n",\ +" button $w.restpoint -text \"Restrict H at point\" \\\n",\ +" -command {\n",\ +" .refinement_dlg.meshsize invoke\n",\ +" .refinement_dlg.loch invoke\n",\ +" Ng_RestrictH point $localh\n",\ +" }\n",\ +"\n",\ +"\n",\ +" pack $w.restface $w.restedge $w.restelement $w.restpoint\n",\ +"\n",\ +"\n",\ +"\n",\ +" button $w.anisoedge -text \"Declare Anisotropic edge\" \\\n",\ +" -command {\n",\ +" Ng_Anisotropy edge \n",\ +" }\n",\ +" pack $w.anisoedge\n",\ +" \n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" button $w.bu.cancle -text \"Done\" -command \"destroy .refinement_dlg\"\n",\ +" button $w.bu.refine -text \"Refine\" \\\n",\ +" -command { \n",\ +" set oldnp 0; set newnp $status_np; \n",\ +" while { $oldnp < $newnp } {\n",\ +" set level [expr $level+1]\n",\ +" Ng_Bisect; \n",\ +" Ng_HighOrder ${options.elementorder}\n",\ +" Ng_ReadStatus;\n",\ +" redraw; \n",\ +" set oldnp $newnp\n",\ +" set newnp $status_np\n",\ +" puts \"oldnp $oldnp newnp $newnp\"\n",\ +" }\n",\ +" } \n",\ +" button $w.bu.zrefine -text \"Z-Refine\" \\\n",\ +" -command { Ng_ZRefinement; Ng_ReadStatus; redraw; }\n",\ +" \n",\ +" pack $w.bu.zrefine $w.bu.refine $w.bu.cancle -expand yes -side left\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Select Refinement\"\n",\ +" focus $w\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc bcpropdialog { } {\n",\ +"\n",\ +" set w .bcprop_dlg\n",\ +" \n",\ +" if {[winfo exists .bcprop_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" frame $w.face -borderwidth 3\n",\ +" pack $w.face -fill x\n",\ +" label $w.face.lab -text \"face index:\"\n",\ +" label $w.face.ent -text 1 -padx 4\n",\ +" button $w.face.next -text \"next\" -command {\n",\ +" set w .bcprop_dlg; \n",\ +" set facenr [$w.face.ent cget -text]\n",\ +" if {$facenr == [Ng_BCProp getnfd]} {\n",\ +" set facenr 1 \n",\ +" } {\n",\ +" set facenr [expr $facenr + 1]\n",\ +" }\n",\ +" $w.face.ent configure -text $facenr\n",\ +" Ng_BCProp setactive $facenr\n",\ +" set bcnr [Ng_BCProp getbc $facenr]\n",\ +" $w.bc.ent delete 0 end\n",\ +" $w.bc.ent insert 0 $bcnr\n",\ +"\n",\ +" redraw\n",\ +" } \n",\ +" button $w.face.prev -text \"prev\" -command {\n",\ +" set w .bcprop_dlg; \n",\ +" set facenr [$w.face.ent cget -text]\n",\ +" if {$facenr == 1} {\n",\ +" set facenr [Ng_BCProp getnfd]\n",\ +" } {\n",\ +" set facenr [expr $facenr - 1]\n",\ +" }\n",\ +" $w.face.ent configure -text $facenr\n",\ +" Ng_BCProp setactive $facenr\n",\ +" set bcnr [Ng_BCProp getbc $facenr]\n",\ +" $w.bc.ent delete 0 end\n",\ +" $w.bc.ent insert 0 $bcnr\n",\ +"\n",\ +" redraw\n",\ +" } \n",\ +" \n",\ +" \n",\ +" pack $w.face.lab $w.face.ent $w.face.prev $w.face.next -side left \n",\ +" \n",\ +" frame $w.bc -borderwidth 3\n",\ +" pack $w.bc -fill x\n",\ +" label $w.bc.lab -text \"bc property:\"\n",\ +" entry $w.bc.ent -width 5 -relief sunken \n",\ +" button $w.bc.but -text \"change\" -command { \n",\ +" set w .bcprop_dlg; \n",\ +" Ng_BCProp setbc [$w.face.ent cget -text] [$w.bc.ent get]; \n",\ +" }\n",\ +" button $w.bc.but2 -text \"all\" -command { \n",\ +" set w .bcprop_dlg; \n",\ +" Ng_BCProp setall [$w.bc.ent get]; \n",\ +" }\n",\ +" pack $w.bc.lab $w.bc.ent $w.bc.but $w.bc.but2 -side left -expand yes\n",\ +"\n",\ +" frame $w.bcname -borderwidth 3\n",\ +" pack $w.bcname -fill x\n",\ +" label $w.bcname.lab -text \"bc name:\"\n",\ +" label $w.bcname.ent -text \"-\"\n",\ +" pack $w.bcname.lab $w.bcname.ent -side left -expand yes\n",\ +" \n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +" button $w.bu.close -text \"Close\" -command { destroy .bcprop_dlg }\n",\ +"\n",\ +" pack $w.bu.close -expand yes -side left\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Boundary Conditions\"\n",\ +" }\n",\ +"\n",\ +" focus $w \n",\ +"\n",\ +" set facenr [Ng_BCProp getactive]\n",\ +" $w.face.ent configure -text $facenr\n",\ +" \n",\ +" set bcnr [Ng_BCProp getbc $facenr]\n",\ +" $w.bc.ent delete 0 end\n",\ +" $w.bc.ent insert 0 $bcnr\n",\ +"\n",\ +" set bcname [Ng_BCProp getbcname $facenr]\n",\ +" $w.bcname.ent configure -text $bcname\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc METISdialog { } {\n",\ +"\n",\ +" set w .metis_dlg\n",\ +" set w.parts 64\n",\ +" \n",\ +" if {[winfo exists .metis_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" frame $w.a -borderwidth 0\n",\ +" frame $w.b -borderwidth 0\n",\ +" pack $w.a $w.b\n",\ +"\n",\ +" label $w.a.lab -text \"Number of partitions:\"\n",\ +" entry $w.a.ent -textvariable w.parts -width 4 -relief sunken\n",\ +"\n",\ +" button $w.b.start -text \"Start METIS\" -command { \n",\ +" Ng_Metis ${w.parts}\n",\ +" redraw\n",\ +" }\n",\ +" button $w.b.cancel -text \"Cancel\" -command { destroy .metis_dlg }\n",\ +" pack $w.a.lab $w.a.ent -side left -expand yes\n",\ +" pack $w.b.start $w.b.cancel -side left\n",\ +"\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"METIS Partitioning\"\n",\ +" focus $w\n",\ +" \n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc stloptionsdialog { } {\n",\ +"\n",\ +" set w .stlopts_dlg\n",\ +" \n",\ +" if {[winfo exists .stlopts_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" tixNoteBook $w.nb -ipadx 6 -ipady 6\n",\ +" \n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +" \n",\ +" \n",\ +" \n",\ +"\n",\ +" \n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" button $w.bu.apply -text \"Apply\" -command { redraw; Ng_GenerateMesh 1 2}\n",\ +" button $w.bu.cancle -text \"Done\" -command { destroy .stlopts_dlg }\n",\ +" pack $w.bu.cancle $w.bu.apply -side left -expand yes\n",\ +" \n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"STL Options\"\n",\ +" focus $w\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"proc stldoctordialog { } {\n",\ +"\n",\ +" set wd .stldoctor_dlg\n",\ +"\n",\ +" if {[winfo exists .stldoctor_dlg] == 1} {\n",\ +" wm withdraw $wd\n",\ +" wm deiconify $wd\n",\ +" focus $wd \n",\ +" } {\n",\ +" \n",\ +" toplevel $wd\n",\ +"\n",\ +" tixNoteBook $wd.nb -ipadx 6 -ipady 6\n",\ +" \n",\ +" $wd.nb add general -label \"General\" -underline 0\n",\ +" $wd.nb add topology -label \"Edit Topology\" -underline 5\n",\ +" $wd.nb add edges -label \"Edit Edges\" -underline 5\n",\ +" $wd.nb add normals -label \"Edit Normals\" -underline 5\n",\ +" $wd.nb add advanced -label \"Advanced\" -underline 0\n",\ +"\n",\ +"\n",\ +" pack $wd.nb -expand yes -fill both -padx 5 -pady 5 -side top \n",\ +"\n",\ +"\n",\ +" \n",\ +" set f [$wd.nb subwidget general]\n",\ +"\n",\ +"\n",\ +" frame $f.show\n",\ +" pack $f.show -fill x\n",\ +" checkbutton $f.show.showtrias -text \"Show STL-Triangles\" \\\n",\ +" -variable stloptions.showtrias -command { Ng_SetVisParameters; redraw }\n",\ +" pack $f.show.showtrias -anchor w\n",\ +" \n",\ +" checkbutton $f.show.showfilledtrias -text \"Show Filled Triangles\" \\\n",\ +" -variable stloptions.showfilledtrias -command { Ng_SetVisParameters; redraw }\n",\ +" pack $f.show.showfilledtrias -anchor w\n",\ +"\n",\ +" set selmodevals { 0 1 2 3 4 }\n",\ +" set selmodelabs(0) \"triangle\" \n",\ +" set selmodelabs(1) \"edge\" \n",\ +" set selmodelabs(2) \"point\" \n",\ +" set selmodelabs(3) \"line\" \n",\ +" set selmodelabs(4) \"line cluster\" \n",\ +"\n",\ +" tixOptionMenu $f.selmode -label \"Double Click selects :\" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +"\n",\ +" foreach selmodev $selmodevals {\n",\ +" $f.selmode add command $selmodev -label $selmodelabs($selmodev)\n",\ +" }\n",\ +" $f.selmode config -variable stldoctor.selectmode\n",\ +" $f.selmode config -command { Ng_STLDoctor }\n",\ +" global stldoctor.selectmode\n",\ +" pack $f.selmode\n",\ +"\n",\ +" frame $f.sm\n",\ +" pack $f.sm -fill x\n",\ +" checkbutton $f.sm.bu -text \"select with mouse\" \\\n",\ +" -variable stldoctor.selectwithmouse\n",\ +" pack $f.sm.bu \n",\ +"\n",\ +" frame $f.st -relief groove -borderwidth 3\n",\ +" pack $f.st -fill x\n",\ +" label $f.st.lab -text \"Select triangle by number\";\n",\ +" entry $f.st.ent -width 5 -relief sunken \\\n",\ +" -textvariable stldoctor.selecttrig\n",\ +" pack $f.st.ent $f.st.lab -side left -expand yes\n",\ +"\n",\ +" frame $f.vc -relief groove -borderwidth 3\n",\ +" pack $f.vc -fill x\n",\ +" checkbutton $f.vc.bu -text \"show vicinity\" \\\n",\ +" -variable stldoctor.showvicinity \\\n",\ +" -command {Ng_STLDoctor vicinity; redraw}\n",\ +" label $f.vc.lab -text \"vicinity size\";\n",\ +" scale $f.vc.sc -orient horizontal -length 200 -from 0 -to 200 \\\n",\ +" -resolution 1 -variable stldoctor.vicinity \\\n",\ +" -command { Ng_STLDoctor vicinity; redraw }\n",\ +" pack $f.vc.bu $f.vc.lab $f.vc.sc -expand yes\n",\ +"\n",\ +" frame $f.ge -relief groove -borderwidth 3\n",\ +" pack $f.ge -fill x\n",\ +" button $f.ge.neighbourangles -text \"calc neighbourangles\" -command {Ng_STLDoctor neighbourangles}\n",\ +" button $f.ge.showcoords -text \"show coords of touched triangle\" -command {Ng_STLDoctor showcoords}\n",\ +" button $f.ge.moveptm -text \"move point to middle of trianglepoints\" -command {Ng_STLDoctor movepointtomiddle; redraw}\n",\ +" button $f.ge.destroy0trigs -text \"destroy 0-volume triangles\" -command {Ng_STLDoctor destroy0trigs}\n",\ +" pack $f.ge.neighbourangles $f.ge.showcoords $f.ge.moveptm $f.ge.destroy0trigs -expand yes \n",\ +"\n",\ +"\n",\ +" button $f.ge.cancle -text \"Done\" -command {destroy .stldoctor_dlg }\n",\ +" pack $f.ge.cancle -expand yes\n",\ +"\n",\ +" set f [$wd.nb subwidget topology]\n",\ +"\n",\ +" frame $f.oc -relief groove -borderwidth 3\n",\ +" pack $f.oc -fill x\n",\ +" button $f.oc.bu -text \"invert orientation of selected trig\" -command {Ng_STLDoctor invertselectedtrig; redraw }\n",\ +" button $f.oc.bu2 -text \"orient after selected trig\" -command {Ng_STLDoctor orientafterselectedtrig; redraw }\n",\ +" pack $f.oc.bu $f.oc.bu2 -side left -expand yes\n",\ +"\n",\ +" button $f.toperr -text \"mark inconsistent triangles\" -command {Ng_STLDoctor marktoperrortrigs; redraw }\n",\ +"\n",\ +" button $f.deltrig -text \"delete selected triangle\" -command {Ng_STLDoctor deleteselectedtrig; redraw }\n",\ +" button $f.geosmooth -text \"geometric smoothing\" -command {Ng_STLDoctor smoothgeometry; redraw }\n",\ +"\n",\ +" pack $f.toperr $f.deltrig $f.geosmooth\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$wd.nb subwidget edges]\n",\ +"\n",\ +"\n",\ +" frame $f.be -relief groove -borderwidth 3 \n",\ +" pack $f.be -fill x\n",\ +" label $f.be.lab -text \"build edges with yellow angle:\";\n",\ +" scale $f.be.sc -orient horizontal -length 200 -from 0 -to 100 \\\n",\ +" -resolution 0.5\n",\ +" $f.be.sc config -variable stloptions.yangle \n",\ +" $f.be.sc config -command { Ng_SetSTLParameters; Ng_STLDoctor buildedges; redraw }\n",\ +" label $f.be.lab2 -text \"continue edges with yellow angle:\";\n",\ +" scale $f.be.sc2 -orient horizontal -length 200 -from 0 -to 100 \\\n",\ +" -resolution 0.5\n",\ +" $f.be.sc2 config -variable stloptions.contyangle \n",\ +" $f.be.sc2 config -command { Ng_SetSTLParameters; Ng_STLDoctor buildedges; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +" button $f.be.buildedges -text \"Build Edges\" -command {Ng_STLDoctor buildedges; redraw}\n",\ +" pack $f.be.lab $f.be.sc $f.be.lab2 $f.be.sc2 $f.be.buildedges -expand yes\n",\ +"\n",\ +" frame $f.se\n",\ +" pack $f.se -fill x\n",\ +" checkbutton $f.se.bu -text \"show excluded\" \\\n",\ +" -variable stldoctor.showexcluded \\\n",\ +" -command {Ng_STLDoctor; redraw}\n",\ +" pack $f.se.bu \n",\ +"\n",\ +" \n",\ +" set edgeselmodevals { 0 1 2 3 4 }\n",\ +" set edgeselmodelabs(0) \"no change\" \n",\ +" set edgeselmodelabs(1) \"undefined\" \n",\ +" set edgeselmodelabs(2) \"confirmed\" \n",\ +" set edgeselmodelabs(3) \"candidate\"\n",\ +" set edgeselmodelabs(4) \"excluded\"\n",\ +"\n",\ +" tixOptionMenu $f.edgeselmode -label \"Double Click sets edge :\" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +"\n",\ +" foreach edgeselmodev $edgeselmodevals {\n",\ +" $f.edgeselmode add command $edgeselmodev -label $edgeselmodelabs($edgeselmodev)\n",\ +" }\n",\ +" $f.edgeselmode config -variable stldoctor.edgeselectmode\n",\ +" $f.edgeselmode config -command { Ng_STLDoctor }\n",\ +" global stldoctor.edgeselectmode\n",\ +" pack $f.edgeselmode\n",\ +"\n",\ +" \n",\ +" frame $f.edg -relief groove -borderwidth 3\n",\ +" pack $f.edg -fill x\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $f.edg.f0\n",\ +" pack $f.edg.f0\n",\ +" button $f.edg.f0.confirmedge -text \"confirm\" -command {Ng_STLDoctor confirmedge; redraw}\n",\ +" button $f.edg.f0.candidateedge -text \"candidate\" -command {Ng_STLDoctor candidateedge; redraw}\n",\ +" button $f.edg.f0.excludeedge -text \"exclude\" -command {Ng_STLDoctor excludeedge; redraw}\n",\ +" button $f.edg.f0.undefinededge -text \"undefined\" -command {Ng_STLDoctor undefinededge; redraw}\n",\ +" pack $f.edg.f0.confirmedge $f.edg.f0.candidateedge $f.edg.f0.excludeedge $f.edg.f0.undefinededge -side left\n",\ +"\n",\ +" frame $f.edg.fa\n",\ +" pack $f.edg.fa\n",\ +" button $f.edg.fa.setallundefined -text \"all undefined\" -command {Ng_STLDoctor setallundefinededges; redraw}\n",\ +" button $f.edg.fa.erasecandidates -text \"candidates to undefined\" -command {Ng_STLDoctor erasecandidateedges; redraw}\n",\ +" pack $f.edg.fa.setallundefined $f.edg.fa.erasecandidates -side left\n",\ +"\n",\ +"\n",\ +" frame $f.edg.fb\n",\ +" pack $f.edg.fb\n",\ +" button $f.edg.fb.confirmcandidates -text \"candidates to confirmed\" -command {Ng_STLDoctor confirmcandidateedges; redraw}\n",\ +" button $f.edg.fb.confirmedtocandidates -text \"confirmed to candidates\" -command {Ng_STLDoctor confirmedtocandidateedges; redraw}\n",\ +" pack $f.edg.fb.confirmcandidates $f.edg.fb.confirmedtocandidates -side left\n",\ +"\n",\ +" frame $f.edg.f1\n",\ +" frame $f.edg.f2\n",\ +" frame $f.edg.f3\n",\ +" frame $f.edg.f4\n",\ +" pack $f.edg.f1 $f.edg.f2 $f.edg.f3 $f.edg.f4\n",\ +"\n",\ +" button $f.edg.f1.exportedges -text \"export edges\" -command {Ng_STLDoctor exportedges}\n",\ +" button $f.edg.f1.importedges -text \"import edges\" -command {Ng_STLDoctor importedges; redraw}\n",\ +" button $f.edg.f1.saveedgedata -text \"save edgedata\" \\\n",\ +" -command { \n",\ +" set types {\n",\ +" {\"Netgen Edgedata\" {.ned} } \n",\ +" }\n",\ +" set file [tk_getSaveFile -filetypes $types -defaultextension \".ned\"]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_STLDoctor saveedgedata $file\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $f.edg.f1.loadedgedata -text \"load edgedata\" \\\n",\ +" -command { \n",\ +" set types {\n",\ +" {\"Netgen Edgedata\" {.ned} }\n",\ +" }\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".ned\"]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_STLDoctor loadedgedata $file \n",\ +" puts \"loading done\"\n",\ +" \n",\ +" redraw\n",\ +" \n",\ +" }\n",\ +" } \n",\ +"\n",\ +" button $f.edg.f1.importAVLedges -text \"import AVL edges\" \\\n",\ +" -command {\n",\ +" set types {{\"Edge file\" {.edg }}}\n",\ +"\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".edg\"]\n",\ +" if {$file != \"\"} {\n",\ +" Ng_STLDoctor importexternaledges $file; \n",\ +" }\n",\ +" }\n",\ +"\n",\ +" pack $f.edg.f1.importAVLedges $f.edg.f1.loadedgedata $f.edg.f1.saveedgedata -side left\n",\ +"\n",\ +" frame $f.edg2 -relief groove -borderwidth 3\n",\ +" pack $f.edg2 -fill x\n",\ +"\n",\ +"\n",\ +" label $f.edg2.lab -text \"length (%):\"\n",\ +" scale $f.edg2.sc -orient horizontal -length 200 -from 0 -to 100 \\\n",\ +" -resolution 0.5 \\\n",\ +" -variable stldoctor.longlinefact \n",\ +"\n",\ +" button $f.edg2.undoedge -text \"undo last edge change\" -command {Ng_STLDoctor undoedgechange; redraw}\n",\ +" \n",\ +" pack $f.edg2.undoedge -expand yes\n",\ +"\n",\ +"\n",\ +"\n",\ +" set f [$wd.nb subwidget normals]\n",\ +"\n",\ +" frame $f.dt -relief groove -borderwidth 3\n",\ +" pack $f.dt -fill x\n",\ +" label $f.dt.lab -text \"dirty triangle factor\";\n",\ +" entry $f.dt.ent -width 5 -relief sunken \\\n",\ +" -textvariable stldoctor.dirtytrigfact\n",\ +" pack $f.dt.ent $f.dt.lab -side left -expand yes\n",\ +"\n",\ +" frame $f.srt -relief groove -borderwidth 3\n",\ +" pack $f.srt -fill x\n",\ +" button $f.srt.bu -text \"smooth reverted triangles geometric\" -command {Ng_STLDoctor smoothrevertedtrigs; redraw }\n",\ +" entry $f.srt.ent -width 5 -relief sunken \\\n",\ +" -textvariable stldoctor.smoothangle\n",\ +" pack $f.srt.ent $f.srt.bu -side left -expand yes\n",\ +"\n",\ +" frame $f.bdt -relief groove -borderwidth 3\n",\ +" pack $f.bdt -fill x\n",\ +" button $f.bdt.bu -text \"mark dirty triangles\" -command {Ng_STLDoctor markdirtytrigs; redraw }\n",\ +" button $f.bdt.bu2 -text \"smooth dirty triangles normal\" -command {Ng_STLDoctor smoothdirtytrigs; redraw }\n",\ +" pack $f.bdt.bu $f.bdt.bu2 -side left -expand yes\n",\ +"\n",\ +" \n",\ +" frame $f.sno -relief groove -borderwidth 3\n",\ +" pack $f.sno\n",\ +" \n",\ +" label $f.sno.labrough -text \"rough\"\n",\ +" scale $f.sno.scsmooth -orient horizontal -length 100 -from 0 -to 0.8 \\\n",\ +" -resolution 0.01 -variable stldoctor.smoothnormalsweight \\\n",\ +" -command { Ng_SetSTLParameters }\n",\ +" label $f.sno.labsmooth -text \"smooth\"\n",\ +" button $f.sno.smoothnormals -text \"smooth normals\" -command { Ng_STLDoctor smoothnormals; redraw}\n",\ +"\n",\ +"\n",\ +"\n",\ +" pack $f.sno.labrough $f.sno.scsmooth $f.sno.labsmooth $f.sno.smoothnormals -side left -padx 5\n",\ +"\n",\ +" frame $f.no -relief groove -borderwidth 3\n",\ +" pack $f.no -fill x\n",\ +"\n",\ +" button $f.no.marknonsmoothnormals -text \"mark non-smooth triangles\" -command {Ng_STLDoctor marknonsmoothnormals; redraw}\n",\ +" button $f.no.calcnormals -text \"calculate normals from geometry\" -command {Ng_STLDoctor calcnormals; redraw}\n",\ +"\n",\ +" pack $f.no.marknonsmoothnormals $f.no.calcnormals -expand yes\n",\ +"\n",\ +"\n",\ +" set f [$wd.nb subwidget advanced]\n",\ +"\n",\ +"\n",\ +" frame $f.sc\n",\ +" pack $f.sc -fill x\n",\ +" checkbutton $f.sc.bu -text \"spiral check\" \\\n",\ +" -variable stldoctor.spiralcheck \\\n",\ +" -command {Ng_STLDoctor;} \n",\ +" checkbutton $f.sc.bu2 -text \"cone check\" \\\n",\ +" -variable stldoctor.conecheck \\\n",\ +" -command {Ng_STLDoctor;} \n",\ +" pack $f.sc.bu $f.sc.bu2\n",\ +"\n",\ +"\n",\ +" tixControl $f.gtol -label \"load-geometry tolerance factor\" -integer false \\\n",\ +" -variable stldoctor.geom_tol_fact \\\n",\ +" -options {\n",\ +" entry.width 8\n",\ +" label.width 30\n",\ +" label.anchor e\n",\ +" } \n",\ +" pack $f.gtol\n",\ +"\n",\ +" button $f.adap -text \"Apply\" -command {\n",\ +" [.stldoctor_dlg.nb subwidget advanced].gtol invoke\n",\ +" Ng_STLDoctor; \n",\ +" }\n",\ +" pack $f.adap -expand yes\n",\ +"\n",\ +"\n",\ +" wm withdraw $wd\n",\ +" wm geom $wd +100+100\n",\ +" wm deiconify $wd\n",\ +" wm title $wd \"STL Doctor\"\n",\ +"\n",\ +" focus $wd\n",\ +"}\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc meshdoctordialog { } {\n",\ +"\n",\ +" set w .meshdoc_dlg\n",\ +" global meshdoctor.active\n",\ +"\n",\ +" if {[winfo exists .meshdoc_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" set meshdoctor.active 1\n",\ +" Ng_MeshDoctor;\n",\ +"\n",\ +"\n",\ +" frame $w.vis -relief groove -borderwidth 3\n",\ +" pack $w.vis\n",\ +"\n",\ +" checkbutton $w.vis.showfilledtrigs -text \"Show filled triangles\" \\\n",\ +" -variable viewoptions.drawfilledtrigs \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" \n",\ +" checkbutton $w.vis.showedges -text \"Show edges\" \\\n",\ +" -variable viewoptions.drawedges \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +" \n",\ +"\n",\ +" checkbutton $w.vis.showoutline -text \"Show Triangle Outline\" \\\n",\ +" -variable viewoptions.drawoutline \\\n",\ +" -command { Ng_SetVisParameters; redraw }\n",\ +"\n",\ +" pack $w.vis.showfilledtrigs $w.vis.showoutline $w.vis.showedges\n",\ +"\n",\ +" tixControl $w.markedgedist -label \"Mark edge dist: \" -integer true \\\n",\ +" -min 0 -max 999 \\\n",\ +" -variable meshdoc.markedgedist \\\n",\ +" -options {\n",\ +" entry.width 3\n",\ +" label.width 20\n",\ +" label.anchor e\n",\ +" } \\\n",\ +" -command {\n",\ +" Ng_MeshDoctor markedgedist ${meshdoc.markedgedist}\n",\ +" redraw\n",\ +" }\n",\ +" pack $w.markedgedist\n",\ +" \n",\ +" button $w.deledge -text \"Delete marked segments\" -command {\n",\ +" Ng_MeshDoctor deletemarkedsegments\n",\ +" redraw\n",\ +" }\n",\ +" pack $w.deledge\n",\ +" \n",\ +" button $w.close -text \"Close\" -command { \n",\ +" set meshdoctor.active 0;\n",\ +" Ng_MeshDoctor;\n",\ +" destroy .meshdoc_dlg \n",\ +" }\n",\ +" pack $w.close -expand yes\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Mesh Doctor\"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc qualityviewdialog { show } {\n",\ +"\n",\ +" set w .qualityview_dlg\n",\ +" \n",\ +" if {[winfo exists .qualityview_dlg] == 1} {\n",\ +"\n",\ +" if { $show == 1 } {\n",\ +" wm withdraw .qualityview_dlg\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" wm withdraw $w\n",\ +" }\n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" set c $w.c\n",\ +"\n",\ +" canvas $c -relief raised -width 450 -height 300\n",\ +" pack $w.c -side top -fill x\n",\ +"\n",\ +" set plotFont {Helvetica 12}\n",\ +" set smallFont {Helvetica 12}\n",\ +"\n",\ +" $c create line 100 250 400 250 -width 2\n",\ +" $c create line 100 250 100 50 -width 2\n",\ +"\n",\ +" for {set i 0} {$i <= 10} {incr i} {\n",\ +" set x [expr {100 + ($i*30)}]\n",\ +" $c create line $x 250 $x 245 -width 2\n",\ +" if { [expr {$i % 2}] == 0 } {\n",\ +" $c create text $x 254 -text [format %1.1f [expr 0.1*$i]] -anchor n -font $plotFont\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" global qualbar\n",\ +" global qualbarnull\n",\ +" global qualbaraxis\n",\ +"\n",\ +" for {set i 0} {$i <= 5} {incr i} {\n",\ +" set y [expr {250 - ($i*40)}]\n",\ +" $c create line 100 $y 105 $y -width 2\n",\ +"\n",\ +" set qualbaraxis($i) \\\n",\ +" [$c create text 96 $y -text [expr $i*50].0 -anchor e -font $plotFont]\n",\ +" }\n",\ +"\n",\ +" for {set i 0} {$i < 20} {incr i} {\n",\ +" set x1 [expr {100 + ($i*15) + 2}]\n",\ +" set x2 [expr {$x1+10}]\n",\ +" set y [expr {250 - 10 * $i}]\n",\ +" set qualbar($i) [$c create rectangle $x1 250 $x2 245 -fill blue]\n",\ +" set qualbarnull($i) [$c create text [expr {($x1+$x2)/2}] 245 -text 0 -anchor s -font $smallFont -fill blue] \n",\ +" }\n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu\n",\ +" \n",\ +" button $w.close -text \"Close\" \\\n",\ +" -command { \n",\ +" wm withdraw .qualityview_dlg\n",\ +" set viewqualityplot 0\n",\ +" }\n",\ +" pack $w.close\n",\ +" \n",\ +" \n",\ +" if { $show == 1 } {\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Mesh Quality\"\n",\ +" focus $w\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc memusedialog { show } {\n",\ +"\n",\ +" set w .memuse_dlg\n",\ +" \n",\ +" if {[winfo exists .memuse_dlg] == 1} {\n",\ +"\n",\ +" if { $show == 1 } {\n",\ +" wm withdraw .memuse_dlg\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" wm withdraw $w\n",\ +" }\n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" set c $w.c\n",\ +"\n",\ +" canvas $c -relief raised -width 600 -height 300\n",\ +" pack $w.c -side top -fill x\n",\ +"\n",\ +" set plotFont {Helvetica 18}\n",\ +" set smallFont {Helvetica 12}\n",\ +"\n",\ +"\n",\ +" global memmark\n",\ +" for {set i 0} {$i < 512} { incr i } {\n",\ +" set memmark($i) [$c create line [expr 50+$i] 50 [expr 50+$i] 70 -fill blue]\n",\ +" }\n",\ +"\n",\ +"\n",\ +" set plotFont {Helvetica 18}\n",\ +" set smallFont {Helvetica 12}\n",\ +"\n",\ +" $c create text 50 90 -text \"0 GB\" -anchor n -font $plotFont\n",\ +" $c create text 178 90 -text \"1 GB\" -anchor n -font $plotFont\n",\ +" $c create text 306 90 -text \"2 GB\" -anchor n -font $plotFont\n",\ +" $c create text 434 90 -text \"3 GB\" -anchor n -font $plotFont\n",\ +" $c create text 562 90 -text \"4 GB\" -anchor n -font $plotFont\n",\ +"\n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu\n",\ +" \n",\ +" button $w.close -text \"Close\" \\\n",\ +" -command { \n",\ +" wm withdraw .memuse_dlg\n",\ +" set memuseplot 0\n",\ +" }\n",\ +" pack $w.close\n",\ +" \n",\ +" if { $show == 1 } {\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Memory Usage\"\n",\ +" focus $w\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc STLinfodialog { show } {\n",\ +"\n",\ +" set w .STLinfo_dlg\n",\ +" \n",\ +" if {[winfo exists .STLinfo_dlg] == 1} {\n",\ +"\n",\ +" if { $show == 1 } {\n",\ +" wm withdraw .STLinfo_dlg\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" wm withdraw $w\n",\ +" }\n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" set c $w.c\n",\ +"\n",\ +" canvas $c -relief raised -width 450 -height 300\n",\ +" pack $w.c -side top -fill x\n",\ +"\n",\ +" set plotFont {Helvetica 18}\n",\ +" set smallFont {Helvetica 12}\n",\ +"\n",\ +" $c create line 100 250 400 250 -width 2\n",\ +" $c create line 100 250 100 50 -width 2\n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu\n",\ +" \n",\ +" button $w.close -text \"Close\" \\\n",\ +" -command { \n",\ +" wm withdraw .STLinfo_dlg\n",\ +" }\n",\ +" pack $w.close\n",\ +" \n",\ +" \n",\ +" if { $show == 1 } {\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"STL Geometry Info\"\n",\ +" focus $w\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc editprimitivedialog2 { name } {\n",\ +"\n",\ +" global w classname\n",\ +"\n",\ +" set w .ep_dlg\n",\ +" toplevel .$w\n",\ +"\n",\ +" Ng_GetPrimitiveData $name classname valuelist\n",\ +" \n",\ +" \n",\ +" label $w.lab1 -text \"Primitive Name: $name\";\n",\ +" label $w.lab2 -text \"Primitive Class: $classname\";\n",\ +" pack $w.lab1 $w.lab2 -fill x -pady 1m -padx 5m \n",\ +" \n",\ +" frame $w.specific -relief groove\n",\ +"\n",\ +" global spec\n",\ +" set spec(sphere) { cx cy cz rad }\n",\ +" set spec(cylinder) { ax ay az bx by bz rad }\n",\ +" set spec(plane) { px py pz nx ny nz }\n",\ +" set spec(cone) { ax ay az bx by bz ra rb }\n",\ +" set spec(brick) { p1x p1y p1z p2x p2y p2z p3x p3y p3z p4x p4y p4z } \n",\ +" \n",\ +" set cnt 0\n",\ +" foreach field $spec($classname) {\n",\ +"\n",\ +" frame $w.specific.f$cnt \n",\ +" pack $w.specific.f$cnt -side top -anchor ne\n",\ +"\n",\ +" label $w.specific.f$cnt.lab -text \"$field\"\n",\ +" entry $w.specific.f$cnt.ent -textvariable dataval($cnt) \\\n",\ +" -width 6 -relief sunken\n",\ +" pack $w.specific.f$cnt.ent $w.specific.f$cnt.lab -side right\n",\ +" $w.specific.f$cnt.ent delete 0 end\n",\ +" $w.specific.f$cnt.ent insert 0 [lindex $valuelist $cnt]\n",\ +" set cnt [expr $cnt + 1]\n",\ +" }\n",\ +" pack $w.specific\n",\ +"\n",\ +"\n",\ +" button $w.cancel -text \"cancel\" -command {\n",\ +" destroy $w \n",\ +" }\n",\ +"\n",\ +" button $w.ok -text \"ok\" -command {\n",\ +"\n",\ +" set valuelist \"\"\n",\ +" set cnt 0\n",\ +" foreach field $spec($classname) {\n",\ +" lappend valuelist $dataval($cnt)\n",\ +" set cnt [expr $cnt + 1]\n",\ +" }\n",\ +" Ng_SetPrimitiveData $name $valuelist\n",\ +" destroy $w\n",\ +" }\n",\ +" pack $w.cancel $w.ok -side left -expand yes\n",\ +"\n",\ +" bind $w { $w.ok invoke}\n",\ +" bind $w { $w.cancel invoke}\n",\ +" \n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +"\n",\ +" focus $w.specific.f0.ent\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc editprimitivedialog { } {\n",\ +" global w\n",\ +"\n",\ +" set w .ep_dlg\n",\ +" toplevel $w\n",\ +"\n",\ +" frame $w.frame -borderwidth 5m\n",\ +" pack $w.frame -side top -expand yes -fill y\n",\ +"\n",\ +" listbox $w.frame.list -yscroll \"$w.frame.scroll set\" -setgrid 1 -height 12\n",\ +" scrollbar $w.frame.scroll -command \"$w.frame.list yview\"\n",\ +" pack $w.frame.scroll -side right -fill y\n",\ +" pack $w.frame.list -side left -expand 1 -fill both\n",\ +" \n",\ +"\n",\ +" Ng_GetPrimitiveList primlist\n",\ +" foreach el $primlist {\n",\ +" $w.frame.list insert end $el }\n",\ +"\n",\ +" button $w.cancel -text \"cancel\" -command { destroy $w }\n",\ +" button $w.ok -text \"ok\" -command {\n",\ +" set name [.ep_dlg.frame.list get active]\n",\ +" puts \"name=($name)\"\n",\ +" destroy $w\n",\ +" if { $name != \"\" } { editprimitivedialog2 $name }\n",\ +" }\n",\ +" \n",\ +" bind $w { $w.cancel invoke }\n",\ +" bind $w { $w.ok invoke }\n",\ +" \n",\ +"\n",\ +" pack $w.cancel $w.ok -side left -expand yes\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +"\n",\ +" focus $w.frame.list\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc newprimitivedialog { } {\n",\ +"\n",\ +" global w name\n",\ +"\n",\ +" set w .ap_dlg\n",\ +" \n",\ +" toplevel $w\n",\ +"\n",\ +" set name \"\"\n",\ +" frame $w.f1\n",\ +" pack $w.f1 -pady 2m\n",\ +" label $w.f1.lab -text \"Primitive Name: \";\n",\ +" entry $w.f1.ent -width 5 -relief sunken \\\n",\ +" -textvariable name\n",\ +" pack $w.f1.lab $w.f1.ent -side left\n",\ +" \n",\ +" frame $w.frame -borderwidth .5c\n",\ +" pack $w.frame -side top -expand yes -fill y\n",\ +"\n",\ +" listbox $w.frame.list -yscroll \"$w.frame.scroll set\" -setgrid 1 -height 8 \n",\ +" scrollbar $w.frame.scroll -command \"$w.frame.list yview\"\n",\ +" pack $w.frame.scroll -side right -fill y\n",\ +" pack $w.frame.list -side left -expand 1 -fill both\n",\ +" \n",\ +" $w.frame.list insert 0 sphere cylinder plane cone brick\n",\ +" $w.frame.list activate 0\n",\ +" \n",\ +" button $w.ok -text \"ok\" -command {\n",\ +" Ng_CreatePrimitive [$w.frame.list get active] $name\n",\ +" destroy $w\n",\ +" editprimitivedialog2 $name\n",\ +" }\n",\ +"\n",\ +" button $w.cancel -text \"cancel\" -command {\n",\ +" destroy $w\n",\ +" }\n",\ +" \n",\ +" pack $w.cancel $w.ok -side left -expand yes -pady 2m\n",\ +"\n",\ +"\n",\ +" bind $w { $w.cancel invoke }\n",\ +" bind $w { $w.ok invoke }\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +"\n",\ +" focus $w.f1.ent\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc newsoliddialog { } {\n",\ +"\n",\ +" global w name val sollist\n",\ +"\n",\ +" set w .ns_dlg\n",\ +" toplevel $w\n",\ +"\n",\ +" set name \"\"\n",\ +" frame $w.f1\n",\ +" label $w.f1.lab -text \"Solid Name: \";\n",\ +" entry $w.f1.ent -width 5 -relief sunken \\\n",\ +" -textvariable name\n",\ +" $w.f1.ent delete 0 end\n",\ +" button $w.f1.getsel -text \"Get Selected\" -command { \n",\ +" $w.f1.ent delete 0 end\n",\ +" $w.f1.ent insert 0 [$w.f3.list get active]\n",\ +" $w.bu.get invoke\n",\ +" }\n",\ +" pack $w.f1.getsel -side bottom\n",\ +" pack $w.f1.ent $w.f1.lab -side right\n",\ +"\n",\ +"\n",\ +" frame $w.f3 -borderwidth .5c\n",\ +" listbox $w.f3.list -yscroll \"$w.f3.scroll set\" -setgrid 1 -height 12\n",\ +" scrollbar $w.f3.scroll -command \"$w.f3.list yview\"\n",\ +" pack $w.f3.scroll -side right -fill y\n",\ +" pack $w.f3.list -side left -expand 1 -fill both\n",\ +" \n",\ +" Ng_GetSolidList sollist\n",\ +" foreach el $sollist {\n",\ +" $w.f3.list insert end $el }\n",\ +"\n",\ +" frame $w.f2\n",\ +" label $w.f2.lab -text \"Solid Description: \";\n",\ +" pack $w.f2.lab\n",\ +"\n",\ +"\n",\ +" entry $w.f2.ent -width 100 -relief sunken \\\n",\ +" -textvariable val -xscrollcommand \"$w.f2.scr set\"\n",\ +" scrollbar $w.f2.scr -relief sunken -orient horiz -command \\\n",\ +" \"$w.f2.ent xview\"\n",\ +" $w.f2.ent delete 0 end\n",\ +" pack $w.f2.ent $w.f2.scr -fill x\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.bu\n",\ +" button $w.bu.close -text \"close\" -command {\n",\ +" destroy $w\n",\ +" }\n",\ +"\n",\ +" button $w.bu.get -text \"get data\" -command {\n",\ +" Ng_GetSolidData $name val\n",\ +" }\n",\ +"\n",\ +" button $w.bu.set -text \"set data\" -command {\n",\ +" Ng_SetSolidData $name $val\n",\ +" }\n",\ +"\n",\ +" pack $w.bu.get $w.bu.set $w.bu.close -side left \n",\ +"\n",\ +"\n",\ +" pack $w.bu -pady 5 -side bottom ; pack $w.f2 -pady 5 -side bottom ; pack $w.f1 -pady 5 -side left ; pack $w.f3 -side left -expand yes -fill y ;\n",\ +"\n",\ +"\n",\ +" bind $w { $w.bu.close invoke }\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +"\n",\ +" focus $w\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc toplevelproperties { w solname surfname } {\n",\ +"\n",\ +" global properties\n",\ +"\n",\ +" Ng_TopLevel getprop $solname $surfname properties\n",\ +"\n",\ +"\n",\ +" set w .tlprop_dlg\n",\ +"\n",\ +" if {[winfo exists $w] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" label $w.lab1 -text \"Red\"\n",\ +" scale $w.scale1 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_TopLevel setprop $solname $surfname properties; redraw } -variable properties(red)\n",\ +" \n",\ +" label $w.lab2 -text \"Green\"\n",\ +" scale $w.scale2 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_TopLevel setprop $solname $surfname properties; redraw } -variable properties(green)\n",\ +" \n",\ +" label $w.lab3 -text \"Blue\"\n",\ +" scale $w.scale3 -orient horizontal -length 300 -from 0 -to 1 \\\n",\ +" -resolution 0.01 -tickinterval 0.2 \\\n",\ +" -command { Ng_TopLevel setprop $solname $surfname properties; redraw } -variable properties(blue)\n",\ +"\n",\ +" \n",\ +" pack $w.lab1 $w.scale1 $w.lab2 $w.scale2 $w.lab3 $w.scale3\n",\ +"\n",\ +" checkbutton $w.cb4 -text \"Visible\" \\\n",\ +" -command { Ng_TopLevel setprop $solname $surfname properties; redraw } \\\n",\ +" -variable properties(visible)\n",\ +" \n",\ +" checkbutton $w.cb5 -text \"Transparent\" \\\n",\ +" -command { Ng_TopLevel setprop $solname $surfname properties; redraw } \\\n",\ +" -variable properties(transp)\n",\ +" \n",\ +" \n",\ +" pack $w.cb4 $w.cb5\n",\ +" \n",\ +" \n",\ +" frame $w.bu\n",\ +" pack $w.bu -fill x\n",\ +" button $w.bu.ok -text \"Ok\" -command \"destroy .tlprop_dlg\"\n",\ +" pack $w.bu.ok -expand yes\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" focus $w\n",\ +" }\n",\ +" wm title $w \"Properties $solname $surfname\"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc topleveldialog { } {\n",\ +"\n",\ +" global w name val sollist\n",\ +"\n",\ +" set w .tl_dlg\n",\ +" toplevel $w\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.sol -borderwidth .5c\n",\ +" listbox $w.sol.list -yscroll \"$w.sol.scroll set\" -setgrid 1 -height 12\n",\ +" scrollbar $w.sol.scroll -command \"$w.sol.list yview\"\n",\ +" pack $w.sol.scroll -side right -fill y\n",\ +" pack $w.sol.list -side left -expand 1 -fill both\n",\ +" \n",\ +" Ng_GetSolidList sollist\n",\ +" foreach el $sollist {\n",\ +" $w.sol.list insert end $el }\n",\ +" Ng_GetPrimitiveList sollist\n",\ +" foreach el $sollist {\n",\ +" $w.sol.list insert end $el }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.sul -borderwidth .5c\n",\ +" listbox $w.sul.list -yscroll \"$w.sul.scroll set\" -setgrid 1 -height 12\n",\ +" scrollbar $w.sul.scroll -command \"$w.sul.list yview\"\n",\ +" pack $w.sul.scroll -side right -fill y\n",\ +" pack $w.sul.list -side left -expand 1 -fill both\n",\ +" \n",\ +" Ng_GetSurfaceList sollist\n",\ +" foreach el $sollist {\n",\ +" $w.sul.list insert end $el }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.topl -borderwidth .5c\n",\ +" listbox $w.topl.list -yscroll \"$w.topl.scroll set\" -setgrid 1 -height 12 \\\n",\ +" -command { puts hi }\n",\ +" scrollbar $w.topl.scroll -command \"$w.topl.list yview\"\n",\ +" pack $w.topl.scroll -side right -fill y\n",\ +" pack $w.topl.list -side left -expand 1 -fill both\n",\ +" \n",\ +" Ng_TopLevel getlist sollist\n",\ +" puts $sollist\n",\ +" foreach el $sollist {\n",\ +" set hel \"[ lindex $el 0 ]\"\n",\ +" if { [ llength $el ] == 2 } {\n",\ +" set hel \"[ lindex $el 1 ] on [ lindex $el 0 ]\"\n",\ +" }\n",\ +" $w.topl.list insert end $hel \n",\ +" }\n",\ +"\n",\ +"\n",\ +" frame $w.bu\n",\ +"\n",\ +" button $w.bu.close -text \"close\" -command {\n",\ +" destroy $w\n",\ +" }\n",\ +" button $w.bu.addsol -text \"Add Solid\" -command {\n",\ +" set solname [$w.sol.list get active]\n",\ +" Ng_TopLevel set $solname \"\"\n",\ +" Ng_ParseGeometry\n",\ +" $w.topl.list insert end $solname\n",\ +" }\n",\ +"\n",\ +" button $w.bu.addsurf -text \"Add Surface\" -command {\n",\ +" set solname [$w.sol.list get active]\n",\ +" set surfname [$w.sul.list get active]\n",\ +" Ng_TopLevel set $solname $surfname\n",\ +" Ng_ParseGeometry\n",\ +" puts \"$solname on $surfname\"\n",\ +" $w.topl.list insert end \"$surfname on $solname\"\n",\ +" }\n",\ +"\n",\ +" button $w.bu.remsol -text \"Remove\" -command {\n",\ +" set solname [$w.topl.list get active]\n",\ +" set surfname \"\"\n",\ +" if { [llength $solname] == 3 } {\n",\ +" set surfname [lindex $solname 0]\n",\ +" set solname [lindex $solname 2]\n",\ +" }\n",\ +" Ng_TopLevel remove $solname $surfname\n",\ +" Ng_ParseGeometry\n",\ +" $w.topl.list delete active\n",\ +" }\n",\ +"\n",\ +" button $w.bu.prop -text \"Properties\" -command {\n",\ +" set solname [$w.topl.list get active]\n",\ +" set surfname \"\"\n",\ +" if { [llength $solname] == 3 } {\n",\ +" set surfname [lindex $solname 0]\n",\ +" set solname [lindex $solname 2]\n",\ +" }\n",\ +" toplevelproperties tlp $solname $surfname\n",\ +" }\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +" pack $w.bu.close $w.bu.addsol $w.bu.addsurf $w.bu.remsol $w.bu.prop -side left \n",\ +"\n",\ +"\n",\ +" pack $w.bu -side bottom\n",\ +" pack $w.sol -side left -expand yes -fill y ; pack $w.sul -side left -expand yes -fill y ; pack $w.topl -side left -expand yes -fill y ;\n",\ +"\n",\ +" bind $w { $w.bu.close invoke }\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +"\n",\ +" focus $w\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc topleveldialog2 { } {\n",\ +" set w .tl2_dlg\n",\ +" \n",\ +" if {[winfo exists .tl2_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" global name val sollist\n",\ +"\n",\ +" frame $w.topl -borderwidth .5c\n",\ +" listbox $w.topl.list -yscroll \"$w.topl.scroll set\" -setgrid 1 -height 12\n",\ +" scrollbar $w.topl.scroll -command \"$w.topl.list yview\"\n",\ +" pack $w.topl.scroll -side right -fill y\n",\ +" pack $w.topl.list -side left -expand 1 -fill both\n",\ +" \n",\ +" Ng_TopLevel getlist sollist\n",\ +" puts $sollist\n",\ +" set i 1\n",\ +" foreach el $sollist {\n",\ +" set hel \"$i: [ lindex $el 0 ]\"\n",\ +" if { [ llength $el ] == 2 } {\n",\ +" set hel \"$i: [ lindex $el 1 ] on [ lindex $el 0 ]\"\n",\ +" }\n",\ +" incr i\n",\ +" $w.topl.list insert end $hel }\n",\ +" \n",\ +" \n",\ +" frame $w.bu\n",\ +" \n",\ +" button $w.bu.close -text \"close\" -command {\n",\ +" destroy .tl2_dlg\n",\ +" }\n",\ +" \n",\ +"\n",\ +" button $w.bu.prop -text \"Properties\" -command {\n",\ +" set solname [.tl2_dlg.topl.list get active]\n",\ +" set surfname \"\"\n",\ +" if { [llength $solname] == 2 } {\n",\ +" set solname [lindex $solname 1]\n",\ +" }\n",\ +" if { [llength $solname] == 4 } {\n",\ +" set surfname [lindex $solname 1]\n",\ +" set solname [lindex $solname 3]\n",\ +" }\n",\ +" toplevelproperties tlp $solname $surfname\n",\ +" }\n",\ +" \n",\ +" pack $w.bu.close $w.bu.prop -side left \n",\ +" pack $w.bu -side bottom\n",\ +" pack $w.topl -side left -expand yes -fill y ; \n",\ +" bind .tl2_dlg.topl.list {\n",\ +" set solname [.tl2_dlg.topl.list get @%x,%y]\n",\ +" set surfname \"\"\n",\ +" if { [llength $solname] == 2 } {\n",\ +" set solname [lindex $solname 1]\n",\ +" }\n",\ +" if { [llength $solname] == 4 } {\n",\ +" set surfname [lindex $solname 1]\n",\ +" set solname [lindex $solname 3]\n",\ +" }\n",\ +" toplevelproperties tlp $solname $surfname\n",\ +" }\n",\ +" \n",\ +" bind .tl2_dlg { .tl2_dlg.bu.close invoke }\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Top-Level Options\" \n",\ +" focus $w\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc logwindow { } {\n",\ +" set w .logwindow\n",\ +" \n",\ +" if {[winfo exists .logwindow] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" text $w.edit -yscroll \"$w.scrolly set\" -setgrid 1 -height 12\n",\ +" scrollbar $w.scrolly -command \"$w.edit yview\" \n",\ +" pack $w.edit -side left -fill both -expand 1\n",\ +" pack $w.scrolly -side left -fill both -expand 0\n",\ +"\n",\ +" .logwindow.edit insert end \"Netgen Log Window\\n\"\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Netgen Log\" \n",\ +" focus $w\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set entities [ ]\n",\ +"\n",\ +"\n",\ +"proc occdialogbuildtree {} {\n",\ +" global entities\n",\ +"\n",\ +" set w .occ_dlg\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +"\n",\ +" set entities [Ng_GetOCCData getentities]\n",\ +" set nrentities [expr [llength $entities]]\n",\ +"\n",\ +"\n",\ +" if {$nrentities != 0} {\n",\ +"\n",\ +" $hlist add Topology -itemtype text -text \"Topology\"\n",\ +" \n",\ +" $hlist add Topology/CompSolids -itemtype text -text \"Composite Solids\" -data \"Composite Solids\"\n",\ +" $hlist add Topology/FreeSolids -itemtype text -text \"Free Solids\" -data \"Free Solids\"\n",\ +" $hlist add Topology/FreeShells -itemtype text -text \"Free Shells\" -data \"Free Shells\"\n",\ +" $hlist add Topology/FreeFaces -itemtype text -text \"Free Faces\" -data \"Free Faces\"\n",\ +" $hlist add Topology/FreeWires -itemtype text -text \"Free Wires\" -data \"Free Wires\"\n",\ +" $hlist add Topology/FreeEdges -itemtype text -text \"Free Edges\" -data \"Free Edges\"\n",\ +" $hlist add Topology/FreeVertices -itemtype text -text \"Free Vertices\" -data \"Free Vertices\"\n",\ +"\n",\ +" \n",\ +" set i [expr 0]\n",\ +" while {$i < $nrentities} {\n",\ +" set entity [lindex $entities [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname [lindex $entities [expr $i]]\n",\ +" $hlist add Topology/$entity -text $entityname -data $entityname\n",\ +" incr i 1\n",\ +" $w.mtre close Topology/$entity\n",\ +" }\n",\ +" \n",\ +" $w.mtre autosetmode\n",\ +" \n",\ +" $w.mtre open Topology\n",\ +" $w.mtre close Topology/CompSolids\n",\ +" $w.mtre close Topology/FreeSolids\n",\ +" $w.mtre close Topology/FreeShells\n",\ +" $w.mtre close Topology/FreeFaces\n",\ +" $w.mtre close Topology/FreeWires\n",\ +" $w.mtre close Topology/FreeEdges\n",\ +" $w.mtre close Topology/FreeVertices\n",\ +" \n",\ +" set i [expr 0]\n",\ +" while {$i < $nrentities} {\n",\ +" set entity [lindex $entities [expr $i]]\n",\ +" $w.mtre close Topology/$entity\n",\ +" incr i 2\n",\ +" }\n",\ +" \n",\ +" set faces [Ng_OCCCommand getunmeshedfaceinfo] \n",\ +" set nrfaces [expr [llength $faces]]\n",\ +" if {$nrfaces >= 2} {\n",\ +" $hlist add ErrorFaces -itemtype text -text \"Faces with surface meshing error\"\n",\ +" $w.mtre open ErrorFaces\n",\ +" set i [expr 0]\n",\ +" while {$i < $nrfaces} {\n",\ +" set entity [lindex $faces [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname [lindex $faces [expr $i]]\n",\ +" $hlist add ErrorFaces/$entity -text $entityname -data $entityname\n",\ +" incr i 1\n",\ +" }\n",\ +" }\n",\ +" \n",\ +"\n",\ +" set faces [Ng_OCCCommand getnotdrawablefaces] \n",\ +" set nrfaces [expr [llength $faces]]\n",\ +" if {$nrfaces >= 2} {\n",\ +" $hlist add NotDrawableFaces -itemtype text -text \"Faces impossible to visualize\"\n",\ +" $w.mtre open NotDrawableFaces\n",\ +" set i [expr 0]\n",\ +" while {$i < $nrfaces} {\n",\ +" set entity [lindex $faces [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname [lindex $faces [expr $i]]\n",\ +" $hlist add NotDrawableFaces/$entity -text $entityname -data $entityname\n",\ +" incr i 1\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +" $w.mtre autosetmode\n",\ +"\n",\ +" puts \"done\"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc rebuildoccdialog {} {\n",\ +" if {[winfo exists .occ_dlg] == 1} {\n",\ +" [.occ_dlg.mtre subwidget hlist] delete all\n",\ +" occdialogbuildtree \n",\ +" }\n",\ +"}\n",\ +"\n",\ +"proc checkoccloaded { } {\n",\ +" set isoccgeometryloaded [Ng_OCCCommand isoccgeometryloaded]\n",\ +" if {$isoccgeometryloaded == 0} {\n",\ +" puts \"no IGES/STEP geometry loaded\"\n",\ +" destroy .occ_dlg\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc selectentity { entityname } {\n",\ +" global entities\n",\ +" set nrentities [expr [llength $entities]]\n",\ +" set i [expr 0]\n",\ +" while {$i < $nrentities} {\n",\ +" set entitylength []\n",\ +" \n",\ +" set entity2 [lindex $entities [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname2 [lindex $entities [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname2 [string range $entityname2 0 [expr [string length $entityname]-1]]\n",\ +" \n",\ +" if {$entityname == $entityname2} {\n",\ +" set hlist [.occ_dlg.mtre subwidget hlist]\n",\ +" .occ_dlg.mtre open Topology\n",\ +" set slashpos [string last \"/\" $entity2]\n",\ +" set entity3 [string range $entity2 0 [expr $slashpos-1]]\n",\ +" while {$slashpos != -1} {\n",\ +" .occ_dlg.mtre open Topology/$entity3\n",\ +" \n",\ +" set slashpos [string last \"/\" $entity3]\n",\ +" set entity3 [string range $entity3 0 [expr $slashpos-1]]\n",\ +" }\n",\ +" $hlist selection clear\n",\ +" $hlist see Topology/$entity2\n",\ +" $hlist selection set Topology/$entity2\n",\ +" } \n",\ +" } \n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc occdialog { } {\n",\ +" \n",\ +" uplevel 1 {\n",\ +"\n",\ +" global entities\n",\ +" set selectvisual geometry\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +"\n",\ +" set w .occ_dlg\n",\ +" \n",\ +" if {[winfo exists .occ_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } { \n",\ +" toplevel $w\n",\ +"\n",\ +" tixTree $w.mtre -options { separator \"/\" }\n",\ +" pack $w.mtre -fill both -expand yes\n",\ +"\n",\ +" occdialogbuildtree\n",\ +"\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +"\n",\ +"\n",\ +" set solname {\"\"}\n",\ +"\n",\ +" \n",\ +" bind $hlist {\n",\ +" set oldsolname {$solname}\n",\ +" set solname [[.occ_dlg.mtre subwidget hlist] info selection]\n",\ +" if {$solname != \"\" && $oldsolname != $solname } {\n",\ +" set seppos [string first \"/\" $solname]\n",\ +" set rootname [string range $solname 0 [expr $seppos-1]]\n",\ +"\n",\ +" set entityname [[.occ_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +" if {$rootname == \"Topology\"} {\n",\ +" Ng_OCCCommand highlightentity $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +" } {\n",\ +" set brackpos [string first \" (\" $entityname]\n",\ +" if {$brackpos != -1} {\n",\ +" set entityname [string range $entityname 0 $brackpos]\n",\ +" }\n",\ +"\n",\ +" selectentity $entityname\n",\ +" }\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" button $w.cl -text \"Close\" -command {\n",\ +" destroy .occ_dlg\n",\ +" }\n",\ +" \n",\ +" button $w.show -text \"Show\" -command {\n",\ +" set solname [[.occ_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.occ_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +"\n",\ +" Ng_OCCCommand show $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +" }\n",\ +" button $w.hide -text \"Hide\" -command {\n",\ +" set solname [[.occ_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.occ_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +"\n",\ +" Ng_OCCCommand hide $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +" button $w.swaporientation -text \"Swap orientation\" -command {\n",\ +" set solname [[.occ_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.occ_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +"\n",\ +" Ng_OCCCommand swaporientation $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +"\n",\ +" [.occ_dlg.mtre subwidget hlist] delete all\n",\ +" occdialogbuildtree \n",\ +" }\n",\ +"\n",\ +" button $w.marksingular -text \"Mark/Unmark as singular\" -command {\n",\ +" set solname [[.occ_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.occ_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" if { $spacepos != 0 } {\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" if { $spacepos2 != 0 } {\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +" \n",\ +" global ismarkedsingular\n",\ +" Ng_OCCCommand marksingular $entitytype $entitynumber\n",\ +" \n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +" \n",\ +" set style1 [tixDisplayStyle imagetext -foreground black -background white -selectforeground white -selectbackground blue]\n",\ +" set style2 [tixDisplayStyle imagetext -foreground red -background white -selectforeground red -selectbackground blue]\n",\ +" \n",\ +" if { $ismarkedsingular == 0 } {\n",\ +" $hlist entryconfigure $solname -style $style1\n",\ +" } {\n",\ +" $hlist entryconfigure $solname -style $style2\n",\ +" }\n",\ +"\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +" }\n",\ +"\n",\ +"\n",\ +" checkbutton $w.zoomtohighlightedentity -text \"Zoom to highlighted entity\" \\\n",\ +" -variable occoptions.zoomtohighlightedentity \\\n",\ +" -command {\n",\ +" Ng_SetOCCVisParameters\n",\ +" if { ${occoptions.zoomtohighlightedentity} == 1} {\n",\ +" set selectvisual geometry\n",\ +" Ng_OCCCommand redrawstatus 1\n",\ +" redraw\n",\ +" } {\n",\ +" Ng_OCCCommand redrawstatus 0\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.healing -relief groove -borderwidth 3\n",\ +"\n",\ +" button $w.healing.checkentities -text \"Analyze geometry\" -command {\n",\ +" set irregent [Ng_OCCCommand findsmallentities]\n",\ +"\n",\ +" set w .occ_dlg\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +" \n",\ +" $hlist add ProblematicEntities -text \"Problematic Entities\"\n",\ +" $hlist delete offsprings ProblematicEntities\n",\ +"\n",\ +" set nritems [expr [llength $irregent]]\n",\ +" set i [expr 0]\n",\ +" while {$i < $nritems} {\n",\ +" set entity [lindex $irregent [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname [lindex $irregent [expr $i]]\n",\ +" $hlist add ProblematicEntities/$entity -text $entityname -data $entityname\n",\ +" incr i 1\n",\ +" }\n",\ +" $w.mtre open ProblematicEntities\n",\ +" $w.mtre autosetmode\n",\ +" }\n",\ +"\n",\ +" tixControl $w.healing.tolerance -label \"Healing tolerance: \" -integer false \\\n",\ +" -variable occoptions.tolerance -min 1e-9 -max 1e6 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" checkbutton $w.healing.fixsmalledges -text \"Fix small edges\" \\\n",\ +" -variable occoptions.fixsmalledges\n",\ +" \n",\ +" checkbutton $w.healing.fixspotstripfaces -text \"Fix spot/strip faces\" \\\n",\ +" -variable occoptions.fixspotstripfaces\n",\ +" \n",\ +" checkbutton $w.healing.sewfaces -text \"Sew faces\" \\\n",\ +" -variable occoptions.sewfaces\n",\ +" \n",\ +" checkbutton $w.healing.makesolids -text \"Make solids\" \\\n",\ +" -variable occoptions.makesolids\n",\ +" \n",\ +" checkbutton $w.healing.splitpartitions -text \"Split partitions\" \\\n",\ +" -variable occoptions.splitpartitions\n",\ +" \n",\ +" button $w.healing.heal -text \"Heal geometry\" -command { \n",\ +" .occ_dlg.healing.tolerance invoke\n",\ +" Ng_OCCCommand shapehealing\n",\ +" redraw \n",\ +" [.occ_dlg.mtre subwidget hlist] delete all\n",\ +" occdialogbuildtree\n",\ +" }\n",\ +"\n",\ +" pack $w.healing.checkentities\n",\ +"\n",\ +" pack $w.healing.tolerance $w.healing.fixsmalledges \\\n",\ +" $w.healing.fixspotstripfaces $w.healing.sewfaces \\\n",\ +" $w.healing.makesolids $w.healing.splitpartitions -anchor w\n",\ +"\n",\ +" pack $w.healing.heal \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" pack $w.show $w.hide\n",\ +"\n",\ +" pack $w.zoomtohighlightedentity -anchor w\n",\ +" pack $w.swaporientation\n",\ +" pack $w.marksingular\n",\ +" pack $w.healing -fill x\n",\ +" pack $w.cl\n",\ +" \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"IGES/STEP Topology Explorer/Doctor\"\n",\ +" focus .occ_dlg\n",\ +" }\n",\ +"}\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc printtable { tablevar } {\n",\ +" set w newtcltable\n",\ +" while {[winfo exists .$w] == 1} {set w 1$w}\n",\ +" set w .$w\n",\ +" toplevel $w\n",\ +" for {set i 0} {$i < [lindex $tablevar 2]} { incr i } {\n",\ +" frame $w.col$i\n",\ +" for {set j 0} {$j < [lindex $tablevar 1]} { incr j } {\n",\ +" frame $w.col$i.row$j\n",\ +" message $w.col$i.row$j.txt -aspect 10000000 -text [lindex $tablevar [expr 3+[lindex $tablevar 2]*$j+$i]]\n",\ +" pack $w.col$i.row$j.txt\n",\ +" pack $w.col$i.row$j -side top\n",\ +" }\n",\ +" pack $w.col$i -side left\n",\ +" }\n",\ +" wm withdraw $w\n",\ +" wm geom $w +200+100; wm deiconify $w\n",\ +" wm title $w [lindex $tablevar 0]\n",\ +" focus $w\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set latestwarning 0\n",\ +"\n",\ +"\n",\ +"proc printwarning { textvar } {\n",\ +" global latestwarning\n",\ +" set latestwarning $textvar\n",\ +" set w warning\n",\ +" while {[winfo exists .$w] == 1} {set w 1$w}\n",\ +" set w .$w\n",\ +" toplevel $w\n",\ +" message $w.mes -aspect 2000 -text \"WARNING:\\n$textvar\"\n",\ +" button $w.done -text \"Done\" -command \"destroy $w\"\n",\ +" pack $w.mes\n",\ +" pack $w.done\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Warning\"\n",\ +" focus $w\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc printlatestwarning { } { \n",\ +" global latestwarning \n",\ +" if {$latestwarning != 0} {printwarning $latestwarning}\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc paralleldialog { } {\n",\ +"\n",\ +" set w .parallel_dlg\n",\ +" \n",\ +" if {[winfo exists .parallel_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" wm geometry $w =270x100\n",\ +"\n",\ +" focus $w \n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +" wm geometry $w =270x100\n",\ +"\n",\ +" set ww $w\n",\ +"\n",\ +" button $ww.visallb -text \"View All\" -width 20 -command\\\n",\ +" { Ng_VisualizeAll; } \n",\ +" pack $ww.visallb \n",\ +" \n",\ +" button $ww.visoneb -text \"View One\" -width 20 -command \\\n",\ +" { Ng_VisualizeOne; } \n",\ +" pack $ww.visoneb \n",\ +" \n",\ +" button $ww.overlap -text \"overlap++\" -width 20 -command \\\n",\ +" { Ng_IncrOverlap; }\n",\ +" \n",\ +" pack $ww.overlap \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Parallel Netgen\"\n",\ +" focus .parallel_dlg \n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc runtestdialog { } {\n",\ +" source $::ngdir/ngtcltk/ngshell.tcl\n",\ +" set w .runtest_dlg\n",\ +" \n",\ +" if {[winfo exists .runtest_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +"\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" frame $w.in2dframe \n",\ +" pack $w.in2dframe\n",\ +"\n",\ +" set in2dlogfile \"\"\n",\ +" tixLabelEntry $w.in2dframe.ent -label \"in2d log-file: console if empty\" \\\n",\ +" -labelside top \\\n",\ +" -options { \n",\ +" entry.textVariable in2dlogfile\n",\ +" entry.width 35\n",\ +" label.width 25\n",\ +" label.anchor w\n",\ +" } \n",\ +" button $w.in2dframe.btn -text \"Browse\" -command {\n",\ +" set types { { \"Log file\" {.log} } }\n",\ +" set in2dlogfile [tk_getOpenFile -filetypes $types -initialfile $in2dlogfile]\n",\ +" }\n",\ +" button $w.in2dframe.test -text \"Test in2d meshing\" -command { ngtest in2d $in2dlogfile }\n",\ +"\n",\ +" \n",\ +" pack $w.in2dframe.test -side left -anchor s -padx 4 -pady 4\n",\ +" pack $w.in2dframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4\n",\ +" pack $w.in2dframe.btn -side left -anchor s -padx 4 -pady 4\n",\ +"\n",\ +" \n",\ +" frame $w.geoframe \n",\ +" pack $w.geoframe\n",\ +"\n",\ +" set geologfile \"\" \n",\ +" tixLabelEntry $w.geoframe.ent -label \"geo log-file: console if empty\" \\\n",\ +" -labelside top \\\n",\ +" -options { \n",\ +" entry.textVariable geologfile\n",\ +" entry.width 35\n",\ +" label.width 25\n",\ +" label.anchor w\n",\ +" } \n",\ +" button $w.geoframe.btn -text \"Browse\" -command {\n",\ +" set types { { \"Log file\" {.log} } }\n",\ +" set geologfile [tk_getOpenFile -filetypes $types -initialfile $geologfile]\n",\ +" }\n",\ +" button $w.geoframe.test -text \"Test geo meshing\" -command { ngtest geo $geologfile }\n",\ +"\n",\ +" \n",\ +" pack $w.geoframe.test -side left -anchor s -padx 4 -pady 4\n",\ +" pack $w.geoframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4\n",\ +" pack $w.geoframe.btn -side left -anchor s -padx 4 -pady 4\n",\ +"\n",\ +" frame $w.stlframe \n",\ +" pack $w.stlframe\n",\ +"\n",\ +" set stllogfile \"\"\n",\ +" tixLabelEntry $w.stlframe.ent -label \"stl log-file: console if empty\" \\\n",\ +" -labelside top \\\n",\ +" -options { \n",\ +" entry.textVariable stllogfile\n",\ +" entry.width 35\n",\ +" label.width 25\n",\ +" label.anchor w\n",\ +" } \n",\ +" button $w.stlframe.btn -text \"Browse\" -command {\n",\ +" set types { { \"Log file\" {.log} } }\n",\ +" set stllogfile [tk_getOpenFile -filetypes $types -initialfile $stllogfile]\n",\ +" }\n",\ +" button $w.stlframe.test -text \"Test stl meshing\" -command { ngtest stl $stllogfile }\n",\ +"\n",\ +" \n",\ +" pack $w.stlframe.test -side left -anchor s -padx 4 -pady 4\n",\ +" pack $w.stlframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4\n",\ +" pack $w.stlframe.btn -side left -anchor s -padx 4 -pady 4\n",\ +"\n",\ +" frame $w.pdeframe \n",\ +" pack $w.pdeframe\n",\ +"\n",\ +" set pdelogfile \"\"\n",\ +" tixLabelEntry $w.pdeframe.ent -label \"pde log-file: console if empty\" \\\n",\ +" -labelside top \\\n",\ +" -options { \n",\ +" entry.textVariable pdelogfile\n",\ +" entry.width 35\n",\ +" label.width 25\n",\ +" label.anchor w\n",\ +" } \n",\ +" button $w.pdeframe.btn -text \"Browse\" -command {\n",\ +" set types { { \"Log file\" {.log} } }\n",\ +" set pdelogfile [tk_getOpenFile -filetypes $types -initialfile $pdelogfile]\n",\ +" }\n",\ +" button $w.pdeframe.test -text \"Test ngsolve pde's\" -command { ngtest pde $pdelogfile }\n",\ +"\n",\ +" \n",\ +" pack $w.pdeframe.test -side left -anchor s -padx 4 -pady 4\n",\ +" pack $w.pdeframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4\n",\ +" pack $w.pdeframe.btn -side left -anchor s -padx 4 -pady 4\n",\ +" \n",\ +" wm title $w \"Testing\"\n",\ +" focus .runtest_dlg \n",\ +" }\n",\ +"}\n",\ +"\n",\ +"set oldmousex 0\n",\ +"set oldmousey 0\n",\ +"if {[catch {togl .ndraw -width 400 -height 300 -rgba true -double true -depth true -privatecmap false -stereo false -indirect false }] } { \n",\ +" puts \"no OpenGL\" \n",\ +"} {\n",\ +" pack .ndraw -expand true -fill both -padx 10 -pady 10\n",\ +" bind .ndraw {\n",\ +" set oldmousex %x; set oldmousey %y;\n",\ +" }\n",\ +" bind .ndraw {\n",\ +" set oldmousex %x; set oldmousey %y;\n",\ +" }\n",\ +" bind .ndraw {\n",\ +" set oldmousex %x; set oldmousey %y;\n",\ +" }\n",\ +" bind .ndraw {\n",\ +" Ng_MouseMove $oldmousex $oldmousey %x %y $drawmode\n",\ +" .ndraw render\n",\ +" set oldmousex %x; set oldmousey %y;\n",\ +" }\n",\ +"\n",\ +" bind .ndraw {\n",\ +" Ng_MouseDblClick %x %y\n",\ +" .ndraw render\n",\ +" if { [winfo exists .bcprop_dlg] } { bcpropdialog }\n",\ +" if { [winfo exists .fieldlines_dlg] } { fieldlinesdialog }\n",\ +" }\n",\ +"\n",\ +" bind .ndraw {\n",\ +" Ng_MouseMove $oldmousex $oldmousey %x %y move\n",\ +" .ndraw render\n",\ +" set oldmousex %x; set oldmousey %y;\n",\ +" }\n",\ +"\n",\ +" bind .ndraw {\n",\ +" Ng_MouseMove $oldmousex $oldmousey %x %y zoom\n",\ +" .ndraw render\n",\ +" set oldmousex %x; set oldmousey %y;\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc popupcheckredraw { vari { x 0 } } {\n",\ +" upvar $vari varname\n",\ +" if { $varname == 1 } {\n",\ +" set varname 0\n",\ +" } {\n",\ +" Ng_Vis_Set parameters\n",\ +" redraw\n",\ +" }\n",\ +"}\n",\ +"proc popupcheckredraw2 { vari boolvar { x 0 } } {\n",\ +" upvar $vari varname\n",\ +" if { $varname == 1 } {\n",\ +" set varname 0\n",\ +" } {\n",\ +" Ng_SetVisParameters\n",\ +" if { $boolvar == 1 } { redraw }\n",\ +" Ng_SetVisParameters\n",\ +" }\n",\ +"}\n",\ +"proc popupcheckredraw3 { vari { x 0 } } {\n",\ +" upvar $vari varname\n",\ +" if { $varname == 1 } {\n",\ +" set varname 0\n",\ +" } {\n",\ +" Ng_Vis_Set parameters\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc redraw { {x 0} } {\n",\ +" if {[winfo exists .ndraw]} { .ndraw render } \n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"bind . { Ng_MouseMove 0 0 -10 0 rotate; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 10 0 rotate; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 0 -10 rotate; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 0 10 rotate; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 -10 0 move; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 10 0 move; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 0 -10 move; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 0 10 move; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 0 -10 zoom; redraw }\n",\ +"bind . { Ng_MouseMove 0 0 0 10 zoom; redraw }\n",\ +"\n",\ +"bind all \\\n",\ +" {event generate [focus -displayof %W] -delta 120}\n",\ +"\n",\ +" bind all \\\n",\ +" {event generate [focus -displayof %W] -delta -120}\n",\ +"\n",\ +"bind all { Ng_MouseMove 0 0 0 [expr {%D/-5}] zoom; redraw }\n",\ +"\n",\ +"proc print_commandline_help { } {\n",\ +" \n",\ +" puts \"Usage: ng { options }\"\n",\ +"\n",\ +" puts \"-geofile=filename Input geometry file (alternative: ng filename)\"\n",\ +" puts \"-meshfile=filename Output mesh file\"\n",\ +" puts \"-verycoarse, -coarse, -moderate, -fine, -veryfine\"\n",\ +" puts \" Automatic mesh-size selection\"\n",\ +" puts \"-meshsizefile=filename Load mesh-size file with local mesh sizes\"\n",\ +" puts \"-meshfiletype={\\\"Neutral Format\\\", ...}\"\n",\ +" puts \" Filetype of output file, default is netgen file\"\n",\ +" puts \"-batchmode Run Netgen in batchmode\"\n",\ +" puts \"-inputmeshfile=filename\"\n",\ +" puts \" Input mesh file (batchmode only)\"\n",\ +" puts \"-mergefile=filename Merge with mesh file (batchmode only)\"\n",\ +" puts \"-refinementfile=filename\"\n",\ +" puts \" Use refinementinfo from file (batchmode only)\"\n",\ +" puts \"-serversocket=\\#num Start a Netgen server with port \\#num\"\n",\ +" puts \"-V Print additional information\"\n",\ +" puts \"-testout=filename file for test output\"\n",\ +"\n",\ +" if { [catch { NGS_GetData } ] == 0 } { \n",\ +" puts \"\\nNGSolve parameters:\"\n",\ +" puts \"-pdefile=filename Load pde input file\"\n",\ +" puts \"-solve Solve pde once\"\n",\ +" puts \"-solve=n Solve pde by n adaptive refinement steps\"\n",\ +" puts \"-recent Load and solve most recently loaded pde\"\n",\ +" }\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc set_menu_help { entry helpmsg } {\n",\ +" global menuhelps\n",\ +" set menuhelps($entry) $helpmsg\n",\ +"}\n",\ +"\n",\ +"proc show_menu_help { entry } {\n",\ +" global menuhelps\n",\ +"\n",\ +"\n",\ +" if {[catch {set helptext $menuhelps($entry)}]} {\n",\ +" set helptext \"no help available \"\n",\ +" } \n",\ +"\n",\ +" .helpline configure -text $helptext\n",\ +" \n",\ +" if {[winfo exists .senshelp_dlg]==1} {\n",\ +" .senshelp_dlg.text delete 1.0 end\n",\ +" .senshelp_dlg.text insert end \"Menu item: $entry\\n\\n\"\n",\ +" .senshelp_dlg.text insert end $helptext\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"tixBalloon .balloon -statusbar .helpline\n",\ +"\n",\ +"proc set_control_help { control helpmsg } {\n",\ +" bind $control \"show_control_help {$helpmsg}\"\n",\ +" bind $control \"show_control_help {None}\"\n",\ +" .balloon bind $control -balloonmsg $helpmsg -statusmsg $helpmsg\n",\ +"}\n",\ +"\n",\ +"proc show_control_help { helpmsg } {\n",\ +" .helpline configure -text $helpmsg\n",\ +" if {[winfo exists .senshelp_dlg]==1} {\n",\ +" .senshelp_dlg.text delete 1.0 end\n",\ +" .senshelp_dlg.text insert end $helpmsg\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc sensitivehelpdialog { show } {\n",\ +"\n",\ +" set w .senshelp_dlg\n",\ +" \n",\ +" if {[winfo exists .senshelp_dlg] == 1} {\n",\ +"\n",\ +" if { $show == 1 } {\n",\ +" wm withdraw .senshelp_dlg\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" wm withdraw $w\n",\ +" }\n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" global senshelptext\n",\ +"\n",\ +" text $w.text -yscrollcommand \"$w.scroll set\" -setgrid true \\\n",\ +" -width 40 -height 10 -wrap word\n",\ +" scrollbar $w.scroll -command \"$w.text yview\"\n",\ +" pack $w.scroll -side right -fill y\n",\ +" pack $w.text -expand yes -fill both\n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu\n",\ +" \n",\ +" button $w.close -text \"Close\" \\\n",\ +" -command { \n",\ +" wm withdraw .senshelp_dlg\n",\ +" set showsensitivehelp 0\n",\ +" }\n",\ +" pack $w.close\n",\ +" \n",\ +" \n",\ +" if { $show == 1 } {\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Help\"\n",\ +" focus $w\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"set_menu_help \"File\" \"In File menu you can load and store geometries, meshes etc.\" \n",\ +"\n",\ +"set_menu_help \"New Geometry\" \"Deletes current geometry\"\n",\ +"set_menu_help \"Load Geometry\" \"Loads Geometry file in one of the formats STL (ASCII or binary), Constructive Solid Geometry (.geo) or 2D geometry. Please have a look into Netgen User's manuel for more details.\"\n",\ +"set_menu_help \"Save Geometry\" \"Saves STL Geometry in in either ASCII or binary STL format.\"\n",\ +"set_menu_help \"Load Mesh\" \"Loads surface and volume mesh in Netgen internal format.\"\n",\ +"set_menu_help \"Save Mesh\" \"Saves surface and volume mesh in Netgen internal format.\"\n",\ +"set_menu_help \"Write EPS File\" \"Dumps OpenGL rendering to EPS File.\"\n",\ +"set_menu_help \"Save Options\" \"Saves current options in file \\\"ng.opt\\\". These options will be loaded again when starting ng in the same directory.\"\n",\ +"set_menu_help \"Export Mesh\" \"Exports mesh in format defined by Export Filetype.\"\n",\ +"set_menu_help \"Export Filetype\" \"Selects file format for exporting mesh. Please have a look into the Netgen User's manual for more information.\"\n",\ +"set_menu_help \"Import Mesh\" \"Imports surface or volume mesh in exchange format.\"\n",\ +"set_menu_help \"Quit\" \"Quits Netgen\"\n",\ +"\n",\ +"set_menu_help \"Geometry\" \"Preparing geometries, visualiztion of geometries.\"\n",\ +"set_menu_help \"Scan CSG Geometry\" \"Generates surface triangulation for rendering\"\n",\ +"set_menu_help \"CSG Options\" \"Sets Options for CSG visualization (bounding box, detail size, number of facets).\"\n",\ +"set_menu_help \"CSG Properties\" \"Defines appearence of current CSG geometry (color, visibility, transparency)\"\n",\ +"set_menu_help \"STL Doctor\" \"Calls STL Doctor for preprocessing STL geometry files.\"\n",\ +"set_menu_help \"STL Info\" \"Retrieves information about current STL geometry.\"\n",\ +"\n",\ +"set_menu_help \"Mesh\" \"Menu for mesh generation\"\n",\ +"set_menu_help \"Generate Mesh\" \"Generates mesh from geometry, same as Button \\\"Generate Mesh\\\"\"\n",\ +"set_menu_help \"Stop Meshing\" \"Terminates meshgeneration. It may take a while until meshing terminates, please be patient.\"\n",\ +"set_menu_help \"Meshing Options\" \"Set options for mesh generation.\"\n",\ +"set_menu_help \"Delete Mesh\" \"Deletes mesh. Not necessary before generation of new mesh.\"\n",\ +"set_menu_help \"Delete Vol Mesh\" \"Deletes only volume mesh.\"\n",\ +"set_menu_help \"Mesh Quality\" \"Computs element shape measures. Triangle angles are inner angles of all triangles (faces of tetrahedra). Tet angles are angles between faces of tetrahedra.\"\n",\ +"set_menu_help \"Check Surface Mesh\" \"Checks consistency and overlap of surface mesh. Marks overlapping elements as bad elements, please enable visualization of bad elements in View->Mesh.\"\n",\ +"set_menu_help \"Check Volume Mesh\" \"Checks conformity of volume mesh.\"\n",\ +"set_menu_help \"Edit Boundary Conditions\" \"Open dialog for setting boundary condition numbers for individual faces.\"\n",\ +"set_menu_help \"Analyze Geometry\" \"Perform only first step in mesh generation. Action depends on geometry type, e.g. generates charts for STL mesh, find vertices in CSG geometries.\"\n",\ +"set_menu_help \"Mesh Edges\" \"Meshes edges\"\n",\ +"set_menu_help \"Mesh Surface\" \"Generates surface mesh. Includes already surface optimization for some geomtry types.\"\n",\ +"set_menu_help \"Optimize Surface\" \"Optimizes surface mesh.\"\n",\ +"set_menu_help \"Surface Optim. Step\" \"Performs a specific surface optimiztion step. Mesh smoothing moves nodes. edge swapping swaps the diagonal of a quadrilateral built by two triangles, criterion either by number of nodes, or anlges. Combine points eliminates triangles by combining points (in the center of gravity).\"\n",\ +"set_menu_help \"Mesh Volume\" \"Performs volume meshing. Algorithm is a combination of Delaunay and Rule-based Advancing Front\"\n",\ +"set_menu_help \"Optimize Volume\" \"Performs additional volume optimization steps\"\n",\ +"set_menu_help \"Smooth Opt Volume\" \"Performs optimization steps by smoothing iterations\"\n",\ +"set_menu_help \"Smooth Opt Volume Jacobian\" \"Volume optimization by smoothing iterations. Criterion is optimization of Jacobi determinants. This optimization step is also available for 10-node tetrahedra.\"\n",\ +"\n",\ +"set_menu_help \"View\" \"Sets viewing options\"\n",\ +"set_menu_help \"Zoom all\" \"Zooms scene to show whole object\"\n",\ +"set_menu_help \"Center\" \"Defines center of rotation\"\n",\ +"set_menu_help \"Viewing Options\" \"Sets viewing options for geometry, mesh, lighting\"\n",\ +"set_menu_help \"Clipping Plane\" \"Introduces clipping plane. The clipping plane is defined by the normal vector, and a scaled offset. Clipping of performed by OpenGl rendering\"\n",\ +"set_menu_help \"Quality Plot\" \"Shows the element quality distribution histogram. Measure is volume scaled by edge-length to the third. Optimal elements have measure 1.\"\n",\ +"set_menu_help \"Sensitve Help\" \"Shows this help window\"\n",\ +"\n",\ +"set_menu_help \"Mesh-size\" \"Manipulations of existing mesh\"\n",\ +"set_menu_help \"Refine uniform\" \"Refines mesh by splitting elements into eight childs (algorithm of J. Bey)\"\n",\ +"set_menu_help \"Second Order\" \"Converts 4 node elements to 10 node elements. Edge-midpoitns are projected to the geometry.\"\n",\ +"set_menu_help \"Refinement Dialog\" \"Controls local mesh refinement\"\n",\ +"set_menu_help \"Load Meshsize\" \"Loads mesh-size file for local mesh refinement.\"\n",\ +"set_menu_help \"MS from Surf Mesh\" \"Defines mesh-size by the surface mesh.\"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set f .options_dlg.nb.nbframe.general\n",\ +"set_control_help $f.fine \"Controls relative mesh size.\\nThis control affects other mesh-size controls in common\"\n",\ +"set_control_help $f.first \"First step in mesh generation. Usually, meshing starts from \\\"analyze geometry\\\". If the surface mesh is already available \\\"First step\\\" should be set to \\\"mesh volume\\\"\"\n",\ +"set_control_help $f.last \"Last step in mesh generation. If only the surface mesh is required, please set \\\"Last Step\\\" to \\\"Optimize Surface\\\"\"\n",\ +"\n",\ +"set_control_help .bubar.surfm \"Start mesh generation\"\n",\ +"set_control_help .bubar.stopm \"Start mesh generation\"\n",\ +"\n",\ +"proc help_item { helptext } {p\n",\ +" puts $helptext\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc show_help { } {\n",\ +" \n",\ +" set w .help\n",\ +" \n",\ +" if {[winfo exists .help] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconif $w\n",\ +" focus $w \n",\ +" } {\n",\ +" \n",\ +" toplevel $w\n",\ +" \n",\ +" frame $w.buttons\n",\ +" pack $w.buttons -side bottom -fill x -pady 2m\n",\ +" button $w.buttons.done -text Done -command \"destroy $w\"\n",\ +" pack $w.buttons.done -side left -expand 1\n",\ +"\n",\ +" text $w.text -yscrollcommand \"$w.scroll set\" -setgrid true \\\n",\ +" -width 60 -height 24 -wrap word\n",\ +" scrollbar $w.scroll -command \"$w.text yview\"\n",\ +" pack $w.scroll -side right -fill y\n",\ +" pack $w.text -expand yes -fill both\n",\ +"\n",\ +" }\n",\ +" $w.text configure -state normal\n",\ +" $w.text delete 1.0 end\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set bold \"-background #43ce80 -relief raised -borderwidth 1\"\n",\ +"set normal \"-background {} -relief flat\"\n",\ +"\n",\ +"\n",\ +"proc help_main { } {\n",\ +"\n",\ +" show_help;\n",\ +" set w .help\n",\ +" global bold\n",\ +" global normal\n",\ +"\n",\ +"\n",\ +" \n",\ +" $w.text insert 0.0 \\\n",\ +" {NETGEN Help}\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {1. General} d1\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {2. Menu items } d2\n",\ +" $w.text insert end \\n\\n\n",\ +"\n",\ +" foreach tag {d1 d2} {\n",\ +" $w.text tag bind $tag \"$w.text tag configure $tag $bold\"\n",\ +" $w.text tag bind $tag \"$w.text tag configure $tag $normal\"\n",\ +" }\n",\ +" \n",\ +" $w.text tag bind d1 <1> { puts \"general\"; help_general }\n",\ +" $w.text tag bind d2 <1> { help_menus }\n",\ +"\n",\ +" $w.text configure -state disabled\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc help_general { } {\n",\ +"\n",\ +" show_help;\n",\ +" set w .help\n",\ +" global bold\n",\ +" global normal\n",\ +"\n",\ +" puts \"general called\"\n",\ +"\n",\ +" $w.text insert 0.0 \\\n",\ +" {NETGEN is an automatic three dimensional tetrahedral mesh generation system. It accepts input from constructive solid geometry (CSG) or boundary representation (BRep) from STEP or STL file format. NETGEN contains modules for mesh optimization and hierarchical mesh refinement.}\n",\ +"\n",\ +" $w.text configure -state disabled\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc help_menus { } {\n",\ +"\n",\ +" show_help;\n",\ +" set w .help\n",\ +" global bold\n",\ +" global normal\n",\ +"\n",\ +"\n",\ +" $w.text insert 0.0 \\\n",\ +" {The NETGEN Menu items are}\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {1. File} d1\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {2. Geometry } d2\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {3. Mesh } d3\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {4. View } d4\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {5. Mesh-size } d5\n",\ +" $w.text insert end \\n\\n\n",\ +" $w.text insert end \\\n",\ +" {6. STL } d6\n",\ +"\n",\ +" foreach tag {d1 d2 d3 d4 d5 d6} {\n",\ +" $w.text tag bind $tag \"$w.text tag configure $tag $bold\"\n",\ +" $w.text tag bind $tag \"$w.text tag configure $tag $normal\"\n",\ +" }\n",\ +" \n",\ +" $w.text tag bind d1 <1> {puts \"File menu\"}\n",\ +" $w.text tag bind d2 <1> {puts \"Geometry menu\"}\n",\ +" $w.text tag bind d3 <1> {puts \"Mesh menu\"}\n",\ +" $w.text tag bind d4 <1> {puts \"View menu\"}\n",\ +" $w.text tag bind d5 <1> {puts \"Mesh-size menu\"}\n",\ +" $w.text tag bind d6 <1> {puts \"STL menu\"}\n",\ +"\n",\ +" $w.text configure -state disabled\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"Ng_Vis_Set parameters\n",\ +"\n",\ +"\n",\ +"\n",\ +"set viscnt 0\n",\ +"proc snapshottimer { } {\n",\ +" after 2000 { snapshottimer }\n",\ +"\n",\ +" global viscnt\n",\ +" set viscnt [expr $viscnt+1]\n",\ +" set s1 0000$viscnt\n",\ +" set cnt [string range $s1 [expr [string length $s1]-4] end]\n",\ +" set filename \"p$cnt.jpg\"\n",\ +"}\n",\ +"snapshottimer\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc redrawtimer { } {\n",\ +" global visoptions.autoredraw\n",\ +" global visoptions.autoredrawtime\n",\ +"\n",\ +" set delay [expr int(${visoptions.autoredrawtime}*1000)]\n",\ +" if { ${visoptions.autoredraw} == 1 } { redraw; }\n",\ +" after $delay { redrawtimer } \n",\ +"}\n",\ +"redrawtimer\n",\ +"\n",\ +"\n",\ +"set perstarttime [clock clicks -millisecond]\n",\ +"proc redrawperiodic { } {\n",\ +" global visoptions.redrawperiodic\n",\ +" global perstarttime\n",\ +" set curtime [clock clicks -millisecond]\n",\ +" Ng_Vis_Set time [expr ($curtime - $perstarttime) / 5]\n",\ +" redraw\n",\ +" if { ${visoptions.redrawperiodic} == 1 } { after 30 { redrawperiodic } };\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc addplotline { identifier datax datay plotinfo {color black}} {\n",\ +" set c $identifier.c\n",\ +"\n",\ +" set xstart [lindex $plotinfo 0]\n",\ +" set ystart [lindex $plotinfo 1]\n",\ +" set xmin [lindex $plotinfo 2]\n",\ +" set ymin [lindex $plotinfo 3]\n",\ +" set unitx [lindex $plotinfo 4]\n",\ +" set unity [lindex $plotinfo 5]\n",\ +" \n",\ +" \n",\ +" \n",\ +" set latestx [expr ([lindex $datax 0]-$xmin)*$unitx + $xstart]\n",\ +" set latesty [expr ([lindex $datay 0]-$ymin)*$unity + $ystart]\n",\ +" \n",\ +" for {set i 1} {$i < [llength $datax]} {incr i} {\n",\ +" set xpos [expr ([lindex $datax $i]-$xmin)*$unitx + $xstart]\n",\ +" set ypos [expr ([lindex $datay $i]-$ymin)*$unity + $ystart]\n",\ +" $c create line $latestx $latesty $xpos $ypos -width 1 -fill $color\n",\ +" set latestx $xpos\n",\ +" set latesty $ypos\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc createlineplot { width height identifier title xmin xmax ymin ymax plotinfo} {\n",\ +" set thiswidth $width\n",\ +" set thisheight $height\n",\ +" if { $thiswidth < 275 } { set thiswidth 275 }\n",\ +" if { $thisheight < 225 } { seth thisheight 225 }\n",\ +"\n",\ +" set w $identifier\n",\ +"\n",\ +" if {[winfo exists $w] == 1} {\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +" \n",\ +" set c $w.c\n",\ +" \n",\ +" canvas $c -relief raised -width $thiswidth -height $thisheight\n",\ +" pack $w.c -side top -fill x\n",\ +" \n",\ +" set titleFont {Helvetica 18}\n",\ +" set smallFont {Helvetica 12}\n",\ +"\n",\ +" set xstart 100\n",\ +" set xend [expr $thiswidth-75]\n",\ +" set ystart [expr $thisheight-75]\n",\ +" set yend 75\n",\ +"\n",\ +" $c create line $xstart $ystart $xstart $yend -width 2\n",\ +" $c create line $xstart $ystart $xend $ystart -width 2\n",\ +"\n",\ +" \n",\ +"\n",\ +" \n",\ +" set unitx [expr double($xend-$xstart)/($xmax-$xmin)]\n",\ +" set unity [expr double($yend-$ystart)/($ymax-$ymin)]\n",\ +"\n",\ +" for {set i 0} {$i <= 1} {set i [expr $i+0.2]} {\n",\ +" $c create line [expr $xstart+$i*($xend-$xstart)] [expr $ystart] [expr $xstart+$i*($xend-$xstart)] [expr $ystart+5] -width 2\n",\ +" $c create text [expr $xstart+$i*($xend-$xstart)] [expr $ystart+7] -anchor n -font $smallFont \\\n",\ +" -text [format \"%.3g\" [expr $xmin+$i*($xmax-$xmin)]]\n",\ +" $c create line [expr $xstart] [expr $ystart+$i*($yend-$ystart)] [expr $xstart-7] [expr $ystart+$i*($yend-$ystart)] -width 2\n",\ +" $c create text [expr $xstart-9] [expr $ystart+$i*($yend-$ystart)] -anchor e -font $smallFont \\\n",\ +" -text [format \"%.3g\" [expr $ymin+$i*($ymax-$ymin)]]\n",\ +" }\n",\ +"\n",\ +" upvar $plotinfo ploti\n",\ +"\n",\ +" set ploti \"$xstart $ystart $xmin $ymin $unitx $unity\"\n",\ +"\n",\ +" \n",\ +" button $w.close -text \"Close\" -command \"destroy $w\"\n",\ +" pack $w.close\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w $title\n",\ +" focus $w\n",\ +"\n",\ +" }\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc getlineplotdata { datax datay xmini xmaxi ymini ymaxi} {\n",\ +"\n",\ +" upvar $datax datx\n",\ +" upvar $datay daty\n",\ +" \n",\ +" upvar $xmini xmin\n",\ +" upvar $xmaxi xmax\n",\ +" upvar $ymini ymin\n",\ +" upvar $ymaxi ymax\n",\ +"\n",\ +" global visoptions.lineplotusingx\n",\ +" global visoptions.lineplotusingy\n",\ +" global visoptions.lineplotsource\n",\ +" global visoptions.lineplotfile\n",\ +"\n",\ +" set datx \"\"\n",\ +" set daty \"\"\n",\ +"\n",\ +" set xmin 1e20\n",\ +" set xmax -1e20\n",\ +" set ymin 1e20\n",\ +" set ymax -1e20\n",\ +" \n",\ +"\n",\ +" if {${visoptions.lineplotsource} == \"file\"} {\n",\ +" set fileId [open ${visoptions.lineplotfile} r]\n",\ +" set line \"\"\n",\ +" \n",\ +" while {[gets $fileId line] >= 0} {\n",\ +" if { [string index [lindex $line 0] 0] != \"\\#\" } {\n",\ +" if { ${visoptions.lineplotusingx} < [llength $line] } {\n",\ +" lappend datx [lindex $line ${visoptions.lineplotusingx}]\n",\ +" \n",\ +" if { [lindex $datx end] < $xmin } {set xmin [lindex $datx end]}\n",\ +" if { [lindex $datx end] > $xmax } {set xmax [lindex $datx end]}\n",\ +" } {\n",\ +" lappend datx 0\n",\ +" }\n",\ +" if { ${visoptions.lineplotusingy} < [llength $line] } {\n",\ +" lappend daty [lindex $line ${visoptions.lineplotusingy}]\n",\ +"\n",\ +" if { [lindex $daty end] < $ymin } {set ymin [lindex $daty end]}\n",\ +" if { [lindex $daty end] > $ymax } {set ymax [lindex $daty end]}\n",\ +" } {\n",\ +" lappend daty 0\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" }\n",\ +" close $fileId\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"proc lineplotdialog { } {\n",\ +"\n",\ +" set w .lineplot_dlg\n",\ +" \n",\ +" if {[winfo exists .lineplot_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" \n",\ +" toplevel $w\n",\ +" \n",\ +" frame $w.filesettings -relief groove -borderwidth 3\n",\ +" frame $w.filesettings.title\n",\ +" radiobutton $w.filesettings.title.choose -variable visoptions.lineplotsource \\\n",\ +" -value file -text \"Data from File\"\n",\ +"\n",\ +" pack $w.filesettings.title.choose -side left\n",\ +"\n",\ +" pack $w.filesettings.title\n",\ +"\n",\ +" \n",\ +" global visoptions.lineplotselectedeval\n",\ +" global visoptions.lineplotfile\n",\ +" global visoptions.evaluatefilenames\n",\ +" global visoptions.evaluatefiledescriptions\n",\ +"\n",\ +" set evdata [NGS_GetData evaluatefiles]\n",\ +" set visoptions.evaluatefilenames none\n",\ +" set visoptions.evaluatefiledescriptions none\n",\ +" for {set i 0} {[expr $i+1] < [llength $evdata]} {incr i 2} {\n",\ +" lappend visoptions.evaluatefilenames [lindex $evdata $i]\n",\ +" lappend visoptions.evaluatefiledescriptions [lindex $evdata [expr $i+1]] \n",\ +" }\n",\ +" \n",\ +"\n",\ +" tixOptionMenu $w.filesettings.latestevals -label \"Use Evaluate Results: \" \\\n",\ +" -options {\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" menubutton.width 40\n",\ +" } \n",\ +" \n",\ +" for {set i 0} {$i < [llength ${visoptions.evaluatefilenames}]} {incr i} {\n",\ +" $w.filesettings.latestevals add command $i \\\n",\ +" -label \"[lindex ${visoptions.evaluatefiledescriptions} $i] ([lindex ${visoptions.evaluatefilenames} $i])\"\n",\ +" }\n",\ +" $w.filesettings.latestevals config -variable visoptions.lineplotselectedeval\n",\ +"\n",\ +" pack $w.filesettings.latestevals\n",\ +" \n",\ +" frame $w.filesettings.sfn\n",\ +"\n",\ +" button $w.filesettings.sfn.bb -text \"Browse\" \\\n",\ +" -command { set visoptions.lineplotfile [tk_getOpenFile] }\n",\ +"\n",\ +" \n",\ +" entry $w.filesettings.sfn.fn -width 50 -relief sunken \\\n",\ +" -textvariable visoptions.lineplotfile\n",\ +"\n",\ +" pack $w.filesettings.sfn.bb $w.filesettings.sfn.fn -side left\n",\ +"\n",\ +" pack $w.filesettings.sfn\n",\ +"\n",\ +" button $w.filesettings.refresh -text \"Refresh\" -command {\n",\ +" if { ${visoptions.lineplotselectedeval} != 0} {\n",\ +" set visoptions.lineplotfile [lindex ${visoptions.evaluatefilenames} ${visoptions.lineplotselectedeval}]\n",\ +" }\n",\ +" \n",\ +" set saveusingx ${visoptions.lineplotusingx}\n",\ +" set saveusingy ${visoptions.lineplotusingy}\n",\ +" \n",\ +"\n",\ +" \n",\ +" for { set i 0 } { $i < [llength ${visoptions.lineplotdatadescr}] } { incr i } {\n",\ +" ${visoptions.lineplotxcoordselector} delete $i\n",\ +" }\n",\ +" for { set i 0 } { $i < [llength ${visoptions.lineplotdatadescr}] } { incr i } {\n",\ +" ${visoptions.lineplotycoordselector} delete $i\n",\ +" }\n",\ +"\n",\ +" \n",\ +" set fileId [open ${visoptions.lineplotfile} r]\n",\ +" set line \"\"\n",\ +" gets $fileId line\n",\ +" close $fileId\n",\ +" if { [lindex $line 0] == \"\\#nglineplotinfo\" } {\n",\ +" set visoptions.lineplotdatadescr [lrange $line 1 end] \n",\ +" } {\n",\ +" set visoptions.lineplotdatadescr \"\"\n",\ +" for { set i 0 } { $i < [llength $line] } { incr i } {\n",\ +" lappend visoptions.lineplotdatadescr \"data[expr $i+1]\"\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" for { set i 0 } { $i < [llength ${visoptions.lineplotdatadescr}] } { incr i } {\n",\ +" ${visoptions.lineplotxcoordselector} add command $i -label [lindex ${visoptions.lineplotdatadescr} $i]\n",\ +" }\n",\ +" for { set i 0 } { $i < [llength ${visoptions.lineplotdatadescr}] } { incr i } {\n",\ +" ${visoptions.lineplotycoordselector} add command $i -label [lindex ${visoptions.lineplotdatadescr} $i]\n",\ +" }\n",\ +"\n",\ +" if { $saveusingx < [llength ${visoptions.lineplotdatadescr}] } {\n",\ +" set visoptions.lineplotusingx $saveusingx\n",\ +" } {\n",\ +" set visoptions.lineplotusingx 0\n",\ +" }\n",\ +" if { $saveusingy < [llength ${visoptions.lineplotdatadescr}] } {\n",\ +" set visoptions.lineplotusingy $saveusingy\n",\ +" } {\n",\ +" set visoptions.lineplotusingy 1\n",\ +" } \n",\ +" }\n",\ +"\n",\ +" pack $w.filesettings.refresh\n",\ +"\n",\ +"\n",\ +" frame $w.filesettings.using\n",\ +"\n",\ +" global visoptions.lineplotdatadescr\n",\ +" \n",\ +" tixOptionMenu $w.filesettings.using.xco -label \"X-Coord:\"\\\n",\ +" -options {\n",\ +" label.width 8\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +" for { set i 0 } { $i < [llength ${visoptions.lineplotdatadescr}] } { incr i } {\n",\ +" $w.filesettings.using.xco add command $i -label [lindex ${visoptions.lineplotdatadescr} $i]\n",\ +" }\n",\ +" $w.filesettings.using.xco config -variable visoptions.lineplotusingx\n",\ +" \n",\ +" tixOptionMenu $w.filesettings.using.yco -label \"Y-Coord:\"\\\n",\ +" -options {\n",\ +" label.width 8\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +" for { set i 0 } { $i < [llength ${visoptions.lineplotdatadescr}] } { incr i } {\n",\ +" $w.filesettings.using.yco add command $i -label [lindex ${visoptions.lineplotdatadescr} $i]\n",\ +" }\n",\ +" $w.filesettings.using.yco config -variable visoptions.lineplotusingy\n",\ +"\n",\ +" global visoptions.lineplotxcoordselector\n",\ +" global visoptions.lineplotycoordselector\n",\ +" set visoptions.lineplotxcoordselector $w.filesettings.using.xco\n",\ +" set visoptions.lineplotycoordselector $w.filesettings.using.yco\n",\ +" \n",\ +"\n",\ +" pack $w.filesettings.using.xco $w.filesettings.using.yco -side left\n",\ +" pack $w.filesettings.using\n",\ +"\n",\ +" pack $w.filesettings -fill x -ipady 3\n",\ +" \n",\ +" frame $w.settings -relief groove -borderwidth 3\n",\ +" label $w.settings.title -text \"\\nSettings\\n\"\n",\ +" pack $w.settings.title\n",\ +"\n",\ +" frame $w.settings.minmax \n",\ +" checkbutton $w.settings.minmax.autoscale -text \"Autoscale\" -variable visoptions.lineplotautoscale\n",\ +" tixControl $w.settings.minmax.xmin -label \"Min. x: \" \\\n",\ +" -integer false -variable visoptions.lineplotxmin \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 8\n",\ +" label.anchor e\n",\ +" } \n",\ +" tixControl $w.settings.minmax.xmax -label \"Max. x: \" \\\n",\ +" -integer false -variable visoptions.lineplotxmax \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 8\n",\ +" label.anchor e\n",\ +" } \n",\ +" tixControl $w.settings.minmax.ymin -label \"Min. y: \" \\\n",\ +" -integer false -variable visoptions.lineplotymin \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 8\n",\ +" label.anchor e\n",\ +" } \n",\ +" tixControl $w.settings.minmax.ymax -label \"Max. y: \" \\\n",\ +" -integer false -variable visoptions.lineplotymax \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 8\n",\ +" label.anchor e\n",\ +" } \n",\ +" \n",\ +"\n",\ +" pack $w.settings.minmax.autoscale $w.settings.minmax.xmin $w.settings.minmax.xmax \\\n",\ +" $w.settings.minmax.ymin $w.settings.minmax.ymax -side left\n",\ +"\n",\ +" pack $w.settings.minmax\n",\ +"\n",\ +" \n",\ +" label $w.settings.empty1 -text \"\"\n",\ +" pack $w.settings.empty1\n",\ +"\n",\ +" frame $w.settings.plotsize\n",\ +"\n",\ +" tixControl $w.settings.plotsize.xsize -label \"Plotsize x: \"\\\n",\ +" -integer true -variable visoptions.lineplotsizex \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 13\n",\ +" label.anchor e\n",\ +" } \n",\ +" tixControl $w.settings.plotsize.ysize -label \"y: \"\\\n",\ +" -integer true -variable visoptions.lineplotsizey \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 3\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" pack $w.settings.plotsize.xsize $w.settings.plotsize.ysize -side left\n",\ +"\n",\ +" pack $w.settings.plotsize\n",\ +"\n",\ +" label $w.settings.empty2 -text \"\"\n",\ +" pack $w.settings.empty2\n",\ +" \n",\ +"\n",\ +" tixOptionMenu $w.settings.color -label \"Linecolor: \" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +" foreach step { red black blue green yellow } {\n",\ +" $w.settings.color add command $step -label $step\n",\ +" }\n",\ +" $w.settings.color config -variable visoptions.lineplotcolor\n",\ +"\n",\ +" pack $w.settings.color\n",\ +"\n",\ +"\n",\ +" pack $w.settings\n",\ +"\n",\ +" set datax \"\"\n",\ +" set datay \"\"\n",\ +" set xmin 0\n",\ +" set xmax 0\n",\ +" set ymin 0\n",\ +" set ymax 0\n",\ +"\n",\ +" frame $w.plots -relief groove -borderwidth 3\n",\ +"\n",\ +" tixOptionMenu $w.plots.selplot -label \"Selected Plot: \" \\\n",\ +" -options {\n",\ +" label.width 19\n",\ +" label.anchor e\n",\ +" menubutton.width 15\n",\ +" } \n",\ +" $w.plots.selplot add command none -label \"None\"\n",\ +"\n",\ +" $w.plots.selplot config -variable visoptions.lineplotselected\n",\ +"\n",\ +" global visoptions.lineplotselector\n",\ +" set visoptions.lineplotselector $w.plots.selplot\n",\ +"\n",\ +" \n",\ +"\n",\ +" button $w.plots.new -text \"Generate New Plot\" -command {\n",\ +" if { ${visoptions.lineplotselectedeval} != 0} {\n",\ +" set visoptions.lineplotfile [lindex ${visoptions.evaluatefilenames} ${visoptions.lineplotselectedeval}]\n",\ +" }\n",\ +"\n",\ +" getlineplotdata datax datay xmin xmax ymin ymax\n",\ +"\n",\ +" puts stdout \"xmin $xmin xmax $xmax ymin $ymin ymax $ymax\"\n",\ +"\n",\ +" global visoptions.lineplotautoscale\n",\ +"\n",\ +" if {! ${visoptions.lineplotautoscale}} {\n",\ +" puts \"using set min/max values\"\n",\ +" set xmin ${visoptions.lineplotxmin}\n",\ +" set xmax ${visoptions.lineplotxmax}\n",\ +" set ymin ${visoptions.lineplotymin}\n",\ +" set ymax ${visoptions.lineplotymax}\n",\ +" }\n",\ +" \n",\ +" incr visoptions.lineplotcurrentnum\n",\ +" \n",\ +" set ident .newplot${visoptions.lineplotcurrentnum}\n",\ +" set plotinfo \"\"\n",\ +" \n",\ +" createlineplot ${visoptions.lineplotsizex} ${visoptions.lineplotsizey} \\\n",\ +" $ident \"Lineplot ${visoptions.lineplotcurrentnum}\" \\\n",\ +" $xmin $xmax $ymin $ymax plotinfo\n",\ +" \n",\ +" lappend visoptions.lineplotinfos $plotinfo\n",\ +"\n",\ +" \n",\ +" ${visoptions.lineplotselector} add command ${visoptions.lineplotcurrentnum} -label \"Lineplot ${visoptions.lineplotcurrentnum}\"\n",\ +"\n",\ +" addplotline $ident $datax $datay $plotinfo ${visoptions.lineplotcolor}\n",\ +" }\n",\ +" \n",\ +" button $w.plots.addto -text \"Add to Selected Plot\" -command {\n",\ +" if { ${visoptions.lineplotselectedeval} != 0} {\n",\ +" set visoptions.lineplotfile [lindex ${visoptions.evaluatefilenames} ${visoptions.lineplotselectedeval}]\n",\ +" }\n",\ +"\n",\ +" if { ${visoptions.lineplotselected} != \"none\" } {\n",\ +"\n",\ +" getlineplotdata datax datay xmin xmax ymin ymax\n",\ +"\n",\ +" set ident .newplot${visoptions.lineplotselected}\n",\ +" set plotinfo [lindex ${visoptions.lineplotinfos} ${visoptions.lineplotselected}]\n",\ +"\n",\ +" addplotline $ident $datax $datay $plotinfo ${visoptions.lineplotcolor}\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" \n",\ +" \n",\ +" pack $w.plots.new $w.plots.addto $w.plots.selplot\n",\ +" \n",\ +" \n",\ +" pack $w.plots -fill x -ipady 3\n",\ +" \n",\ +"\n",\ +"\n",\ +" button $w.close -text \"Close\" -command \"destroy $w\"\n",\ +" pack $w.close\n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +200+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"2D Lineplots\"\n",\ +"\n",\ +" focus $w\n",\ +" \n",\ +"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set fieldlinesdialog_pop1 0\n",\ +"\n",\ +"\n",\ +"proc fieldlinesdialog { } {\n",\ +" \n",\ +" set w .fieldlines_dlg\n",\ +"\n",\ +" global fieldlinesdialog_pop1\n",\ +" set fieldlinesdialog_pop1 1\n",\ +"\n",\ +" \n",\ +" if {[winfo exists .fieldlines_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" \n",\ +" toplevel $w\n",\ +"\n",\ +" tixNoteBook $w.nb -ipadx 6 -ipady 6\n",\ +"\n",\ +" $w.nb add draw -label \"Draw\"\n",\ +" $w.nb add settings -label \"Settings\"\n",\ +"\n",\ +" pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top\n",\ +"\n",\ +"\n",\ +" \n",\ +" set f [$w.nb subwidget draw]\n",\ +" \n",\ +"\n",\ +" frame $f.general\n",\ +"\n",\ +" \n",\ +" checkbutton $f.general.enable -text \"Enable Fieldlines\" \\\n",\ +" -variable visoptions.drawfieldlines \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; \n",\ +" redraw \n",\ +" }\n",\ +" tixControl $f.general.num -label \"Num: \" -integer true \\\n",\ +" -variable visoptions.numfieldlines \\\n",\ +" -command { Ng_Vis_Set parameters; redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 12\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" \n",\ +" pack $f.general.enable $f.general.num -side left\n",\ +"\n",\ +" pack $f.general\n",\ +"\n",\ +" label $f.labe0 -text \" \"\n",\ +"\n",\ +" pack $f.labe0\n",\ +"\n",\ +" frame $f.general1\n",\ +" \n",\ +" checkbutton $f.general1.randomstart -text \"Field dependent density \" \\\n",\ +" -variable visoptions.fieldlinesrandomstart \\\n",\ +" -command { Ng_Vis_Set parameters; redraw}\n",\ +"\n",\ +" \n",\ +" checkbutton $f.general1.redrawperiodic -text \"Animate periodic\" \\\n",\ +" -variable visoptions.redrawperiodic \\\n",\ +" -command { \n",\ +" redrawperiodic\n",\ +" Ng_Vis_Set parameters; \n",\ +" redraw \n",\ +" }\n",\ +"\n",\ +" pack $f.general1.randomstart $f.general1.redrawperiodic -side left\n",\ +"\n",\ +" pack $f.general1\n",\ +"\n",\ +"\n",\ +"\n",\ +" label $f.lab0 -text \" \"\n",\ +"\n",\ +" pack $f.lab0\n",\ +"\n",\ +"\n",\ +" \n",\ +" tixOptionMenu $f.vecfun -label \"Vector Function: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" }\n",\ +" $f.vecfun add command none -label None \n",\ +" for { set i 1 } { $i <= [Ng_Vis_Field getnfieldnames] } { incr i } {\n",\ +" set fname [Ng_Vis_Field getfieldname $i]\n",\ +" set fcomp [Ng_Vis_Field getfieldcomponents $i]\n",\ +" set iscomplex [Ng_Vis_Field iscomplex $i]\n",\ +" set sdim [Ng_Vis_Field getdimension]\n",\ +" if { $iscomplex == 1 } { set fcomp [expr $fcomp / 2] }\n",\ +" if { ($fcomp == $sdim) || ($fcomp == 3) } {\n",\ +" $f.vecfun add command $fname -label $fname\n",\ +" } \n",\ +" }\n",\ +" $f.vecfun configure -variable visoptions.fieldlinesvecfunction\n",\ +" $f.vecfun configure -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" pack $f.vecfun\n",\ +" \n",\ +"\n",\ +"\n",\ +" label $f.lab00 -text \" \"\n",\ +"\n",\ +" pack $f.lab00\n",\ +"\n",\ +" frame $f.phasesettings\n",\ +"\n",\ +" checkbutton $f.phasesettings.onephase -text \"Fix Phase\" -variable visoptions.fieldlinesonlyonephase\n",\ +" scale $f.phasesettings.phase -orient horizontal -length 300 -from 0 -to 360 \\\n",\ +" -label \"phi\" \\\n",\ +" -resolution 1 \\\n",\ +" -variable visoptions.fieldlinesphase \\\n",\ +" -command { popupcheckredraw3 fieldlinesdialog_pop1 }\n",\ +"\n",\ +" pack $f.phasesettings.onephase $f.phasesettings.phase -side left\n",\ +" \n",\ +" pack $f.phasesettings\n",\ +"\n",\ +"\n",\ +"\n",\ +" label $f.lab1 -text \" \"\n",\ +"\n",\ +" pack $f.lab1\n",\ +"\n",\ +"\n",\ +" \n",\ +" frame $f.boxsettings -relief groove -borderwidth 3\n",\ +" frame $f.boxsettings.title\n",\ +" radiobutton $f.boxsettings.title.choose -variable visoptions.fieldlinesstartarea \\\n",\ +" -value box -text \"Startpoints in Box\"\n",\ +"\n",\ +" pack $f.boxsettings.title.choose -side left\n",\ +"\n",\ +" pack $f.boxsettings.title\n",\ +"\n",\ +" frame $f.boxsettings.points\n",\ +"\n",\ +" label $f.boxsettings.points.lab2 -text \"Pmin\";\n",\ +" entry $f.boxsettings.points.ent1x -width 8 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesstartareap1x\n",\ +" entry $f.boxsettings.points.ent1y -width 8 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesstartareap1y\n",\ +" entry $f.boxsettings.points.ent1z -width 8 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesstartareap1z\n",\ +" label $f.boxsettings.points.lab3 -text \" Pmax\";\n",\ +" entry $f.boxsettings.points.ent2x -width 8 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesstartareap2x\n",\ +" entry $f.boxsettings.points.ent2y -width 8 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesstartareap2y\n",\ +" entry $f.boxsettings.points.ent2z -width 8 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesstartareap2z\n",\ +" \n",\ +" pack $f.boxsettings.points\n",\ +" pack $f.boxsettings.points.lab2 $f.boxsettings.points.ent1x $f.boxsettings.points.ent1y $f.boxsettings.points.ent1z -side left\n",\ +" pack $f.boxsettings.points.lab3 $f.boxsettings.points.ent2x $f.boxsettings.points.ent2y $f.boxsettings.points.ent2z -side left\n",\ +"\n",\ +" button $f.boxsettings.settobb -text \"Bounding Box\" -command {\n",\ +" set bbox [Ng_MeshInfo bbox]\n",\ +" set visoptions.fieldlinesstartareap1x [lindex $bbox 0]\n",\ +" set visoptions.fieldlinesstartareap2x [lindex $bbox 1]\n",\ +" set visoptions.fieldlinesstartareap1y [lindex $bbox 2]\n",\ +" set visoptions.fieldlinesstartareap2y [lindex $bbox 3]\n",\ +" set visoptions.fieldlinesstartareap1z [lindex $bbox 4]\n",\ +" set visoptions.fieldlinesstartareap2z [lindex $bbox 5]\n",\ +" }\n",\ +"\n",\ +" pack $f.boxsettings.settobb\n",\ +" \n",\ +" \n",\ +" pack $f.boxsettings -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" frame $f.facesettings -relief groove -borderwidth 3\n",\ +" frame $f.facesettings.title\n",\ +" radiobutton $f.facesettings.title.choose -variable visoptions.fieldlinesstartarea \\\n",\ +" -value face -text \"Startpoints on Face\"\n",\ +"\n",\ +" pack $f.facesettings.title.choose -side left\n",\ +"\n",\ +" pack $f.facesettings.title\n",\ +" \n",\ +" frame $f.facesettings.index\n",\ +" label $f.facesettings.index.lab -text \"face index:\"\n",\ +" label $f.facesettings.index.ent -text 1 -padx 4\n",\ +"\n",\ +" pack $f.facesettings.index.lab $f.facesettings.index.ent -side left\n",\ +"\n",\ +" pack $f.facesettings.index\n",\ +" \n",\ +" pack $f.facesettings -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" global visoptions.fieldlinesfilename\n",\ +"\n",\ +" frame $f.filesettings -relief groove -borderwidth 3\n",\ +" frame $f.filesettings.title\n",\ +" radiobutton $f.filesettings.title.choose -variable visoptions.fieldlinesstartarea \\\n",\ +" -value file -text \"Startpoints from File\"\n",\ +"\n",\ +" pack $f.filesettings.title.choose -side left\n",\ +"\n",\ +" pack $f.filesettings.title\n",\ +"\n",\ +" frame $f.filesettings.sfn\n",\ +"\n",\ +" button $f.filesettings.sfn.bb -text \"Browse\" \\\n",\ +" -command {\n",\ +" set types {\n",\ +" { \"Netgen Fieldlines\" {.nef} }\n",\ +" }\n",\ +" set visoptions.fieldlinesfilename [tk_getOpenFile -filetypes $types -defaultextension \".nef\"]\n",\ +" }\n",\ +"\n",\ +" \n",\ +" entry $f.filesettings.sfn.fn -width 50 -relief sunken \\\n",\ +" -textvariable visoptions.fieldlinesfilename\n",\ +"\n",\ +" pack $f.filesettings.sfn.bb $f.filesettings.sfn.fn -side left\n",\ +"\n",\ +" pack $f.filesettings.sfn\n",\ +"\n",\ +" pack $f.filesettings -fill x -ipady 3\n",\ +" \n",\ +"\n",\ +"\n",\ +" \n",\ +" \n",\ +" set g [$w.nb subwidget settings]\n",\ +"\n",\ +" frame $g.linesettings -relief groove -borderwidth 3\n",\ +" label $g.linesettings.title -text \"\\nLine Settings\\n\"\n",\ +" tixControl $g.linesettings.length -label \"rel. Length: \" -integer false \\\n",\ +" -variable visoptions.fieldlineslength -min 0.00001 -max 10000 -step 0.1 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" }\n",\ +"\n",\ +" tixControl $g.linesettings.maxpoints -label \"max. Points: \" -integer true \\\n",\ +" -variable visoptions.fieldlinesmaxpoints -min 0 -max 10000 -step 1 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" }\n",\ +"\n",\ +" tixControl $g.linesettings.thick -label \"rel. Thickness: \" -integer false \\\n",\ +" -variable visoptions.fieldlinesthickness -min 1e-10 -max 0.5 -step 0.001 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" }\n",\ +"\n",\ +" pack $g.linesettings.title $g.linesettings.length $g.linesettings.maxpoints $g.linesettings.thick\n",\ +"\n",\ +" pack $g.linesettings -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +" global visoptions.fieldlinestolerance\n",\ +"\n",\ +" frame $g.odesettings -relief groove -borderwidth 3\n",\ +" label $g.odesettings.title -text \"\\nODE Settings\\n\"\n",\ +" tixControl $g.odesettings.tol -label \"rel. Tolerance: \" -integer false \\\n",\ +" -variable visoptions.fieldlinestolerance -min 0.00001 -max 1 -step 0.01 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +"\n",\ +" tixOptionMenu $g.odesettings.rktype -label \"RK-Type \" \\\n",\ +" -options {\n",\ +" label.width 20\n",\ +" label.anchor e\n",\ +" menubutton.width 25\n",\ +" }\n",\ +" $g.odesettings.rktype add command euler -label \"Euler, order 1\"\n",\ +" $g.odesettings.rktype add command eulercauchy -label \"Euler-Cauchy, order 2\"\n",\ +" $g.odesettings.rktype add command simpson -label \"Simpson, order 3\"\n",\ +" $g.odesettings.rktype add command crungekutta -label \"classical Runge-Kutta, order 4\"\n",\ +" $g.odesettings.rktype configure -variable visoptions.fieldlinesrktype\n",\ +" $g.odesettings.rktype configure -command { Ng_Vis_Set parameters; redraw }\n",\ +" \n",\ +" pack $g.odesettings.title $g.odesettings.tol $g.odesettings.rktype\n",\ +"\n",\ +" pack $g.odesettings -fill x -ipady 3\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu \n",\ +"\n",\ +" button $w.bu.calc -text \"Build Fieldlines\" -command { \n",\ +" if { ${visoptions.fieldlinesvecfunction} == \"none\" } {\n",\ +" bgerror \"Please select the vector function first!\"\n",\ +" } {\n",\ +" set visoptions.drawfieldlines 1\n",\ +" Ng_Vis_Set parameters\n",\ +" Ng_BuildFieldLines\n",\ +" redraw \n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.bu.help -text \"Help\" -command {\n",\ +" if {[winfo exists .fieldlines_help] == 1} {\n",\ +" wm withdraw .fieldlines_help\n",\ +" wm deiconify .fieldlines_help\n",\ +" focus .fieldlines_help\n",\ +" } {\n",\ +" toplevel .fieldlines_help\n",\ +"\n",\ +" tixScrolledText .fieldlines_help.ht -scrollbar y\n",\ +" set text [.fieldlines_help.ht subwidget text]\n",\ +"\n",\ +" $text configure -setgrid true -wrap word \n",\ +"\n",\ +" $text tag configure bold -font *-*-bold-*-*-*-*\n",\ +"\n",\ +" \n",\ +" $text insert end \\\n",\ +" \"Draw menu\\n \\n\" bold\n",\ +" $text insert end \\\n",\ +" \"Enable Fieldlines\\n To turn on and off the calculated fieldlines. (Has to be turned on to start the calculation)\\n\"\n",\ +" $text insert end \\\n",\ +" \"Num\\n Number of fieldlines to calculate. (May not be used exactly.)\"\n",\ +" $text insert end \\\n",\ +" \"Field dependent density\\n There will be more fieldline startpoints where the field is stronger\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"Animate periodic\\n (for quasistationary fields) The fieldlines of the different phase angles are animated.\\n ATTENTION: \\\"Fix Phase\\\" has to be turned off\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"Vector Function\\n The function fixing the direction of the lines\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"Fix Phase\\n (for quasistationary fields) Only calculate and draw fieldlines for one special phase angle.\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"Startpoints in Box\\n Set the startpoints inside the box \\[Pmin1,Pmax1\\] x \\[Pmin2,Pmax2\\] x \\[Pmin3,Pmax3\\]\\n\"\n",\ +" $text insert end \\\n",\ +" \" With the button \\\"Bounding Box\\\" the whole bounding box of the geometry is selected.\\n\\n\" \n",\ +" $text insert end \\\n",\ +" \"Startpoints on Face\\n All startpoints will be set on one face. This face is selected by double-clicking with the mouse.\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"Startpoints from File\\n The startpoint information will be read from the selected file.\\n The entries in the file can be as follows:\\n\"\n",\ +" $text insert end \\\n",\ +" \" point \\n set a (potential) startpoint\\n\"\n",\ +" $text insert end \\\n",\ +" \" line \\n set n (potential) startpoints on the line from (x1,y1,z1) to (x2,y2,z2)\\n\"\n",\ +" $text insert end \\\n",\ +" \" box \\n set n (potential) startpoints inside the box \\[x1,x2\\] x \\[y1,y2\\] x \\[z1,z2\\]\\n\"\n",\ +" $text insert end \\\n",\ +" \" ATTENTION: These are potential startpoints.\\n The total number of startpoints will be bounded by the \\\"Num\\\"-parameter.\\n \\n \\n \\n\"\n",\ +" $text insert end \\\n",\ +" \"Settings Menu\\n \\n\" bold\n",\ +" $text insert end \\\n",\ +" \"rel. Length\\n The maximal length of a fieldline relative to the diameter of the geometry.\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"max. Points\\n The maximum number of Runge-Kutta steps.\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"rel. Thickness\\n The thickness of the fieldlines relative to the diameter of the geometry.\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"rel. Tolerance\\n The tolerance for the step-length control of the Runge-Kutta method.\\n\\n\"\n",\ +" $text insert end \\\n",\ +" \"RK-Type\\n Which Runge-Kutta scheme to use\\n \\n \\n \\n\"\n",\ +" $text insert end \\\n",\ +" \"Button \\\"Build Fieldlines\\\"\\n\" bold\n",\ +" $text insert end \\\n",\ +" \" Build the fieldlines.\"\n",\ +" \n",\ +"\n",\ +" $text configure -state disabled\n",\ +"\n",\ +" pack .fieldlines_help.ht -expand yes -fill both\n",\ +"\n",\ +" wm withdraw .fieldlines_help\n",\ +" wm geom .fieldlines_help +300+200\n",\ +" wm deiconify .fieldlines_help\n",\ +" wm title .fieldlines_help \"Fieldlines Help\"\n",\ +" focus .fieldlines_help\n",\ +" \n",\ +" }\n",\ +"\n",\ +"\n",\ +" }\n",\ +"\n",\ +" button $w.bu.cancel -text \"Done\" -command \"destroy $w\"\n",\ +" pack $w.bu.calc $w.bu.help $w.bu.cancel -side left -expand yes\n",\ +" \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +200+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Fieldlines\"\n",\ +" focus $w\n",\ +"\n",\ +" }\n",\ +"\n",\ +" global visoptions.fieldlinesstartface\n",\ +"\n",\ +" \n",\ +" set f [$w.nb subwidget draw]\n",\ +" set visoptions.fieldlinesstartface [Ng_BCProp getactive]\n",\ +" $f.facesettings.index.ent configure -text ${visoptions.fieldlinesstartface}\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set visual_dialog_pop1 0\n",\ +"set visual_dialog_pop2 0\n",\ +"set visual_dialog_pop3 0\n",\ +"set visual_dialog_pop4 0\n",\ +"set visual_dialog_pop5 0\n",\ +"set visual_dialog_pop6 0\n",\ +"set visual_dialog_pop7 0\n",\ +"\n",\ +"proc visual_dialog { } {\n",\ +"\n",\ +" set w .visoptions_dlg\n",\ +"\n",\ +" \n",\ +" global visual_dialog_pop1\n",\ +" global visual_dialog_pop2\n",\ +" global visual_dialog_pop3\n",\ +" global visual_dialog_pop4\n",\ +" global visual_dialog_pop5\n",\ +" global visual_dialog_pop6\n",\ +" global visual_dialog_pop7\n",\ +" set visual_dialog_pop1 1\n",\ +" set visual_dialog_pop2 1\n",\ +" set visual_dialog_pop3 1\n",\ +" set visual_dialog_pop4 1\n",\ +" set visual_dialog_pop5 1\n",\ +" set visual_dialog_pop6 1\n",\ +" set visual_dialog_pop7 1\n",\ +" \n",\ +" if {[winfo exists .visoptions_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w\n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +"\n",\ +" checkbutton $w.imaginary -text \"Imaginary Part\" \\\n",\ +" -variable visoptions.imaginary \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" \n",\ +" frame $w.texframe\n",\ +"\n",\ +" checkbutton $w.texframe.usetexture -text \"Use Textures (\" \\\n",\ +" -variable visoptions.usetexture \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +" \n",\ +" checkbutton $w.texframe.lintexture -text \"Linear )\" \\\n",\ +" -variable visoptions.lineartexture \\\n",\ +" -command { Ng_Vis_Set parametersrange; redraw }\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +" checkbutton $w.invcolor -text \"Inverse Color\" \\\n",\ +" -variable visoptions.invcolor \\\n",\ +" -command { Ng_Vis_Set parametersrange; redraw }\n",\ +" \n",\ +" checkbutton $w.redrawperiodic -text \"Animate periodic\" \\\n",\ +" -variable visoptions.redrawperiodic \\\n",\ +" -command { \n",\ +" redrawperiodic\n",\ +" Ng_Vis_Set parameters; \n",\ +" redraw \n",\ +" }\n",\ +" \n",\ +"\n",\ +" checkbutton $w.logscale -text \"Log Scale\" \\\n",\ +" -variable visoptions.logscale \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +" \n",\ +" checkbutton $w.lineartexture -text \"Use Linear Texture\" \\\n",\ +" -variable visoptions.lineartexture \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +" \n",\ +" scale $w.numcols -orient horizontal -length 100 -from 0 -to 50 \\\n",\ +" -resolution 1 \\\n",\ +" -variable visoptions.numtexturecols \\\n",\ +" -command { popupcheckredraw visual_dialog_pop1 }\n",\ +"\n",\ +" checkbutton $w.showclipsolution -text \"Draw Clipping Plane Solution\" \\\n",\ +" -variable visoptions.showclipsolution \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" checkbutton $w.showsurfsolution -text \"Draw Surface Solution\" \\\n",\ +" -variable visoptions.showsurfacesolution \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.grid -relief groove -borderwidth 3\n",\ +" scale $w.grid.size -orient horizontal -length 100 -from 1 -to 200 \\\n",\ +" -label \"Grid\" \\\n",\ +" -resolution 1 \\\n",\ +" -variable visoptions.gridsize \\\n",\ +" -command { popupcheckredraw visual_dialog_pop2 }\n",\ +" \n",\ +"\n",\ +" scale $w.grid.xoffset -orient horizontal -length 80 -from 0 -to 1 \\\n",\ +" -label \"x-Offset\" \\\n",\ +" -resolution 0.05 \\\n",\ +" -variable visoptions.xoffset \\\n",\ +" -command { popupcheckredraw visual_dialog_pop3 }\n",\ +"\n",\ +" scale $w.grid.yoffset -orient horizontal -length 80 -from 0 -to 1 \\\n",\ +" -label \"y-Offset\" \\\n",\ +" -resolution 0.05 \\\n",\ +" -variable visoptions.yoffset \\\n",\ +" -command { popupcheckredraw visual_dialog_pop4 }\n",\ +"\n",\ +"\n",\ +" pack $w.showsurfsolution\n",\ +" pack $w.grid -fill x -ipady 3\n",\ +" pack $w.grid.size $w.grid.xoffset $w.grid.yoffset -side left -expand yes\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +" frame $w.deform -relief groove -borderwidth 3\n",\ +" checkbutton $w.deform.cb -text \"Deformation\" \\\n",\ +" -variable visoptions.deformation \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" tixControl $w.deform.sc1 -label \"Scale: \" -integer false \\\n",\ +" -variable visoptions.scaledeform1 \\\n",\ +" -command { Ng_Vis_Set parameters; redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 7\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" scale $w.deform.sc2 -orient horizontal -length 100 -from 0 -to 1 \\\n",\ +" -resolution 0.01 \\\n",\ +" -variable visoptions.scaledeform2 \\\n",\ +" -command { popupcheckredraw visual_dialog_pop5 }\n",\ +"\n",\ +" pack $w.deform -fill x -ipady 2\n",\ +" pack $w.deform.cb $w.deform.sc1 $w.deform.sc2 -side left -expand yes\n",\ +" \n",\ +"\n",\ +" frame $w.as -relief groove -borderwidth 3\n",\ +" checkbutton $w.as.autoscale -text \"Autoscale\" \\\n",\ +" -variable visoptions.autoscale \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" tixControl $w.as.minval -label \"Min-value: \" -integer false \\\n",\ +" -variable visoptions.mminval \\\n",\ +" -command { Ng_Vis_Set parametersrange; redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 12\n",\ +" label.anchor e\n",\ +" } \n",\ +" tixControl $w.as.maxval -label \"Max-value: \" -integer false \\\n",\ +" -variable visoptions.mmaxval \\\n",\ +" -command { Ng_Vis_Set parametersrange; redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 12\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" pack $w.as -fill x -ipady 3\n",\ +" pack $w.as.autoscale $w.as.minval $w.as.maxval -side left\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.iso -relief groove -borderwidth 3\n",\ +" pack $w.iso -fill x -ipady 3\n",\ +"\n",\ +" frame $w.iso.cb\n",\ +" pack $w.iso.cb -side left\n",\ +"\n",\ +" checkbutton $w.iso.cb.isolines -text \"Iso-lines\" \\\n",\ +" -variable visoptions.isolines \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +" pack $w.iso.cb.isolines -side top\n",\ +"\n",\ +" checkbutton $w.iso.cb.isosurf -text \"Iso-Surface\" \\\n",\ +" -variable visoptions.isosurf \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +" pack $w.iso.cb.isosurf -side top\n",\ +"\n",\ +"\n",\ +"\n",\ +" scale $w.iso.numiso -orient horizontal -length 100 -from 2 -to 50 \\\n",\ +" -label \"\" \\\n",\ +" -resolution 1 \\\n",\ +" -variable visoptions.numiso \\\n",\ +" -command { popupcheckredraw visual_dialog_pop6 }\n",\ +"\n",\ +" pack $w.iso.numiso -side left\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.iso.subdiv\n",\ +" radiobutton $w.iso.subdiv.zero -text \"0\" -variable visoptions.subdivisions -value 0 \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; redraw;\n",\ +" }\n",\ +" radiobutton $w.iso.subdiv.one -text \"1\" -variable visoptions.subdivisions -value 1 \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; redraw;\n",\ +" }\n",\ +" radiobutton $w.iso.subdiv.two -text \"2\" -variable visoptions.subdivisions -value 2 \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; redraw;\n",\ +" }\n",\ +" radiobutton $w.iso.subdiv.three -text \"3\" -variable visoptions.subdivisions -value 3 \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; redraw;\n",\ +" }\n",\ +" radiobutton $w.iso.subdiv.four -text \"4\" -variable visoptions.subdivisions -value 4 \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; redraw;\n",\ +" }\n",\ +" radiobutton $w.iso.subdiv.five -text \"5\" -variable visoptions.subdivisions -value 5 \\\n",\ +" -command { \n",\ +" Ng_Vis_Set parameters; redraw;\n",\ +" }\n",\ +"\n",\ +" label $w.iso.subdiv.text -text \"subdivision\"\n",\ +"\n",\ +" pack $w.iso.subdiv -side right -ipadx 10\n",\ +"\n",\ +" pack $w.iso.subdiv.text -side top\n",\ +" pack $w.iso.subdiv.zero $w.iso.numiso -side left\n",\ +" pack $w.iso.subdiv.one $w.iso.numiso -side left\n",\ +" pack $w.iso.subdiv.two $w.iso.numiso -side left\n",\ +" pack $w.iso.subdiv.three $w.iso.numiso -side left\n",\ +" pack $w.iso.subdiv.four $w.iso.numiso -side left\n",\ +" pack $w.iso.subdiv.five $w.iso.numiso -side left\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" checkbutton $w.showcurves -text \"Show Curves\" \\\n",\ +" -variable visoptions.drawpointcurves \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" pack $w.showcurves\n",\ +"\n",\ +" frame $w.redraw -relief groove -borderwidth 3\n",\ +" checkbutton $w.redraw.auto -text \"Auto-redraw\" \\\n",\ +" -variable visoptions.autoredraw \n",\ +"\n",\ +" tixControl $w.redraw.val -label \" after (sec) \" -integer false \\\n",\ +" -variable visoptions.autoredrawtime \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 0\n",\ +" label.anchor w\n",\ +" } \n",\ +"\n",\ +" pack $w.redraw -fill x -ipady 3\n",\ +" pack $w.redraw.auto $w.redraw.val -side left\n",\ +"\n",\ +"\n",\ +"\n",\ +" tixControl $w.redraw.simtime -label \" Simulation Time (1e-6 s)\" -integer false \\\n",\ +" -variable visoptions.simulationtime \\\n",\ +" -command { \n",\ +" Ng_Vis_Set time ${visoptions.simulationtime}; \n",\ +" catch {NGS_Set time ${visoptions.simulationtime};}\n",\ +" redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 0\n",\ +" label.anchor w\n",\ +" } \n",\ +" pack $w.redraw.simtime -side left\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +" tixOptionMenu $w.clipsol -label \"Clipping Plane Sol: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" }\n",\ +"\n",\ +" set none 1\n",\ +" $w.clipsol add command none -label None\n",\ +" $w.clipsol add command scal -label \"Scalar Function\"\n",\ +" $w.clipsol add command vec -label \"Vector Function\"\n",\ +"\n",\ +" $w.clipsol configure -variable visoptions.clipsolution\n",\ +" $w.clipsol configure -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" pack $w.clipsol\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" tixOptionMenu $w.scalfun -label \"Scalar Function: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" }\n",\ +"\n",\ +" tixOptionMenu $w.vecfun -label \"Vector Function: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" }\n",\ +"\n",\ +"\n",\ +" $w.scalfun add command none -label None\n",\ +" for { set i 1 } { $i <= [Ng_Vis_Field getnfieldnames] } { incr i } {\n",\ +" set fname [Ng_Vis_Field getfieldname $i]\n",\ +" set fcomp [Ng_Vis_Field getfieldcomponents $i]\n",\ +" if { $fcomp == 1 } {\n",\ +" $w.scalfun add command $fname.1 -label $fname\n",\ +" } {\n",\ +" for { set j 1 } { $j <= $fcomp } { incr j } {\n",\ +" $w.scalfun add command $fname.$j -label \"$fname ($j)\"\n",\ +" }\n",\ +" $w.scalfun add command $fname.0 -label \"func ($fname)\"\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" $w.vecfun add command none -label None \n",\ +" for { set i 1 } { $i <= [Ng_Vis_Field getnfieldnames] } { incr i } {\n",\ +" set fname [Ng_Vis_Field getfieldname $i]\n",\ +" set fcomp [Ng_Vis_Field getfieldcomponents $i]\n",\ +" set iscomplex [Ng_Vis_Field iscomplex $i]\n",\ +" set sdim [Ng_Vis_Field getdimension]\n",\ +" if { $iscomplex == 1 } { set fcomp [expr $fcomp / 2] }\n",\ +" if { ($fcomp == $sdim) || ($fcomp == 3) } {\n",\ +" $w.vecfun add command $fname -label $fname\n",\ +" } \n",\ +" }\n",\ +"\n",\ +"\n",\ +" $w.scalfun configure -variable visoptions.scalfunction \n",\ +" $w.scalfun configure -command { Ng_Vis_Set parameters; redraw }\n",\ +" $w.vecfun configure -variable visoptions.vecfunction\n",\ +" $w.vecfun configure -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" tixOptionMenu $w.evaluate -label \"Evaluate: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" } \n",\ +" $w.evaluate add command abs -label \"|.|\"\n",\ +" $w.evaluate add command abstens -label \"|tensor|\"\n",\ +" $w.evaluate add command mises -label \"Mises\"\n",\ +" $w.evaluate add command main -label \"Main\"\n",\ +" $w.evaluate configure -variable visoptions.evaluate\n",\ +" $w.evaluate configure -command { \n",\ +" Ng_Vis_Set parameters; \n",\ +" redraw \n",\ +" }\n",\ +"\n",\ +" pack $w.scalfun $w.vecfun $w.evaluate\n",\ +"\n",\ +" tixControl $w.multidimcomp -label \"multidim-component: \" -integer true \\\n",\ +" -variable visoptions.multidimcomponent -min 0 \\\n",\ +" -command { Ng_Vis_Set parameters; redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +"\n",\ +" pack $w.multidimcomp\n",\ +"\n",\ +" pack $w.imaginary $w.logscale $w.texframe $w.invcolor $w.redrawperiodic\n",\ +" pack $w.texframe.usetexture $w.texframe.lintexture -side left -expand yes\n",\ +" \n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu -pady 5\n",\ +"\n",\ +" button $w.bu.showsol -text \"Show Solution\" -command { \n",\ +" set selectvisual solution\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" }\n",\ +" button $w.bu.clipping -text \"Clipping\" -command { \n",\ +" clippingdialog; \n",\ +" }\n",\ +" button $w.bu.fieldlines -text \"Fieldlines\" -command { \n",\ +" fieldlinesdialog; \n",\ +" }\n",\ +"\n",\ +" button $w.bu.lineplot -text \"2D Lineplot\" -command {\n",\ +" lineplotdialog;\n",\ +" }\n",\ +"\n",\ +" button $w.bu.done -text \"Close\" -command { \n",\ +" destroy .visoptions_dlg\n",\ +" }\n",\ +"\n",\ +" pack $w.bu.showsol $w.bu.clipping $w.bu.fieldlines $w.bu.lineplot $w.bu.done -side left -expand yes\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Visualization\"\n",\ +"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc reset_visual_dialog { } {\n",\ +" \n",\ +" set w .visoptions_dlg\n",\ +" \n",\ +" if {[winfo exists .visoptions_dlg] == 1} {\n",\ +" \n",\ +" \n",\ +" destroy $w.scalfun $w.vecfun $w.evaluate $w.multidimcomp\n",\ +" destroy $w.imaginary $w.logscale $w.texframe.usetexture $w.texframe.lintexture\n",\ +" destroy $w.texframe\n",\ +" destroy $w.invcolor $w.redrawperiodic\n",\ +" destroy $w.bu -pady 5\n",\ +" destroy $w.bu.showsol $w.bu.clipping $w.bu.fieldlines $w.bu.lineplot $w.bu.done -side left -expand yes\n",\ +" \n",\ +" \n",\ +" checkbutton $w.imaginary -text \"Imaginary Part\" \\\n",\ +" -variable visoptions.imaginary \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" frame $w.texframe\n",\ +"\n",\ +" checkbutton $w.texframe.usetexture -text \"Use Textures (\" \\\n",\ +" -variable visoptions.usetexture \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +" checkbutton $w.texframe.lintexture -text \"Linear )\" \\\n",\ +" -variable visoptions.lineartexture \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +" \n",\ +" checkbutton $w.invcolor -text \"Inverse Color\" \\\n",\ +" -variable visoptions.invcolor \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +" \n",\ +" checkbutton $w.redrawperiodic -text \"Animate periodic\" \\\n",\ +" -variable visoptions.redrawperiodic \\\n",\ +" -command { \n",\ +" redrawperiodic\n",\ +" Ng_Vis_Set parameters; \n",\ +" redraw \n",\ +" }\n",\ +" \n",\ +"\n",\ +" checkbutton $w.logscale -text \"Log Scale\" \\\n",\ +" -variable visoptions.logscale \\\n",\ +" -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +"\n",\ +" tixOptionMenu $w.scalfun -label \"Scalar Function: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" }\n",\ +"\n",\ +" tixOptionMenu $w.vecfun -label \"Vector Function: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" $w.scalfun add command none -label None\n",\ +" for { set i 1 } { $i <= [Ng_Vis_Field getnfieldnames] } { incr i } {\n",\ +" set fname [Ng_Vis_Field getfieldname $i]\n",\ +" set fcomp [Ng_Vis_Field getfieldcomponents $i]\n",\ +" if { $fcomp == 1 } {\n",\ +" $w.scalfun add command $fname.1 -label $fname\n",\ +" } {\n",\ +" for { set j 1 } { $j <= $fcomp } { incr j } {\n",\ +" $w.scalfun add command $fname.$j -label \"$fname ($j)\"\n",\ +" }\n",\ +" $w.scalfun add command $fname.0 -label \"func ($fname)\"\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" $w.vecfun add command none -label None \n",\ +" for { set i 1 } { $i <= [Ng_Vis_Field getnfieldnames] } { incr i } {\n",\ +" set fname [Ng_Vis_Field getfieldname $i]\n",\ +" set fcomp [Ng_Vis_Field getfieldcomponents $i]\n",\ +" set iscomplex [Ng_Vis_Field iscomplex $i]\n",\ +" set sdim [Ng_Vis_Field getdimension]\n",\ +" if { $iscomplex == 1 } { set fcomp [expr $fcomp / 2] }\n",\ +" if { ($fcomp == $sdim) || ($fcomp == 3) } {\n",\ +" $w.vecfun add command $fname -label $fname\n",\ +" } \n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" $w.scalfun configure -variable visoptions.scalfunction \n",\ +" $w.scalfun configure -command { Ng_Vis_Set parameters; redraw }\n",\ +" $w.vecfun configure -variable visoptions.vecfunction\n",\ +" $w.vecfun configure -command { Ng_Vis_Set parameters; redraw }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" tixOptionMenu $w.evaluate -label \"Evaluate: \" \\\n",\ +" -options {\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" menubutton.width 12\n",\ +" } \n",\ +" $w.evaluate add command abs -label \"|.|\"\n",\ +" $w.evaluate add command abstens -label \"|tensor|\"\n",\ +" $w.evaluate add command mises -label \"Mises\"\n",\ +" $w.evaluate add command main -label \"Main\"\n",\ +" $w.evaluate configure -variable visoptions.evaluate\n",\ +" $w.evaluate configure -command { \n",\ +" Ng_Vis_Set parameters; \n",\ +" redraw \n",\ +" }\n",\ +"\n",\ +" pack $w.scalfun $w.vecfun $w.evaluate\n",\ +"\n",\ +" tixControl $w.multidimcomp -label \"multidim-component: \" -integer true \\\n",\ +" -variable visoptions.multidimcomponent -min 0 \\\n",\ +" -command { Ng_Vis_Set parameters; redraw } \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 18\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +"\n",\ +" pack $w.multidimcomp\n",\ +"\n",\ +" pack $w.imaginary $w.logscale $w.texframe $w.invcolor $w.redrawperiodic\n",\ +" pack $w.texframe.usetexture $w.texframe.lintexture -side left -expand yes\n",\ +"\n",\ +"\n",\ +" frame $w.bu\n",\ +" pack $w.bu -pady 5\n",\ +"\n",\ +" button $w.bu.showsol -text \"Show Solution\" -command { \n",\ +" set selectvisual solution\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" }\n",\ +" button $w.bu.clipping -text \"Clipping\" -command { \n",\ +" clippingdialog; \n",\ +" }\n",\ +" button $w.bu.fieldlines -text \"Fieldlines\" -command { \n",\ +" fieldlinesdialog; \n",\ +" }\n",\ +"\n",\ +" button $w.bu.lineplot -text \"2D Lineplot\" -command {\n",\ +" lineplotdialog;\n",\ +" }\n",\ +"\n",\ +" button $w.bu.done -text \"Close\" -command { \n",\ +" destroy .visoptions_dlg\n",\ +" }\n",\ +"\n",\ +" pack $w.bu.showsol $w.bu.clipping $w.bu.fieldlines $w.bu.lineplot $w.bu.done -side left -expand yes\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +"\n",\ +"\n",\ +" }\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"set sockets.serverport 0\n",\ +"set sockets.serverhost \"localhost\"\n",\ +"set sockets.serverlistbox 0\n",\ +"set sockets.queuelistbox 0\n",\ +"set sockets.currentjoblistbox 0\n",\ +"set sockets.answerlistbox 0\n",\ +"set sockets.myidlabel -1\n",\ +"\n",\ +"\n",\ +"proc updateserverlist { } {\n",\ +" global sockets.serverlistbox\n",\ +" \n",\ +" set retval [Ng_Socket getserverlist]\n",\ +"\n",\ +" ${sockets.serverlistbox} delete 0 end\n",\ +"\n",\ +" for {set i 0} {$i < [llength $retval]} {incr i 3} {\n",\ +" ${sockets.serverlistbox} insert end \\\n",\ +" [format \"%-16s %6i %6i\" [lindex $retval $i] [lindex $retval [expr $i+1]] [lindex $retval [expr $i+2]]]\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"proc clientsocketdialog { } {\n",\ +" set w .clientsock_dlg\n",\ +" \n",\ +" if {[winfo exists .clientsock_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +" toplevel $w\n",\ +"\n",\ +" global sockets.serverhost\n",\ +" global sockets.serverport\n",\ +"\n",\ +" frame $w.general\n",\ +" frame $w.host\n",\ +" label $w.host.lab -text \"Serverhost: \"\n",\ +" entry $w.host.name -width 30 -relief sunken -textvariable sockets.serverhost\n",\ +"\n",\ +" pack $w.host.lab $w.host.name -side left\n",\ +" pack $w.host\n",\ +"\n",\ +" frame $w.ports\n",\ +" label $w.ports.lab1 -text \"Serverport: \"\n",\ +" entry $w.ports.statport -width 6 -relief sunken -textvariable sockets.serverport\n",\ +" \n",\ +" pack $w.ports.lab1 $w.ports.statport -side left\n",\ +" pack $w.ports\n",\ +"\n",\ +" frame $w.listboxes\n",\ +"\n",\ +" frame $w.listboxes.choosesocketframe\n",\ +"\n",\ +" tixScrolledListBox $w.listboxes.choosesocketframe.choosesocket -scrollbar auto\n",\ +"\n",\ +" global sockets.serverlistbox\n",\ +"\n",\ +" set sockets.serverlistbox [$w.listboxes.choosesocketframe.choosesocket subwidget listbox]\n",\ +"\n",\ +" ${sockets.serverlistbox} configure -width 35\n",\ +" ${sockets.serverlistbox} configure -selectmode browse\n",\ +" ${sockets.serverlistbox} configure -exportselection false\n",\ +"\n",\ +" button $w.addserver -text \"Add ServerSocket\" -command {\n",\ +" Ng_Socket addserver ${sockets.serverport} ${sockets.serverhost}\n",\ +" updateserverlist\n",\ +" }\n",\ +" \n",\ +" pack $w.addserver\n",\ +"\n",\ +" label $w.linefeed -text \"\\n\"\n",\ +" pack $w.linefeed\n",\ +" \n",\ +" frame $w.clientidframe\n",\ +" label $w.clientidframe.lab -text \"Client ID: \";\n",\ +" global sockets.myidlabel\n",\ +" entry $w.clientidframe.val -width 5 -relief sunken -textvariable sockets.myidlabel\n",\ +" button $w.clientidframe.but -text \"Set\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" Ng_Socket setid $opserver ${sockets.myidlabel}\n",\ +" updateserverlist\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" pack $w.clientidframe.lab $w.clientidframe.val $w.clientidframe.but -side left\n",\ +" pack $w.clientidframe\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" label $w.listboxes.choosesocketframe.chooselab -text [format \"\\n\\n%-16s %6s %6s \" Host Socket MyID ]\n",\ +" pack $w.listboxes.choosesocketframe.chooselab\n",\ +" pack $w.listboxes.choosesocketframe.choosesocket\n",\ +"\n",\ +" frame $w.listboxes.choosesocketframe.serverbuttons\n",\ +"\n",\ +" button $w.listboxes.choosesocketframe.serverbuttons.save -text \"Save\" -command {\n",\ +" Ng_Socket saveserverlist\n",\ +" }\n",\ +"\n",\ +" global sockets.serverlist\n",\ +" Ng_Socket loadserverlist\n",\ +" updateserverlist\n",\ +"\n",\ +" button $w.listboxes.choosesocketframe.serverbuttons.delete -text \"Delete\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" Ng_Socket deletesocket [lindex $opsel 0]\n",\ +" updateserverlist\n",\ +" } \n",\ +" }\n",\ +" \n",\ +" pack $w.listboxes.choosesocketframe.serverbuttons.save $w.listboxes.choosesocketframe.serverbuttons.delete -side left\n",\ +" pack $w.listboxes.choosesocketframe.serverbuttons\n",\ +"\n",\ +" frame $w.listboxes.statusframe\n",\ +"\n",\ +" label $w.listboxes.statusframe.statuslabel1 -text \"\\n\\njobqueue\"\n",\ +"\n",\ +" tixScrolledListBox $w.listboxes.statusframe.queuestatus -scrollbar auto\n",\ +"\n",\ +" label $w.listboxes.statusframe.statuslabel2 -text \"\\ncurrent job\"\n",\ +"\n",\ +" tixScrolledListBox $w.listboxes.statusframe.currentjobstatus -scrollbar auto\n",\ +"\n",\ +" label $w.listboxes.statusframe.statuslabel3 -text \"\\nanswers\"\n",\ +"\n",\ +" tixScrolledListBox $w.listboxes.statusframe.answers -scrollbar auto\n",\ +"\n",\ +" global sockets.queuelistbox\n",\ +" global sockets.currentjoblistbox\n",\ +" global sockets.answerlistbox\n",\ +"\n",\ +" set sockets.queuelistbox [$w.listboxes.statusframe.queuestatus subwidget listbox]\n",\ +" set sockets.currentjoblistbox [$w.listboxes.statusframe.currentjobstatus subwidget listbox]\n",\ +" set sockets.answerlistbox [$w.listboxes.statusframe.answers subwidget listbox]\n",\ +"\n",\ +" ${sockets.queuelistbox} configure -width 50\n",\ +" ${sockets.queuelistbox} configure -height 5\n",\ +" ${sockets.queuelistbox} configure -selectmode browse\n",\ +" ${sockets.queuelistbox} configure -exportselection false\n",\ +" \n",\ +" ${sockets.currentjoblistbox} configure -width 50\n",\ +" ${sockets.currentjoblistbox} configure -height 1\n",\ +" ${sockets.currentjoblistbox} configure -selectmode browse\n",\ +" ${sockets.currentjoblistbox} configure -exportselection false\n",\ +"\n",\ +" ${sockets.answerlistbox} configure -width 50\n",\ +" ${sockets.answerlistbox} configure -height 5\n",\ +" ${sockets.answerlistbox} configure -selectmode browse\n",\ +" ${sockets.answerlistbox} configure -exportselection false\n",\ +"\n",\ +" button $w.listboxes.statusframe.updatebutton -text \"Update\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [Ng_Socket sendqueuestatus $opserver]\n",\ +"\n",\ +" ${sockets.queuelistbox} delete 0 end\n",\ +" \n",\ +" if {[lindex $retval 0] > 0} {\n",\ +" ${sockets.queuelistbox} insert end [format \"Blocked for user %i\" [lindex $retval 0]]\n",\ +" } {\n",\ +" ${sockets.queuelistbox} insert end \"Not blocked\"\n",\ +" }\n",\ +" \n",\ +" for {set i 2} {$i < [expr 2*[lindex $retval 1]+2]} {incr i 2} {\n",\ +" ${sockets.queuelistbox} insert end [format \"client %i, command %s\" [lindex $retval $i] [lindex $retval [expr $i+1]]]\n",\ +" }\n",\ +" \n",\ +" ${sockets.answerlistbox} delete 0 end\n",\ +" \n",\ +" for {set i [expr 2*[lindex $retval 1]+3]} {$i < [llength $retval]} {incr i 2} {\n",\ +" ${sockets.answerlistbox} insert end [format \"client %i, command %s\" [lindex $retval $i] [lindex $retval [expr $i+1]]]\n",\ +" }\n",\ +"\n",\ +" ${sockets.currentjoblistbox} delete 0 end\n",\ +" set retval [Ng_Socket sendjobstatus $opserver]\n",\ +" if {[lindex $retval 0] != 0} {\n",\ +" ${sockets.currentjoblistbox} insert end [format \"client %i, command %s: %s\" [lindex $retval 0] [lindex $retval 1] [lrange $retval 2 end]]\n",\ +" }\n",\ +" \n",\ +" }\n",\ +" }\n",\ +"\n",\ +" pack $w.listboxes.statusframe.statuslabel1 $w.listboxes.statusframe.queuestatus \\\n",\ +" $w.listboxes.statusframe.statuslabel2 $w.listboxes.statusframe.currentjobstatus \\\n",\ +" $w.listboxes.statusframe.statuslabel3 $w.listboxes.statusframe.answers \\\n",\ +" $w.listboxes.statusframe.updatebutton\n",\ +"\n",\ +" pack $w.listboxes.choosesocketframe $w.listboxes.statusframe -side left\n",\ +" \n",\ +" pack $w.listboxes\n",\ +"\n",\ +" label $w.lab1 -text \"\\n\"\n",\ +" pack $w.lab1\n",\ +"\n",\ +"\n",\ +" frame $w.buttons1\n",\ +" frame $w.buttons2\n",\ +" \n",\ +" button $w.buttons1.getid -text \"Get ID\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [Ng_Socket getid $opserver]\n",\ +" updateserverlist\n",\ +" set sockets.myidlabel $retval\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons1.killjob -text \"Kill Cur. Job\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" Ng_Socket killcurrentjob $opserver\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons2.sendmesh -text \"Send Mesh\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [Ng_Socket sendmesh $opserver]\n",\ +" set sockets.meshsent 1\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons2.sendpde -text \"Send PDE\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [NGS_Socket sendpdefile $opserver]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons2.solvepde -text \"Solve PDE\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [NGS_Socket solvepde $opserver]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons2.writesol -text \"Write Solution\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [NGS_Socket writesolution $opserver]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons2.sendsol -text \"Receive Solution\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [NGS_Socket sendsolution $opserver]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons1.blockserver -text \"Block Server\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [Ng_Socket blockserver $opserver]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.buttons1.unblockserver -text \"UnBlock Server\" -command {\n",\ +" set opsel [${sockets.serverlistbox} curselection]\n",\ +" if {[llength $opsel] > 0} {\n",\ +" set opserver [lindex $opsel 0]\n",\ +" set retval [Ng_Socket unblockserver $opserver]\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" \n",\ +" pack $w.buttons1.getid $w.buttons1.blockserver $w.buttons1.unblockserver $w.buttons1.killjob -side left\n",\ +" pack $w.buttons2.sendmesh $w.buttons2.sendpde $w.buttons2.solvepde $w.buttons2.writesol $w.buttons2.sendsol -side left\n",\ +"\n",\ +" pack $w.buttons1 $w.buttons2\n",\ +"\n",\ +"\n",\ +" wm withdraw $w\n",\ +" wm geom $w +200+200\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Client Socket\"\n",\ +" focus .options_dlg\n",\ +"\n",\ +" }\n",\ +" \n",\ +"\n",\ +"}\n",\ +"\n",\ +".ngmenu.special add command -label \"Client Socket\" \\\n",\ +" -command { clientsocketdialog }\n",\ +"\n",\ +"\n",\ +"\n",\ +"set entities [ ]\n",\ +"\n",\ +"\n",\ +"proc acisdialogbuildtree {} {\n",\ +"\n",\ +" global entities\n",\ +"\n",\ +" set w .acis_dlg\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +" \n",\ +" set entities [Ng_ACISCommand getentities]\n",\ +"\n",\ +" set nrentities [expr [llength $entities]]\n",\ +"\n",\ +" if {$nrentities != 0} {\n",\ +"\n",\ +" $hlist add Topology -itemtype text -text \"Topology\"\n",\ +" \n",\ +" set i [expr 0]\n",\ +" while {$i < $nrentities} {\n",\ +" set entity [lindex $entities [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname [lindex $entities [expr $i]]\n",\ +" $hlist add Topology/$entity -text $entityname -data $entityname\n",\ +" incr i 1\n",\ +" $w.mtre close Topology/$entity\n",\ +" }\n",\ +" \n",\ +" $w.mtre autosetmode\n",\ +" $w.mtre open Topology\n",\ +" \n",\ +" set i [expr 0]\n",\ +" while {$i < $nrentities} {\n",\ +" set entity [lindex $entities [expr $i]]\n",\ +" $w.mtre close Topology/$entity\n",\ +" incr i 2\n",\ +" }\n",\ +"\n",\ +" $w.mtre autosetmode\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc rebuildacisdialog {} {\n",\ +" if {[winfo exists .acis_dlg] == 1} {\n",\ +" [.acis_dlg.mtre subwidget hlist] delete all\n",\ +" acisdialogbuildtree \n",\ +" }\n",\ +"}\n",\ +"\n",\ +"proc checkacisloaded { } {\n",\ +" set isacisgeometryloaded [Ng_ACISCommand isacisgeometryloaded]\n",\ +" if {$isacisgeometryloaded == 0} {\n",\ +" puts \"no IGES/STEP geometry loaded\"\n",\ +" destroy .acis_dlg\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc selectentity { entityname } {\n",\ +" global entities\n",\ +" set nrentities [expr [llength $entities]]\n",\ +" set i [expr 0]\n",\ +" while {$i < $nrentities} {\n",\ +" set entitylength []\n",\ +" \n",\ +" set entity2 [lindex $entities [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname2 [lindex $entities [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname2 [string range $entityname2 0 [expr [string length $entityname]-1]]\n",\ +" \n",\ +" if {$entityname == $entityname2} {\n",\ +" set hlist [.acis_dlg.mtre subwidget hlist]\n",\ +" .acis_dlg.mtre open Topology\n",\ +" set slashpos [string last \"/\" $entity2]\n",\ +" set entity3 [string range $entity2 0 [expr $slashpos-1]]\n",\ +" while {$slashpos != -1} {\n",\ +" .acis_dlg.mtre open Topology/$entity3\n",\ +" \n",\ +" set slashpos [string last \"/\" $entity3]\n",\ +" set entity3 [string range $entity3 0 [expr $slashpos-1]]\n",\ +" }\n",\ +" $hlist selection clear\n",\ +" $hlist see Topology/$entity2\n",\ +" $hlist selection set Topology/$entity2\n",\ +" } \n",\ +" } \n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"proc acisdialog { } {\n",\ +" \n",\ +" uplevel 1 {\n",\ +" \n",\ +" global entities\n",\ +" set selectvisual geometry\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" \n",\ +" set w .acis_dlg\n",\ +"\n",\ +" if {[winfo exists .acis_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } { \n",\ +" toplevel $w\n",\ +" \n",\ +" tixTree $w.mtre -options { separator \"/\" }\n",\ +" pack $w.mtre -fill both -expand yes\n",\ +"\n",\ +"\n",\ +" acisdialogbuildtree\n",\ +"\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +" set solname {\"\"}\n",\ +"\n",\ +" puts \"acisdialog2\"\n",\ +" \n",\ +"\n",\ +" bind $hlist {\n",\ +"\n",\ +" set entry [[.acis_dlg.mtre subwidget hlist] info selection]\n",\ +" set hentry [string trimleft $entry Topology/]\n",\ +"\n",\ +" Ng_ACISCommand selectentity $hentry\n",\ +" redraw\n",\ +" }\n",\ +" \n",\ +"\n",\ +" bind $hlist {\n",\ +"\n",\ +" puts \"double 1\"\n",\ +"\n",\ +" set oldsolname {$solname}\n",\ +" set solname [[.acis_dlg.mtre subwidget hlist] info selection]\n",\ +"\n",\ +" puts \"solname = $solname\"\n",\ +"\n",\ +" if {$solname != \"\" && $oldsolname != $solname } {\n",\ +" set seppos [string first \"/\" $solname]\n",\ +" set rootname [string range $solname 0 [expr $seppos-1]]\n",\ +" \n",\ +" set entityname [[.acis_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +" if {$rootname == \"Topology\"} {\n",\ +" Ng_ACISCommand highlightentity $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +" } {\n",\ +" set brackpos [string first \" (\" $entityname]\n",\ +" if {$brackpos != -1} {\n",\ +" set entityname [string range $entityname 0 $brackpos]\n",\ +" }\n",\ +"\n",\ +" selectentity $entityname\n",\ +" }\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" button $w.cl -text \"Close\" -command {\n",\ +" destroy .acis_dlg\n",\ +" }\n",\ +" \n",\ +" puts \"acisdialog3\"\n",\ +"\n",\ +" button $w.show -text \"Show\" -command {\n",\ +" set solname [[.acis_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.acis_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +"\n",\ +" Ng_ACISCommand show $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +" }\n",\ +" button $w.hide -text \"Hide\" -command {\n",\ +" set solname [[.acis_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.acis_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +"\n",\ +" Ng_ACISCommand hide $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +" button $w.swaporientation -text \"Swap orientation\" -command {\n",\ +" set solname [[.acis_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.acis_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +"\n",\ +" Ng_ACISCommand swaporientation $entitytype $entitynumber\n",\ +" set selectvisual geometry\n",\ +" redraw\n",\ +"\n",\ +" [.acis_dlg.mtre subwidget hlist] delete all\n",\ +" acisdialogbuildtree \n",\ +" }\n",\ +"\n",\ +" button $w.marksingular -text \"Mark/Unmark as singular\" -command {\n",\ +" set solname [[.acis_dlg.mtre subwidget hlist] info selection]\n",\ +" set entityname [[.acis_dlg.mtre subwidget hlist] info data $solname]\n",\ +" set spacepos [string first \" \" $entityname]\n",\ +" if { $spacepos != 0 } {\n",\ +" set entitytype [string range $entityname 0 [expr $spacepos-1]]\n",\ +" set helpstring [string range $entityname [expr $spacepos+1] [expr [string length $entityname]-1]]\n",\ +" set spacepos2 [string first \" \" $helpstring]\n",\ +" if { $spacepos2 != 0 } {\n",\ +" set entitynumber [string range $helpstring 0 [expr $spacepos2-1]]\n",\ +" \n",\ +" global ismarkedsingular\n",\ +" Ng_ACISCommand marksingular $entitytype $entitynumber\n",\ +" \n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +" \n",\ +" set style1 [tixDisplayStyle imagetext -foreground black -background white -selectforeground white -selectbackground blue]\n",\ +" set style2 [tixDisplayStyle imagetext -foreground red -background white -selectforeground red -selectbackground blue]\n",\ +" \n",\ +" if { $ismarkedsingular == 0 } {\n",\ +" $hlist entryconfigure $solname -style $style1\n",\ +" } {\n",\ +" $hlist entryconfigure $solname -style $style2\n",\ +" }\n",\ +"\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" \n",\ +" }\n",\ +"\n",\ +"\n",\ +" checkbutton $w.zoomtohighlightedentity -text \"Zoom to highlighted entity\" \\\n",\ +" -variable acisoptions.zoomtohighlightedentity \\\n",\ +" -command {\n",\ +" Ng_SetACISVisParameters\n",\ +" if { ${acisoptions.zoomtohighlightedentity} == 1} {\n",\ +" set selectvisual geometry\n",\ +" Ng_ACISCommand redrawstatus 1\n",\ +" redraw\n",\ +" } {\n",\ +" Ng_ACISCommand redrawstatus 0\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" frame $w.healing -relief groove -borderwidth 3\n",\ +"\n",\ +" button $w.healing.checkentities -text \"Analyze geometry\" -command {\n",\ +" set irregent [Ng_ACISCommand findsmallentities]\n",\ +"\n",\ +" set w .acis_dlg\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +" \n",\ +" $hlist add ProblematicEntities -text \"Problematic Entities\"\n",\ +" $hlist delete offsprings ProblematicEntities\n",\ +"\n",\ +" set nritems [expr [llength $irregent]]\n",\ +" set i [expr 0]\n",\ +" while {$i < $nritems} {\n",\ +" set entity [lindex $irregent [expr $i]]\n",\ +" incr i 1\n",\ +" set entityname [lindex $irregent [expr $i]]\n",\ +" $hlist add ProblematicEntities/$entity -text $entityname -data $entityname\n",\ +" incr i 1\n",\ +" }\n",\ +" $w.mtre open ProblematicEntities\n",\ +" $w.mtre autosetmode\n",\ +" }\n",\ +"\n",\ +" tixControl $w.healing.tolerance -label \"Healing tolerance: \" -integer false \\\n",\ +" -variable acisoptions.tolerance -min 1e-9 -max 1e6 \\\n",\ +" -options {\n",\ +" entry.width 6\n",\ +" label.width 25\n",\ +" label.anchor e\n",\ +" } \n",\ +"\n",\ +" checkbutton $w.healing.fixsmalledges -text \"Fix small edges\" \\\n",\ +" -variable acisoptions.fixsmalledges\n",\ +" \n",\ +" checkbutton $w.healing.fixspotstripfaces -text \"Fix spot/strip faces\" \\\n",\ +" -variable acisoptions.fixspotstripfaces\n",\ +" \n",\ +" checkbutton $w.healing.sewfaces -text \"Sew faces\" \\\n",\ +" -variable acisoptions.sewfaces\n",\ +" \n",\ +" checkbutton $w.healing.makesolids -text \"Make solids\" \\\n",\ +" -variable acisoptions.makesolids\n",\ +" \n",\ +" checkbutton $w.healing.splitpartitions -text \"Split partitions\" \\\n",\ +" -variable acisoptions.splitpartitions\n",\ +" \n",\ +" button $w.healing.heal -text \"Heal geometry\" -command { \n",\ +" .acis_dlg.healing.tolerance invoke\n",\ +" Ng_ACISCommand shapehealing\n",\ +" redraw \n",\ +" [.acis_dlg.mtre subwidget hlist] delete all\n",\ +" acisdialogbuildtree\n",\ +" }\n",\ +"\n",\ +" pack $w.healing.checkentities\n",\ +"\n",\ +" pack $w.healing.tolerance $w.healing.fixsmalledges \\\n",\ +" $w.healing.fixspotstripfaces $w.healing.sewfaces \\\n",\ +" $w.healing.makesolids $w.healing.splitpartitions -anchor w\n",\ +"\n",\ +" pack $w.healing.heal \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" pack $w.show $w.hide\n",\ +"\n",\ +" pack $w.zoomtohighlightedentity -anchor w\n",\ +" pack $w.swaporientation\n",\ +" pack $w.marksingular\n",\ +" pack $w.healing -fill x\n",\ +" pack $w.cl\n",\ +" \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"IGES/STEP Topology Explorer/Doctor\"\n",\ +" focus .acis_dlg\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"if { [catch { NGS_GetData } ] == 0 } { \n",\ +" \n",\ +" set progname \"NGSolve\"\n",\ +" wm title . $progname\n",\ +" \n",\ +" .ngmenu add cascade -label \"Solve\" -menu .ngmenu.solve -underline 1\n",\ +" \n",\ +" \n",\ +" menu .ngmenu.solve\n",\ +" .ngmenu.solve add command -label \"Print Equations\" \\\n",\ +" -command { NGS_PrintRegistered }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" menu .ngmenusolvehelp\n",\ +" .ngmenu.solve add cascade -label \"Help\" -menu .ngmenusolvehelp\n",\ +" \n",\ +" .ngmenusolvehelp add command -label \"Coefficient...\" \\\n",\ +" -command { tk_messageBox -title \"Help\" -message [ NGS_Help coefficient ] -type ok }\n",\ +" .ngmenusolvehelp add command -label \"Bilinear-form...\" \\\n",\ +" -command { tk_messageBox -title \"Help\" -message [ NGS_Help bilinearform ] -type ok }\n",\ +" .ngmenusolvehelp add command -label \"Linear-form...\" \\\n",\ +" -command { tk_messageBox -title \"Help\" -message [ NGS_Help linearform ] -type ok }\n",\ +"\n",\ +" .ngmenusolvehelp add cascade -label \"Numprocs...\" -menu .ngmenusolvehelpnp \n",\ +" \n",\ +" .ngmenusolvehelp add command -label \"Latest News...\" \\\n",\ +" -command { tk_messageBox -title \"Latest News\" -message \\\n",\ +" { \n",\ +" 06042004 online documentation (JS) \n",\ +" } -type ok } ;\n",\ +" \n",\ +"\n",\ +"\n",\ +" .ngmenu.solve add command -label \"Load PDE...\" -accelerator \"

\"\\\n",\ +" -command { \n",\ +" set types { {\"Partial Differential Equation\" {.pde} } }\n",\ +" set file [tk_getOpenFile -filetypes $types]\n",\ +" if {$file != \"\"} {\n",\ +" AddRecentNGSFile $file;\n",\ +" NGS_LoadPDE $file; \n",\ +" set selectvisual mesh;\n",\ +" Ng_SetVisParameters \n",\ +" }\n",\ +" }\n",\ +" \n",\ +" .ngmenu.solve add cascade -label \"Recent Files\" -menu .ngmenu.solve.recent \n",\ +" menu .ngmenu.solve.recent\n",\ +"\n",\ +" .ngmenu.solve add command -label \"Components...\" \\\n",\ +" -command { componentsdialog }\n",\ +" \n",\ +"\n",\ +" .ngmenu.solve add command -label \"Print Report\" \\\n",\ +" -command { NGS_PrintPDE }\n",\ +"\n",\ +" .ngmenu.solve add command -label \"Memory Usage\" \\\n",\ +" -command { NGS_PrintMemoryUsage }\n",\ +"\n",\ +" .ngmenu.solve add command -label \"Print Timing\" \\\n",\ +" -command { NGS_PrintTiming }\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +" .ngmenu.solve add command -label \"Solve Recent PDE\" -accelerator \"\"\\\n",\ +" -command { \n",\ +" NGS_LoadPDE [.ngmenu.solve.recent entrycget 1 -label]\n",\ +" NGS_SolvePDE\n",\ +" set selectvisual solution\n",\ +" Ng_SetVisParameters \n",\ +"\n",\ +"\n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" button .bubar.pde -text \"Recent\" \\\n",\ +" -command { .ngmenu.solve invoke \"Solve Recent PDE\"; }\n",\ +" pack .bubar.pde -side right\n",\ +"\n",\ +" button .bubar.solve -text \"Solve\" \\\n",\ +" -command { .ngmenu.solve invoke \"Solve PDE\"; }\n",\ +" pack .bubar.solve -side right\n",\ +"\n",\ +" button .bubar.visualize -text \"Visual\" \\\n",\ +" -command { visual_dialog }\n",\ +" pack .bubar.visualize -side right\n",\ +"\n",\ +" .ngmenu.solve add command -label \"Solve PDE\" -accelerator \"

\"\\\n",\ +" -command {\n",\ +" \n",\ +" \n",\ +" \n",\ +" NGS_SolvePDE\n",\ +" set selectvisual solution\n",\ +" Ng_SetVisParameters \n",\ +"\n",\ +" Ng_Vis_Set parameters; \n",\ +"\n",\ +" \n",\ +" redraw\n",\ +" }\n",\ +"\n",\ +" .ngmenu.solve add cascade -label \"Solve PDE x\" -menu .ngmenu.solve.solvex\n",\ +" menu .ngmenu.solve.solvex\n",\ +"\n",\ +" proc SolveX { num } {\n",\ +" for { set i 1 } { $i <= $num } { incr i } {\n",\ +" uplevel 1 \"NGS_SolvePDE $i\"\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" .ngmenu.solve.solvex add command -label \"1 Level\" -command { SolveX 1 }\n",\ +" .ngmenu.solve.solvex add command -label \"2 Level\" -command { SolveX 2 }\n",\ +" .ngmenu.solve.solvex add command -label \"3 Level\" -command { SolveX 3 }\n",\ +" .ngmenu.solve.solvex add command -label \"4 Level\" -command { SolveX 4 }\n",\ +" .ngmenu.solve.solvex add command -label \"5 Level\" -command { SolveX 5 }\n",\ +" .ngmenu.solve.solvex add command -label \"6 Level\" -command { SolveX 6 }\n",\ +" .ngmenu.solve.solvex add command -label \"7 Level\" -command { SolveX 7 }\n",\ +" .ngmenu.solve.solvex add command -label \"8 Level\" -command { SolveX 8 }\n",\ +" .ngmenu.solve.solvex add command -label \"9 Level\" -command { SolveX 9 }\n",\ +" .ngmenu.solve.solvex add command -label \"10 Level\" -command { SolveX 10 }\n",\ +" .ngmenu.solve.solvex add command -label \"11 Level\" -command { SolveX 11 }\n",\ +" .ngmenu.solve.solvex add command -label \"12 Level\" -command { SolveX 12 }\n",\ +" .ngmenu.solve.solvex add command -label \"13 Level\" -command { SolveX 13 }\n",\ +" .ngmenu.solve.solvex add command -label \"14 Level\" -command { SolveX 14 }\n",\ +" .ngmenu.solve.solvex add command -label \"15 Level\" -command { SolveX 15 }\n",\ +" .ngmenu.solve.solvex add command -label \"16 Level\" -command { SolveX 16 }\n",\ +" .ngmenu.solve.solvex add command -label \"17 Level\" -command { SolveX 17 }\n",\ +" .ngmenu.solve.solvex add command -label \"18 Level\" -command { SolveX 18 }\n",\ +" .ngmenu.solve.solvex add command -label \"19 Level\" -command { SolveX 19 }\n",\ +" .ngmenu.solve.solvex add command -label \"20 Level\" -command { SolveX 20 }\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +" .ngmenu.solve add command -label \"Visualization...\" \\\n",\ +" -command { \n",\ +" visual_dialog;\n",\ +" }\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +" .ngmenu.solve add command -label \"Save Solution...\" \\\n",\ +" -command { \n",\ +" set types { {\"Solution File\" {.sol} } }\n",\ +" set file [tk_getSaveFile -filetypes $types -defaultextension \".sol\" ]\n",\ +" if {$file != \"\"} {\n",\ +" NGS_SaveSolution $file \n",\ +" }\n",\ +" }\n",\ +" \n",\ +" .ngmenu.solve add command -label \"Load Solution...\" \\\n",\ +" -command { \n",\ +" set types { {\"Solution File\" {.sol} } }\n",\ +" set file [tk_getOpenFile -filetypes $types -defaultextension \".sol\" ]\n",\ +" if {$file != \"\"} {\n",\ +" NGS_LoadSolution $file \n",\ +" set selectvisual solution\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +".ngmenu.help delete \"About...\"\n",\ +".ngmenu.help add command -label \"About...\" \\\n",\ +" -command {\n",\ +" tk_messageBox -message \\\n",\ +" \"This is NETGEN/NGSolve \\n mainly written by \\n Joachim Schöberl \\n\\\n",\ +" at RWTH Aachen University, Germany \\n\\\n",\ +" and Johannes Kepler University, Linz, Austria \\n\\\n",\ +" supported by the Austrian Science Foundation FWF \\n\\\n",\ +" thanks to \\n\\\n",\ +" F. Bachinger, A. Becirovic, H. Egger, R. Gaisbauer, J. Gerstmayr, U. Langer, A. Sinwel, M. Wabro, S. Zaglmayr\"\n",\ +" }\n",\ +" \n",\ +"\n",\ +"\n",\ +" proc AddRecentNGSFile { filename } {\n",\ +" global progname\n",\ +" catch { [.ngmenu.solve.recent delete $filename] }\n",\ +" .ngmenu.solve.recent insert 0 command -label $filename \\\n",\ +" -command \"AddRecentNGSFile {$filename}; \n",\ +" NGS_LoadPDE {$filename};\n",\ +" set selectvisual mesh;\n",\ +" Ng_SetVisParameters \n",\ +" wm title . [concat \\\" $progname - $filename \\\"];\"\n",\ +" \n",\ +" if { [.ngmenu.solve.recent index last] >= 6 } {\n",\ +" .ngmenu.solve.recent delete last }\n",\ +" \n",\ +" savengsinifile;\n",\ +" }\n",\ +" \n",\ +"\n",\ +" proc savengsinifile { } {\n",\ +" uplevel 1 {\n",\ +" set datei [open ngs.ini w]\n",\ +" for { set i [.ngmenu.solve.recent index last] } { $i >= 1 } { incr i -1 } {\n",\ +" puts $datei \"recentfile \\\"[.ngmenu.solve.recent entrycget $i -label]\\\"\"\n",\ +" }\n",\ +" \n",\ +" close $datei\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" proc loadngsinifile { } {\n",\ +" if { [file exists ngs.ini] == 1 } {\n",\ +" set datei [open ngs.ini r]\n",\ +" while { [gets $datei line] >= 0 } {\n",\ +" if {[lindex $line 0] == \"recentfile\"} {\n",\ +" AddRecentNGSFile [lindex $line 1]\n",\ +" }\n",\ +" }\n",\ +" close $datei\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"\n",\ +"loadngsinifile;\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" proc componentsdialog { } {\n",\ +" \n",\ +" set w .components_dlg\n",\ +" \n",\ +" if {[winfo exists .components_dlg] == 1} {\n",\ +" wm withdraw $w\n",\ +" wm deiconify $w\n",\ +" focus $w \n",\ +" } {\n",\ +"\n",\ +" toplevel $w\n",\ +"\n",\ +"\n",\ +" tixTree $w.mtre -options { separator \"\\\\\" }\n",\ +" pack $w.mtre -fill both -expand y\n",\ +" set hlist [$w.mtre subwidget hlist]\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" $hlist add coeffs -itemtype text -text \"Coefficients\"\n",\ +" set coefs [NGS_GetData coefficients]\n",\ +" foreach coef $coefs {\n",\ +" $hlist add coeffs\\\\$coef -itemtype text -text $coef\n",\ +" }\n",\ +"\n",\ +"\n",\ +" $hlist add spaces -itemtype text -text \"Spaces\"\n",\ +" set spaces [NGS_GetData spaces]\n",\ +" foreach space $spaces {\n",\ +" $hlist add spaces\\\\$space -itemtype text -text $space\n",\ +" }\n",\ +"\n",\ +" $hlist add biforms -itemtype text -text \"Bilinear-forms\"\n",\ +" set biforms [NGS_GetData bilinearforms]\n",\ +" foreach biform $biforms {\n",\ +" $hlist add biforms\\\\$biform -itemtype text -text $biform\n",\ +" }\n",\ +"\n",\ +" $hlist add liforms -itemtype text -text \"Linear-forms\"\n",\ +" set liforms [NGS_GetData linearforms]\n",\ +" foreach liform $liforms {\n",\ +" $hlist add liforms\\\\$liform -itemtype text -text $liform\n",\ +" }\n",\ +"\n",\ +" $hlist add gridfuns -itemtype text -text \"Grid-functions\"\n",\ +" set gridfuns [NGS_GetData gridfunctions]\n",\ +" foreach gridfun $gridfuns {\n",\ +" $hlist add gridfuns\\\\$gridfun -itemtype text -text $gridfun\n",\ +" }\n",\ +"\n",\ +" $hlist add preconds -itemtype text -text \"Preconditioners\"\n",\ +" set preconds [NGS_GetData preconditioners]\n",\ +" foreach precond $preconds {\n",\ +" $hlist add preconds\\\\$precond -itemtype text -text $precond\n",\ +" }\n",\ +"\n",\ +" $hlist add numprocs -itemtype text -text \"NumProcs\"\n",\ +" set numprocs [NGS_GetData numprocs]\n",\ +" foreach numproc $numprocs {\n",\ +" $hlist add numprocs\\\\$numproc -itemtype text -text $numproc\n",\ +" }\n",\ +"\n",\ +"\n",\ +"\n",\ +" \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +" $w.mtre autosetmode\n",\ +" \n",\ +"\n",\ +" bind $hlist {\n",\ +" set solname [[.components_dlg.mtre subwidget hlist] info selection]\n",\ +" puts $solname\n",\ +" set seppos [string first \\\\ $solname]\n",\ +" if { $seppos != -1 } {\n",\ +" set field [string range $solname 1 [expr $seppos-1]]\n",\ +" set name [string range $solname [expr $seppos+1] [expr [string length $solname]-2]]\n",\ +" puts \"field = $field, name = $name\"\n",\ +" NGS_PrintPDE $field $name\n",\ +" }\n",\ +" }\n",\ +"\n",\ +" button $w.cl -text \"Close\" -command {\n",\ +" destroy .components_dlg\n",\ +" }\n",\ +"\n",\ +" pack $w.cl\n",\ +" \n",\ +" \n",\ +" wm withdraw $w\n",\ +" wm geom $w +100+100\n",\ +" wm deiconify $w\n",\ +" wm title $w \"Components\"\n",\ +" focus .components_dlg\n",\ +" }\n",\ +" }\n",\ +"\n",\ +"bind .

{ .ngmenu.solve invoke \"Load PDE...\" } ; \n",\ +"bind . { .ngmenu.solve invoke \"Solve Recent PDE\" } ; \n",\ +"bind .

{ .ngmenu.solve invoke \"Solve PDE\" } ; \n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"set zugstange 0\n",\ +"\n",\ +"\n",\ +"catch { source ${ngdir}/trafo/menu.tcl }\n",\ +"\n",\ +"\n",\ +"\n",\ +"setgranularity ${meshoptions.fineness}\n",\ +"\n",\ +"Ng_SetMeshingParameters\n",\ +"Ng_SetVisParameters\n",\ +"Ng_SetDebugParameters\n",\ +"Ng_STLDoctor\n",\ +"Ng_GeometryOptions set\n",\ +"Ng_SetOCCVisParameters\n",\ +"\n",\ +"if { $batchmode != \"defined\" } {\n",\ +" catch { \n",\ +" wm protocol . WM_DELETE_WINDOW { .ngmenu.file invoke \"Quit\" }\n",\ +" wm deiconify .\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"set trafoapp 0\n",\ +"catch { source ${ngdir}/trafoapp/trafoapp.tcl }\n",\ +"\n",\ +"set geofilename [Ng_GetCommandLineParameter geofile]\n",\ +"\n",\ +"if { $geofilename != \"undefined\" && \n",\ +" [info exists trafo] == 0 && $zugstange == 0} {\n",\ +"\n",\ +" if { [ catch { Ng_LoadGeometry $geofilename } errstring] == 0 } {\n",\ +" if { $batchmode != \"defined\" } {\n",\ +" AddRecentFile $geofilename\n",\ +" }\n",\ +" Ng_ParseGeometry\n",\ +" if { $batchmode != \"defined\" } {\n",\ +" set selectvisual geometry\n",\ +" Ng_SetVisParameters\n",\ +" redraw\n",\ +" wm title . [concat \"$progname - \" $geofilename]\n",\ +" }\n",\ +" set dirname [file dirname $geofilename]\n",\ +" set basefilename [file tail [file rootname $geofilename]]\n",\ +" } {\n",\ +" puts \"Problem with input file:\"\n",\ +" puts \"$errstring\"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set cnt 0\n",\ +"foreach { gran } { verycoarse coarse moderate fine veryfine } {\n",\ +" set cnt [expr $cnt + 1]\n",\ +" if { [Ng_GetCommandLineParameter $gran] == \"defined\" } {\n",\ +" set meshoptions.fineness $cnt\n",\ +" setgranularity ${meshoptions.fineness}\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"set meshfilename [Ng_GetCommandLineParameter meshfile]\n",\ +"if { $meshfilename == \"undefined\" } {\n",\ +" set meshfilename out.mesh\n",\ +"}\n",\ +"\n",\ +"set meshfiletype [Ng_GetCommandLineParameter meshfiletype]\n",\ +"if { $meshfiletype == \"undefined\" } {\n",\ +" set meshfiletype netgen\n",\ +"}\n",\ +"\n",\ +"set inputmeshfilename [Ng_GetCommandLineParameter inputmeshfile]\n",\ +"\n",\ +"set mergemeshfilename [Ng_GetCommandLineParameter mergefile]\n",\ +"\n",\ +"set meshsizefilename [Ng_GetCommandLineParameter meshsizefile]\n",\ +"\n",\ +"if { $meshsizefilename != \"undefined\" } {\n",\ +" set options.meshsizefilename $meshsizefilename\n",\ +"}\n",\ +"\n",\ +"set refinementfilename [Ng_GetCommandLineParameter refinementfile]\n",\ +"\n",\ +"\n",\ +"if { $batchmode == \"defined\" && $solvemode != \"defined\"} {\n",\ +" set options.parthread 0\n",\ +" if { $shellmode == \"undefined\" } {\n",\ +" set selectvisual mesh\n",\ +" Ng_SetVisParameters\n",\ +"\n",\ +" set meshsize [Ng_GetCommandLineParameter meshsize]\n",\ +" if {$meshsize != \"undefined\"} { set options.meshsize $meshsize }\n",\ +" \n",\ +" if { $inputmeshfilename == \"undefined\" } {\n",\ +" Ng_GenerateMesh ${meshoptions.firststep} ${meshoptions.laststep}\n",\ +" } else {\n",\ +" Ng_LoadMesh $inputmeshfilename\n",\ +" if { $mergemeshfilename != \"undefined\" } {\n",\ +" Ng_MergeMesh $mergemeshfilename\n",\ +" }\n",\ +" }\n",\ +" \n",\ +" if { $refinementfilename != \"undefined\" } {\n",\ +" Ng_Bisect $refinementfilename\n",\ +" }\n",\ +"\n",\ +" if { $meshfiletype == \"netgen\" } {\n",\ +" Ng_SaveMesh $meshfilename\n",\ +" } else {\n",\ +" if { [catch { Ng_ExportMesh $meshfilename $meshfiletype } ] == 1 } {\n",\ +" puts \"Unknown file format $meshfiletype\"\n",\ +" }\n",\ +" }\n",\ +" Ng_Exit;\n",\ +"\n",\ +" exit\n",\ +" } else {\n",\ +" set code [catch { source ${ngdir}/ngtcltk/ngshell.tcl } errcode]\n",\ +" if {$code} {\n",\ +" puts \"error: $errcode\"\n",\ +" } \n",\ +" set code [ catch {Ng_RunShell} errcode]\n",\ +" if {$code} {\n",\ +" puts \"error: $errcode\"\n",\ +" } \n",\ +" \n",\ +" Ng_Exit;\n",\ +" exit\n",\ +" }\n",\ +" \n",\ +"}\n",\ +"\n",\ +"set stereo [Ng_GetCommandLineParameter stereo]\n",\ +"if { $stereo == \"defined\" } {\n",\ +" set viewoptions.stereo 1 \n",\ +" puts \"use stereo mode\" \n",\ +" Ng_SetVisParameters; \n",\ +" redraw \n",\ +"}\n",\ +"\n",\ +"\n",\ +"set scriptfilename [Ng_GetCommandLineParameter script]\n",\ +"if { $scriptfilename != \"undefined\" } {\n",\ +" if { [catch { source $scriptfilename } errstring] == 1 } {\n",\ +" puts \"Error in input: $errstring\"\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"if { [Ng_GetCommandLineParameter help]==\"defined\" } {\n",\ +" if { $zugstange == 1 } {\n",\ +" print_zug_commandline_help\n",\ +" exit;\n",\ +" } {\n",\ +" if { $trafoapp == 1 } {\n",\ +" print_trafo_commandline_help;\n",\ +" } {\n",\ +" print_commandline_help; \n",\ +" Ng_Exit;\n",\ +" exit\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"if { [file exists startup.tcl] } {\n",\ +" source startup.tcl }\n",\ +"\n",\ +"if { [Ng_GetCommandLineParameter recent]==\"defined\" } {\n",\ +" if { [catch { .ngmenu.solve invoke \"Solve Recent PDE\"; } errstring] == 1 } {\n",\ +" puts \"TCL-ERROR handler:\\n $errstring\";\n",\ +" exit;\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"set pdefilename [Ng_GetCommandLineParameter pdefile]\n",\ +"if { $pdefilename != \"undefined\" } {\n",\ +" NGS_LoadPDE $pdefilename; \n",\ +"\n",\ +" set solve [Ng_GetCommandLineParameter solve]\n",\ +" if { $zugstange == 1 } {\n",\ +" set options.parthread 0\n",\ +" NGS_SolvePDE;\n",\ +" } {\n",\ +" if { $solve == \"defined\" } {\n",\ +" set options.parthread 0\n",\ +" NGS_SolvePDE\n",\ +" exit;\n",\ +" } {\n",\ +" if { $solve != \"undefined\" } {\n",\ +" set options.parthread 0\n",\ +" for { set l 1 } { $l <= $solve } { incr l } { NGS_SolvePDE $l }\n",\ +" exit;\n",\ +" }\n",\ +" }\n",\ +" }\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"catch { source ${ngdir}/trafo/trafo.tcl }\n",\ +"\n",\ +"catch { source ${ngdir}/trafoapp/smallmodels.tcl }\n",\ +"\n",\ +"catch { \n",\ +" source ${ngdir}/ngtcltk/ngshell.tcl\n",\ +" source ${ngdir}/ngtcltk/ngtesting.tcl\n",\ +"}\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +0};