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