00001 #ifndef K3DSDK_MESH_H
00002 #define K3DSDK_MESH_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <k3dsdk/bounding_box3.h>
00024 #include <k3dsdk/named_arrays.h>
00025 #include <k3dsdk/named_array_types.h>
00026 #include <k3dsdk/named_tables.h>
00027 #include <k3dsdk/pipeline_data.h>
00028 #include <k3dsdk/table.h>
00029 #include <k3dsdk/typed_array.h>
00030 #include <k3dsdk/uint_t_array.h>
00031
00032 namespace k3d
00033 {
00034
00035 class imaterial;
00036 class mesh_selection;
00037
00039
00040
00042 class mesh
00043 {
00044 public:
00045 mesh();
00046
00048 typedef uint_t_array indices_t;
00050 typedef uint_t_array counts_t;
00052 typedef uint_t_array orders_t;
00054 typedef typed_array<double_t> weights_t;
00056 typedef typed_array<double_t> knots_t;
00058 typedef typed_array<double_t> selection_t;
00060 typedef typed_array<imaterial*> materials_t;
00062 typedef typed_array<bool_t> bools_t;
00064 typedef typed_array<color> colors_t;
00066 typedef typed_array<double_t> doubles_t;
00068 typedef typed_array<matrix4> matrices_t;
00070 typedef typed_array<normal3> normals_t;
00072 typedef typed_array<point2> points_2d_t;
00074 typedef typed_array<point3> points_t;
00076 typedef typed_array<string_t> strings_t;
00078 typedef typed_array<texture3> texture_coordinates_t;
00080 typedef typed_array<vector3> vectors_t;
00082 typedef k3d::named_arrays named_arrays_t;
00084 typedef k3d::table table_t;
00086 typedef k3d::named_tables named_tables_t;
00087
00089 class primitive
00090 {
00091 public:
00092 primitive();
00093 primitive(const string_t& Type);
00094
00096 string_t type;
00098 named_tables_t structure;
00100 named_tables_t attributes;
00101
00103 void difference(const primitive& Other, difference::accumulator& Result) const;
00104 };
00105
00107 class primitives_t :
00108 public std::vector<pipeline_data<primitive> >
00109 {
00110 public:
00112 primitive& create(const string_t& Type);
00113 };
00114
00116 pipeline_data<points_t> points;
00118 pipeline_data<selection_t> point_selection;
00120 table_t point_attributes;
00122 primitives_t primitives;
00123
00125 void difference(const mesh& Other, difference::accumulator& Result) const;
00126
00128 static const bounding_box3 bounds(const mesh& Mesh);
00130 static const bounding_box3 bounds(const points_t& Points);
00131
00133 static void create_index_removal_map(const mesh::bools_t& KeepIndices, mesh::indices_t& IndexMap);
00135 static void create_index_list(const mesh::bools_t& SelectedIndices, mesh::indices_t& IndexSet);
00137 static void lookup_unused_points(const mesh& Mesh, mesh::bools_t& UnusedPoints);
00139 static void remap_points(mesh& Mesh, const mesh::indices_t& PointMap);
00141 static void delete_points(mesh& Mesh, const mesh::bools_t& Points);
00143 static void delete_points(mesh& Mesh, const mesh::bools_t& Points, mesh::indices_t& PointMap);
00145 static void deep_copy(const mesh& From, mesh& To);
00146
00148 template<typename FunctorT>
00149 static void visit_arrays(const mesh::primitive& Primitive, FunctorT Functor)
00150 {
00151 for(mesh::named_tables_t::const_iterator structure = Primitive.structure.begin(); structure != Primitive.structure.end(); ++structure)
00152 {
00153 for(mesh::table_t::const_iterator array = structure->second.begin(); array != structure->second.end(); ++array)
00154 Functor(structure->first, structure->second, array->first, array->second);
00155 }
00156
00157 for(mesh::named_tables_t::const_iterator attributes = Primitive.attributes.begin(); attributes != Primitive.attributes.end(); ++attributes)
00158 {
00159 for(mesh::table_t::const_iterator array = attributes->second.begin(); array != attributes->second.end(); ++array)
00160 Functor(attributes->first, attributes->second, array->first, array->second);
00161 }
00162 }
00163
00165 template<typename FunctorT>
00166 static void visit_arrays(mesh::primitive& Primitive, FunctorT Functor)
00167 {
00168 for(mesh::named_tables_t::iterator structure = Primitive.structure.begin(); structure != Primitive.structure.end(); ++structure)
00169 {
00170 for(mesh::named_arrays_t::iterator array = structure->second.begin(); array != structure->second.end(); ++array)
00171 Functor(structure->first, structure->second, array->first, array->second);
00172 }
00173
00174 for(mesh::named_tables_t::iterator attributes = Primitive.attributes.begin(); attributes != Primitive.attributes.end(); ++attributes)
00175 {
00176 for(mesh::table_t::iterator array = attributes->second.begin(); array != attributes->second.end(); ++array)
00177 Functor(attributes->first, attributes->second, array->first, array->second);
00178 }
00179 }
00180
00182 template<typename FunctorT>
00183 static void visit_arrays(const mesh& Mesh, FunctorT Functor)
00184 {
00185 for(mesh::primitives_t::const_iterator p = Mesh.primitives.begin(); p != Mesh.primitives.end(); ++p)
00186 visit_arrays(**p, Functor);
00187 }
00188
00190 template<typename FunctorT>
00191 static void visit_arrays(mesh& Mesh, FunctorT Functor)
00192 {
00193 for(mesh::primitives_t::iterator p = Mesh.primitives.begin(); p != Mesh.primitives.end(); ++p)
00194 visit_arrays(p->writable(), Functor);
00195 }
00196
00199 static void append(const mesh& Source, mesh& Target, uint_t* const PointBegin = 0, uint_t* const PointEnd = 0, uint_t* const PrimitiveBegin = 0, uint_t* const PrimitiveEnd = 0);
00200 };
00201
00203 std::ostream& operator<<(std::ostream& Stream, const mesh& RHS);
00204 std::ostream& operator<<(std::ostream& Stream, const mesh::primitive& RHS);
00205
00207 namespace difference
00208 {
00209
00210 inline void test(const k3d::mesh& A, const k3d::mesh& B, accumulator& Result)
00211 {
00212 A.difference(B, Result);
00213 }
00214
00216 inline void test(const k3d::mesh::primitive& A, const k3d::mesh::primitive& B, accumulator& Result)
00217 {
00218 A.difference(B, Result);
00219 }
00220
00221 }
00222
00223 }
00224
00225 #endif // !K3DSDK_MESH_H
00226