00001
00002
00003
00004 #ifndef UV_DATA_H_IS_INCLUDED
00005 #define UV_DATA_H_IS_INCLUDED
00006
00007 #include "lface.H"
00008
00009 class UVMapping;
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #define CUVdata const UVdata
00030 class UVdata : public SimplexData {
00031 public:
00032
00033
00034
00035
00036 DEFINE_RTTI_METHODS2("UVdata", SimplexData, CSimplexData*);
00037
00038
00039
00040
00041
00042
00043
00044
00045 static bool has_uv(CBface* f) { return lookup(f) != NULL; }
00046
00047
00048 static bool quad_has_uv(CBface* quad);
00049
00050
00051
00052
00053
00054 static bool get_uv(CBvert* v, UVpt& uv);
00055
00056
00057
00058
00059 static bool get_uv(CBvert* v, CBface* f, UVpt& uv);
00060
00061
00062 static UVpt get_uv(CBvert* v, CBface* f);
00063
00064 static bool get_uvs(CBface* f, UVpt& uv1, mlib::UVpt& uv2, mlib::UVpt& uv3) {
00065 if (!f)
00066 return false;
00067 return get_uv(f->v1(), f, uv1) &&
00068 get_uv(f->v2(), f, uv2) && get_uv(f->v3(), f, uv3);
00069 }
00070
00071 static bool get_uvs(CBvert* v1, CBvert* v2, CBvert* v3,
00072 UVpt& uv1, mlib::UVpt& uv2, mlib::UVpt& uv3) {
00073 Bface* f = lookup_face(v1,v2,v3);
00074 if (!f)
00075 return false;
00076 return get_uv(v1, f, uv1) && get_uv(v2, f, uv2) && get_uv(v3, f, uv3);
00077 }
00078
00079
00080 static UVpt get_uv(CBvert* v, CBface* f, bool& success) {
00081 UVpt ret;
00082 if (get_uv(v, f, ret)) {
00083 success = 1;
00084 return ret;
00085 }
00086 success = false;
00087 return ret;
00088 }
00089
00090
00091 static bool get_quad_uvs(CBface* quad,
00092 UVpt& uva, mlib::UVpt& uvb, mlib::UVpt& uvc, mlib::UVpt& uvd);
00093
00094
00095 static bool get_quad_uvs(CBvert* a, CBvert* b, CBvert* c, CBvert* d,
00096 UVpt& uva, mlib::UVpt& uvb, mlib::UVpt& uvc, mlib::UVpt& uvd);
00097
00098
00099
00100
00101
00102
00103
00104 static bool quad_interp_texcoord(
00105 CBface* quad, CUVpt& uv, mlib::UVpt& texcoord);
00106
00107
00108
00109
00110
00111 static bool set(Bvert* v, CUVpt& uv);
00112
00113
00114 static bool set(Bvert* v, Bface* f, CUVpt& uv);
00115
00116
00117 static bool set(Bface* f,
00118 Bvert* v1, Bvert* v2, Bvert* v3,
00119 CUVpt& a, mlib::CUVpt& b, mlib::CUVpt& c) {
00120 return (set(v1,f,a) && set(v2,f,b) && set(v3,f,c));
00121 }
00122
00123
00124
00125 static bool set(Bface* f, CUVpt& a, mlib::CUVpt& b, mlib::CUVpt& c) {
00126 return set(f, f->v1(), f->v2(), f->v3(), a, b, c);
00127 }
00128
00129
00130 static bool set(Bvert* v1, Bvert* v2, Bvert* v3,
00131 CUVpt& uv1, mlib::CUVpt& uv2, mlib::CUVpt& uv3);
00132
00133
00134 static bool set(Bvert* v1, Bvert* v2, Bvert* v3, Bvert* v4,
00135 CUVpt& uv1, mlib::CUVpt& uv2, mlib::CUVpt& uv3, mlib::CUVpt& uv4);
00136
00137
00138
00139
00140
00141 static bool offset_uv(Bvert* v, CUVvec& delt);
00142 static bool offset_uv(Bvert* v, Bface* f, CUVvec& delt);
00143
00144
00145
00146 static void split(CEdgeStrip& stip);
00147
00148
00149
00150
00151 static bool is_continuous(CBedge* e);
00152
00153
00154 static int discontinuity_degree(CBvert* v);
00155
00156
00157 static bool is_continuous(CBvert* v) {
00158 return (discontinuity_degree(v) == 0);
00159 }
00160
00161
00162
00163 static UVdata* lookup(CBsimplex* s) {
00164 return s ? (UVdata*)s->find_data(key()) : 0;
00165 }
00166
00167
00168 static UVdata* get_data(Bsimplex* s) {
00169 UVdata* ret = lookup(s);
00170 return ret ? ret : s ? new UVdata(s) : 0;
00171 }
00172
00173
00174
00175
00176
00177
00178 UVMapping* mapping() const { return _mapping; }
00179 void set_mapping(UVMapping *m) { _mapping = m; }
00180
00181
00182
00183
00184 Bface* face() const { assert(is_face(_simplex)); return (Bface*)_simplex; }
00185
00186
00187
00188 CUVpt& uv(CBvert* v) const;
00189 CUVpt& uv(int i) const { return uv(face()->v(i)); }
00190 CUVpt& uv1() const { return uv(1); }
00191 CUVpt& uv2() const { return uv(2); }
00192 CUVpt& uv3() const { return uv(3); }
00193
00194
00195
00196
00197
00198 void set_do_simple() { _calc_type = SIMPLE_CALC; }
00199 void set_do_loop() { _calc_type = LOOP_CALC; }
00200 void set_do_hybrid() { _calc_type = HYBRID_CALC; }
00201
00202
00203
00204 void bc2uv(CWvec& bc, mlib::UVpt& ret) {
00205 ret = (uv1()*bc[0]) + (uv2()*bc[1]) + (uv3()*bc[2]);
00206 }
00207
00208
00209
00210
00211 void set(uint id, Bsimplex* s) { SimplexData::set(id,s); }
00212 void set(Cstr_ptr& str, Bsimplex* s) { SimplexData::set(str,s); }
00213
00214 virtual void notify_split(Bsimplex*) {
00215
00216
00217 err_msg("UVdata::notify_split: Warning: not implemented");
00218 }
00219
00220
00221 virtual void notify_subdiv_gen();
00222
00223
00224 virtual void notify_simplex_deleted() {
00225
00226
00227 assert(!_mapping);
00228
00229
00230 SimplexData::notify_simplex_deleted();
00231 }
00232
00233
00234 virtual bool handle_subdiv_calc();
00235
00236
00237 protected:
00238
00239
00240 enum calc_type {
00241 SIMPLE_CALC = 0,
00242 LOOP_CALC,
00243 HYBRID_CALC
00244 };
00245
00246 UVpt _uv;
00247 bool _uv_valid;
00248 calc_type _calc_type;
00249 bool _did_subdiv;
00250
00251 UVMapping* _mapping;
00252
00253
00254 static uint key() {
00255 uint ret = (uint)**static_name();
00256 return ret;
00257 }
00258
00259
00260
00261
00262
00263
00264 UVdata(Bsimplex* s);
00265
00266
00267
00268
00269 void set_uv(CUVpt& uv) {
00270 assert(is_vert(simplex()));
00271 _uv = uv;
00272 _uv_valid = true;
00273 }
00274
00275
00276
00277
00278
00279
00280 static void _set(Bvert* v, CUVpt& uv) {
00281 UVdata* uvd = get_data(v);
00282 assert(uvd);
00283 uvd->set_uv(uv);
00284 }
00285
00286
00287
00288
00289 static void split(Bvert* v);
00290
00291
00292 static void split(CBvert_list& verts);
00293
00294
00295 static void split_chain(Bvert_list chain);
00296
00297
00298
00299 UVpt subdiv_uv(CBvert* v, CBface* f) const;
00300 UVpt subdiv_uv(CBedge* e, CBface* f) const;
00301
00302 void set_subdiv_uv(Ledge* e, Lface* f);
00303 void set_subdiv_uv(Lvert* v, Lface* f);
00304 };
00305
00306 #endif // UV_DATA_H_IS_INCLUDED
00307
00308