netgen-mesher 6.2.2506.post35.dev0__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netgen/NgOCC.py +7 -0
- netgen/__init__.py +114 -0
- netgen/__init__.pyi +22 -0
- netgen/__main__.py +53 -0
- netgen/cmake/NetgenConfig.cmake +79 -0
- netgen/cmake/netgen-targets-release.cmake +69 -0
- netgen/cmake/netgen-targets.cmake +146 -0
- netgen/config/__init__.py +1 -0
- netgen/config/__init__.pyi +52 -0
- netgen/config/__main__.py +4 -0
- netgen/config/config.py +68 -0
- netgen/config/config.pyi +54 -0
- netgen/csg.py +25 -0
- netgen/geom2d.py +178 -0
- netgen/gui.py +82 -0
- netgen/include/core/archive.hpp +1256 -0
- netgen/include/core/array.hpp +1760 -0
- netgen/include/core/autodiff.hpp +1131 -0
- netgen/include/core/autodiffdiff.hpp +733 -0
- netgen/include/core/bitarray.hpp +240 -0
- netgen/include/core/concurrentqueue.h +3619 -0
- netgen/include/core/exception.hpp +145 -0
- netgen/include/core/flags.hpp +199 -0
- netgen/include/core/hashtable.hpp +1281 -0
- netgen/include/core/localheap.hpp +318 -0
- netgen/include/core/logging.hpp +117 -0
- netgen/include/core/memtracer.hpp +221 -0
- netgen/include/core/mpi4py_pycapi.h +245 -0
- netgen/include/core/mpi_wrapper.hpp +643 -0
- netgen/include/core/ng_mpi.hpp +94 -0
- netgen/include/core/ng_mpi_generated_declarations.hpp +155 -0
- netgen/include/core/ng_mpi_native.hpp +25 -0
- netgen/include/core/ngcore.hpp +32 -0
- netgen/include/core/ngcore_api.hpp +152 -0
- netgen/include/core/ngstream.hpp +115 -0
- netgen/include/core/paje_trace.hpp +279 -0
- netgen/include/core/profiler.hpp +382 -0
- netgen/include/core/python_ngcore.hpp +457 -0
- netgen/include/core/ranges.hpp +109 -0
- netgen/include/core/register_archive.hpp +100 -0
- netgen/include/core/signal.hpp +82 -0
- netgen/include/core/simd.hpp +160 -0
- netgen/include/core/simd_arm64.hpp +407 -0
- netgen/include/core/simd_avx.hpp +394 -0
- netgen/include/core/simd_avx512.hpp +285 -0
- netgen/include/core/simd_generic.hpp +1053 -0
- netgen/include/core/simd_math.hpp +178 -0
- netgen/include/core/simd_sse.hpp +289 -0
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/symboltable.hpp +153 -0
- netgen/include/core/table.hpp +810 -0
- netgen/include/core/taskmanager.hpp +1161 -0
- netgen/include/core/type_traits.hpp +65 -0
- netgen/include/core/utils.hpp +385 -0
- netgen/include/core/version.hpp +102 -0
- netgen/include/core/xbool.hpp +47 -0
- netgen/include/csg/algprim.hpp +563 -0
- netgen/include/csg/brick.hpp +150 -0
- netgen/include/csg/csg.hpp +43 -0
- netgen/include/csg/csgeom.hpp +389 -0
- netgen/include/csg/csgparser.hpp +101 -0
- netgen/include/csg/curve2d.hpp +67 -0
- netgen/include/csg/edgeflw.hpp +112 -0
- netgen/include/csg/explicitcurve2d.hpp +113 -0
- netgen/include/csg/extrusion.hpp +185 -0
- netgen/include/csg/gencyl.hpp +70 -0
- netgen/include/csg/geoml.hpp +16 -0
- netgen/include/csg/identify.hpp +213 -0
- netgen/include/csg/manifold.hpp +29 -0
- netgen/include/csg/meshsurf.hpp +46 -0
- netgen/include/csg/polyhedra.hpp +121 -0
- netgen/include/csg/revolution.hpp +180 -0
- netgen/include/csg/singularref.hpp +84 -0
- netgen/include/csg/solid.hpp +295 -0
- netgen/include/csg/specpoin.hpp +194 -0
- netgen/include/csg/spline3d.hpp +99 -0
- netgen/include/csg/splinesurface.hpp +85 -0
- netgen/include/csg/surface.hpp +394 -0
- netgen/include/csg/triapprox.hpp +63 -0
- netgen/include/csg/vscsg.hpp +34 -0
- netgen/include/general/autodiff.hpp +356 -0
- netgen/include/general/autoptr.hpp +39 -0
- netgen/include/general/gzstream.h +121 -0
- netgen/include/general/hashtabl.hpp +1692 -0
- netgen/include/general/myadt.hpp +48 -0
- netgen/include/general/mystring.hpp +226 -0
- netgen/include/general/netgenout.hpp +205 -0
- netgen/include/general/ngarray.hpp +797 -0
- netgen/include/general/ngbitarray.hpp +149 -0
- netgen/include/general/ngpython.hpp +74 -0
- netgen/include/general/optmem.hpp +44 -0
- netgen/include/general/parthreads.hpp +138 -0
- netgen/include/general/seti.hpp +50 -0
- netgen/include/general/sort.hpp +47 -0
- netgen/include/general/spbita2d.hpp +59 -0
- netgen/include/general/stack.hpp +114 -0
- netgen/include/general/table.hpp +280 -0
- netgen/include/general/template.hpp +509 -0
- netgen/include/geom2d/csg2d.hpp +750 -0
- netgen/include/geom2d/geometry2d.hpp +280 -0
- netgen/include/geom2d/spline2d.hpp +234 -0
- netgen/include/geom2d/vsgeom2d.hpp +28 -0
- netgen/include/gprim/adtree.hpp +1392 -0
- netgen/include/gprim/geom2d.hpp +858 -0
- netgen/include/gprim/geom3d.hpp +749 -0
- netgen/include/gprim/geomfuncs.hpp +212 -0
- netgen/include/gprim/geomobjects.hpp +544 -0
- netgen/include/gprim/geomops.hpp +404 -0
- netgen/include/gprim/geomtest3d.hpp +101 -0
- netgen/include/gprim/gprim.hpp +33 -0
- netgen/include/gprim/spline.hpp +778 -0
- netgen/include/gprim/splinegeometry.hpp +73 -0
- netgen/include/gprim/transform3d.hpp +216 -0
- netgen/include/include/acisgeom.hpp +3 -0
- netgen/include/include/csg.hpp +1 -0
- netgen/include/include/geometry2d.hpp +1 -0
- netgen/include/include/gprim.hpp +1 -0
- netgen/include/include/incopengl.hpp +62 -0
- netgen/include/include/inctcl.hpp +13 -0
- netgen/include/include/incvis.hpp +6 -0
- netgen/include/include/linalg.hpp +1 -0
- netgen/include/include/meshing.hpp +1 -0
- netgen/include/include/myadt.hpp +1 -0
- netgen/include/include/mydefs.hpp +70 -0
- netgen/include/include/mystdlib.h +59 -0
- netgen/include/include/netgen_config.hpp +27 -0
- netgen/include/include/netgen_version.hpp +9 -0
- netgen/include/include/nginterface_v2_impl.hpp +395 -0
- netgen/include/include/ngsimd.hpp +1 -0
- netgen/include/include/occgeom.hpp +1 -0
- netgen/include/include/opti.hpp +1 -0
- netgen/include/include/parallel.hpp +1 -0
- netgen/include/include/stlgeom.hpp +1 -0
- netgen/include/include/visual.hpp +1 -0
- netgen/include/interface/rw_medit.hpp +11 -0
- netgen/include/interface/writeuser.hpp +80 -0
- netgen/include/linalg/densemat.hpp +414 -0
- netgen/include/linalg/linalg.hpp +29 -0
- netgen/include/linalg/opti.hpp +142 -0
- netgen/include/linalg/polynomial.hpp +47 -0
- netgen/include/linalg/vector.hpp +217 -0
- netgen/include/meshing/adfront2.hpp +274 -0
- netgen/include/meshing/adfront3.hpp +332 -0
- netgen/include/meshing/basegeom.hpp +370 -0
- netgen/include/meshing/bcfunctions.hpp +53 -0
- netgen/include/meshing/bisect.hpp +72 -0
- netgen/include/meshing/boundarylayer.hpp +113 -0
- netgen/include/meshing/classifyhpel.hpp +1984 -0
- netgen/include/meshing/clusters.hpp +46 -0
- netgen/include/meshing/curvedelems.hpp +274 -0
- netgen/include/meshing/delaunay2d.hpp +73 -0
- netgen/include/meshing/fieldlines.hpp +103 -0
- netgen/include/meshing/findip.hpp +198 -0
- netgen/include/meshing/findip2.hpp +103 -0
- netgen/include/meshing/geomsearch.hpp +69 -0
- netgen/include/meshing/global.hpp +54 -0
- netgen/include/meshing/hpref_hex.hpp +330 -0
- netgen/include/meshing/hpref_prism.hpp +3405 -0
- netgen/include/meshing/hpref_pyramid.hpp +154 -0
- netgen/include/meshing/hpref_quad.hpp +2082 -0
- netgen/include/meshing/hpref_segm.hpp +122 -0
- netgen/include/meshing/hpref_tet.hpp +4230 -0
- netgen/include/meshing/hpref_trig.hpp +848 -0
- netgen/include/meshing/hprefinement.hpp +366 -0
- netgen/include/meshing/improve2.hpp +178 -0
- netgen/include/meshing/improve3.hpp +151 -0
- netgen/include/meshing/localh.hpp +223 -0
- netgen/include/meshing/meshclass.hpp +1076 -0
- netgen/include/meshing/meshfunc.hpp +47 -0
- netgen/include/meshing/meshing.hpp +63 -0
- netgen/include/meshing/meshing2.hpp +163 -0
- netgen/include/meshing/meshing3.hpp +123 -0
- netgen/include/meshing/meshtool.hpp +90 -0
- netgen/include/meshing/meshtype.hpp +1930 -0
- netgen/include/meshing/msghandler.hpp +62 -0
- netgen/include/meshing/paralleltop.hpp +172 -0
- netgen/include/meshing/python_mesh.hpp +206 -0
- netgen/include/meshing/ruler2.hpp +172 -0
- netgen/include/meshing/ruler3.hpp +211 -0
- netgen/include/meshing/soldata.hpp +141 -0
- netgen/include/meshing/specials.hpp +17 -0
- netgen/include/meshing/surfacegeom.hpp +73 -0
- netgen/include/meshing/topology.hpp +1003 -0
- netgen/include/meshing/validate.hpp +21 -0
- netgen/include/meshing/visual_interface.hpp +71 -0
- netgen/include/mydefs.hpp +70 -0
- netgen/include/nginterface.h +474 -0
- netgen/include/nginterface_v2.hpp +406 -0
- netgen/include/nglib.h +697 -0
- netgen/include/nglib_occ.h +50 -0
- netgen/include/occ/occ_edge.hpp +47 -0
- netgen/include/occ/occ_face.hpp +52 -0
- netgen/include/occ/occ_solid.hpp +23 -0
- netgen/include/occ/occ_utils.hpp +376 -0
- netgen/include/occ/occ_vertex.hpp +30 -0
- netgen/include/occ/occgeom.hpp +659 -0
- netgen/include/occ/occmeshsurf.hpp +168 -0
- netgen/include/occ/vsocc.hpp +33 -0
- netgen/include/pybind11/LICENSE +29 -0
- netgen/include/pybind11/attr.h +722 -0
- netgen/include/pybind11/buffer_info.h +208 -0
- netgen/include/pybind11/cast.h +2361 -0
- netgen/include/pybind11/chrono.h +228 -0
- netgen/include/pybind11/common.h +2 -0
- netgen/include/pybind11/complex.h +74 -0
- netgen/include/pybind11/conduit/README.txt +15 -0
- netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
- netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
- netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
- netgen/include/pybind11/critical_section.h +56 -0
- netgen/include/pybind11/detail/class.h +823 -0
- netgen/include/pybind11/detail/common.h +1348 -0
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +226 -0
- netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
- netgen/include/pybind11/detail/exception_translation.h +71 -0
- netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
- netgen/include/pybind11/detail/init.h +538 -0
- netgen/include/pybind11/detail/internals.h +799 -0
- netgen/include/pybind11/detail/native_enum_data.h +209 -0
- netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
- netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
- netgen/include/pybind11/detail/type_caster_base.h +1591 -0
- netgen/include/pybind11/detail/typeid.h +65 -0
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/common.h +9 -0
- netgen/include/pybind11/eigen/matrix.h +723 -0
- netgen/include/pybind11/eigen/tensor.h +521 -0
- netgen/include/pybind11/eigen.h +12 -0
- netgen/include/pybind11/embed.h +320 -0
- netgen/include/pybind11/eval.h +161 -0
- netgen/include/pybind11/functional.h +147 -0
- netgen/include/pybind11/gil.h +199 -0
- netgen/include/pybind11/gil_safe_call_once.h +102 -0
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/iostream.h +265 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +2312 -0
- netgen/include/pybind11/operators.h +202 -0
- netgen/include/pybind11/options.h +92 -0
- netgen/include/pybind11/pybind11.h +3645 -0
- netgen/include/pybind11/pytypes.h +2680 -0
- netgen/include/pybind11/stl/filesystem.h +114 -0
- netgen/include/pybind11/stl.h +666 -0
- netgen/include/pybind11/stl_bind.h +858 -0
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/type_caster_pyobject_ptr.h +61 -0
- netgen/include/pybind11/typing.h +298 -0
- netgen/include/pybind11/warnings.h +75 -0
- netgen/include/stlgeom/meshstlsurface.hpp +67 -0
- netgen/include/stlgeom/stlgeom.hpp +491 -0
- netgen/include/stlgeom/stlline.hpp +193 -0
- netgen/include/stlgeom/stltool.hpp +331 -0
- netgen/include/stlgeom/stltopology.hpp +419 -0
- netgen/include/stlgeom/vsstl.hpp +58 -0
- netgen/include/visualization/meshdoc.hpp +42 -0
- netgen/include/visualization/mvdraw.hpp +325 -0
- netgen/include/visualization/vispar.hpp +128 -0
- netgen/include/visualization/visual.hpp +28 -0
- netgen/include/visualization/visual_api.hpp +10 -0
- netgen/include/visualization/vssolution.hpp +399 -0
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/lib/togl.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.lib +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +1545 -0
- netgen/libngpy/__init__.pyi +7 -0
- netgen/libngpy/_csg.pyi +259 -0
- netgen/libngpy/_geom2d.pyi +323 -0
- netgen/libngpy/_meshing.pyi +1111 -0
- netgen/libngpy/_stl.pyi +131 -0
- netgen/libngpy.lib +0 -0
- netgen/libngpy.pyd +0 -0
- netgen/meshing.py +65 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/occ.py +52 -0
- netgen/read_gmsh.py +259 -0
- netgen/read_meshio.py +22 -0
- netgen/stl.py +2 -0
- netgen/togl.dll +0 -0
- netgen/version.py +2 -0
- netgen/webgui.py +529 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boundarycondition.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boxcyl.geo +32 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/circle_on_cube.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cone.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cube.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandring.geo +55 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandspheres.geo +21 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemcyl.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemsphere.geo +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylinder.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylsphere.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/doc/ng4.pdf +0 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipsoid.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipticcyl.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/extrusion.geo +99 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/fichera.geo +24 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/frame.step +11683 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/hinge.stl +8486 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/lshape3d.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes2.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/matrix.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ortho.geo +11 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/part1.stl +2662 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/period.geo +33 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/exportNeutral.py +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/mesh.py +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/revolution.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/screw.step +1694 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sculpture.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shell.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphere.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphereincube.geo +17 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/square.in2d +35 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarecircle.in2d +48 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarehole.in2d +47 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/torus.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/trafo.geo +57 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twobricks.geo +15 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocubes.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocyl.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/METADATA +15 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/RECORD +340 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/WHEEL +5 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/entry_points.txt +2 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/AUTHORS +1 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/LICENSE +504 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/top_level.txt +2 -0
- pyngcore/__init__.py +1 -0
- pyngcore/pyngcore.cp314-win_amd64.pyd +0 -0
|
@@ -0,0 +1,1392 @@
|
|
|
1
|
+
#ifndef FILE_ADTREE
|
|
2
|
+
#define FILE_ADTREE
|
|
3
|
+
|
|
4
|
+
/* *************************************************************************/
|
|
5
|
+
/* File: adtree.hh */
|
|
6
|
+
/* Author: Joachim Schoeberl */
|
|
7
|
+
/* Date: 16. Feb. 98 */
|
|
8
|
+
/* Redesigned by Wolfram Muehlhuber, May 1998 */
|
|
9
|
+
/* *************************************************************************/
|
|
10
|
+
|
|
11
|
+
#include <general/optmem.hpp>
|
|
12
|
+
#include <general/template.hpp>
|
|
13
|
+
#include <general/hashtabl.hpp>
|
|
14
|
+
|
|
15
|
+
#include "geomfuncs.hpp"
|
|
16
|
+
|
|
17
|
+
namespace netgen
|
|
18
|
+
{
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
Alternating Digital Tree
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// #include "../include/mystdlib.h"
|
|
25
|
+
// #include "../include/myadt.hpp"
|
|
26
|
+
|
|
27
|
+
class ADTreeNode
|
|
28
|
+
{
|
|
29
|
+
public:
|
|
30
|
+
ADTreeNode *left, *right, *father;
|
|
31
|
+
int dim;
|
|
32
|
+
float sep;
|
|
33
|
+
float *data;
|
|
34
|
+
float *boxmin;
|
|
35
|
+
float *boxmax;
|
|
36
|
+
int pi;
|
|
37
|
+
int nchilds;
|
|
38
|
+
|
|
39
|
+
ADTreeNode (int adim);
|
|
40
|
+
~ADTreeNode ();
|
|
41
|
+
|
|
42
|
+
friend class ADTree;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ADTreeCriterion
|
|
47
|
+
{
|
|
48
|
+
public:
|
|
49
|
+
ADTreeCriterion() { }
|
|
50
|
+
virtual int Eval (const ADTreeNode * node) const = 0;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class ADTree
|
|
55
|
+
{
|
|
56
|
+
int dim;
|
|
57
|
+
ADTreeNode * root;
|
|
58
|
+
float *cmin, *cmax;
|
|
59
|
+
NgArray<ADTreeNode*> ela;
|
|
60
|
+
const ADTreeCriterion * criterion;
|
|
61
|
+
|
|
62
|
+
NgArray<ADTreeNode*> stack;
|
|
63
|
+
NgArray<int> stackdir;
|
|
64
|
+
int stackindex;
|
|
65
|
+
|
|
66
|
+
public:
|
|
67
|
+
ADTree (int adim, const float * acmin,
|
|
68
|
+
const float * acmax);
|
|
69
|
+
~ADTree ();
|
|
70
|
+
|
|
71
|
+
void Insert (const float * p, int pi);
|
|
72
|
+
// void GetIntersecting (const float * bmin, const float * bmax,
|
|
73
|
+
// NgArray<int> & pis) const;
|
|
74
|
+
void SetCriterion (ADTreeCriterion & acriterion);
|
|
75
|
+
void Reset ();
|
|
76
|
+
int Next ();
|
|
77
|
+
void GetMatch (NgArray<int> & matches);
|
|
78
|
+
|
|
79
|
+
void DeleteElement (int pi);
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
void Print (ostream & ost) const
|
|
83
|
+
{ PrintRec (ost, root); }
|
|
84
|
+
|
|
85
|
+
void PrintRec (ostream & ost, const ADTreeNode * node) const;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ADTreeNode3
|
|
91
|
+
{
|
|
92
|
+
public:
|
|
93
|
+
ADTreeNode3 *left, *right, *father;
|
|
94
|
+
float sep;
|
|
95
|
+
float data[3];
|
|
96
|
+
int pi;
|
|
97
|
+
int nchilds;
|
|
98
|
+
|
|
99
|
+
ADTreeNode3 ();
|
|
100
|
+
void DeleteChilds ();
|
|
101
|
+
friend class ADTree3;
|
|
102
|
+
|
|
103
|
+
static BlockAllocator ball;
|
|
104
|
+
void * operator new(size_t);
|
|
105
|
+
void operator delete (void *);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class ADTree3
|
|
110
|
+
{
|
|
111
|
+
ADTreeNode3 * root;
|
|
112
|
+
float cmin[3], cmax[3];
|
|
113
|
+
NgArray<ADTreeNode3*> ela;
|
|
114
|
+
|
|
115
|
+
public:
|
|
116
|
+
ADTree3 (const float * acmin,
|
|
117
|
+
const float * acmax);
|
|
118
|
+
~ADTree3 ();
|
|
119
|
+
|
|
120
|
+
void Insert (const float * p, int pi);
|
|
121
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
122
|
+
NgArray<int> & pis) const;
|
|
123
|
+
|
|
124
|
+
void DeleteElement (int pi);
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
void Print (ostream & ost) const
|
|
128
|
+
{ PrintRec (ost, root); }
|
|
129
|
+
|
|
130
|
+
void PrintRec (ostream & ost, const ADTreeNode3 * node) const;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
/*
|
|
135
|
+
|
|
136
|
+
// divide each direction
|
|
137
|
+
#define ADTN_DIV 10
|
|
138
|
+
class ADTreeNode3Div
|
|
139
|
+
{
|
|
140
|
+
public:
|
|
141
|
+
ADTreeNode3Div *father;
|
|
142
|
+
ADTreeNode3Div *childs[ADTN_DIV];
|
|
143
|
+
|
|
144
|
+
float minx, dist;
|
|
145
|
+
float data[3];
|
|
146
|
+
int pi;
|
|
147
|
+
int nchilds;
|
|
148
|
+
|
|
149
|
+
ADTreeNode3Div ();
|
|
150
|
+
void DeleteChilds ();
|
|
151
|
+
friend class ADTree3Div;
|
|
152
|
+
|
|
153
|
+
static BlockAllocator ball;
|
|
154
|
+
void * operator new(size_t);
|
|
155
|
+
void operator delete (void *);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ADTree3Div
|
|
160
|
+
{
|
|
161
|
+
ADTreeNode3Div * root;
|
|
162
|
+
float cmin[3], cmax[3];
|
|
163
|
+
NgArray<ADTreeNode3Div*> ela;
|
|
164
|
+
|
|
165
|
+
public:
|
|
166
|
+
ADTree3Div (const float * acmin,
|
|
167
|
+
const float * acmax);
|
|
168
|
+
~ADTree3Div ();
|
|
169
|
+
|
|
170
|
+
void Insert (const float * p, int pi);
|
|
171
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
172
|
+
NgArray<int> & pis) const;
|
|
173
|
+
|
|
174
|
+
void DeleteElement (int pi);
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
void Print (ostream & ost) const
|
|
178
|
+
{ PrintRec (ost, root); }
|
|
179
|
+
|
|
180
|
+
void PrintRec (ostream & ost, const ADTreeNode3Div * node) const;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
#define ADTN_SIZE 10
|
|
187
|
+
|
|
188
|
+
// multiple entries
|
|
189
|
+
class ADTreeNode3M
|
|
190
|
+
{
|
|
191
|
+
public:
|
|
192
|
+
ADTreeNode3M *left, *right, *father;
|
|
193
|
+
float sep;
|
|
194
|
+
float data[ADTN_SIZE][3];
|
|
195
|
+
int pi[ADTN_SIZE];
|
|
196
|
+
int nchilds;
|
|
197
|
+
|
|
198
|
+
ADTreeNode3M ();
|
|
199
|
+
void DeleteChilds ();
|
|
200
|
+
friend class ADTree3M;
|
|
201
|
+
|
|
202
|
+
static BlockAllocator ball;
|
|
203
|
+
void * operator new(size_t);
|
|
204
|
+
void operator delete (void *);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class ADTree3M
|
|
209
|
+
{
|
|
210
|
+
ADTreeNode3M * root;
|
|
211
|
+
float cmin[3], cmax[3];
|
|
212
|
+
NgArray<ADTreeNode3M*> ela;
|
|
213
|
+
|
|
214
|
+
public:
|
|
215
|
+
ADTree3M (const float * acmin,
|
|
216
|
+
const float * acmax);
|
|
217
|
+
~ADTree3M ();
|
|
218
|
+
|
|
219
|
+
void Insert (const float * p, int pi);
|
|
220
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
221
|
+
NgArray<int> & pis) const;
|
|
222
|
+
|
|
223
|
+
void DeleteElement (int pi);
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
void Print (ostream & ost) const
|
|
227
|
+
{ PrintRec (ost, root); }
|
|
228
|
+
|
|
229
|
+
void PrintRec (ostream & ost, const ADTreeNode3M * node) const;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class ADTreeNode3F
|
|
238
|
+
{
|
|
239
|
+
public:
|
|
240
|
+
ADTreeNode3F *father;
|
|
241
|
+
ADTreeNode3F *childs[8];
|
|
242
|
+
float sep[3];
|
|
243
|
+
float data[3];
|
|
244
|
+
int pi;
|
|
245
|
+
int nchilds;
|
|
246
|
+
|
|
247
|
+
ADTreeNode3F ();
|
|
248
|
+
void DeleteChilds ();
|
|
249
|
+
friend class ADTree3F;
|
|
250
|
+
|
|
251
|
+
static BlockAllocator ball;
|
|
252
|
+
void * operator new(size_t);
|
|
253
|
+
void operator delete (void *);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// fat tree
|
|
257
|
+
class ADTree3F
|
|
258
|
+
{
|
|
259
|
+
ADTreeNode3F * root;
|
|
260
|
+
float cmin[3], cmax[3];
|
|
261
|
+
NgArray<ADTreeNode3F*> ela;
|
|
262
|
+
|
|
263
|
+
public:
|
|
264
|
+
ADTree3F (const float * acmin,
|
|
265
|
+
const float * acmax);
|
|
266
|
+
~ADTree3F ();
|
|
267
|
+
|
|
268
|
+
void Insert (const float * p, int pi);
|
|
269
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
270
|
+
NgArray<int> & pis) const;
|
|
271
|
+
|
|
272
|
+
void DeleteElement (int pi);
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
void Print (ostream & ost) const
|
|
276
|
+
{ PrintRec (ost, root); }
|
|
277
|
+
|
|
278
|
+
void PrintRec (ostream & ost, const ADTreeNode3F * node) const;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class ADTreeNode3FM
|
|
285
|
+
{
|
|
286
|
+
public:
|
|
287
|
+
ADTreeNode3FM *father;
|
|
288
|
+
ADTreeNode3FM *childs[8];
|
|
289
|
+
float sep[3];
|
|
290
|
+
float data[ADTN_SIZE][3];
|
|
291
|
+
int pi[ADTN_SIZE];
|
|
292
|
+
int nchilds;
|
|
293
|
+
|
|
294
|
+
ADTreeNode3FM ();
|
|
295
|
+
void DeleteChilds ();
|
|
296
|
+
friend class ADTree3FM;
|
|
297
|
+
|
|
298
|
+
static BlockAllocator ball;
|
|
299
|
+
void * operator new(size_t);
|
|
300
|
+
void operator delete (void *);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
// fat tree
|
|
304
|
+
class ADTree3FM
|
|
305
|
+
{
|
|
306
|
+
ADTreeNode3FM * root;
|
|
307
|
+
float cmin[3], cmax[3];
|
|
308
|
+
NgArray<ADTreeNode3FM*> ela;
|
|
309
|
+
|
|
310
|
+
public:
|
|
311
|
+
ADTree3FM (const float * acmin,
|
|
312
|
+
const float * acmax);
|
|
313
|
+
~ADTree3FM ();
|
|
314
|
+
|
|
315
|
+
void Insert (const float * p, int pi);
|
|
316
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
317
|
+
NgArray<int> & pis) const;
|
|
318
|
+
|
|
319
|
+
void DeleteElement (int pi);
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
void Print (ostream & ost) const
|
|
323
|
+
{ PrintRec (ost, root); }
|
|
324
|
+
|
|
325
|
+
void PrintRec (ostream & ost, const ADTreeNode3FM * node) const;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
*/
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
class ADTreeNode6
|
|
337
|
+
{
|
|
338
|
+
public:
|
|
339
|
+
ADTreeNode6 *left, *right, *father;
|
|
340
|
+
float sep;
|
|
341
|
+
float data[6];
|
|
342
|
+
int pi;
|
|
343
|
+
int nchilds;
|
|
344
|
+
|
|
345
|
+
ADTreeNode6 ();
|
|
346
|
+
void DeleteChilds ();
|
|
347
|
+
friend class ADTree6;
|
|
348
|
+
|
|
349
|
+
static BlockAllocator ball;
|
|
350
|
+
void * operator new(size_t);
|
|
351
|
+
void operator delete (void *);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class ADTree6
|
|
356
|
+
{
|
|
357
|
+
ADTreeNode6 * root;
|
|
358
|
+
float cmin[6], cmax[6];
|
|
359
|
+
NgArray<ADTreeNode6*> ela;
|
|
360
|
+
|
|
361
|
+
public:
|
|
362
|
+
ADTree6 (const float * acmin,
|
|
363
|
+
const float * acmax);
|
|
364
|
+
~ADTree6 ();
|
|
365
|
+
|
|
366
|
+
void Insert (const float * p, int pi);
|
|
367
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
368
|
+
NgArray<int> & pis) const;
|
|
369
|
+
|
|
370
|
+
void DeleteElement (int pi);
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
void Print (ostream & ost) const
|
|
374
|
+
{ PrintRec (ost, root); }
|
|
375
|
+
int Depth () const
|
|
376
|
+
{ return DepthRec (root); }
|
|
377
|
+
int Elements () const
|
|
378
|
+
{ return ElementsRec (root); }
|
|
379
|
+
|
|
380
|
+
void PrintRec (ostream & ost, const ADTreeNode6 * node) const;
|
|
381
|
+
int DepthRec (const ADTreeNode6 * node) const;
|
|
382
|
+
int ElementsRec (const ADTreeNode6 * node) const;
|
|
383
|
+
|
|
384
|
+
void PrintMemInfo (ostream & ost) const;
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
template <int DIM, typename T>
|
|
392
|
+
class T_ADTreeNode
|
|
393
|
+
{
|
|
394
|
+
public:
|
|
395
|
+
T_ADTreeNode *left, *right, *father;
|
|
396
|
+
float sep;
|
|
397
|
+
// float data[DIM];
|
|
398
|
+
Point<DIM,float> data;
|
|
399
|
+
T pi;
|
|
400
|
+
int nchilds;
|
|
401
|
+
|
|
402
|
+
T_ADTreeNode ()
|
|
403
|
+
{
|
|
404
|
+
// pi = -1;
|
|
405
|
+
SetInvalid(pi);
|
|
406
|
+
left = NULL;
|
|
407
|
+
right = NULL;
|
|
408
|
+
father = NULL;
|
|
409
|
+
nchilds = 0;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
void DeleteChilds (BlockAllocator & ball)
|
|
413
|
+
{
|
|
414
|
+
if (left)
|
|
415
|
+
{
|
|
416
|
+
left->DeleteChilds(ball);
|
|
417
|
+
ball.Free(left);
|
|
418
|
+
left = NULL;
|
|
419
|
+
}
|
|
420
|
+
if (right)
|
|
421
|
+
{
|
|
422
|
+
right->DeleteChilds(ball);
|
|
423
|
+
ball.Free(right);
|
|
424
|
+
right = NULL;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
template <int dim, typename T = INDEX>
|
|
432
|
+
class T_ADTree
|
|
433
|
+
{
|
|
434
|
+
T_ADTreeNode<dim,T> * root;
|
|
435
|
+
// float cmin[dim], cmax[dim];
|
|
436
|
+
Point<dim> cmin, cmax;
|
|
437
|
+
// NgArray<T_ADTreeNode<dim>*> ela;
|
|
438
|
+
NgClosedHashTable<T, T_ADTreeNode<dim,T>*> ela;
|
|
439
|
+
|
|
440
|
+
BlockAllocator ball{sizeof(T_ADTreeNode<dim,T>)};
|
|
441
|
+
public:
|
|
442
|
+
T_ADTree (Point<dim> acmin, Point<dim> acmax)
|
|
443
|
+
{
|
|
444
|
+
cmin = acmin;
|
|
445
|
+
cmax = acmax;
|
|
446
|
+
|
|
447
|
+
root = new (ball.Alloc()) T_ADTreeNode<dim,T>;
|
|
448
|
+
root->sep = (cmin[0] + cmax[0]) / 2;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
~T_ADTree ()
|
|
452
|
+
{
|
|
453
|
+
root->DeleteChilds(ball);
|
|
454
|
+
ball.Free(root);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
void Insert (Point<dim> p, T pi)
|
|
458
|
+
{
|
|
459
|
+
T_ADTreeNode<dim,T> *node(NULL);
|
|
460
|
+
T_ADTreeNode<dim,T> *next;
|
|
461
|
+
int dir;
|
|
462
|
+
int lr(0);
|
|
463
|
+
|
|
464
|
+
Point<dim> bmin = cmin;
|
|
465
|
+
Point<dim> bmax = cmax;
|
|
466
|
+
|
|
467
|
+
next = root;
|
|
468
|
+
dir = 0;
|
|
469
|
+
while (next)
|
|
470
|
+
{
|
|
471
|
+
node = next;
|
|
472
|
+
|
|
473
|
+
if (IsInvalid(node->pi))
|
|
474
|
+
{
|
|
475
|
+
// memcpy (node->data, p, dim * sizeof(float));
|
|
476
|
+
node->data = p;
|
|
477
|
+
node->pi = pi;
|
|
478
|
+
|
|
479
|
+
// if (ela.Size() < pi+1)
|
|
480
|
+
// ela.SetSize (pi+1);
|
|
481
|
+
ela[pi] = node;
|
|
482
|
+
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (node->sep > p[dir])
|
|
487
|
+
{
|
|
488
|
+
next = node->left;
|
|
489
|
+
bmax(dir) = node->sep;
|
|
490
|
+
lr = 0;
|
|
491
|
+
}
|
|
492
|
+
else
|
|
493
|
+
{
|
|
494
|
+
next = node->right;
|
|
495
|
+
bmin(dir) = node->sep;
|
|
496
|
+
lr = 1;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
dir++;
|
|
500
|
+
if (dir == dim) dir = 0;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
next = new (ball.Alloc()) T_ADTreeNode<dim,T>;
|
|
505
|
+
next->data = p;
|
|
506
|
+
next->pi = pi;
|
|
507
|
+
next->sep = (bmin[dir] + bmax[dir]) / 2;
|
|
508
|
+
|
|
509
|
+
// if (ela.Size() < pi+1)
|
|
510
|
+
// ela.SetSize (pi+1);
|
|
511
|
+
ela[pi] = next;
|
|
512
|
+
|
|
513
|
+
if (lr)
|
|
514
|
+
node->right = next;
|
|
515
|
+
else
|
|
516
|
+
node->left = next;
|
|
517
|
+
next -> father = node;
|
|
518
|
+
|
|
519
|
+
while (node)
|
|
520
|
+
{
|
|
521
|
+
node->nchilds++;
|
|
522
|
+
node = node->father;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
class inttn {
|
|
528
|
+
public:
|
|
529
|
+
int dir;
|
|
530
|
+
T_ADTreeNode<dim,T> * node;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
void GetIntersecting (Point<dim> bmin, Point<dim> bmax,
|
|
534
|
+
NgArray<T> & pis) const
|
|
535
|
+
{
|
|
536
|
+
NgArrayMem<inttn,10000> stack(10000);
|
|
537
|
+
pis.SetSize(0);
|
|
538
|
+
|
|
539
|
+
stack[0].node = root;
|
|
540
|
+
stack[0].dir = 0;
|
|
541
|
+
int stacks = 0;
|
|
542
|
+
|
|
543
|
+
while (stacks >= 0)
|
|
544
|
+
{
|
|
545
|
+
T_ADTreeNode<dim,T> * node = stack[stacks].node;
|
|
546
|
+
int dir = stack[stacks].dir;
|
|
547
|
+
|
|
548
|
+
stacks--;
|
|
549
|
+
if (!IsInvalid(node->pi)) // != -1)
|
|
550
|
+
{
|
|
551
|
+
bool found = true;
|
|
552
|
+
for (int i = 0; i < dim/2; i++)
|
|
553
|
+
if (node->data[i] > bmax[i])
|
|
554
|
+
found = false;
|
|
555
|
+
for (int i = dim/2; i < dim; i++)
|
|
556
|
+
if (node->data[i] < bmin[i])
|
|
557
|
+
found = false;
|
|
558
|
+
if (found)
|
|
559
|
+
pis.Append (node->pi);
|
|
560
|
+
/*
|
|
561
|
+
if (node->data[0] > bmax[0] ||
|
|
562
|
+
node->data[1] > bmax[1] ||
|
|
563
|
+
node->data[2] > bmax[2] ||
|
|
564
|
+
node->data[3] < bmin[3] ||
|
|
565
|
+
node->data[4] < bmin[4] ||
|
|
566
|
+
node->data[5] < bmin[5])
|
|
567
|
+
;
|
|
568
|
+
else
|
|
569
|
+
{
|
|
570
|
+
pis.Append (node->pi);
|
|
571
|
+
}
|
|
572
|
+
*/
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
int ndir = (dir+1) % dim;
|
|
576
|
+
|
|
577
|
+
if (node->left && bmin[dir] <= node->sep)
|
|
578
|
+
{
|
|
579
|
+
stacks++;
|
|
580
|
+
stack[stacks].node = node->left;
|
|
581
|
+
stack[stacks].dir = ndir;
|
|
582
|
+
}
|
|
583
|
+
if (node->right && bmax[dir] >= node->sep)
|
|
584
|
+
{
|
|
585
|
+
stacks++;
|
|
586
|
+
stack[stacks].node = node->right;
|
|
587
|
+
stack[stacks].dir = ndir;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
void DeleteElement (T pi)
|
|
595
|
+
{
|
|
596
|
+
T_ADTreeNode<dim,T> * node = ela[pi];
|
|
597
|
+
ela.Delete(pi);
|
|
598
|
+
|
|
599
|
+
SetInvalid(node->pi); // = -1;
|
|
600
|
+
|
|
601
|
+
node = node->father;
|
|
602
|
+
while (node)
|
|
603
|
+
{
|
|
604
|
+
node->nchilds--;
|
|
605
|
+
node = node->father;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
void Print (ostream & ost) const
|
|
611
|
+
{ PrintRec (ost, root); }
|
|
612
|
+
int Depth () const
|
|
613
|
+
{ return DepthRec (root); }
|
|
614
|
+
int Elements () const
|
|
615
|
+
{ return ElementsRec (root); }
|
|
616
|
+
|
|
617
|
+
void PrintRec (ostream & ost, const T_ADTreeNode<dim,T> * node) const
|
|
618
|
+
{
|
|
619
|
+
|
|
620
|
+
// if (node->data) // true anyway
|
|
621
|
+
{
|
|
622
|
+
ost << node->pi << ": ";
|
|
623
|
+
ost << node->nchilds << " childs, ";
|
|
624
|
+
for (int i = 0; i < dim; i++)
|
|
625
|
+
ost << node->data[i] << " ";
|
|
626
|
+
ost << endl;
|
|
627
|
+
}
|
|
628
|
+
if (node->left)
|
|
629
|
+
PrintRec (ost, node->left);
|
|
630
|
+
if (node->right)
|
|
631
|
+
PrintRec (ost, node->right);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
int DepthRec (const T_ADTreeNode<dim,T> * node) const
|
|
635
|
+
{
|
|
636
|
+
int ldepth = 0;
|
|
637
|
+
int rdepth = 0;
|
|
638
|
+
|
|
639
|
+
if (node->left)
|
|
640
|
+
ldepth = DepthRec(node->left);
|
|
641
|
+
if (node->right)
|
|
642
|
+
rdepth = DepthRec(node->right);
|
|
643
|
+
return 1 + max2 (ldepth, rdepth);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
int ElementsRec (const T_ADTreeNode<dim,T> * node) const
|
|
647
|
+
{
|
|
648
|
+
int els = 1;
|
|
649
|
+
if (node->left)
|
|
650
|
+
els += ElementsRec(node->left);
|
|
651
|
+
if (node->right)
|
|
652
|
+
els += ElementsRec(node->right);
|
|
653
|
+
return els;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
void PrintMemInfo (ostream & ost) const
|
|
658
|
+
{
|
|
659
|
+
ost << Elements() << " elements a " << sizeof(ADTreeNode6)
|
|
660
|
+
<< " Bytes = "
|
|
661
|
+
<< Elements() * sizeof(T_ADTreeNode<dim,T>) << endl;
|
|
662
|
+
ost << "maxind = " << ela.Size() << " = " << sizeof(T_ADTreeNode<dim,T>*) * ela.Size() << " Bytes" << endl;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
/*
|
|
673
|
+
|
|
674
|
+
class ADTreeNode6F
|
|
675
|
+
{
|
|
676
|
+
public:
|
|
677
|
+
ADTreeNode6F * father;
|
|
678
|
+
ADTreeNode6F * childs[64];
|
|
679
|
+
|
|
680
|
+
float sep[6];
|
|
681
|
+
float data[6];
|
|
682
|
+
int pi;
|
|
683
|
+
int nchilds;
|
|
684
|
+
|
|
685
|
+
ADTreeNode6F ();
|
|
686
|
+
void DeleteChilds ();
|
|
687
|
+
friend class ADTree6F;
|
|
688
|
+
|
|
689
|
+
static BlockAllocator ball;
|
|
690
|
+
void * operator new(size_t);
|
|
691
|
+
void operator delete (void *);
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
class ADTree6F
|
|
696
|
+
{
|
|
697
|
+
ADTreeNode6F * root;
|
|
698
|
+
float cmin[6], cmax[6];
|
|
699
|
+
NgArray<ADTreeNode6F*> ela;
|
|
700
|
+
|
|
701
|
+
public:
|
|
702
|
+
ADTree6F (const float * acmin,
|
|
703
|
+
const float * acmax);
|
|
704
|
+
~ADTree6F ();
|
|
705
|
+
|
|
706
|
+
void Insert (const float * p, int pi);
|
|
707
|
+
void GetIntersecting (const float * bmin, const float * bmax,
|
|
708
|
+
NgArray<int> & pis) const;
|
|
709
|
+
|
|
710
|
+
void DeleteElement (int pi);
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
void Print (ostream & ost) const
|
|
714
|
+
{ PrintRec (ost, root); }
|
|
715
|
+
int Depth () const
|
|
716
|
+
{ return DepthRec (root); }
|
|
717
|
+
|
|
718
|
+
void PrintRec (ostream & ost, const ADTreeNode6F * node) const;
|
|
719
|
+
int DepthRec (const ADTreeNode6F * node) const;
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
*/
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
class Point3dTree
|
|
735
|
+
{
|
|
736
|
+
ADTree3 * tree;
|
|
737
|
+
|
|
738
|
+
public:
|
|
739
|
+
DLL_HEADER Point3dTree (const Point<3> & pmin, const Point<3> & pmax);
|
|
740
|
+
DLL_HEADER ~Point3dTree ();
|
|
741
|
+
DLL_HEADER void Insert (const Point<3> & p, int pi);
|
|
742
|
+
void DeleteElement (int pi)
|
|
743
|
+
{ tree->DeleteElement(pi); }
|
|
744
|
+
DLL_HEADER void GetIntersecting (const Point<3> & pmin, const Point<3> & pmax,
|
|
745
|
+
NgArray<int> & pis) const;
|
|
746
|
+
const ADTree3 & Tree() const { return *tree; };
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
template<int dim, typename T=INDEX>
|
|
750
|
+
class BoxTree
|
|
751
|
+
{
|
|
752
|
+
public:
|
|
753
|
+
// Number of entries per leaf
|
|
754
|
+
static constexpr int N = 100;
|
|
755
|
+
|
|
756
|
+
struct Node;
|
|
757
|
+
|
|
758
|
+
struct Leaf
|
|
759
|
+
{
|
|
760
|
+
Point<2*dim> p[N];
|
|
761
|
+
T index[N];
|
|
762
|
+
int n_elements;
|
|
763
|
+
|
|
764
|
+
Leaf() : n_elements(0)
|
|
765
|
+
{ }
|
|
766
|
+
|
|
767
|
+
void Add( NgClosedHashTable<T, Leaf*> &leaf_index, const Point<2*dim> &ap, T aindex )
|
|
768
|
+
{
|
|
769
|
+
p[n_elements] = ap;
|
|
770
|
+
index[n_elements] = aindex;
|
|
771
|
+
n_elements++;
|
|
772
|
+
leaf_index[aindex] = this;
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
|
|
776
|
+
struct Node
|
|
777
|
+
{
|
|
778
|
+
union
|
|
779
|
+
{
|
|
780
|
+
Node *children[2];
|
|
781
|
+
Leaf *leaf;
|
|
782
|
+
};
|
|
783
|
+
double sep;
|
|
784
|
+
int level;
|
|
785
|
+
|
|
786
|
+
Node()
|
|
787
|
+
: children{nullptr,nullptr}
|
|
788
|
+
{ }
|
|
789
|
+
|
|
790
|
+
~Node()
|
|
791
|
+
{ }
|
|
792
|
+
|
|
793
|
+
Leaf *GetLeaf() const
|
|
794
|
+
{
|
|
795
|
+
return children[1] ? nullptr : leaf;
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
private:
|
|
800
|
+
Node root;
|
|
801
|
+
|
|
802
|
+
NgClosedHashTable<T, Leaf*> leaf_index;
|
|
803
|
+
|
|
804
|
+
Point<dim> global_min, global_max;
|
|
805
|
+
double tol;
|
|
806
|
+
size_t n_leaves;
|
|
807
|
+
size_t n_nodes;
|
|
808
|
+
BlockAllocator ball_nodes;
|
|
809
|
+
BlockAllocator ball_leaves;
|
|
810
|
+
|
|
811
|
+
public:
|
|
812
|
+
|
|
813
|
+
BoxTree (const Point<dim> & pmin, const Point<dim> & pmax)
|
|
814
|
+
: global_min(pmin), global_max(pmax), n_leaves(1), n_nodes(1), ball_nodes(sizeof(Node)), ball_leaves(sizeof(Leaf))
|
|
815
|
+
{
|
|
816
|
+
root.leaf = (Leaf*) ball_leaves.Alloc(); new (root.leaf) Leaf();
|
|
817
|
+
root.level = 0;
|
|
818
|
+
tol = 1e-7 * Dist(pmax, pmin);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
BoxTree (const Box<dim> & box)
|
|
822
|
+
: BoxTree(box.PMin(), box.PMax())
|
|
823
|
+
{ }
|
|
824
|
+
|
|
825
|
+
void SetTolerance(double _tol) { tol = _tol; }
|
|
826
|
+
double GetTolerance() { return tol; }
|
|
827
|
+
|
|
828
|
+
size_t GetNLeaves()
|
|
829
|
+
{
|
|
830
|
+
return n_leaves;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
size_t GetNNodes()
|
|
834
|
+
{
|
|
835
|
+
return n_nodes;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
template<typename TFunc>
|
|
839
|
+
void GetFirstIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
|
|
840
|
+
TFunc func=[](auto pi){return false;}) const
|
|
841
|
+
{
|
|
842
|
+
// static Timer timer("BoxTree::GetIntersecting"); RegionTimer rt(timer);
|
|
843
|
+
// static Timer timer1("BoxTree::GetIntersecting-LinearSearch");
|
|
844
|
+
ArrayMem<const Node*, 100> stack;
|
|
845
|
+
ArrayMem<int, 100> dir_stack;
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
Point<2*dim> tpmin, tpmax;
|
|
849
|
+
|
|
850
|
+
for (size_t i : IntRange(dim))
|
|
851
|
+
{
|
|
852
|
+
tpmin(i) = global_min(i);
|
|
853
|
+
tpmax(i) = pmax(i)+tol;
|
|
854
|
+
|
|
855
|
+
tpmin(i+dim) = pmin(i)-tol;
|
|
856
|
+
tpmax(i+dim) = global_max(i);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
stack.SetSize(0);
|
|
860
|
+
stack.Append(&root);
|
|
861
|
+
dir_stack.SetSize(0);
|
|
862
|
+
dir_stack.Append(0);
|
|
863
|
+
|
|
864
|
+
while(stack.Size())
|
|
865
|
+
{
|
|
866
|
+
const Node *node = stack.Last();
|
|
867
|
+
stack.DeleteLast();
|
|
868
|
+
|
|
869
|
+
int dir = dir_stack.Last();
|
|
870
|
+
dir_stack.DeleteLast();
|
|
871
|
+
|
|
872
|
+
if(Leaf *leaf = node->GetLeaf())
|
|
873
|
+
{
|
|
874
|
+
// RegionTimer rt1(timer1);
|
|
875
|
+
for (auto i : IntRange(leaf->n_elements))
|
|
876
|
+
{
|
|
877
|
+
bool intersect = true;
|
|
878
|
+
const auto p = leaf->p[i];
|
|
879
|
+
|
|
880
|
+
for (int d = 0; d < dim; d++)
|
|
881
|
+
if (p[d] > tpmax[d])
|
|
882
|
+
intersect = false;
|
|
883
|
+
for (int d = dim; d < 2*dim; d++)
|
|
884
|
+
if (p[d] < tpmin[d])
|
|
885
|
+
intersect = false;
|
|
886
|
+
if(intersect)
|
|
887
|
+
if(func(leaf->index[i])) return;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
else
|
|
891
|
+
{
|
|
892
|
+
int newdir = dir+1;
|
|
893
|
+
if(newdir==2*dim) newdir = 0;
|
|
894
|
+
if (tpmin[dir] <= node->sep)
|
|
895
|
+
{
|
|
896
|
+
stack.Append(node->children[0]);
|
|
897
|
+
dir_stack.Append(newdir);
|
|
898
|
+
}
|
|
899
|
+
if (tpmax[dir] >= node->sep)
|
|
900
|
+
{
|
|
901
|
+
stack.Append(node->children[1]);
|
|
902
|
+
dir_stack.Append(newdir);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
void GetIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
|
|
909
|
+
NgArray<T> & pis) const
|
|
910
|
+
{
|
|
911
|
+
pis.SetSize(0);
|
|
912
|
+
GetFirstIntersecting(pmin, pmax, [&pis](auto pi) { pis.Append(pi); return false;});
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
void GetIntersecting(const Point<dim> & pmin,
|
|
916
|
+
const Point<dim> & pmax,
|
|
917
|
+
Array<T> & pis) const
|
|
918
|
+
{
|
|
919
|
+
pis.SetSize0();
|
|
920
|
+
GetFirstIntersecting(pmin, pmax, [&pis](auto pi) { pis.Append(pi); return false;});
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
void Insert (const Box<dim> & box, T pi)
|
|
924
|
+
{
|
|
925
|
+
Insert (box.PMin(), box.PMax(), pi);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
void Insert (const Point<dim> & pmin, const Point<dim> & pmax, T pi)
|
|
929
|
+
{
|
|
930
|
+
// static Timer timer("BoxTree::Insert"); RegionTimer rt(timer);
|
|
931
|
+
int dir = 0;
|
|
932
|
+
Point<2*dim> p;
|
|
933
|
+
for (auto i : IntRange(dim))
|
|
934
|
+
{
|
|
935
|
+
p(i) = pmin[i];
|
|
936
|
+
p(i+dim) = pmax[i];
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
Node * node = &root;
|
|
940
|
+
Leaf * leaf = node->GetLeaf();
|
|
941
|
+
|
|
942
|
+
// search correct leaf to add point
|
|
943
|
+
while(!leaf)
|
|
944
|
+
{
|
|
945
|
+
node = p[dir] < node->sep ? node->children[0] : node->children[1];
|
|
946
|
+
dir++;
|
|
947
|
+
if(dir==2*dim) dir = 0;
|
|
948
|
+
leaf = node->GetLeaf();
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// add point to leaf
|
|
952
|
+
if(leaf->n_elements < N)
|
|
953
|
+
leaf->Add(leaf_index, p,pi);
|
|
954
|
+
else // assume leaf->n_elements == N
|
|
955
|
+
{
|
|
956
|
+
// add two new nodes and one new leaf
|
|
957
|
+
int n_elements = leaf->n_elements;
|
|
958
|
+
ArrayMem<double, N> coords(n_elements);
|
|
959
|
+
ArrayMem<int, N> order(n_elements);
|
|
960
|
+
|
|
961
|
+
// separate points in two halves, first sort all coordinates in direction dir
|
|
962
|
+
for (auto i : IntRange(n_elements))
|
|
963
|
+
{
|
|
964
|
+
order[i] = i;
|
|
965
|
+
coords[i] = leaf->p[i][dir];
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
QuickSortI(coords, order);
|
|
969
|
+
int isplit = N/2;
|
|
970
|
+
Leaf *leaf1 = (Leaf*) ball_leaves.Alloc(); new (leaf1) Leaf();
|
|
971
|
+
Leaf *leaf2 = (Leaf*) ball_leaves.Alloc(); new (leaf2) Leaf();
|
|
972
|
+
|
|
973
|
+
for (auto i : order.Range(0, isplit))
|
|
974
|
+
leaf1->Add(leaf_index, leaf->p[i], leaf->index[i] );
|
|
975
|
+
for (auto i : order.Range(isplit, N))
|
|
976
|
+
leaf2->Add(leaf_index, leaf->p[i], leaf->index[i] );
|
|
977
|
+
|
|
978
|
+
Node *node1 = (Node*) ball_nodes.Alloc(); new (node1) Node();
|
|
979
|
+
node1->leaf = leaf1;
|
|
980
|
+
node1->level = node->level+1;
|
|
981
|
+
|
|
982
|
+
Node *node2 = (Node*) ball_nodes.Alloc(); new (node2) Node();
|
|
983
|
+
node2->leaf = leaf2;
|
|
984
|
+
node2->level = node->level+1;
|
|
985
|
+
|
|
986
|
+
node->children[0] = node1;
|
|
987
|
+
node->children[1] = node2;
|
|
988
|
+
node->sep = 0.5 * (leaf->p[order[isplit-1]][dir] + leaf->p[order[isplit]][dir]);
|
|
989
|
+
|
|
990
|
+
// add new point to one of the new leaves
|
|
991
|
+
if (p[dir] < node->sep)
|
|
992
|
+
leaf1->Add( leaf_index, p, pi );
|
|
993
|
+
else
|
|
994
|
+
leaf2->Add( leaf_index, p, pi );
|
|
995
|
+
|
|
996
|
+
ball_leaves.Free(leaf);
|
|
997
|
+
n_leaves++;
|
|
998
|
+
n_nodes+=2;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
void DeleteElement (T pi)
|
|
1003
|
+
{
|
|
1004
|
+
// static Timer timer("BoxTree::DeleteElement"); RegionTimer rt(timer);
|
|
1005
|
+
Leaf *leaf = leaf_index[pi];
|
|
1006
|
+
leaf_index.Delete(pi);
|
|
1007
|
+
auto & n_elements = leaf->n_elements;
|
|
1008
|
+
auto & index = leaf->index;
|
|
1009
|
+
auto & p = leaf->p;
|
|
1010
|
+
|
|
1011
|
+
for (auto i : IntRange(n_elements))
|
|
1012
|
+
{
|
|
1013
|
+
if(index[i] == pi)
|
|
1014
|
+
{
|
|
1015
|
+
n_elements--;
|
|
1016
|
+
if(i!=n_elements)
|
|
1017
|
+
{
|
|
1018
|
+
index[i] = index[n_elements];
|
|
1019
|
+
p[i] = p[n_elements];
|
|
1020
|
+
}
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
// template <int dim, typename T = INDEX>
|
|
1028
|
+
// class BoxTree
|
|
1029
|
+
// {
|
|
1030
|
+
// T_ADTree<2*dim,T> * tree;
|
|
1031
|
+
// Point<dim> boxpmin, boxpmax;
|
|
1032
|
+
// public:
|
|
1033
|
+
// BoxTree (const Box<dim> & abox)
|
|
1034
|
+
// {
|
|
1035
|
+
// boxpmin = abox.PMin();
|
|
1036
|
+
// boxpmax = abox.PMax();
|
|
1037
|
+
// Point<2*dim> tpmin, tpmax;
|
|
1038
|
+
// for (int i = 0; i < dim; i++)
|
|
1039
|
+
// {
|
|
1040
|
+
// tpmin(i) = tpmin(i+dim) = boxpmin(i);
|
|
1041
|
+
// tpmax(i) = tpmax(i+dim) = boxpmax(i);
|
|
1042
|
+
// }
|
|
1043
|
+
// tree = new T_ADTree<2*dim,T> (tpmin, tpmax);
|
|
1044
|
+
// }
|
|
1045
|
+
//
|
|
1046
|
+
// BoxTree (const Point<dim> & apmin, const Point<dim> & apmax)
|
|
1047
|
+
// {
|
|
1048
|
+
// boxpmin = apmin;
|
|
1049
|
+
// boxpmax = apmax;
|
|
1050
|
+
// Point<2*dim> tpmin, tpmax;
|
|
1051
|
+
// for (int i = 0; i < dim; i++)
|
|
1052
|
+
// {
|
|
1053
|
+
// tpmin(i) = tpmin(i+dim) = boxpmin(i);
|
|
1054
|
+
// tpmax(i) = tpmax(i+dim) = boxpmax(i);
|
|
1055
|
+
// }
|
|
1056
|
+
// tree = new T_ADTree<2*dim,T> (tpmin, tpmax);
|
|
1057
|
+
// }
|
|
1058
|
+
//
|
|
1059
|
+
// ~BoxTree ()
|
|
1060
|
+
// {
|
|
1061
|
+
// delete tree;
|
|
1062
|
+
// }
|
|
1063
|
+
//
|
|
1064
|
+
// void Insert (const Point<dim> & bmin, const Point<dim> & bmax, T pi)
|
|
1065
|
+
// {
|
|
1066
|
+
// Point<2*dim> tp;
|
|
1067
|
+
//
|
|
1068
|
+
// for (size_t i = 0; i < dim; i++)
|
|
1069
|
+
// {
|
|
1070
|
+
// tp(i) = bmin(i);
|
|
1071
|
+
// tp(i+dim) = bmax(i);
|
|
1072
|
+
// }
|
|
1073
|
+
//
|
|
1074
|
+
// tree->Insert (tp, pi);
|
|
1075
|
+
// }
|
|
1076
|
+
//
|
|
1077
|
+
// void Insert (const Box<dim> & box, T pi)
|
|
1078
|
+
// {
|
|
1079
|
+
// Insert (box.PMin(), box.PMax(), pi);
|
|
1080
|
+
// }
|
|
1081
|
+
//
|
|
1082
|
+
// void DeleteElement (T pi)
|
|
1083
|
+
// {
|
|
1084
|
+
// tree->DeleteElement(pi);
|
|
1085
|
+
// }
|
|
1086
|
+
//
|
|
1087
|
+
// void GetIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
|
|
1088
|
+
// NgArray<T> & pis) const
|
|
1089
|
+
// {
|
|
1090
|
+
// Point<2*dim> tpmin, tpmax;
|
|
1091
|
+
// double tol = Tolerance();
|
|
1092
|
+
// for (size_t i = 0; i < dim; i++)
|
|
1093
|
+
// {
|
|
1094
|
+
// tpmin(i) = boxpmin(i);
|
|
1095
|
+
// tpmax(i) = pmax(i)+tol;
|
|
1096
|
+
//
|
|
1097
|
+
// tpmin(i+dim) = pmin(i)-tol;
|
|
1098
|
+
// tpmax(i+dim) = boxpmax(i);
|
|
1099
|
+
// }
|
|
1100
|
+
//
|
|
1101
|
+
// tree->GetIntersecting (tpmin, tpmax, pis);
|
|
1102
|
+
// }
|
|
1103
|
+
//
|
|
1104
|
+
//
|
|
1105
|
+
// double Tolerance() const { return 1e-7 * Dist(boxpmax, boxpmin); } // single precision
|
|
1106
|
+
// const auto & Tree() const { return *tree; };
|
|
1107
|
+
// auto & Tree() { return *tree; };
|
|
1108
|
+
// };
|
|
1109
|
+
|
|
1110
|
+
template<int dim, typename T=INDEX, typename TSCAL=double>
|
|
1111
|
+
class DelaunayTree
|
|
1112
|
+
{
|
|
1113
|
+
public:
|
|
1114
|
+
// Number of entries per leaf
|
|
1115
|
+
static constexpr int N = 100;
|
|
1116
|
+
|
|
1117
|
+
struct Node;
|
|
1118
|
+
|
|
1119
|
+
struct Leaf
|
|
1120
|
+
{
|
|
1121
|
+
Point<2*dim, TSCAL> p[N];
|
|
1122
|
+
T index[N];
|
|
1123
|
+
int n_elements;
|
|
1124
|
+
int nr;
|
|
1125
|
+
|
|
1126
|
+
Leaf() : n_elements(0)
|
|
1127
|
+
{ }
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
void Add( Array<Leaf*> &leaves, Array<T> &leaf_index, const Point<2*dim> &ap, T aindex )
|
|
1131
|
+
{
|
|
1132
|
+
p[n_elements] = ap;
|
|
1133
|
+
index[n_elements] = aindex;
|
|
1134
|
+
n_elements++;
|
|
1135
|
+
if(leaf_index.Size()<aindex+1)
|
|
1136
|
+
leaf_index.SetSize(aindex+1);
|
|
1137
|
+
leaf_index[aindex] = nr;
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
struct Node
|
|
1142
|
+
{
|
|
1143
|
+
union
|
|
1144
|
+
{
|
|
1145
|
+
Node *children[2];
|
|
1146
|
+
Leaf *leaf;
|
|
1147
|
+
};
|
|
1148
|
+
double sep;
|
|
1149
|
+
int level;
|
|
1150
|
+
|
|
1151
|
+
Node()
|
|
1152
|
+
: children{nullptr,nullptr}
|
|
1153
|
+
{ }
|
|
1154
|
+
|
|
1155
|
+
~Node()
|
|
1156
|
+
{ }
|
|
1157
|
+
|
|
1158
|
+
Leaf *GetLeaf() const
|
|
1159
|
+
{
|
|
1160
|
+
return children[1] ? nullptr : leaf;
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
private:
|
|
1165
|
+
Node root;
|
|
1166
|
+
|
|
1167
|
+
Array<Leaf*> leaves;
|
|
1168
|
+
Array<T> leaf_index;
|
|
1169
|
+
|
|
1170
|
+
Point<dim> global_min, global_max;
|
|
1171
|
+
double tol;
|
|
1172
|
+
size_t n_leaves;
|
|
1173
|
+
size_t n_nodes;
|
|
1174
|
+
BlockAllocator ball_nodes;
|
|
1175
|
+
BlockAllocator ball_leaves;
|
|
1176
|
+
|
|
1177
|
+
public:
|
|
1178
|
+
|
|
1179
|
+
DelaunayTree (const Point<dim> & pmin, const Point<dim> & pmax)
|
|
1180
|
+
: global_min(pmin), global_max(pmax), n_leaves(1), n_nodes(1), ball_nodes(sizeof(Node)), ball_leaves(sizeof(Leaf))
|
|
1181
|
+
{
|
|
1182
|
+
root.leaf = (Leaf*) ball_leaves.Alloc(); new (root.leaf) Leaf();
|
|
1183
|
+
root.leaf->nr = 0;
|
|
1184
|
+
leaves.Append(root.leaf);
|
|
1185
|
+
root.level = 0;
|
|
1186
|
+
tol = 1e-7 * Dist(pmax, pmin);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
DelaunayTree (const Box<dim> & box)
|
|
1190
|
+
: DelaunayTree(box.PMin(), box.PMax())
|
|
1191
|
+
{ }
|
|
1192
|
+
|
|
1193
|
+
double GetTolerance() { return tol; }
|
|
1194
|
+
|
|
1195
|
+
size_t GetNLeaves()
|
|
1196
|
+
{
|
|
1197
|
+
return n_leaves;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
size_t GetNNodes()
|
|
1201
|
+
{
|
|
1202
|
+
return n_nodes;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
template<typename TFunc>
|
|
1206
|
+
void GetFirstIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
|
|
1207
|
+
TFunc func=[](auto pi){return false;}) const
|
|
1208
|
+
{
|
|
1209
|
+
// static Timer timer("DelaunayTree::GetIntersecting"); RegionTimer rt(timer);
|
|
1210
|
+
// static Timer timer1("DelaunayTree::GetIntersecting-LinearSearch");
|
|
1211
|
+
ArrayMem<const Node*, 100> stack;
|
|
1212
|
+
ArrayMem<int, 100> dir_stack;
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
Point<2*dim> tpmin, tpmax;
|
|
1216
|
+
|
|
1217
|
+
for (size_t i : IntRange(dim))
|
|
1218
|
+
{
|
|
1219
|
+
tpmin(i) = global_min(i);
|
|
1220
|
+
tpmax(i) = pmax(i)+tol;
|
|
1221
|
+
|
|
1222
|
+
tpmin(i+dim) = pmin(i)-tol;
|
|
1223
|
+
tpmax(i+dim) = global_max(i);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
stack.SetSize(0);
|
|
1227
|
+
stack.Append(&root);
|
|
1228
|
+
dir_stack.SetSize(0);
|
|
1229
|
+
dir_stack.Append(0);
|
|
1230
|
+
|
|
1231
|
+
while(stack.Size())
|
|
1232
|
+
{
|
|
1233
|
+
const Node *node = stack.Last();
|
|
1234
|
+
stack.DeleteLast();
|
|
1235
|
+
|
|
1236
|
+
int dir = dir_stack.Last();
|
|
1237
|
+
dir_stack.DeleteLast();
|
|
1238
|
+
|
|
1239
|
+
if(Leaf *leaf = node->GetLeaf())
|
|
1240
|
+
{
|
|
1241
|
+
// RegionTimer rt1(timer1);
|
|
1242
|
+
for (auto i : IntRange(leaf->n_elements))
|
|
1243
|
+
{
|
|
1244
|
+
bool intersect = true;
|
|
1245
|
+
const auto p = leaf->p[i];
|
|
1246
|
+
|
|
1247
|
+
for (int d = 0; d < dim; d++)
|
|
1248
|
+
if (p[d] > tpmax[d])
|
|
1249
|
+
intersect = false;
|
|
1250
|
+
for (int d = dim; d < 2*dim; d++)
|
|
1251
|
+
if (p[d] < tpmin[d])
|
|
1252
|
+
intersect = false;
|
|
1253
|
+
if(intersect)
|
|
1254
|
+
if(func(leaf->index[i])) return;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
else
|
|
1258
|
+
{
|
|
1259
|
+
int newdir = dir+1;
|
|
1260
|
+
if(newdir==2*dim) newdir = 0;
|
|
1261
|
+
if (tpmin[dir] <= node->sep)
|
|
1262
|
+
{
|
|
1263
|
+
stack.Append(node->children[0]);
|
|
1264
|
+
dir_stack.Append(newdir);
|
|
1265
|
+
}
|
|
1266
|
+
if (tpmax[dir] >= node->sep)
|
|
1267
|
+
{
|
|
1268
|
+
stack.Append(node->children[1]);
|
|
1269
|
+
dir_stack.Append(newdir);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
void GetIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
|
|
1276
|
+
NgArray<T> & pis) const
|
|
1277
|
+
{
|
|
1278
|
+
pis.SetSize(0);
|
|
1279
|
+
GetFirstIntersecting(pmin, pmax, [&pis](auto pi) { pis.Append(pi); return false;});
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
void Insert (const Box<dim> & box, T pi)
|
|
1283
|
+
{
|
|
1284
|
+
Insert (box.PMin(), box.PMax(), pi);
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
void Insert (const Point<dim> & pmin, const Point<dim> & pmax, T pi)
|
|
1288
|
+
{
|
|
1289
|
+
// static Timer timer("DelaunayTree::Insert"); RegionTimer rt(timer);
|
|
1290
|
+
int dir = 0;
|
|
1291
|
+
Point<2*dim> p;
|
|
1292
|
+
for (auto i : IntRange(dim))
|
|
1293
|
+
{
|
|
1294
|
+
p(i) = pmin[i];
|
|
1295
|
+
p(i+dim) = pmax[i];
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
Node * node = &root;
|
|
1299
|
+
Leaf * leaf = node->GetLeaf();
|
|
1300
|
+
|
|
1301
|
+
// search correct leaf to add point
|
|
1302
|
+
while(!leaf)
|
|
1303
|
+
{
|
|
1304
|
+
node = p[dir] < node->sep ? node->children[0] : node->children[1];
|
|
1305
|
+
dir++;
|
|
1306
|
+
if(dir==2*dim) dir = 0;
|
|
1307
|
+
leaf = node->GetLeaf();
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
// add point to leaf
|
|
1311
|
+
if(leaf->n_elements < N)
|
|
1312
|
+
leaf->Add(leaves, leaf_index, p,pi);
|
|
1313
|
+
else // assume leaf->n_elements == N
|
|
1314
|
+
{
|
|
1315
|
+
// add two new nodes and one new leaf
|
|
1316
|
+
int n_elements = leaf->n_elements;
|
|
1317
|
+
ArrayMem<TSCAL, N> coords(n_elements);
|
|
1318
|
+
ArrayMem<int, N> order(n_elements);
|
|
1319
|
+
|
|
1320
|
+
// separate points in two halves, first sort all coordinates in direction dir
|
|
1321
|
+
for (auto i : IntRange(n_elements))
|
|
1322
|
+
{
|
|
1323
|
+
order[i] = i;
|
|
1324
|
+
coords[i] = leaf->p[i][dir];
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
QuickSortI(coords, order);
|
|
1328
|
+
int isplit = N/2;
|
|
1329
|
+
Leaf *leaf1 = (Leaf*) ball_leaves.Alloc(); new (leaf1) Leaf();
|
|
1330
|
+
Leaf *leaf2 = (Leaf*) ball_leaves.Alloc(); new (leaf2) Leaf();
|
|
1331
|
+
|
|
1332
|
+
leaf1->nr = leaf->nr;
|
|
1333
|
+
leaf2->nr = leaves.Size();
|
|
1334
|
+
leaves.Append(leaf2);
|
|
1335
|
+
leaves[leaf1->nr] = leaf1;
|
|
1336
|
+
|
|
1337
|
+
for (auto i : order.Range(0,isplit))
|
|
1338
|
+
leaf1->Add(leaves, leaf_index, leaf->p[i], leaf->index[i] );
|
|
1339
|
+
for (auto i : order.Range(isplit, N))
|
|
1340
|
+
leaf2->Add(leaves, leaf_index, leaf->p[i], leaf->index[i] );
|
|
1341
|
+
|
|
1342
|
+
Node *node1 = (Node*) ball_nodes.Alloc(); new (node1) Node();
|
|
1343
|
+
node1->leaf = leaf1;
|
|
1344
|
+
node1->level = node->level+1;
|
|
1345
|
+
|
|
1346
|
+
Node *node2 = (Node*) ball_nodes.Alloc(); new (node2) Node();
|
|
1347
|
+
node2->leaf = leaf2;
|
|
1348
|
+
node2->level = node->level+1;
|
|
1349
|
+
|
|
1350
|
+
node->children[0] = node1;
|
|
1351
|
+
node->children[1] = node2;
|
|
1352
|
+
node->sep = 0.5 * (leaf->p[order[isplit-1]][dir] + leaf->p[order[isplit]][dir]);
|
|
1353
|
+
|
|
1354
|
+
// add new point to one of the new leaves
|
|
1355
|
+
if (p[dir] < node->sep)
|
|
1356
|
+
leaf1->Add( leaves, leaf_index, p, pi );
|
|
1357
|
+
else
|
|
1358
|
+
leaf2->Add( leaves, leaf_index, p, pi );
|
|
1359
|
+
|
|
1360
|
+
ball_leaves.Free(leaf);
|
|
1361
|
+
n_leaves++;
|
|
1362
|
+
n_nodes+=2;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
void DeleteElement (T pi)
|
|
1367
|
+
{
|
|
1368
|
+
// static Timer timer("DelaunayTree::DeleteElement"); RegionTimer rt(timer);
|
|
1369
|
+
Leaf *leaf = leaves[leaf_index[pi]];
|
|
1370
|
+
leaf_index[pi] = -1;
|
|
1371
|
+
auto & n_elements = leaf->n_elements;
|
|
1372
|
+
auto & index = leaf->index;
|
|
1373
|
+
auto & p = leaf->p;
|
|
1374
|
+
|
|
1375
|
+
for (auto i : IntRange(n_elements))
|
|
1376
|
+
{
|
|
1377
|
+
if(index[i] == pi)
|
|
1378
|
+
{
|
|
1379
|
+
n_elements--;
|
|
1380
|
+
if(i!=n_elements)
|
|
1381
|
+
{
|
|
1382
|
+
index[i] = index[n_elements];
|
|
1383
|
+
p[i] = p[n_elements];
|
|
1384
|
+
}
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
#endif
|