00001
00002 #ifndef __octree_hpp__
00003 #define __octree_hpp__
00004
00005 #include <string>
00006 #include <map>
00007
00008 #include "math3d.hpp"
00009 #include "utils.hpp"
00010 #include "threading.hpp"
00011
00012 class OctreeBuilder;
00013
00014
00015 class Octree
00016 {
00017 public:
00018 Octree ();
00019 ~Octree ();
00020
00021 operator bool () { return false; }
00022
00023 bool getValues (const vect3d& pos, prec_t *scalars, vect3d *vectors);
00024
00025 struct cell_t;
00026 struct subcells_t;
00027
00028 struct interp_t
00029 {
00030 vect3d corner;
00031 float *fact;
00032 };
00033
00034 struct subcells_t
00035 {
00036 vect3d middle;
00037 cell_t *sc[8];
00038 };
00039
00040 struct cell_t
00041 {
00042 subcells_t *subcells;
00043 interp_t *interp;
00044 struct cell_t *next;
00045 size_t index;
00046 };
00047
00048 bool save (const char *path);
00049 bool load (const char *path);
00050
00051 friend class OctreeBuilder;
00052
00053 void clear ();
00054
00055 std::string getPovrayScript();
00056
00057 struct level_t
00058 {
00059 vect3d bs;
00060 vect3d hbs;
00061 vect3d rbs;
00062 };
00063
00064 size_t size () const;
00065
00066 private:
00067 vect3d corner, box, hbox, rbox;
00068 size_t xc, yc, zc;
00069 typedef std::vector<level_t> levels_t;
00070 levels_t levels;
00071
00072 size_t nScalars;
00073 size_t nVectors;
00074 size_t nValues;
00075
00076 typedef std::vector<cell_t*> hash_t;
00077 hash_t hash;
00078
00079 allocator<interp_t, 1024> a_interp;
00080 allocator<cell_t, 1024> a_cell;
00081 allocator<subcells_t, 1024> a_subcell;
00082 allocator<float, 4096> a_fact;
00083
00084 typedef std::map<void *, size_t> cmap_t;
00085
00086 void addPovrayScript(std::string& str, cell_t *cell, size_t level);
00087 void save (FPWriter& w, cmap_t& cmap, cell_t *cell);
00088 void get_stats (cell_t *cell, size_t& nCells, size_t& nInterp, size_t& nMirror, size_t& nSubcell,
00089 cmap_t& cmap);
00090 };
00091
00092
00093 class OctreeBuilder
00094 {
00095 public:
00096 OctreeBuilder (const vect3d& c1 = vect3d(-1, -1, -1), const vect3d& c2 = vect3d(1, 1, 1),
00097 size_t nScalars = 1, size_t nVectors = 0, size_t limitMemoryMB = 100, prec_t smallestResolution = 0.0);
00098 virtual ~OctreeBuilder ();
00099
00100 void addLimit (const vect3d& n);
00101
00102 void build (Octree& tree);
00103
00104 virtual void getValues (const vect3d& pos, prec_t *f, prec_t *dfdx, prec_t *dfdy, prec_t *dfdz,
00105 prec_t *d2fdxdy, prec_t *d2fdxdz, prec_t *d2fdydz, prec_t *d3fdxdydz) = 0;
00106 virtual bool inContact (const vect3d& pos) = 0;
00107
00108 private:
00109 vect3d c1, c2;
00110 size_t nScalars;
00111 size_t nVectors;
00112 size_t nValues;
00113 size_t limitMemoryMB;
00114 prec_t smallestResolution;
00115
00116 struct values_str {
00117 values_str() : values(0) { }
00118 ~values_str () { delete [] values; }
00119 vect3d pos;
00120 prec_t *f, *dfdx, *dfdy, *dfdz, *d2fdxdy, *d2fdxdz, *d2fdydz, *d3fdxdydz;
00121 prec_t *values;
00122 };
00123
00124 struct o8entry_t
00125 {
00126 Octree::cell_t *cell;
00127 vect3d c1, c2;
00128 values_str *vals[8];
00129 };
00130
00131 typedef std::vector<vect3d> limits_t;
00132 limits_t limits;
00133
00134 bool isInside(const vect3d& c1, const vect3d& c2);
00135
00136 struct fieldtask : public Task
00137 {
00138 size_t part;
00139 OctreeBuilder *builder;
00140 std::vector<values_str*> *values_map_calc;
00141 void execute () { builder->run_calc_values (*values_map_calc, part); }
00142 };
00143
00144 struct celltask : public Task
00145 {
00146 size_t part;
00147 OctreeBuilder *builder;
00148 std::vector<o8entry_t> *cells;
00149 vect3d box;
00150 void execute () { builder->run_calc_cells (*cells, part, box); }
00151 };
00152
00153 void run_calc_values (std::vector<values_str*>& values_map_calc, size_t part);
00154 void run_calc_cells (std::vector<o8entry_t>& cells, size_t part, vect3d box);
00155 };
00156
00157 #endif // !__octree_hpp__
00158