Logo Search packages:      
Sourcecode: k3d version File versions

mesh.h

#ifndef K3DSDK_MESH_H
#define K3DSDK_MESH_H

// K-3D
// Copyright (c) 1995-2004, Timothy M. Shead
//
// Contact: tshead@k-3d.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include "algebra.h"
#include "bounding_box.h"
#include "result.h"
#include "selectable.h"
#include "utility.h"

#include <boost/any.hpp>
#include <boost/array.hpp>
#include <boost/multi_array.hpp>
#include <boost/tuple/tuple.hpp>

#include <map>
#include <string>
#include <vector>

#include <sdpgl/sdpgl.h>

namespace k3d
{

// Forward declarations
00044 class imaterial;

/////////////////////////////////////////////////////////////////////////////
// parameters_t

/// Encapsulates a set of name-value pairs
typedef std::map<std::string, boost::any> parameters_t;

/////////////////////////////////////////////////////////////////////////////
// point

/// Encapsulates a point in 3D space
00056 class point :
      public selectable
{
public:
      point(const vector3& Position);
      point(const double X, const double Y, const double Z);

      /// Stores the position of the point in 3D space
00064       vector3 position;
      /// Stores vertex data for the point
00066       parameters_t vertex_data;
      /// Stores tag (SDS) data for the point
00068       parameters_t tags;
};

/////////////////////////////////////////////////////////////////////////////
// point_group

/// Encapsulates a group of rendered points
00075 class point_group :
      public selectable
{
public:
      point_group();

      typedef std::vector<point*> points_t;
      points_t points;

      /// Stores a reference to the material to use rendering the point group
00085       imaterial* material;
      /// Stores constant data for the group
00087       parameters_t constant_data;
};

/////////////////////////////////////////////////////////////////////////////
// split_edge

/// Encapsulates a split-edge data structure for representing topology information in a polygon mesh
00094 class split_edge :
      public selectable
{
public:
      split_edge(point* Vertex, split_edge* FaceClockwise = 0, split_edge* Companion = 0) :
            vertex(Vertex),
            face_clockwise(FaceClockwise),
            companion(Companion)
      {
      }

      /// Stores a reference to the edge vertex
00106       point* vertex;
      /// Stores a reference to the next edge in clockwise order around the face
00108       split_edge* face_clockwise;
      /// Stores a reference to the "companion" edge associated with the face on the opposite side of this edge
00110       split_edge* companion;
      /// Stores facevarying data for this edge (specifically, its vertex)
00112       parameters_t facevarying_data;
      /// Stores tag (SDS) data for the edge
00114       parameters_t tags;
};

/// Convenience function for setting two edges as companions
00118 inline void join_edges(split_edge& Edge1, split_edge& Edge2)
{
      Edge1.companion = &Edge2;
      Edge2.companion = &Edge1;
}

/// Convenience function for joining a collection of edges into a closed loop
template<typename IteratorType>
00126 inline void loop_edges(IteratorType Begin, IteratorType End)
{
      if(Begin == End)
            return;

      IteratorType i;
      for(i = Begin; i+1 != End; ++i)
            (*i)->face_clockwise = *(i+1);

      (*i)->face_clockwise = *Begin;
}

/////////////////////////////////////////////////////////////////////////////
// face

/// Encapsulates a polygonal face
00142 class face :
      public selectable
{
public:
      face(split_edge* FirstEdge);

      /// Points to the first edge in the loop of edges that define the polygon
00149       split_edge* first_edge;
      /// Defines a collection of holes in the polygon face (each element points to the first edge in a loop that defines a hole)
00151       typedef std::vector<split_edge*> holes_t;
      /// Contains any holes in the polygon face
00153       holes_t holes;
      /// Stores uniform data for the face
00155       parameters_t uniform_data;
      /// Stores tag (SDS) data for the face
00157       parameters_t tags;
};

#include "mesh_triangulate_detail.h"

/// Decomposes a collection of faces into triangles
template<typename InputFaceIterator, typename OutputFaceIterator, typename OutputEdgeIterator, typename OutputPointIterator>
void triangulate(InputFaceIterator Begin, InputFaceIterator End, OutputFaceIterator OutputFaces, OutputEdgeIterator OutputEdges, OutputPointIterator OutputPoints)
{
      detail::glu_triangulator_t<OutputFaceIterator, OutputEdgeIterator, OutputPointIterator> triangulator(OutputFaces, OutputEdges, OutputPoints);
      for(InputFaceIterator face = Begin; face != End; ++face)
            triangulator(**face);
}

/// Calculates the normal for an edge loop (returns a zero-length normal for degenerate cases)
vector3 normal(const split_edge* const Loop);
/// Calculates the normal for a face (returns a zero-length normal for degenerate cases)
vector3 normal(const face& Face);

/////////////////////////////////////////////////////////////////////////////
// polyhedron

/// Encapsulates a manifold polyhedron composed of polygon faces
class polyhedron :
      public selectable
{
public:
      polyhedron();
      ~polyhedron();

      typedef std::vector<split_edge*> edges_t;
      edges_t edges;

      typedef std::vector<face*> faces_t;
      faces_t faces;

      typedef enum
      {
            POLYGONS,
            CATMULL_CLARK_SUBDIVISION_MESH,
      } type_t;

      /// Stores the polyhedron type
      type_t type;
      /// Stores a reference to the (optional) material for the polyhedron
      imaterial* material;
      /// Stores constant data for the polyhedron
      parameters_t constant_data;
      /// Stores tag (SDS) data for the polyhedron
      parameters_t tags;

      friend std::ostream& operator<<(std::ostream&, const type_t&);
      friend std::istream& operator>>(std::istream&, type_t&);
};

/////////////////////////////////////////////////////////////////////////////
// linear_curve

/// Encapsulates a linear curve
class linear_curve :
      public selectable
{
public:
      /// Defines storage for the set of curve control points
      typedef std::vector<point*> control_points_t;
      /// Stores the set of curve control points
      control_points_t control_points;
      /// Stores uniform data
      parameters_t uniform_data;
      /// Defines storage for varying data
      typedef std::vector<parameters_t> varying_t;
      /// Stores varying data
      varying_t varying_data;
};

/////////////////////////////////////////////////////////////////////////////
// linear_curve_group

/// Encapsulates a collection of linear curves
class linear_curve_group :
      public selectable
{
public:
      linear_curve_group();
      ~linear_curve_group();

      /// Defines storage for a collection of linear curves
      typedef std::vector<linear_curve*> curves_t;
      /// Stores the collection of linear curves
      curves_t curves;
      /// Set to true iff the curves should wrap in the V direction
      bool wrap;
      /// Stores constant data
      parameters_t constant_data;
      /// Stores a reference to the optional curves material
      imaterial* material;
};

/////////////////////////////////////////////////////////////////////////////
// cubic_curve

/// Encapsulates a cubic curve
class cubic_curve :
      public selectable
{
public:
      /// Defines storage for the set of curve control points
      typedef std::vector<point*> control_points_t;
      /// Stores the set of curve control points
      control_points_t control_points;
      /// Stores uniform data
      parameters_t uniform_data;
      /// Defines storage for varying data
      typedef std::vector<parameters_t> varying_t;
      /// Stores varying data
      varying_t varying_data;
};

/////////////////////////////////////////////////////////////////////////////
// cubic_curve_group

/// Encapsulates a collection of cubic curves
class cubic_curve_group :
      public selectable
{
public:
      cubic_curve_group();
      ~cubic_curve_group();

      /// Defines storage for a collection of cubic curves
      typedef std::vector<cubic_curve*> curves_t;
      /// Stores the collection of cubic curves
      curves_t curves;
      /// Set to true iff the curves should wrap in the V direction
      bool wrap;
      /// Stores constant data
      parameters_t constant_data;
      /// Stores a reference to the optional curves material
      imaterial* material;
};

/////////////////////////////////////////////////////////////////////////////
// nucurve

/// Encapsulates a NURBS curve - note: there is no equivalent RenderMan primitive, so these can't be rendered - take a look at cubic_curve, instead.
class nucurve :
      public selectable
{
public:
      nucurve();

      /// Stores the curve order (note - the curve order is defined as the curve degree plus 1)
      unsigned int order;
      /// Defines a collection of knots
      typedef std::vector<double> knots_t;
      /// The set of knots that define the curve's knot vector
      knots_t knots;

      /// Defines a control point - a combination of a point and a weight
      struct control_point
      {
            control_point(point* Position, const double Weight = 1.0) : position(Position), weight(Weight) { }

            point* position;
            double weight;
      };
      /// Defines a collection of control vertices
      typedef std::vector<control_point> control_points_t;
      /// The set of control vertices that define this curve
      control_points_t control_points;
};

/// Encapsulates a collection of NURBS curves - note: there is no equivalent RenderMan primitive, so these can't be rendered - take a look at cubic_curve_group, instead
class nucurve_group :
      public selectable
{
public:
      nucurve_group();
      ~nucurve_group();

      /// Defines storage for a collection of NURBS curves
      typedef std::vector<nucurve*> curves_t;
      /// Stores the collection of NURBS curves
      curves_t curves;
      /// Stores a reference to the optional curve material
      imaterial* material;
};

/////////////////////////////////////////////////////////////////////////////
// bilinear_patch

/// Encapsulates a bilinear patch
class bilinear_patch :
      public selectable
{
public:
      bilinear_patch();

      /// Defines control points for the patch
      typedef boost::array<point*, 4> control_points_t;
      /// Stores the patch control points
      control_points_t control_points;
      /// Defines storage for varying data
      typedef boost::array<parameters_t, 4> varying_t;
      /// Stores varying data
      varying_t varying_data;
      /// Stores uniform data
      parameters_t uniform_data;
      /// Stores a reference to the optional patch material
      imaterial* material;
};


/////////////////////////////////////////////////////////////////////////////
// bicubic_patch

/// Encapsulates a bicubic patch
class bicubic_patch :
      public selectable
{
public:
      bicubic_patch();

00380       /// Defines storage for the patch control-points
      typedef boost::array<point*, 16> control_points_t;
      /// Stores the patch control-points
      control_points_t control_points;
      /// Defines storage for varying data
      typedef boost::array<parameters_t, 4> varying_t;
      /// Stores varying data
      varying_t varying_data;
      /// Stores uniform data
      parameters_t uniform_data;
      /// Stores a reference to the (optional) patch material
      imaterial* material;
};

/////////////////////////////////////////////////////////////////////////////
// nupatch
00396 
/// Encapsulates a NURBS patch
class nupatch :
      public selectable
{
public:
      nupatch();

      /// Stores the patch order for u parametric direction (note: order is defined as degree + 1)
      unsigned int u_order;
      /// Stores the patch order for v parametric direction (note: order is defined as degree + 1)
      unsigned int v_order;
      /// Defines a collection of knots
      typedef std::vector<double> knots_t;
      /// The set of knots that define the patch's knot vector for u parametric direction
      knots_t u_knots;
      /// The set of knots that define the patch's knot vector for v parametric direction
      knots_t v_knots;

      /// Defines a control point - a combination of a point and a weight
00416       struct control_point
      {
00418             control_point(point* Position, const double Weight = 1.0) : position(Position), weight(Weight) { }

00420             point* position;
            double weight;
00422       };
      /// Defines a collection of control vertices
      typedef std::vector<control_point> control_points_t;
      /// The set of control vertices that define this curve
      control_points_t control_points;

      /// Stores a reference to the (optional) patch material
      imaterial* material;
};

00432 /////////////////////////////////////////////////////////////////////////////
// blobby

/// Encapsulates a RenderMan blobby (implicit surface) primitive as a tree
class blobby
00437 {
public:
00439       // Forward declarations
      class opcode;
00441       class visitor;

00443       blobby(opcode* Opcode);
      ~blobby();
00445 
      /// Visitor design pattern
      void accept(visitor& Visitor);

      /// Stores the root "instruction" for the implicit surface function
      opcode* root;
      /// Stores a reference to the (optional) blobby material
00452       imaterial* material;
      /// Stores constant data
      parameters_t constant_data;

      /// Defines an "instruction" used to define the implicit surface function
      class opcode :
            public selectable
      {
00460       public:
            virtual ~opcode() {}
00462 
            /// Virtual copy constructor design pattern
00464             virtual opcode* clone() = 0;
            /// Visitor design pattern
00466             virtual void accept(visitor& Visitor) = 0;
      };
00468 
      /// Inserts a constant value into the implicit surface function
      class constant :
            public opcode
      {
      public:
            constant(double Value);
00475             opcode* clone();
            void accept(visitor& Visitor);

            /// Stores the value to be inserted
            double value;
00480       };

00482       /// Inserts an ellipsoid primitive into the implicit surface function
      class ellipsoid :
00484             public opcode
      {
00486       public:
            ellipsoid(point* Origin, const matrix4& Transformation);
00488             opcode* clone();
            void accept(visitor& Visitor);

            /// Stores the origin of the unit sphere that underlies the ellipsoid
            point* origin;
            /// Stores a matrix used to transform the unit sphere into an ellipsoid in mesh coordinates
            matrix4 transformation;
00495             /// Stores vertex data for this primitive
            parameters_t vertex_data;
      };

      /// Inserts a segment blob primitive into the implicit surface function
      class segment :
            public opcode
      {
00503       public:
            segment(point* Start, point* End, double Radius, const matrix4& Transformation);
00505             opcode* clone();
            void accept(visitor& Visitor);
00507 
            /// Stores the first end point that defines the segment blob
00509             point* start;
            /// Stores the second end point that defines the segment blob
00511             point* end;
            /// Stores the radius of the segment blob
            double radius;
            /// Stores a matrix used to transform the segment blob into mesh coordinates
            matrix4 transformation;
            /// Stores vertex data for this primitive
            parameters_t vertex_data;
00518       };

      /// Inserts a subtraction operation into the implicit surface function
      class subtract :
            public opcode
      {
      public:
00525             subtract(opcode* Subtrahend, opcode* Minuend);
            ~subtract();
00527             opcode* clone();
            void accept(visitor& Visitor);
00529 
            opcode* subtrahend;
            opcode* minuend;
00532       };

      /// Inserts a division operation into the implicit surface function
      class divide :
            public opcode
      {
      public:
            divide(opcode* Dividend, opcode* Divisor);
00540             ~divide();
            opcode* clone();
00542             void accept(visitor& Visitor);

            opcode* dividend;
            opcode* divisor;
00546       };

      /// Base class for opcodes that act on a variable number of arguments
      class variable_operands :
            public opcode
      {
      public:
            void add_operand(opcode* Operand);
00554             void operands_accept(visitor& Visitor);

00556             typedef std::vector<opcode*> operands_t;
            operands_t operands;
00558 
      protected:
            ~variable_operands();
            void clone_operands();
      };

      /// Inserts an addition operation into the implicit surface function
00565       class add :
            public variable_operands
      {
      public:
            opcode* clone();
            void accept(visitor& Visitor);
      };
00572 
      /// Inserts a multiplication operation into the implicit surface function
00574       class multiply :
            public variable_operands
00576       {
      public:
00578             opcode* clone();
            void accept(visitor& Visitor);
00580       };

00582       /// Inserts a maximum operation into the implicit surface function
      class max :
            public variable_operands
      {
      public:
            opcode* clone();
            void accept(visitor& Visitor);
      };
00590 
      /// Inserts a minimum operation into the implicit surface function
      class min :
            public variable_operands
      {
      public:
            opcode* clone();
00597             void accept(visitor& Visitor);
      };
00599 
      /// Visitor design pattern
00601       class visitor
      {
00603       public:
            virtual void visit_constant(constant&) = 0;
00605             virtual void visit_ellipsoid(ellipsoid&) = 0;
            virtual void visit_segment(segment&) = 0;
00607             virtual void visit_subtract(subtract&) = 0;
            virtual void visit_divide(divide&) = 0;
            virtual void visit_add(add&) = 0;
            virtual void visit_multiply(multiply&) = 0;
            virtual void visit_min(min&) = 0;
            virtual void visit_max(max&) = 0;

00614       protected:
            visitor() {}
            visitor(const visitor&) {}
            visitor& operator=(const visitor&) { return *this; }
      };
};

00621 /////////////////////////////////////////////////////////////////////////////
// mesh
00623 
/// Encapsulates a collection of geometry
00625 class mesh :
      public selectable
00627 {
public:
00629       mesh();
      virtual ~mesh();

00632       /// Defines a collection of points
      typedef std::vector<point*> points_t;
      /// Stores the set of points within the mesh that are shared among the rest of the mesh geometry
      points_t points;

      /// Defines a collection of rendered point groups
      typedef std::vector<point_group*> point_groups_t;
      /// Stores a collection of rendered point groups
00640       point_groups_t point_groups;

00642       /// Defines a collection of manifold polyhedra
      typedef std::vector<polyhedron*> polyhedra_t;
      /// Stores a collection of manifold polyhedra
00645       polyhedra_t polyhedra;

      /// Defines a collection of linear curve groups
      typedef std::vector<linear_curve_group*> linear_curve_groups_t;
      /// Stores a collection of linear curve groups
      linear_curve_groups_t linear_curve_groups;

00652       /// Defines a collection of cubic curve groups
      typedef std::vector<cubic_curve_group*> cubic_curve_groups_t;
      /// Stores a collection of cubic curve groups
      cubic_curve_groups_t cubic_curve_groups;

      /// Defines a collection of NURBS curve groups
      typedef std::vector<nucurve_group*> nucurve_groups_t;
      /// Stores a collection of nucurves
      nucurve_groups_t nucurve_groups;

      /// Defines a collection of bilinear patches
      typedef std::vector<bilinear_patch*> bilinear_patches_t;
      /// Stores a collection of bilinear patches
      bilinear_patches_t bilinear_patches;
00666 
      /// Defines a collection of bicubic patches
00668       typedef std::vector<bicubic_patch*> bicubic_patches_t;
      /// Stores a collection of bicubic patches
00670       bicubic_patches_t bicubic_patches;

      /// Defines a collection of nupatches
00673       typedef std::vector<nupatch*> nupatches_t;
      /// Stores a collection of nupatches
      nupatches_t nupatches;

      /// Defines a collection of blobbies
      typedef std::vector<blobby*> blobbies_t;
      /// Stores a collection of blobbies
      blobbies_t blobbies;

private:
      mesh(const mesh& RHS);
      mesh& operator=(const mesh& RHS);
};
00686 
/// Creates data for a unit cube and appends it to the given Mesh & Polyhedron
void add_unit_cube(mesh& Mesh, polyhedron& Polyhedron);
/// Defines a reference to polygonal grid data that maintains the topology in a convenient form
typedef boost::tuple<boost::multi_array<point*, 2>, boost::multi_array<split_edge*, 3>, boost::multi_array<face*, 2> > grid_results_t;
/// Creates data for a grid, optionally stitched along either or both axes (e.g. a cylinder or a torus)
grid_results_t add_grid(mesh& Mesh, polyhedron& Polyhedron, const unsigned long Rows, const unsigned long Columns, const bool StitchTop, const bool StitchSide);
/// Copies the input mesh into the output mesh
void deep_copy(const mesh& Input, mesh& Output);
00695 
/// Returns true iff the given polyhedron contains valid data
bool is_valid(const polyhedron& Polyhedron);
/// Returns true iff the given NURBS curve contains valid data
00699 bool is_valid(const nucurve& Curve);
/// Returns true iff the given NURBS patch contains valid data
bool is_valid(const nupatch& Patch);

/// Returns true iff the given polyhedron is a solid volume (no holes!)
bool is_solid(const polyhedron& Polyhedron);

/// Returns a bounding-box containing every point in the given mesh
const bounding_box bounds(const mesh& Mesh);
00708 
} // namespace k3d
00710 
#endif // K3DSDK_MESH_H
00712 


Generated by  Doxygen 1.6.0   Back to index