1 #ifndef MSP_GEOMETRY_LOADER_H_
2 #define MSP_GEOMETRY_LOADER_H_
5 #include <msp/datafile/loader.h>
6 #include "extrudedshape.h"
9 #include "hypersphere.h"
10 #include "intersection.h"
13 #include "transformedshape.h"
19 template<typename T, unsigned D>
20 class DimensionIndependentLoader: public DataFile::Loader
24 std::list<Shape<T, D> *> shapes;
26 DimensionIndependentLoader(bool = true);
28 virtual ~DimensionIndependentLoader();
30 const Shape<T, D> &get_shape() const;
38 template<typename T, unsigned D, bool = (D>1)>
41 template<typename T, unsigned D>
42 class Loader<T, D, false>: public DimensionIndependentLoader<T, D>
48 template<typename T, unsigned D>
49 class Loader<T, D, true>: public DimensionIndependentLoader<T, D>
59 template<typename T, unsigned D>
60 class ShapeLoader<ExtrudedShape<T, D> >: public Loader<T, D-1>
68 ExtrudedShape<T, D> *create() const;
74 template<typename T, unsigned D>
75 class ShapeLoader<HalfSpace<T, D> >: public DataFile::Loader
78 LinAl::Vector<T, D> normal_;
83 HalfSpace<T, D> *create() const;
86 void normal(const std::vector<T> &);
89 template<typename T, unsigned D>
90 class ShapeLoader<HyperBox<T, D> >: public DataFile::Loader
93 LinAl::Vector<T, D> dimensions_;
98 HyperBox<T, D> *create() const;
101 void dimensions(const std::vector<T> &);
104 template<typename T, unsigned D>
105 class ShapeLoader<HyperSphere<T, D> >: public DataFile::Loader
113 HyperSphere<T, D> *create() const;
119 template<typename T, unsigned D, typename S>
120 class CompositeLoader: public Loader<T, D>
128 template<typename T, unsigned D>
129 class ShapeLoader<Intersection<T, D> >: public CompositeLoader<T, D, Intersection<T, D> >
132 template<typename T, unsigned D>
133 class ShapeLoader<Negation<T, D> >: public Loader<T, D>
136 Negation<T, D> *create() const;
139 template<typename T, unsigned D>
140 class TransformationLoader: public Loader<T, D>
143 AffineTransformation<T, D> transformation;
146 TransformationLoader();
148 TransformedShape<T, D> *create() const;
150 void translate(const std::vector<T> &);
151 void scale(const std::vector<T> &);
152 void shear(const std::vector<T> &);
155 template<typename T, unsigned D>
156 class ShapeLoader<TransformedShape<T, D> >: public TransformationLoader<T, D>
160 class ShapeLoader<TransformedShape<T, 2> >: public TransformationLoader<T, 2>
169 class ShapeLoader<TransformedShape<T, 3> >: public TransformationLoader<T, 3>
174 void rotate(T, T, T, T);
177 template<typename T, unsigned D>
178 class ShapeLoader<Union<T, D> >: public CompositeLoader<T, D, Union<T, D> >
182 template<typename T, unsigned D>
183 inline DimensionIndependentLoader<T, D>::DimensionIndependentLoader(bool s):
186 add("box", &DimensionIndependentLoader::shape<HyperBox<T, D> >);
187 add("halfspace", &DimensionIndependentLoader::shape<HalfSpace<T, D> >);
188 add("intersection", &DimensionIndependentLoader::shape<Intersection<T, D> >);
189 add("negation", &DimensionIndependentLoader::shape<Negation<T, D> >);
190 add("sphere", &DimensionIndependentLoader::shape<HyperSphere<T, D> >);
191 add("transformed", &DimensionIndependentLoader::shape<TransformedShape<T, D> >);
192 add("union", &DimensionIndependentLoader::shape<Union<T, D> >);
195 template<typename T, unsigned D>
196 inline DimensionIndependentLoader<T, D>::~DimensionIndependentLoader()
198 for(typename std::list<Shape<T, D> *>::iterator i=shapes.begin(); i!=shapes.end(); ++i)
202 template<typename T, unsigned D>
203 inline const Shape<T, D> &DimensionIndependentLoader<T, D>::get_shape() const
206 throw std::runtime_error("no shape");
207 return *shapes.front();
210 template<typename T, unsigned D>
212 inline void DimensionIndependentLoader<T, D>::shape()
214 if(single && !shapes.empty())
215 throw std::runtime_error("shape already loaded");
219 shapes.push_back(ldr.create());
223 template<typename T, unsigned D>
224 inline Loader<T, D, false>::Loader(bool s):
225 DimensionIndependentLoader<T, D>(s)
228 template<typename T, unsigned D>
229 inline Loader<T, D, true>::Loader(bool s):
230 DimensionIndependentLoader<T, D>(s)
232 this->add("extruded", &Loader<T, D>::template shape<ExtrudedShape<T, D> >);
236 template<typename T, unsigned D>
237 inline ShapeLoader<ExtrudedShape<T, D> >::ShapeLoader():
240 this->add("length", &ShapeLoader::length);
243 template<typename T, unsigned D>
244 inline ExtrudedShape<T, D> *ShapeLoader<ExtrudedShape<T, D> >::create() const
246 return new ExtrudedShape<T, D>(*this->shapes.front(), length_);
249 template<typename T, unsigned D>
250 inline void ShapeLoader<ExtrudedShape<T, D> >::length(T l)
256 template<typename T, unsigned D>
257 inline ShapeLoader<HalfSpace<T, D> >::ShapeLoader()
261 add("normal", &ShapeLoader::normal);
264 template<typename T, unsigned D>
265 inline HalfSpace<T, D> *ShapeLoader<HalfSpace<T, D> >::create() const
267 return new HalfSpace<T, D>(normal_);
270 template<typename T, unsigned D>
271 inline void ShapeLoader<HalfSpace<T, D> >::normal(const std::vector<T> &d)
274 throw std::invalid_argument("ShapeLoader<HalfSpace>::normal");
276 normal_ = LinAl::Vector<T, D>(&d[0]);
280 template<typename T, unsigned D>
281 inline ShapeLoader<HyperBox<T, D> >::ShapeLoader()
283 for(unsigned i=0; i<D; ++i)
284 dimensions_[i] = T(1);
286 add("dimensions", &ShapeLoader::dimensions);
289 template<typename T, unsigned D>
290 inline HyperBox<T, D> *ShapeLoader<HyperBox<T, D> >::create() const
292 return new HyperBox<T, D>(dimensions_);
295 template<typename T, unsigned D>
296 inline void ShapeLoader<HyperBox<T, D> >::dimensions(const std::vector<T> &d)
299 throw std::invalid_argument("ShapeLoader<HyperBox>::dimensions");
301 dimensions_ = LinAl::Vector<T, D>(&d[0]);
305 template<typename T, unsigned D>
306 inline ShapeLoader<HyperSphere<T, D> >::ShapeLoader():
309 add("radius", &ShapeLoader::radius);
312 template<typename T, unsigned D>
313 inline HyperSphere<T, D> *ShapeLoader<HyperSphere<T, D> >::create() const
315 return new HyperSphere<T, D>(radius_);
318 template<typename T, unsigned D>
319 inline void ShapeLoader<HyperSphere<T, D> >::radius(T r)
325 template<typename T, unsigned D>
326 inline Negation<T, D> *ShapeLoader<Negation<T, D> >::create() const
328 return new Negation<T, D>(*this->shapes.front());
332 template<typename T, unsigned D>
333 inline TransformationLoader<T, D>::TransformationLoader()
335 this->add("translate", &TransformationLoader::translate);
336 this->add("scale", &TransformationLoader::scale);
337 this->add("shear", &TransformationLoader::shear);
340 template<typename T, unsigned D>
341 inline TransformedShape<T, D> *TransformationLoader<T, D>::create() const
343 return new TransformedShape<T, D>(*this->shapes.front(), transformation);
346 template<typename T, unsigned D>
347 inline void TransformationLoader<T, D>::translate(const std::vector<T> &offset)
350 throw std::invalid_argument("TransformationLoader::translate");
352 transformation *= AffineTransformation<T, D>::translation(LinAl::Vector<T, D>(&offset[0]));
355 template<typename T, unsigned D>
356 inline void TransformationLoader<T, D>::scale(const std::vector<T> &s)
358 if(s.size()!=1 && s.size()!=D)
359 throw std::invalid_argument("TransformationLoader::scale");
363 LinAl::Vector<T, D> us;
364 for(unsigned i=0; i<D; ++i)
366 transformation *= AffineTransformation<T, D>::scaling(us);
369 transformation *= AffineTransformation<T, D>::scaling(LinAl::Vector<T, D>(&s[0]));
372 template<typename T, unsigned D>
373 inline void TransformationLoader<T, D>::shear(const std::vector<T> &s)
376 throw std::invalid_argument("TransformationLoader::shear");
378 transformation *= AffineTransformation<T, D>::shear(LinAl::Vector<T, D>(&s[0]), LinAl::Vector<T, D>(&s[D]));
383 inline ShapeLoader<TransformedShape<T, 2> >::ShapeLoader()
385 this->add("rotate", &ShapeLoader::rotate);
389 inline void ShapeLoader<TransformedShape<T, 2> >::rotate(T a)
391 TransformationLoader<T, 2>::transformation *= AffineTransformation<T, 2>::rotation(Angle<T>::from_degrees(a));
396 inline ShapeLoader<TransformedShape<T, 3> >::ShapeLoader()
398 this->add("rotate", &ShapeLoader::rotate);
402 inline void ShapeLoader<TransformedShape<T, 3> >::rotate(T a, T x, T y, T z)
404 TransformationLoader<T, 3>::transformation *= AffineTransformation<T, 3>::rotation(Angle<T>::from_degrees(a), LinAl::Vector<T, 3>(x, y, z));
408 template<typename T, unsigned D, typename S>
409 inline CompositeLoader<T, D, S>::CompositeLoader():
413 template<typename T, unsigned D, typename S>
414 inline S *CompositeLoader<T, D, S>::create() const
416 if(this->shapes.empty())
417 throw std::runtime_error("no shapes");
418 return S::from_iterator_range(this->shapes.begin(), this->shapes.end()).clone();
421 } // namespace Geometry