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