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

bmesh.H

Go to the documentation of this file.
00001 
00002 
00003 /**********************************************************************/
00004 /*! \file bmesh.H                                                     */
00005 /**********************************************************************/
00006 #ifndef BMESH_H_HAS_BEEN_INCLUDED
00007 #define BMESH_H_HAS_BEEN_INCLUDED
00008 
00009 #include "disp/view.H"
00010 #include "dlhandler/dlhandler.H"
00011 #include "geom/body.H"
00012 #include "geom/geom.H" // GEOM for _geom member
00013 #include "std/thread_mutex.H"
00014 
00015 #include "mesh/drawable.H"
00016 #include "mesh/tri_strip.H"
00017 #include "mesh/edge_strip.H"
00018 #include "mesh/vert_strip.H"
00019 #include "mesh/zcross_path.H"
00020 #include "mesh/bmesh_curvature.H"
00021 
00022 class Patch;
00023 /*****************************************************************/
00024 /*!
00025  * \brief List of Patches w/ convenience methods (defined in patch.H)
00026  */
00027 /*****************************************************************/
00028 class Patch_list : public BMD_array<Patch> {
00029  public:
00030 
00031    //! \name MANAGERS
00032    //@{
00033 
00034    Patch_list(int n=0)                : BMD_array<Patch>(n)    {}
00035    Patch_list(const Patch_list& list) : BMD_array<Patch>(list) {}
00036 
00037    //@}
00038 
00039    //! \name Convenience methods
00040    //@{
00041 
00042    double min_alpha()                   const;
00043 
00044    void delete_all();
00045 
00046    void creases_changed()               const;
00047    void triangulation_changed()         const;
00048 
00049    void write_stream(ostream& os)       const;
00050 
00051    //@}
00052 };
00053 typedef const Patch_list CPatch_list;
00054 
00055 /**********************************************************************/
00056 /*!BMESH:
00057  *
00058  *      Triangle-based mesh class.
00059  *
00060  *      Primarily consists of a collection of vertices,
00061  *      edges, and faces (Bvert, Bedge, and Bface classes).
00062  *
00063  *      Subdivision surfaces are implemented in the subclass LMESH.
00064  */
00065 /**********************************************************************/
00066 MAKE_PTR_SUBC(BMESH,BODY);
00067 typedef const BMESHptr CBMESHptr;
00068 class BMESH : public BODY {
00069  public:
00070 
00071    //******** ENUMS ********
00072 
00073    /// various types of meshes:
00074    enum mesh_type_t {   
00075       EMPTY_MESH        = 0,
00076       POINTS            = 1,
00077       POLYLINES         = 2,
00078       OPEN_SURFACE      = 4,
00079       CLOSED_SURFACE    = 8
00080    };
00081 
00082    /// various ways a mesh can change:
00083    enum change_t {
00084       TOPOLOGY_CHANGED = 0,
00085       PATCHES_CHANGED,
00086       TRIANGULATION_CHANGED,
00087       VERT_POSITIONS_CHANGED,
00088       VERT_COLORS_CHANGED,
00089       CREASES_CHANGED,
00090       RENDERING_CHANGED,
00091       NO_CHANGE
00092    };
00093 
00094    //******** MANAGERS ********
00095 
00096    BMESH(int num_v=0, int num_e=0, int num_f=0);
00097    BMESH(CBMESH& m);
00098 
00099    virtual ~BMESH();
00100 
00101    //******** RUN-TIME TYPE ID ********
00102 
00103    DEFINE_RTTI_METHODS3("BMESH", BMESH*, BODY, CDATA_ITEM*);
00104 
00105    //******** ASSIGNMENT ********
00106 
00107    virtual BMESH& operator =(CBMESH& m);
00108    virtual BMESH& operator =(BODY& b);
00109 
00110    //******** ACCESSORS / CONVENIENCE ********
00111 
00112    // Vertices, edges and faces of this mesh:
00113      /// Vertices of this mesh
00114    CBvert_list&  verts()                   const { return _verts; }
00115   /// Edges in this mesh
00116    CBedge_list&  edges()                   const { return _edges; }
00117   /// Triangular faces in this mesh
00118    CBface_list&  faces()                   const { return _faces; }
00119 
00120    // Vertices, edges and faces of the current subdiv mesh (if any):
00121   /// Vertices ofthe current subdivision mesh, if any
00122    virtual CBvert_list& cur_verts()        const { return _verts; }
00123   /// Edges ofthe current subdivision mesh, if any
00124    virtual CBedge_list& cur_edges()        const { return _edges; }
00125   /// Faces ofthe current subdivision mesh, if any
00126    virtual CBface_list& cur_faces()        const { return _faces; }
00127 
00128    // turn on/off indexing in vert, edge, and face lists.
00129    // indexing allows O(1) index lookup and removal, but
00130    // adds data to simplex data lists:
00131   void begin_index(); ///< Turn on indexing in vert, edge and face lists
00132   void end_index(); ///< Turn off indexing in vert, edge and face lists
00133 
00134    // size of lists:
00135   /// Number of vertices
00136    int    nverts()      const   { return _verts.num(); }
00137   /// Number of edges
00138    int    nedges()      const   { return _edges.num(); }
00139   /// Number of faces
00140    int    nfaces()      const   { return _faces.num(); }
00141   /// Number of patches
00142    int    npatches()    const   { return _patches.num(); }
00143   /// Is the vertex list empty?
00144    bool   empty()       const   { return _verts.empty(); }
00145 
00146    // shorthand accessors of individual elements:
00147   /// Shorthand for accessing kth vertex
00148    Bvert* bv(int k)     const   { return _verts[k]; }
00149   /// Shorthand for accessing kth edge
00150    Bedge* be(int k)     const   { return _edges[k]; }
00151   /// Shorthand for accessing kth face
00152    Bface* bf(int k)     const   { return _faces[k]; }
00153   /// Shorthand for accessing kth patch
00154    Patch* patch(int k)  const   { return _patches[k]; }
00155 
00156    Bedge* lookup_edge (const Point2i &p);
00157    Bface* lookup_face (const Point3i &p);
00158 
00159   /// List of patches
00160    CPatch_list& patches()                       const { return _patches; }
00161 
00162    // All drawing takes place via the drawables list. 
00163    // E.g. patches are entered into the list.
00164    // XXX - modifiable -- anyone can add to or remove from the list:
00165    BMESHdrawable_array& drawables()   { return _drawables; }
00166 
00167    // GEOM accessor
00168    GEOM* geom() const   { return _geom; } 
00169    virtual void set_geom(GEOM *geom);
00170 
00171   /// Transformation from object to world coordinates for this mesh
00172    CWtransf&  xform()      const;
00173   /// Transformation from world to object coordinates for this mesh
00174    CWtransf&  inv_xform()  const;
00175   
00176    CWtransf& obj_to_ndc() const;
00177 
00178    /// Camera (eye) position in this object's coordinate system
00179    CWpt&     eye_local()  const;
00180 
00181    // optional flag for enabling/disabling drawing
00182    void enable_draw()           { _draw_enabled = true; }
00183    void disable_draw()          { _draw_enabled = false; }
00184    bool draw_enabled()  const   { return _draw_enabled && !empty(); }
00185 
00186    virtual void changed(change_t);
00187    virtual void changed() { changed(TOPOLOGY_CHANGED); }
00188 
00189    //******** RENDERING STYLE ********
00190 
00191    // The rendering style is only set on a mesh when you want to
00192    // override the current rendering style of the view. i.e., almost
00193    // never. Virtual methods over-rode in LMESH to deflect calls to
00194    // the control mesh.
00195    virtual void set_render_style(Cstr_ptr& s);
00196    virtual void push_render_style(Cstr_ptr& s);
00197    virtual void pop_render_style();
00198    virtual Cstr_ptr& render_style() const;
00199 
00200    void toggle_render_style(Cstr_ptr& s) {
00201       if (render_style() == s)  pop_render_style();
00202       else                      push_render_style(s);
00203    }
00204 
00205    /// Does a Patch with a current GTexture named name already exist in this mesh?
00206    int tex_already_exists(Cstr_ptr &name) const;
00207   /// Do the vertices have colors?
00208   bool has_vert_colors() const { return (nverts()>0 && bv(0)->has_color()); }
00209 
00210    //******** STRIPS ********
00211 
00212    int get_sil_strips       (); ///< extracts silhouette edge strips
00213    int build_sil_strips     (); ///< distributes them to patches
00214 
00215    /// extract silhouette edge strip and return a copy of it:
00216    EdgeStrip sil_strip();
00217 
00218    /// finds "strips" for zero-set definition of silhouettes (as in
00219    /// WYSIWYG NPR, Siggraph 2002):
00220    int get_zcross_strips    ();
00221    int build_zcross_strips  ();
00222 
00223    // deals with "strips" for isolated edges and vertices:
00224    int build_polyline_strips();
00225    int build_vert_strips    ();
00226 
00227    // LMESH over-rides this:
00228    virtual void clear_creases();
00229    void    compute_creases();
00230 
00231   /*! Given a filter that accepts a particular kind of edges
00232    * (e.g. crease edges), returns an edge strip consisting of
00233    *chains of edges of the given kind. */
00234    EdgeStrip get_edge_strip(CSimplexFilter& edge_filter) const {
00235       EdgeStrip ret;
00236       ret.build_with_tips(edges(), edge_filter);
00237       return ret;
00238    }
00239   /*! Like get_edge_strip(), but allocates the returned EdgeStrip.
00240    * So for an LMESH this returns an LedgeStrip.
00241    * (The caller is responsible to delete the strip).
00242    */
00243    EdgeStrip* new_edge_strip(CSimplexFilter& edge_filter) {
00244       EdgeStrip* ret = new_edge_strip();
00245       assert(ret);
00246       *ret = get_edge_strip(edge_filter);
00247       return ret;
00248    }
00249 
00250   /*! Specialzed for crease and border strips:
00251    *  these strips are cached, so it's a lightweight
00252    *  operation after the first time
00253    */
00254    EdgeStrip* get_crease_strip() const {
00255       if (!_creases) {
00256          ((BMESH*)this)->_creases = new_edge_strip();
00257          _creases->build_with_tips(edges(),CreaseEdgeFilter());
00258       }
00259       return _creases;
00260    }
00261    EdgeStrip* get_border_strip() const {
00262       if (!_borders) {
00263          ((BMESH*)this)->_borders = new_edge_strip();
00264          _borders->build_with_tips(edges(),BorderEdgeFilter());
00265       }
00266       return _borders;
00267    }
00268 
00269   /*! Given a filter that accepts a particular kind of edges
00270    *(e.g. crease edges), returns an edge list consisting of
00271    * edges of the given kind.
00272    *
00273    * For crease and border edges, see get_creases() and
00274    * get_borders(), below.
00275    */
00276    Bedge_list get_edges(CSimplexFilter& edge_filter) const {
00277       return edges().filter(edge_filter);
00278    }
00279 
00280    // Note: the following use cached edge strips, so they run in
00281    // O(1) time (after the first time). Crease edges can also be
00282    // retrieved via get_edges(CreaseEdgeFilter()), which is O(n)
00283    // every time (where n is the number of edges).
00284    CBedge_list& get_creases() const { return get_crease_strip()->edges(); }
00285    CBedge_list& get_borders() const { return get_border_strip()->edges(); }
00286 
00287    //******** FACTORY METHODS ********
00288      /// Convert the given world-space point to a vertex
00289    virtual Bvert*  new_vert(CWpt& p=mlib::Wpt::Origin()) const {
00290       return new Bvert(p);
00291    }
00292 
00293   /// NB: caller should first check u,v doesn't have an edge already
00294    virtual Bedge*  new_edge(Bvert* u, Bvert* v)   const {
00295       return new Bedge(u,v);
00296    }
00297 
00298   /// NB: caller should first check requested face doesn't exist already
00299    virtual Bface*  new_face(Bvert* u,
00300                             Bvert* v,
00301                             Bvert* w,
00302                             Bedge* e,
00303                             Bedge* f,
00304                             Bedge* g) const {
00305       return new Bface(u,v,w,e,f,g);
00306    }
00307 
00308    virtual TriStrip*    new_tri_strip()   const { return new TriStrip; }
00309    virtual EdgeStrip*   new_edge_strip()  const { return new EdgeStrip;}
00310    virtual VertStrip*   new_vert_strip()  const { return new VertStrip;}
00311    virtual Patch*       new_patch();
00312 
00313    /// Remove the Patch from the patch list; returns 1 on success
00314    bool unlist(Patch* p);
00315 
00316    void                 make_patch_if_needed();
00317 
00318    //******** ADDING MESH ELEMENTS ********
00319 
00320      /// Include the given vertex in this mesh and set the vertex's mesh to this one.
00321    virtual Bvert* add_vertex(Bvert* v);
00322   /// Include the given world-space point as a vertex in this mesh and set the vertex's mesh to this one.
00323   virtual Bvert* add_vertex(CWpt& loc=mlib::Wpt::Origin());
00324   /// Add the given edge to this mesh's edge-list, setting the edge's mesh to this one.
00325   virtual Bedge* add_edge(Bedge* e);
00326   /// Add the edge between the two given vertices to this mesh's list, checking error conditions and setting the edge's mesh to this one.
00327   virtual Bedge* add_edge(Bvert* u, Bvert* v);
00328   /// Add edge between the ith and jth vertices, checking for error conditions, and set the edge's mesh to this one.
00329   virtual Bedge* add_edge(int i, int j);
00330   /// Add the given face to the face-list in this mesh, and set the face's mesh to this one. Set the face to use the given patch (if any).
00331   virtual Bface* add_face(Bface* f, Patch* p=0);
00332   /*! Add the triangular face defined by the given vertices and patch (if any),
00333    * creating the necessary edges and checking for error conditions. */
00334    virtual Bface* add_face(Bvert* u, Bvert* v, Bvert* w, Patch* p=0);
00335   /*! Add the triangular face defined by the ith, jth and kth vertices in this mesh's vertex-list,
00336    * creating the necessary edges and checking for error conditions. */
00337   virtual Bface* add_face(int i, int j, int k, Patch* p=0);
00338 
00339   /// Add the given list of world-space points, as vertices, to this mesh, set their mesh to this one. Return this list as a vertex-list.
00340    Bvert_list add_verts(CWpt_list& pts);
00341 
00342    Bface* add_face(Bvert* u, Bvert* v, Bvert* w,
00343                    CUVpt& a, mlib::CUVpt& b, mlib::CUVpt& c, Patch* p=0);
00344    Bface* add_face(int    i, int    j, int    k,
00345                    CUVpt& a, mlib::CUVpt& b, mlib::CUVpt& c, Patch* p=0);
00346 
00347    /// Creates the quad from the given vertices and patch, if possible, and returns the quad rep, or nil.
00348    Bface* add_quad(Bvert* u, Bvert* v, Bvert* w, Bvert* x, Patch* p=0);
00349    /// Creates the quad if possible, and returns the quad rep, or nil:
00350    Bface* add_quad(Bvert* u, Bvert* v, Bvert* w, Bvert* x,
00351                    CUVpt& a, mlib::CUVpt& b, mlib::CUVpt& c, mlib::CUVpt& d, Patch* p=0);
00352    /// Creates the quad from the ith, jth, kth and lth vertices in this mesh's vertex list, if possible, and returns the quad rep, or nil.
00353    Bface* add_quad(int    i, int    j, int    k, int    l, Patch* p=0);
00354    /// Creates the quad if possible, and returns the quad rep, or nil:
00355    Bface* add_quad(int    i, int    j, int    k, int    l,
00356                    CUVpt& a, mlib::CUVpt& b, mlib::CUVpt& c, mlib::CUVpt& d, Patch* p=0);
00357 
00358    //******** DELETING ELEMENTS ********
00359 
00360      /// Simply releases memory allocated to the vertex by calling delete
00361    virtual void delete_vert(Bvert* v) const   { delete v; }
00362      /// Simply releases memory allocated to the edge by calling delete
00363    virtual void delete_edge(Bedge* e) const   { delete e; }
00364      /// Simply releases memory allocated to the face by calling delete
00365    virtual void delete_face(Bface* f) const   { delete f; }
00366 
00367    virtual void delete_elements();
00368    virtual void delete_patches();
00369 
00370    //******** REMOVING MESH ELEMENTS ********
00371 
00372      /// Removes the given face from this mesh's face-list, and releases memory allocated to it.
00373    virtual int    remove_face(Bface* f);
00374      /// Removes the given edge from this mesh's edge-list, and releases memory allocated to it.
00375    virtual int    remove_edge(Bedge* e);
00376      /// Removes the given vertex from this mesh's vertex-list, and releases memory allocated to it.
00377    virtual int    remove_vertex(Bvert* v);
00378 
00379   /// Remove each face in the list given and release memory allocated to it.
00380    virtual int    remove_faces(CBface_list& faces);
00381   /// Remove each edge in the list given and release memory allocated to it.
00382    virtual int    remove_edges(CBedge_list& edges);
00383   /// Remove each vertex in the list given and release memory allocated to it.
00384    virtual int    remove_verts(CBvert_list& verts);
00385 
00386    //******** PRIMITIVES ********
00387      /// Create a cube with the two given points as the body diagonal, and apply the patch if given (default if not).
00388    virtual void   Cube       (CWpt& =mlib::Wpt(0,0,0),mlib::CWpt& =mlib::Wpt(1,1,1), Patch* p=0);
00389 
00390   /// Create an octahedron with the given points, and apply the patch if given (default if not).
00391    virtual void   Octahedron (CWpt& =mlib::Wpt( 0, -M_SQRT2, 0),
00392                               CWpt& =mlib::Wpt( 1,        0, 1),
00393                               CWpt& =mlib::Wpt( 1,        0,-1),
00394                               CWpt& =mlib::Wpt(-1,        0,-1),
00395                               CWpt& =mlib::Wpt(-1,        0, 1),
00396                               CWpt& =mlib::Wpt( 0,  M_SQRT2, 0), Patch* p=0);
00397 
00398   /// Create a canonical icosahedron and apply the patch if given (default if not)
00399    virtual void   Icosahedron(Patch* p=0);
00400    //sphere with correct spherical texture coordinates
00401    virtual void     Sphere(Patch* p=0);
00402 
00403    //******** MEASURES ********
00404      /// Sum up the volume using the divergence theorem.
00405    virtual double volume() const;
00406   /// Sum of areas of all faces.
00407    virtual double area  () const;
00408 
00409    /// Approximate pixel extent based on bounding box
00410    double pix_size() const { 
00411       if (_pix_size_stamp != VIEW::stamp())
00412          ((BMESH*)this)->compute_pix_size();
00413       return _pix_size;
00414    }
00415    void compute_pix_size();
00416 
00417    //******** MISC UTIL METHODS ********
00418    void           recenter();
00419    double         avg_len () const;
00420    double         z_span  (double& zmin, double& zmax) const;
00421    double         z_span  ()                           const;
00422 
00423    //******** TOPOLOGY ********
00424    int type() const {
00425       if (!_type_valid)
00426          ((BMESH*)this)->check_type();
00427       return _type;
00428    }
00429    bool is_points()             const   { return (type() & POINTS)         != 0; }
00430    bool is_polylines()          const   { return (type() & POLYLINES)      != 0; }
00431    bool is_open_surface()       const   { return (type() & OPEN_SURFACE)   != 0; }
00432    bool is_closed_surface()     const   { return (type() & CLOSED_SURFACE) != 0; }
00433    bool is_surface() const {
00434       return is_open_surface() || is_closed_surface();
00435    }
00436 
00437    bool fix_orientation();
00438 
00439    /// Reverse orientation of all the faces
00440    void reverse() {
00441       for (int k=0; k<nfaces(); k++) 
00442          bf(k)->reverse();
00443    }
00444 
00445    void get_enclosed_verts(CXYpt_list& boundary,
00446                            Bface* startface,
00447                            ARRAY<Bvert*>& ret);
00448 
00449    void remove_duplicate_vertices(bool keep_vert=1);
00450 
00451    /// Returns separate Bface_lists, one for each connected component of the mesh:
00452    ARRAY<Bface_list> get_components() const;
00453 
00454    /// split mesh into connected components:
00455    virtual ARRAY<BMESH*> split_components();
00456 
00457    /// wipe out a connected component containing the start vertex:
00458    virtual void           kill_component  (Bvert* start_vert);
00459 
00460   /*! Merging two meshes:
00461    *    Merge the two meshes together if it's legal to do
00462    *    so. The result is that one mesh ends up an empty husk,
00463    *    with its elements and patches sucked into the other
00464    *    mesh. The smaller mesh is the one that gets sucked
00465    *    dry; the other one is returned.  If the meshes are
00466    *    different types the operation fails and a null pointer
00467    *    is returned. (In that case the meshes are not changed).
00468    */
00469    static BMESHptr merge(BMESHptr m1, BMESHptr m2);
00470 
00471    //******** RETRIANGULATION ********
00472    // edge operations
00473    int     try_swap_edge(Bedge* edge, bool favor_deg_6 = 0);
00474    int     try_collapse_edge(Bedge* e, Bvert* v); // checks legality first
00475    void    merge_vertex(Bvert* v, Bvert* u, bool keep_vert=0); // collapses
00476    Bvert*  split_edge(Bedge* edge, CWpt &new_pt); // there is no try, only do
00477    Bvert*  split_edge(Bedge* edge) {
00478       Wpt mid;
00479       return split_edge(edge, edge->mid_pt(mid));
00480    }
00481 
00482    // face operations:
00483    Bvert*  split_face(Bface* face, CWpt &pt);
00484    int     split_faces(CXYpt_list&, ARRAY<Bvert*>&, Bface* =0); 
00485    void    split_tris(Bface* start_face, Wplane plane, ARRAY<Bvert*>& nv);
00486 
00487    //******** SUBDIVISION/EDIT LEVEL ********
00488 
00489    /// The level of this mesh in the hierarchy (0 == control mesh, next level is 1, etc.):
00490    virtual int subdiv_level() const { return 0; }
00491 
00492    /// Level of "current" mesh in the hierarchy:
00493    virtual int cur_level()    const { return 0; }
00494 
00495    /// Level of "active" mesh in the hierarchy:
00496    virtual int edit_level()   const { return _edit_level; }
00497 
00498    /// Same as above, but relative to the level of this mesh:
00499    int rel_cur_level()  const { return cur_level()  - subdiv_level(); }
00500    int rel_edit_level() const { return edit_level() - subdiv_level(); }
00501 
00502    virtual void inc_edit_level() { _edit_level++; }
00503    virtual void dec_edit_level() { _edit_level = max(_edit_level - 1, 0); }
00504 
00505    //******** PICKING ********
00506 
00507      /*! Brute force intersection:
00508       *   Given ray in world space, return intersected face (if any)
00509       *   and intersection point in world space:
00510       */
00511    Bface* pick_face(CWline& world_ray, mlib::Wpt& world_hit) const;
00512 
00513    //******** DIAGNOSTIC ********
00514 
00515    // Return the approximate memory used for this mesh.
00516    virtual int  size()  const;
00517    virtual void print() const;
00518 
00519    static void toggle_freeze_sils() { _freeze_sils = !_freeze_sils; }
00520    static void toggle_random_sils() { _random_sils = !_random_sils; }
00521 
00522    //******** CENTER OF INTEREST ********
00523      /*! Center of interest:
00524       * Typically the mesh that the user has been lately
00525       * interacting with in some way.
00526       */
00527    static void   set_center_of_interest(BMESH* m) { _center_of_interest = m; }
00528    static BMESH* center_of_interest()             { return _center_of_interest; }
00529    static bool   is_center_of_interest(BMESH* m)  { return _center_of_interest==m;}
00530 
00531    //******** I/O HELPER ********
00532 
00533    int set_crease(int i, int j)         const;
00534    int set_weak_edge(int i, int j)      const;
00535    int set_patch_boundary(int i, int j) const;
00536 
00537    bool valid_vert_indices(int i, int j) const {
00538       return (_verts.valid_index(i) && _verts.valid_index(j));
00539    }
00540    bool valid_vert_indices(int i, int j, int k) const {
00541       return valid_vert_indices(i,j) && _verts.valid_index(k);
00542    }
00543    bool valid_vert_indices(int i, int j, int k, int l) const {
00544       return valid_vert_indices(i,j,k) && _verts.valid_index(l);
00545    }
00546 
00547    //******** I/O - READ ********
00548 
00549    // Read a mesh from a stream and return it.  Handles new
00550    // .jot or .sm formats, as well as old .sm format. If ret
00551    // is null, a new mesh will be generated (BMESH or LMESH,
00552    // depending on what type is specified in the stream). If
00553    // ret is a BMESH and the file specifies LMESH, an LMESH is
00554    // generated, read from the stream, and then the mesh data
00555    // is copied into ret.
00556    static BMESHptr read_jot_stream(istream& is, BMESHptr ret=0);
00557 
00558    // Opens the file and calls BMESH::read_jot_stream(), above.
00559    static BMESHptr read_jot_file(char* filename, BMESHptr ret=0);
00560 
00561    // Read a mesh file into *this* mesh:
00562    bool read_file(char* filename);
00563 
00564    // XXX - the following are all deprecated in favor of the
00565    //       new I/O using tags:
00566    virtual int  read_update_file  (char* filename);
00567    virtual int  read_update_stream(istream& is);
00568 
00569    virtual int  read_stream     (istream& is);  // deprecated: old .sm format
00570    virtual int  read_blocks     (istream& is);
00571    virtual int  read_header     (istream& is);
00572    virtual int  read_vertices   (istream& is);
00573    virtual int  read_faces      (istream& is);
00574    virtual int  read_creases    (istream& is);
00575    virtual int  read_polylines  (istream& is);
00576    virtual int  read_weak_edges (istream& is, str_list &leftover);
00577    virtual int  read_colors     (istream& is, str_list &leftover);
00578    virtual int  read_texcoords2 (istream& is, str_list &leftover);
00579    virtual int  read_patch      (istream& is, str_list &leftover);
00580    virtual int  read_include    (istream& is, str_list &leftover);
00581 
00582    //******** I/O - WRITE ********
00583    virtual int  write_file      (char *filename);
00584    virtual int  write_stream    (ostream& os);
00585    //virtual int  write_header    (ostream& os) const;
00586    virtual int  write_vertices  (ostream& os) const;
00587    virtual int  write_faces     (ostream& os) const;
00588    virtual int  write_creases   (ostream& os) const;
00589    virtual int  write_weak_edges(ostream& os) const;
00590    virtual int  write_polylines (ostream& os) const;
00591    virtual int  write_colors    (ostream& os) const;
00592    virtual int  write_texcoords2(ostream& os) const;
00593    virtual int  write_patches   (ostream& os) const;
00594 
00595    //******** RefImageClient METHODS: ********
00596    virtual ref_img_t use_ref_image();
00597 
00598    virtual int draw_vis_ref();
00599    virtual int draw_ref_img(ref_img_t);
00600    virtual int draw_final(CVIEWptr &v) { return _drawables.draw_final(v); }
00601 
00602    //******** BODY VIRTUAL METHODS ********
00603    virtual BODYptr copy(int make_new=1) const {
00604       if (make_new)
00605          return BODYptr(new BMESH(*this));
00606       else
00607          return BODYptr((BODY*)this);
00608    }
00609    virtual int  intersect(RAYhit&, CWtransf&, mlib::Wpt&, mlib::Wvec&,
00610                                   double& d, double&, XYpt&) const;
00611    virtual int  draw(CVIEWptr&);
00612    // apply xform to each vertex
00613    virtual void transform(CWtransf &xform, CMOD& m = MOD());
00614 
00615    // CSG methods:
00616    virtual BODY* subtract (BODYptr&) { return 0; } // CSG subtract
00617    virtual BODY* combine  (BODYptr&) { return 0; } // CSG union
00618    virtual BODY* intersect(BODYptr&) { return 0; } // CSG intersect
00619 
00620    virtual void         set_vertices(CWpt_list &) { }
00621    virtual CWpt_list&   vertices();
00622    virtual CEDGElist&   body_edges() {return BODY::_edges;}
00623    virtual CBBOX&       get_bb();
00624    virtual void         triangulate(Wpt_list &verts, FACElist &faces);
00625 
00626    //******** DATA_ITEM METHODS ********
00627    virtual CTAGlist &tags           ()             const;
00628 
00629    virtual void   put_vertices      (TAGformat &)  const;
00630    virtual void   put_faces         (TAGformat &)  const;
00631    virtual void   put_uvfaces       (TAGformat &)  const;
00632    virtual void   put_creases       (TAGformat &)  const;
00633    virtual void   put_polylines     (TAGformat &)  const;
00634    virtual void   put_weak_edges    (TAGformat &)  const;
00635    virtual void   put_sec_faces     (TAGformat &)  const; 
00636    virtual void   put_colors        (TAGformat &)  const;
00637    virtual void   put_texcoords2    (TAGformat &)  const;
00638    virtual void   put_render_style  (TAGformat &)  const;
00639    virtual void   put_patches       (TAGformat &)  const;
00640                                              
00641    virtual void   get_vertices      (TAGformat &);
00642    virtual void   get_faces         (TAGformat &);
00643    virtual void   get_uvfaces       (TAGformat &);
00644    virtual void   get_creases       (TAGformat &);
00645    virtual void   get_polylines     (TAGformat &);
00646    virtual void   get_weak_edges    (TAGformat &);
00647    virtual void   get_sec_faces     (TAGformat &); 
00648    virtual void   get_colors        (TAGformat &);
00649    virtual void   get_texcoords2    (TAGformat &);
00650    virtual void   get_render_style  (TAGformat &);
00651    virtual void   get_patches       (TAGformat &);
00652 
00653    virtual DATA_ITEM   *dup()  const { return new BMESH(0,0,0); }
00654    virtual STDdstream  &format(STDdstream &d) const;
00655    virtual STDdstream  &decode(STDdstream &d);
00656    
00657    //******* CURVATURE STUFF ********
00658    
00659    BMESHcurvature_data *curvature() const {
00660       if (!_curv_data)
00661          _curv_data = new BMESHcurvature_data(this);
00662       return _curv_data;
00663    }
00664         
00665    //******** OBSOLETE STUFF ********
00666 
00667    uint   version()     const   { return _version; }
00668 
00669    // XXX - static function in bmesh.C, unused elsewhere
00670    static void grow_oriented_face_lists(Bface*, ARRAY<Bface*>&,
00671                                         ARRAY<Bface*>&);
00672 
00673    // XXX - not used by anyone, brute force approach
00674    Bedge* nearest_edge(CWpt&);
00675    Bvert* nearest_vert(CWpt&);
00676 
00677    // XXX - remove or make set & accessor methods?
00678    static bool _freeze_sils;
00679    static bool _random_sils;
00680 
00681    //*******************************************************
00682    // PROTECTED
00683    //*******************************************************
00684  protected:
00685  
00686    //******** MESH ELEMENTS ********
00687    Bvert_list   _verts;    ///< list of vertices
00688    Bedge_list   _edges;    ///< list of edges
00689    Bface_list   _faces;    ///< list of faces
00690 
00691    //******** PATCHES ********
00692    Patch_list   _patches;  ///< list of patches
00693    uint         _version;  ///< increment to invalidate display lists
00694    ThreadMutex  _patch_mutex;
00695 
00696    //******** STRIPS ********
00697    ZcrossPath   _zx_sils;               ///< zero-cross sil-strip class
00698    EdgeStrip    _sils;                  ///< silhouette edge strips
00699    EdgeStrip*   _creases;               ///< crease edge strips
00700    EdgeStrip*   _borders;               ///< border edge strips
00701 
00702    EdgeStrip*   _polylines;             ///< pointer to allow subclasses
00703    VertStrip*   _lone_verts;            ///< pointer to allow subclasses
00704 
00705    // used for updating silhouette strips just when needed:
00706 
00707    uint        _sil_stamp;
00708    uint        _zx_stamp;
00709 
00710    //******** RENDERING STUFF ********
00711    BMESHdrawable_array  _drawables;     ///< list of drawable things
00712    LIST<str_ptr>        _render_style;  ///< name of render style to use (if any)
00713    bool                 _draw_enabled;  ///< flag to enable/disable drawing
00714    double               _pix_size;      ///< approx pix size
00715    uint                 _pix_size_stamp;///< for caching per-frame
00716 
00717    //******** MESH TYPE ********
00718    int          _type;          ///< type of surface from enum above
00719    bool         _type_valid;    ///< true if _type has been set
00720 
00721    //******** BODY STUFF ********
00722    Wpt_list     _vert_locs;       // XXX - rename
00723    BODYptr      _body;            // XXX - TODO: understand what this is for
00724 
00725    //******** XFORM STUFF ********
00726    GEOM*        _geom;            // XXX - shouldn't need to know about GEOM
00727    
00728    Wtransf      _pm;              ///< object space to NDCZ space transform
00729    // _pm = Projection matrix * Model matrix:
00730    uint         _pm_stamp;        ///< frame number last updated. \todo XXX - fix
00731    Wpt          _eye_local;       ///< camera location in local coordinates
00732    uint         _eye_local_stamp; ///< frame number last updated. \todo XXX - fix
00733 
00734    Wtransf  _obj_to_world;
00735    Wtransf  _world_to_obj;
00736 
00737    //******** CURVATURE STUFF ********
00738    mutable BMESHcurvature_data *_curv_data;
00739 
00740    //******** I/O ********
00741    /// Full set of tags
00742    static TAGlist*      _bmesh_tags;
00743    /// Partial set of tags used for loading frames of animation (e.g. just the vertices change position)
00744    static TAGlist*      _bmesh_update_tags;
00745 
00746    //******** CACHED MEASURES ********
00747    double      _avg_edge_len;
00748    bool        _avg_edge_len_valid;
00749 
00750    //******** EDITING ********
00751    int          _edit_level;
00752 
00753    static BMESH* _center_of_interest;
00754 
00755    //******** SHOW SECONDARY FACES ********
00756    static bool _show_secondary_faces;   // initially false
00757  public:
00758    static bool show_secondary_faces()        { return _show_secondary_faces; }
00759    static void toggle_show_secondary_faces() {
00760       _show_secondary_faces = !_show_secondary_faces;
00761    }
00762 
00763  protected:
00764 
00765    //******** PROTECTED METHODS ********
00766    int check_type();    ///< recalculate the mesh type
00767 
00768    // Clean out any empty patches:
00769    void clean_patches();
00770    bool remove_patch(int k);
00771 
00772    /// internal version of merge(), after error checking:
00773    virtual void _merge(BMESH* mesh);
00774 
00775   /*! In BMESH, just calls BMESHobs::broadcast_update_request(this),
00776    * but in LMESH also updates subdivision meshes: */
00777    virtual void send_update_notification();
00778 
00779    // obsolete?
00780    void grow_mesh_equivalence_class(
00781       Bvert*, 
00782       ARRAY<Bface*>&, ARRAY<Bedge*>&, ARRAY<Bvert*>&
00783       );
00784 };
00785 
00786 /*****************************************************************
00787  * inlines
00788  *****************************************************************/
00789 
00790 inline BMESHptr
00791 gel_to_bmesh(CGELptr &gel) 
00792 {
00793    return BMESH::upcast(gel_to_body(gel));
00794 }
00795 
00796 inline GEL*
00797 bmesh_to_gel(BMESH* mesh)
00798 {
00799    return mesh ? mesh->geom() : 0;
00800 }
00801 
00802 inline GEOM*
00803 bmesh_to_geom(BMESH* mesh)
00804 {
00805    return mesh ? mesh->geom() : 0;
00806 }
00807 
00808 /*! Convenience method for returning the GEOM that owns a
00809  * given BMESH, and upcasting it to a given type, if valid.
00810  */
00811 template <class T>
00812 inline T* mesh_geom(BMESH* mesh, T* init) 
00813 {
00814    GEOM* geom = bmesh_to_geom(mesh);
00815    return T::isa(geom) ? (T*)geom : init; 
00816 }
00817 
00818 inline void
00819 set_edit_level(BMESHptr m, int level)
00820 {
00821    if (m) {
00822       while (level > m->edit_level()) // increase edit level as needed
00823          m->inc_edit_level();
00824       while (level < m->edit_level()) // decrease edit level as needed
00825          m->dec_edit_level();
00826    }
00827 }
00828 
00829 /************************************************************
00830  * BMESHobs_list:
00831  *
00832  *      Convenience class: ARRAY of BMESH observers
00833  *      (class BMESHobs) with methods for forwarding
00834  *      notifications to all observers in the list.
00835  *      See BMESHobs class, below.
00836  ************************************************************/
00837 class BMESHobs;
00838 class BMESHobs_list : public ARRAY<BMESHobs*> {
00839  public:
00840 
00841    //******** MANAGERS ********
00842 
00843    BMESHobs_list(int k=0) : ARRAY<BMESHobs*>(k) { set_unique(); }
00844 
00845    //******** CONVENIENCE METHODS ********
00846 
00847    // Forward notifications to all observers in the list:
00848    void notify_change        (BMESH*, BMESH::change_t)  const;
00849    void notify_xform         (BMESH*, CWtransf&, CMOD&) const;
00850    void notify_merge         (BMESH*, BMESH*)           const;
00851    void notify_split         (BMESH*, CARRAY<BMESH*>&)  const;
00852    void notify_subdiv_gen    (BMESH* parent)            const;
00853    void notify_delete        (BMESH*)                   const;
00854    void notify_sub_delete    (BMESH*)                   const;
00855    void notify_update_request(BMESH*)                   const;
00856 
00857    //******** UTILITIES ********
00858 
00859    void print_names() const;
00860 };
00861 typedef const BMESHobs_list CBMESHobs_list;
00862 
00863 /************************************************************
00864  * BMESHobs:
00865  *
00866  *      A "BMESH observer" object that gets notifications of
00867  *      BMESH events.
00868  ************************************************************/
00869 class BMESHobs {
00870  public:
00871 
00872    virtual ~BMESHobs() {}
00873 
00874    //******** SIGN-UP METHODS ********
00875 
00876    // Used by observers to subscribe or unsubscribe 
00877    // to mesh notifications for a given BMESH:
00878    void subscribe_mesh_notifications(BMESH* m) {
00879       bmesh_obs_list(m).add_uniquely(this);
00880    }
00881    void unsubscribe_mesh_notifications(BMESH* m) {
00882       bmesh_obs_list(m).rem(this);
00883    }
00884 
00885    // Used by observers to subscribe or unsubscribe 
00886    // to mesh notifications for all BMESHes:
00887    void subscribe_all_mesh_notifications() {
00888       _all_observers.add_uniquely(this);
00889    }
00890    void unsubscribe_all_mesh_notifications() {
00891       _all_observers.rem(this);
00892    }
00893 
00894    //******** NOTIFICATION CALLBACKS ********
00895 
00896    // Virtual methods filled in by BMESHobs subclasses, 
00897    // to respond to various BMESH events:
00898    virtual void notify_change    (BMESH*, BMESH::change_t)  {}
00899    virtual void notify_xform     (BMESH*, CWtransf&, CMOD&) {}
00900    virtual void notify_merge     (BMESH*, BMESH*)           {}
00901    virtual void notify_split     (BMESH*, CARRAY<BMESH*>&)  {}
00902    virtual void notify_subdiv_gen(BMESH*)                   {}
00903    virtual void notify_delete    (BMESH*)                   {}
00904    virtual void notify_sub_delete(BMESH*)                   {}
00905 
00906    // This is for observers who want to update the mesh before it
00907    // does something important like try to draw itself:
00908    virtual void notify_update_request(BMESH*)               {}
00909 
00910    //******** STATICS ********
00911 
00912    // These are called by a BMESH to notify observers:
00913    static  void broadcast_change        (BMESH*, BMESH::change_t);
00914    static  void broadcast_xform         (BMESH*, CWtransf& xf, CMOD&);
00915    static  void broadcast_merge         (BMESH* joined, BMESH* removed);
00916    static  void broadcast_split         (BMESH*, CARRAY<BMESH*>&);
00917    static  void broadcast_subdiv_gen    (BMESH*);
00918    static  void broadcast_delete        (BMESH*);
00919    static  void broadcast_sub_delete    (BMESH*);
00920    static  void broadcast_update_request(BMESH*);
00921 
00922    //******** UTILITIES ********
00923 
00924    // For debugging, e.g.:
00925    virtual str_ptr name() const { return "bmesh_obs"; }
00926 
00927    // Returns the observer list for a particular mesh:
00928    static const BMESHobs_list& observers(BMESH* m)  {
00929       return bmesh_obs_list(m);
00930    }
00931 
00932    static void print_names(BMESH* m) { observers(m).print_names(); }
00933 
00934  protected:
00935    // Hash table that maps an observer list to a particular mesh:
00936    static HASH  _hash;
00937 
00938    // List of observers that want to get notified if ANY mesh
00939    // changes:
00940    static BMESHobs_list _all_observers;
00941 
00942    // Returns the observer list for a particular mesh:
00943    static BMESHobs_list& bmesh_obs_list(BMESH* m)  {
00944       BMESHobs_list *list = (BMESHobs_list*) _hash.find((long)m);
00945       if (!list)
00946          _hash.add((long)m, (void*)(list = new BMESHobs_list));
00947       return *list;
00948    }
00949 };
00950 typedef const BMESHobs CBMESHobs;
00951 
00952 
00953 /************************************************************
00954  * BMESHray:
00955  *
00956  *    A RAYhit subclass that stores the Bsimplex that was
00957  *    hit when a BMESH was intersected.
00958  ************************************************************/
00959 #define CBMESHray const BMESHray
00960 class BMESHray : public RAYhit {
00961  public :
00962    //******** MANAGERS ********
00963    BMESHray(CWpt  &p, mlib::CWvec &v):RAYhit(p,v), _simplex(0) { }
00964    BMESHray(CWpt  &a, mlib::CWpt  &b):RAYhit(a,b), _simplex(0) { }
00965    BMESHray(CXYpt &p)          :RAYhit(p),   _simplex(0) { }
00966 
00967    //******** RUN-TIME TYPE ID ********
00968    DEFINE_RTTI_METHODS2("BMESHray", RAYhit, CRAYhit *);
00969    static  int isa (CRAYhit &r)       { return ISA((&r)); }
00970 
00971    //******** ACCESSORS ********
00972    Bsimplex* simplex()          const   { return _simplex; }
00973    void      set_simplex(Bsimplex *s)   { _simplex = s; }
00974 
00975    BMESH* mesh() const { return _simplex ? _simplex->mesh() : (BMESH*)0; }
00976 
00977    //******** CONVENIENT UPCASTS ********
00978    Bvert* vert() const { return bvert(_simplex); }
00979    Bedge* edge() const { return bedge(_simplex); }
00980    Bface* face() const { return bface(_simplex); }
00981 
00982    //******** STATIC METHODS ********
00983    static Bsimplex* simplex(CRAYhit &r) {
00984       return BMESHray::isa(r) ? ((BMESHray &)r).simplex():0;
00985    }
00986    static  void  set_simplex (CRAYhit &r, Bsimplex *f) { 
00987       if (BMESHray::isa(r)) ((BMESHray &)r).set_simplex(f);
00988    }
00989 
00990    static Bvert* vert(CRAYhit& r) { return bvert(simplex(r)); }
00991    static Bedge* edge(CRAYhit& r) { return bedge(simplex(r)); }
00992    static Bface* face(CRAYhit& r) { return bface(simplex(r)); }
00993 
00994    //******** RAYhit METHODS ********
00995    virtual void check(double, int, double, CGELptr &, CWvec &, mlib::CWpt &,
00996                       CWpt &, APPEAR *a, mlib::CXYpt &);
00997 
00998    //*******************************************************
00999    // PROTECTED
01000    //*******************************************************
01001  protected:
01002    Bsimplex*     _simplex; // the mesh simplex that was hit
01003 };
01004 
01005 /*****************************************************************
01006  * BMESH_list:
01007  *
01008  *      A LIST of BMESHes with convenience methods for passing
01009  *      calls to all the items in the list.
01010  *****************************************************************/
01011 class BMESH_list : public RIC_list<BMESHptr> {
01012  public:
01013 
01014    //******** MANAGERS ********
01015 
01016    BMESH_list(int n=0)                     : RIC_list<BMESHptr>(n) {}
01017    BMESH_list(const RIC_list<BMESHptr>& l) : RIC_list<BMESHptr>(l) {}
01018    
01019    //******** CONVENIENCE ********
01020 
01021    // Notify all meshes of a change
01022    void changed(BMESH::change_t c = BMESH::TOPOLOGY_CHANGED) {
01023       for (int i=0; i<_num; i++)
01024          _array[i]->changed(c);
01025    }
01026 
01027    // Returns true if any of the meshes are draw enabled:
01028    bool draw_enabled() const {
01029       bool ret = false;
01030       for (int i=0; i<_num; i++)
01031          ret |= _array[i]->draw_enabled();
01032       return ret;
01033    }
01034 
01035    // Get the aggregate BBOX of all the meshes:
01036    BBOX bbox() const {
01037       BBOX ret;
01038       for (int i=0; i<_num; i++)
01039          if (_array[i]->draw_enabled())
01040             ret += _array[i]->get_bb();
01041       return ret;
01042    }
01043 
01044    // XXX - why is the compiler making me do this??
01045    BMESH_list operator+(const BMESH_list& m) const {
01046       BMESH_list ret(num() + m.num());
01047       ret = *this;
01048       for (int i=0; i<m.num(); i++)
01049          ret += m[i];
01050       return ret;
01051    }
01052 
01053    // minimum alpha (transparency in OpenGL):
01054    double min_alpha() const {
01055       double ret=1;
01056       for (int k=0; k<_num; k++)
01057          ret = min(ret, _array[k]->patches().min_alpha());
01058       return ret;
01059    }
01060 };
01061 typedef const BMESH_list CBMESH_list;
01062 
01063 #endif  // BMESH_H_HAS_BEEN_INCLUDED
01064 
01065 // end of file bmesh.H

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