Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

control_frame.C

Go to the documentation of this file.
00001 /**********************************************************************
00002  * control_frame.C
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 // XXX - temporary, to determine good values:
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    // Create a strip for the given mesh type (BMESH or LMESH):
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      // Draw control curves down to the current "edit level"
00042      int el = max(_patch->rel_edit_level(), 0);
00043 
00044      // Draw each level:
00045      for (int k = 0; k <= el; k++)
00046        draw_level(v, k);
00047 
00048       // end the display list here
00049       if (_dl.dl(v)) {
00050          _dl.close_dl(v);
00051 
00052          // the display list is built; now execute it
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    // Draw the control curves for the Patch at level k,
00067    // which is relative to the control Patch.
00068 
00069    // Get the level-k edge strip:
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    // Set line thickness, color and alpha
00078 
00079    // Default top-level line thickness is 1.0:
00080    static double top_w = Config::get_var_dbl("CTRL_FRAME_TOP_THICKNESS", 2.0,true);
00081    // Get a scale factor s = r^k used to control line width.
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    // 'a' is opacity (alpha) determined by GL_VIEW::init_line_smooth()
00087    // needed to simulate line widths below the minimum supported value:
00088    GLfloat a = 1;
00089    // Init line smoothing, set width, and push attributes:
00090    GL_VIEW::init_line_smooth(v->line_scale()*w, GL_CURRENT_BIT);//, &a);
00091    glDisable(GL_LIGHTING);      // GL_ENABLE_BIT
00092    GL_COL(_color, a*alpha());   // GL_CURRENT_BIT
00093 
00094    err_adv(debug, "ControlFrameTexture::draw_level: level %d, width %f", k, w);
00095 
00096    _strip->draw(_cb);
00097 
00098    // Restore gl state:
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    // Build edge strips from edges of level k Patch
00122 
00123    // Make sure we get the sub-patch at level k
00124    // (relative to our patch, i.e. the control patch):
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    // Clear all edge flags
00140    edges.clear_flags();
00141 
00142    // If secondary edges shouldn't be drawn, set their flags
00143    // so they won't be drawn:
00144    if (!BMESH::show_secondary_faces())
00145       edges.secondary_edges().set_flags(1);
00146 
00147    // But now set flags for children of edges of the parent mesh.
00148    // (We don't draw these since they are drawn at some level < k):
00149    if (LMESH::isa(_patch->mesh())) {
00150       edges.filter(EdgeChildFilter()).set_flags(1);
00151    }
00152 
00153    // Get an edge strip to use
00154    if (_strip)
00155       _strip->reset();
00156    else
00157       _strip = mesh()->new_edge_strip();
00158 
00159    // Construct filter that accepts unreached strong edges of
00160    // the sub-patch
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  * drawing selected elements
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 //   glNormal3dv(f->norm().data());
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    // Start with ALL selected faces, from every mesh:
00201    CBface_list& sel_faces = MeshGlobal::selected_faces();
00202                                                                                 
00203    // Remap to current subdiv level
00204    // keeping only those from our patch:
00205    Bface_list sub_faces;
00206    int i=0; // loop index
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);                             // GL_ENABLE_BIT
00215    glDisable(GL_LIGHTING);                              // GL_ENABLE_BIT
00216    double a = SELECTED_SIMPLEX_ALPHA*alpha();
00217    if (a < 1) {
00218       glEnable(GL_BLEND);                               // GL_COLOR_BUFFER_BIT
00219       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// GL_COLOR_BUFFER_BIT
00220    } else {
00221       glDisable(GL_BLEND);                              // GL_COLOR_BUFFER_BIT
00222    }
00223    GL_COL(orange_pencil_l, a);                          // GL_CURRENT_BIT
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    // See comments in ControlFrameTexture::draw_selected_faces()
00259    // for additional verbiage.
00260 
00261    CBedge_list& sel_edges = MeshGlobal::selected_edges(); 
00262 
00263    // draw the selected edges at the current subdivision level
00264    Bedge_list sub_edges;
00265 
00266    int i=0; // loop index
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);                              // GL_LIGHTING_BIT
00279    double a = SELECTED_SIMPLEX_ALPHA*alpha();
00280    GL_COL(Color::red_pencil, a);                        // GL_CURRENT_BIT
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    // Arbitrarily chose a face containing v and return its patch
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    // See comments in ControlFrameTexture::draw_selected_faces()
00323    // for additional verbiage.
00324 
00325    CBvert_list& sel_verts = MeshGlobal::selected_verts(); 
00326 
00327    // draw the selected verts at the current subdivision level
00328    Bvert_list sub_verts;
00329 
00330    int i=0; // loop index
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    // Draw the verts color tan 8 pixels wide
00339    double a = SELECTED_SIMPLEX_ALPHA*alpha();
00340    GL_VIEW::draw_pts(sub_verts.pts(), Color::tan, a, 8.0);
00341 }
00342 
00343 // end of file control_frame.C

Generated on Mon Sep 18 11:39:29 2006 for jot by  doxygen 1.4.4