00001
00002
00003
00004
00005
00006
00007 #ifndef __UIUC_CHARM_CG3D_H
00008 #define __UIUC_CHARM_CG3D_H
00009
00010 #include "ckvector3d.h"
00011 #include "charm.h"
00012
00013 #define OSL_CG3D_DEBUG 0
00014
00015 namespace cg3d {
00016
00018 extern double epsilon;
00019
00024 class PointSet3d {
00025 int nPts; enum {maxPts=32, firstPt=1000000000};
00026 CkVector3d pts[maxPts];
00027 int saved_nPts;
00028
00029 int nHalf; enum {maxHalfs=12, firstHalf=2000000000};
00030 CkHalfspace3d half[maxHalfs];
00031 int setPts;
00032
00037 typedef unsigned int halfset_t;
00038 halfset_t inHalf[maxHalfs];
00039 halfset_t outHalf[maxHalfs];
00040 void addHalf(const CkVector3d &pt,int p);
00041 public:
00043 PointSet3d();
00044
00046 int addHalfspace(const CkHalfspace3d &h);
00047 inline int getHalfpaces(void) const {return nHalf;}
00048 inline const CkHalfspace3d &getHalfspace(int f) const {
00049 #if OSL_CG3D_DEBUG
00050 if ((f-firstHalf)<0 || (f-firstHalf)>=nHalf)
00051 CkAbort("PointSet3d::halfspace index out of range!");
00052 #endif
00053 return half[f-firstHalf];
00054 }
00055
00057 int addPoint(const CkVector3d &p);
00058 inline int getPoints(void) const {return nPts;}
00059 inline const CkVector3d &getPoint(int p) const {
00060 #if OSL_CG3D_DEBUG
00061 if ((p-firstPt)<0 || (p-firstPt)>=nPts)
00062 CkAbort("PointSet3d::point index out of range!");
00063 #endif
00064 return pts[p-firstPt];
00065 }
00066
00068 inline bool isInside(int p,int h) const
00069 {
00070 if (p<setPts)
00071 return inHalf[h-firstHalf]&(1<<(p-firstPt));
00072 else
00073 return isInside(getPoint(p),h);
00074 }
00075 inline bool isInside(const CkVector3d &p,int h) const
00076 { return getHalfspace(h).side(p)>epsilon; }
00077
00079 inline bool isOutside(int p,int h) const
00080 {
00081 if (p<setPts)
00082 return outHalf[h-firstHalf]&(1<<(p-firstPt));
00083 else
00084 return isOutside(getPoint(p),h);
00085 }
00086 inline bool isOutside(const CkVector3d &p,int h) const
00087 { return getHalfspace(h).side(p)<-epsilon; }
00088
00090 void calculateHalfspaces(void);
00091
00093 inline void pushPoints(void) { saved_nPts=nPts; }
00095 inline void popPoints(void) { nPts=saved_nPts; }
00096 };
00097
00105 class Planar3d {
00106 PointSet3d *ps;
00107 int nPts; enum {maxPts=4+2*6};
00108 int pts[maxPts];
00109 public:
00110 Planar3d(PointSet3d *ps_);
00111
00112 inline int getPoints(void) const {return nPts;}
00113 inline int getPointIndex(int p) const {return pts[p];}
00114 inline const CkVector3d &getPoint(int p) const
00115 {return ps->getPoint(pts[p]);}
00116
00118 inline void addPoint(int ptIdx) {
00119 pts[nPts++]=ptIdx;
00120 }
00121 inline void addPoint(int pt0,int pt1,int pt2) {
00122 pts[nPts+0]=pt0;
00123 pts[nPts+1]=pt1;
00124 pts[nPts+2]=pt2;
00125 nPts+=3;
00126 }
00127 inline void addPoint(int pt0,int pt1,int pt2,int pt3) {
00128 pts[nPts+0]=pt0;
00129 pts[nPts+1]=pt1;
00130 pts[nPts+2]=pt2;
00131 pts[nPts+3]=pt3;
00132 nPts+=4;
00133 }
00134
00137 bool addConstraint(int halfspace);
00138 };
00139
00140
00145 class Shape3d {
00146 protected:
00147 PointSet3d *ps;
00148 private:
00149 int nFaces; int nPoints;
00150 const int *halfspaces;
00151 const int *points;
00152 public:
00153 Shape3d(PointSet3d *ps_,int nFaces_,int nPoints_,
00154 const int *halfspaces_,const int *points_)
00155 :ps(ps_), nFaces(nFaces_), nPoints(nPoints_),
00156 halfspaces(halfspaces_), points(points_) {}
00157 virtual ~Shape3d();
00158
00159 inline PointSet3d *getSet(void) const {return ps;}
00160
00161 inline int getFaces(void) const {return nFaces;}
00162 inline int getPoints(void) const {return nPoints;}
00163
00168 inline int getPointIndex(int p) const {return points[p];}
00169 inline const CkVector3d &getPoint(int p) const
00170 {return ps->getPoint(getPointIndex(p));}
00171
00177 inline int getHalfspaceIndex(int f) const {return halfspaces[f];}
00178 inline const CkHalfspace3d &getHalfspace(int f) const
00179 {return ps->getHalfspace(getHalfspaceIndex(f));}
00180
00185 virtual void getFace(int f, Planar3d &face) const =0;
00186
00187
00190 bool contains(const CkVector3d &pt) const;
00191 };
00192
00195 void testShape(const Shape3d &s);
00196
00197
00201 class Tet3d : public Shape3d {
00202 int p[4];
00203 int h[4];
00204 void operator=(const Tet3d &t);
00205 public:
00206 Tet3d(PointSet3d *ps_,const CkVector3d &A_,const CkVector3d &B_,
00207 const CkVector3d &C_,const CkVector3d &D_);
00209 Tet3d(const Tet3d &t)
00210 :Shape3d(t.ps,4,4,h,p)
00211 {
00212 for (int i=0;i<4;i++) { h[i]=t.h[i]; p[i]=t.p[i]; }
00213 }
00214
00215 virtual void getFace(int f, Planar3d &face) const;
00216 };
00217
00219 class Planar3dDest {
00220 public:
00221 virtual void addFace(const Planar3d &f,int src) =0;
00222 };
00223
00225 class NonManifoldException {
00226 public:
00227 double a;
00228 double b;
00229 NonManifoldException(double a_,double b_) :a(a_), b(b_) {}
00230 };
00231
00233 class Volume3dDest : public Planar3dDest {
00234 bool hasOrigin;
00235 CkVector3d origin;
00236 double volume;
00237 #if OSL_CG3D_DEBUG
00238 Volume3dDest *subVolume;
00239 #endif
00240 public:
00241 Volume3dDest();
00243 Volume3dDest(const CkVector3d &origin_);
00244 #if OSL_CG3D_DEBUG
00245 ~Volume3dDest();
00246 #endif
00247 virtual void addFace(const Planar3d &f,int src);
00248 inline double getVolume(void) const { return volume; }
00249 };
00250
00251
00255 double tetVolume(const CkVector3d &A,const CkVector3d &B,
00256 const CkVector3d &C,const CkVector3d &D);
00257
00262 void intersect(PointSet3d *ps,const Shape3d &shape0, const Shape3d &shape1,
00263 Planar3dDest &faceDest);
00264
00269 double intersectDebug(PointSet3d *ps,const Tet3d &S,const Tet3d &D);
00270
00271 };
00272
00273
00274 #endif