home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / include / k3d / k3dsdk / legacy_mesh.h < prev    next >
C/C++ Source or Header  |  2008-11-07  |  27KB  |  899 lines

  1. #ifndef K3DSDK_LEGACY_MESH_H
  2. #define K3DSDK_LEGACY_MESH_H
  3.  
  4. // K-3D
  5. // Copyright (c) 1995-2006, Timothy M. Shead
  6. //
  7. // Contact: tshead@k-3d.com
  8. //
  9. // This program is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. // General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public
  20. // License along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22.  
  23. #include "algebra.h"
  24. #include "bounding_box3.h"
  25. #include "mesh.h"
  26. #include "selectable.h"
  27. #include "utility.h"
  28.  
  29. #include <boost/any.hpp>
  30. #include <boost/array.hpp>
  31. #include <boost/multi_array.hpp>
  32. #include <boost/tuple/tuple.hpp>
  33.  
  34. #include <map>
  35. #include <string>
  36. #include <vector>
  37.  
  38. namespace k3d
  39. {
  40.  
  41. class imaterial;
  42.  
  43. namespace legacy
  44. {
  45.  
  46. /////////////////////////////////////////////////////////////////////////////
  47. // parameters_t
  48.  
  49. /// Encapsulates a set of name-value pairs
  50. typedef std::map<std::string, boost::any> parameters_t;
  51.  
  52. /////////////////////////////////////////////////////////////////////////////
  53. // point
  54.  
  55. /// Encapsulates a point in 3D space
  56. class point :
  57.     public selectable
  58. {
  59. public:
  60.     point(const point3& Position);
  61.     point(const double X, const double Y, const double Z);
  62.  
  63.     /// Stores the position of the point in 3D space
  64.     point3 position;
  65.     /// Stores vertex data for the point
  66.     parameters_t vertex_data;
  67.     /// Stores tag (SDS) data for the point
  68.     parameters_t tags;
  69. };
  70.  
  71. /////////////////////////////////////////////////////////////////////////////
  72. // split_edge
  73.  
  74. /// Encapsulates a split-edge data structure for representing topology information in a polygon mesh
  75. class split_edge :
  76.     public selectable
  77. {
  78. public:
  79.     split_edge(point* Vertex, split_edge* FaceClockwise = 0, split_edge* Companion = 0) :
  80.         vertex(Vertex),
  81.         face_clockwise(FaceClockwise),
  82.         companion(Companion)
  83.     {
  84.     }
  85.     ~split_edge();
  86.  
  87.     /// Stores a reference to the edge vertex
  88.     point* vertex;
  89.     /// Stores a reference to the next edge in clockwise order around the face
  90.     split_edge* face_clockwise;
  91.     /// Stores a reference to the "companion" edge associated with the face on the opposite side of this edge
  92.     split_edge* companion;
  93.     /// Stores facevarying data for this edge (specifically, its vertex)
  94.     parameters_t facevarying_data;
  95.     /// Stores tag (SDS) data for the edge
  96.     parameters_t tags;
  97. };
  98.  
  99. /// Convenience function for setting two edges as companions
  100. inline void join_edges(split_edge& Edge1, split_edge& Edge2)
  101. {
  102.     Edge1.companion = &Edge2;
  103.     Edge2.companion = &Edge1;
  104. }
  105.  
  106. /// Convenience function for joining a collection of edges into a closed loop
  107. template<typename IteratorType>
  108. inline void loop_edges(IteratorType Begin, IteratorType End)
  109. {
  110.     if(Begin == End)
  111.         return;
  112.  
  113.     IteratorType i = Begin;
  114.     IteratorType j = i;
  115.     while(++j != End)
  116.     {
  117.         (*i)->face_clockwise = *j;
  118.  
  119.         j = ++i;
  120.     }
  121.  
  122.     (*i)->face_clockwise = *Begin;
  123. }
  124.  
  125. /// Convenience function that returns face anticlockwise edge
  126. inline split_edge* face_anticlockwise(split_edge* Edge)
  127. {
  128.     split_edge* current_edge = Edge;
  129.     while(current_edge && current_edge->face_clockwise != Edge)
  130.         current_edge = current_edge->face_clockwise;
  131.  
  132.     return current_edge;
  133. }
  134.  
  135. /////////////////////////////////////////////////////////////////////////////
  136. // face
  137.  
  138. /// Encapsulates a polygonal face
  139. class face :
  140.     public selectable
  141. {
  142. public:
  143.     face(split_edge* FirstEdge, imaterial* Material);
  144.     ~face();
  145.  
  146.     /// Points to the first edge in the loop of edges that define the polygon
  147.     split_edge* first_edge;
  148.     /// Defines a collection of holes in the polygon face (each element points to the first edge in a loop that defines a hole)
  149.     typedef std::vector<split_edge*> holes_t;
  150.     /// Contains any holes in the polygon face
  151.     holes_t holes;
  152.     /// Stores a reference to the (optional) material for the face
  153.     imaterial* material;
  154.     /// Stores uniform data for the face
  155.     parameters_t uniform_data;
  156.     /// Stores tag (SDS) data for the face
  157.     parameters_t tags;
  158. };
  159.  
  160. /// Calculates the normal for an edge loop (returns a zero-length normal for degenerate cases)
  161. normal3 normal(const split_edge* const Loop);
  162. /// Calculates the normal for a face (returns a zero-length normal for degenerate cases)
  163. normal3 normal(const face& Face);
  164.  
  165. /////////////////////////////////////////////////////////////////////////////
  166. // polyhedron
  167.  
  168. /// Encapsulates a manifold polyhedron composed of polygon faces
  169. class polyhedron :
  170.     public selectable
  171. {
  172. public:
  173.     polyhedron();
  174.     ~polyhedron();
  175.  
  176.     typedef std::vector<face*> faces_t;
  177.     faces_t faces;
  178.  
  179.     typedef enum
  180.     {
  181.         POLYGONS,
  182.         CATMULL_CLARK_SUBDIVISION_MESH,
  183.     } type_t;
  184.  
  185.     /// Stores the polyhedron type
  186.     type_t type;
  187.     /// Stores constant data for the polyhedron
  188.     parameters_t constant_data;
  189.     /// Stores tag (SDS) data for the polyhedron
  190.     parameters_t tags;
  191.  
  192.     friend std::ostream& operator<<(std::ostream&, const type_t&);
  193.     friend std::istream& operator>>(std::istream&, type_t&);
  194. };
  195.  
  196. /// Convenience function for setting all companions of a raw polygon edges
  197. void set_companions(polyhedron& Polyhedron);
  198.  
  199. /////////////////////////////////////////////////////////////////////////////
  200. // linear_curve
  201.  
  202. /// Encapsulates a linear curve
  203. class linear_curve :
  204.     public selectable
  205. {
  206. public:
  207.     /// Defines storage for the set of curve control points
  208.     typedef std::vector<point*> control_points_t;
  209.     /// Stores the set of curve control points
  210.     control_points_t control_points;
  211.     /// Stores uniform data
  212.     parameters_t uniform_data;
  213.     /// Defines storage for varying data
  214.     typedef std::vector<parameters_t> varying_t;
  215.     /// Stores varying data
  216.     varying_t varying_data;
  217. };
  218.  
  219. /////////////////////////////////////////////////////////////////////////////
  220. // linear_curve_group
  221.  
  222. /// Encapsulates a collection of linear curves
  223. class linear_curve_group :
  224.     public selectable
  225. {
  226. public:
  227.     linear_curve_group();
  228.     ~linear_curve_group();
  229.  
  230.     /// Defines storage for a collection of linear curves
  231.     typedef std::vector<linear_curve*> curves_t;
  232.     /// Stores the collection of linear curves
  233.     curves_t curves;
  234.     /// Set to true iff the curves should wrap in the V direction
  235.     bool wrap;
  236.     /// Stores constant data
  237.     parameters_t constant_data;
  238.     /// Stores a reference to the optional curves material
  239.     imaterial* material;
  240. };
  241.  
  242. /////////////////////////////////////////////////////////////////////////////
  243. // cubic_curve
  244.  
  245. /// Encapsulates a cubic curve
  246. class cubic_curve :
  247.     public selectable
  248. {
  249. public:
  250.     /// Defines storage for the set of curve control points
  251.     typedef std::vector<point*> control_points_t;
  252.     /// Stores the set of curve control points
  253.     control_points_t control_points;
  254.     /// Stores uniform data
  255.     parameters_t uniform_data;
  256.     /// Defines storage for varying data
  257.     typedef std::vector<parameters_t> varying_t;
  258.     /// Stores varying data
  259.     varying_t varying_data;
  260. };
  261.  
  262. /////////////////////////////////////////////////////////////////////////////
  263. // cubic_curve_group
  264.  
  265. /// Encapsulates a collection of cubic curves
  266. class cubic_curve_group :
  267.     public selectable
  268. {
  269. public:
  270.     cubic_curve_group();
  271.     ~cubic_curve_group();
  272.  
  273.     /// Defines storage for a collection of cubic curves
  274.     typedef std::vector<cubic_curve*> curves_t;
  275.     /// Stores the collection of cubic curves
  276.     curves_t curves;
  277.     /// Set to true iff the curves should wrap in the V direction
  278.     bool wrap;
  279.     /// Stores constant data
  280.     parameters_t constant_data;
  281.     /// Stores a reference to the optional curves material
  282.     imaterial* material;
  283. };
  284.  
  285. /////////////////////////////////////////////////////////////////////////////
  286. // nucurve
  287.  
  288. /// Encapsulates a NURBS curve - note: there is no equivalent RenderMan primitive, so these can't be rendered - take a look at cubic_curve, instead.
  289. class nucurve :
  290.     public selectable
  291. {
  292. public:
  293.     nucurve();
  294.  
  295.     /// Stores the curve order (note - the curve order is defined as the curve degree plus 1)
  296.     unsigned int order;
  297.     /// Defines a collection of knots
  298.     typedef std::vector<double> knots_t;
  299.     /// The set of knots that define the curve's knot vector
  300.     knots_t knots;
  301.  
  302.     /// Defines a control point - a combination of a point and a weight
  303.     struct control_point
  304.     {
  305.         control_point(point* Position, const double Weight = 1.0) : position(Position), weight(Weight) { }
  306.  
  307.         point* position;
  308.         double weight;
  309.     };
  310.     /// Defines a collection of control vertices
  311.     typedef std::vector<control_point> control_points_t;
  312.     /// The set of control vertices that define this curve
  313.     control_points_t control_points;
  314. };
  315.  
  316. /// 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
  317. class nucurve_group :
  318.     public selectable
  319. {
  320. public:
  321.     nucurve_group();
  322.     ~nucurve_group();
  323.  
  324.     /// Defines storage for a collection of NURBS curves
  325.     typedef std::vector<nucurve*> curves_t;
  326.     /// Stores the collection of NURBS curves
  327.     curves_t curves;
  328.     /// Stores a reference to the optional curve material
  329.     imaterial* material;
  330. };
  331.  
  332. /////////////////////////////////////////////////////////////////////////////
  333. // bilinear_patch
  334.  
  335. /// Encapsulates a bilinear patch
  336. class bilinear_patch :
  337.     public selectable
  338. {
  339. public:
  340.     bilinear_patch();
  341.  
  342.     /// Defines control points for the patch
  343.     typedef boost::array<point*, 4> control_points_t;
  344.     /// Stores the patch control points
  345.     control_points_t control_points;
  346.     /// Defines storage for varying data
  347.     typedef boost::array<parameters_t, 4> varying_t;
  348.     /// Stores varying data
  349.     varying_t varying_data;
  350.     /// Stores uniform data
  351.     parameters_t uniform_data;
  352.     /// Stores a reference to the optional patch material
  353.     imaterial* material;
  354. };
  355.  
  356.  
  357. /////////////////////////////////////////////////////////////////////////////
  358. // bicubic_patch
  359.  
  360. /// Encapsulates a bicubic patch
  361. class bicubic_patch :
  362.     public selectable
  363. {
  364. public:
  365.     bicubic_patch();
  366.  
  367.     /// Defines storage for the patch control-points
  368.     typedef boost::array<point*, 16> control_points_t;
  369.     /// Stores the patch control-points
  370.     control_points_t control_points;
  371.     /// Defines storage for varying data
  372.     typedef boost::array<parameters_t, 4> varying_t;
  373.     /// Stores varying data
  374.     varying_t varying_data;
  375.     /// Stores uniform data
  376.     parameters_t uniform_data;
  377.     /// Stores a reference to the (optional) patch material
  378.     imaterial* material;
  379. };
  380.  
  381. /////////////////////////////////////////////////////////////////////////////
  382. // nupatch
  383.  
  384. /// Encapsulates a NURBS patch
  385. class nupatch :
  386.     public selectable
  387. {
  388. public:
  389.     nupatch();
  390.  
  391.     /// Stores the patch order for u parametric direction (note: order is defined as degree + 1)
  392.     unsigned int u_order;
  393.     /// Stores the patch order for v parametric direction (note: order is defined as degree + 1)
  394.     unsigned int v_order;
  395.     /// Defines a collection of knots
  396.     typedef std::vector<double> knots_t;
  397.     /// The set of knots that define the patch's knot vector for u parametric direction
  398.     knots_t u_knots;
  399.     /// The set of knots that define the patch's knot vector for v parametric direction
  400.     knots_t v_knots;
  401.  
  402.     /// Defines a control point - a combination of a point and a weight
  403.     struct control_point
  404.     {
  405.         control_point(point* Position, const double Weight = 1.0) : position(Position), weight(Weight) { }
  406.  
  407.         point* position;
  408.         double weight;
  409.     };
  410.     /// Defines a collection of control vertices
  411.     typedef std::vector<control_point> control_points_t;
  412.     /// The set of control vertices that define this curve
  413.     control_points_t control_points;
  414.  
  415.     /// Stores a reference to the (optional) patch material
  416.     imaterial* material;
  417. };
  418.  
  419. /////////////////////////////////////////////////////////////////////////////
  420. // blobby
  421.  
  422. /// Encapsulates a RenderMan blobby (implicit surface) primitive as a tree
  423. class blobby
  424. {
  425. public:
  426.     // Forward declarations
  427.     class opcode;
  428.     class visitor;
  429.  
  430.     blobby(opcode* Opcode);
  431.     ~blobby();
  432.  
  433.     /// Visitor design pattern
  434.     void accept(visitor& Visitor);
  435.  
  436.     /// Stores the root "instruction" for the implicit surface function
  437.     opcode* root;
  438.     /// Stores a reference to the (optional) blobby material
  439.     imaterial* material;
  440.     /// Stores constant data
  441.     parameters_t constant_data;
  442.  
  443.     /// Defines an "instruction" used to define the implicit surface function
  444.     class opcode :
  445.         public selectable
  446.     {
  447.     public:
  448.         virtual ~opcode() {}
  449.  
  450.         /// Virtual copy constructor design pattern
  451.         virtual opcode* clone() = 0;
  452.         /// Visitor design pattern
  453.         virtual void accept(visitor& Visitor) = 0;
  454.     };
  455.  
  456.     /// Inserts a constant value into the implicit surface function
  457.     class constant :
  458.         public opcode
  459.     {
  460.     public:
  461.         constant(double Value);
  462.         opcode* clone();
  463.         void accept(visitor& Visitor);
  464.  
  465.         /// Stores the value to be inserted
  466.         double value;
  467.     };
  468.  
  469.     /// Inserts an ellipsoid primitive into the implicit surface function
  470.     class ellipsoid :
  471.         public opcode
  472.     {
  473.     public:
  474.         ellipsoid(point* Origin, const matrix4& Transformation);
  475.         opcode* clone();
  476.         void accept(visitor& Visitor);
  477.  
  478.         /// Stores the origin of the unit sphere that underlies the ellipsoid
  479.         point* origin;
  480.         /// Stores a matrix used to transform the unit sphere into an ellipsoid in mesh coordinates
  481.         matrix4 transformation;
  482.         /// Stores vertex data for this primitive
  483.         parameters_t vertex_data;
  484.     };
  485.  
  486.     /// Inserts a segment blob primitive into the implicit surface function
  487.     class segment :
  488.         public opcode
  489.     {
  490.     public:
  491.         segment(point* Start, point* End, double Radius, const matrix4& Transformation);
  492.         opcode* clone();
  493.         void accept(visitor& Visitor);
  494.  
  495.         /// Stores the first end point that defines the segment blob
  496.         point* start;
  497.         /// Stores the second end point that defines the segment blob
  498.         point* end;
  499.         /// Stores the radius of the segment blob
  500.         double radius;
  501.         /// Stores a matrix used to transform the segment blob into mesh coordinates
  502.         matrix4 transformation;
  503.         /// Stores vertex data for this primitive
  504.         parameters_t vertex_data;
  505.     };
  506.  
  507.     /// Inserts a subtraction operation into the implicit surface function
  508.     class subtract :
  509.         public opcode
  510.     {
  511.     public:
  512.         subtract(opcode* Subtrahend, opcode* Minuend);
  513.         ~subtract();
  514.         opcode* clone();
  515.         void accept(visitor& Visitor);
  516.  
  517.         opcode* subtrahend;
  518.         opcode* minuend;
  519.     };
  520.  
  521.     /// Inserts a division operation into the implicit surface function
  522.     class divide :
  523.         public opcode
  524.     {
  525.     public:
  526.         divide(opcode* Dividend, opcode* Divisor);
  527.         ~divide();
  528.         opcode* clone();
  529.         void accept(visitor& Visitor);
  530.  
  531.         opcode* dividend;
  532.         opcode* divisor;
  533.     };
  534.  
  535.     /// Base class for opcodes that act on a variable number of arguments
  536.     class variable_operands :
  537.         public opcode
  538.     {
  539.     public:
  540.         void add_operand(opcode* Operand);
  541.         void operands_accept(visitor& Visitor);
  542.  
  543.         typedef std::vector<opcode*> operands_t;
  544.         operands_t operands;
  545.  
  546.     protected:
  547.         ~variable_operands();
  548.         void clone_operands();
  549.     };
  550.  
  551.     /// Inserts an addition operation into the implicit surface function
  552.     class add :
  553.         public variable_operands
  554.     {
  555.     public:
  556.         opcode* clone();
  557.         void accept(visitor& Visitor);
  558.     };
  559.  
  560.     /// Inserts a multiplication operation into the implicit surface function
  561.     class multiply :
  562.         public variable_operands
  563.     {
  564.     public:
  565.         opcode* clone();
  566.         void accept(visitor& Visitor);
  567.     };
  568.  
  569.     /// Inserts a maximum operation into the implicit surface function
  570.     class max :
  571.         public variable_operands
  572.     {
  573.     public:
  574.         opcode* clone();
  575.         void accept(visitor& Visitor);
  576.     };
  577.  
  578.     /// Inserts a minimum operation into the implicit surface function
  579.     class min :
  580.         public variable_operands
  581.     {
  582.     public:
  583.         opcode* clone();
  584.         void accept(visitor& Visitor);
  585.     };
  586.  
  587.     /// Visitor design pattern
  588.     class visitor
  589.     {
  590.     public:
  591.         virtual void visit_constant(constant&) = 0;
  592.         virtual void visit_ellipsoid(ellipsoid&) = 0;
  593.         virtual void visit_segment(segment&) = 0;
  594.         virtual void visit_subtract(subtract&) = 0;
  595.         virtual void visit_divide(divide&) = 0;
  596.         virtual void visit_add(add&) = 0;
  597.         virtual void visit_multiply(multiply&) = 0;
  598.         virtual void visit_min(min&) = 0;
  599.         virtual void visit_max(max&) = 0;
  600.  
  601.     protected:
  602.         visitor() {}
  603.         virtual ~visitor() {}
  604.         visitor(const visitor&) {}
  605.         visitor& operator=(const visitor&) { return *this; }
  606.     };
  607. };
  608.  
  609. /////////////////////////////////////////////////////////////////////////////
  610. // mesh
  611.  
  612. /// Encapsulates a collection of geometry
  613. class mesh :
  614.     public selectable
  615. {
  616. public:
  617.     mesh();
  618.     virtual ~mesh();
  619.  
  620.     /// Defines a collection of points
  621.     typedef std::vector<point*> points_t;
  622.     /// Stores the set of points within the mesh that are shared among the rest of the mesh geometry
  623.     points_t points;
  624.  
  625.     /// Defines a collection of manifold polyhedra
  626.     typedef std::vector<polyhedron*> polyhedra_t;
  627.     /// Stores a collection of manifold polyhedra
  628.     polyhedra_t polyhedra;
  629.  
  630.     /// Defines a collection of linear curve groups
  631.     typedef std::vector<linear_curve_group*> linear_curve_groups_t;
  632.     /// Stores a collection of linear curve groups
  633.     linear_curve_groups_t linear_curve_groups;
  634.  
  635.     /// Defines a collection of cubic curve groups
  636.     typedef std::vector<cubic_curve_group*> cubic_curve_groups_t;
  637.     /// Stores a collection of cubic curve groups
  638.     cubic_curve_groups_t cubic_curve_groups;
  639.  
  640.     /// Defines a collection of NURBS curve groups
  641.     typedef std::vector<nucurve_group*> nucurve_groups_t;
  642.     /// Stores a collection of nucurves
  643.     nucurve_groups_t nucurve_groups;
  644.  
  645.     /// Defines a collection of bilinear patches
  646.     typedef std::vector<bilinear_patch*> bilinear_patches_t;
  647.     /// Stores a collection of bilinear patches
  648.     bilinear_patches_t bilinear_patches;
  649.  
  650.     /// Defines a collection of bicubic patches
  651.     typedef std::vector<bicubic_patch*> bicubic_patches_t;
  652.     /// Stores a collection of bicubic patches
  653.     bicubic_patches_t bicubic_patches;
  654.  
  655.     /// Defines a collection of nupatches
  656.     typedef std::vector<nupatch*> nupatches_t;
  657.     /// Stores a collection of nupatches
  658.     nupatches_t nupatches;
  659.  
  660.     /// Defines a collection of blobbies
  661.     typedef std::vector<blobby*> blobbies_t;
  662.     /// Stores a collection of blobbies
  663.     blobbies_t blobbies;
  664.  
  665.     /// Conversion from a new mesh to a legacy mesh
  666.     mesh& operator=(const k3d::mesh& RHS);
  667.  
  668.     k3d::mesh::primitives_t primitives;
  669.  
  670. private:
  671.     mesh(const mesh& RHS);
  672.     mesh& operator=(const mesh& RHS);
  673. };
  674.  
  675. /// Function template in the spirit of std::for_each that applies a functor to every point in a mesh
  676. template<typename T>
  677. void for_each_point(mesh& Mesh, T Functor)
  678. {
  679.     for(mesh::points_t::iterator point = Mesh.points.begin(); point != Mesh.points.end(); ++point)
  680.         Functor(**point);
  681. }
  682.  
  683. /// Function template in the spirit of std::for_each that applies a functor to every edge in a mesh
  684. template<typename T>
  685. void for_each_edge(mesh& Mesh, T Functor)
  686. {
  687.     for(mesh::polyhedra_t::iterator polyhedron = Mesh.polyhedra.begin(); polyhedron != Mesh.polyhedra.end(); ++polyhedron)
  688.     {
  689.         for(polyhedron::faces_t::const_iterator face = (*polyhedron)->faces.begin(); face != (*polyhedron)->faces.end(); ++face)
  690.         {
  691.             for(split_edge* edge = (*face)->first_edge; edge; edge = edge->face_clockwise)
  692.             {
  693.                 Functor(*edge);
  694.  
  695.                 if(edge->face_clockwise == (*face)->first_edge)
  696.                     break;
  697.             }
  698.  
  699.             // Face holes
  700.             for(face::holes_t::iterator hole = (*face)->holes.begin(); hole != (*face)->holes.end(); ++hole)
  701.             {
  702.                 for(split_edge* edge = *hole; edge; edge = edge->face_clockwise)
  703.                 {
  704.                     Functor(*edge);
  705.  
  706.                     if(edge->face_clockwise == (*hole))
  707.                         break;
  708.                 }
  709.             }
  710.         }
  711.     }
  712. }
  713.  
  714. /// Function template in the spirit of std::for_each that applies a functor to every face in a mesh
  715. template<typename T>
  716. void for_each_face(mesh& Mesh, T Functor)
  717. {
  718.     for(mesh::polyhedra_t::iterator polyhedron = Mesh.polyhedra.begin(); polyhedron != Mesh.polyhedra.end(); ++polyhedron)
  719.     {
  720.         Functor(**polyhedron);
  721.         for(polyhedron::faces_t::const_iterator face = (*polyhedron)->faces.begin(); face != (*polyhedron)->faces.end(); ++face)
  722.             Functor(**face);
  723.     }
  724. }
  725.  
  726. /// Function template in the spirit of std::for_each that applies a functor to every linear curve in a mesh
  727. template<typename T>
  728. void for_each_linear_curve(mesh& Mesh, T Functor)
  729. {
  730.     for(mesh::linear_curve_groups_t::iterator group = Mesh.linear_curve_groups.begin(); group != Mesh.linear_curve_groups.end(); ++group)
  731.     {
  732.         Functor(**group);
  733.         for(linear_curve_group::curves_t::iterator curve = (*group)->curves.begin(); curve != (*group)->curves.end(); ++curve)
  734.             Functor(**curve);
  735.     }
  736. }
  737.  
  738. /// Function template in the spirit of std::for_each that applies a functor to every cubic curve in a mesh
  739. template<typename T>
  740. void for_each_cubic_curve(mesh& Mesh, T Functor)
  741. {
  742.     for(mesh::cubic_curve_groups_t::iterator group = Mesh.cubic_curve_groups.begin(); group != Mesh.cubic_curve_groups.end(); ++group)
  743.     {
  744.         Functor(**group);
  745.         for(cubic_curve_group::curves_t::iterator curve = (*group)->curves.begin(); curve != (*group)->curves.end(); ++curve)
  746.             Functor(**curve);
  747.     }
  748. }
  749.  
  750. /// Function template in the spirit of std::for_each that applies a functor to every nucurve in a mesh
  751. template<typename T>
  752. void for_each_nucurve(mesh& Mesh, T Functor)
  753. {
  754.     for(mesh::nucurve_groups_t::iterator group = Mesh.nucurve_groups.begin(); group != Mesh.nucurve_groups.end(); ++group)
  755.     {
  756.         Functor(**group);
  757.         for(nucurve_group::curves_t::iterator curve = (*group)->curves.begin(); curve != (*group)->curves.end(); ++curve)
  758.             Functor(**curve);
  759.     }
  760. }
  761.  
  762. /// Function template in the spirit of std::for_each that applies a functor to every bilinear patch in a mesh
  763. template<typename T>
  764. void for_each_bilinear_patch(mesh& Mesh, T Functor)
  765. {
  766.     for(mesh::bilinear_patches_t::iterator patch = Mesh.bilinear_patches.begin(); patch != Mesh.bilinear_patches.end(); ++patch)
  767.         Functor(**patch);
  768. }
  769.  
  770. /// Function template in the spirit of std::for_each that applies a functor to every bicubic patch in a mesh
  771. template<typename T>
  772. void for_each_bicubic_patch(mesh& Mesh, T Functor)
  773. {
  774.     for(mesh::bicubic_patches_t::iterator patch = Mesh.bicubic_patches.begin(); patch != Mesh.bicubic_patches.end(); ++patch)
  775.         Functor(**patch);
  776. }
  777.  
  778. /// Function template in the spirit of std::for_each that applies a functor to every bilinear patch in a mesh
  779. template<typename T>
  780. void for_each_nupatch(mesh& Mesh, T Functor)
  781. {
  782.     for(mesh::nupatches_t::iterator patch = Mesh.nupatches.begin(); patch != Mesh.nupatches.end(); ++patch)
  783.         Functor(**patch);
  784. }
  785.  
  786. /// Function template in the spirit of std::for_each that applies a functor to every part of a mesh
  787. template<typename T>
  788. T for_each_component(mesh& Mesh, T Functor)
  789. {
  790.     Functor(Mesh);
  791.  
  792.     for(mesh::points_t::iterator point = Mesh.points.begin(); point != Mesh.points.end(); ++point)
  793.         Functor(**point);
  794.  
  795.     for(mesh::polyhedra_t::iterator polyhedron = Mesh.polyhedra.begin(); polyhedron != Mesh.polyhedra.end(); ++polyhedron)
  796.     {
  797.         Functor(**polyhedron);
  798.  
  799.         for(polyhedron::faces_t::iterator face = (*polyhedron)->faces.begin(); face != (*polyhedron)->faces.end(); ++face)
  800.         {
  801.             Functor(**face);
  802.  
  803.             for(split_edge* edge = (*face)->first_edge; edge; edge = edge->face_clockwise)
  804.             {
  805.                 Functor(*edge);
  806.  
  807.                 if(edge->face_clockwise == (*face)->first_edge)
  808.                     break;
  809.             }
  810.  
  811.             // Face holes
  812.             for(face::holes_t::iterator hole = (*face)->holes.begin(); hole != (*face)->holes.end(); ++hole)
  813.             {
  814.                 for(split_edge* edge = *hole; edge; edge = edge->face_clockwise)
  815.                 {
  816.                     Functor(*edge);
  817.  
  818.                     if(edge->face_clockwise == (*hole))
  819.                         break;
  820.                 }
  821.             }
  822.         }
  823.     }
  824.  
  825.     for(mesh::linear_curve_groups_t::iterator group = Mesh.linear_curve_groups.begin(); group != Mesh.linear_curve_groups.end(); ++group)
  826.     {
  827.         Functor(**group);
  828.         for(linear_curve_group::curves_t::iterator curve = (*group)->curves.begin(); curve != (*group)->curves.end(); ++curve)
  829.             Functor(**curve);
  830.     }
  831.  
  832.     for(mesh::cubic_curve_groups_t::iterator group = Mesh.cubic_curve_groups.begin(); group != Mesh.cubic_curve_groups.end(); ++group)
  833.     {
  834.         Functor(**group);
  835.         for(cubic_curve_group::curves_t::iterator curve = (*group)->curves.begin(); curve != (*group)->curves.end(); ++curve)
  836.             Functor(**curve);
  837.     }
  838.  
  839.     for(mesh::nucurve_groups_t::iterator group = Mesh.nucurve_groups.begin(); group != Mesh.nucurve_groups.end(); ++group)
  840.     {
  841.         Functor(**group);
  842.         for(nucurve_group::curves_t::iterator curve = (*group)->curves.begin(); curve != (*group)->curves.end(); ++curve)
  843.             Functor(**curve);
  844.     }
  845.  
  846.     for(mesh::bilinear_patches_t::iterator patch = Mesh.bilinear_patches.begin(); patch != Mesh.bilinear_patches.end(); ++patch)
  847.         Functor(**patch);
  848.  
  849.     for(mesh::bicubic_patches_t::iterator patch = Mesh.bicubic_patches.begin(); patch != Mesh.bicubic_patches.end(); ++patch)
  850.         Functor(**patch);
  851.  
  852.     for(mesh::nupatches_t::iterator patch = Mesh.nupatches.begin(); patch != Mesh.nupatches.end(); ++patch)
  853.         Functor(**patch);
  854.  
  855.     return Functor;
  856. }
  857.  
  858. /// Decomposes a collection of faces into triangles
  859. void triangulate(const polyhedron::faces_t& Faces, polyhedron::faces_t& NewFaces, mesh::points_t& NewPoints);
  860.  
  861. /// Creates data for a unit cube and appends it to the given Mesh & Polyhedron
  862. void add_unit_cube(mesh& Mesh, polyhedron& Polyhedron, imaterial* const Material);
  863. /// Defines a reference to polygonal grid data that maintains the topology in a convenient form
  864. typedef boost::tuple<boost::multi_array<point*, 2>, boost::multi_array<split_edge*, 3>, boost::multi_array<face*, 2> > grid_results_t;
  865. /// Creates data for a grid, optionally stitched along either or both axes (e.g. a cylinder or a torus)
  866. grid_results_t add_grid(mesh& Mesh, polyhedron& Polyhedron, const unsigned long Rows, const unsigned long Columns, const bool StitchTop, const bool StitchSide, imaterial* const Material);
  867. /// Copies the input mesh into the output mesh
  868. void deep_copy(const mesh& Input, mesh& Output);
  869.  
  870. /// Returns the number of segments in a linear curve, based on the control point count and wrap state
  871. const unsigned long segment_count(const linear_curve& Curve, const bool Wrap);
  872. /// Returns the number of segments in a cubic curve, based on the control point count, basis, and wrap state
  873. const unsigned long segment_count(const cubic_curve& Curve, const bool Wrap);
  874.  
  875. /// Returns the number of varying parameters in a linear curve, based on the control point count and wrap state
  876. const unsigned long varying_count(const linear_curve& Curve, const bool Wrap);
  877. /// Returns the number of varying parameters in a cubic curve, based on the control point count, basis, and wrap state
  878. const unsigned long varying_count(const cubic_curve& Curve, const bool Wrap);
  879.  
  880. /// Returns true iff the given polyhedron contains valid data
  881. bool is_valid(const polyhedron& Polyhedron);
  882. /// Returns true iff the given NURBS curve contains valid data
  883. bool is_valid(const nucurve& Curve);
  884. /// Returns true iff the given NURBS patch contains valid data
  885. bool is_valid(const nupatch& Patch);
  886.  
  887. /// Returns true iff the given polyhedron is a solid volume (no holes!)
  888. bool is_solid(const polyhedron& Polyhedron);
  889.  
  890. /// Returns a bounding-box containing every point in the given mesh
  891. const bounding_box3 bounds(const mesh& Mesh);
  892.  
  893. } // namespace legacy
  894.  
  895. } // namespace k3d
  896.  
  897. #endif // !K3DSDK_LEGACY_MESH_H
  898.  
  899.