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

lface.C

Go to the documentation of this file.
00001 #include "mesh/lmesh.H"
00002 #include "mesh/patch.H"
00003 
00004 using namespace mlib;
00005 
00006 void 
00007 Lface::color_changed()
00008 {
00009    for (int i = 1; i <= 3; i++) {
00010       lv(i)->subdiv_color_changed();
00011       le(i)->subdiv_color_changed();
00012    }
00013 }
00014 
00015 void
00016 Lface::delete_subdiv_elements()
00017 {
00018    // Make this lightweight, so you can call
00019    // it when you're not sure if you need to:
00020    if (!is_set(SUBDIV_ALLOCATED_BIT))
00021       return;
00022    clear_bit(SUBDIV_ALLOCATED_BIT);
00023 
00024    // After this we need to get treated as a "dirty" face.
00025    // That means the vertices have to be dirty
00026    lv(1)->mark_dirty();
00027    lv(2)->mark_dirty();
00028    lv(3)->mark_dirty();
00029 
00030    LMESH* submesh = lmesh()->subdiv_mesh();
00031    assert(submesh);
00032 
00033    // Removing a face (or edge) also causes it to remove
00034    // *its* subdiv elements.  I.e., this is recursive.
00035 
00036    Lface* subface;
00037    if ((subface = subdiv_face_center()))
00038       submesh->remove_face(subface);
00039    if ((subface = subdiv_face1()))
00040       submesh->remove_face(subface);
00041    if ((subface = subdiv_face2()))
00042       submesh->remove_face(subface);
00043    if ((subface = subdiv_face3()))
00044       submesh->remove_face(subface);
00045 
00046    Ledge* subedge;
00047    if ((subedge = subdiv_edge1()))
00048       submesh->remove_edge(subedge);
00049    if ((subedge = subdiv_edge2()))
00050       submesh->remove_edge(subedge);
00051    if ((subedge = subdiv_edge3()))
00052       submesh->remove_edge(subedge);
00053 }
00054 
00055 inline void
00056 reverse_face(Bface* f)
00057 {
00058    if (f)
00059       f->reverse();
00060 }
00061 
00062 void 
00063 Lface::reverse()
00064 {
00065    if (is_set(SUBDIV_ALLOCATED_BIT)) {
00066       reverse_face(subdiv_face_center());
00067       reverse_face(subdiv_face1());
00068       reverse_face(subdiv_face2());
00069       reverse_face(subdiv_face3());
00070    }
00071    Bface::reverse();
00072 }
00073 
00074 int
00075 Lface::detach()
00076 {
00077    delete_subdiv_elements();
00078    return Bface::detach();
00079 }
00080 
00081 // Helper used in Lface::set_layer() below
00082 inline void
00083 set_layer(ushort l, Lface* f)
00084 {
00085    if (f)
00086       f->set_layer(l);
00087 }
00088 
00089 void 
00090 Lface::set_layer(ushort l)
00091 {
00092    if (_layer == l)
00093       return;
00094 
00095    Bface::set_layer(l);
00096 
00097    // Pass the layer number down to any children that exist:
00098    if (is_set(SUBDIV_ALLOCATED_BIT)) {
00099       ::set_layer(_layer, subdiv_face1());
00100       ::set_layer(_layer, subdiv_face2());
00101       ::set_layer(_layer, subdiv_face3());
00102       ::set_layer(_layer, subdiv_face_center());
00103    }
00104 }
00105 
00106 // Helper used in Lface::make_secondary() below
00107 inline void
00108 push_secondary(Lface* f)
00109 {
00110    if (f)
00111       f->make_secondary();
00112 }
00113 
00114 void 
00115 Lface::make_secondary()
00116 {
00117    // (For non-manifold meshes).
00118    // Label the face as "secondary." I.e.,
00119    // as not being in the primary layer
00120 
00121    if (is_secondary())
00122       return;
00123 
00124    Bface::make_secondary();
00125    
00126    // Pass the label down to any children that exist:
00127    if (is_set(SUBDIV_ALLOCATED_BIT)) {
00128       push_secondary(subdiv_face1());
00129       push_secondary(subdiv_face2());
00130       push_secondary(subdiv_face3());
00131       push_secondary(subdiv_face_center());
00132    }
00133 }
00134 
00135 // Helper used in Lface::make_primary() below
00136 inline void
00137 push_primary(Lface* f)
00138 {
00139    if (f)
00140       f->make_primary();
00141 }
00142 
00143 void 
00144 Lface::make_primary()
00145 {
00146    // (For non-manifold meshes).
00147    // Label the face as "primary." I.e.,
00148    // as not being in the primary layer
00149 
00150    if (is_primary())
00151       return;
00152 
00153    Bface::make_primary();
00154    
00155    // Pass the label down to any children that exist:
00156    if (is_set(SUBDIV_ALLOCATED_BIT)) {
00157       push_primary(subdiv_face1());
00158       push_primary(subdiv_face2());
00159       push_primary(subdiv_face3());
00160       push_primary(subdiv_face_center());
00161    }
00162 }
00163 
00164 Lface* 
00165 Lface::gen_child_face(
00166    Bvert* v1,
00167    Bvert* v2,
00168    Bvert* v3,
00169    Patch* p,
00170    LMESH* m,
00171    bool center_face
00172    )
00173 {
00174    // Lface Internal method.
00175 
00176    if (!(v1 && v2 && v3 && m))
00177       return 0;
00178 
00179    // Create child of this face
00180    Lface* child = (Lface*)m->add_face(v1, v2, v3, p);
00181 
00182    // Record this face as its parent, and propagate any
00183    // attributes that it should inherit
00184    claim_child(child, center_face);
00185 
00186    return child;
00187 }
00188 
00189 void
00190 Lface::claim_child(Lface* child, bool center_face)
00191 {
00192    // Protected helper function used in Lface::gen_child_face()
00193    // and Lface::set_subdiv_elements().
00194    //
00195    // Record this face as parent of given child face, and
00196    // propagate attributes to the child.
00197 
00198    // 'center_face' is true for the center face, whose edges
00199    // consider this face to be their parent.
00200 
00201    // It's protected because we assume child legitimately
00202    // belongs to this face.
00203 
00204    if (!child)
00205       return;
00206 
00207    // Record this face as the child's parent
00208    assert(child->parent() == NULL);
00209    child->set_parent(this);
00210    if (center_face) {
00211      child->le(1)->set_parent(this);
00212       child->le(2)->set_parent(this);
00213       child->le(3)->set_parent(this);
00214    }
00215 
00216    // Propagate attributes to child:
00217    if (is_secondary())
00218       child->make_secondary();
00219    child->set_layer(_layer);
00220 
00221    // Add more attributes here... (when needed).
00222 }
00223 
00224 void 
00225 Lface::allocate_subdiv_elements()
00226 {
00227    // Generate 4 faces and 3 internal edges
00228    // in the subdivision mesh next level down.
00229 
00230    // NOTE: The specific order that sub-faces are created,
00231    // and the order of the vertices used in creating them,
00232    // should not be changed. The barycentric coordinate
00233    // conversion routines (below) depend on these orderings.
00234 
00235    // Make this lightweight, so you can call
00236    // it when you're not sure if you need to:
00237    if (is_set(SUBDIV_ALLOCATED_BIT))
00238       return;
00239    set_bit(SUBDIV_ALLOCATED_BIT);
00240 
00241    assert(lmesh() != NULL);
00242    lmesh()->allocate_subdiv_mesh();
00243    LMESH* submesh = lmesh()->subdiv_mesh();
00244    assert(submesh != NULL);
00245 
00246 
00247    //                       lv3                                       #
00248    //                        /\                                       #
00249    //                       /3 \                                      #
00250    //                      /    \                                     #
00251    //                     /      \                                    #
00252    //                    / child3 \                                   #
00253    //                   /          \                                  #
00254    //                  / 1        2 \                                 #
00255    //            le3  /______________\ le2                            #
00256    //                /\ 2          1 /\                               #
00257    //               /3 \            /3 \                              #
00258    //              /    \  center  /    \                             #
00259    //             /      \  child /      \                            #
00260    //            /        \      /        \                           #
00261    //           /  child1  \    /  child2  \                          #
00262    //          /            \3 /            \                         #
00263    //         / 1          2 \/ 1          2 \                        #
00264    //     lv1 -------------------------------- lv2                    #
00265    //                       le1                                       #
00266 
00267    // Make sure subdiv elements have
00268    // been allocated around face boundary:
00269    lv(1)->allocate_subdiv_vert();
00270    lv(2)->allocate_subdiv_vert();
00271    lv(3)->allocate_subdiv_vert();
00272 
00273    le(1)->allocate_subdiv_elements();
00274    le(2)->allocate_subdiv_elements();
00275    le(3)->allocate_subdiv_elements();
00276 
00277    Patch* child_patch = _patch ? _patch->get_child() : 0;
00278 
00279    // hook up 4 faces (verifying they're not already there):
00280    if (!subdiv_face1())
00281       gen_child_face(
00282          lv(1)->subdiv_vertex(),
00283          le(1)->subdiv_vertex(),
00284          le(3)->subdiv_vertex(),
00285          child_patch, submesh);
00286 
00287    if (!subdiv_face2())
00288       gen_child_face(
00289          le(1)->subdiv_vertex(),
00290          lv(2)->subdiv_vertex(),
00291          le(2)->subdiv_vertex(),
00292          child_patch, submesh);
00293 
00294    if (!subdiv_face3())
00295       gen_child_face(
00296          le(3)->subdiv_vertex(),
00297          le(2)->subdiv_vertex(),
00298          lv(3)->subdiv_vertex(),
00299          child_patch, submesh);
00300 
00301    if (!subdiv_face_center())
00302       gen_child_face(
00303          le(2)->subdiv_vertex(),
00304          le(3)->subdiv_vertex(),
00305          le(1)->subdiv_vertex(),
00306          child_patch, submesh, true);   // true: face is at center
00307 
00308    if (is_quad()) {
00309       //
00310       //       o                                         
00311       //       | .                                       
00312       //       |   .                                     
00313       //       |     .  w                                
00314       //       |       .                                 
00315       //  sub1 o .----- o.                               
00316       //       |   .    |  .                             
00317       //       |     .  |    .                           
00318       //       |       .|      .                         
00319       //       o ------ o ----- o                        
00320       //      v       sub2                               
00321       //                                                 
00322       // A quad face is one that has a "weak" edge
00323       // (shown as the dotted edge labelled 'w' above).
00324       // A weak edge is considered to be the internal
00325       // diagonal edge of a quad, with this face making
00326       // up one half of the quad and the face on the
00327       // other side (not shown) making up the other
00328       // half. In subdivision we label the subdivision
00329       // edges accordingly. I.e. the edge connecting
00330       // subdivision vertices sub1 and sub2 should be
00331       // labelled weak.
00332 
00333       Bedge* w = weak_edge();
00334       Bvert* v = other_vertex(w);
00335       Bvert* sub1 = ((Ledge*)v->lookup_edge(w->v1()))->subdiv_vertex();
00336       Bvert* sub2 = ((Ledge*)v->lookup_edge(w->v2()))->subdiv_vertex();
00337       sub1->lookup_edge(sub2)->set_bit(Bedge::WEAK_BIT);
00338    }
00339 
00340    // Now that child faces are generated, propagate multi
00341    // status (if any) to children
00342    le(1)->push_multi(this);
00343    le(2)->push_multi(this);
00344    le(3)->push_multi(this);
00345 
00346    // Notify observers:
00347    if (_data_list)
00348       _data_list->notify_subdiv_gen();
00349 }
00350 
00351 void 
00352 Lface::set_subdiv_elements()
00353 {
00354    // Claim parental ownership of 4 faces and 3 internal
00355    // edges in the subdivision mesh next level down.
00356 
00357    if (is_set(SUBDIV_ALLOCATED_BIT)) {
00358       err_msg("Lface::set_subdiv_elements: elements already set");
00359       return;
00360    }
00361    set_bit(SUBDIV_ALLOCATED_BIT);
00362 
00363    // hook up the 4 faces 
00364    claim_child(subdiv_face1());
00365    claim_child(subdiv_face2());
00366    claim_child(subdiv_face3());
00367    claim_child(subdiv_face_center(), true);     // true: face is at center
00368 
00369    // Notify observers:
00370    if (_data_list)
00371       _data_list->notify_subdiv_gen();
00372 }
00373 
00374 //
00375 // Helper function used in Lface::set_patch(), below:
00376 //
00377 void
00378 Lface::set_child_patch(Lface* f, Patch*& child)
00379 {
00380    // Do nothing for Mr. No-face:
00381    if (!f)
00382       return;
00383 
00384    if (_patch && (child || (child = _patch->get_child())))
00385       child->add(f);
00386    else
00387       f->set_patch(0);
00388 }
00389 
00390 void
00391 Lface::set_patch(Patch* p)
00392 {
00393    Bface::set_patch(p);
00394 
00395    // In case subfaces already exist, set the patch on each
00396    Patch* child_patch = 0;
00397    set_child_patch(subdiv_face1(),       child_patch);
00398    set_child_patch(subdiv_face2(),       child_patch);
00399    set_child_patch(subdiv_face3(),       child_patch);
00400    set_child_patch(subdiv_face_center(), child_patch);
00401 }
00402 
00403 inline void
00404 get_subdiv_faces(Lface* f, int lev, ARRAY<Bface*>& faces)
00405 {
00406    if (f) 
00407       f->append_subdiv_faces(lev, faces);
00408 }
00409 
00410 void 
00411 Lface::append_subdiv_faces(int lev, ARRAY<Bface*>& faces)
00412 {
00413    if (lev < 0) {
00414       err_msg("Lface::append_subdiv_faces: error: bad level: %d", lev);
00415       return;
00416    } else if (lev == 0) {
00417       faces += this;
00418    } else {
00419       get_subdiv_faces(subdiv_face1(),       lev-1, faces);
00420       get_subdiv_faces(subdiv_face2(),       lev-1, faces);
00421       get_subdiv_faces(subdiv_face3(),       lev-1, faces);
00422       get_subdiv_faces(subdiv_face_center(), lev-1, faces);
00423    }
00424 }
00425 
00426 ////////////////////////////////////////////////////////////
00427 //
00428 //      Barycentric coordinate conversions
00429 //
00430 //        These rely on the following relationship
00431 //        between a given Lface and its 4 child
00432 //        sub-faces:
00433 //                                                                 #
00434 //                        v3                                       #
00435 //                                                                 #
00436 //                        /\                                       #
00437 //                       /3 \                                      #
00438 //                      /    \                                     #
00439 //                     /      \                                    #
00440 //                    / child3 \                                   #
00441 //                   /          \                                  #
00442 //                  / 1        2 \                                 #
00443 //            e3   /______________\ e2                             #
00444 //                /\ 2          1 /\                               #
00445 //               /3 \            /3 \                              #
00446 //              /    \  center  /    \                             #
00447 //             /      \  child /      \                            #
00448 //            /        \      /        \                           #
00449 //           /  child1  \    /  child2  \                          #
00450 //          /            \3 /            \                         #
00451 //         / 1          2 \/ 1          2 \                        #
00452 //      v1 -------------------------------- v2                     #
00453 //                       e1                                        #
00454 //                                                                 #
00455 //   The following matrices convert between barycentric
00456 //   coordinates with respect to a parent triangle and its
00457 //   children.
00458 //
00459 static Wtransf c1_to_p(Wvec(1.0, 0.0, 0.0),     // child 1 to parent
00460                        Wvec(0.5, 0.5, 0.0),
00461                        Wvec(0.5, 0.0, 0.5));
00462 
00463 static Wtransf c2_to_p(Wvec(0.5, 0.5, 0.0),     // child 2 to parent
00464                        Wvec(0.0, 1.0, 0.0),
00465                        Wvec(0.0, 0.5, 0.5));
00466 
00467 static Wtransf c3_to_p(Wvec(0.5, 0.0, 0.5),     // child 3 to parent
00468                        Wvec(0.0, 0.5, 0.5),
00469                        Wvec(0.0, 0.0, 1.0));
00470 
00471 static Wtransf cc_to_p(Wvec(0.0, 0.5, 0.5),     // center child to parent
00472                        Wvec(0.5, 0.0, 0.5),
00473                        Wvec(0.5, 0.5, 0.0));
00474 
00475 static Wtransf p_to_c1 = c1_to_p.inverse();     // parent to child 1
00476 static Wtransf p_to_c2 = c2_to_p.inverse();     // parent to child 2
00477 static Wtransf p_to_c3 = c3_to_p.inverse();     // parent to child 3
00478 static Wtransf p_to_cc = cc_to_p.inverse();     // parent to center child
00479 
00480 Lface*
00481 Lface::child_bc(
00482    CWvec& bc,   // Barycentric coordinates of a point inside this face
00483    Wvec& ret    // Corresponding barycentric coords WRT corresponding sub-face
00484    ) const
00485 {
00486    // For the given barycentric coordinates 'bc' WRT this
00487    // face, convert to barycentric coords WRT the
00488    // corresponding child face (i.e. subdivision face).
00489    //
00490    // Returns the sub-face, and sets 'ret' to the computed
00491    // barycentric coords WRT that face.
00492    //
00493    // Note: it's okay for 'ret' to actually be a reference to
00494    // 'bc'.
00495 
00496    // Reject the input if bc has any negative coordinates.
00497    // Negative coordinates occur when the point is outside the
00498    // triangle, and so does not correspond to any child face.
00499    //
00500    // XXX - we're not checking that the coordinates sum to 1,
00501    // which is a prerequisite for this whole thing to make
00502    // sense.
00503    if ((bc[0] < 0) || (bc[1] < 0) || (bc[2] < 0)) {
00504       err_msg("Lface::child_bc: barycentric coords outside face (%f,%f,%f)",
00505               bc[0], bc[1], bc[2]);
00506       return 0;
00507    }
00508 
00509    if (bc[0] >= 0.5) {
00510       // Child 1
00511       ret = p_to_c1 * bc;
00512       return subdiv_face1();
00513    } else if (bc[1] >= 0.5) {
00514       // Child 2
00515       ret = p_to_c2 * bc;
00516       return subdiv_face2();
00517    } else if (bc[2] >= 0.5) {
00518       // Child 3
00519       ret = p_to_c3 * bc;
00520       return subdiv_face3();
00521    } else {
00522       // Center child
00523       ret = p_to_cc * bc;
00524       return subdiv_face_center();
00525    }
00526 }
00527 
00528 Lface*
00529 Lface::parent_bc(CWvec& bc, Wvec& ret) const
00530 {
00531    // Converts barycentric coordinates WRT this Lface to
00532    // barycentric coords WRT its parent.
00533    //
00534    // See child_bc() above for more discussion.
00535 
00536    if (!_parent) {
00537       err_msg("Lface::parent_bc: Error: no parent");
00538       return 0;
00539    }
00540 
00541    // Get parent simplex of v1:
00542    Bsimplex* v1p = lv(1)->parent();
00543    if (!v1p) {
00544       err_msg("Lface::parent_bc: Error: can't get v1 parent");
00545       return 0;
00546    }
00547 
00548    if (v1p == _parent->v1()) {
00549       // We are child 1
00550       ret = c1_to_p * bc;
00551    } else if (v1p == _parent->e1()) {
00552       // We are child 2
00553       ret = c2_to_p * bc;
00554    } else if (v1p == _parent->e3()) {
00555       // We are child 3
00556       ret = c3_to_p * bc;
00557    } else if (v1p == _parent->e2()) {
00558       // We are the center child 
00559       ret = cc_to_p * bc;
00560    } else {
00561       // We are screwed
00562       err_msg("Lface::parent_bc: Error: can't determine child");
00563       return 0;
00564    }
00565 
00566    return _parent;
00567 }
00568 
00569 Lface*                  // Corresponding Lface at desired mesh level
00570 Lface::bc_to_level(
00571    int level,           // Desired mesh level to convert to
00572    CWvec& bc,           // Given barycentric coords WRT this face
00573    Wvec& ret_bc         // Corresponding barycentric coords WRT returned face
00574    ) const
00575 {
00576    // Find the parent or child Lface at the desired mesh level, return
00577    // that face, and convert the given barycentric coords WRT this
00578    // face to corresponding coords WRT the returned face.
00579    //
00580    // If the desired level isn't available, returns the Lface* and
00581    // barycentric coordinates of the closest level to it we can reach.
00582 
00583    // Get the difference between the desired level and the
00584    // mesh level of this Lface:
00585    int delta_level = level - lmesh()->subdiv_level();
00586 
00587    CLface*     f = this, *p = 0;
00588    Wvec   tmp_bc = bc;
00589 
00590    ret_bc = bc;
00591 
00592    if (delta_level < 0) {
00593       // We have to go coarser
00594       for (int i = -delta_level; i>0; i--) {
00595          p = f->parent_bc(tmp_bc);
00596          if (p) {
00597             ret_bc = tmp_bc;
00598             f = p;
00599          } else
00600             break;
00601       }
00602    } else if (delta_level > 0) {
00603       // We have to go finer
00604       for (int i = delta_level; i>0; i--) {
00605          p = f->child_bc(tmp_bc);
00606          if (p) {
00607             ret_bc = tmp_bc;
00608             f = p;
00609          } else
00610             break;
00611       }
00612    } else {
00613       // They are toying with us...
00614       // We're at the correct level already
00615    }
00616 
00617    // XXX -- if we couldn't reach the requested level, this returns
00618    // the last reachable face at some coarser level
00619    return (Lface*)f;    // corresponding face at desired level
00620 }
00621 
00622 Lface* 
00623 Lface::parent(int rel_level)
00624 {
00625    // Return the parent face at the given subdivision level
00626    // relative to this face.
00627    //   rel_level <= 0: this face
00628    //   rel_level == 1: immediate parent
00629    //   rel_level == 2: parent of parent,
00630    //   etc.
00631    //
00632    // If there is no parent at the requested level,
00633    // return the parent at the highest available level.
00634 
00635    Lface* ret = (Lface*) this;
00636    for ( ; rel_level > 0 && ret->parent() != NULL; rel_level--)
00637       ret = ret->parent();
00638 
00639    return ret;
00640 }
00641 
00642 /* end of file lface.C */
00643 
00644 

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