00001
00002
00003
00004 #include "bmesh.H"
00005 #include "mesh_global.H"
00006 #include "stripcb.H"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 static const uchar CLEARED_FLAG = 0;
00019 static const uchar MARKED_FLAG = 1;
00020 static const uchar CLAIMED_FLAG = 2;
00021
00022 inline bool
00023 is_cleared(Bface* f)
00024 {
00025 return f->flag() == CLEARED_FLAG;
00026 }
00027
00028 inline bool
00029 is_marked(Bface* f)
00030 {
00031 return f->flag() == MARKED_FLAG;
00032 }
00033
00034 inline bool
00035 is_claimed(Bface* f)
00036 {
00037 return f->flag() == CLAIMED_FLAG;
00038 }
00039
00040 inline void
00041 mark_face(Bface* f)
00042 {
00043 f->set_flag(MARKED_FLAG);
00044 }
00045
00046 inline void
00047 claim_face(Bface* f)
00048 {
00049 f->set_flag(CLAIMED_FLAG);
00050 }
00051
00052
00053
00054
00055 Bface*
00056 TriStrip::backup_strip(Bface* f, Bvert*& a)
00057 {
00058
00059
00060
00061
00062
00063
00064 assert(!f->flag());
00065
00066 mark_face(f);
00067
00068 Bface* ret = f;
00069 Bvert* b = f->next_vert_ccw(a);
00070 Bvert* c = f->next_vert_ccw(b);
00071 Bedge* e;
00072
00073 int i = 0;
00074 while((e = f->edge_from_vert((i%2) ? b : a)) &&
00075 e->consistent_orientation() &&
00076 e->is_crossable() &&
00077 (f = e->other_face(f)) &&
00078 is_cleared(f)) {
00079 mark_face(f);
00080 ret = f;
00081 Bvert* d = f->other_vertex(a,b);
00082 c = b;
00083 b = a;
00084 a = d;
00085 i++;
00086 }
00087
00088 _orientation = ((i%2) != 0);
00089
00090 return ret;
00091 }
00092
00093 bool
00094 TriStrip::build(
00095 Bface* start,
00096 Bface_list& stack
00097 )
00098 {
00099
00100 assert(!start->flag());
00101
00102
00103 reset();
00104
00105
00106 if (!start->orient_strip())
00107 start->orient_strip(start->v1());
00108
00109
00110
00111
00112 Bvert *a = start->orient_strip(), *b, *c;
00113
00114
00115 start = backup_strip(start,a);
00116
00117 if (!start) {
00118
00119
00120 err_msg("TriStrip::build: error: backup_strip() failed");
00121 err_msg("*** check mesh for inconsistently oriented faces ***");
00122
00123 return 0;
00124 }
00125
00126
00127 claim_face(start);
00128
00129
00130 start->orient_strip(a);
00131
00132
00133 if (_orientation) {
00134 c = start->next_vert_ccw(a);
00135 b = start->next_vert_ccw(c);
00136 } else {
00137 b = start->next_vert_ccw(a);
00138 c = start->next_vert_ccw(b);
00139 }
00140
00141 add(a,start);
00142 add(b,start);
00143 add(c,start);
00144
00145 Bface* opp;
00146 if ((opp = start->opposite_face(b)) && is_cleared(opp) &&
00147 opp->patch() == start->patch()) {
00148 opp->orient_strip(_orientation ? a : c);
00149 stack += opp;
00150 }
00151
00152 int i=_orientation;
00153 Bface* cur = start;
00154 while ((cur = cur->next_strip_face()) && !is_claimed(cur)) {
00155 claim_face(cur);
00156 i++;
00157 a = b;
00158 b = c;
00159 c = cur->other_vertex(a,b);
00160 cur->orient_strip(a);
00161
00162 if ((opp = cur->opposite_face(b)) && is_cleared(opp) &&
00163 opp->patch() == start->patch()) {
00164 opp->orient_strip(i % 2 ? a : c);
00165 stack += opp;
00166 }
00167
00168 add(c,cur);
00169 }
00170
00171 return 1;
00172 }
00173
00174 void
00175 TriStrip::get_strips(
00176 Bface* start,
00177 ARRAY<TriStrip*>& strips
00178 )
00179 {
00180
00181 if (!is_cleared(start))
00182 return;
00183
00184
00185
00186
00187 static Bface_list stack(1024);
00188 stack.clear();
00189 stack += start;
00190
00191 BMESH* mesh = start->mesh();
00192
00193 while (!stack.empty()) {
00194 start = stack.pop();
00195 if (is_cleared(start)) {
00196 TriStrip* strip = mesh->new_tri_strip();
00197 strip->build(start, stack);
00198 strips += strip;
00199 }
00200 }
00201 }
00202
00203 void
00204 TriStrip::draw(StripCB* cb)
00205 {
00206
00207 if (empty())
00208 return;
00209
00210
00211
00212 if (!BMESH::show_secondary_faces() && _faces.has_any_secondary()) {
00213 err_msg("TriStrip::draw: warning: %d/%d secondary faces",
00214 _faces.num_secondary(), _faces.num());
00215 MeshGlobal::select(_faces.secondary_faces());
00216 }
00217
00218 cb->begin_faces(this);
00219
00220
00221
00222 if (_orientation)
00223 cb->faceCB(_verts[0], _faces[0]);
00224
00225 for (int i=0; i<_verts.num(); i++)
00226 cb->faceCB(_verts[i], _faces[i]);
00227
00228 cb->end_faces(this);
00229 }
00230
00231