1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 
19 /*! \file SiconosShape.hpp
20   \brief Definition of an abstract rigid shape
21 */
22 
23 
24 #ifndef SiconosShape_h
25 #define SiconosShape_h
26 
27 #include "MechanicsFwd.hpp"
28 #include <SiconosVisitor.hpp>
29 #include <SiconosSerialization.hpp>
30 #include <SiconosVector.hpp>
31 #include <SiconosMatrix.hpp>
32 
33 class SiconosShape
34 {
35 protected:
36   /** serialization hooks
37    */
38   ACCEPT_SERIALIZATION(SiconosShape);
39 
40   double _inside_margin;
41   double _outside_margin;
42   unsigned int _version; // version number tracks changes to shape properties
43 
SiconosShape()44   SiconosShape()
45     : _inside_margin(0.1)
46     , _outside_margin(0.0)
47     , _version(0)
48     {}
49 
50 public:
51 
~SiconosShape()52   virtual ~SiconosShape() {}
53 
54   /** Set the inside margin of the shape.  This is a distance that the
55    * contour should be shrunk to improve contact detection robustness.
56    * It will have an effect on the roundness of corners. */
setInsideMargin(double margin)57   void setInsideMargin (double margin)
58   {
59     _inside_margin = margin;
60     _version ++;
61   }
62 
63   /** Set the outside margin of the shape.  This is the distance from
64     * the contact shell to an external shell used to detect contacts
65     * in advance.  The implementation will detect contact points on
66     * the external shell and project them back to the contact shell.
67     * Note: Currently not working in Bullet implementation!  Better to
68     * leave at zero. */
setOutsideMargin(double margin)69   void setOutsideMargin(double margin)
70   {
71     _outside_margin = margin;
72     _version ++;
73   }
74 
insideMargin()75   double insideMargin() { return _inside_margin; }
76 
outsideMargin()77   double outsideMargin() { return _outside_margin; }
78 
version() const79   unsigned int version() const { return _version; }
80 
81   /** visitors hook
82    */
83   VIRTUAL_ACCEPT_VISITORS();
84 };
85 
86 class SiconosPlane : public SiconosShape,
87                      public std::enable_shared_from_this<SiconosPlane>
88 {
89 protected:
90   /** serialization hooks
91    */
92   ACCEPT_SERIALIZATION(SiconosPlane);
93 
94 public:
SiconosPlane()95   SiconosPlane() : SiconosShape() {}
96 
~SiconosPlane()97   virtual ~SiconosPlane() {}
98 
99   /** visitors hook
100    */
101   ACCEPT_VISITORS();
102 };
103 
104 class SiconosSphere : public SiconosShape,
105                       public std::enable_shared_from_this<SiconosSphere>
106 {
107 private:
SiconosSphere()108   SiconosSphere() : SiconosShape() {};
109 
110 protected:
111   /** serialization hooks
112    */
113   ACCEPT_SERIALIZATION(SiconosSphere);
114   float _radius;
115 
116 public:
SiconosSphere(float radius)117   SiconosSphere(float radius)
118     : SiconosShape(), _radius(radius) {}
119 
~SiconosSphere()120   virtual ~SiconosSphere() {}
121 
radius() const122   float radius() const { return _radius; }
setRadius(float r)123   void setRadius(float r) { _radius = r; _version ++; }
124 
125   /** visitors hook
126    */
127   ACCEPT_VISITORS();
128 };
129 
130 class SiconosBox : public SiconosShape,
131                    public std::enable_shared_from_this<SiconosBox>
132 {
133 private:
SiconosBox()134   SiconosBox() : SiconosShape() {};
135 
136 protected:
137   /** serialization hooks
138    */
139   ACCEPT_SERIALIZATION(SiconosBox);
140   SP::SiconosVector _dimensions;
141 
142 public:
SiconosBox(double width,double height,double depth)143   SiconosBox(double width, double height, double depth)
144     : SiconosShape(), _dimensions(new SiconosVector(3))
145   {
146     (*_dimensions)(0) = width;
147     (*_dimensions)(1) = height;
148     (*_dimensions)(2) = depth;
149   }
150 
SiconosBox(SP::SiconosVector dimensions)151   SiconosBox(SP::SiconosVector dimensions)
152     : SiconosShape(), _dimensions(dimensions) {}
153 
~SiconosBox()154   virtual ~SiconosBox() {}
155 
dimensions() const156   SP::SiconosVector dimensions() const { return _dimensions; }
157 
setDimensions(double width,double height,double depth)158   void setDimensions(double width, double height, double depth)
159   {
160     (*_dimensions)(0) = width;
161     (*_dimensions)(1) = height;
162     (*_dimensions)(2) = depth;
163     _version ++;
164   }
165 
setDimensions(SP::SiconosVector dim)166   void setDimensions(SP::SiconosVector dim)
167   {
168     _dimensions = dim;
169     _version ++;
170   }
171 
setDimensions(const SiconosVector & dim)172   void setDimensions(const SiconosVector& dim)
173   {
174     (*_dimensions)(0) = dim(0);
175     (*_dimensions)(1) = dim(1);
176     (*_dimensions)(2) = dim(2);
177     _version ++;
178   }
179 
180   /** visitors hook
181    */
182   ACCEPT_VISITORS();
183 };
184 
185 class SiconosCylinder : public SiconosShape,
186                         public std::enable_shared_from_this<SiconosCylinder>
187 {
188 private:
SiconosCylinder()189   SiconosCylinder() : SiconosShape() {};
190 
191 protected:
192   /** serialization hooks
193    */
194   ACCEPT_SERIALIZATION(SiconosCylinder);
195   double _radius;
196   double _length;
197 
198 public:
SiconosCylinder(float radius,float length)199   SiconosCylinder(float radius, float length)
200     : SiconosShape(), _radius(radius), _length(length)
201   {
202   }
203 
~SiconosCylinder()204   virtual ~SiconosCylinder() {}
205 
setRadius(double radius)206   void setRadius(double radius)
207   {
208     _radius = radius;
209     _version ++;
210   }
211 
radius()212   double radius() { return _radius; }
213 
setLength(double length)214   void setLength(double length)
215   {
216     _length = length;
217     _version ++;
218   }
219 
length()220   double length() { return _length; }
221 
222   /** visitors hook
223    */
224   ACCEPT_VISITORS();
225 };
226 
227 class SiconosCone : public SiconosShape,
228                         public std::enable_shared_from_this<SiconosCone>
229 {
230 private:
SiconosCone()231   SiconosCone() : SiconosShape() {};
232 
233 protected:
234   /** serialization hooks
235    */
236   ACCEPT_SERIALIZATION(SiconosCone);
237   double _radius;
238   double _length;
239 
240 public:
SiconosCone(float radius,float length)241   SiconosCone(float radius, float length)
242     : SiconosShape(), _radius(radius), _length(length)
243   {
244   }
245 
~SiconosCone()246   virtual ~SiconosCone() {}
247 
setRadius(double radius)248   void setRadius(double radius)
249   {
250     _radius = radius;
251     _version ++;
252   }
253 
radius()254   double radius() { return _radius; }
255 
setLength(double length)256   void setLength(double length)
257   {
258     _length = length;
259     _version ++;
260   }
261 
length()262   double length() { return _length; }
263 
264   /** visitors hook
265    */
266   ACCEPT_VISITORS();
267 };
268 
269 class SiconosCapsule : public SiconosShape,
270                         public std::enable_shared_from_this<SiconosCapsule>
271 {
272 private:
SiconosCapsule()273   SiconosCapsule() : SiconosShape() {};
274 
275 protected:
276   /** serialization hooks
277    */
278   ACCEPT_SERIALIZATION(SiconosCapsule);
279   double _radius;
280   double _length;
281 
282 public:
SiconosCapsule(float radius,float length)283   SiconosCapsule(float radius, float length)
284     : SiconosShape(), _radius(radius), _length(length)
285   {
286   }
287 
~SiconosCapsule()288   virtual ~SiconosCapsule() {}
289 
setRadius(double radius)290   void setRadius(double radius)
291   {
292     _radius = radius;
293     _version ++;
294   }
295 
radius()296   double radius() { return _radius; }
297 
setLength(double length)298   void setLength(double length)
299   {
300     _length = length;
301     _version ++;
302   }
303 
length()304   double length() { return _length; }
305 
306   /** visitors hook
307    */
308   ACCEPT_VISITORS();
309 };
310 
311 
312 
313 class SiconosConvexHull : public SiconosShape,
314                           public std::enable_shared_from_this<SiconosConvexHull>
315 {
316 private:
SiconosConvexHull()317   SiconosConvexHull() : SiconosShape() {};
318 
319 protected:
320   /** serialization hooks
321    */
322   ACCEPT_SERIALIZATION(SiconosConvexHull);
323   SP::SiconosMatrix _vertices;
324 
325 public:
SiconosConvexHull(SP::SiconosMatrix vertices)326   SiconosConvexHull(SP::SiconosMatrix vertices)
327     : SiconosShape(), _vertices(vertices)
328   {
329     if (_vertices && _vertices->size(1) != 3)
330       THROW_EXCEPTION("Convex hull vertices matrix must have 3 columns.");
331   }
332 
~SiconosConvexHull()333   virtual ~SiconosConvexHull() {}
334 
vertices() const335   SP::SiconosMatrix vertices() const { return _vertices; }
336 
setVertices(SP::SiconosMatrix vertices)337   void setVertices(SP::SiconosMatrix vertices)
338   {
339     _vertices = vertices;
340     _version ++;
341   }
342 
343   /** visitors hook
344    */
345   ACCEPT_VISITORS();
346 };
347 
348 typedef std::vector<unsigned int> VUInt;
349 TYPEDEF_SPTR(VUInt)
350 
351 class SiconosMesh : public SiconosShape,
352                     public std::enable_shared_from_this<SiconosMesh>
353 {
354 private:
SiconosMesh()355   SiconosMesh() : SiconosShape() {};
356 
357 protected:
358   /** serialization hooks
359    */
360   ACCEPT_SERIALIZATION(SiconosMesh);
361   SP::VUInt _indexes;
362   SP::SiconosMatrix _vertices;
363 
364 public:
SiconosMesh(SP::VUInt indexes,SP::SiconosMatrix vertices)365   SiconosMesh(SP::VUInt indexes,
366               SP::SiconosMatrix vertices)
367     : SiconosShape(), _indexes(indexes), _vertices(vertices)
368   {
369     if (!_indexes || (_indexes->size() % 3) != 0)
370       THROW_EXCEPTION("Mesh indexes size must be divisible by 3.");
371     if (!_vertices || _vertices->size(0) != 3)
372       THROW_EXCEPTION("Mesh vertices matrix must have 3 columns.");
373   }
374 
indexes()375   SP::VUInt indexes() { return _indexes; }
vertices()376   SP::SiconosMatrix vertices() { return _vertices; }
377 
~SiconosMesh()378   virtual ~SiconosMesh() {}
379 
380   /** visitors hook
381    */
382   ACCEPT_VISITORS();
383 };
384 
385 class SiconosHeightMap : public SiconosShape,
386                          public std::enable_shared_from_this<SiconosHeightMap>
387 {
388 private:
SiconosHeightMap()389   SiconosHeightMap() : SiconosShape() {};
390 
391 protected:
392   /** serialization hooks
393    */
394   ACCEPT_SERIALIZATION(SiconosHeightMap);
395   SP::SiconosMatrix _height_data;
396   double _length_x;
397   double _length_y;
398 
399 public:
SiconosHeightMap(SP::SiconosMatrix height_data,double length_x,double length_y)400   SiconosHeightMap(SP::SiconosMatrix height_data,
401                    double length_x, double length_y)
402     : SiconosShape(), _height_data(height_data),
403       _length_x(length_x), _length_y(length_y)
404   {
405   }
406 
height_data()407   SP::SiconosMatrix height_data() { return _height_data; }
length_x()408   double length_x() { return _length_x; }
length_y()409   double length_y() { return _length_y; }
410 
~SiconosHeightMap()411   virtual ~SiconosHeightMap() {}
412 
413   /** visitors hook
414    */
415   ACCEPT_VISITORS();
416 };
417 
418 
419 class SiconosDisk : public SiconosShape,
420                     public std::enable_shared_from_this<SiconosDisk>
421 {
422 private:
SiconosDisk()423   SiconosDisk() : SiconosShape() {};
424 
425 protected:
426   /** serialization hooks
427    */
428   ACCEPT_SERIALIZATION(SiconosDisk);
429   float _radius;
430 
431 public:
SiconosDisk(float radius)432   SiconosDisk(float radius)
433     : SiconosShape(), _radius(radius) {}
434 
~SiconosDisk()435   virtual ~SiconosDisk() {}
436 
radius() const437   float radius() const { return _radius; }
setRadius(float r)438   void setRadius(float r) { _radius = r; _version ++; }
439 
440   /** visitors hook
441    */
442   ACCEPT_VISITORS();
443 };
444 
445 class SiconosBox2d : public SiconosShape,
446                    public std::enable_shared_from_this<SiconosBox2d>
447 {
448 private:
SiconosBox2d()449   SiconosBox2d() : SiconosShape() {};
450 
451 protected:
452   /** serialization hooks
453    */
454   ACCEPT_SERIALIZATION(SiconosBox2d);
455   SP::SiconosVector _dimensions;
456 
457 public:
SiconosBox2d(double width,double height)458   SiconosBox2d(double width, double height)
459     : SiconosShape(), _dimensions(new SiconosVector(2))
460   {
461     (*_dimensions)(0) = width;
462     (*_dimensions)(1) = height;
463   }
464 
SiconosBox2d(SP::SiconosVector dimensions)465   SiconosBox2d(SP::SiconosVector dimensions)
466     : SiconosShape(), _dimensions(dimensions) {}
467 
~SiconosBox2d()468   virtual ~SiconosBox2d() {}
469 
dimensions() const470   SP::SiconosVector dimensions() const { return _dimensions; }
471 
setDimensions(double width,double height)472   void setDimensions(double width, double height)
473   {
474     (*_dimensions)(0) = width;
475     (*_dimensions)(1) = height;
476     _version ++;
477   }
478 
setDimensions(SP::SiconosVector dim)479   void setDimensions(SP::SiconosVector dim)
480   {
481     _dimensions = dim;
482     _version ++;
483   }
484 
setDimensions(const SiconosVector & dim)485   void setDimensions(const SiconosVector& dim)
486   {
487     (*_dimensions)(0) = dim(0);
488     (*_dimensions)(1) = dim(1);
489     _version ++;
490   }
491 
492   /** visitors hook
493    */
494   ACCEPT_VISITORS();
495 };
496 
497 class SiconosConvexHull2d : public SiconosShape,
498                           public std::enable_shared_from_this<SiconosConvexHull2d>
499 {
500 private:
SiconosConvexHull2d()501   SiconosConvexHull2d() : SiconosShape() {};
502 
503 protected:
504   /** serialization hooks
505    */
506   ACCEPT_SERIALIZATION(SiconosConvexHull2d);
507   SP::SiconosMatrix _vertices;
508 
509 public:
SiconosConvexHull2d(SP::SiconosMatrix vertices)510   SiconosConvexHull2d(SP::SiconosMatrix vertices)
511     : SiconosShape(), _vertices(vertices)
512   {
513     if (_vertices && _vertices->size(1) != 2)
514       THROW_EXCEPTION("Convex hull vertices matrix must have 2 columns in 2d.");
515   }
516 
~SiconosConvexHull2d()517   virtual ~SiconosConvexHull2d() {}
518 
vertices() const519   SP::SiconosMatrix vertices() const { return _vertices; }
520 
setVertices(SP::SiconosMatrix vertices)521   void setVertices(SP::SiconosMatrix vertices)
522   {
523     _vertices = vertices;
524     _version ++;
525   }
526 
527   /** visitors hook
528    */
529   ACCEPT_VISITORS();
530 };
531 
532 
533 
534 
535 
536 #endif /* SiconosShape_h */
537