region.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2020 by
  4. * The Salk Institute for Biological Studies
  5. *
  6. * Use of this source code is governed by an MIT-style
  7. * license that can be found in the LICENSE file or at
  8. * https://opensource.org/licenses/MIT.
  9. *
  10. ******************************************************************************/
  11. #ifndef API_REGION_H
  12. #define API_REGION_H
  13. #include "generated/gen_region.h"
  14. #include "api/api_common.h"
  15. namespace MCell {
  16. namespace API {
  17. enum class RegionType {
  18. UNKNOWN,
  19. VOLUME,
  20. SURFACE
  21. };
  22. class Region: public GenRegion, public std::enable_shared_from_this<Region> {
  23. public:
  24. REGION_CTOR()
  25. void postprocess_in_ctor() {
  26. set_all_custom_attributes_to_default();
  27. }
  28. void set_all_custom_attributes_to_default() override {
  29. region_type = RegionType::UNKNOWN;
  30. }
  31. std::shared_ptr<Region> __add__(std::shared_ptr<Region> other) override {
  32. check_has_compatible_type(other, false);
  33. std::shared_ptr<Region> res = std::make_shared<Region>(RegionNodeType::UNION, shared_from_this(), other);
  34. res->region_type = other->region_type;
  35. return res;
  36. }
  37. std::shared_ptr<Region> __sub__(std::shared_ptr<Region> other) override {
  38. check_has_compatible_type(other, true);
  39. std::shared_ptr<Region> res = std::make_shared<Region>(RegionNodeType::DIFFERENCE, shared_from_this(), other);
  40. res->region_type = other->region_type;
  41. return res;
  42. }
  43. std::shared_ptr<Region> __mul__(std::shared_ptr<Region> other) override {
  44. check_has_compatible_type(other, false);
  45. std::shared_ptr<Region> res = std::make_shared<Region>(RegionNodeType::INTERSECT, shared_from_this(), other);
  46. res->region_type = other->region_type;
  47. return res;
  48. }
  49. // added
  50. void check_has_compatible_type(std::shared_ptr<Region> other, const bool is_sub = false) {
  51. bool ok = true;
  52. if (is_sub) {
  53. ok = (class_name == NAME_CLASS_GEOMETRY_OBJECT && other->region_type == RegionType::SURFACE) ||
  54. region_type == other->region_type;
  55. }
  56. else {
  57. ok = (region_type == other->region_type);
  58. }
  59. if (!ok) {
  60. throw RuntimeError(S("When creating regions, one can only combine regions of identical type ") +
  61. "(both volume or both surface)" +
  62. ", also one can subtract a " + NAME_CLASS_SURFACE_REGION + " from a " + NAME_CLASS_GEOMETRY_OBJECT + ", error for:\n" +
  63. to_str() + "and\n" + other->to_str() +
  64. "-- end of error message related to combining regions of different type --");
  65. }
  66. }
  67. // set to true in GeometryObject, allows to find out whether it is safe to
  68. // cast this object to a GeometryObject
  69. RegionType region_type;
  70. };
  71. } // namespace API
  72. } // namespace MCell
  73. #endif // API_REGION_H