00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "shape.h"
00025 #include "paramset.h"
00026 #include "dynload.h"
00027 #include "texture.h"
00028 #include "error.h"
00029 #include <set>
00030 #include <map>
00031 using std::set;
00032 using std::map;
00033
00034 #define NEXT(i) (((i)+1)%3)
00035 #define PREV(i) (((i)+2)%3)
00036
00037 namespace lux
00038 {
00039
00040
00041 struct SDFace;
00042 struct SDFace;
00043 struct SDVertex {
00044
00045 SDVertex(Point pt = Point(0,0,0), float uu = 0.0f, float vv = 0.0f)
00046 : P(pt), u(uu), v(vv), startFace(NULL), child(NULL),
00047 regular(false), boundary(false) {
00048 }
00049
00050
00051 int valence();
00052 void oneRing(Point *P);
00053 void oneRing(SDVertex **V);
00054
00055 Point P;
00056 float u, v;
00057 SDFace *startFace;
00058 SDVertex *child;
00059 bool regular, boundary, hasUV;
00060 };
00061
00062 struct SDFace {
00063
00064 SDFace() {
00065 int i;
00066 for (i = 0; i < 3; ++i) {
00067 v[i] = NULL;
00068 f[i] = NULL;
00069 }
00070 for (i = 0; i < 4; ++i)
00071 children[i] = NULL;
00072 }
00073
00074 int vnum(SDVertex *vert) const {
00075 for (int i = 0; i < 3; ++i)
00076 if (v[i] == vert) return i;
00077 luxError(LUX_BUG,LUX_SEVERE,"Basic logic error in SDFace::vnum()");
00078 return -1;
00079 }
00080 SDFace *nextFace(SDVertex *vert) {
00081 return f[vnum(vert)];
00082 }
00083 SDFace *prevFace(SDVertex *vert) {
00084 return f[PREV(vnum(vert))];
00085 }
00086 SDVertex *nextVert(SDVertex *vert) {
00087 return v[NEXT(vnum(vert))];
00088 }
00089 SDVertex *prevVert(SDVertex *vert) {
00090 return v[PREV(vnum(vert))];
00091 }
00092 SDVertex *otherVert(SDVertex *v0, SDVertex *v1) {
00093 for (int i = 0; i < 3; ++i)
00094 if (v[i] != v0 && v[i] != v1)
00095 return v[i];
00096 luxError(LUX_BUG,LUX_SEVERE,"Basic logic error in SDVertex::otherVert()");
00097 return NULL;
00098 }
00099 SDVertex *v[3];
00100 SDFace *f[3];
00101 SDFace *children[4];
00102 };
00103
00104 struct SDEdge {
00105
00106 SDEdge(SDVertex *v0 = NULL, SDVertex *v1 = NULL) {
00107 v[0] = min(v0, v1);
00108 v[1] = max(v0, v1);
00109 f[0] = f[1] = NULL;
00110 f0edgeNum = -1;
00111 }
00112
00113 bool operator<(const SDEdge &e2) const {
00114 if (v[0] == e2.v[0]) return v[1] < e2.v[1];
00115 return v[0] < e2.v[0];
00116 }
00117 SDVertex *v[2];
00118 SDFace *f[2];
00119 int f0edgeNum;
00120 };
00121
00122
00123 class LoopSubdiv : public Shape {
00124 public:
00125
00126 LoopSubdiv(const Transform &o2w, bool ro,
00127 int nt, int nv, const int *vi,
00128 const Point *P, const float *uv, int nlevels,
00129 const boost::shared_ptr<Texture<float> > dismap,
00130 float dmscale, float dmoffset,
00131 bool dmnormalsmooth, bool dmsharpboundary);
00132 ~LoopSubdiv();
00133 bool CanIntersect() const;
00134 void Refine(vector<boost::shared_ptr<Shape> > &refined) const;
00135 BBox ObjectBound() const;
00136 BBox WorldBound() const;
00137
00138 static Shape *CreateShape(const Transform &o2w, bool reverseOrientation,
00139 const ParamSet ¶ms, map<string,
00140 boost::shared_ptr<Texture<float> > > *floatTextures);
00141
00142 private:
00143
00144 float beta(int valence) const {
00145 if (valence == 3) return 3.f/16.f;
00146 else return 3.f / (8.f * valence);
00147 }
00148 void weightOneRing(SDVertex *destVert, SDVertex *vert, float beta) const ;
00149 void weightBoundary(SDVertex *destVert, SDVertex *vert, float beta) const;
00150 float gamma(int valence) const {
00151 return 1.f / (valence + 3.f / (8.f * beta(valence)));
00152 }
00153 static void GenerateNormals(const vector<SDVertex *> verts, vector<Normal> &Ns);
00154
00155 void ApplyDisplacementMap(
00156 const vector<SDVertex *> verts,
00157 const Normal *norms,
00158 const float *uvs) const;
00159
00160
00161 int nLevels;
00162 vector<SDVertex *> vertices;
00163 vector<SDFace *> faces;
00164
00165
00166 boost::shared_ptr<Texture<float> > displacementMap;
00167 float displacementMapScale;
00168 float displacementMapOffset;
00169
00170 bool hasUV, displacementMapNormalSmooth, displacementMapSharpBoundary;
00171 };
00172
00173
00174 inline int SDVertex::valence() {
00175 SDFace *f = startFace;
00176 if (!boundary) {
00177
00178 int nf = 1;
00179 while ((f = f->nextFace(this)) != startFace)
00180 ++nf;
00181 return nf;
00182 }
00183 else {
00184
00185 int nf = 1;
00186 while ((f = f->nextFace(this)) != NULL)
00187 ++nf;
00188 f = startFace;
00189 while ((f = f->prevFace(this)) != NULL)
00190 ++nf;
00191 return nf+1;
00192 }
00193 }
00194
00195 }
00196