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

lpatch.C

Go to the documentation of this file.
00001 #include "lpatch.H"
00002 #include "std/config.H"
00003 
00004 
00005 static bool debug = Config::get_var_bool("DEBUG_LPATCH",false);
00006 TAGlist* Lpatch::_lpatch_tags = NULL;
00007 
00008 Lpatch::~Lpatch() 
00009 {
00010    // Recurse down thru the subdivision hierarchy:
00011    delete_child();
00012 }
00013 
00014 void 
00015 Lpatch::triangulation_changed()
00016 {
00017    Patch::triangulation_changed();
00018 }
00019 
00020 Lpatch* 
00021 Lpatch::sub_patch(int k)
00022 {
00023    // Returns the child patch at the given subdivision level
00024    // relative to this patch. E.g.:
00025    //
00026    //     k | returned Patch
00027    // ---------------------
00028    //    -1 | _parent
00029    //     0 | this
00030    //     1 | _child
00031    //     2 | _child->_child
00032    //      ...
00033    //
00034 
00035    // If there is no parent, returns this Patch for k < 0:
00036    if (k < 0)
00037       return _parent ? _parent->sub_patch(k+1) : this;
00038    if (k == 0)
00039       return this;
00040 
00041    // Ensure child is allocated:
00042    if (!_child)
00043       get_child();
00044 
00045    // if for some reason the child could not be allocated, 
00046    // return this:
00047    return _child ? _child->sub_patch(k-1) : this;
00048 }
00049 
00050 Patch*
00051 Lpatch::get_child()
00052 {
00053    if (!_child) {
00054 
00055       // Have to generate the child patch
00056 
00057       if (!lmesh()) {
00058          err_msg("Lpatch::get_child: error: mesh is NULL");
00059          return 0;
00060       }
00061 
00062       LMESH* child_mesh = lmesh()->subdiv_mesh();
00063       if (!child_mesh) {
00064          err_msg("Lpatch::get_child: error: child mesh is NULL");
00065          return 0;
00066       }
00067 
00068       // The mesh creates the child and adds it to its list of
00069       // patches and also to its drawables list:
00070       _child = (Lpatch*)child_mesh->new_patch();
00071 
00072       _child->set_parent(this);
00073    }
00074    return _child;
00075 }
00076 
00077 bool 
00078 Lpatch::set_parent(Patch* p)
00079 {
00080    // enters into child relationship w/ given patch,
00081    // if it's legal. returns true on success
00082    // (asserts zero on failure!)
00083 
00084    // upcast to Lpatch
00085    if (!isa(p))
00086       return false;
00087    Lpatch* pa = (Lpatch*)p;
00088    assert(
00089       pa->lmesh()->subdiv_mesh() == lmesh() &&
00090       (!_parent || _parent == pa) &&
00091       (!pa->_child || pa->_child == this)
00092       );
00093 
00094    // accept this union
00095    pa->_child = this;
00096    _parent = pa;
00097    return true;
00098 }
00099 
00100 int
00101 Lpatch::draw(CVIEWptr& v)
00102 {
00103    // XXX -
00104    //   this is here more for the comments than the
00105    //   functionaliy!
00106 
00107    // Should only be called on the control patch
00108    assert(is_ctrl_patch());
00109 
00110    // The control patch chooses an appropriate GTexture,
00111    // which at some point in its procedure typically calls
00112    // _patch->draw_tri_strips() (on the control patch).
00113    // Lpatch::draw_tri_strips(), below, ensures that the
00114    // triangle strips of the currently displayed subdivision
00115    // patch are the ones that are drawn.
00116    return Patch::draw(v);
00117 }
00118 
00119 int
00120 Lpatch::draw_tri_strips(StripCB* cb)
00121 {
00122    return cur_patch()->Patch::draw_tri_strips(cb);
00123 }
00124 
00125 int
00126 Lpatch::draw_sil_strips(StripCB* cb)
00127 {
00128    return cur_patch()->Patch::draw_sil_strips(cb);
00129 }
00130 
00131 int 
00132 Lpatch::num_faces() const 
00133 {
00134    // Returns number of faces at current subdiv level:
00135 
00136    return ((Lpatch*)this)->cur_patch()->Patch::num_faces();
00137 }
00138 
00139 double 
00140 Lpatch::tris_per_strip() const 
00141 {
00142    // Diagnostic:
00143    return ((Lpatch*)this)->cur_patch()->Patch::tris_per_strip();
00144 }
00145 
00146 CBface_list& 
00147 Lpatch::cur_faces() const
00148 {
00149    return ((Lpatch*)this)->cur_patch()->Patch::cur_faces();
00150 }
00151 
00152 Bvert_list
00153 Lpatch::cur_verts() const
00154 {
00155    // Return vertices at current subdivision level
00156 
00157    assert(_mesh);
00158 
00159    // Short-cut if patch is whole mesh
00160    if (_mesh->nfaces() == _faces.num() &&
00161        !(_mesh->is_polylines() || _mesh->is_points()))
00162       return lmesh()->cur_mesh()->verts();
00163 
00164    return cur_faces().get_verts();
00165 }
00166 
00167 Bedge_list
00168 Lpatch::cur_edges() const
00169 {
00170    // Return edges at current subdivision level
00171 
00172    assert(_mesh);
00173 
00174    // Short-cut if patch is whole mesh
00175    if (_mesh->nfaces() == _faces.num() && !_mesh->is_polylines())
00176       return lmesh()->cur_mesh()->edges();
00177 
00178    if (debug)
00179       err_msg("Lpatch: level %d, faces %d, edges %d",
00180               subdiv_level(), _faces.num(), cur_faces().get_edges().num());
00181 
00182    return cur_faces().get_edges();
00183 }
00184 
00185 void 
00186 Lpatch::clear_subdiv_strips(int /* level */)
00187 {
00188    // XXX - being phased out... (not called)
00189    //
00190    // the problem is that when subdivision meshes get deleted, we also
00191    // have to delete the sub-strips that reference Lfaces in
00192    // them. this first implementation ignores the given level at which
00193    // subdivision faces were deleted, and just blows away subdiv
00194    // strips at all levels below the top.
00195 
00196    if (!_tri_strips_dirty) {
00197       for (int i=0; i<_tri_strips.num(); i++)
00198          lstrip(i)->delete_substrips();
00199    }
00200 }
00201 
00202 
00203 //******DATA ITEM METHODS**********************************************//
00204 
00205 CTAGlist &
00206 Lpatch::tags() const
00207 {
00208    return Patch::tags();
00209    
00210    if (!_lpatch_tags) 
00211    {
00212       _lpatch_tags = new TAGlist;
00213      *_lpatch_tags += Patch::tags();
00214       *_lpatch_tags += new TAG_meth<Lpatch> ("parent_patch",    
00215                                  &Lpatch::put_parent_patch, &Lpatch::get_parent_patch,  1);
00216    }
00217    return *_lpatch_tags;
00218 }
00219 
00220 
00221 DATA_ITEM*              
00222 Lpatch::dup() const
00223 {
00224    // to be filled in...
00225    
00226    return 0;
00227 }
00228 
00229 void
00230 Lpatch::put_parent_patch(TAGformat &d) const
00231 {
00232 
00233    if (!(Config::get_var_bool("WRITE_SUBDIV_MESHES",false)))
00234       return;
00235    
00236    if (is_ctrl_patch())
00237       return;
00238 
00239    int parent_index;
00240 
00241    int num_patches = lmesh()->parent_mesh()->npatches();
00242 
00243    for (parent_index = 0; parent_index < num_patches; parent_index++)
00244       if (lmesh()->parent_mesh()->patch(parent_index) == parent())
00245          break;
00246 
00247    if(parent_index == num_patches)   
00248    {  
00249       cerr << "Lpatch::put_parent_patch - error: found a noncontrol patch without a parent!\n";
00250       parent_index = -1;
00251    }
00252 
00253    d.id();
00254    *d << parent_index;
00255    d.end_id();
00256 
00257 
00258 }
00259 
00260 void
00261 Lpatch::get_parent_patch(TAGformat &d) 
00262 {
00263 
00264    int parent_index;
00265    *d >> parent_index;
00266    
00267    if (parent_index == -1)
00268       _parent = 0;
00269    else if(set_parent(lmesh()->parent_mesh()->patch(parent_index)) != true)
00270       _parent = 0;
00271    
00272 }
00273 
00274 /* end of file lpatch.C */

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