00001
00002
00003
00004 #ifndef LVERT_H_HAS_BEEN_INCLUDED
00005 #define LVERT_H_HAS_BEEN_INCLUDED
00006
00007 #include "ledge.H"
00008
00009 template <class T> class SubdivCalc;
00010 typedef SubdivCalc<Wpt> LocCalc;
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 class Lvert : public Bvert {
00028 friend class REPARENT_CMD;
00029 friend class Ledge;
00030 public:
00031
00032
00033
00034 enum mask_t {
00035 SMOOTH_VERTEX = 0,
00036 DART_VERTEX,
00037 REGULAR_CREASE_VERTEX,
00038 NON_REGULAR_CREASE_VERTEX,
00039 CORNER_VERTEX,
00040 CUSP_VERTEX
00041 };
00042
00043
00044
00045 enum {
00046 SUBDIV_LOC_VALID_BIT = Bvert::NEXT_AVAILABLE_BIT,
00047 SUBDIV_COLOR_VALID_BIT,
00048 SUBDIV_CORNER_VALID_BIT,
00049 DIRTY_VERT_LIST_BIT,
00050 MASK_VALID_BIT,
00051 DEAD_BIT,
00052 DISPLACED_LOC_VALID,
00053 SUBDIV_ALLOCATED_BIT,
00054 NEXT_AVAILABLE_BIT
00055 };
00056
00057
00058
00059 Lvert(CWpt& p=mlib::Wpt::Origin()) :
00060 Bvert(p),
00061 _subdiv_vertex(0),
00062 _corner(0),
00063 _mask(SMOOTH_VERTEX),
00064 _parent(0),
00065 _offset(0) {}
00066
00067 virtual ~Lvert();
00068
00069
00070
00071 LMESH* lmesh() const { return (LMESH*)mesh(); }
00072 Ledge* le(int k) const { return (Ledge*)_adj[k]; }
00073 Lvert* lv(int k) const { return (Lvert*)nbr(k); }
00074 Lvert* subdiv_vertex() const { return _subdiv_vertex; }
00075
00076 public:
00077
00078
00079
00080 bool is_control() const { return _parent == 0; }
00081
00082
00083
00084 Bsimplex* parent() const { return _parent; }
00085
00086
00087
00088 Bsimplex* ctrl_element() const;
00089
00090
00091 Lvert* ctrl_vert() const {
00092 Bsimplex* sim = ctrl_element();
00093 return is_vert(sim) ? (Lvert*)sim : (Lvert*)0;
00094 }
00095
00096
00097
00098
00099
00100 Lvert* subdiv_vert(int level=1);
00101
00102
00103
00104 Lvert* parent_vert(int rel_level) const;
00105
00106
00107 Lvert* cur_subdiv_vert();
00108
00109 void set_parent(Bsimplex* p) { _parent=p; }
00110
00111
00112
00113 unsigned short subdiv_mask() const {
00114 if (!is_set(MASK_VALID_BIT))
00115 ((Lvert*)this)->set_mask();
00116 return _mask;
00117 }
00118
00119 void set_corner(unsigned short c = USHRT_MAX);
00120 unsigned short corner_value(void) const {return _corner;}
00121 bool is_smooth() const { return subdiv_mask() <= DART_VERTEX; }
00122 bool is_regular_crease() const {
00123 return subdiv_mask() == REGULAR_CREASE_VERTEX;
00124 }
00125
00126
00127
00128 Lvert* update_subdivision();
00129 Lvert* allocate_subdiv_vert();
00130 void set_subdiv_vert(Lvert* subv);
00131 void delete_subdiv_vert();
00132
00133
00134 void subdiv_vert_deleted();
00135
00136 Wpt& limit_loc(mlib::Wpt&) const;
00137 Wvec& loop_normal(mlib::Wvec&) const;
00138
00139
00140 CWpt& displaced_loc(LocCalc*);
00141
00142 bool has_offset() const { return _offset != 0; }
00143 double offset() const { return _offset; }
00144 void add_offset(double d) { set_offset(_offset + d); }
00145 void clear_offset() { set_offset(0); }
00146 void set_offset(double d);
00147
00148
00149
00150
00151 Wpt smooth_loc_from_parent() const;
00152
00153
00154 Wpt detail_loc_from_parent() const;
00155
00156
00157
00158 void fit_subdiv_offset(CWpt& detail_loc);
00159
00160 protected:
00161
00162
00163
00164
00165
00166
00167
00168 void set_subdiv_base_loc(CWpt& base_loc);
00169
00170 public:
00171
00172
00173
00174 void mark_dirty(int bit = SUBDIV_LOC_VALID_BIT);
00175 void subdiv_color_changed() { mark_dirty(SUBDIV_COLOR_VALID_BIT); }
00176 void subdiv_loc_changed() {
00177 clear_bit(DISPLACED_LOC_VALID);
00178 mark_dirty(SUBDIV_LOC_VALID_BIT);
00179 }
00180
00181
00182
00183 virtual void geometry_changed();
00184 virtual void normal_changed();
00185 virtual void crease_changed();
00186 virtual void degree_changed();
00187 virtual void color_changed();
00188 virtual void mask_changed();
00189
00190
00191
00192
00193 protected:
00194 Lvert* _subdiv_vertex;
00195 unsigned short _corner;
00196 unsigned short _mask;
00197 Bsimplex* _parent;
00198 double _offset;
00199 Wpt _displaced_loc;
00200
00201
00202
00203 void set_mask();
00204
00205 private:
00206
00207
00208 void assign_subdiv_vert(Lvert* v) { _subdiv_vertex = v; }
00209 };
00210
00211 #endif // LVERT_H_HAS_BEEN_INCLUDED
00212
00213