00001
00002
00003
00004 #include "geom/gl_view.H"
00005 #include "mesh/lpatch.H"
00006 #include "mesh/mi.H"
00007 #include "std/config.H"
00008 #include "control_frame.H"
00009
00010 static bool debug = Config::get_var_bool("DEBUG_CONTROL_FRAME",false,true);
00011
00012 static const double SELECTED_SIMPLEX_ALPHA =
00013 Config::get_var_dbl("SELECTED_SIMPLEX_ALPHA",0.5);
00014
00015 static const GLfloat SELECTED_EDGE_WIDTH = (GLfloat)
00016 Config::get_var_dbl("SELECTED_EDGE_WIDTH",4);
00017
00018
00019 static CCOLOR orange_pencil_l (255.0/255, 204.0/255, 51.0/255);
00020 static CCOLOR orange_pencil_m (255.0/255, 153.0/255, 11.0/255);
00021 static CCOLOR orange_pencil_d (243.0/255, 102.0/255, 0.0/255);
00022
00023 int
00024 ControlFrameTexture::draw(CVIEWptr& v)
00025 {
00026 if (_ctrl)
00027 return _ctrl->draw(v);
00028
00029
00030 assert(_patch && _patch->mesh());
00031 if (_strip)
00032 _strip->reset();
00033 else
00034 _strip = _patch->mesh()->new_edge_strip();
00035
00036 if (!BasicTexture::draw(v)) {
00037 int dl = 0;
00038 if ((dl = _dl.get_dl(v, 1, _patch->stamp())))
00039 glNewList(dl, GL_COMPILE);
00040
00041
00042 int el = max(_patch->rel_edit_level(), 0);
00043
00044
00045 for (int k = 0; k <= el; k++)
00046 draw_level(v, k);
00047
00048
00049 if (_dl.dl(v)) {
00050 _dl.close_dl(v);
00051
00052
00053 BasicTexture::draw(v);
00054 }
00055 }
00056 draw_selected_faces();
00057 draw_selected_edges();
00058 draw_selected_verts();
00059
00060 return _patch->num_faces();
00061 }
00062
00063 void
00064 ControlFrameTexture::draw_level(CVIEWptr& v, int k)
00065 {
00066
00067
00068
00069
00070 if (!build_strip(k)) {
00071 err_adv(debug, "ControlFrameTexture::draw_level: build_strip failed");
00072 return;
00073 }
00074
00075 assert(_strip != NULL);
00076
00077
00078
00079
00080 static double top_w = Config::get_var_dbl("CTRL_FRAME_TOP_THICKNESS", 2.0,true);
00081
00082 double r = Config::get_var_dbl("CONTROL_FRAME_RATIO", 0.6,true);
00083 assert(r > 0 && r < 1);
00084 GLfloat w = GLfloat( top_w * pow(r, k + mesh()->subdiv_level()));
00085
00086
00087
00088 GLfloat a = 1;
00089
00090 GL_VIEW::init_line_smooth(v->line_scale()*w, GL_CURRENT_BIT);
00091 glDisable(GL_LIGHTING);
00092 GL_COL(_color, a*alpha());
00093
00094 err_adv(debug, "ControlFrameTexture::draw_level: level %d, width %f", k, w);
00095
00096 _strip->draw(_cb);
00097
00098
00099 GL_VIEW::end_line_smooth();
00100 }
00101
00102 inline Patch*
00103 get_sub_patch(Patch* p, int k)
00104 {
00105 return (k == 0) ? p : Lpatch::isa(p) ? ((Lpatch*)p)->sub_patch(k) : 0;
00106 }
00107
00108 bool
00109 ControlFrameTexture::build_strip(int k)
00110 {
00111 if (!(_patch && _patch->mesh())) {
00112 err_adv(debug, "ControlFrameTexture::build_strip: no patch/mesh");
00113 return 0;
00114 }
00115
00116 err_adv(debug, "ctrl frame: level %d/%d", k, mesh()->rel_edit_level());
00117
00118 if (k < 0)
00119 return false;
00120
00121
00122
00123
00124
00125 assert(_patch->ctrl_patch() == _patch);
00126 Patch* sub = get_sub_patch(_patch, k);
00127 if (!(sub && sub->rel_subdiv_level() == k)) {
00128 if (debug) {
00129 if (sub)
00130 err_msg( "ControlFrameTexture::draw_level: %s %d != %d",
00131 "got patch level", sub->rel_subdiv_level(), k);
00132 else
00133 err_msg( "ControlFrameTexture::draw_level: can't get sub-patch");
00134 }
00135 return false;
00136 }
00137 Bedge_list edges = sub->edges();
00138
00139
00140 edges.clear_flags();
00141
00142
00143
00144 if (!BMESH::show_secondary_faces())
00145 edges.secondary_edges().set_flags(1);
00146
00147
00148
00149 if (LMESH::isa(_patch->mesh())) {
00150 edges.filter(EdgeChildFilter()).set_flags(1);
00151 }
00152
00153
00154 if (_strip)
00155 _strip->reset();
00156 else
00157 _strip = mesh()->new_edge_strip();
00158
00159
00160
00161 UnreachedSimplexFilter unreached;
00162 StrongEdgeFilter strong;
00163 PatchEdgeFilter mine(sub);
00164 _strip->build(edges, unreached + strong + mine);
00165
00166 return !_strip->empty();
00167 }
00168
00169
00170
00171
00172 inline void
00173 get_cur_sub_faces(Patch* p, Bface* f, Bface_list& ret)
00174 {
00175 if (!(p && f && f->patch()->ctrl_patch() == p) )
00176 return;
00177
00178 if (LMESH::isa(f->mesh())) {
00179 int lev = f->mesh()->rel_cur_level();
00180 if (lev >= 0)
00181 ((Lface*)f)->append_subdiv_faces(f->mesh()->rel_cur_level(), ret);
00182 } else {
00183 ret += f;
00184 }
00185 }
00186
00187 inline void
00188 draw_face(Bface* f)
00189 {
00190 if (!f) return;
00191
00192 glVertex3dv(f->v1()->loc().data());
00193 glVertex3dv(f->v2()->loc().data());
00194 glVertex3dv(f->v3()->loc().data());
00195 }
00196
00197 void
00198 ControlFrameTexture::draw_selected_faces()
00199 {
00200
00201 CBface_list& sel_faces = MeshGlobal::selected_faces();
00202
00203
00204
00205 Bface_list sub_faces;
00206 int i=0;
00207 for (i=0; i<sel_faces.num(); i++) {
00208 get_cur_sub_faces(patch(), sel_faces[i], sub_faces);
00209 }
00210 if (sub_faces.empty())
00211 return;
00212
00213 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
00214 glDisable(GL_CULL_FACE);
00215 glDisable(GL_LIGHTING);
00216 double a = SELECTED_SIMPLEX_ALPHA*alpha();
00217 if (a < 1) {
00218 glEnable(GL_BLEND);
00219 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00220 } else {
00221 glDisable(GL_BLEND);
00222 }
00223 GL_COL(orange_pencil_l, a);
00224 glBegin(GL_TRIANGLES);
00225 for (i=0; i<sub_faces.num(); i++) {
00226 draw_face(sub_faces[i]);
00227 }
00228 glEnd();
00229 glPopAttrib();
00230 }
00231
00232 inline void
00233 get_cur_sub_edges(Patch* p, Bedge* e, Bedge_list& ret)
00234 {
00235 if ( !(p && e && e->patch()->ctrl_patch() == p) )
00236 return;
00237
00238 if (LMESH::isa(e->mesh())) {
00239 int lev = e->mesh()->rel_cur_level();
00240 if (lev >= 0)
00241 ((Ledge*)e)->append_subdiv_edges(e->mesh()->rel_cur_level(), ret);
00242 } else {
00243 ret += e;
00244 }
00245 }
00246
00247 inline void
00248 draw_edge(Bedge* e)
00249 {
00250 if (!e) return;
00251 glVertex3dv(e->v1()->loc().data());
00252 glVertex3dv(e->v2()->loc().data());
00253 }
00254
00255 void
00256 ControlFrameTexture::draw_selected_edges()
00257 {
00258
00259
00260
00261 CBedge_list& sel_edges = MeshGlobal::selected_edges();
00262
00263
00264 Bedge_list sub_edges;
00265
00266 int i=0;
00267 for (i=0; i<sel_edges.num(); i++) {
00268 get_cur_sub_edges(patch(), sel_edges[i], sub_edges);
00269 }
00270
00271 if (sub_edges.empty())
00272 return;
00273
00274 err_adv(false, "ControlFrameTexture::draw_selected_edges: drawing %d edges",
00275 sub_edges.num());
00276
00277 GL_VIEW::init_line_smooth(SELECTED_EDGE_WIDTH, GL_CURRENT_BIT);
00278 glDisable(GL_LIGHTING);
00279 double a = SELECTED_SIMPLEX_ALPHA*alpha();
00280 GL_COL(Color::red_pencil, a);
00281 glBegin(GL_LINES);
00282 for (i=0; i<sub_edges.num(); i++) {
00283 draw_edge(sub_edges[i]);
00284 }
00285 glEnd();
00286 GL_VIEW::end_line_smooth();
00287 }
00288
00289 inline Patch*
00290 get_patch(CBvert* v)
00291 {
00292
00293
00294 if (!v) return 0;
00295 Bface* f = v->get_face();
00296 if (!f) return 0;
00297 return f->patch();
00298 }
00299
00300 inline void
00301 get_cur_sub_vert(Patch* p, Bvert* v, Bvert_list& ret)
00302 {
00303 Patch* q = get_patch(v);
00304 if ( !(p && q && q->ctrl_patch() == p) )
00305 return;
00306
00307 if (LMESH::isa(v->mesh())) {
00308 int lev = v->mesh()->rel_cur_level();
00309 if (lev >= 0) {
00310 Lvert* u = ((Lvert*)v)->subdiv_vert(lev);
00311 if (u)
00312 ret += u;
00313 }
00314 } else {
00315 ret += v;
00316 }
00317 }
00318
00319 void
00320 ControlFrameTexture::draw_selected_verts()
00321 {
00322
00323
00324
00325 CBvert_list& sel_verts = MeshGlobal::selected_verts();
00326
00327
00328 Bvert_list sub_verts;
00329
00330 int i=0;
00331 for (i=0; i<sel_verts.num(); i++) {
00332 get_cur_sub_vert(patch(), sel_verts[i], sub_verts);
00333 }
00334
00335 if (sub_verts.empty())
00336 return;
00337
00338
00339 double a = SELECTED_SIMPLEX_ALPHA*alpha();
00340 GL_VIEW::draw_pts(sub_verts.pts(), Color::tan, a, 8.0);
00341 }
00342
00343