00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #ifndef __VOXEL_H__
00022 #define __VOXEL_H__
00023 
00024 #include "bt_assert.h"
00025 #include "symmetries.h"
00026 #include "gridtype.h"
00027 #include "types.h"
00028 
00029 #include <stdio.h>
00030 #include <string>
00031 
00032 class xmlWriter_c;
00033 class xmlParser_c;
00034 class Polyhedron;
00035 
00051 class voxel_c {
00052 
00053 protected:
00054 
00058   const gridType_c *gt;
00059 
00060   unsigned int sx; 
00061   unsigned int sy; 
00062   unsigned int sz; 
00063 
00069   unsigned int voxels;
00070 
00076   voxel_type * space;
00077 
00085   unsigned int bx1; 
00086   unsigned int bx2; 
00087   unsigned int by1; 
00088   unsigned int by2; 
00089   unsigned int bz1; 
00090   unsigned int bz2; 
00091   bool doRecalc;    
00092 
00098   mutable symmetries_t symmetries;
00099 
00131   int hx; 
00132   int hy; 
00133   int hz; 
00134 
00138   std::string name;
00139 
00144   int weight;
00145 
00159   int * BbHsCache;
00160 
00161 protected:
00162 
00176   void recalcBoundingBox(void);
00177 
00178 public:
00179 
00189   typedef enum {
00190     VX_EMPTY,   
00191     VX_FILLED,  
00192     VX_VARIABLE 
00193   } VoxelState;
00194 
00203   void skipRecalcBoundingBox(bool skipit) {
00204     if (skipit)
00205       doRecalc = false;
00206     else {
00207       doRecalc = true;
00208       recalcBoundingBox();
00209     }
00210   }
00211 
00212 public:
00213 
00218   voxel_c(unsigned int x, unsigned int y, unsigned int z, const gridType_c * gt, voxel_type init = 0);
00219 
00223   voxel_c(xmlParser_c & pars, const gridType_c * gt);
00224 
00229   voxel_c(const voxel_c & orig);
00230 
00235   voxel_c(const voxel_c * orig);
00236 
00241   virtual ~voxel_c();
00242 
00247   void copy(const voxel_c * orig);
00248 
00249   unsigned int getX(void) const { return sx; } 
00250   unsigned int getY(void) const { return sy; } 
00251   unsigned int getZ(void) const { return sz; } 
00252 
00254   const gridType_c * getGridType(void) const { return gt; }
00255 
00259   unsigned int getDiagonal(void) const { return sx*sx + sy*sy + sz*sz; }
00260 
00264   unsigned int getBiggestDimension(void) const {
00265     if (sx > sy)
00266       if (sz > sx)
00267         return sz;
00268       else
00269         return sx;
00270     else
00271       if (sz > sy)
00272         return sz;
00273       else
00274         return sy;
00275   }
00276 
00280   unsigned int getXYZ(void) const { return voxels; }
00281 
00285   int getIndex(unsigned int x, unsigned int y, unsigned int z) const {
00286     bt_assert((x<sx)&&(y<sy)&&(z<sz));
00287     return x + sx * (y + sy * z);
00288   }
00289 
00294   bool indexToXYZ(unsigned int index, unsigned int *x, unsigned int *y, unsigned int *z) const;
00295 
00299   voxel_type get(unsigned int x, unsigned int y, unsigned int z) const {
00300     return space[getIndex(x, y, z)];
00301   }
00302 
00307   voxel_type get2(int x, int y, int z) const {
00308     if ((x>=0)&&(y>=0)&&(z>=0)&&((long)x<(long)sx)&&((long)y<(long)sy)&&((long)z<(long)sz))
00309       return space[getIndex(x, y, z)];
00310     else
00311       return VX_EMPTY;
00312   }
00313 
00322   voxel_type get(unsigned int p) const {
00323     bt_assert(p<voxels);
00324     return space[p];
00325   }
00326 
00331   bool neighbour(unsigned int p, voxel_type val) const;
00332 
00345   virtual bool getNeighbor(unsigned int idx, unsigned int typ, int x, int y, int z, int * xn, int *yn, int *zn) const = 0;
00346 
00350   void set(unsigned int x, unsigned int y, unsigned int z, voxel_type val) {
00351     space[getIndex(x, y, z)] = val;
00352     recalcBoundingBox();
00353     symmetries = symmetryInvalid();
00354   }
00355 
00359   void set(unsigned int p, voxel_type val) {
00360     bt_assert(p<voxels);
00361     space[p] = val;
00362     recalcBoundingBox();
00363     symmetries = symmetryInvalid();
00364   }
00365 
00369   void setAll(voxel_type val) {
00370     memset(space, val, voxels);
00371     recalcBoundingBox();
00372     symmetries = symmetryInvalid();
00373   }
00374 
00379   unsigned int count(voxel_type val) const;
00380 
00385   virtual void transformPoint(int * x, int * y, int * z, unsigned int trans) const = 0;
00386 
00392   void translate(int dx, int dy, int dz, voxel_type filler);
00393 
00402   virtual void minimizePiece(void);
00403 
00404   unsigned int boundX1(void) const { return bx1; } 
00405   unsigned int boundX2(void) const { return bx2; } 
00406   unsigned int boundY1(void) const { return by1; } 
00407   unsigned int boundY2(void) const { return by2; } 
00408   unsigned int boundZ1(void) const { return bz1; } 
00409   unsigned int boundZ2(void) const { return bz2; } 
00410 
00416   bool getBoundingBox(unsigned char trans, int * x1, int * y1, int * z1, int * x2 = 0, int * y2 = 0, int * z2 = 0) const;
00417 
00424   bool operator == (const voxel_c & op) const;
00425 
00440   virtual bool identicalInBB(const voxel_c * op, bool includeColors = true) const;
00441 
00458   bool identicalWithRots(const voxel_c * op, bool includeMirror, bool includeColors) const;
00459 
00468   unsigned char getMirrorTransform(const voxel_c * op) const;
00469 
00476   void resize(unsigned int nsx, unsigned int nsy, unsigned int nsz, voxel_type filler);
00477 
00485   virtual void resizeInclude(int & px, int & py, int & pz) = 0;
00486 
00496   virtual void scale(unsigned int amount, bool grid = false);
00497 
00511   virtual bool scaleDown(unsigned char by, bool action);
00512 
00513   private:
00514 
00524   void unionFind(int * tree, char type, bool inverse, voxel_type value, bool outsideZ) const;
00525 
00526   public:
00527 
00545   bool connected(char type, bool inverse, voxel_type value, bool outsideZ = true) const;
00546 
00550   void fillHoles(char type);
00551 
00561   virtual bool transform(unsigned int nr) = 0;
00562 
00570   symmetries_t selfSymmetries(void) const;
00571 
00576   unsigned char normalizeTransformation(unsigned char trans) const {
00577     return gt->getSymmetries()->minimizeTransformation(selfSymmetries(), trans);
00578   }
00579 
00580 
00581 public:
00582 
00584 
00587   int getState(unsigned int x, unsigned int y, unsigned int z) const { return get(x, y, z) & 0x3; }
00588   int getState2(int x, int y, int z) const { return get2(x, y, z) & 0x3; }
00589   int getState(unsigned int i) const { return get(i) & 0x3; }
00590   unsigned int getColor(unsigned int x, unsigned int y, unsigned int z) const { return get(x, y, z) >> 2; }
00591   unsigned int getColor2(int x, int y, int z) const { return get2(x, y, z) >> 2; }
00592   unsigned int getColor(unsigned int i) const { return get(i) >> 2; }
00594 
00596 
00599   bool isEmpty(unsigned int x, unsigned int y, unsigned int z) const { return getState(x, y, z) == VX_EMPTY; }
00600   bool isEmpty2(int x, int y, int z) const { return getState2(x, y, z) == VX_EMPTY; }
00601   bool isEmpty(unsigned int i) const { return getState(i) == VX_EMPTY; }
00602   bool isFilled(unsigned int x, unsigned int y, unsigned int z) const { return getState(x, y, z) == VX_FILLED; }
00603   bool isFilled2(int x, int y, int z) const { return getState2(x, y, z) == VX_FILLED; }
00604   bool isFilled(unsigned int i) const { return getState(i) == VX_FILLED; }
00605   bool isVariable(unsigned int x, unsigned int y, unsigned int z) const { return getState(x, y, z) == VX_VARIABLE; }
00606   bool isVariable2(int x, int y, int z) const { return getState2(x, y, z) == VX_VARIABLE; }
00607   bool isVariable(unsigned int i) const { return getState(i) == VX_VARIABLE; }
00609 
00611 
00615   void setState(unsigned int x, unsigned int y, unsigned int z, int state) { set(x, y, z, (get(x, y, z) & ~0x3) | state); }
00616   void setColor(unsigned int x, unsigned int y, unsigned int z, unsigned int color) { bt_assert(color < 64); set(x, y, z, (get(x, y, z) & 0x3) | color << 2); }
00617   void setState(unsigned int i, int state) { set(i, (get(i) & ~0x3) | state); }
00618   void setColor(unsigned int i, unsigned int color) { bt_assert(color < 64); set(i, (get(i) & 0x3) | color << 2); }
00620 
00626   unsigned int countState(int state) const;
00627 
00629 
00632   typedef enum {
00633     ACT_FIXED,    
00634     ACT_VARIABLE, 
00635     ACT_DECOLOR   
00636   } VoxelAction;
00637 
00645   void actionOnSpace(VoxelAction action, bool inside);
00647 
00651   void save(xmlWriter_c & xml) const;
00652 
00653   int getHx(void) const { return hx; } 
00654   int getHy(void) const { return hy; } 
00655   int getHz(void) const { return hz; } 
00656   void setHotspot(int x, int y, int z); 
00657 
00668   virtual void initHotspot(void);
00669 
00673   bool getHotspot(unsigned char trans, int * x, int * y, int * z) const;
00674 
00676   const std::string & getName(void) const { return name; }
00677 
00682   void setName(const std::string & n) { name = n; }
00683 
00684   int getWeight(void) const { return weight; } 
00685   void setWeight(int w) { weight = w; }        
00686 
00694   virtual bool validCoordinate(int x, int y, int z) const = 0;
00695 
00696   
00697 
00698 
00699 
00700 
00701   bool unionintersect(
00702       const voxel_c * va, int xa, int ya, int za,
00703       const voxel_c * vb, int xb, int yb, int zb
00704       );
00705 
00714   virtual bool onGrid(int x, int y, int z) const = 0;
00715 
00724   virtual Polyhedron * getMesh(double bevel, double offset) const;
00725 
00726   
00727 
00728 
00729   virtual bool meshParamsValid(double , double ) const { return true; }
00730 
00737   virtual Polyhedron * getDrawingMesh(void) const;
00738 
00742   virtual Polyhedron * getWireframeMesh(void) const;
00743 
00750   virtual void getConnectionFace(int , int , int , int , double , double , std::vector<float> & ) const {};
00751 
00755   virtual void calculateSize(float * x, float * y, float * z) const { *x = 0; *y = 0; *z = 0; }
00756 
00757 
00758   virtual void recalcSpaceCoordinates(float * , float * , float * ) const {}
00759 
00760 private:
00761 
00762   virtual Polyhedron * getMeshInternal(double bevel, double offset, bool fast) const;
00763 
00764   
00765   void operator=(const voxel_c&);
00766 
00767 };
00768 
00769 
00770 
00771 
00772 #define FF_COLOR_LIGHT    0x01 // this helps with the colorisation
00773 #define FF_VARIABLE_MARK  0x02 // when set, the face is supposed to be with a variable marker
00774 #define FF_VARIABLE_FACE  0x04 // when set, the face itself is the variable marker only one or none of these 2 should be set
00775 #define FF_WIREFRAME      0x08 // when set, the face stays when in wire frame more
00776 #define FF_BEVEL_FACE     0x10 // the face got added because the polyhedron has a bevel
00777 #define FF_OFFSET_FACE    0x20 // the face is added because the polyhedron has an offset
00778 #define FF_PROCESSED_FACE 0x40 // tags faces already processed by the polygon fill routine
00779 #define FF_INSIDE_FACE    0x80 // tags faces already processed by the polygon fill routine
00780 
00781 #endif